Index: runtime/vm/object.h |
diff --git a/runtime/vm/object.h b/runtime/vm/object.h |
index e51b26f61adb7f785290aef0918e934b91f62dcb..6322276ddd530d66bed5ec5ce31385868d67555f 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. |
@@ -1454,8 +1454,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 +1519,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 +1564,10 @@ 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 that we consistently use a |
+ // 32bit Smi representation for the hash code on all architectures. |
+ static const intptr_t kHashBits = 30; |
Cutch
2016/05/16 17:01:57
should this constant `kHashBits` sit somewhere hig
rmacnak
2016/05/16 19:37:02
"so that we consistently use a 32bit Smi represent
siva
2016/05/16 23:24:25
Done.
siva
2016/05/16 23:24:25
I am thinking it is specific to hashes in classes
|
+ |
intptr_t Length() const; |
RawAbstractType* TypeAt(intptr_t index) const; |
static intptr_t type_at_offset(intptr_t index) { |
@@ -1717,8 +1712,8 @@ 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) + (3 * kWordSize))); |
Cutch
2016/05/16 17:01:57
Should this "3" be a named constant with an ASSERT
siva
2016/05/16 23:24:25
made a named constant, the ASSERT captures any iss
|
ASSERT(0 <= len && len <= kMaxElements); |
return RoundedAllocationSize( |
sizeof(RawTypeArguments) + (len * kBytesPerElement)); |
@@ -1729,6 +1724,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 |
@@ -5570,6 +5568,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 +5687,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 +5780,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 +5845,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 +5868,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 +5937,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 +7134,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 +7505,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 +8555,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; |
regis
2016/05/16 20:17:48
Thinking aloud here. Is it OK to return 0? 0 means
siva
2016/05/16 23:24:25
Acknowledged.
|
+ 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_ |