Bug 902095 - Allow accessing the compartment/zone for ExclusiveContext, r=billm.

This commit is contained in:
Brian Hackett 2013-08-13 09:13:46 -06:00
Родитель 6c8dc2c0b0
Коммит ca2162becd
30 изменённых файлов: 204 добавлений и 194 удалений

Просмотреть файл

@ -44,16 +44,6 @@ namespace js {}
#define JS_ALWAYS_TRUE(expr) MOZ_ALWAYS_TRUE(expr)
#define JS_ALWAYS_FALSE(expr) MOZ_ALWAYS_FALSE(expr)
#ifdef DEBUG
# ifdef JS_THREADSAFE
# define JS_THREADSAFE_ASSERT(expr) JS_ASSERT(expr)
# else
# define JS_THREADSAFE_ASSERT(expr) ((void) 0)
# endif
#else
# define JS_THREADSAFE_ASSERT(expr) ((void) 0)
#endif
#if defined(DEBUG)
# define JS_DIAGNOSTICS_ASSERT(expr) MOZ_ASSERT(expr)
#elif defined(JS_CRASH_DIAGNOSTICS)

Просмотреть файл

@ -206,7 +206,7 @@ static bool
CompileRegExpObject(JSContext *cx, RegExpObjectBuilder &builder, CallArgs args)
{
if (args.length() == 0) {
RegExpStatics *res = cx->regExpStatics();
RegExpStatics *res = cx->global()->getRegExpStatics();
Rooted<JSAtom*> empty(cx, cx->runtime()->emptyString);
RegExpObject *reobj = builder.build(empty, res->getFlags());
if (!reobj)
@ -295,7 +295,7 @@ CompileRegExpObject(JSContext *cx, RegExpObjectBuilder &builder, CallArgs args)
if (!js::RegExpShared::checkSyntax(cx, NULL, escapedSourceStr))
return false;
RegExpStatics *res = cx->regExpStatics();
RegExpStatics *res = cx->global()->getRegExpStatics();
RegExpObject *reobj = builder.build(escapedSourceStr, RegExpFlag(flags | res->getFlags()));
if (!reobj)
return false;
@ -397,7 +397,7 @@ static const JSFunctionSpec regexp_methods[] = {
static bool \
name(JSContext *cx, HandleObject obj, HandleId id, MutableHandleValue vp) \
{ \
RegExpStatics *res = cx->regExpStatics(); \
RegExpStatics *res = cx->global()->getRegExpStatics(); \
code; \
}
@ -423,7 +423,7 @@ DEFINE_STATIC_GETTER(static_paren9_getter, return res->createParen(cx, 9,
static bool \
name(JSContext *cx, HandleObject obj, HandleId id, bool strict, MutableHandleValue vp)\
{ \
RegExpStatics *res = cx->regExpStatics(); \
RegExpStatics *res = cx->global()->getRegExpStatics(); \
code; \
return true; \
}
@ -538,7 +538,9 @@ js::ExecuteRegExp(JSContext *cx, HandleObject regexp, HandleString string,
if (!reobj->getShared(cx, &re))
return RegExpRunStatus_Error;
RegExpStatics *res = (staticsUpdate == UpdateRegExpStatics) ? cx->regExpStatics() : NULL;
RegExpStatics *res = (staticsUpdate == UpdateRegExpStatics)
? cx->global()->getRegExpStatics()
: NULL;
/* Step 3. */
Rooted<JSLinearString*> input(cx, string->ensureLinear(cx));

Просмотреть файл

@ -6225,7 +6225,7 @@ Parser<ParseHandler>::newRegExp()
RegExpFlag flags = tokenStream.currentToken().regExpFlags();
Rooted<RegExpObject*> reobj(context);
if (RegExpStatics *res = context->regExpStatics())
if (RegExpStatics *res = context->global()->getRegExpStatics())
reobj = RegExpObject::create(context, res, chars.get(), length, flags, &tokenStream);
else
reobj = RegExpObject::createNoStatics(context, chars.get(), length, flags, &tokenStream);

Просмотреть файл

@ -182,7 +182,7 @@ HeapValue::set(Zone *zone, const Value &v)
#ifdef DEBUG
if (value.isMarkable()) {
JS_ASSERT(ZoneOfValue(value) == zone ||
ZoneOfValue(value) == zone->runtimeFromMainThread()->atomsCompartment->zone());
zone->runtimeFromAnyThread()->isAtomsZone(ZoneOfValue(value)));
}
#endif

Просмотреть файл

@ -145,12 +145,10 @@ CheckMarkedThing(JSTracer *trc, T *thing)
JS_ASSERT(MapTypeToTraceKind<T>::kind == GetGCThingTraceKind(thing));
JS_ASSERT_IF(rt->gcStrictCompartmentChecking,
thing->zone()->isCollecting() ||
thing->zone() == rt->atomsCompartment->zone());
thing->zone()->isCollecting() || rt->isAtomsZone(thing->zone()));
JS_ASSERT_IF(IS_GC_MARKING_TRACER(trc) && AsGCMarker(trc)->getMarkColor() == GRAY,
thing->zone()->isGCMarkingGray() ||
thing->zone() == rt->atomsCompartment->zone());
thing->zone()->isGCMarkingGray() || rt->isAtomsZone(thing->zone()));
/*
* Try to assert that the thing is allocated. This is complicated by the
@ -742,7 +740,7 @@ gc::IsCellAboutToBeFinalized(Cell **thingp)
#define JS_COMPARTMENT_ASSERT_STR(rt, thing) \
JS_ASSERT((thing)->zone()->isGCMarking() || \
(thing)->zone() == (rt)->atomsCompartment->zone());
(rt)->isAtomsZone((thing)->zone()));
static void
PushMarkStack(GCMarker *gcmarker, JSObject *thing)
@ -1411,8 +1409,7 @@ GCMarker::processMarkStackTop(SliceBudget &budget)
if (v.isString()) {
JSString *str = v.toString();
JS_COMPARTMENT_ASSERT_STR(runtime, str);
JS_ASSERT(str->zone() == runtime->atomsCompartment->zone() ||
str->zone() == obj->zone());
JS_ASSERT(runtime->isAtomsZone(str->zone()) || str->zone() == obj->zone());
if (str->markIfUnmarked())
ScanString(this, str);
} else if (v.isObject()) {

Просмотреть файл

@ -688,7 +688,7 @@ js::gc::MarkRuntime(JSTracer *trc, bool useSavedRoots)
}
if (!trc->runtime->isHeapMinorCollecting() &&
(!IS_GC_MARKING_TRACER(trc) || rt->atomsCompartment->zone()->isCollecting()))
(!IS_GC_MARKING_TRACER(trc) || rt->atomsCompartment()->zone()->isCollecting()))
{
MarkAtoms(trc);
#ifdef JS_ION

Просмотреть файл

@ -68,7 +68,7 @@ CheckStackRoot(JSRuntime *rt, uintptr_t *w, Rooter *begin, Rooter *end)
return;
/* Don't check atoms as these will never be subject to generational collection. */
if (static_cast<Cell *>(thing)->tenuredZone() == rt->atomsCompartment->zone())
if (rt->isAtomsZone(static_cast<Cell *>(thing)->tenuredZone()))
return;
/*

Просмотреть файл

@ -282,7 +282,7 @@ IonRuntime::debugTrapHandler(JSContext *cx)
// IonRuntime code stubs are shared across compartments and have to
// be allocated in the atoms compartment.
AutoLockForExclusiveAccess lock(cx);
AutoCompartment ac(cx, cx->runtime()->atomsCompartment);
AutoCompartment ac(cx, cx->runtime()->atomsCompartment());
debugTrapHandler_ = generateDebugTrapHandler(cx);
}
return debugTrapHandler_;
@ -385,7 +385,7 @@ FinishAllOffThreadCompilations(IonCompartment *ion)
IonRuntime::Mark(JSTracer *trc)
{
JS_ASSERT(!trc->runtime->isHeapMinorCollecting());
Zone *zone = trc->runtime->atomsCompartment->zone();
Zone *zone = trc->runtime->atomsCompartment()->zone();
for (gc::CellIterUnderGC i(zone, gc::FINALIZE_IONCODE); !i.done(); i.next()) {
IonCode *code = i.get<IonCode>();
MarkIonCodeRoot(trc, &code, "wrapper");

Просмотреть файл

@ -1340,7 +1340,7 @@ JS_PUBLIC_API(bool)
JS_InitStandardClasses(JSContext *cx, JSObject *objArg)
{
RootedObject obj(cx, objArg);
JS_THREADSAFE_ASSERT(cx->compartment() != cx->runtime()->atomsCompartment);
JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
@ -2911,7 +2911,7 @@ JS_NewGlobalObject(JSContext *cx, JSClass *clasp, JSPrincipals *principals,
{
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
JS_THREADSAFE_ASSERT(cx->compartment() != cx->runtime()->atomsCompartment);
JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
JS_ASSERT(!cx->isExceptionPending());
JSRuntime *rt = cx->runtime();
@ -2966,7 +2966,7 @@ JS_NewObject(JSContext *cx, JSClass *jsclasp, JSObject *protoArg, JSObject *pare
{
RootedObject proto(cx, protoArg);
RootedObject parent(cx, parentArg);
JS_THREADSAFE_ASSERT(cx->compartment() != cx->runtime()->atomsCompartment);
JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, proto, parent);
@ -2996,7 +2996,7 @@ JS_NewObjectWithGivenProto(JSContext *cx, JSClass *jsclasp, JSObject *protoArg,
{
RootedObject proto(cx, protoArg);
RootedObject parent(cx, parentArg);
JS_THREADSAFE_ASSERT(cx->compartment() != cx->runtime()->atomsCompartment);
JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, proto, parent);
@ -4249,7 +4249,7 @@ JS_NewArrayObject(JSContext *cx, int length, jsval *vector)
{
AutoArrayRooter tvr(cx, length, vector);
JS_THREADSAFE_ASSERT(cx->compartment() != cx->runtime()->atomsCompartment);
JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
@ -4347,7 +4347,7 @@ JS_NewFunction(JSContext *cx, JSNative native, unsigned nargs, unsigned flags,
JSObject *parentArg, const char *name)
{
RootedObject parent(cx, parentArg);
JS_THREADSAFE_ASSERT(cx->compartment() != cx->runtime()->atomsCompartment);
JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
@ -4370,7 +4370,7 @@ JS_NewFunctionById(JSContext *cx, JSNative native, unsigned nargs, unsigned flag
{
RootedObject parent(cx, parentArg);
JS_ASSERT(JSID_IS_STRING(id));
JS_THREADSAFE_ASSERT(cx->compartment() != cx->runtime()->atomsCompartment);
JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, parent);
@ -4519,7 +4519,7 @@ js_generic_native_method_dispatcher(JSContext *cx, unsigned argc, Value *vp)
JS_PUBLIC_API(bool)
JS_DefineFunctions(JSContext *cx, JSObject *objArg, const JSFunctionSpec *fs)
{
JS_THREADSAFE_ASSERT(cx->compartment() != cx->runtime()->atomsCompartment);
JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, objArg);
@ -4619,7 +4619,7 @@ JS_DefineFunction(JSContext *cx, JSObject *objArg, const char *name, JSNative ca
unsigned nargs, unsigned attrs)
{
RootedObject obj(cx, objArg);
JS_THREADSAFE_ASSERT(cx->compartment() != cx->runtime()->atomsCompartment);
JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, obj);
@ -4636,7 +4636,7 @@ JS_DefineUCFunction(JSContext *cx, JSObject *objArg,
unsigned nargs, unsigned attrs)
{
RootedObject obj(cx, objArg);
JS_THREADSAFE_ASSERT(cx->compartment() != cx->runtime()->atomsCompartment);
JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, obj);
@ -4653,7 +4653,7 @@ JS_DefineFunctionById(JSContext *cx, JSObject *objArg, jsid id_, JSNative call,
{
RootedObject obj(cx, objArg);
RootedId id(cx, id_);
JS_THREADSAFE_ASSERT(cx->compartment() != cx->runtime()->atomsCompartment);
JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, obj);
@ -4797,7 +4797,7 @@ JSScript *
JS::Compile(JSContext *cx, HandleObject obj, CompileOptions options,
const jschar *chars, size_t length)
{
JS_THREADSAFE_ASSERT(cx->compartment() != cx->runtime()->atomsCompartment);
JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, obj);
@ -4950,7 +4950,7 @@ JS::CompileFunction(JSContext *cx, HandleObject obj, CompileOptions options,
const char *name, unsigned nargs, const char **argnames,
const jschar *chars, size_t length)
{
JS_THREADSAFE_ASSERT(cx->compartment() != cx->runtime()->atomsCompartment);
JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, obj);
@ -5051,7 +5051,7 @@ JS_CompileFunction(JSContext *cx, JSObject *objArg, const char *name,
JS_PUBLIC_API(JSString *)
JS_DecompileScript(JSContext *cx, JSScript *scriptArg, const char *name, unsigned indent)
{
JS_THREADSAFE_ASSERT(cx->compartment() != cx->runtime()->atomsCompartment);
JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
@ -5068,7 +5068,7 @@ JS_DecompileScript(JSContext *cx, JSScript *scriptArg, const char *name, unsigne
JS_PUBLIC_API(JSString *)
JS_DecompileFunction(JSContext *cx, JSFunction *funArg, unsigned indent)
{
JS_THREADSAFE_ASSERT(cx->compartment() != cx->runtime()->atomsCompartment);
JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, funArg);
@ -5079,7 +5079,7 @@ JS_DecompileFunction(JSContext *cx, JSFunction *funArg, unsigned indent)
JS_PUBLIC_API(JSString *)
JS_DecompileFunctionBody(JSContext *cx, JSFunction *funArg, unsigned indent)
{
JS_THREADSAFE_ASSERT(cx->compartment() != cx->runtime()->atomsCompartment);
JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, funArg);
@ -5093,7 +5093,7 @@ JS_ExecuteScript(JSContext *cx, JSObject *objArg, JSScript *scriptArg, jsval *rv
RootedObject obj(cx, objArg);
RootedScript script(cx, scriptArg);
JS_THREADSAFE_ASSERT(cx->compartment() != cx->runtime()->atomsCompartment);
JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, obj);
@ -5134,7 +5134,7 @@ extern JS_PUBLIC_API(bool)
JS::Evaluate(JSContext *cx, HandleObject obj, CompileOptions options,
const jschar *chars, size_t length, jsval *rval)
{
JS_THREADSAFE_ASSERT(cx->compartment() != cx->runtime()->atomsCompartment);
JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, obj);
@ -5308,7 +5308,7 @@ JS_CallFunction(JSContext *cx, JSObject *objArg, JSFunction *fun, unsigned argc,
jsval *rval)
{
RootedObject obj(cx, objArg);
JS_THREADSAFE_ASSERT(cx->compartment() != cx->runtime()->atomsCompartment);
JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, obj, fun, JSValueArray(argv, argc));
@ -5326,7 +5326,7 @@ JS_CallFunctionName(JSContext *cx, JSObject *objArg, const char *name, unsigned
jsval *rval)
{
RootedObject obj(cx, objArg);
JS_THREADSAFE_ASSERT(cx->compartment() != cx->runtime()->atomsCompartment);
JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, obj, JSValueArray(argv, argc));
@ -5353,7 +5353,7 @@ JS_CallFunctionValue(JSContext *cx, JSObject *objArg, jsval fval, unsigned argc,
jsval *rval)
{
RootedObject obj(cx, objArg);
JS_THREADSAFE_ASSERT(cx->compartment() != cx->runtime()->atomsCompartment);
JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
assertSameCompartment(cx, obj, fval, JSValueArray(argv, argc));

Просмотреть файл

@ -117,13 +117,14 @@ const char js_yield_str[] = "yield";
bool
js::InitAtoms(JSRuntime *rt)
{
return rt->atoms.init(JS_STRING_HASH_COUNT);
AutoLockForExclusiveAccess lock(rt);
return rt->atoms().init(JS_STRING_HASH_COUNT);
}
void
js::FinishAtoms(JSRuntime *rt)
{
AtomSet &atoms = rt->atoms;
AtomSet &atoms = rt->atoms();
if (!atoms.initialized()) {
/*
* We are called with uninitialized state when JS_NewRuntime fails and
@ -181,7 +182,7 @@ void
js::MarkAtoms(JSTracer *trc)
{
JSRuntime *rt = trc->runtime;
for (AtomSet::Range r = rt->atoms.all(); !r.empty(); r.popFront()) {
for (AtomSet::Range r = rt->atoms().all(); !r.empty(); r.popFront()) {
AtomStateEntry entry = r.front();
if (!entry.isTagged())
continue;
@ -195,7 +196,7 @@ js::MarkAtoms(JSTracer *trc)
void
js::SweepAtoms(JSRuntime *rt)
{
for (AtomSet::Enum e(rt->atoms); !e.empty(); e.popFront()) {
for (AtomSet::Enum e(rt->atoms()); !e.empty(); e.popFront()) {
AtomStateEntry entry = e.front();
JSAtom *atom = entry.asPtr();
bool isDying = IsStringAboutToBeFinalized(&atom);
@ -215,7 +216,9 @@ AtomIsInterned(JSContext *cx, JSAtom *atom)
if (StaticStrings::isStatic(atom))
return true;
AtomSet::Ptr p = cx->runtime()->atoms.lookup(atom);
AutoLockForExclusiveAccess lock(cx);
AtomSet::Ptr p = cx->runtime()->atoms().lookup(atom);
if (!p)
return false;

Просмотреть файл

@ -330,41 +330,39 @@ class ExclusiveContext : public ThreadSafeContext
// If required, pause this thread until notified to continue by the main thread.
inline void maybePause() const;
inline bool typeInferenceEnabled() const;
// Threads with an ExclusiveContext may freely access any data in their
// compartment and zone.
JSCompartment *compartment() const {
JS_ASSERT_IF(runtime_->isAtomsCompartment(compartment_),
runtime_->currentThreadHasExclusiveAccess());
return compartment_;
}
JS::Zone *zone() const {
JS_ASSERT_IF(!compartment(), !zone_);
JS_ASSERT_IF(compartment(), js::GetCompartmentZone(compartment()) == zone_);
return zone_;
}
// Per compartment data that can be accessed freely from an ExclusiveContext.
inline RegExpCompartment &regExps();
inline RegExpStatics *regExpStatics();
inline PropertyTree &propertyTree();
inline BaseShapeSet &baseShapes();
inline InitialShapeSet &initialShapes();
inline DtoaCache &dtoaCache();
// Zone local methods that can be used freely from an ExclusiveContext.
inline bool typeInferenceEnabled() const;
types::TypeObject *getNewType(Class *clasp, TaggedProto proto, JSFunction *fun = NULL);
// Current global. This is only safe to use within the scope of the
// AutoCompartment from which it's called.
inline js::Handle<js::GlobalObject*> global() const;
// Methods to access runtime wide data that must be protected by locks.
// Methods to access runtime data that must be protected by locks.
frontend::ParseMapPool &parseMapPool() {
JS_ASSERT(runtime_->currentThreadHasExclusiveAccess());
return runtime_->parseMapPool;
return runtime_->parseMapPool();
}
AtomSet &atoms() {
JS_ASSERT(runtime_->currentThreadHasExclusiveAccess());
return runtime_->atoms;
return runtime_->atoms();
}
JSCompartment *atomsCompartment() {
JS_ASSERT(runtime_->currentThreadHasExclusiveAccess());
return runtime_->atomsCompartment;
return runtime_->atomsCompartment();
}
ScriptDataTable &scriptDataTable() {
JS_ASSERT(runtime_->currentThreadHasExclusiveAccess());
return runtime_->scriptDataTable;
return runtime_->scriptDataTable();
}
};
@ -383,13 +381,6 @@ struct JSContext : public js::ExclusiveContext,
~JSContext();
JSRuntime *runtime() const { return runtime_; }
JSCompartment *compartment() const { return compartment_; }
inline JS::Zone *zone() const {
JS_ASSERT_IF(!compartment(), !zone_);
JS_ASSERT_IF(compartment(), js::GetCompartmentZone(compartment()) == zone_);
return zone_;
}
js::PerThreadData &mainThread() const { return runtime()->mainThread; }
friend class js::ExclusiveContext;

Просмотреть файл

@ -45,16 +45,16 @@ class CompartmentChecker
MOZ_CRASH();
}
/* Note: should only be used when neither c1 nor c2 may be the default compartment. */
/* Note: should only be used when neither c1 nor c2 may be the atoms compartment. */
static void check(JSCompartment *c1, JSCompartment *c2) {
JS_ASSERT(c1 != c1->runtimeFromMainThread()->atomsCompartment);
JS_ASSERT(c2 != c2->runtimeFromMainThread()->atomsCompartment);
JS_ASSERT(!c1->runtimeFromMainThread()->isAtomsCompartment(c1));
JS_ASSERT(!c2->runtimeFromMainThread()->isAtomsCompartment(c2));
if (c1 != c2)
fail(c1, c2);
}
void check(JSCompartment *c) {
if (c && c != compartment->runtimeFromMainThread()->atomsCompartment) {
if (c && !compartment->runtimeFromMainThread()->isAtomsCompartment(c)) {
if (!compartment)
compartment = c;
else if (c != compartment)
@ -338,36 +338,6 @@ GetNativeStackLimit(ExclusiveContext *cx)
return cx->perThreadData->nativeStackLimit;
}
inline RegExpCompartment &
ExclusiveContext::regExps()
{
return compartment_->regExps;
}
inline PropertyTree&
ExclusiveContext::propertyTree()
{
return compartment_->propertyTree;
}
inline BaseShapeSet &
ExclusiveContext::baseShapes()
{
return compartment_->baseShapes;
}
inline InitialShapeSet &
ExclusiveContext::initialShapes()
{
return compartment_->initialShapes;
}
inline DtoaCache &
ExclusiveContext::dtoaCache()
{
return compartment_->dtoaCache;
}
inline void
ExclusiveContext::maybePause() const
{
@ -505,7 +475,7 @@ inline void
js::ExclusiveContext::setCompartment(JSCompartment *comp)
{
// ExclusiveContexts can only be in the atoms zone or in exclusive zones.
JS_ASSERT_IF(!isJSContext() && comp != runtime_->atomsCompartment,
JS_ASSERT_IF(!isJSContext() && !runtime_->isAtomsCompartment(comp),
comp->zone()->usedByExclusiveThread);
// Normal JSContexts cannot enter exclusive zones.
@ -513,12 +483,12 @@ js::ExclusiveContext::setCompartment(JSCompartment *comp)
!comp->zone()->usedByExclusiveThread);
// Only one thread can be in the atoms compartment at a time.
JS_ASSERT_IF(comp == runtime_->atomsCompartment,
JS_ASSERT_IF(runtime_->isAtomsCompartment(comp),
runtime_->currentThreadHasExclusiveAccess());
// Make sure that the atoms compartment has its own zone.
JS_ASSERT_IF(comp && comp != runtime_->atomsCompartment,
comp->zone() != runtime_->atomsCompartment->zone());
JS_ASSERT_IF(comp && !runtime_->isAtomsCompartment(comp),
!runtime_->isAtomsZone(comp->zone()));
// Both the current and the new compartment should be properly marked as
// entered at this point.

Просмотреть файл

@ -128,9 +128,10 @@ JSRuntime::createIonRuntime(JSContext *cx)
js_delete(ionRuntime_);
ionRuntime_ = NULL;
if (cx->runtime()->atomsCompartment->ionCompartment_) {
js_delete(cx->runtime()->atomsCompartment->ionCompartment_);
cx->runtime()->atomsCompartment->ionCompartment_ = NULL;
JSCompartment *comp = cx->runtime()->atomsCompartment();
if (comp->ionCompartment_) {
js_delete(comp->ionCompartment_);
comp->ionCompartment_ = NULL;
}
return NULL;
@ -200,7 +201,7 @@ JSCompartment::wrap(JSContext *cx, MutableHandleValue vp, HandleObject existingA
JSRuntime *rt = runtimeFromMainThread();
JS_ASSERT(cx->compartment() == this);
JS_ASSERT(this != rt->atomsCompartment);
JS_ASSERT(!rt->isAtomsCompartment(this));
JS_ASSERT_IF(existingArg, existingArg->compartment() == cx->compartment());
JS_ASSERT_IF(existingArg, vp.isObject());
JS_ASSERT_IF(existingArg, IsDeadProxyObject(existingArg));
@ -224,7 +225,7 @@ JSCompartment::wrap(JSContext *cx, MutableHandleValue vp, HandleObject existingA
/* If the string is an atom, we don't have to copy. */
if (str->isAtom()) {
JS_ASSERT(str->zone() == cx->runtime()->atomsCompartment->zone());
JS_ASSERT(cx->runtime()->isAtomsZone(str->zone()));
return true;
}
}

Просмотреть файл

@ -394,6 +394,12 @@ struct JSCompartment
#endif
};
inline bool
JSRuntime::isAtomsZone(JS::Zone *zone)
{
return zone == atomsCompartment_->zone();
}
// For use when changing the debug mode flag on one or more compartments.
// Do not run scripts in any compartment that is scheduled for GC using this
// object. See comment in updateForDebugMode.

Просмотреть файл

@ -277,7 +277,7 @@ JS_FRIEND_API(bool)
JS_DefineFunctionsWithHelp(JSContext *cx, JSObject *objArg, const JSFunctionSpecWithHelp *fs)
{
RootedObject obj(cx, objArg);
JS_ASSERT(cx->compartment() != cx->runtime()->atomsCompartment);
JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
CHECK_REQUEST(cx);
assertSameCompartment(cx, obj);
@ -338,7 +338,7 @@ js::IsSystemZone(Zone *zone)
JS_FRIEND_API(bool)
js::IsAtomsCompartment(JSCompartment *comp)
{
return comp == comp->runtimeFromAnyThread()->atomsCompartment;
return comp->runtimeFromAnyThread()->isAtomsCompartment(comp);
}
JS_FRIEND_API(bool)
@ -431,7 +431,7 @@ js::DefineFunctionWithReserved(JSContext *cx, JSObject *objArg, const char *name
unsigned nargs, unsigned attrs)
{
RootedObject obj(cx, objArg);
JS_THREADSAFE_ASSERT(cx->compartment() != cx->runtime()->atomsCompartment);
JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
CHECK_REQUEST(cx);
assertSameCompartment(cx, obj);
JSAtom *atom = Atomize(cx, name, strlen(name));
@ -446,7 +446,7 @@ js::NewFunctionWithReserved(JSContext *cx, JSNative native, unsigned nargs, unsi
JSObject *parentArg, const char *name)
{
RootedObject parent(cx, parentArg);
JS_THREADSAFE_ASSERT(cx->compartment() != cx->runtime()->atomsCompartment);
JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
CHECK_REQUEST(cx);
assertSameCompartment(cx, parent);
@ -469,7 +469,7 @@ js::NewFunctionByIdWithReserved(JSContext *cx, JSNative native, unsigned nargs,
{
RootedObject parent(cx, parentArg);
JS_ASSERT(JSID_IS_STRING(id));
JS_THREADSAFE_ASSERT(cx->compartment() != cx->runtime()->atomsCompartment);
JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
CHECK_REQUEST(cx);
assertSameCompartment(cx, parent);

Просмотреть файл

@ -1012,7 +1012,6 @@ js_FinishGC(JSRuntime *rt)
}
rt->zones.clear();
rt->atomsCompartment = NULL;
rt->gcSystemAvailableChunkListHead = NULL;
rt->gcUserAvailableChunkListHead = NULL;
@ -1961,7 +1960,7 @@ js::TriggerZoneGC(Zone *zone, JS::gcreason::Reason reason)
return;
}
if (zone == rt->atomsCompartment->zone()) {
if (rt->isAtomsZone(zone)) {
/* We can't do a zone GC of the atoms compartment. */
TriggerGC(rt, reason);
return;
@ -2525,7 +2524,7 @@ SweepCompartments(FreeOp *fop, Zone *zone, bool keepAtleastOne, bool lastGC)
bool foundOne = false;
while (read < end) {
JSCompartment *comp = *read++;
JS_ASSERT(comp != rt->atomsCompartment);
JS_ASSERT(!rt->isAtomsCompartment(comp));
/*
* Don't delete the last compartment if all the ones before it were
@ -2558,7 +2557,7 @@ SweepZones(FreeOp *fop, bool lastGC)
Zone **end = rt->zones.end();
Zone **write = read;
JS_ASSERT(rt->zones.length() >= 1);
JS_ASSERT(rt->zones[0] == rt->atomsCompartment->zone());
JS_ASSERT(rt->isAtomsZone(rt->zones[0]));
while (read < end) {
Zone *zone = *read++;
@ -2597,7 +2596,7 @@ PurgeRuntime(JSRuntime *rt)
for (ThreadDataIter iter(rt); !iter.done(); iter.next())
activeCompilations |= iter->activeCompilations;
if (!activeCompilations)
rt->parseMapPool.purgeAll();
rt->parseMapPool().purgeAll();
}
static bool
@ -2658,7 +2657,7 @@ CheckCompartment(CompartmentCheckTracer *trc, JSCompartment *thingCompartment,
Cell *thing, JSGCTraceKind kind)
{
JS_ASSERT(thingCompartment == trc->compartment ||
thingCompartment == trc->runtime->atomsCompartment ||
trc->runtime->isAtomsCompartment(thingCompartment) ||
(trc->srcKind == JSTRACE_OBJECT &&
InCrossCompartmentMap((JSObject *)trc->src, thing, kind)));
}
@ -2689,7 +2688,7 @@ CheckCompartmentCallback(JSTracer *trcArg, void **thingp, JSGCTraceKind kind)
CheckCompartment(trc, comp, thing, kind);
} else {
JS_ASSERT(thing->tenuredZone() == trc->zone ||
thing->tenuredZone() == trc->runtime->atomsCompartment->zone());
trc->runtime->isAtomsZone(thing->tenuredZone()));
}
}
@ -2738,7 +2737,7 @@ BeginMarkPhase(JSRuntime *rt)
/* Set up which zones will be collected. */
if (zone->isGCScheduled()) {
if (zone != rt->atomsCompartment->zone()) {
if (!rt->isAtomsZone(zone)) {
any = true;
zone->setGCState(Zone::Mark);
}
@ -2768,7 +2767,7 @@ BeginMarkPhase(JSRuntime *rt)
* atoms. Otherwise, the non-collected zones could contain pointers
* to atoms that we would miss.
*/
Zone *atomsZone = rt->atomsCompartment->zone();
Zone *atomsZone = rt->atomsCompartment()->zone();
bool keepAtoms = false;
for (ThreadDataIter iter(rt); !iter.done(); iter.next())
@ -3302,8 +3301,8 @@ Zone::findOutgoingEdges(ComponentFinder<JS::Zone> &finder)
* compartment, and these aren't in the cross compartment map.
*/
JSRuntime *rt = runtimeFromMainThread();
if (rt->atomsCompartment->zone()->isGCMarking())
finder.addEdgeTo(rt->atomsCompartment->zone());
if (rt->atomsCompartment()->zone()->isGCMarking())
finder.addEdgeTo(rt->atomsCompartment()->zone());
for (CompartmentsInZoneIter comp(this); !comp.done(); comp.next())
comp->findOutgoingEdges(finder);
@ -3649,7 +3648,7 @@ BeginSweepingZoneGroup(JSRuntime *rt)
/* Purge the ArenaLists before sweeping. */
zone->allocator.arenas.purge();
if (zone == rt->atomsCompartment->zone())
if (rt->isAtomsZone(zone))
sweepingAtoms = true;
}

Просмотреть файл

@ -394,7 +394,7 @@ NewGCThing(ThreadSafeContext *cx, AllocKind kind, size_t thingSize, InitialHeap
if (cx->isJSContext()) {
JSContext *ncx = cx->asJSContext();
JS_ASSERT_IF(ncx->compartment() == ncx->runtime()->atomsCompartment,
JS_ASSERT_IF(ncx->runtime()->isAtomsCompartment(ncx->compartment()),
kind == FINALIZE_STRING ||
kind == FINALIZE_SHORT_STRING ||
kind == FINALIZE_IONCODE);

Просмотреть файл

@ -550,8 +550,11 @@ js::Int32ToString(ThreadSafeContext *cx, int32_t si)
JS_ASSERT_IF(si == INT32_MIN, ui == uint32_t(INT32_MAX) + 1);
}
if (cx->isExclusiveContext()) {
if (JSFlatString *str = cx->asExclusiveContext()->dtoaCache().lookup(10, si))
JSCompartment *comp = cx->isExclusiveContext()
? cx->asExclusiveContext()->compartment()
: NULL;
if (comp) {
if (JSFlatString *str = comp->dtoaCache.lookup(10, si))
return str;
}
@ -570,8 +573,8 @@ js::Int32ToString(ThreadSafeContext *cx, int32_t si)
jschar *dst = str->init(end - start);
PodCopy(dst, start.get(), end - start + 1);
if (cx->isExclusiveContext())
cx->asExclusiveContext()->dtoaCache().cache(10, si, str);
if (comp)
comp->dtoaCache.cache(10, si, str);
return str;
}
@ -1275,6 +1278,10 @@ js_NumberToStringWithBase(ThreadSafeContext *cx, double d, int base)
if (base < 2 || base > 36)
return NULL;
JSCompartment *comp = cx->isExclusiveContext()
? cx->asExclusiveContext()->compartment()
: NULL;
int32_t i;
if (mozilla::DoubleIsInt32(d, &i)) {
if (base == 10 && StaticStrings::hasInt(i))
@ -1287,16 +1294,16 @@ js_NumberToStringWithBase(ThreadSafeContext *cx, double d, int base)
return cx->staticStrings().getUnit(c);
}
if (cx->isExclusiveContext()) {
if (JSFlatString *str = cx->asExclusiveContext()->dtoaCache().lookup(base, d))
if (comp) {
if (JSFlatString *str = comp->dtoaCache.lookup(base, d))
return str;
}
numStr = IntToCString(&cbuf, i, base);
JS_ASSERT(!cbuf.dbuf && numStr >= cbuf.sbuf && numStr < cbuf.sbuf + cbuf.sbufSize);
} else {
if (cx->isExclusiveContext()) {
if (JSFlatString *str = cx->asExclusiveContext()->dtoaCache().lookup(base, d))
if (comp) {
if (JSFlatString *str = comp->dtoaCache.lookup(base, d))
return str;
}
@ -1313,8 +1320,8 @@ js_NumberToStringWithBase(ThreadSafeContext *cx, double d, int base)
JSFlatString *s = js_NewStringCopyZ<allowGC>(cx, numStr);
if (cx->isExclusiveContext())
cx->asExclusiveContext()->dtoaCache().cache(base, d, s);
if (comp)
comp->dtoaCache.cache(base, d, s);
return s;
}

Просмотреть файл

@ -1186,7 +1186,7 @@ JSObject::sealOrFreeze(JSContext *cx, HandleObject obj, ImmutabilityType it)
if (!JSID_IS_EMPTY(child.propid))
MarkTypePropertyConfigured(cx, obj, child.propid);
last = cx->propertyTree().getChild(cx, last, obj->numFixedSlots(), child);
last = cx->compartment()->propertyTree.getChild(cx, last, obj->numFixedSlots(), child);
if (!last)
return false;
}

Просмотреть файл

@ -1591,7 +1591,7 @@ void
js::SweepScriptData(JSRuntime *rt)
{
JS_ASSERT(rt->gcIsFull);
ScriptDataTable &table = rt->scriptDataTable;
ScriptDataTable &table = rt->scriptDataTable();
bool keepAtoms = false;
for (ThreadDataIter iter(rt); !iter.done(); iter.next())
@ -1611,7 +1611,7 @@ js::SweepScriptData(JSRuntime *rt)
void
js::FreeScriptData(JSRuntime *rt)
{
ScriptDataTable &table = rt->scriptDataTable;
ScriptDataTable &table = rt->scriptDataTable();
if (!table.initialized())
return;

Просмотреть файл

@ -1926,7 +1926,7 @@ js::str_match(JSContext *cx, unsigned argc, Value *vp)
if (!g.normalizeRegExp(cx, false, 1, args))
return false;
RegExpStatics *res = cx->regExpStatics();
RegExpStatics *res = cx->global()->getRegExpStatics();
Rooted<JSLinearString*> linearStr(cx, str->ensureLinear(cx));
if (!linearStr)
return false;
@ -1964,7 +1964,7 @@ js::str_search(JSContext *cx, unsigned argc, Value *vp)
const jschar *chars = linearStr->chars();
size_t length = linearStr->length();
RegExpStatics *res = cx->regExpStatics();
RegExpStatics *res = cx->global()->getRegExpStatics();
/* Per ECMAv5 15.5.4.12 (5) The last index property is ignored and left unchanged. */
size_t i = 0;
@ -2627,13 +2627,13 @@ str_replace_regexp_remove(JSContext *cx, CallArgs args, HandleString str, RegExp
/* If unmatched, return the input string. */
if (!lastIndex) {
if (startIndex > 0)
cx->regExpStatics()->updateLazily(cx, stableStr, &re, lazyIndex);
cx->global()->getRegExpStatics()->updateLazily(cx, stableStr, &re, lazyIndex);
args.rval().setString(str);
return true;
}
/* The last successful match updates the RegExpStatics. */
cx->regExpStatics()->updateLazily(cx, stableStr, &re, lazyIndex);
cx->global()->getRegExpStatics()->updateLazily(cx, stableStr, &re, lazyIndex);
/* Include any remaining part of the string. */
if (lastIndex < charsLen) {
@ -2664,7 +2664,7 @@ str_replace_regexp(JSContext *cx, CallArgs args, ReplaceData &rdata)
rdata.leftIndex = 0;
rdata.calledBack = false;
RegExpStatics *res = cx->regExpStatics();
RegExpStatics *res = cx->global()->getRegExpStatics();
RegExpShared &re = rdata.g.regExp();
/* Optimize removal. */
@ -3015,7 +3015,7 @@ SplitHelper(JSContext *cx, Handle<JSLinearString*> str, uint32_t limit, const Ma
/* Step 13(c)(iii)(6-7). */
if (Matcher::returnsCaptures) {
RegExpStatics *res = cx->regExpStatics();
RegExpStatics *res = cx->global()->getRegExpStatics();
const MatchPairs &matches = res->getMatches();
for (size_t i = 0; i < matches.parenCount(); i++) {
/* Steps 13(c)(iii)(7)(a-c). */
@ -3196,7 +3196,7 @@ js::str_split(JSContext *cx, unsigned argc, Value *vp)
SplitStringMatcher matcher(cx, sepstr);
aobj = SplitHelper(cx, linearStr, limit, matcher, type);
} else {
SplitRegExpMatcher matcher(*re, cx->regExpStatics());
SplitRegExpMatcher matcher(*re, cx->global()->getRegExpStatics());
aobj = SplitHelper(cx, linearStr, limit, matcher, type);
}
if (!aobj)

Просмотреть файл

@ -601,10 +601,12 @@ WorkerThread::threadLoop()
}
AutoPauseWorkersForGC::AutoPauseWorkersForGC(JSRuntime *rt MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
: runtime(rt), needsUnpause(false)
: runtime(rt), needsUnpause(false), oldExclusiveThreadsPaused(rt->exclusiveThreadsPaused)
{
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
rt->exclusiveThreadsPaused = true;
if (!runtime->workerThreadState)
return;
@ -634,6 +636,8 @@ AutoPauseWorkersForGC::AutoPauseWorkersForGC(JSRuntime *rt MOZ_GUARD_OBJECT_NOTI
AutoPauseWorkersForGC::~AutoPauseWorkersForGC()
{
runtime->exclusiveThreadsPaused = oldExclusiveThreadsPaused;
if (!needsUnpause)
return;

Просмотреть файл

@ -292,6 +292,7 @@ class AutoPauseWorkersForGC
#ifdef JS_WORKER_THREADS
JSRuntime *runtime;
bool needsUnpause;
mozilla::DebugOnly<bool> oldExclusiveThreadsPaused;
#endif
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER

Просмотреть файл

@ -177,7 +177,7 @@ GlobalObject::initFunctionAndObjectClasses(JSContext *cx)
{
Rooted<GlobalObject*> self(cx, this);
JS_THREADSAFE_ASSERT(cx->compartment() != cx->runtime()->atomsCompartment);
JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
JS_ASSERT(isNative());
cx->setDefaultCompartmentObjectIfUnset(self);

Просмотреть файл

@ -264,7 +264,7 @@ RegExpObject::createShared(ExclusiveContext *cx, RegExpGuard *g)
Rooted<RegExpObject*> self(cx, this);
JS_ASSERT(!maybeShared());
if (!cx->regExps().get(cx, getSource(), getFlags(), g))
if (!cx->compartment()->regExps.get(cx, getSource(), getFlags(), g))
return false;
self->setShared(cx, **g);

Просмотреть файл

@ -528,12 +528,6 @@ RegExpStatics::checkInvariants()
#endif /* DEBUG */
}
inline RegExpStatics *
ExclusiveContext::regExpStatics()
{
return global()->getRegExpStatics();
}
} /* namespace js */
#endif /* vm_RegExpStatics_h */

Просмотреть файл

@ -108,9 +108,9 @@ JSRuntime::JSRuntime(JSUseHelperThreads useHelperThreads)
exclusiveAccessLock(NULL),
exclusiveAccessOwner(NULL),
mainThreadHasExclusiveAccess(false),
exclusiveThreadsPaused(false),
numExclusiveThreads(0),
#endif
atomsCompartment(NULL),
systemZone(NULL),
numCompartments(0),
localeCallbacks(NULL),
@ -253,6 +253,7 @@ JSRuntime::JSRuntime(JSUseHelperThreads useHelperThreads)
#endif
mathCache_(NULL),
trustedPrincipals_(NULL),
atomsCompartment_(NULL),
wrapObjectCallback(TransparentObjectWrapper),
sameCompartmentWrapObjectCallback(NULL),
preWrapObjectCallback(NULL),
@ -352,7 +353,7 @@ JSRuntime::init(uint32_t maxbytes)
atomsZone->setGCLastBytes(8192, GC_NORMAL);
atomsZone.forget();
this->atomsCompartment = atomsCompartment.forget();
this->atomsCompartment_ = atomsCompartment.forget();
if (!InitAtoms(this))
return false;
@ -362,7 +363,7 @@ JSRuntime::init(uint32_t maxbytes)
dateTimeInfo.updateTimeZoneAdjustment();
if (!scriptDataTable.init())
if (!scriptDataTable_.init())
return false;
if (!threadPool.init())
@ -400,6 +401,9 @@ JSRuntime::~JSRuntime()
JS_ASSERT(!exclusiveAccessOwner);
if (exclusiveAccessLock)
PR_DestroyLock(exclusiveAccessLock);
JS_ASSERT(!numExclusiveThreads);
exclusiveThreadsPaused = true; // Avoid bogus asserts during teardown.
#endif
/*
@ -430,6 +434,8 @@ JSRuntime::~JSRuntime()
FinishAtoms(this);
js_FinishGC(this);
atomsCompartment_ = NULL;
#ifdef JS_THREADSAFE
if (gcLock)
PR_DestroyLock(gcLock);
@ -517,7 +523,7 @@ JSRuntime::sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf, JS::RuntimeSi
rtSizes->object = mallocSizeOf(this);
rtSizes->atomsTable = atoms.sizeOfExcludingThis(mallocSizeOf);
rtSizes->atomsTable = atoms().sizeOfExcludingThis(mallocSizeOf);
rtSizes->contexts = 0;
for (ContextIter acx(this); !acx.done(); acx.next())
@ -539,8 +545,8 @@ JSRuntime::sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf, JS::RuntimeSi
rtSizes->mathCache = mathCache_ ? mathCache_->sizeOfIncludingThis(mallocSizeOf) : 0;
rtSizes->scriptData = scriptDataTable.sizeOfExcludingThis(mallocSizeOf);
for (ScriptDataTable::Range r = scriptDataTable.all(); !r.empty(); r.popFront())
rtSizes->scriptData = scriptDataTable().sizeOfExcludingThis(mallocSizeOf);
for (ScriptDataTable::Range r = scriptDataTable().all(); !r.empty(); r.popFront())
rtSizes->scriptData += mallocSizeOf(r.front());
}

Просмотреть файл

@ -662,6 +662,7 @@ class MarkingValidator;
typedef Vector<JS::Zone *, 1, SystemAllocPolicy> ZoneVector;
class AutoLockForExclusiveAccess;
class AutoPauseWorkersForGC;
} // namespace js
@ -757,11 +758,13 @@ struct JSRuntime : public JS::shadow::Runtime,
PRLock *exclusiveAccessLock;
mozilla::DebugOnly<PRThread *> exclusiveAccessOwner;
mozilla::DebugOnly<bool> mainThreadHasExclusiveAccess;
mozilla::DebugOnly<bool> exclusiveThreadsPaused;
/* Number of non-main threads with an ExclusiveContext. */
size_t numExclusiveThreads;
friend class js::AutoLockForExclusiveAccess;
friend class js::AutoPauseWorkersForGC;
public:
#endif // JS_THREADSAFE
@ -769,6 +772,7 @@ struct JSRuntime : public JS::shadow::Runtime,
bool currentThreadHasExclusiveAccess() {
#if defined(JS_THREADSAFE) && defined(DEBUG)
return (!numExclusiveThreads && mainThreadHasExclusiveAccess) ||
exclusiveThreadsPaused ||
exclusiveAccessOwner == PR_GetCurrentThread();
#else
return true;
@ -783,9 +787,6 @@ struct JSRuntime : public JS::shadow::Runtime,
#endif
}
/* Default compartment. */
JSCompartment *atomsCompartment;
/* Embedders can use this zone however they wish. */
JS::Zone *systemZone;
@ -1363,8 +1364,15 @@ struct JSRuntime : public JS::shadow::Runtime,
js::ConservativeGCData conservativeGC;
/* Pool of maps used during parse/emit. */
js::frontend::ParseMapPool parseMapPool;
// Pool of maps used during parse/emit. This may be modified by threads
// with an ExclusiveContext and requires a lock.
private:
js::frontend::ParseMapPool parseMapPool_;
public:
js::frontend::ParseMapPool &parseMapPool() {
JS_ASSERT(currentThreadHasExclusiveAccess());
return parseMapPool_;
}
private:
JSPrincipals *trustedPrincipals_;
@ -1372,8 +1380,29 @@ struct JSRuntime : public JS::shadow::Runtime,
void setTrustedPrincipals(JSPrincipals *p) { trustedPrincipals_ = p; }
JSPrincipals *trustedPrincipals() const { return trustedPrincipals_; }
/* Set of all currently-living atoms. */
js::AtomSet atoms;
// Set of all currently-living atoms, and the compartment in which they
// reside. The atoms compartment is additionally used to hold runtime
// wide Ion code stubs. These may be modified by threads with an
// ExclusiveContext and require a lock.
private:
js::AtomSet atoms_;
JSCompartment *atomsCompartment_;
public:
js::AtomSet &atoms() {
JS_ASSERT(currentThreadHasExclusiveAccess());
return atoms_;
}
JSCompartment *atomsCompartment() {
JS_ASSERT(currentThreadHasExclusiveAccess());
return atomsCompartment_;
}
bool isAtomsCompartment(JSCompartment *comp) {
return comp == atomsCompartment_;
}
// The atoms compartment is the only one in its zone.
inline bool isAtomsZone(JS::Zone *zone);
union {
/*
@ -1393,7 +1422,16 @@ struct JSRuntime : public JS::shadow::Runtime,
JSPreWrapCallback preWrapObjectCallback;
js::PreserveWrapperCallback preserveWrapperCallback;
js::ScriptDataTable scriptDataTable;
// Table of bytecode and other data that may be shared across scripts
// within the runtime. This may be modified by threads with an
// ExclusiveContext and requires a lock.
private:
js::ScriptDataTable scriptDataTable_;
public:
js::ScriptDataTable &scriptDataTable() {
JS_ASSERT(currentThreadHasExclusiveAccess());
return scriptDataTable_;
}
#ifdef DEBUG
size_t noGCOrAllocationCheck;

Просмотреть файл

@ -275,7 +275,7 @@ Shape::getChildBinding(ExclusiveContext *cx, const StackShape &child)
gc::AllocKind kind = gc::GetGCObjectKind(slots);
uint32_t nfixed = gc::GetGCKindSlots(kind);
return cx->propertyTree().getChild(cx, this, nfixed, child);
return cx->compartment()->propertyTree.getChild(cx, this, nfixed, child);
}
/* static */ Shape *
@ -302,7 +302,8 @@ Shape::replaceLastProperty(ExclusiveContext *cx, const StackBaseShape &base,
child.base = nbase;
}
return cx->propertyTree().getChild(cx, shape->parent, shape->numFixedSlots(), child);
return cx->compartment()->propertyTree.getChild(cx, shape->parent,
shape->numFixedSlots(), child);
}
/*
@ -349,7 +350,7 @@ JSObject::getChildProperty(ExclusiveContext *cx,
}
shape->initDictionaryShape(child, obj->numFixedSlots(), &obj->shape_);
} else {
shape = cx->propertyTree().getChild(cx, parent, obj->numFixedSlots(), child);
shape = cx->compartment()->propertyTree.getChild(cx, parent, obj->numFixedSlots(), child);
if (!shape)
return NULL;
//JS_ASSERT(shape->parent == parent);
@ -1240,7 +1241,7 @@ StackBaseShape::AutoRooter::trace(JSTracer *trc)
/* static */ UnownedBaseShape*
BaseShape::getUnowned(ExclusiveContext *cx, const StackBaseShape &base)
{
BaseShapeSet &table = cx->baseShapes();
BaseShapeSet &table = cx->compartment()->baseShapes;
if (!table.initialized() && !table.init())
return NULL;
@ -1337,7 +1338,7 @@ EmptyShape::getInitialShape(ExclusiveContext *cx, Class *clasp, TaggedProto prot
JS_ASSERT_IF(proto.isObject(), cx->isInsideCurrentCompartment(proto.toObject()));
JS_ASSERT_IF(parent, cx->isInsideCurrentCompartment(parent));
InitialShapeSet &table = cx->initialShapes();
InitialShapeSet &table = cx->compartment()->initialShapes;
if (!table.initialized() && !table.init())
return NULL;
@ -1359,7 +1360,7 @@ EmptyShape::getInitialShape(ExclusiveContext *cx, Class *clasp, TaggedProto prot
if (!nbase)
return NULL;
Shape *shape = cx->propertyTree().newShape(cx);
Shape *shape = cx->compartment()->propertyTree.newShape(cx);
if (!shape)
return NULL;
new (shape) EmptyShape(nbase, nfixed);
@ -1409,7 +1410,7 @@ EmptyShape::insertInitialShape(ExclusiveContext *cx, HandleShape shape, HandleOb
shape->getObjectParent(), shape->getObjectMetadata(),
shape->numFixedSlots(), shape->getObjectFlags());
InitialShapeSet::Ptr p = cx->initialShapes().lookup(lookup);
InitialShapeSet::Ptr p = cx->compartment()->initialShapes.lookup(lookup);
JS_ASSERT(p);
InitialShapeEntry &entry = const_cast<InitialShapeEntry &>(*p);

Просмотреть файл

@ -627,7 +627,7 @@ bool
StaticStrings::init(JSContext *cx)
{
AutoLockForExclusiveAccess lock(cx);
AutoCompartment ac(cx, cx->runtime()->atomsCompartment);
AutoCompartment ac(cx, cx->runtime()->atomsCompartment());
for (uint32_t i = 0; i < UNIT_STATIC_LIMIT; i++) {
jschar buffer[] = { jschar(i), '\0' };