Backout 67296c6ede81 (bug 1175466) on a CLOSED TREE.
authorJan de Mooij <jdemooij@mozilla.com>
Sat, 20 Jun 2015 22:38:18 -0700
changeset 280692 5f942c1cd0d005f3ded3fa265eb15afa4859f063
parent 280691 f90880e6841a8bc54d48fa99347bacd60ea1949c
child 280693 b60de195ad59e7170b56a3f7470bf64aa69dc035
push id4932
push userjlund@mozilla.com
push dateMon, 10 Aug 2015 18:23:06 +0000
treeherdermozilla-beta@6dd5a4f5f745 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1175466
milestone41.0a1
backs out67296c6ede81f20370d7731234c90f858e8007b5
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
Backout 67296c6ede81 (bug 1175466) on a CLOSED TREE.
js/src/gc/Marking.cpp
js/src/jsobj.cpp
js/src/vm/ArgumentsObject.cpp
js/src/vm/ArgumentsObject.h
--- a/js/src/gc/Marking.cpp
+++ b/js/src/gc/Marking.cpp
@@ -1967,28 +1967,24 @@ js::TenuringTracer::moveObjectToTenured(
         // The shape's list head may point into the old object. This can only
         // happen for dictionaries, which are native objects.
         if (&nsrc->shape_ == ndst->shape_->listp) {
             MOZ_ASSERT(nsrc->shape_->inDictionary());
             ndst->shape_->listp = &ndst->shape_;
         }
     }
 
-    if (src->getClass()->flags & JSCLASS_SKIP_NURSERY_FINALIZE) {
-        if (src->is<InlineTypedObject>()) {
-            InlineTypedObject::objectMovedDuringMinorGC(this, dst, src);
-        } else if (src->is<UnboxedArrayObject>()) {
-            tenuredSize += UnboxedArrayObject::objectMovedDuringMinorGC(this, dst, src, dstKind);
-        } else if (src->is<ArgumentsObject>()) {
-            tenuredSize += ArgumentsObject::objectMovedDuringMinorGC(this, dst, src);
-        } else {
-            // Objects with JSCLASS_SKIP_NURSERY_FINALIZE need to be handled above
-            // to ensure any additional nursery buffers they hold are moved.
-            MOZ_CRASH("Unhandled JSCLASS_SKIP_NURSERY_FINALIZE Class");
-        }
+    if (src->is<InlineTypedObject>()) {
+        InlineTypedObject::objectMovedDuringMinorGC(this, dst, src);
+    } else if (src->is<UnboxedArrayObject>()) {
+        tenuredSize += UnboxedArrayObject::objectMovedDuringMinorGC(this, dst, src, dstKind);
+    } else {
+        // Objects with JSCLASS_SKIP_NURSERY_FINALIZE need to be handled above
+        // to ensure any additional nursery buffers they hold are moved.
+        MOZ_ASSERT(!(src->getClass()->flags & JSCLASS_SKIP_NURSERY_FINALIZE));
     }
 
     return tenuredSize;
 }
 
 size_t
 js::TenuringTracer::moveSlotsToTenured(NativeObject* dst, NativeObject* src, AllocKind dstKind)
 {
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -3999,19 +3999,16 @@ JSObject::sizeOfIncludingThisInNursery()
         size += native.numFixedSlots() * sizeof(Value);
         size += native.numDynamicSlots() * sizeof(Value);
 
         if (native.hasDynamicElements()) {
             js::ObjectElements& elements = *native.getElementsHeader();
             if (!elements.isCopyOnWrite() || elements.ownerObject() == this)
                 size += elements.capacity * sizeof(HeapSlot);
         }
-
-        if (is<ArgumentsObject>())
-            size += as<ArgumentsObject>().sizeOfData();
     }
 
     return size;
 }
 
 size_t
 JS::ubi::Concrete<JSObject>::size(mozilla::MallocSizeOf mallocSizeOf) const
 {
--- a/js/src/vm/ArgumentsObject.cpp
+++ b/js/src/vm/ArgumentsObject.cpp
@@ -1,25 +1,22 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "vm/ArgumentsObject-inl.h"
 
-#include "mozilla/PodOperations.h"
-
 #include "jit/JitFrames.h"
 #include "vm/GlobalObject.h"
 #include "vm/Stack.h"
 
 #include "jsobjinlines.h"
 
-#include "gc/Nursery-inl.h"
 #include "vm/Stack-inl.h"
 
 using namespace js;
 using namespace js::gc;
 
 static void
 CopyStackFrameArguments(const AbstractFramePtr frame, HeapValue* dst, unsigned totalArgs)
 {
@@ -180,43 +177,41 @@ ArgumentsObject::create(JSContext* cx, H
 
     unsigned numFormals = callee->nargs();
     unsigned numDeletedWords = NumWordsForBitArrayOfLength(numActuals);
     unsigned numArgs = Max(numActuals, numFormals);
     unsigned numBytes = offsetof(ArgumentsData, args) +
                         numDeletedWords * sizeof(size_t) +
                         numArgs * sizeof(Value);
 
+    // Allocate zeroed memory to make the object GC-safe for early attachment.
+    ArgumentsData* data = reinterpret_cast<ArgumentsData*>(
+            cx->zone()->pod_calloc<uint8_t>(numBytes));
+    if (!data)
+        return nullptr;
+
     Rooted<ArgumentsObject*> obj(cx);
     JSObject* base = JSObject::create(cx, FINALIZE_KIND,
                                       GetInitialHeap(GenericObject, clasp),
                                       shape, group);
-    if (!base)
+    if (!base) {
+        js_free(data);
         return nullptr;
+    }
     obj = &base->as<ArgumentsObject>();
 
-    ArgumentsData* data =
-        reinterpret_cast<ArgumentsData*>(AllocateObjectBuffer<uint8_t>(cx, obj, numBytes));
-    if (!data) {
-        // Make the object safe for GC.
-        obj->initFixedSlot(DATA_SLOT, PrivateValue(nullptr));
-        return nullptr;
-    }
-
     data->numArgs = numArgs;
-    data->dataBytes = numBytes;
     data->callee.init(ObjectValue(*callee.get()));
     data->script = script;
 
-    // Zero the argument Values. This sets each value to DoubleValue(0), which
-    // is safe for GC tracing.
-    memset(data->args, 0, numArgs * sizeof(Value));
+    // Attach the argument object.
+    // Because the argument object was zeroed by pod_calloc(), each Value in
+    // ArgumentsData is DoubleValue(0) and therefore safe for GC tracing.
     MOZ_ASSERT(DoubleValue(0).asRawBits() == 0x0);
     MOZ_ASSERT_IF(numArgs > 0, data->args[0].asRawBits() == 0x0);
-
     obj->initFixedSlot(DATA_SLOT, PrivateValue(data));
 
     /* Copy [0, numArgs) into data->slots. */
     copy.copyArgs(cx, data->args, numArgs);
 
     data->deletedBits = reinterpret_cast<size_t*>(data->args + numArgs);
     ClearAllBitArrayElements(data->deletedBits, numDeletedWords);
 
@@ -531,71 +526,40 @@ strictargs_enumerate(JSContext* cx, Hand
     }
 
     return true;
 }
 
 void
 ArgumentsObject::finalize(FreeOp* fop, JSObject* obj)
 {
-    MOZ_ASSERT(!IsInsideNursery(obj));
     fop->free_(reinterpret_cast<void*>(obj->as<ArgumentsObject>().data()));
 }
 
 void
 ArgumentsObject::trace(JSTracer* trc, JSObject* obj)
 {
     ArgumentsObject& argsobj = obj->as<ArgumentsObject>();
     ArgumentsData* data = argsobj.data();
     TraceEdge(trc, &data->callee, js_callee_str);
     TraceRange(trc, data->numArgs, data->begin(), js_arguments_str);
     TraceManuallyBarrieredEdge(trc, &data->script, "script");
 }
 
-/* static */ size_t
-ArgumentsObject::objectMovedDuringMinorGC(JSTracer* trc, JSObject* dst, JSObject* src)
-{
-    ArgumentsObject* ndst = &dst->as<ArgumentsObject>();
-    ArgumentsObject* nsrc = &src->as<ArgumentsObject>();
-    MOZ_ASSERT(ndst->data() == nsrc->data());
-
-    Nursery& nursery = trc->runtime()->gc.nursery;
-
-    if (!nursery.isInside(nsrc->data())) {
-        nursery.removeMallocedBuffer(nsrc->data());
-        return 0;
-    }
-
-    uint32_t nbytes = nsrc->data()->dataBytes;
-    uint8_t* data = nsrc->zone()->pod_malloc<uint8_t>(nbytes);
-    if (!data)
-        CrashAtUnhandlableOOM("Failed to allocate ArgumentsObject data while tenuring.");
-    ndst->initFixedSlot(DATA_SLOT, PrivateValue(data));
-
-    mozilla::PodCopy(data, reinterpret_cast<uint8_t*>(nsrc->data()), nbytes);
-
-    ArgumentsData* dstData = ndst->data();
-    dstData->deletedBits = reinterpret_cast<size_t*>(dstData->args + dstData->numArgs);
-
-    return nbytes;
-}
-
 /*
  * The classes below collaborate to lazily reflect and synchronize actual
  * argument values, argument count, and callee function object stored in a
  * stack frame with their corresponding property values in the frame's
  * arguments object.
  */
 const Class NormalArgumentsObject::class_ = {
     "Arguments",
     JSCLASS_IMPLEMENTS_BARRIERS |
     JSCLASS_HAS_RESERVED_SLOTS(NormalArgumentsObject::RESERVED_SLOTS) |
-    JSCLASS_HAS_CACHED_PROTO(JSProto_Object) |
-    JSCLASS_SKIP_NURSERY_FINALIZE |
-    JSCLASS_BACKGROUND_FINALIZE,
+    JSCLASS_HAS_CACHED_PROTO(JSProto_Object) | JSCLASS_BACKGROUND_FINALIZE,
     nullptr,                 /* addProperty */
     args_delProperty,
     nullptr,                 /* getProperty */
     nullptr,                 /* setProperty */
     args_enumerate,
     args_resolve,
     nullptr,                 /* mayResolve  */
     nullptr,                 /* convert     */
@@ -610,19 +574,17 @@ const Class NormalArgumentsObject::class
  * Strict mode arguments is significantly less magical than non-strict mode
  * arguments, so it is represented by a different class while sharing some
  * functionality.
  */
 const Class StrictArgumentsObject::class_ = {
     "Arguments",
     JSCLASS_IMPLEMENTS_BARRIERS |
     JSCLASS_HAS_RESERVED_SLOTS(StrictArgumentsObject::RESERVED_SLOTS) |
-    JSCLASS_HAS_CACHED_PROTO(JSProto_Object) |
-    JSCLASS_SKIP_NURSERY_FINALIZE |
-    JSCLASS_BACKGROUND_FINALIZE,
+    JSCLASS_HAS_CACHED_PROTO(JSProto_Object) | JSCLASS_BACKGROUND_FINALIZE,
     nullptr,                 /* addProperty */
     args_delProperty,
     nullptr,                 /* getProperty */
     nullptr,                 /* setProperty */
     strictargs_enumerate,
     strictargs_resolve,
     nullptr,                 /* mayResolve  */
     nullptr,                 /* convert     */
--- a/js/src/vm/ArgumentsObject.h
+++ b/js/src/vm/ArgumentsObject.h
@@ -28,20 +28,17 @@ class JitFrameLayout;
  * when the relevant value is flagged to memorialize the modification.
  */
 struct ArgumentsData
 {
     /*
      * numArgs = Max(numFormalArgs, numActualArgs)
      * The array 'args' has numArgs elements.
      */
-    uint32_t    numArgs;
-
-    /* Size of ArgumentsData and data allocated after it. */
-    uint32_t    dataBytes;
+    unsigned    numArgs;
 
     /*
      * arguments.callee, or MagicValue(JS_OVERWRITTEN_CALLEE) if
      * arguments.callee has been modified.
      */
     HeapValue   callee;
 
     /* The script for the function containing this arguments object. */
@@ -262,23 +259,19 @@ class ArgumentsObject : public NativeObj
 
     /*
      * Measures things hanging off this ArgumentsObject that are counted by the
      * |miscSize| argument in JSObject::sizeOfExcludingThis().
      */
     size_t sizeOfMisc(mozilla::MallocSizeOf mallocSizeOf) const {
         return mallocSizeOf(data());
     }
-    size_t sizeOfData() const {
-        return data()->dataBytes;
-    }
 
     static void finalize(FreeOp* fop, JSObject* obj);
     static void trace(JSTracer* trc, JSObject* obj);
-    static size_t objectMovedDuringMinorGC(JSTracer* trc, JSObject* dst, JSObject* src);
 
     /* For jit use: */
     static size_t getDataSlotOffset() {
         return getFixedSlotOffset(DATA_SLOT);
     }
     static size_t getInitialLengthSlotOffset() {
         return getFixedSlotOffset(INITIAL_LENGTH_SLOT);
     }