Index: runtime/vm/object.h |
diff --git a/runtime/vm/object.h b/runtime/vm/object.h |
index e51b26f61adb7f785290aef0918e934b91f62dcb..755d9b524869321dd5b598be47bb8a03619ab447 100644 |
--- a/runtime/vm/object.h |
+++ b/runtime/vm/object.h |
@@ -1051,8 +1051,8 @@ class Class : public Object { |
// Caches the canonical type of this class. |
void SetCanonicalType(const Type& type) const; |
- static intptr_t canonical_types_offset() { |
- return OFFSET_OF(RawClass, canonical_types_); |
+ static intptr_t canonical_type_offset() { |
+ return OFFSET_OF(RawClass, canonical_type_); |
} |
// The super type of this class, Object type if not explicitly specified. |
@@ -1221,9 +1221,6 @@ class Class : public Object { |
intptr_t index, |
const Number& constant) const; |
- intptr_t FindCanonicalTypeIndex(const AbstractType& needle) const; |
- RawAbstractType* CanonicalTypeFromIndex(intptr_t idx) const; |
- |
void RehashConstants(Zone* zone) const; |
static intptr_t InstanceSize() { |
@@ -1454,8 +1451,8 @@ class Class : public Object { |
void set_constants(const Array& value) const; |
- void set_canonical_types(const Object& value) const; |
- RawObject* canonical_types() const; |
+ void set_canonical_type(const Type& value) const; |
+ RawType* canonical_type() const; |
RawArray* invocation_dispatcher_cache() const; |
void set_invocation_dispatcher_cache(const Array& cache) const; |
@@ -1519,15 +1516,6 @@ class Class : public Object { |
TrailPtr bound_trail, |
Heap::Space space); |
- // Returns AbstractType::null() if type not found. |
- RawAbstractType* LookupCanonicalType(Zone* zone, |
- const AbstractType& type, |
- intptr_t* index) const; |
- |
- // Returns canonical type. Thread safe. |
- RawAbstractType* LookupOrAddCanonicalType(const AbstractType& type, |
- intptr_t start_index) const; |
- |
FINAL_HEAP_OBJECT_IMPLEMENTATION(Class, Object); |
friend class AbstractType; |
friend class Instance; |
@@ -1573,6 +1561,11 @@ class UnresolvedClass : public Object { |
// A TypeArguments is an array of AbstractType. |
class TypeArguments : public Object { |
public: |
+ // We use 30 bits for the hash code so hashes in a snapshot taken on a |
+ // 64-bit architecture stay in Smi range when loaded on a 32-bit |
+ // architecture. |
+ static const intptr_t kHashBits = 30; |
+ |
intptr_t Length() const; |
RawAbstractType* TypeAt(intptr_t index) const; |
static intptr_t type_at_offset(intptr_t index) { |
@@ -1717,8 +1710,9 @@ class TypeArguments : public Object { |
static intptr_t InstanceSize(intptr_t len) { |
// Ensure that the types() is not adding to the object size, which includes |
- // 2 fields: instantiations_ and length_. |
- ASSERT(sizeof(RawTypeArguments) == (sizeof(RawObject) + (2 * kWordSize))); |
+ // 3 fields: instantiations_, length_ and hash_. |
+ ASSERT(sizeof(RawTypeArguments) == |
+ (sizeof(RawObject) + (kNumFields * kWordSize))); |
ASSERT(0 <= len && len <= kMaxElements); |
return RoundedAllocationSize( |
sizeof(RawTypeArguments) + (len * kBytesPerElement)); |
@@ -1729,6 +1723,9 @@ class TypeArguments : public Object { |
static RawTypeArguments* New(intptr_t len, Heap::Space space = Heap::kOld); |
private: |
+ intptr_t ComputeHash() const; |
+ void SetHash(intptr_t value) const; |
+ |
// Check if the subvector of length 'len' starting at 'from_index' of this |
// type argument vector consists solely of DynamicType. |
// If raw_instantiated is true, consider each type parameter to be first |
@@ -1757,6 +1754,8 @@ class TypeArguments : public Object { |
void set_instantiations(const Array& value) const; |
RawAbstractType* const* TypeAddr(intptr_t index) const; |
void SetLength(intptr_t value) const; |
+ // Number of fields in the raw object=3 (instantiations_, length_ and hash_). |
+ static const int kNumFields = 3; |
FINAL_HEAP_OBJECT_IMPLEMENTATION(TypeArguments, Object); |
friend class AbstractType; |
@@ -5570,6 +5569,10 @@ class AbstractType : public Instance { |
// relate to a 'raw type', as opposed to a 'cooked type' or 'rare type'. |
class Type : public AbstractType { |
public: |
+ // We use 30 bits for the hash code so that we consistently use a |
+ // 32bit Smi representation for the hash code on all architectures. |
+ static const intptr_t kHashBits = 30; |
+ |
static intptr_t type_class_offset() { |
return OFFSET_OF(RawType, type_class_); |
} |
@@ -5685,6 +5688,9 @@ class Type : public AbstractType { |
Heap::Space space = Heap::kOld); |
private: |
+ intptr_t ComputeHash() const; |
+ void SetHash(intptr_t value) const; |
+ |
void set_token_pos(TokenPosition token_pos) const; |
void set_type_state(int8_t state) const; |
@@ -5775,6 +5781,10 @@ class TypeRef : public AbstractType { |
// to the ObjectType. |
class TypeParameter : public AbstractType { |
public: |
+ // We use 30 bits for the hash code so that we consistently use a |
+ // 32bit Smi representation for the hash code on all architectures. |
+ static const intptr_t kHashBits = 30; |
+ |
virtual bool IsFinalized() const { |
ASSERT(raw_ptr()->type_state_ != RawTypeParameter::kFinalizedInstantiated); |
return raw_ptr()->type_state_ == RawTypeParameter::kFinalizedUninstantiated; |
@@ -5836,6 +5846,9 @@ class TypeParameter : public AbstractType { |
TokenPosition token_pos); |
private: |
+ intptr_t ComputeHash() const; |
+ void SetHash(intptr_t value) const; |
+ |
void set_parameterized_class(const Class& value) const; |
void set_name(const String& value) const; |
void set_token_pos(TokenPosition token_pos) const; |
@@ -5856,6 +5869,10 @@ class TypeParameter : public AbstractType { |
// mode is known to be checked mode. |
class BoundedType : public AbstractType { |
public: |
+ // We use 30 bits for the hash code so that we consistently use a |
+ // 32bit Smi representation for the hash code on all architectures. |
+ static const intptr_t kHashBits = 30; |
+ |
virtual bool IsFinalized() const { |
return AbstractType::Handle(type()).IsFinalized(); |
} |
@@ -5921,6 +5938,9 @@ class BoundedType : public AbstractType { |
const TypeParameter& type_parameter); |
private: |
+ intptr_t ComputeHash() const; |
+ void SetHash(intptr_t value) const; |
+ |
void set_type(const AbstractType& value) const; |
void set_bound(const AbstractType& value) const; |
void set_type_parameter(const TypeParameter& value) const; |
@@ -7115,6 +7135,10 @@ class Bool : public Instance { |
class Array : public Instance { |
public: |
+ // We use 30 bits for the hash code so that we consistently use a |
+ // 32bit Smi representation for the hash code on all architectures. |
+ static const intptr_t kHashBits = 30; |
+ |
intptr_t Length() const { |
ASSERT(!IsNull()); |
return Smi::Value(raw_ptr()->length_); |
@@ -7482,6 +7506,10 @@ class Float64x2 : public Instance { |
class TypedData : public Instance { |
public: |
+ // We use 30 bits for the hash code so that we consistently use a |
+ // 32bit Smi representation for the hash code on all architectures. |
+ static const intptr_t kHashBits = 30; |
+ |
intptr_t Length() const { |
ASSERT(!IsNull()); |
return Smi::Value(raw_ptr()->length_); |
@@ -8528,6 +8556,72 @@ RawObject* MegamorphicCache::GetTargetFunction(const Array& array, |
return array.At((index * kEntryLength) + kTargetFunctionIndex); |
} |
+ |
+inline intptr_t Type::Hash() const { |
+ intptr_t result = Smi::Value(raw_ptr()->hash_); |
+ if (result != 0) { |
+ return result; |
+ } |
+ return ComputeHash(); |
+} |
+ |
+ |
+inline void Type::SetHash(intptr_t value) const { |
+ // This is only safe because we create a new Smi, which does not cause |
+ // heap allocation. |
+ StoreSmi(&raw_ptr()->hash_, Smi::New(value)); |
+} |
+ |
+ |
+inline intptr_t TypeParameter::Hash() const { |
+ ASSERT(IsFinalized()); |
+ intptr_t result = Smi::Value(raw_ptr()->hash_); |
+ if (result != 0) { |
+ return result; |
+ } |
+ return ComputeHash(); |
+} |
+ |
+ |
+inline void TypeParameter::SetHash(intptr_t value) const { |
+ // This is only safe because we create a new Smi, which does not cause |
+ // heap allocation. |
+ StoreSmi(&raw_ptr()->hash_, Smi::New(value)); |
+} |
+ |
+ |
+inline intptr_t BoundedType::Hash() const { |
+ intptr_t result = Smi::Value(raw_ptr()->hash_); |
+ if (result != 0) { |
+ return result; |
+ } |
+ return ComputeHash(); |
+} |
+ |
+ |
+inline void BoundedType::SetHash(intptr_t value) const { |
+ // This is only safe because we create a new Smi, which does not cause |
+ // heap allocation. |
+ StoreSmi(&raw_ptr()->hash_, Smi::New(value)); |
+} |
+ |
+ |
+inline intptr_t TypeArguments::Hash() const { |
+ if (IsNull()) return 0; |
+ intptr_t result = Smi::Value(raw_ptr()->hash_); |
+ if (result != 0) { |
+ return result; |
+ } |
+ return ComputeHash(); |
+} |
+ |
+ |
+inline void TypeArguments::SetHash(intptr_t value) const { |
+ // This is only safe because we create a new Smi, which does not cause |
+ // heap allocation. |
+ StoreSmi(&raw_ptr()->hash_, Smi::New(value)); |
+} |
+ |
} // namespace dart |
#endif // VM_OBJECT_H_ |