Index: runtime/vm/object.cc |
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc |
index 62844ac892779b7ad81664024b61fa86d0e9c57b..45320b5eeb7de108d60b244d9b478641cf2061fe 100644 |
--- a/runtime/vm/object.cc |
+++ b/runtime/vm/object.cc |
@@ -3757,7 +3757,7 @@ RawType* Class::canonical_type() const { |
void Class::set_canonical_type(const Type& value) const { |
- ASSERT(!value.IsNull()); |
+ ASSERT(!value.IsNull() && value.IsCanonical() && value.IsOld()); |
StorePointer(&raw_ptr()->canonical_type_, value.raw()); |
} |
@@ -17522,13 +17522,12 @@ RawAbstractType* Type::Canonicalize(TrailPtr trail) const { |
return Object::dynamic_type().raw(); |
} |
- AbstractType& type = Type::Handle(zone); |
const Class& cls = Class::Handle(zone, type_class()); |
// Fast canonical lookup/registry for simple types. |
if (!cls.IsGeneric() && !cls.IsClosureClass() && !cls.IsTypedefClass()) { |
ASSERT(!IsFunctionType()); |
- type = cls.CanonicalType(); |
+ Type& type = Type::Handle(zone, cls.CanonicalType()); |
if (type.IsNull()) { |
ASSERT(!cls.raw()->IsVMHeapObject() || (isolate == Dart::vm_isolate())); |
// Canonicalize the type arguments of the supertype, if any. |
@@ -17546,18 +17545,26 @@ RawAbstractType* Type::Canonicalize(TrailPtr trail) const { |
// Recheck if type exists. |
type = cls.CanonicalType(); |
if (type.IsNull()) { |
- ComputeHash(); |
- SetCanonical(); |
- cls.set_canonical_type(*this); |
- return this->raw(); |
+ if (this->IsNew()) { |
+ type ^= Object::Clone(*this, Heap::kOld); |
+ } else { |
+ type ^= this->raw(); |
+ } |
+ ASSERT(type.IsOld()); |
+ type.ComputeHash(); |
+ type.SetCanonical(); |
+ cls.set_canonical_type(type); |
+ return type.raw(); |
} |
} |
} |
ASSERT(this->Equals(type)); |
ASSERT(type.IsCanonical()); |
+ ASSERT(type.IsOld()); |
return type.raw(); |
} |
+ AbstractType& type = Type::Handle(zone); |
ObjectStore* object_store = isolate->object_store(); |
{ |
SafepointMutexLocker ml(isolate->type_canonicalization_mutex()); |