Bug 910771 (part 2) - Move some stuff from JS::Zone to JS::shadow::Zone, and from JSRuntime to JS::shadow::Runtime.h. r=terrence.

This commit is contained in:
Nicholas Nethercote 2013-09-04 19:19:04 -07:00
parent 3e6eda137c
commit 73b867f80f
8 changed files with 97 additions and 39 deletions

View File

@ -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<JS::shadow::Zone*>(zone);
}
};
} /* namespace shadow */

View File

@ -424,14 +424,20 @@ class EncapsulatedValue : public ValueOperations<EncapsulatedValue>
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>;

View File

@ -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<JS::shadow::Runtime*>(runtimeFromAnyThread());
}
AllocKind
Cell::tenuredGetAllocKind() const
{

View File

@ -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),

View File

@ -92,13 +92,11 @@ namespace JS {
* 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:
@ -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,

View File

@ -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<JS::shadow::Runtime*>(rt);
}
};
} /* namespace shadow */

View File

@ -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),

View File

@ -1226,10 +1226,6 @@ struct JSRuntime : public JS::shadow::Runtime,
needsBarrier_ = needs;
}
bool needsBarrier() const {
return needsBarrier_;
}
struct ExtraTracer {
JSTraceDataOp op;
void *data;