зеркало из https://github.com/mozilla/gecko-dev.git
Bug 902095 - Allow accessing the compartment/zone for ExclusiveContext, r=billm.
This commit is contained in:
Родитель
6c8dc2c0b0
Коммит
ca2162becd
|
@ -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 ®Exps();
|
||||
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' };
|
||||
|
|
Загрузка…
Ссылка в новой задаче