Bug 1461938 part 18 - Move objectMetadataState_ from JSCompartment to JS::Realm. r=luke
authorJan de Mooij <jdemooij@mozilla.com>
Wed, 23 May 2018 11:03:25 +0200
changeset 473794 9f59efaed14290cc5ab065a13d76ecf739776e91
parent 473793 2a317ad122f8f6d8a937c560602c3de6d569655f
child 473795 fd6c61be7966932862f8fcc009855ab2b4f327c8
push id9374
push userjlund@mozilla.com
push dateMon, 18 Jun 2018 21:43:20 +0000
treeherdermozilla-beta@160e085dfb0b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs1461938
milestone62.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 1461938 part 18 - Move objectMetadataState_ from JSCompartment to JS::Realm. r=luke
js/src/builtin/TypedObject.cpp
js/src/vm/ArrayObject-inl.h
js/src/vm/Caches-inl.h
js/src/vm/JSCompartment.cpp
js/src/vm/JSCompartment.h
js/src/vm/JSObject.cpp
js/src/vm/NativeObject-inl.h
js/src/vm/ProxyObject.cpp
js/src/vm/UnboxedObject.cpp
--- a/js/src/builtin/TypedObject.cpp
+++ b/js/src/builtin/TypedObject.cpp
@@ -2327,17 +2327,17 @@ TypedObject::create(JSContext* cx, js::g
     if (!obj)
         return cx->alreadyReportedOOM();
 
     TypedObject* tobj = static_cast<TypedObject*>(obj);
     tobj->initGroup(group);
     tobj->initShape(shape);
 
     MOZ_ASSERT(clasp->shouldDelayMetadataBuilder());
-    cx->compartment()->setObjectPendingMetadata(cx, tobj);
+    cx->realm()->setObjectPendingMetadata(cx, tobj);
 
     js::gc::gcTracer.traceCreateObject(tobj);
 
     return tobj;
 }
 
 /******************************************************************************
  * Intrinsics
--- a/js/src/vm/ArrayObject-inl.h
+++ b/js/src/vm/ArrayObject-inl.h
@@ -56,17 +56,17 @@ ArrayObject::createArrayInternal(JSConte
     ArrayObject* aobj = static_cast<ArrayObject*>(obj);
     aobj->initGroup(group);
     aobj->initShape(shape);
     // NOTE: Dynamic slots are created internally by Allocate<JSObject>.
     if (!nDynamicSlots)
         aobj->initSlots(nullptr);
 
     MOZ_ASSERT(clasp->shouldDelayMetadataBuilder());
-    cx->compartment()->setObjectPendingMetadata(cx, aobj);
+    cx->realm()->setObjectPendingMetadata(cx, aobj);
 
     return aobj;
 }
 
 /* static */ inline ArrayObject*
 ArrayObject::finishCreateArray(ArrayObject* obj, HandleShape shape, AutoSetNewObjectMetadata& metadata)
 {
     size_t span = shape->slotSpan();
--- a/js/src/vm/Caches-inl.h
+++ b/js/src/vm/Caches-inl.h
@@ -66,17 +66,17 @@ NewObjectCache::newObjectFromHit(JSConte
                                                                             /* nDynamicSlots = */ 0,
                                                                             heap, group->clasp()));
     if (!obj)
         return nullptr;
 
     copyCachedToObject(obj, templateObj, entry->kind);
 
     if (group->clasp()->shouldDelayMetadataBuilder())
-        cx->compartment()->setObjectPendingMetadata(cx, obj);
+        cx->realm()->setObjectPendingMetadata(cx, obj);
     else
         obj = static_cast<NativeObject*>(SetNewObjectMetadata(cx, obj));
 
     probes::CreateObject(cx, obj);
     gc::gcTracer.traceCreateObject(obj);
     return obj;
 }
 
--- a/js/src/vm/JSCompartment.cpp
+++ b/js/src/vm/JSCompartment.cpp
@@ -47,17 +47,16 @@ JSCompartment::JSCompartment(Zone* zone)
     principals_(nullptr),
     isSystem_(false),
     isSelfHosting(false),
     performanceMonitoring(runtime_),
     data(nullptr),
     regExps(),
     globalWriteBarriered(0),
     detachedTypedObjects(0),
-    objectMetadataState(ImmediateMetadata()),
     selfHostingScriptSource(nullptr),
     objectMetadataTable(nullptr),
     innerViews(zone),
     lazyArrayBuffers(nullptr),
     nonSyntacticLexicalEnvironments_(nullptr),
     gcIncomingGrayPointers(nullptr),
     debugModeBits(0),
     validAccessPtr(nullptr),
@@ -656,19 +655,19 @@ Realm::traceGlobal(JSTracer* trc)
     // Atoms are always tenured.
     if (!JS::CurrentThreadIsHeapMinorCollecting())
         varNames_.trace(trc);
 }
 
 void
 Realm::traceRoots(JSTracer* trc, js::gc::GCRuntime::TraceOrMarkRuntime traceOrMark)
 {
-    if (objectMetadataState.is<PendingMetadata>()) {
+    if (objectMetadataState_.is<PendingMetadata>()) {
         TraceRoot(trc,
-                  &objectMetadataState.as<PendingMetadata>(),
+                  &objectMetadataState_.as<PendingMetadata>(),
                   "on-stack object pending metadata");
     }
 
     if (!JS::CurrentThreadIsHeapMinorCollecting()) {
         // The global is never nursery allocated, so we don't need to
         // trace it when doing a minor collection.
         //
         // If a compartment is on-stack, we mark its global so that
@@ -1365,47 +1364,47 @@ JSCompartment::randomHashCodeScrambler()
     return mozilla::HashCodeScrambler(randomKeyGenerator_.next(),
                                       randomKeyGenerator_.next());
 }
 
 AutoSetNewObjectMetadata::AutoSetNewObjectMetadata(JSContext* cx
                                                    MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
     : CustomAutoRooter(cx)
     , cx_(cx->helperThread() ? nullptr : cx)
-    , prevState_(cx->compartment()->objectMetadataState)
+    , prevState_(cx->realm()->objectMetadataState_)
 {
     MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     if (cx_)
-        cx_->compartment()->objectMetadataState = NewObjectMetadataState(DelayMetadata());
+        cx_->realm()->objectMetadataState_ = NewObjectMetadataState(DelayMetadata());
 }
 
 AutoSetNewObjectMetadata::~AutoSetNewObjectMetadata()
 {
     // If we don't have a cx, we didn't change the metadata state, so no need to
     // reset it here.
     if (!cx_)
         return;
 
-    if (!cx_->isExceptionPending() && cx_->compartment()->hasObjectPendingMetadata()) {
+    if (!cx_->isExceptionPending() && cx_->realm()->hasObjectPendingMetadata()) {
         // This destructor often runs upon exit from a function that is
         // returning an unrooted pointer to a Cell. The allocation metadata
         // callback often allocates; if it causes a GC, then the Cell pointer
         // being returned won't be traced or relocated.
         //
         // The only extant callbacks are those internal to SpiderMonkey that
         // capture the JS stack. In fact, we're considering removing general
         // callbacks altogther in bug 1236748. Since it's not running arbitrary
         // code, it's adequate to simply suppress GC while we run the callback.
         AutoSuppressGC autoSuppressGC(cx_);
 
-        JSObject* obj = cx_->compartment()->objectMetadataState.as<PendingMetadata>();
+        JSObject* obj = cx_->realm()->objectMetadataState_.as<PendingMetadata>();
 
         // Make sure to restore the previous state before setting the object's
         // metadata. SetNewObjectMetadata asserts that the state is not
         // PendingMetadata in order to ensure that metadata callbacks are called
         // in order.
-        cx_->compartment()->objectMetadataState = prevState_;
+        cx_->realm()->objectMetadataState_ = prevState_;
 
         obj = SetNewObjectMetadata(cx_, obj);
     } else {
-        cx_->compartment()->objectMetadataState = prevState_;
+        cx_->realm()->objectMetadataState_ = prevState_;
     }
 }
--- a/js/src/vm/JSCompartment.h
+++ b/js/src/vm/JSCompartment.h
@@ -658,36 +658,22 @@ struct JSCompartment
      * written to a property of the global.
      */
     uint32_t                     globalWriteBarriered;
 
     // Non-zero if the storage underlying any typed object in this compartment
     // might be detached.
     int32_t                      detachedTypedObjects;
 
-  protected:
-    friend class js::AutoSetNewObjectMetadata;
-    js::NewObjectMetadataState objectMetadataState;
-
-  public:
     // Recompute the probability with which this compartment should record
     // profiling data (stack traces, allocations log, etc.) about each
     // allocation. We consult the probabilities requested by the Debugger
     // instances observing us, if any.
     void chooseAllocationSamplingProbability() { savedStacks_.chooseSamplingProbability(this); }
 
-    bool hasObjectPendingMetadata() const { return objectMetadataState.is<js::PendingMetadata>(); }
-
-    void setObjectPendingMetadata(JSContext* cx, JSObject* obj) {
-        if (!cx->helperThread()) {
-            MOZ_ASSERT(objectMetadataState.is<js::DelayMetadata>());
-            objectMetadataState = js::NewObjectMetadataState(js::PendingMetadata(obj));
-        }
-    }
-
   protected:
     void addSizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf,
                                 size_t* crossCompartmentWrappersArg);
 
   public:
     // Object group tables and other state in the compartment.
     js::ObjectGroupCompartment   objectGroups;
 
@@ -1032,16 +1018,19 @@ class JS::Realm : public JSCompartment
     // VariableDeclaration declarations in global code in this realm.
     // Names are only removed from this list by a |delete IdentifierReference|
     // that successfully removes that global property.
     using VarNamesSet = JS::GCHashSet<JSAtom*,
                                       js::DefaultHasher<JSAtom*>,
                                       js::SystemAllocPolicy>;
     VarNamesSet varNames_;
 
+    friend class js::AutoSetNewObjectMetadata;
+    js::NewObjectMetadataState objectMetadataState_ { js::ImmediateMetadata() };
+
     // Used by memory reporters and invalid otherwise.
     JS::RealmStats* realmStats_ = nullptr;
 
     const js::AllocationMetadataBuilder* allocationMetadataBuilder_ = nullptr;
     void* realmPrivate_ = nullptr;
 
     unsigned enterRealmDepth_ = 0;
 
@@ -1190,16 +1179,26 @@ class JS::Realm : public JSCompartment
     const void* addressOfMetadataBuilder() const {
         return &allocationMetadataBuilder_;
     }
     void setAllocationMetadataBuilder(const js::AllocationMetadataBuilder* builder);
     void forgetAllocationMetadataBuilder();
     void setNewObjectMetadata(JSContext* cx, JS::HandleObject obj);
     void clearObjectMetadata();
 
+    bool hasObjectPendingMetadata() const {
+        return objectMetadataState_.is<js::PendingMetadata>();
+    }
+    void setObjectPendingMetadata(JSContext* cx, JSObject* obj) {
+        if (!cx->helperThread()) {
+            MOZ_ASSERT(objectMetadataState_.is<js::DelayMetadata>());
+            objectMetadataState_ = js::NewObjectMetadataState(js::PendingMetadata(obj));
+        }
+    }
+
     void* realmPrivate() const {
         return realmPrivate_;
     }
     void setRealmPrivate(void* p) {
         realmPrivate_ = p;
     }
 
     // This should only be called when it is non-null, i.e. during memory
--- a/js/src/vm/JSObject.cpp
+++ b/js/src/vm/JSObject.cpp
@@ -4161,17 +4161,17 @@ JSObject::debugCheckNewObject(ObjectGrou
         MOZ_ASSERT(finalizeFlags == 0);
     }
 
     MOZ_ASSERT_IF(clasp->hasFinalize(), heap == gc::TenuredHeap ||
                                         CanNurseryAllocateFinalizedClass(clasp) ||
                                         clasp->isProxy());
     MOZ_ASSERT_IF(group->hasUnanalyzedPreliminaryObjects(), heap == gc::TenuredHeap);
 
-    MOZ_ASSERT(!group->compartment()->hasObjectPendingMetadata());
+    MOZ_ASSERT(!group->realm()->hasObjectPendingMetadata());
 
     // Non-native classes manage their own data and slots, so numFixedSlots and
     // slotSpan are always 0. Note that proxy classes can have reserved slots
     // but they're also not included in numFixedSlots/slotSpan.
     if (!clasp->isNative()) {
         MOZ_ASSERT_IF(!clasp->isProxy(), JSCLASS_RESERVED_SLOTS(clasp) == 0);
         MOZ_ASSERT(!clasp->hasPrivate());
         MOZ_ASSERT_IF(shape, shape->numFixedSlots() == 0);
--- a/js/src/vm/NativeObject-inl.h
+++ b/js/src/vm/NativeObject-inl.h
@@ -548,17 +548,17 @@ NativeObject::create(JSContext* cx, js::
 
     if (clasp->hasPrivate())
         nobj->initPrivate(nullptr);
 
     if (size_t span = shape->slotSpan())
         nobj->initializeSlotRange(0, span);
 
     if (clasp->shouldDelayMetadataBuilder())
-        cx->compartment()->setObjectPendingMetadata(cx, nobj);
+        cx->realm()->setObjectPendingMetadata(cx, nobj);
     else
         nobj = SetNewObjectMetadata(cx, nobj);
 
     js::gc::gcTracer.traceCreateObject(nobj);
 
     return nobj;
 }
 
--- a/js/src/vm/ProxyObject.cpp
+++ b/js/src/vm/ProxyObject.cpp
@@ -185,17 +185,17 @@ ProxyObject::create(JSContext* cx, const
     if (!obj)
         return cx->alreadyReportedOOM();
 
     ProxyObject* pobj = static_cast<ProxyObject*>(obj);
     pobj->initGroup(group);
     pobj->initShape(shape);
 
     MOZ_ASSERT(clasp->shouldDelayMetadataBuilder());
-    cx->compartment()->setObjectPendingMetadata(cx, pobj);
+    cx->realm()->setObjectPendingMetadata(cx, pobj);
 
     js::gc::gcTracer.traceCreateObject(pobj);
 
     if (newKind == SingletonObject) {
         Rooted<ProxyObject*> pobjRoot(cx, pobj);
         if (!JSObject::setSingleton(cx, pobjRoot))
             return cx->alreadyReportedOOM();
         pobj = pobjRoot;
--- a/js/src/vm/UnboxedObject.cpp
+++ b/js/src/vm/UnboxedObject.cpp
@@ -774,17 +774,17 @@ UnboxedObject::createInternal(JSContext*
     JSObject* obj = js::Allocate<JSObject>(cx, kind, /* nDynamicSlots = */ 0, heap, clasp);
     if (!obj)
         return cx->alreadyReportedOOM();
 
     UnboxedObject* uobj = static_cast<UnboxedObject*>(obj);
     uobj->initGroup(group);
 
     MOZ_ASSERT(clasp->shouldDelayMetadataBuilder());
-    cx->compartment()->setObjectPendingMetadata(cx, uobj);
+    cx->realm()->setObjectPendingMetadata(cx, uobj);
 
     js::gc::gcTracer.traceCreateObject(uobj);
 
     return uobj;
 }
 
 /* static */
 UnboxedPlainObject*