Index: runtime/vm/object.cc |
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc |
index ff4d497e028904dd7478c0b7ddcf670d2f81de9c..8cc2cc2d0321ccfd0b80f81075b1d904a0663a3c 100644 |
--- a/runtime/vm/object.cc |
+++ b/runtime/vm/object.cc |
@@ -14455,9 +14455,12 @@ RawInstance* Instance::CheckAndCanonicalize(const char** error_str) const { |
if (!CheckAndCanonicalizeFields(error_str)) { |
return Instance::null(); |
} |
- Instance& result = Instance::Handle(); |
- const Class& cls = Class::Handle(this->clazz()); |
- Array& constants = Array::Handle(cls.constants()); |
+ Thread* thread = Thread::Current(); |
+ Zone* zone = thread->zone(); |
+ Isolate* isolate = thread->isolate(); |
+ Instance& result = Instance::Handle(zone); |
+ const Class& cls = Class::Handle(zone, this->clazz()); |
+ Array& constants = Array::Handle(zone, cls.constants()); |
const intptr_t constants_len = constants.Length(); |
// Linear search to see whether this value is already present in the |
// list of canonicalized constants. |
@@ -14476,7 +14479,23 @@ RawInstance* Instance::CheckAndCanonicalize(const char** error_str) const { |
// The value needs to be added to the list. Grow the list if |
// it is full. |
result ^= this->raw(); |
- if (result.IsNew()) { |
+ if (result.IsNew() || |
+ (result.InVMHeap() && (isolate != Dart::vm_isolate()))) { |
+ /** |
+ * When a snapshot is generated on a 64 bit architecture and then read |
+ * into a 32 bit architecture, values which are Smi on the 64 bit |
+ * architecture could potentially be converted to Mint objects, however |
+ * since Smi values do not have any notion of canonical bits we lose |
+ * that information when the object becomes a Mint. |
+ * Some of these values could be literal values and end up in the |
+ * VM isolate heap. Later when these values are referenced in a |
+ * constant list we try to ensure that all the objects in the list |
+ * are canonical and try to canonicalize them. When these Mint objects |
+ * are encountered they do not have the canonical bit set and |
+ * canonicalizing them won't work as the VM heap is read only now. |
+ * In these cases we clone the object into the isolate and then |
+ * canonicalize it. |
+ */ |
// Create a canonical object in old space. |
result ^= Object::Clone(result, Heap::kOld); |
} |