diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc index de012076a46..5b3fe6de69c 100644 --- a/runtime/vm/class_finalizer.cc +++ b/runtime/vm/class_finalizer.cc @@ -557,8 +557,6 @@ void ClassFinalizer::FinalizeTypeArguments(const Class& cls, const Class& super_class = Class::Handle(super_type.type_class()); const intptr_t num_super_type_params = super_class.NumTypeParameters(); const intptr_t num_super_type_args = super_class.NumTypeArguments(); - ASSERT(num_super_type_args == - (cls.NumTypeArguments() - cls.NumOwnTypeArguments())); if (!super_type.IsFinalized() && !super_type.IsBeingFinalized()) { super_type = FinalizeType(cls, super_type, kFinalize, pending_types); cls.set_super_type(super_type); @@ -1384,7 +1382,7 @@ void ClassFinalizer::VerifyImplicitFieldOffsets() { cls = class_table.At(kFfiPointerCid); error = cls.EnsureIsFinalized(thread); ASSERT(error.IsNull()); - ASSERT(cls.NumOwnTypeArguments() == 1); + ASSERT(cls.NumTypeParameters() == 1); type_param ^= TypeParameter::RawCast( TypeArguments::Handle(cls.type_parameters()).TypeAt(0)); ASSERT(Pointer::kNativeTypeArgPos == type_param.index()); diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc index 817c6570637..a71b9cbee5b 100644 --- a/runtime/vm/clustered_snapshot.cc +++ b/runtime/vm/clustered_snapshot.cc @@ -182,11 +182,10 @@ class ClassSerializationCluster : public SerializationCluster { s->Write(cls->ptr()->instance_size_in_words_); s->Write(cls->ptr()->next_field_offset_in_words_); s->Write(cls->ptr()->type_arguments_field_offset_in_words_); - s->Write(cls->ptr()->num_type_arguments_); - s->Write(cls->ptr()->has_pragma_and_num_own_type_arguments_); + s->Write(cls->ptr()->num_type_arguments_); s->Write(cls->ptr()->num_native_fields_); s->WriteTokenPosition(cls->ptr()->token_pos_); - s->Write(cls->ptr()->state_bits_); + s->Write(cls->ptr()->state_bits_); } private: @@ -244,11 +243,10 @@ class ClassDeserializationCluster : public DeserializationCluster { d->Read(); // Skip. } cls->ptr()->type_arguments_field_offset_in_words_ = d->Read(); - cls->ptr()->num_type_arguments_ = d->Read(); - cls->ptr()->has_pragma_and_num_own_type_arguments_ = d->Read(); + cls->ptr()->num_type_arguments_ = d->Read(); cls->ptr()->num_native_fields_ = d->Read(); cls->ptr()->token_pos_ = d->ReadTokenPosition(); - cls->ptr()->state_bits_ = d->Read(); + cls->ptr()->state_bits_ = d->Read(); } for (intptr_t id = start_index_; id < stop_index_; id++) { @@ -271,11 +269,10 @@ class ClassDeserializationCluster : public DeserializationCluster { cls->ptr()->instance_size_in_words_ = d->Read(); cls->ptr()->next_field_offset_in_words_ = d->Read(); cls->ptr()->type_arguments_field_offset_in_words_ = d->Read(); - cls->ptr()->num_type_arguments_ = d->Read(); - cls->ptr()->has_pragma_and_num_own_type_arguments_ = d->Read(); + cls->ptr()->num_type_arguments_ = d->Read(); cls->ptr()->num_native_fields_ = d->Read(); cls->ptr()->token_pos_ = d->ReadTokenPosition(); - cls->ptr()->state_bits_ = d->Read(); + cls->ptr()->state_bits_ = d->Read(); table->AllocateIndex(class_id); table->SetAt(class_id, cls); diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc index 09d5af118f7..f914e286fb0 100644 --- a/runtime/vm/object.cc +++ b/runtime/vm/object.cc @@ -537,8 +537,6 @@ void Object::Init(Isolate* isolate) { cls.set_is_type_finalized(); cls.set_type_arguments_field_offset_in_words(Class::kNoTypeArguments); cls.set_num_type_arguments(0); - cls.set_num_own_type_arguments(0); - cls.set_has_pragma(false); cls.set_num_native_fields(0); cls.InitEmptyFields(); isolate->RegisterClass(cls); @@ -547,13 +545,11 @@ void Object::Init(Isolate* isolate) { // Allocate and initialize the null class. cls = Class::New(kNullCid); cls.set_num_type_arguments(0); - cls.set_num_own_type_arguments(0); isolate->object_store()->set_null_class(cls); // Allocate and initialize the free list element class. cls = Class::New(kFreeListElement); cls.set_num_type_arguments(0); - cls.set_num_own_type_arguments(0); cls.set_is_finalized(); cls.set_is_declaration_loaded(); cls.set_is_type_finalized(); @@ -561,7 +557,6 @@ void Object::Init(Isolate* isolate) { // Allocate and initialize the forwarding corpse class. cls = Class::New(kForwardingCorpse); cls.set_num_type_arguments(0); - cls.set_num_own_type_arguments(0); cls.set_is_finalized(); cls.set_is_declaration_loaded(); cls.set_is_type_finalized(); @@ -688,12 +683,10 @@ void Object::Init(Isolate* isolate) { isolate->object_store()->set_array_class(cls); cls.set_type_arguments_field_offset(Array::type_arguments_offset()); cls.set_num_type_arguments(1); - cls.set_num_own_type_arguments(1); cls = Class::New(kImmutableArrayCid); isolate->object_store()->set_immutable_array_class(cls); cls.set_type_arguments_field_offset(Array::type_arguments_offset()); cls.set_num_type_arguments(1); - cls.set_num_own_type_arguments(1); cls = Class::New(); isolate->object_store()->set_growable_object_array_class(cls); cls.set_type_arguments_field_offset( @@ -830,7 +823,6 @@ void Object::Init(Isolate* isolate) { cls = Class::New(kDynamicCid); cls.set_is_abstract(); cls.set_num_type_arguments(0); - cls.set_num_own_type_arguments(0); cls.set_is_finalized(); cls.set_is_declaration_loaded(); cls.set_is_type_finalized(); @@ -838,7 +830,6 @@ void Object::Init(Isolate* isolate) { cls = Class::New(kVoidCid); cls.set_num_type_arguments(0); - cls.set_num_own_type_arguments(0); cls.set_is_finalized(); cls.set_is_declaration_loaded(); cls.set_is_type_finalized(); @@ -1551,7 +1542,6 @@ RawError* Object::Init(Isolate* isolate, object_store->set_object_class(cls); cls.set_name(Symbols::Object()); cls.set_num_type_arguments(0); - cls.set_num_own_type_arguments(0); cls.set_is_prefinalized(); core_lib.AddClass(cls); pending_classes.Add(cls); @@ -1566,7 +1556,6 @@ RawError* Object::Init(Isolate* isolate, cls = Class::New(kNullCid); object_store->set_null_class(cls); cls.set_num_type_arguments(0); - cls.set_num_own_type_arguments(0); cls.set_is_prefinalized(); RegisterClass(cls, Symbols::Null(), core_lib); pending_classes.Add(cls); @@ -1649,7 +1638,6 @@ RawError* Object::Init(Isolate* isolate, object_store->set_linked_hash_map_class(cls); cls.set_type_arguments_field_offset(LinkedHashMap::type_arguments_offset()); cls.set_num_type_arguments(2); - cls.set_num_own_type_arguments(0); RegisterPrivateClass(cls, Symbols::_LinkedHashMap(), lib); pending_classes.Add(cls); @@ -1723,7 +1711,6 @@ RawError* Object::Init(Isolate* isolate, cls = Class::New(kIllegalCid); RegisterClass(cls, Symbols::Float32x4(), lib); cls.set_num_type_arguments(0); - cls.set_num_own_type_arguments(0); cls.set_is_prefinalized(); type = Type::NewNonParameterizedType(cls); object_store->set_float32x4_type(type); @@ -1736,7 +1723,6 @@ RawError* Object::Init(Isolate* isolate, cls = Class::New(kIllegalCid); RegisterClass(cls, Symbols::Int32x4(), lib); cls.set_num_type_arguments(0); - cls.set_num_own_type_arguments(0); cls.set_is_prefinalized(); type = Type::NewNonParameterizedType(cls); object_store->set_int32x4_type(type); @@ -1749,7 +1735,6 @@ RawError* Object::Init(Isolate* isolate, cls = Class::New(kIllegalCid); RegisterClass(cls, Symbols::Float64x2(), lib); cls.set_num_type_arguments(0); - cls.set_num_own_type_arguments(0); cls.set_is_prefinalized(); type = Type::NewNonParameterizedType(cls); object_store->set_float64x2_type(type); @@ -1763,7 +1748,6 @@ RawError* Object::Init(Isolate* isolate, // Note that this class is implemented by Dart class _AbstractType. cls = Class::New(kIllegalCid); cls.set_num_type_arguments(0); - cls.set_num_own_type_arguments(0); cls.set_is_prefinalized(); RegisterClass(cls, Symbols::Type(), core_lib); pending_classes.Add(cls); @@ -1773,7 +1757,6 @@ RawError* Object::Init(Isolate* isolate, // Abstract class that represents the Dart class Function. cls = Class::New(kIllegalCid); cls.set_num_type_arguments(0); - cls.set_num_own_type_arguments(0); cls.set_is_prefinalized(); RegisterClass(cls, Symbols::Function(), core_lib); pending_classes.Add(cls); @@ -1789,7 +1772,6 @@ RawError* Object::Init(Isolate* isolate, cls = Class::New(kIllegalCid); RegisterClass(cls, Symbols::Int(), core_lib); cls.set_num_type_arguments(0); - cls.set_num_own_type_arguments(0); cls.set_is_prefinalized(); pending_classes.Add(cls); type = Type::NewNonParameterizedType(cls); @@ -1798,7 +1780,6 @@ RawError* Object::Init(Isolate* isolate, cls = Class::New(kIllegalCid); RegisterClass(cls, Symbols::Double(), core_lib); cls.set_num_type_arguments(0); - cls.set_num_own_type_arguments(0); cls.set_is_prefinalized(); pending_classes.Add(cls); type = Type::NewNonParameterizedType(cls); @@ -1808,7 +1789,6 @@ RawError* Object::Init(Isolate* isolate, cls = Class::New(kIllegalCid); RegisterClass(cls, name, core_lib); cls.set_num_type_arguments(0); - cls.set_num_own_type_arguments(0); cls.set_is_prefinalized(); pending_classes.Add(cls); type = Type::NewNonParameterizedType(cls); @@ -1884,7 +1864,6 @@ RawError* Object::Init(Isolate* isolate, cls = Class::New(kFfiNativeTypeCid); cls.set_num_type_arguments(0); - cls.set_num_own_type_arguments(0); cls.set_is_prefinalized(); pending_classes.Add(cls); object_store->set_ffi_native_type_class(cls); @@ -1893,7 +1872,6 @@ RawError* Object::Init(Isolate* isolate, #define REGISTER_FFI_TYPE_MARKER(clazz) \ cls = Class::New(kFfi##clazz##Cid); \ cls.set_num_type_arguments(0); \ - cls.set_num_own_type_arguments(0); \ cls.set_is_prefinalized(); \ pending_classes.Add(cls); \ RegisterClass(cls, Symbols::Ffi##clazz(), lib); @@ -1903,7 +1881,6 @@ RawError* Object::Init(Isolate* isolate, cls = Class::New(kFfiNativeFunctionCid); cls.set_type_arguments_field_offset(Pointer::type_arguments_offset()); cls.set_num_type_arguments(1); - cls.set_num_own_type_arguments(1); cls.set_is_prefinalized(); pending_classes.Add(cls); RegisterClass(cls, Symbols::FfiNativeFunction(), lib); @@ -2307,8 +2284,6 @@ RawClass* Class::New() { COMPILE_ASSERT((FakeObject::kClassId != kInstanceCid)); result.set_id(FakeObject::kClassId); result.set_num_type_arguments(0); - result.set_num_own_type_arguments(0); - result.set_has_pragma(false); result.set_num_native_fields(0); result.set_state_bits(0); if ((FakeObject::kClassId < kInstanceCid) || @@ -2345,25 +2320,8 @@ void Class::set_num_type_arguments(intptr_t value) const { StoreNonPointer(&raw_ptr()->num_type_arguments_, value); } -void Class::set_num_own_type_arguments(intptr_t value) const { - if (!Utils::IsUint(kNumOwnTypeArgumentsSize, value)) { - ReportTooManyTypeArguments(*this); - } - StoreNonPointer( - &raw_ptr()->has_pragma_and_num_own_type_arguments_, - NumOwnTypeArguments::update( - value, raw_ptr()->has_pragma_and_num_own_type_arguments_)); -} - -void Class::set_has_pragma_and_num_own_type_arguments(uint16_t value) const { - StoreNonPointer(&raw_ptr()->has_pragma_and_num_own_type_arguments_, value); -} - void Class::set_has_pragma(bool value) const { - StoreNonPointer( - &raw_ptr()->has_pragma_and_num_own_type_arguments_, - HasPragmaBit::update(value, - raw_ptr()->has_pragma_and_num_own_type_arguments_)); + set_state_bits(HasPragmaBit::update(value, raw_ptr()->state_bits_)); } // Initialize class fields of type Array with empty array. @@ -2613,7 +2571,7 @@ void Class::set_signature_function(const Function& value) const { } void Class::set_state_bits(intptr_t bits) const { - StoreNonPointer(&raw_ptr()->state_bits_, static_cast(bits)); + StoreNonPointer(&raw_ptr()->state_bits_, static_cast(bits)); } void Class::set_library(const Library& value) const { @@ -2621,8 +2579,6 @@ void Class::set_library(const Library& value) const { } void Class::set_type_parameters(const TypeArguments& value) const { - ASSERT((num_own_type_arguments() == kUnknownNumTypeArguments) || - is_prefinalized()); ASSERT((num_type_arguments() == kUnknownNumTypeArguments) || is_prefinalized()); StorePointer(&raw_ptr()->type_parameters_, value.raw()); @@ -2643,39 +2599,45 @@ intptr_t Class::NumTypeParameters(Thread* thread) const { return type_params.Length(); } -intptr_t Class::NumOwnTypeArguments() const { - // Return cached value if already calculated. - if (num_own_type_arguments() != kUnknownNumTypeArguments) { - return num_own_type_arguments(); - } +intptr_t Class::ComputeNumTypeArguments() const { + ASSERT(is_declaration_loaded()); Thread* thread = Thread::Current(); - Isolate* isolate = thread->isolate(); Zone* zone = thread->zone(); + Isolate* isolate = thread->isolate(); const intptr_t num_type_params = NumTypeParameters(); - if ((num_type_params == 0) || (super_type() == AbstractType::null()) || + + if ((super_type() == AbstractType::null()) || (super_type() == isolate->object_store()->object_type())) { - set_num_own_type_arguments(num_type_params); return num_type_params; } - const AbstractType& sup_type = AbstractType::Handle(zone, super_type()); - const TypeArguments& sup_type_args = - TypeArguments::Handle(zone, sup_type.arguments()); + + const auto& sup_type = AbstractType::Handle(zone, super_type()); + ASSERT(sup_type.IsType()); + + const auto& sup_class = Class::Handle(zone, sup_type.type_class()); + ASSERT(!sup_class.IsTypedefClass()); + + const intptr_t sup_class_num_type_args = sup_class.NumTypeArguments(); + if (num_type_params == 0) { + return sup_class_num_type_args; + } + + const auto& sup_type_args = TypeArguments::Handle(zone, sup_type.arguments()); if (sup_type_args.IsNull()) { // The super type is raw or the super class is non generic. // In either case, overlapping is not possible. - set_num_own_type_arguments(num_type_params); - return num_type_params; + return sup_class_num_type_args + num_type_params; } - const intptr_t num_sup_type_args = sup_type_args.Length(); + + const intptr_t sup_type_args_length = sup_type_args.Length(); // At this point, the super type may or may not be finalized. In either case, // the result of this function must remain the same. // The value of num_sup_type_args may increase when the super type is - // finalized, but the last num_sup_type_args type arguments will not be + // finalized, but the last [sup_type_args_length] type arguments will not be // modified by finalization, only shifted to higher indices in the vector. // The super type may not even be resolved yet. This is not necessary, since // we only check for matching type parameters, which are resolved by default. - const TypeArguments& type_params = - TypeArguments::Handle(zone, type_parameters()); + const auto& type_params = TypeArguments::Handle(zone, type_parameters()); // Determine the maximum overlap of a prefix of the vector consisting of the // type parameters of this class with a suffix of the vector consisting of the // type arguments of the super type of this class. @@ -2684,58 +2646,38 @@ intptr_t Class::NumOwnTypeArguments() const { // Attempt to overlap the whole vector of type parameters; reduce the size // of the vector (keeping the first type parameter) until it fits or until // its size is zero. - TypeParameter& type_param = TypeParameter::Handle(zone); - AbstractType& sup_type_arg = AbstractType::Handle(zone); + auto& type_param = TypeParameter::Handle(zone); + auto& sup_type_arg = AbstractType::Handle(zone); for (intptr_t num_overlapping_type_args = - (num_type_params < num_sup_type_args) ? num_type_params - : num_sup_type_args; + (num_type_params < sup_type_args_length) ? num_type_params + : sup_type_args_length; num_overlapping_type_args > 0; num_overlapping_type_args--) { intptr_t i = 0; for (; i < num_overlapping_type_args; i++) { type_param ^= type_params.TypeAt(i); - sup_type_arg = sup_type_args.TypeAt(num_sup_type_args - + sup_type_arg = sup_type_args.TypeAt(sup_type_args_length - num_overlapping_type_args + i); if (!type_param.Equals(sup_type_arg)) break; } if (i == num_overlapping_type_args) { // Overlap found. - set_num_own_type_arguments(num_type_params - num_overlapping_type_args); - return num_type_params - num_overlapping_type_args; + return sup_class_num_type_args + num_type_params - + num_overlapping_type_args; } } // No overlap found. - set_num_own_type_arguments(num_type_params); - return num_type_params; + return sup_class_num_type_args + num_type_params; } intptr_t Class::NumTypeArguments() const { // Return cached value if already calculated. - if (num_type_arguments() != kUnknownNumTypeArguments) { - return num_type_arguments(); + intptr_t num_type_args = num_type_arguments(); + if (num_type_args != kUnknownNumTypeArguments) { + return num_type_args; } - // To work properly, this call requires the super class of this class to be - // resolved, which is checked by the type_class() call on the super type. - Thread* thread = Thread::Current(); - Zone* zone = thread->zone(); - Isolate* isolate = thread->isolate(); - Class& cls = Class::Handle(zone); - AbstractType& sup_type = AbstractType::Handle(zone); - cls = raw(); - intptr_t num_type_args = 0; - do { - num_type_args += cls.NumOwnTypeArguments(); - // Super type of Object class is null. - if ((cls.super_type() == AbstractType::null()) || - (cls.super_type() == isolate->object_store()->object_type())) { - break; - } - sup_type = cls.super_type(); - // A TypeRef or function type can appear as type argument of - // sup_type, but not as sup_type itself. - ASSERT(sup_type.IsType()); - cls = sup_type.type_class(); - ASSERT(!cls.IsTypedefClass()); - } while (true); + + num_type_args = ComputeNumTypeArguments(); + ASSERT(num_type_args != kUnknownNumTypeArguments); set_num_type_arguments(num_type_args); return num_type_args; } @@ -3693,8 +3635,6 @@ RawClass* Class::NewCommon(intptr_t index) { result.set_next_field_offset(FakeInstance::NextFieldOffset()); result.set_id(index); result.set_num_type_arguments(kUnknownNumTypeArguments); - result.set_num_own_type_arguments(kUnknownNumTypeArguments); - result.set_has_pragma(false); result.set_num_native_fields(0); result.set_state_bits(0); result.InitEmptyFields(); diff --git a/runtime/vm/object.h b/runtime/vm/object.h index f0343a3c2c9..33261dad677 100644 --- a/runtime/vm/object.h +++ b/runtime/vm/object.h @@ -916,10 +916,6 @@ class Class : public Object { // the super class. intptr_t NumTypeArguments() const; - // Return the number of type arguments that are specific to this class, i.e. - // not overlapping with the type arguments of the super class of this class. - intptr_t NumOwnTypeArguments() const; - // Return true if this class declares type parameters. bool IsGeneric() const { return NumTypeParameters(Thread::Current()) > 0; } @@ -1353,28 +1349,30 @@ class Class : public Object { kTransformedMixinApplicationBit, kIsAllocatedBit, kIsLoadedBit, + kHasPragmaBit, }; - class ConstBit : public BitField {}; - class ImplementedBit : public BitField {}; - class ClassFinalizedBits : public BitField {}; + class ImplementedBit : public BitField {}; + class ClassFinalizedBits : public BitField {}; - class ClassLoadingBits : public BitField {}; - class AbstractBit : public BitField {}; - class PatchBit : public BitField {}; + class AbstractBit : public BitField {}; + class PatchBit : public BitField {}; class SynthesizedClassBit - : public BitField {}; + : public BitField {}; class FieldsMarkedNullableBit - : public BitField {}; - class EnumBit : public BitField {}; + : public BitField {}; + class EnumBit : public BitField {}; class TransformedMixinApplicationBit - : public BitField {}; - class IsAllocatedBit : public BitField {}; - class IsLoadedBit : public BitField {}; + : public BitField {}; + class IsAllocatedBit : public BitField {}; + class IsLoadedBit : public BitField {}; + class HasPragmaBit : public BitField {}; void set_name(const String& value) const; void set_user_name(const String& value) const; @@ -1392,40 +1390,23 @@ class Class : public Object { // functions_hash_table is in use iff there are at least this many functions. static const intptr_t kFunctionLookupHashTreshold = 16; - enum HasPragmaAndNumOwnTypeArgumentsBits { - kHasPragmaBit = 0, - kNumOwnTypeArgumentsPos = 1, - kNumOwnTypeArgumentsSize = 15 - }; - - class HasPragmaBit : public BitField {}; - class NumOwnTypeArguments : public BitField {}; - // Initial value for the cached number of type arguments. - static const intptr_t kUnknownNumTypeArguments = - (1U << kNumOwnTypeArgumentsSize) - 1; + static const intptr_t kUnknownNumTypeArguments = -1; int16_t num_type_arguments() const { return raw_ptr()->num_type_arguments_; } void set_num_type_arguments(intptr_t value) const; public: bool has_pragma() const { - return HasPragmaBit::decode( - raw_ptr()->has_pragma_and_num_own_type_arguments_); + return HasPragmaBit::decode(raw_ptr()->state_bits_); } void set_has_pragma(bool has_pragma) const; private: - uint16_t num_own_type_arguments() const { - return NumOwnTypeArguments::decode( - raw_ptr()->has_pragma_and_num_own_type_arguments_); - } - void set_num_own_type_arguments(intptr_t value) const; - - void set_has_pragma_and_num_own_type_arguments(uint16_t value) const; + // Calculates number of type arguments of this class. + // This includes type arguments of a superclass and takes overlapping + // of type arguments into account. + intptr_t ComputeNumTypeArguments() const; // Assigns empty array to all raw class array fields. void InitEmptyFields(); diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h index a554d7d337a..1028af12ddf 100644 --- a/runtime/vm/raw_object.h +++ b/runtime/vm/raw_object.h @@ -805,13 +805,8 @@ class RawClass : public RawObject { int32_t next_field_offset_in_words_; // Offset of the next instance field. classid_t id_; // Class Id, also index in the class table. int16_t num_type_arguments_; // Number of type arguments in flattened vector. - - // Bitfields with number of non-overlapping type arguments and 'has_pragma' - // bit. - uint16_t has_pragma_and_num_own_type_arguments_; - uint16_t num_native_fields_; - uint16_t state_bits_; + uint32_t state_bits_; NOT_IN_PRECOMPILED(intptr_t kernel_offset_); friend class Instance;