Bug 1204594 - Use MOZ_RAII to replace GUARD_OBJECT where possible in the GC; r=sfink
authorTerrence Cole <terrence@mozilla.com>
Tue, 15 Sep 2015 12:12:26 -0700
changeset 295271 60fdd3ce9836cb81adebfe7a21a3e48e094f11a2
parent 295270 b762a8a3c846a8ccf210f160782641ebb7a5e846
child 295272 c76ccb113197cacd158a011b0f985da4bff94853
push id5245
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:30:51 +0000
treeherdermozilla-beta@dac831dc1bd0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfink
bugs1204594
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 1204594 - Use MOZ_RAII to replace GUARD_OBJECT where possible in the GC; r=sfink
js/public/RootingAPI.h
js/public/TracingAPI.h
js/src/gc/GCInternals.h
js/src/gc/GCRuntime.h
js/src/gc/Marking.cpp
js/src/gc/Statistics.h
js/src/jsgc.cpp
js/src/jsgc.h
--- a/js/public/RootingAPI.h
+++ b/js/public/RootingAPI.h
@@ -664,30 +664,26 @@ class MOZ_RAII Rooted : public js::Roote
         js::ThingRootKind kind = js::RootKind<T>::rootKind();
         this->stack = &roots.stackRoots_[kind];
         this->prev = *stack;
         *stack = reinterpret_cast<Rooted<void*>*>(this);
     }
 
   public:
     template <typename RootingContext>
-    explicit Rooted(const RootingContext& cx
-                    MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
+    explicit Rooted(const RootingContext& cx)
       : ptr(js::GCMethods<T>::initial())
     {
-        MOZ_GUARD_OBJECT_NOTIFIER_INIT;
         registerWithRootLists(js::RootListsForRootingContext(cx));
     }
 
     template <typename RootingContext, typename S>
-    Rooted(const RootingContext& cx, S&& initial
-           MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
+    Rooted(const RootingContext& cx, S&& initial)
       : ptr(mozilla::Forward<S>(initial))
     {
-        MOZ_GUARD_OBJECT_NOTIFIER_INIT;
         registerWithRootLists(js::RootListsForRootingContext(cx));
     }
 
     ~Rooted() {
         MOZ_ASSERT(*stack == reinterpret_cast<Rooted<void*>*>(this));
         *stack = prev;
     }
 
@@ -725,18 +721,16 @@ class MOZ_RAII Rooted : public js::Roote
      * DispatchWrapper.
      */
     using MaybeWrapped = typename mozilla::Conditional<
         mozilla::IsBaseOf<Traceable, T>::value,
         js::DispatchWrapper<T>,
         T>::Type;
     MaybeWrapped ptr;
 
-    MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
-
     Rooted(const Rooted&) = delete;
 };
 
 } /* namespace JS */
 
 namespace js {
 
 /*
@@ -776,46 +770,34 @@ class HandleBase<JSObject*>
 };
 
 /* Interface substitute for Rooted<T> which does not root the variable's memory. */
 template <typename T>
 class MOZ_RAII FakeRooted : public RootedBase<T>
 {
   public:
     template <typename CX>
-    explicit FakeRooted(CX* cx
-                        MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
-      : ptr(GCMethods<T>::initial())
-    {
-        MOZ_GUARD_OBJECT_NOTIFIER_INIT;
-    }
+    explicit FakeRooted(CX* cx) : ptr(GCMethods<T>::initial()) {}
 
     template <typename CX>
-    explicit FakeRooted(CX* cx, T initial
-                        MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
-      : ptr(initial)
-    {
-        MOZ_GUARD_OBJECT_NOTIFIER_INIT;
-    }
+    FakeRooted(CX* cx, T initial) : ptr(initial) {}
 
     DECLARE_POINTER_COMPARISON_OPS(T);
     DECLARE_POINTER_CONSTREF_OPS(T);
     DECLARE_POINTER_ASSIGN_OPS(FakeRooted, T);
     DECLARE_NONPOINTER_ACCESSOR_METHODS(ptr);
     DECLARE_NONPOINTER_MUTABLE_ACCESSOR_METHODS(ptr);
 
   private:
     T ptr;
 
     void set(const T& value) {
         ptr = value;
     }
 
-    MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
-
     FakeRooted(const FakeRooted&) = delete;
 };
 
 /* Interface substitute for MutableHandle<T> which is not required to point to rooted memory. */
 template <typename T>
 class FakeMutableHandle : public js::MutableHandleBase<T>
 {
   public:
--- a/js/public/TracingAPI.h
+++ b/js/public/TracingAPI.h
@@ -195,34 +195,34 @@ class JS_PUBLIC_API(CallbackTracer) : pu
     friend class AutoTracingIndex;
     size_t contextIndex_;
 
     friend class AutoTracingDetails;
     ContextFunctor* contextFunctor_;
 };
 
 // Set the name portion of the tracer's context for the current edge.
-class AutoTracingName
+class MOZ_RAII AutoTracingName
 {
     CallbackTracer* trc_;
     const char* prior_;
 
   public:
     AutoTracingName(CallbackTracer* trc, const char* name) : trc_(trc), prior_(trc->contextName_) {
         MOZ_ASSERT(name);
         trc->contextName_ = name;
     }
     ~AutoTracingName() {
         MOZ_ASSERT(trc_->contextName_);
         trc_->contextName_ = prior_;
     }
 };
 
 // Set the index portion of the tracer's context for the current range.
-class AutoTracingIndex
+class MOZ_RAII AutoTracingIndex
 {
     CallbackTracer* trc_;
 
   public:
     explicit AutoTracingIndex(JSTracer* trc, size_t initial = 0) : trc_(nullptr) {
         if (trc->isCallbackTracer()) {
             trc_ = trc->asCallbackTracer();
             MOZ_ASSERT(trc_->contextIndex_ == CallbackTracer::InvalidIndex);
@@ -241,17 +241,17 @@ class AutoTracingIndex
             MOZ_ASSERT(trc_->contextIndex_ != CallbackTracer::InvalidIndex);
             ++trc_->contextIndex_;
         }
     }
 };
 
 // Set a context callback for the trace callback to use, if it needs a detailed
 // edge description.
-class AutoTracingDetails
+class MOZ_RAII AutoTracingDetails
 {
     CallbackTracer* trc_;
 
   public:
     AutoTracingDetails(JSTracer* trc, CallbackTracer::ContextFunctor& func) : trc_(nullptr) {
         if (trc->isCallbackTracer()) {
             trc_ = trc->asCallbackTracer();
             MOZ_ASSERT(trc_->contextFunctor_ == nullptr);
--- a/js/src/gc/GCInternals.h
+++ b/js/src/gc/GCInternals.h
@@ -17,53 +17,53 @@
 #include "vm/Runtime.h"
 
 namespace js {
 namespace gc {
 
 void
 MarkPersistentRootedChains(JSTracer* trc);
 
-class AutoCopyFreeListToArenas
+class MOZ_RAII AutoCopyFreeListToArenas
 {
     JSRuntime* runtime;
     ZoneSelector selector;
 
   public:
     AutoCopyFreeListToArenas(JSRuntime* rt, ZoneSelector selector);
     ~AutoCopyFreeListToArenas();
 };
 
-struct AutoFinishGC
+struct MOZ_RAII AutoFinishGC
 {
     explicit AutoFinishGC(JSRuntime* rt);
 };
 
 /*
  * This class should be used by any code that needs to exclusive access to the
  * heap in order to trace through it...
  */
-class AutoTraceSession
+class MOZ_RAII AutoTraceSession
 {
   public:
     explicit AutoTraceSession(JSRuntime* rt, JS::HeapState state = JS::HeapState::Tracing);
     ~AutoTraceSession();
 
   protected:
     AutoLockForExclusiveAccess lock;
     JSRuntime* runtime;
 
   private:
     AutoTraceSession(const AutoTraceSession&) = delete;
     void operator=(const AutoTraceSession&) = delete;
 
     JS::HeapState prevState;
 };
 
-struct AutoPrepareForTracing
+struct MOZ_RAII AutoPrepareForTracing
 {
     AutoFinishGC finish;
     AutoTraceSession session;
     AutoCopyFreeListToArenas copy;
 
     AutoPrepareForTracing(JSRuntime* rt, ZoneSelector selector);
 };
 
@@ -91,25 +91,22 @@ IncrementalSafety
 IsIncrementalGCSafe(JSRuntime* rt);
 
 #ifdef JS_GC_ZEAL
 
 class MOZ_RAII AutoStopVerifyingBarriers
 {
     GCRuntime* gc;
     bool restartPreVerifier;
-    MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
 
   public:
-    AutoStopVerifyingBarriers(JSRuntime* rt, bool isShutdown
-                              MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
+    AutoStopVerifyingBarriers(JSRuntime* rt, bool isShutdown)
       : gc(&rt->gc)
     {
         restartPreVerifier = gc->endVerifyPreBarriers() && !isShutdown;
-        MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     }
 
     ~AutoStopVerifyingBarriers() {
         // Nasty special case: verification runs a minor GC, which *may* nest
         // inside of an outer minor GC. This is not allowed by the
         // gc::Statistics phase tree. So we pause the "real" GC, if in fact one
         // is in progress.
         gcstats::Phase outer = gc->stats.currentPhase();
@@ -122,17 +119,17 @@ class MOZ_RAII AutoStopVerifyingBarriers
         if (restartPreVerifier)
             gc->startVerifyPreBarriers();
 
         if (outer != gcstats::PHASE_NONE)
             gc->stats.beginPhase(outer);
     }
 };
 #else
-struct AutoStopVerifyingBarriers
+struct MOZ_RAII AutoStopVerifyingBarriers
 {
     AutoStopVerifyingBarriers(JSRuntime*, bool) {}
 };
 #endif /* JS_GC_ZEAL */
 
 #ifdef JSGC_HASH_TABLE_CHECKS
 void
 CheckHashTablesAfterMovingGC(JSRuntime* rt);
@@ -151,55 +148,50 @@ struct MovingTracer : JS::CallbackTracer
     TracerKind getTracerKind() const override { return TracerKind::Moving; }
 #endif
 };
 
 class MOZ_RAII AutoMaybeStartBackgroundAllocation
 {
   private:
     JSRuntime* runtime;
-    MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
 
   public:
-    explicit AutoMaybeStartBackgroundAllocation(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM)
+    AutoMaybeStartBackgroundAllocation()
       : runtime(nullptr)
-    {
-        MOZ_GUARD_OBJECT_NOTIFIER_INIT;
-    }
+    {}
 
     void tryToStartBackgroundAllocation(JSRuntime* rt) {
         runtime = rt;
     }
 
     ~AutoMaybeStartBackgroundAllocation() {
         if (runtime)
             runtime->gc.startBackgroundAllocTaskIfIdle();
     }
 };
 
 // In debug builds, set/unset the GC sweeping flag for the current thread.
 struct MOZ_RAII AutoSetThreadIsSweeping
 {
 #ifdef DEBUG
-    explicit AutoSetThreadIsSweeping(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM)
+    AutoSetThreadIsSweeping()
       : threadData_(js::TlsPerThreadData.get())
     {
         MOZ_ASSERT(!threadData_->gcSweeping);
         threadData_->gcSweeping = true;
-        MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     }
 
     ~AutoSetThreadIsSweeping() {
         MOZ_ASSERT(threadData_->gcSweeping);
         threadData_->gcSweeping = false;
     }
 
   private:
     PerThreadData* threadData_;
-    MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
 #else
     AutoSetThreadIsSweeping() {}
 #endif
 };
 
 // Structure for counting how many times objects in a particular group have
 // been tenured during a minor collection.
 struct TenureCount
--- a/js/src/gc/GCRuntime.h
+++ b/js/src/gc/GCRuntime.h
@@ -1308,17 +1308,17 @@ class GCRuntime
 
     friend class js::GCHelperState;
     friend class js::gc::MarkingValidator;
     friend class js::gc::AutoTraceSession;
     friend class AutoEnterIteration;
 };
 
 /* Prevent compartments and zones from being collected during iteration. */
-class AutoEnterIteration {
+class MOZ_RAII AutoEnterIteration {
     GCRuntime* gc;
 
   public:
     explicit AutoEnterIteration(GCRuntime* gc_) : gc(gc_) {
         ++gc->numActiveZoneIters;
     }
 
     ~AutoEnterIteration() {
--- a/js/src/gc/Marking.cpp
+++ b/js/src/gc/Marking.cpp
@@ -4,16 +4,17 @@
  * 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 "gc/Marking.h"
 
 #include "mozilla/DebugOnly.h"
 #include "mozilla/IntegerRange.h"
 #include "mozilla/ReentrancyGuard.h"
+#include "mozilla/ScopeExit.h"
 #include "mozilla/TypeTraits.h"
 
 #include "jsgc.h"
 #include "jsprf.h"
 
 #include "builtin/ModuleObject.h"
 #include "gc/GCInternals.h"
 #include "jit/IonCode.h"
@@ -1243,24 +1244,19 @@ VisitTraceList(F f, const int32_t* trace
 
 
 /*** Mark-stack Marking ***************************************************************************/
 
 bool
 GCMarker::drainMarkStack(SliceBudget& budget)
 {
 #ifdef DEBUG
-    struct AutoCheckCompartment {
-        bool& flag;
-        explicit AutoCheckCompartment(bool& comparmentCheckFlag) : flag(comparmentCheckFlag) {
-            MOZ_ASSERT(!flag);
-            flag = true;
-        }
-        ~AutoCheckCompartment() { flag = false; }
-    } acc(strictCompartmentChecking);
+    MOZ_ASSERT(!strictCompartmentChecking);
+    strictCompartmentChecking = true;
+    auto acc = mozilla::MakeScopeExit([&] {strictCompartmentChecking = false;});
 #endif
 
     if (budget.isOverBudget())
         return false;
 
     for (;;) {
         while (!stack.isEmpty()) {
             processMarkStackTop(budget);
--- a/js/src/gc/Statistics.h
+++ b/js/src/gc/Statistics.h
@@ -329,53 +329,44 @@ struct Statistics
     UniqueChars formatJsonPhaseTimes(const PhaseTimeTable phaseTimes);
 
     double computeMMU(int64_t resolution) const;
 };
 
 struct MOZ_RAII AutoGCSlice
 {
     AutoGCSlice(Statistics& stats, const ZoneGCStats& zoneStats, JSGCInvocationKind gckind,
-                SliceBudget budget, JS::gcreason::Reason reason
-                MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
+                SliceBudget budget, JS::gcreason::Reason reason)
       : stats(stats)
     {
-        MOZ_GUARD_OBJECT_NOTIFIER_INIT;
         stats.beginSlice(zoneStats, gckind, budget, reason);
     }
     ~AutoGCSlice() { stats.endSlice(); }
 
     Statistics& stats;
-    MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
 };
 
 struct MOZ_RAII AutoPhase
 {
-    AutoPhase(Statistics& stats, Phase phase
-              MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
+    AutoPhase(Statistics& stats, Phase phase)
       : stats(stats), task(nullptr), phase(phase), enabled(true)
     {
-        MOZ_GUARD_OBJECT_NOTIFIER_INIT;
         stats.beginPhase(phase);
     }
 
-    AutoPhase(Statistics& stats, bool condition, Phase phase
-              MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
+    AutoPhase(Statistics& stats, bool condition, Phase phase)
       : stats(stats), task(nullptr), phase(phase), enabled(condition)
     {
-        MOZ_GUARD_OBJECT_NOTIFIER_INIT;
         if (enabled)
             stats.beginPhase(phase);
     }
 
-    AutoPhase(Statistics& stats, const GCParallelTask& task, Phase phase
-              MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
+    AutoPhase(Statistics& stats, const GCParallelTask& task, Phase phase)
       : stats(stats), task(&task), phase(phase), enabled(true)
     {
-        MOZ_GUARD_OBJECT_NOTIFIER_INIT;
         if (enabled)
             stats.beginPhase(phase);
     }
 
     ~AutoPhase() {
         if (enabled) {
             if (task)
                 stats.endParallelPhase(phase, task);
@@ -383,36 +374,32 @@ struct MOZ_RAII AutoPhase
                 stats.endPhase(phase);
         }
     }
 
     Statistics& stats;
     const GCParallelTask* task;
     Phase phase;
     bool enabled;
-    MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
 };
 
 struct MOZ_RAII AutoSCC
 {
-    AutoSCC(Statistics& stats, unsigned scc
-            MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
+    AutoSCC(Statistics& stats, unsigned scc)
       : stats(stats), scc(scc)
     {
-        MOZ_GUARD_OBJECT_NOTIFIER_INIT;
         start = stats.beginSCC();
     }
     ~AutoSCC() {
         stats.endSCC(scc, start);
     }
 
     Statistics& stats;
     unsigned scc;
     int64_t start;
-    MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
 };
 
 const char* ExplainInvocationKind(JSGCInvocationKind gckind);
 const char* ExplainReason(JS::gcreason::Reason reason);
 
 } /* namespace gcstats */
 } /* namespace js */
 
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -6936,21 +6936,19 @@ AutoSuppressGC::AutoSuppressGC(JSRuntime
 
 bool
 js::UninlinedIsInsideNursery(const gc::Cell* cell)
 {
     return IsInsideNursery(cell);
 }
 
 #ifdef DEBUG
-AutoDisableProxyCheck::AutoDisableProxyCheck(JSRuntime* rt
-                                             MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
+AutoDisableProxyCheck::AutoDisableProxyCheck(JSRuntime* rt)
   : gc(rt->gc)
 {
-    MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     gc.disableStrictProxyChecking();
 }
 
 AutoDisableProxyCheck::~AutoDisableProxyCheck()
 {
     gc.enableStrictProxyChecking();
 }
 
--- a/js/src/jsgc.h
+++ b/js/src/jsgc.h
@@ -1292,34 +1292,34 @@ MaybeVerifyBarriers(JSContext* cx, bool 
 #endif
 
 /*
  * Instances of this class set the |JSRuntime::suppressGC| flag for the duration
  * that they are live. Use of this class is highly discouraged. Please carefully
  * read the comment in vm/Runtime.h above |suppressGC| and take all appropriate
  * precautions before instantiating this class.
  */
-class AutoSuppressGC
+class MOZ_RAII AutoSuppressGC
 {
     int32_t& suppressGC_;
 
   public:
     explicit AutoSuppressGC(ExclusiveContext* cx);
     explicit AutoSuppressGC(JSCompartment* comp);
     explicit AutoSuppressGC(JSRuntime* rt);
 
     ~AutoSuppressGC()
     {
         suppressGC_--;
     }
 };
 
 #ifdef DEBUG
 /* Disable OOM testing in sections which are not OOM safe. */
-class AutoEnterOOMUnsafeRegion
+class MOZ_RAII AutoEnterOOMUnsafeRegion
 {
     bool oomEnabled_;
     int64_t oomAfter_;
 
   public:
     AutoEnterOOMUnsafeRegion()
       : oomEnabled_(OOM_maxAllocations != UINT32_MAX), oomAfter_(0)
     {
@@ -1331,17 +1331,17 @@ class AutoEnterOOMUnsafeRegion
 
     ~AutoEnterOOMUnsafeRegion() {
         MOZ_ASSERT(OOM_maxAllocations == UINT32_MAX);
         if (oomEnabled_)
             OOM_maxAllocations = OOM_counter + oomAfter_;
     }
 };
 #else
-class AutoEnterOOMUnsafeRegion {};
+class MOZ_RAII AutoEnterOOMUnsafeRegion {};
 #endif /* DEBUG */
 
 // A singly linked list of zones.
 class ZoneList
 {
     static Zone * const End;
 
     Zone* head;
@@ -1371,32 +1371,30 @@ JSObject*
 NewMemoryStatisticsObject(JSContext* cx);
 
 } /* namespace gc */
 
 #ifdef DEBUG
 /* Use this to avoid assertions when manipulating the wrapper map. */
 class MOZ_RAII AutoDisableProxyCheck
 {
-    MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER;
     gc::GCRuntime& gc;
 
   public:
-    explicit AutoDisableProxyCheck(JSRuntime* rt
-                                   MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
+    explicit AutoDisableProxyCheck(JSRuntime* rt);
     ~AutoDisableProxyCheck();
 };
 #else
-struct AutoDisableProxyCheck
+struct MOZ_RAII AutoDisableProxyCheck
 {
     explicit AutoDisableProxyCheck(JSRuntime* rt) {}
 };
 #endif
 
-struct AutoDisableCompactingGC
+struct MOZ_RAII AutoDisableCompactingGC
 {
     explicit AutoDisableCompactingGC(JSRuntime* rt);
     ~AutoDisableCompactingGC();
 
   private:
     gc::GCRuntime& gc;
 };