Skip to content

Commit 082c10a

Browse files
committed
Revert "[VM/nnbd] Pass nullability when creating Class::DeclarationType."
This reverts commit ea57b1e. Reason for revert: Please see https://buganizer.corp.google.com/issues/144304690 Original change's description: > [VM/nnbd] Pass nullability when creating Class::DeclarationType. > > Passing nullability rather than forcing kLegacy helps slightly reduce the number > of Types in the VM and in snapshots. > This allows to remove the kludge about declaration type of Null being kNullable. > Also pass nullability when creating a simple type may help. > > Note that CFE is still producing super types and some interface types that are > non-nullable, even with nnbd features disabled. But this should get fixed and > further reduce the number of types in the snapshot. > > Change-Id: I397f00902026ee5bc91d36328f4156427702efdb > Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/124480 > Commit-Queue: Régis Crelier <regis@google.com> > Reviewed-by: Alexander Markov <alexmarkov@google.com> TBR=rmacnak@google.com,alexmarkov@google.com,asiva@google.com,regis@google.com # Not skipping CQ checks because original CL landed > 1 day ago. Change-Id: Icae0a69cda6cc531bba4d5d12471e7267a277340 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/125102 Reviewed-by: Siva Annamalai <asiva@google.com>
1 parent b4779e8 commit 082c10a

File tree

6 files changed

+85
-85
lines changed

6 files changed

+85
-85
lines changed

runtime/vm/compiler/backend/il_deserializer.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1848,7 +1848,7 @@ bool FlowGraphDeserializer::ParseType(SExpression* sexp, Object* out) {
18481848
}
18491849
// Guaranteed not to re-enter ParseType.
18501850
if (!ParseClass(cls_sexp, &type_class_)) return false;
1851-
*out = Type::New(type_class_, *type_args_ptr, token_pos);
1851+
*out = Type::New(type_class_, *type_args_ptr, token_pos, Heap::kOld);
18521852
auto& type = Type::Cast(*out);
18531853
if (auto const sig_sexp = list->ExtraLookupValue("signature")) {
18541854
auto& function = Function::Handle(zone());

runtime/vm/compiler/frontend/bytecode_reader.cc

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1669,7 +1669,14 @@ RawObject* BytecodeReaderHelper::ReadType(intptr_t tag,
16691669
if (!cls.is_declaration_loaded()) {
16701670
LoadReferencedClass(cls);
16711671
}
1672-
return cls.DeclarationType(nullability);
1672+
Type& type = Type::Handle(Z, cls.DeclarationType());
1673+
// TODO(regis): Remove this workaround once nullability of Null provided
1674+
// by CFE is always kNullable.
1675+
if (type.IsNullType()) {
1676+
ASSERT(type.IsNullable());
1677+
return type.raw();
1678+
}
1679+
return type.ToNullability(nullability, Heap::kOld);
16731680
}
16741681
case kTypeParameter: {
16751682
Object& parent = Object::Handle(Z, ReadObject());
@@ -1703,9 +1710,9 @@ RawObject* BytecodeReaderHelper::ReadType(intptr_t tag,
17031710
}
17041711
const TypeArguments& type_arguments =
17051712
TypeArguments::CheckedHandle(Z, ReadObject());
1706-
const Type& type =
1707-
Type::Handle(Z, Type::New(cls, type_arguments,
1708-
TokenPosition::kNoSource, nullability));
1713+
const Type& type = Type::Handle(
1714+
Z, Type::New(cls, type_arguments, TokenPosition::kNoSource));
1715+
type.set_nullability(nullability);
17091716
type.SetIsFinalized();
17101717
return type.Canonicalize();
17111718
}
@@ -1735,9 +1742,9 @@ RawObject* BytecodeReaderHelper::ReadType(intptr_t tag,
17351742
pending_recursive_types_->SetLength(id);
17361743
pending_recursive_types_ = saved_pending_recursive_types;
17371744

1738-
Type& type =
1739-
Type::Handle(Z, Type::New(cls, type_arguments,
1740-
TokenPosition::kNoSource, nullability));
1745+
Type& type = Type::Handle(
1746+
Z, Type::New(cls, type_arguments, TokenPosition::kNoSource));
1747+
type.set_nullability(nullability);
17411748
type_ref.set_type(type);
17421749
type.SetIsFinalized();
17431750
if (id != 0) {

runtime/vm/compiler/frontend/kernel_to_il.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2275,7 +2275,8 @@ FlowGraph* FlowGraphBuilder::BuildGraphOfNoSuchMethodForwarder(
22752275
Function::ZoneHandle(Z, function.parent_function());
22762276
const Class& owner = Class::ZoneHandle(Z, parent.Owner());
22772277
AbstractType& type = AbstractType::ZoneHandle(Z);
2278-
type = Type::New(owner, TypeArguments::Handle(Z), owner.token_pos());
2278+
type = Type::New(owner, TypeArguments::Handle(Z), owner.token_pos(),
2279+
Heap::kOld);
22792280
type = ClassFinalizer::FinalizeType(owner, type);
22802281
body += Constant(type);
22812282
} else {

runtime/vm/compiler/frontend/kernel_translation_helper.cc

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2767,8 +2767,9 @@ void TypeTranslator::BuildTypeInternal() {
27672767
result_ = Object::void_type().raw();
27682768
break;
27692769
case kBottomType:
2770-
result_ = Class::Handle(Z, I->object_store()->null_class())
2771-
.DeclarationType(kNullable);
2770+
result_ =
2771+
Class::Handle(Z, I->object_store()->null_class()).DeclarationType();
2772+
// We set the nullability of Null to kNullable, even in legacy mode.
27722773
ASSERT(result_.IsNullable());
27732774
break;
27742775
case kNeverType:
@@ -2813,13 +2814,18 @@ void TypeTranslator::BuildInterfaceType(bool simple) {
28132814
if (simple) {
28142815
if (finalize_ || klass.is_type_finalized()) {
28152816
// Fast path for non-generic types: retrieve or populate the class's only
2816-
// canonical type (as long as only one nullability variant is used), which
2817-
// is its declaration type.
2818-
result_ = klass.DeclarationType(nullability);
2817+
// canonical type, which is its declaration type.
2818+
result_ = klass.DeclarationType();
2819+
// TODO(regis): Remove this workaround once nullability of Null provided
2820+
// by CFE is always kNullable.
2821+
if (!result_.IsNullType()) {
2822+
result_ = Type::Cast(result_).ToNullability(nullability, Heap::kOld);
2823+
}
28192824
} else {
28202825
// Note that the type argument vector is not yet extended.
2821-
result_ = Type::New(klass, Object::null_type_arguments(),
2822-
klass.token_pos(), nullability);
2826+
result_ =
2827+
Type::New(klass, Object::null_type_arguments(), klass.token_pos());
2828+
Type::Cast(result_).set_nullability(nullability);
28232829
}
28242830
return;
28252831
}
@@ -2924,7 +2930,8 @@ void TypeTranslator::BuildFunctionType(bool simple) {
29242930
finalize_ = finalize;
29252931

29262932
Type& signature_type =
2927-
Type::ZoneHandle(Z, signature_function.SignatureType(nullability));
2933+
Type::ZoneHandle(Z, signature_function.SignatureType());
2934+
signature_type.set_nullability(nullability);
29282935

29292936
if (finalize_) {
29302937
signature_type ^=

runtime/vm/object.cc

Lines changed: 36 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -944,13 +944,13 @@ void Object::Init(Isolate* isolate) {
944944
cls.set_is_type_finalized();
945945

946946
cls = dynamic_class_;
947-
*dynamic_type_ = Type::NewNonParameterizedType(cls, kNullable);
947+
*dynamic_type_ = Type::NewNonParameterizedType(cls);
948948

949949
cls = void_class_;
950-
*void_type_ = Type::NewNonParameterizedType(cls, kNullable);
950+
*void_type_ = Type::NewNonParameterizedType(cls);
951951

952952
cls = never_class_;
953-
*never_type_ = Type::NewNonParameterizedType(cls, kNonNullable);
953+
*never_type_ = Type::NewNonParameterizedType(cls);
954954

955955
// Since TypeArguments objects are passed as function arguments, make them
956956
// behave as Dart instances, although they are just VM objects.
@@ -1567,7 +1567,7 @@ RawError* Object::Init(Isolate* isolate,
15671567
cls = object_store->array_class(); // Was allocated above.
15681568
RegisterPrivateClass(cls, Symbols::_List(), core_lib);
15691569
pending_classes.Add(cls);
1570-
// We cannot use NewNonParameterizedType(), because Array is
1570+
// We cannot use NewNonParameterizedType(cls), because Array is
15711571
// parameterized. Warning: class _List has not been patched yet. Its
15721572
// declared number of type parameters is still 0. It will become 1 after
15731573
// patching. The array type allocated below represents the raw type _List
@@ -1934,8 +1934,7 @@ RawError* Object::Init(Isolate* isolate,
19341934
// name is a built-in identifier (this is wrong). The corresponding types
19351935
// are stored in the object store.
19361936
cls = object_store->null_class();
1937-
type = Type::NewNonParameterizedType(cls, kNullable);
1938-
cls.set_declaration_type(type);
1937+
type = Type::NewNonParameterizedType(cls);
19391938
object_store->set_null_type(type);
19401939
ASSERT(type.IsNullable());
19411940

@@ -4336,23 +4335,18 @@ void Class::set_declaration_type(const Type& value) const {
43364335
// TODO(regis): Since declaration type is used as the runtime type of
43374336
// instances of a non-generic class, the nullability should be set to
43384337
// kNonNullable instead of kLegacy.
4339-
// For now, we accept any except for Null (kNullable).
4340-
ASSERT(!value.IsNullType() || value.IsNullable());
4338+
// For now, we set the nullability to kLegacy, except for Null.
4339+
ASSERT(value.IsLegacy() || (value.IsNullType() && value.IsNullable()));
43414340
StorePointer(&raw_ptr()->declaration_type_, value.raw());
43424341
}
43434342

4344-
RawType* Class::DeclarationType(Nullability nullability) const {
4343+
RawType* Class::DeclarationType() const {
43454344
ASSERT(is_declaration_loaded());
4346-
if (IsNullClass()) {
4347-
// Ignore requested nullability (e.g. by mirrors).
4348-
nullability = kNullable;
4349-
}
4350-
Type& type = Type::Handle(declaration_type());
4351-
if (!type.IsNull()) {
4352-
return type.ToNullability(nullability, Heap::kOld);
4345+
if (declaration_type() != Type::null()) {
4346+
return declaration_type();
43534347
}
4354-
type = Type::New(*this, TypeArguments::Handle(type_parameters()), token_pos(),
4355-
nullability);
4348+
Type& type = Type::Handle(
4349+
Type::New(*this, TypeArguments::Handle(type_parameters()), token_pos()));
43564350
type ^= ClassFinalizer::FinalizeType(*this, type);
43574351
set_declaration_type(type);
43584352
return type.raw();
@@ -6324,8 +6318,8 @@ RawType* Function::SignatureType(Nullability nullability) const {
63246318
const TypeArguments& signature_type_arguments =
63256319
TypeArguments::Handle(scope_class.type_parameters());
63266320
// Return the still unfinalized signature type.
6327-
type = Type::New(scope_class, signature_type_arguments, token_pos(),
6328-
nullability);
6321+
type = Type::New(scope_class, signature_type_arguments, token_pos());
6322+
type.set_nullability(nullability);
63296323
type.set_signature(*this);
63306324
SetSignatureType(type);
63316325
}
@@ -16662,10 +16656,7 @@ RawAbstractType* Instance::GetType(Heap::Space space) const {
1666216656
if (cls.NumTypeArguments() > 0) {
1666316657
type_arguments = GetTypeArguments();
1666416658
}
16665-
// TODO(regis): The runtime type of a non-null instance should be
16666-
// non-nullable instead of legacy. Revisit.
16667-
type = Type::New(cls, type_arguments, TokenPosition::kNoSource, kLegacy,
16668-
space);
16659+
type = Type::New(cls, type_arguments, TokenPosition::kNoSource, space);
1666916660
type.SetIsFinalized();
1667016661
type ^= type.Canonicalize();
1667116662
}
@@ -17649,22 +17640,20 @@ RawType* Type::DartTypeType() {
1764917640
return Isolate::Current()->object_store()->type_type();
1765017641
}
1765117642

17652-
RawType* Type::NewNonParameterizedType(const Class& type_class,
17653-
Nullability nullability) {
17643+
RawType* Type::NewNonParameterizedType(const Class& type_class) {
1765417644
ASSERT(type_class.NumTypeArguments() == 0);
1765517645
// It is too early to use the class finalizer, as type_class may not be named
1765617646
// yet, so do not call DeclarationType().
1765717647
Type& type = Type::Handle(type_class.declaration_type());
1765817648
if (type.IsNull()) {
1765917649
type = Type::New(Class::Handle(type_class.raw()),
17660-
Object::null_type_arguments(), TokenPosition::kNoSource,
17661-
nullability);
17650+
Object::null_type_arguments(), TokenPosition::kNoSource);
1766217651
type.SetIsFinalized();
1766317652
type ^= type.Canonicalize();
1766417653
type_class.set_declaration_type(type);
1766517654
}
1766617655
ASSERT(type.IsFinalized());
17667-
return type.ToNullability(nullability, Heap::kOld);
17656+
return type.raw();
1766817657
}
1766917658

1767017659
void Type::SetIsFinalized() const {
@@ -17800,8 +17789,8 @@ RawAbstractType* Type::InstantiateFrom(
1780017789
}
1780117790
// This uninstantiated type is not modified, as it can be instantiated
1780217791
// with different instantiators. Allocate a new instantiated version of it.
17803-
const Type& instantiated_type = Type::Handle(
17804-
zone, Type::New(cls, type_arguments, token_pos(), nullability(), space));
17792+
const Type& instantiated_type =
17793+
Type::Handle(zone, Type::New(cls, type_arguments, token_pos(), space));
1780517794
// For a function type, possibly instantiate and set its signature.
1780617795
if (!sig_fun.IsNull()) {
1780717796
// If we are finalizing a typedef, do not yet instantiate its signature,
@@ -18020,8 +18009,10 @@ RawAbstractType* Type::Canonicalize(TrailPtr trail) const {
1802018009
const Class& cls = Class::Handle(zone, type_class());
1802118010

1802218011
// Fast canonical lookup/registry for simple types.
18023-
if (!cls.IsGeneric() && !cls.IsClosureClass() && !cls.IsTypedefClass()) {
18012+
if (IsNullType() || (IsLegacy() && !cls.IsGeneric() &&
18013+
!cls.IsClosureClass() && !cls.IsTypedefClass())) {
1802418014
ASSERT(!IsFunctionType());
18015+
ASSERT(!IsNullType() || IsNullable());
1802518016
Type& type = Type::Handle(zone, cls.declaration_type());
1802618017
if (type.IsNull()) {
1802718018
ASSERT(!cls.raw()->InVMIsolateHeap() || (isolate == Dart::vm_isolate()));
@@ -18054,12 +18045,10 @@ RawAbstractType* Type::Canonicalize(TrailPtr trail) const {
1805418045
}
1805518046
}
1805618047
}
18057-
if (nullability() == type.nullability()) {
18058-
ASSERT(this->Equals(type));
18059-
ASSERT(type.IsCanonical());
18060-
ASSERT(type.IsOld());
18061-
return type.raw();
18062-
}
18048+
ASSERT(this->Equals(type));
18049+
ASSERT(type.IsCanonical());
18050+
ASSERT(type.IsOld());
18051+
return type.raw();
1806318052
}
1806418053

1806518054
AbstractType& type = Type::Handle(zone);
@@ -18147,13 +18136,12 @@ bool Type::CheckIsCanonical(Thread* thread) const {
1814718136
const Class& cls = Class::Handle(zone, type_class());
1814818137

1814918138
// Fast canonical lookup/registry for simple types.
18150-
if (!cls.IsGeneric() && !cls.IsClosureClass() && !cls.IsTypedefClass()) {
18139+
if (IsNullType() || (IsLegacy() && !cls.IsGeneric() &&
18140+
!cls.IsClosureClass() && !cls.IsTypedefClass())) {
1815118141
ASSERT(!IsFunctionType());
18142+
ASSERT(!IsNullType() || IsNullable());
1815218143
type = cls.declaration_type();
18153-
ASSERT(type.IsCanonical());
18154-
if (nullability() == type.nullability()) {
18155-
return (raw() == type.raw());
18156-
}
18144+
return (raw() == type.raw());
1815718145
}
1815818146

1815918147
ObjectStore* object_store = isolate->object_store();
@@ -18246,7 +18234,6 @@ RawType* Type::New(Heap::Space space) {
1824618234
RawType* Type::New(const Class& clazz,
1824718235
const TypeArguments& arguments,
1824818236
TokenPosition token_pos,
18249-
Nullability nullability,
1825018237
Heap::Space space) {
1825118238
Zone* Z = Thread::Current()->zone();
1825218239
const Type& result = Type::Handle(Z, Type::New(space));
@@ -18255,7 +18242,11 @@ RawType* Type::New(const Class& clazz,
1825518242
result.SetHash(0);
1825618243
result.set_token_pos(token_pos);
1825718244
result.StoreNonPointer(&result.raw_ptr()->type_state_, RawType::kAllocated);
18258-
result.set_nullability(nullability);
18245+
if (clazz.id() == kNullCid) {
18246+
result.set_nullability(kNullable);
18247+
} else {
18248+
result.set_nullability(kLegacy);
18249+
}
1825918250

1826018251
result.SetTypeTestingStub(
1826118252
Code::Handle(Z, TypeTestingStubGenerator::DefaultCodeForType(result)));

runtime/vm/object.h

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -837,21 +837,6 @@ typedef ZoneGrowableHandlePtrArray<const AbstractType>* TrailPtr;
837837
// The third string in the triplet is "print" if the triplet should be printed.
838838
typedef ZoneGrowableHandlePtrArray<const String> URIs;
839839

840-
// Keep in sync with package:kernel/lib/ast.dart
841-
enum Nullability {
842-
kUndetermined = 0,
843-
kNullable = 1,
844-
kNonNullable = 2,
845-
kLegacy = 3,
846-
};
847-
848-
// Nullability aware subtype checking modes.
849-
enum NNBDMode {
850-
kUnaware,
851-
kWeak,
852-
kStrong,
853-
};
854-
855840
class Class : public Object {
856841
public:
857842
enum InvocationDispatcherEntry {
@@ -950,11 +935,7 @@ class Class : public Object {
950935
// class B<T, S>
951936
// class C<R> extends B<R, int>
952937
// C.DeclarationType() --> C [R, int, R]
953-
// The declaration type is legacy by default, but another nullability
954-
// variant may be requested. The first requested type gets cached in the class
955-
// and subsequent nullability variants get cached in the object store.
956-
// TODO(regis): Is this caching still useful or should we eliminate it?
957-
RawType* DeclarationType(Nullability nullability = kLegacy) const;
938+
RawType* DeclarationType() const;
958939

959940
static intptr_t declaration_type_offset() {
960941
return OFFSET_OF(RawClass, declaration_type_);
@@ -2149,6 +2130,21 @@ class ICData : public Object {
21492130
friend class SnapshotWriter;
21502131
};
21512132

2133+
// Keep in sync with package:kernel/lib/ast.dart
2134+
enum Nullability {
2135+
kUndetermined = 0,
2136+
kNullable = 1,
2137+
kNonNullable = 2,
2138+
kLegacy = 3,
2139+
};
2140+
2141+
// Nullability aware subtype checking modes.
2142+
enum NNBDMode {
2143+
kUnaware,
2144+
kWeak,
2145+
kStrong,
2146+
};
2147+
21522148
// Often used constants for number of free function type parameters.
21532149
enum {
21542150
kNoneFree = 0,
@@ -7157,13 +7153,11 @@ class Type : public AbstractType {
71577153
static RawType* DartTypeType();
71587154

71597155
// The finalized type of the given non-parameterized class.
7160-
static RawType* NewNonParameterizedType(const Class& type_class,
7161-
Nullability nullability = kLegacy);
7156+
static RawType* NewNonParameterizedType(const Class& type_class);
71627157

71637158
static RawType* New(const Class& clazz,
71647159
const TypeArguments& arguments,
71657160
TokenPosition token_pos,
7166-
Nullability nullability = kLegacy,
71677161
Heap::Space space = Heap::kOld);
71687162

71697163
private:

0 commit comments

Comments
 (0)