Bug 1108007 - Don't allow GC to observe uninitialized elements in cloned array. r=nbp, a=sledru
authorJon Coppeard <jcoppeard@mozilla.com>
Fri, 23 Jan 2015 11:30:40 +0000
changeset 243035 a160dd7b5dda
parent 243034 ea3b10634381
child 243036 228ee06444b5
push id4370
push userryanvm@gmail.com
push date2015-01-26 15:57 +0000
treeherdermozilla-beta@bf8644a5c52a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnbp, sledru
bugs1108007
milestone36.0
Bug 1108007 - Don't allow GC to observe uninitialized elements in cloned array. r=nbp, a=sledru
js/src/jit-test/tests/gc/bug-1108007.js
js/src/jsobj.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/gc/bug-1108007.js
@@ -0,0 +1,24 @@
+// |jit-test| --no-threads; --no-ion; --no-baseline
+if (!("gczeal" in this))
+    quit();
+gczeal(2);
+(function() {
+    evaluate(cacheEntry((function() {
+        return "".toSource()
+    })()), Object.create({}, {
+        saveBytecode: {
+            value: true
+        }
+    }))
+})();
+[[0], [0], [0], [0], [0], [0], [0], [0], [0], [0],
+ [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], 
+ [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], 
+ [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], 
+ [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], 
+ [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], 
+ [0], [0], [0], [0], [0], [0], [0], [0], [0], [0],
+ [0], [0], [0], [0], [0], [0], [0], [0], [0], [0],
+ [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], 
+ [0], [0], [0], [0], [0], [0], [0], [0], [0], [0], 
+ [0], [0], [0], [0]];
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -2013,33 +2013,30 @@ js::DeepCloneObjectLiteral(JSContext *cx
                                               TaggedProto(typeObj->proto().toObject()),
                                               parent, kind, newKind);
     }
 
     // Allocate the same number of slots.
     if (!clone || !clone->ensureElements(cx, obj->getDenseCapacity()))
         return nullptr;
 
-    // Copy the number of initialized elements.
+    // Recursive copy of dense element.
     uint32_t initialized = obj->getDenseInitializedLength();
-    if (initialized)
-        clone->setDenseInitializedLength(initialized);
-
-    // Recursive copy of dense element.
     for (uint32_t i = 0; i < initialized; ++i) {
         v = obj->getDenseElement(i);
         if (v.isObject()) {
             deepObj = &v.toObject().as<NativeObject>();
             deepObj = js::DeepCloneObjectLiteral(cx, deepObj, newKind);
             if (!deepObj) {
                 JS_ReportOutOfMemory(cx);
                 return nullptr;
             }
             v.setObject(*deepObj);
         }
+        clone->setDenseInitializedLength(i + 1);
         clone->initDenseElement(i, v);
     }
 
     MOZ_ASSERT(obj->compartment() == clone->compartment());
     MOZ_ASSERT(!obj->hasPrivate());
     RootedShape shape(cx, obj->lastProperty());
     size_t span = shape->slotSpan();
     clone->setLastProperty(cx, clone, shape);