Bug 1194627 - Change group when sweeping preliminary objects to avoid leaking their slots. r=bhackett a=ritu
authorJan de Mooij <jdemooij@mozilla.com>
Sat, 15 Aug 2015 19:27:16 +0200
changeset 288801 0007d7e6e8ab23b6eb33c463d8e43697fe109e28
parent 288800 aea52aa8c59acb5b63c27961d5e44029c11f301d
child 288802 2867fa5b43d6bc4976a3bbf966c2c16dc6ffbd37
push id5067
push userraliiev@mozilla.com
push dateMon, 21 Sep 2015 14:04:52 +0000
treeherdermozilla-beta@14221ffe5b2f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbhackett, ritu
bugs1194627
milestone42.0a2
Bug 1194627 - Change group when sweeping preliminary objects to avoid leaking their slots. r=bhackett a=ritu
js/src/vm/TypeInference.cpp
--- a/js/src/vm/TypeInference.cpp
+++ b/js/src/vm/TypeInference.cpp
@@ -3334,18 +3334,35 @@ PreliminaryObjectArray::empty() const
 
 void
 PreliminaryObjectArray::sweep()
 {
     // All objects in the array are weak, so clear any that are about to be
     // destroyed.
     for (size_t i = 0; i < COUNT; i++) {
         JSObject** ptr = &objects[i];
-        if (*ptr && IsAboutToBeFinalizedUnbarriered(ptr))
+        if (*ptr && IsAboutToBeFinalizedUnbarriered(ptr)) {
+            // Before we clear this reference, change the object's group to the
+            // Object.prototype group. This is done to ensure JSObject::finalize
+            // sees a NativeObject Class even if we change the current group's
+            // Class to one of the unboxed object classes in the meantime. If
+            // the compartment's global is dead, we don't do anything as the
+            // group's Class is not going to change in that case.
+            JSObject* obj = *ptr;
+            GlobalObject* global = obj->compartment()->maybeGlobal();
+            if (global && !obj->isSingleton()) {
+                JSObject* objectProto = GetBuiltinPrototypePure(global, JSProto_Object);
+                obj->setGroup(objectProto->groupRaw());
+                MOZ_ASSERT(obj->is<NativeObject>());
+                MOZ_ASSERT(obj->getClass() == objectProto->getClass());
+                MOZ_ASSERT(!obj->getClass()->finalize);
+            }
+
             *ptr = nullptr;
+        }
     }
 }
 
 void
 PreliminaryObjectArrayWithTemplate::trace(JSTracer* trc)
 {
     if (shape_)
         TraceEdge(trc, &shape_, "PreliminaryObjectArrayWithTemplate_shape");