Bug 910771 (part 2) - Move some stuff from JS::Zone to JS::shadow::Zone, and from JSRuntime to JS::shadow::Runtime.h. r=terrence.
authorNicholas Nethercote <nnethercote@mozilla.com>
Wed, 04 Sep 2013 19:19:04 -0700
changeset 146165 10e767f5eb9eb5e413f7d40b2a0b248edd90b389
parent 146164 830a850a6af6476b15c2d69eaf2f614acbaed9f6
child 146166 f3bd74c444d99cda051343ccdbfc20966bca144c
push id25244
push userryanvm@gmail.com
push dateMon, 09 Sep 2013 20:03:14 +0000
treeherdermozilla-central@f320b8c034bd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersterrence
bugs910771
milestone26.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 910771 (part 2) - Move some stuff from JS::Zone to JS::shadow::Zone, and from JSRuntime to JS::shadow::Runtime.h. r=terrence.
js/public/HeapAPI.h
js/src/gc/Barrier.h
js/src/gc/Heap.h
js/src/gc/Zone.cpp
js/src/gc/Zone.h
js/src/jspubtd.h
js/src/vm/Runtime.cpp
js/src/vm/Runtime.h
--- a/js/public/HeapAPI.h
+++ b/js/public/HeapAPI.h
@@ -8,16 +8,22 @@
 #define js_HeapAPI_h
 
 #include "jspubtd.h"
 
 #include "js/Utility.h"
 
 /* These values are private to the JS engine. */
 namespace js {
+
+// Whether the current thread is permitted access to any part of the specified
+// runtime or zone.
+extern bool CurrentThreadCanAccessRuntime(JSRuntime *rt);
+extern bool CurrentThreadCanAccessZone(JS::Zone *zone);
+
 namespace gc {
 
 const size_t ArenaShift = 12;
 const size_t ArenaSize = size_t(1) << ArenaShift;
 const size_t ArenaMask = ArenaSize - 1;
 
 const size_t ChunkShift = 20;
 const size_t ChunkSize = size_t(1) << ChunkShift;
@@ -52,19 +58,53 @@ namespace shadow {
 
 struct ArenaHeader
 {
     JS::Zone *zone;
 };
 
 struct Zone
 {
+  protected:
+    JSRuntime *const runtime_;
+    JSTracer *const barrierTracer_;     // A pointer to the JSRuntime's |gcMarker|.
+
+  public:
     bool needsBarrier_;
 
-    Zone() : needsBarrier_(false) {}
+    Zone(JSRuntime *runtime, JSTracer *barrierTracerArg)
+      : runtime_(runtime),
+        barrierTracer_(barrierTracerArg),
+        needsBarrier_(false)
+    {}
+
+    bool needsBarrier() const {
+        return needsBarrier_;
+    }
+
+    JSTracer *barrierTracer() {
+        JS_ASSERT(needsBarrier_);
+        JS_ASSERT(js::CurrentThreadCanAccessRuntime(runtime_));
+        return barrierTracer_;
+    }
+
+    JSRuntime *runtimeFromMainThread() const {
+        JS_ASSERT(js::CurrentThreadCanAccessRuntime(runtime_));
+        return runtime_;
+    }
+
+    // Note: Unrestricted access to the zone's runtime from an arbitrary
+    // thread can easily lead to races. Use this method very carefully.
+    JSRuntime *runtimeFromAnyThread() const {
+        return runtime_;
+    }
+
+    static JS::shadow::Zone *asShadowZone(JS::Zone *zone) {
+        return reinterpret_cast<JS::shadow::Zone*>(zone);
+    }
 };
 
 } /* namespace shadow */
 } /* namespace JS */
 
 namespace js {
 namespace gc {
 
--- a/js/src/gc/Barrier.h
+++ b/js/src/gc/Barrier.h
@@ -419,24 +419,30 @@ class EncapsulatedValue : public ValueOp
 
     static inline void writeBarrierPre(const Value &v);
     static inline void writeBarrierPre(Zone *zone, const Value &v);
 
   protected:
     inline void pre();
     inline void pre(Zone *zone);
 
-    static inline JSRuntime *runtimeFromMainThread(const Value &v) {
+    static JSRuntime *runtimeFromMainThread(const Value &v) {
         JS_ASSERT(v.isMarkable());
         return static_cast<js::gc::Cell *>(v.toGCThing())->runtimeFromMainThread();
     }
-    static inline JSRuntime *runtimeFromAnyThread(const Value &v) {
+    static JSRuntime *runtimeFromAnyThread(const Value &v) {
         JS_ASSERT(v.isMarkable());
         return static_cast<js::gc::Cell *>(v.toGCThing())->runtimeFromAnyThread();
     }
+    static JS::shadow::Runtime *shadowRuntimeFromMainThread(const Value &v) {
+        return reinterpret_cast<JS::shadow::Runtime*>(runtimeFromMainThread(v));
+    }
+    static JS::shadow::Runtime *shadowRuntimeFromAnyThread(const Value &v) {
+        return reinterpret_cast<JS::shadow::Runtime*>(runtimeFromAnyThread(v));
+    }
 
   private:
     friend class ValueOperations<EncapsulatedValue>;
     const Value * extract() const { return &value; }
 };
 
 class HeapValue : public EncapsulatedValue
 {
--- a/js/src/gc/Heap.h
+++ b/js/src/gc/Heap.h
@@ -17,27 +17,26 @@
 #include "jstypes.h"
 #include "jsutil.h"
 
 #include "ds/BitArray.h"
 #include "js/HeapAPI.h"
 
 struct JSCompartment;
 
-extern "C" {
 struct JSRuntime;
+
+namespace JS {
+namespace shadow {
+class Runtime;
+}
 }
 
 namespace js {
 
-// Whether the current thread is permitted access to any part of the specified
-// runtime or zone.
-extern bool CurrentThreadCanAccessRuntime(JSRuntime *rt);
-extern bool CurrentThreadCanAccessZone(JS::Zone *zone);
-
 class FreeOp;
 
 namespace gc {
 
 struct Arena;
 struct ArenaHeader;
 struct Chunk;
 
@@ -101,16 +100,17 @@ struct Cell
 
     inline JSRuntime *runtimeFromMainThread() const;
     inline JS::Zone *tenuredZone() const;
     inline bool tenuredIsInsideZone(JS::Zone *zone) const;
 
     // Note: Unrestricted access to the runtime of a GC thing from an arbitrary
     // thread can easily lead to races. Use this method very carefully.
     inline JSRuntime *runtimeFromAnyThread() const;
+    inline JS::shadow::Runtime *shadowRuntimeFromAnyThread() const;
 
 #ifdef DEBUG
     inline bool isAligned() const;
     inline bool isTenured() const;
 #endif
 
   protected:
     inline uintptr_t address() const;
@@ -964,16 +964,22 @@ Cell::runtimeFromMainThread() const
 }
 
 inline JSRuntime *
 Cell::runtimeFromAnyThread() const
 {
     return chunk()->info.runtime;
 }
 
+inline JS::shadow::Runtime *
+Cell::shadowRuntimeFromAnyThread() const
+{
+    return reinterpret_cast<JS::shadow::Runtime*>(runtimeFromAnyThread());
+}
+
 AllocKind
 Cell::tenuredGetAllocKind() const
 {
     return arenaHeader()->getAllocKind();
 }
 
 bool
 Cell::isMarked(uint32_t color /* = BLACK */) const
--- a/js/src/gc/Zone.cpp
+++ b/js/src/gc/Zone.cpp
@@ -19,17 +19,17 @@
 #include "jsgcinlines.h"
 
 #include "vm/ObjectImpl-inl.h"
 
 using namespace js;
 using namespace js::gc;
 
 JS::Zone::Zone(JSRuntime *rt)
-  : runtime_(rt),
+  : JS::shadow::Zone(rt, &rt->gcMarker),
     allocator(this),
     hold(false),
     ionUsingBarriers_(false),
     active(false),
     gcScheduled(false),
     gcState(NoGC),
     gcPreserveCode(false),
     gcBytes(0),
--- a/js/src/gc/Zone.h
+++ b/js/src/gc/Zone.h
@@ -87,53 +87,36 @@ namespace JS {
  * shapes within it are alive.
  *
  * We always guarantee that a zone has at least one live compartment by refusing
  * to delete the last compartment in a live zone. (This could happen, for
  * example, if the conservative scanner marks a string in an otherwise dead
  * zone.)
  */
 
-struct Zone : private JS::shadow::Zone,
+struct Zone : public JS::shadow::Zone,
               public js::gc::GraphNodeBase<JS::Zone>,
               public js::MallocProvider<JS::Zone>
 {
   private:
-    JSRuntime                    *runtime_;
-
     friend bool js::CurrentThreadCanAccessZone(Zone *zone);
 
   public:
     js::Allocator                allocator;
 
     js::CompartmentVector        compartments;
 
     bool                         hold;
 
   private:
     bool                         ionUsingBarriers_;
 
   public:
     bool                         active;  // GC flag, whether there are active frames
 
-    JSRuntime *runtimeFromMainThread() const {
-        JS_ASSERT(CurrentThreadCanAccessRuntime(runtime_));
-        return runtime_;
-    }
-
-    // Note: Unrestricted access to the zone's runtime from an arbitrary
-    // thread can easily lead to races. Use this method very carefully.
-    JSRuntime *runtimeFromAnyThread() const {
-        return runtime_;
-    }
-
-    bool needsBarrier() const {
-        return needsBarrier_;
-    }
-
     bool compileBarriers(bool needsBarrier) const {
         return needsBarrier || runtimeFromMainThread()->gcZeal() == js::gc::ZealVerifierPreValue;
     }
 
     bool compileBarriers() const {
         return compileBarriers(needsBarrier());
     }
 
@@ -143,21 +126,16 @@ struct Zone : private JS::shadow::Zone,
     };
 
     void setNeedsBarrier(bool needs, ShouldUpdateIon updateIon);
 
     static size_t OffsetOfNeedsBarrier() {
         return offsetof(Zone, needsBarrier_);
     }
 
-    js::GCMarker *barrierTracer() {
-        JS_ASSERT(needsBarrier_);
-        return &runtimeFromMainThread()->gcMarker;
-    }
-
   public:
     enum CompartmentGCState {
         NoGC,
         Mark,
         MarkGray,
         Sweep,
         Finished
     };
--- a/js/src/jspubtd.h
+++ b/js/src/jspubtd.h
@@ -167,40 +167,67 @@ typedef bool                    (*JSInit
 
 /*
  * Generic trace operation that calls JS_CallTracer on each traceable thing
  * stored in data.
  */
 typedef void
 (* JSTraceDataOp)(JSTracer *trc, void *data);
 
+namespace js {
+namespace gc {
+class StoreBuffer;
+}
+}
+
 namespace JS {
 
 typedef void (*OffThreadCompileCallback)(void *token, void *callbackData);
 
 namespace shadow {
 
 struct Runtime
 {
     /* Restrict zone access during Minor GC. */
     bool needsBarrier_;
 
 #ifdef JSGC_GENERATIONAL
     /* Allow inlining of Nursery::isInside. */
     uintptr_t gcNurseryStart_;
     uintptr_t gcNurseryEnd_;
+
+  private:
+    js::gc::StoreBuffer *gcStoreBufferPtr_;
 #endif
 
-    Runtime()
+  public:
+    Runtime(
+#ifdef JSGC_GENERATIONAL
+        js::gc::StoreBuffer *gcStoreBufferPtr
+#endif
+    )
       : needsBarrier_(false)
 #ifdef JSGC_GENERATIONAL
       , gcNurseryStart_(0)
       , gcNurseryEnd_(0)
+      , gcStoreBufferPtr_(gcStoreBufferPtr)
 #endif
     {}
+
+    bool needsBarrier() const {
+        return needsBarrier_;
+    }
+
+#ifdef JSGC_GENERATIONAL
+    js::gc::StoreBuffer *gcStoreBufferPtr() { return gcStoreBufferPtr_; }
+#endif
+
+    static JS::shadow::Runtime *asShadowRuntime(JSRuntime *rt) {
+        return reinterpret_cast<JS::shadow::Runtime*>(rt);
+    }
 };
 
 } /* namespace shadow */
 } /* namespace JS */
 
 namespace js {
 
 /*
--- a/js/src/vm/Runtime.cpp
+++ b/js/src/vm/Runtime.cpp
@@ -93,17 +93,22 @@ PerThreadData::addToThreadList()
 void
 PerThreadData::removeFromThreadList()
 {
     JS_ASSERT(CurrentThreadCanAccessRuntime(runtime_));
     removeFrom(runtime_->threadList);
 }
 
 JSRuntime::JSRuntime(JSUseHelperThreads useHelperThreads)
-  : mainThread(this),
+  : JS::shadow::Runtime(
+#ifdef JSGC_GENERATIONAL
+        &gcStoreBuffer
+#endif
+    ),
+    mainThread(this),
     interrupt(0),
     handlingSignal(false),
     operationCallback(NULL),
 #ifdef JS_THREADSAFE
     operationCallbackLock(NULL),
 #ifdef DEBUG
     operationCallbackOwner(NULL),
 #endif
--- a/js/src/vm/Runtime.h
+++ b/js/src/vm/Runtime.h
@@ -1221,20 +1221,16 @@ struct JSRuntime : public JS::shadow::Ru
      */
     volatile ptrdiff_t  gcMallocBytes;
 
   public:
     void setNeedsBarrier(bool needs) {
         needsBarrier_ = needs;
     }
 
-    bool needsBarrier() const {
-        return needsBarrier_;
-    }
-
     struct ExtraTracer {
         JSTraceDataOp op;
         void *data;
 
         ExtraTracer()
           : op(NULL), data(NULL)
         {}
         ExtraTracer(JSTraceDataOp op, void *data)