Bug 1194627 - Change group when sweeping preliminary objects to avoid leaking their slots. r=bhackett
authorJan de Mooij <jdemooij@mozilla.com>
Sat, 15 Aug 2015 19:27:16 +0200
changeset 257956 ca20318c36272e2060bd94894a82807cc6db216b
parent 257955 f8dd6bbde6ce8165f752aa4edfe2abaa40edf8be
child 257957 9b34691fd5cda4be9ad9674a0883f51de2198d69
push id29238
push userryanvm@gmail.com
push dateMon, 17 Aug 2015 13:06:57 +0000
treeherdermozilla-central@a6eeb28458fd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbhackett
bugs1194627
milestone43.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1194627 - Change group when sweeping preliminary objects to avoid leaking their slots. r=bhackett
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");