Chromium Code Reviews| Index: runtime/vm/precompiler.cc |
| diff --git a/runtime/vm/precompiler.cc b/runtime/vm/precompiler.cc |
| index 59af6d4d233845ac40c0973730cbfe8a0dec0fa6..a885508499a0f0c5e6eb391377c69b5f4d237261 100644 |
| --- a/runtime/vm/precompiler.cc |
| +++ b/runtime/vm/precompiler.cc |
| @@ -2553,6 +2553,7 @@ void Precompiler::SortClasses() { |
| RemapClassIds(old_to_new_cid); |
| delete[] old_to_new_cid; |
| + RehashTypes(); // Types use cid's as part of their hashes. |
| } |
| @@ -2627,6 +2628,101 @@ void Precompiler::RemapClassIds(intptr_t* old_to_new_cid) { |
| } |
| +class ClearTypeHashVisitor : public ObjectVisitor { |
| + public: |
| + explicit ClearTypeHashVisitor(Zone* zone) |
| + : type_param_(TypeParameter::Handle(zone)), |
| + type_(Type::Handle(zone)), |
| + type_args_(TypeArguments::Handle(zone)), |
| + bounded_type_(BoundedType::Handle(zone)) {} |
| + |
| + void VisitObject(RawObject* obj) { |
| + if (obj->IsTypeParameter()) { |
| + type_param_ ^= obj; |
| + type_param_.SetHash(0); |
| + } else if (obj->IsType()) { |
| + type_ ^= obj; |
| + type_.SetHash(0); |
| + } else if (obj->IsBoundedType()) { |
| + bounded_type_ ^= obj; |
| + bounded_type_.SetHash(0); |
| + } else if (obj->IsTypeArguments()) { |
| + type_args_ ^= obj; |
| + type_args_.SetHash(0); |
| + } |
|
siva
2017/01/20 18:37:02
Should we also be clearing the hash value for IsMi
regis
2017/01/20 19:21:59
As soon as the super type of a class is resolved,
rmacnak
2017/01/20 20:13:12
Removed hash_ from RawMixinAppType
|
| + } |
| + |
| + private: |
| + TypeParameter& type_param_; |
| + Type& type_; |
| + TypeArguments& type_args_; |
| + BoundedType& bounded_type_; |
| +}; |
| + |
| + |
| +void Precompiler::RehashTypes() { |
| + // Clear all cached hash values. |
| + { |
| + HeapIterationScope his; |
| + ClearTypeHashVisitor visitor(Z); |
| + I->heap()->VisitObjects(&visitor); |
| + } |
| + |
| + // Rehash the canonical Types table. |
| + ObjectStore* object_store = I->object_store(); |
| + GrowableObjectArray& types = |
| + GrowableObjectArray::Handle(Z, GrowableObjectArray::New()); |
| + Array& types_array = Array::Handle(Z); |
| + Type& type = Type::Handle(Z); |
| + { |
| + CanonicalTypeSet types_table(Z, object_store->canonical_types()); |
| + types_array = HashTables::ToArray(types_table, false); |
| + for (intptr_t i = 0; i < (types_array.Length() - 1); i++) { |
| + type ^= types_array.At(i); |
| + types.Add(type); |
| + } |
| + types_table.Release(); |
| + } |
| + |
| + intptr_t dict_size = Utils::RoundUpToPowerOfTwo(types.Length() * 4 / 3); |
| + types_array = HashTables::New<CanonicalTypeSet>(dict_size, Heap::kOld); |
| + CanonicalTypeSet types_table(Z, types_array.raw()); |
| + for (intptr_t i = 0; i < types.Length(); i++) { |
| + type ^= types.At(i); |
| + bool present = types_table.Insert(type); |
| + ASSERT(!present); |
| + } |
| + object_store->set_canonical_types(types_table.Release()); |
| + |
| + // Rehash the canonical TypeArguments table. |
| + Array& typeargs_array = Array::Handle(Z); |
| + GrowableObjectArray& typeargs = |
| + GrowableObjectArray::Handle(Z, GrowableObjectArray::New()); |
| + TypeArguments& typearg = TypeArguments::Handle(Z); |
| + { |
| + CanonicalTypeArgumentsSet typeargs_table( |
| + Z, object_store->canonical_type_arguments()); |
| + typeargs_array = HashTables::ToArray(typeargs_table, false); |
| + for (intptr_t i = 0; i < (typeargs_array.Length() - 1); i++) { |
| + typearg ^= typeargs_array.At(i); |
| + typeargs.Add(typearg); |
| + } |
| + typeargs_table.Release(); |
| + } |
| + |
| + dict_size = Utils::RoundUpToPowerOfTwo(typeargs.Length() * 4 / 3); |
| + typeargs_array = |
| + HashTables::New<CanonicalTypeArgumentsSet>(dict_size, Heap::kOld); |
| + CanonicalTypeArgumentsSet typeargs_table(Z, typeargs_array.raw()); |
| + for (intptr_t i = 0; i < typeargs.Length(); i++) { |
| + typearg ^= typeargs.At(i); |
| + bool present = typeargs_table.Insert(typearg); |
| + ASSERT(!present); |
| + } |
| + object_store->set_canonical_type_arguments(typeargs_table.Release()); |
| +} |
| + |
| + |
| void Precompiler::VerifyJITFeedback() { |
| if (jit_feedback_ == NULL) return; |