From 6af0765bfc83a5e2152474791603c04971288cad Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 4 Sep 2013 19:19:04 -0700 Subject: [PATCH] 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 | 42 +++++++++++++++++++++++++++++++++++++++++- js/src/gc/Barrier.h | 10 ++++++++-- js/src/gc/Heap.h | 18 ++++++++++++------ js/src/gc/Zone.cpp | 2 +- js/src/gc/Zone.h | 24 +----------------------- js/src/jspubtd.h | 29 ++++++++++++++++++++++++++++- js/src/vm/Runtime.cpp | 7 ++++++- js/src/vm/Runtime.h | 4 ---- 8 files changed, 97 insertions(+), 39 deletions(-) diff --git a/js/public/HeapAPI.h b/js/public/HeapAPI.h index ec83caf9e8bd..5b13c94043ca 100644 --- a/js/public/HeapAPI.h +++ b/js/public/HeapAPI.h @@ -13,6 +13,12 @@ /* 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; @@ -57,9 +63,43 @@ struct ArenaHeader 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(zone); + } }; } /* namespace shadow */ diff --git a/js/src/gc/Barrier.h b/js/src/gc/Barrier.h index 1f89937fcac8..5c6dbcefcc24 100644 --- a/js/src/gc/Barrier.h +++ b/js/src/gc/Barrier.h @@ -424,14 +424,20 @@ class EncapsulatedValue : public ValueOperations 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(v.toGCThing())->runtimeFromMainThread(); } - static inline JSRuntime *runtimeFromAnyThread(const Value &v) { + static JSRuntime *runtimeFromAnyThread(const Value &v) { JS_ASSERT(v.isMarkable()); return static_cast(v.toGCThing())->runtimeFromAnyThread(); } + static JS::shadow::Runtime *shadowRuntimeFromMainThread(const Value &v) { + return reinterpret_cast(runtimeFromMainThread(v)); + } + static JS::shadow::Runtime *shadowRuntimeFromAnyThread(const Value &v) { + return reinterpret_cast(runtimeFromAnyThread(v)); + } private: friend class ValueOperations; diff --git a/js/src/gc/Heap.h b/js/src/gc/Heap.h index 6a0321ee027b..26678e57049f 100644 --- a/js/src/gc/Heap.h +++ b/js/src/gc/Heap.h @@ -22,17 +22,16 @@ 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 { @@ -106,6 +105,7 @@ struct Cell // 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; @@ -969,6 +969,12 @@ Cell::runtimeFromAnyThread() const return chunk()->info.runtime; } +inline JS::shadow::Runtime * +Cell::shadowRuntimeFromAnyThread() const +{ + return reinterpret_cast(runtimeFromAnyThread()); +} + AllocKind Cell::tenuredGetAllocKind() const { diff --git a/js/src/gc/Zone.cpp b/js/src/gc/Zone.cpp index e09b40d86dc8..c2069d6212d0 100644 --- a/js/src/gc/Zone.cpp +++ b/js/src/gc/Zone.cpp @@ -24,7 +24,7 @@ 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), diff --git a/js/src/gc/Zone.h b/js/src/gc/Zone.h index a4fe007856d9..838d0f352e3c 100644 --- a/js/src/gc/Zone.h +++ b/js/src/gc/Zone.h @@ -92,13 +92,11 @@ namespace JS { * zone.) */ -struct Zone : private JS::shadow::Zone, +struct Zone : public JS::shadow::Zone, public js::gc::GraphNodeBase, public js::MallocProvider { private: - JSRuntime *runtime_; - friend bool js::CurrentThreadCanAccessZone(Zone *zone); public: @@ -114,21 +112,6 @@ struct Zone : private JS::shadow::Zone, 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; } @@ -148,11 +131,6 @@ struct Zone : private JS::shadow::Zone, return offsetof(Zone, needsBarrier_); } - js::GCMarker *barrierTracer() { - JS_ASSERT(needsBarrier_); - return &runtimeFromMainThread()->gcMarker; - } - public: enum CompartmentGCState { NoGC, diff --git a/js/src/jspubtd.h b/js/src/jspubtd.h index 1d5d7277d088..beb16155a000 100644 --- a/js/src/jspubtd.h +++ b/js/src/jspubtd.h @@ -172,6 +172,12 @@ typedef bool (*JSInitCallback)(void); typedef void (* JSTraceDataOp)(JSTracer *trc, void *data); +namespace js { +namespace gc { +class StoreBuffer; +} +} + namespace JS { typedef void (*OffThreadCompileCallback)(void *token, void *callbackData); @@ -187,15 +193,36 @@ struct Runtime /* 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(rt); + } }; } /* namespace shadow */ diff --git a/js/src/vm/Runtime.cpp b/js/src/vm/Runtime.cpp index f7c587502185..a9444388a9a2 100644 --- a/js/src/vm/Runtime.cpp +++ b/js/src/vm/Runtime.cpp @@ -98,7 +98,12 @@ PerThreadData::removeFromThreadList() } JSRuntime::JSRuntime(JSUseHelperThreads useHelperThreads) - : mainThread(this), + : JS::shadow::Runtime( +#ifdef JSGC_GENERATIONAL + &gcStoreBuffer +#endif + ), + mainThread(this), interrupt(0), handlingSignal(false), operationCallback(NULL), diff --git a/js/src/vm/Runtime.h b/js/src/vm/Runtime.h index 873532bc09b4..438f5bf858dd 100644 --- a/js/src/vm/Runtime.h +++ b/js/src/vm/Runtime.h @@ -1226,10 +1226,6 @@ struct JSRuntime : public JS::shadow::Runtime, needsBarrier_ = needs; } - bool needsBarrier() const { - return needsBarrier_; - } - struct ExtraTracer { JSTraceDataOp op; void *data;