Bug 772820 - Disallow GCs during script analysis or compilation, r=billm.

This commit is contained in:
Brian Hackett 2013-01-18 09:23:28 -07:00
parent 7563370004
commit bfc1e7cc66
22 changed files with 119 additions and 139 deletions

View File

@ -1145,7 +1145,7 @@ ParallelArrayObject::create(JSContext *cx, HandleObject buffer, uint32_t offset,
// Propagate element types.
if (cx->typeInferenceEnabled()) {
AutoEnterTypeInference enter(cx);
AutoEnterAnalysis enter(cx);
TypeObject *bufferType = buffer->getType(cx);
TypeObject *resultType = result->getType(cx);
if (!bufferType->unknownProperties() && !resultType->unknownProperties()) {

View File

@ -668,6 +668,8 @@ js::gc::MarkRuntime(JSTracer *trc, bool useSavedRoots)
JSRuntime *rt = trc->runtime;
JS_ASSERT(trc->callback != GCMarker::GrayCallback);
JS_ASSERT(!rt->mainThread.suppressGC);
if (IS_GC_MARKING_TRACER(trc)) {
for (CompartmentsIter c(rt); !c.done(); c.next()) {
if (!c->isCollecting())
@ -730,7 +732,7 @@ js::gc::MarkRuntime(JSTracer *trc, bool useSavedRoots)
if (IS_GC_MARKING_TRACER(trc) && !c->isCollecting())
continue;
if (IS_GC_MARKING_TRACER(trc) && (c->activeAnalysis || c->isPreservingCode())) {
if (IS_GC_MARKING_TRACER(trc) && c->isPreservingCode()) {
gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_MARK_TYPES);
c->markTypes(trc);
}

View File

@ -806,6 +806,9 @@ MaybeVerifyPreBarriers(JSRuntime *rt, bool always)
if (rt->gcZeal() != ZealVerifierPreValue)
return;
if (rt->mainThread.suppressGC)
return;
if (VerifyPreTracer *trc = (VerifyPreTracer *)rt->gcVerifyPreData) {
if (++trc->count < rt->gcZealFrequency && !always)
return;
@ -821,6 +824,9 @@ MaybeVerifyPostBarriers(JSRuntime *rt, bool always)
if (rt->gcZeal() != ZealVerifierPostValue)
return;
if (rt->mainThread.suppressGC)
return;
if (VerifyPostTracer *trc = (VerifyPostTracer *)rt->gcVerifyPostData) {
if (++trc->count < rt->gcZealFrequency && !always)
return;

View File

@ -456,7 +456,7 @@ ReflowArgTypes(JSContext *cx)
unsigned nargs = fp->fun()->nargs;
RootedScript script(cx, fp->script());
types::AutoEnterTypeInference enter(cx);
types::AutoEnterAnalysis enter(cx);
if (!fp->isConstructing())
types::TypeScript::SetThis(cx, script, fp->thisValue());
@ -486,7 +486,7 @@ ion::ReflowTypeInfo(uint32_t bailoutResult)
IonSpew(IonSpew_Bailouts, "reflowing type info at %s:%d pcoff %d", script->filename,
script->lineno, pc - script->code);
types::AutoEnterTypeInference enter(cx);
types::AutoEnterAnalysis enter(cx);
if (bailoutResult == BAILOUT_RETURN_TYPE_BARRIER)
script->analysis()->breakTypeBarriers(cx, pc - script->code, false);
else

View File

@ -1080,7 +1080,7 @@ AttachFinishedCompilations(JSContext *cx)
// previously, though any GC activity would discard the builder.
codegen->masm.constructRoot(cx);
types::AutoEnterTypeInference enterTypes(cx);
types::AutoEnterAnalysis enterTypes(cx);
ExecutionMode executionMode = builder->info().executionMode();
types::AutoEnterCompilation enterCompiler(cx, CompilerOutputKind(executionMode));
@ -1149,7 +1149,7 @@ IonCompile(JSContext *cx, HandleScript script, HandleFunction fun, jsbytecode *o
if (!info)
return AbortReason_Alloc;
types::AutoEnterTypeInference enter(cx, true);
types::AutoEnterAnalysis enter(cx);
TypeInferenceOracle oracle;
if (!oracle.init(cx, script))

View File

@ -2015,7 +2015,7 @@ CrossScriptSSA::foldValue(const CrossSSAValue &cv)
void
ScriptAnalysis::printSSA(JSContext *cx)
{
AutoEnterAnalysis enter(cx);
types::AutoEnterAnalysis enter(cx);
printf("\n");

View File

@ -1204,39 +1204,6 @@ class ScriptAnalysis
#endif
};
/* Protect analysis structures from GC while they are being used. */
class AutoEnterAnalysis
{
JSCompartment *compartment;
bool oldActiveAnalysis;
bool left;
void construct(JSCompartment *compartment)
{
this->compartment = compartment;
oldActiveAnalysis = compartment->activeAnalysis;
compartment->activeAnalysis = true;
left = false;
}
public:
AutoEnterAnalysis(JSContext *cx) { construct(cx->compartment); }
AutoEnterAnalysis(JSCompartment *compartment) { construct(compartment); }
void leave()
{
if (!left) {
left = true;
compartment->activeAnalysis = oldActiveAnalysis;
}
}
~AutoEnterAnalysis()
{
leave();
}
};
/* SSA value as used by CrossScriptSSA, identifies the frame it came from. */
struct CrossSSAValue
{

View File

@ -875,7 +875,7 @@ static inline bool
InitArrayTypes(JSContext *cx, TypeObject *type, const Value *vector, unsigned count)
{
if (cx->typeInferenceEnabled() && !type->unknownProperties()) {
AutoEnterTypeInference enter(cx);
AutoEnterAnalysis enter(cx);
TypeSet *types = type->getProperty(cx, JSID_VOID, true);
if (!types)

View File

@ -121,7 +121,7 @@ JSCompartment::init(JSContext *cx)
if (cx)
cx->runtime->dateTimeInfo.updateTimeZoneAdjustment();
activeAnalysis = activeInference = false;
activeAnalysis = false;
types.init(cx);
if (!crossCompartmentWrappers.init())
@ -564,7 +564,8 @@ JSCompartment::markTypes(JSTracer *trc)
* compartment. These can be referred to directly by type sets, which we
* cannot modify while code which depends on these type sets is active.
*/
JS_ASSERT(activeAnalysis || isPreservingCode());
JS_ASSERT(!activeAnalysis);
JS_ASSERT(isPreservingCode());
for (CellIterUnderGC i(this, FINALIZE_SCRIPT); !i.done(); i.next()) {
JSScript *script = i.get<JSScript>();
@ -640,9 +641,11 @@ JSCompartment::isDiscardingJitCode(JSTracer *trc)
void
JSCompartment::sweep(FreeOp *fop, bool releaseTypes)
{
JS_ASSERT(!activeAnalysis);
{
gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_SWEEP_DISCARD_CODE);
discardJitCode(fop, !activeAnalysis && !gcPreserveCode);
discardJitCode(fop, !gcPreserveCode);
}
/* This function includes itself in PHASE_SWEEP_TABLES. */
@ -682,7 +685,7 @@ JSCompartment::sweep(FreeOp *fop, bool releaseTypes)
WeakMapBase::sweepCompartment(this);
}
if (!activeAnalysis && !gcPreserveCode) {
if (!gcPreserveCode) {
JS_ASSERT(!types.constrainedOutputs);
gcstats::AutoPhase ap(rt->gcStats, gcstats::PHASE_DISCARD_ANALYSIS);

View File

@ -293,7 +293,6 @@ struct JSCompartment : private JS::shadow::Compartment, public js::gc::GraphNode
js::LifoAlloc typeLifoAlloc;
bool activeAnalysis;
bool activeInference;
/* Type information about the scripts and objects in this compartment. */
js::types::TypeCompartment types;

View File

@ -4151,14 +4151,11 @@ IncrementalCollectSlice(JSRuntime *rt,
IncrementalSafety
gc::IsIncrementalGCSafe(JSRuntime *rt)
{
JS_ASSERT(!rt->mainThread.suppressGC);
if (rt->gcKeepAtoms)
return IncrementalSafety::Unsafe("gcKeepAtoms set");
for (CompartmentsIter c(rt); !c.done(); c.next()) {
if (c->activeAnalysis)
return IncrementalSafety::Unsafe("activeAnalysis set");
}
if (!rt->gcIncrementalEnabled)
return IncrementalSafety::Unsafe("incremental permanently disabled");
@ -4520,6 +4517,10 @@ gc::RunDebugGC(JSContext *cx)
{
#ifdef JS_GC_ZEAL
JSRuntime *rt = cx->runtime;
if (rt->mainThread.suppressGC)
return;
PrepareForDebugGC(cx->runtime);
int type = rt->gcZeal();
@ -4557,8 +4558,7 @@ gc::RunDebugGC(JSContext *cx)
rt->gcIncrementalLimit = rt->gcZealFrequency / 2;
}
} else if (type == ZealPurgeAnalysisValue) {
if (!cx->compartment->activeAnalysis)
cx->compartment->types.maybePurgeAnalysis(cx, /* force = */ true);
cx->compartment->types.maybePurgeAnalysis(cx, /* force = */ true);
} else {
Collect(rt, false, SliceBudget::Unlimited, GC_NORMAL, gcreason::DEBUG_GC);
}
@ -4592,17 +4592,6 @@ void PreventGCDuringInteractiveDebug()
#endif
gc::AutoSuppressGC::AutoSuppressGC(JSContext *cx)
: suppressGC_(cx->runtime->mainThread.suppressGC)
{
suppressGC_++;
}
gc::AutoSuppressGC::~AutoSuppressGC()
{
suppressGC_--;
}
void
js::ReleaseAllJITCode(FreeOp *fop)
{

View File

@ -1199,21 +1199,6 @@ MaybeVerifyBarriers(JSContext *cx, bool always = false)
#endif
/*
* Instances of this class set the |JSRuntime::suppressGC| flag for the duration
* that they are live. Use of this class is highly discouraged. Please carefully
* read the comment in jscntxt.h above |suppressGC| and take all appropriate
* precautions before instantiating this class.
*/
class AutoSuppressGC
{
int32_t &suppressGC_;
public:
AutoSuppressGC(JSContext *cx);
~AutoSuppressGC();
};
} /* namespace gc */
void

View File

@ -546,6 +546,35 @@ TryNewGCThing(JSContext *cx, js::gc::AllocKind kind, size_t thingSize)
return t;
}
/*
* Instances of this class set the |JSRuntime::suppressGC| flag for the duration
* that they are live. Use of this class is highly discouraged. Please carefully
* read the comment in jscntxt.h above |suppressGC| and take all appropriate
* precautions before instantiating this class.
*/
class AutoSuppressGC
{
int32_t &suppressGC_;
public:
AutoSuppressGC(JSContext *cx)
: suppressGC_(cx->runtime->mainThread.suppressGC)
{
suppressGC_++;
}
AutoSuppressGC(JSCompartment *comp)
: suppressGC_(comp->rt->mainThread.suppressGC)
{
suppressGC_++;
}
~AutoSuppressGC()
{
suppressGC_--;
}
};
} /* namespace gc */
} /* namespace js */

View File

@ -269,7 +269,7 @@ types::TypeHasProperty(JSContext *cx, TypeObject *obj, jsid id, const Value &val
Type type = GetValueType(cx, value);
AutoEnterTypeInference enter(cx);
AutoEnterAnalysis enter(cx);
/*
* We don't track types for properties inherited from prototypes which
@ -375,7 +375,7 @@ TypeSet::add(JSContext *cx, TypeConstraint *constraint, bool callExisting)
return;
}
JS_ASSERT(cx->compartment->activeInference);
JS_ASSERT(cx->compartment->activeAnalysis);
InferSpew(ISpewOps, "addConstraint: %sT%p%s %sC%p%s %s",
InferSpewColor(this), this, InferSpewColorReset(),
@ -442,7 +442,7 @@ TypeSet::print()
StackTypeSet *
StackTypeSet::make(JSContext *cx, const char *name)
{
JS_ASSERT(cx->compartment->activeInference);
JS_ASSERT(cx->compartment->activeAnalysis);
StackTypeSet *res = cx->analysisLifoAlloc().new_<StackTypeSet>();
if (!res) {
@ -2348,7 +2348,7 @@ FindPreviousInnerInitializer(HandleScript script, jsbytecode *initpc)
TypeObject *
TypeCompartment::addAllocationSiteTypeObject(JSContext *cx, AllocationSiteKey key)
{
AutoEnterTypeInference enter(cx);
AutoEnterAnalysis enter(cx);
if (!allocationSiteTable) {
allocationSiteTable = cx->new_<AllocationSiteTable>();
@ -2473,7 +2473,7 @@ types::UseNewTypeForInitializer(JSContext *cx, HandleScript script, jsbytecode *
if (key != JSProto_Object && !(key >= JSProto_Int8Array && key <= JSProto_Uint8ClampedArray))
return false;
AutoEnterTypeInference enter(cx);
AutoEnterAnalysis enter(cx);
if (!JSScript::ensureRanAnalysis(cx, script))
return false;
@ -2572,7 +2572,7 @@ TypeCompartment::setPendingNukeTypes(JSContext *cx)
void
TypeCompartment::setPendingNukeTypesNoReport()
{
JS_ASSERT(compartment()->activeInference);
JS_ASSERT(compartment()->activeAnalysis);
if (!pendingNukeTypes)
pendingNukeTypes = true;
}
@ -2764,7 +2764,7 @@ TypeCompartment::markSetsUnknown(JSContext *cx, TypeObject *target)
JS_ASSERT(target->unknownProperties());
target->flags |= OBJECT_FLAG_SETS_MARKED_UNKNOWN;
AutoEnterTypeInference enter(cx);
AutoEnterAnalysis enter(cx);
/*
* Mark both persistent and transient type sets which contain obj as having
@ -2928,7 +2928,7 @@ TypeCompartment::print(JSContext *cx, bool force)
gc::AutoSuppressGC suppressGC(cx);
JSCompartment *compartment = this->compartment();
AutoEnterAnalysis enter(compartment);
AutoEnterAnalysis enter(NULL, compartment);
if (!force && !InferSpewActive(ISpewResult))
return;
@ -3016,7 +3016,7 @@ struct types::ArrayTableKey
void
TypeCompartment::fixArrayType(JSContext *cx, HandleObject obj)
{
AutoEnterTypeInference enter(cx);
AutoEnterAnalysis enter(cx);
if (!arrayTypeTable) {
arrayTypeTable = cx->new_<ArrayTypeTable>();
@ -3136,7 +3136,7 @@ struct types::ObjectTableEntry
void
TypeCompartment::fixObjectType(JSContext *cx, HandleObject obj)
{
AutoEnterTypeInference enter(cx);
AutoEnterAnalysis enter(cx);
if (!objectTypeTable) {
objectTypeTable = cx->new_<ObjectTypeTable>();
@ -3369,7 +3369,7 @@ TypeObject::addDefiniteProperties(JSContext *cx, HandleObject obj)
return true;
/* Mark all properties of obj as definite properties of this type. */
AutoEnterTypeInference enter(cx);
AutoEnterAnalysis enter(cx);
RootedShape shape(cx, obj->lastProperty());
while (!shape->isEmptyShape()) {
@ -3421,7 +3421,7 @@ InlineAddTypeProperty(JSContext *cx, TypeObject *obj, jsid id, Type type)
AssertCanGC();
JS_ASSERT(id == MakeTypeId(cx, id));
AutoEnterTypeInference enter(cx);
AutoEnterAnalysis enter(cx);
TypeSet *types = obj->getProperty(cx, id, true);
if (!types || types->hasType(type))
@ -3452,7 +3452,7 @@ TypeObject::addPropertyType(JSContext *cx, const char *name, Type type)
if (name) {
JSAtom *atom = Atomize(cx, name, strlen(name));
if (!atom) {
AutoEnterTypeInference enter(cx);
AutoEnterAnalysis enter(cx);
cx->compartment->types.setPendingNukeTypes(cx);
return;
}
@ -3470,7 +3470,7 @@ TypeObject::addPropertyType(JSContext *cx, const char *name, const Value &value)
void
TypeObject::markPropertyConfigured(JSContext *cx, jsid id)
{
AutoEnterTypeInference enter(cx);
AutoEnterAnalysis enter(cx);
id = MakeTypeId(cx, id);
@ -3487,7 +3487,7 @@ TypeObject::markStateChange(JSContext *cx)
if (unknownProperties())
return;
AutoEnterTypeInference enter(cx);
AutoEnterAnalysis enter(cx);
TypeSet *types = maybeGetProperty(cx, JSID_EMPTY);
if (types) {
TypeConstraint *constraint = types->constraintList;
@ -3504,7 +3504,7 @@ TypeObject::setFlags(JSContext *cx, TypeObjectFlags flags)
if ((this->flags & flags) == flags)
return;
AutoEnterTypeInference enter(cx);
AutoEnterAnalysis enter(cx);
if (singleton) {
/* Make sure flags are consistent with persistent object state. */
@ -3524,9 +3524,9 @@ TypeObject::setFlags(JSContext *cx, TypeObjectFlags flags)
void
TypeObject::markUnknown(JSContext *cx)
{
AutoEnterTypeInference enter(cx);
AutoEnterAnalysis enter(cx);
JS_ASSERT(cx->compartment->activeInference);
JS_ASSERT(cx->compartment->activeAnalysis);
JS_ASSERT(!unknownProperties());
if (!(flags & OBJECT_FLAG_NEW_SCRIPT_CLEARED))
@ -3572,7 +3572,7 @@ TypeObject::clearNewScript(JSContext *cx)
if (!newScript)
return;
AutoEnterTypeInference enter(cx);
AutoEnterAnalysis enter(cx);
/*
* Any definite properties we added due to analysis of the new script when
@ -5144,7 +5144,7 @@ CheckNewScriptProperties(JSContext *cx, HandleTypeObject type, JSFunction *fun)
void
ScriptAnalysis::printTypes(JSContext *cx)
{
AutoEnterAnalysis enter(script_->compartment());
AutoEnterAnalysis enter(NULL, script_->compartment());
TypeCompartment *compartment = &script_->compartment()->types;
/*
@ -5292,7 +5292,7 @@ types::MarkIteratorUnknownSlow(JSContext *cx)
if (JSOp(*pc) != JSOP_ITER)
return;
AutoEnterTypeInference enter(cx);
AutoEnterAnalysis enter(cx);
/*
* This script is iterating over an actual Iterator or Generator object, or
@ -5377,7 +5377,7 @@ void
types::TypeDynamicResult(JSContext *cx, HandleScript script, jsbytecode *pc, Type type)
{
JS_ASSERT(cx->typeInferenceEnabled());
AutoEnterTypeInference enter(cx);
AutoEnterAnalysis enter(cx);
/* Directly update associated type sets for applicable bytecodes. */
if (js_CodeSpec[*pc].format & JOF_TYPESET) {
@ -5482,7 +5482,7 @@ types::TypeMonitorResult(JSContext *cx, HandleScript script, jsbytecode *pc, con
if (!(js_CodeSpec[*pc].format & JOF_TYPESET))
return;
AutoEnterTypeInference enter(cx);
AutoEnterAnalysis enter(cx);
if (!JSScript::ensureRanAnalysis(cx, script)) {
cx->compartment->types.setPendingNukeTypes(cx);
@ -5593,7 +5593,7 @@ JSScript::makeTypes(JSContext *cx)
return true;
}
AutoEnterTypeInference enter(cx);
AutoEnterAnalysis enter(cx);
unsigned count = TypeScript::NumTypeSets(this);
@ -5703,7 +5703,7 @@ JSFunction::setTypeForScriptedFunction(JSContext *cx, HandleFunction fun, bool s
/* static */ void
TypeScript::CheckBytecode(JSContext *cx, HandleScript script, jsbytecode *pc, const js::Value *sp)
{
AutoEnterTypeInference enter(cx);
AutoEnterAnalysis enter(cx);
if (js_CodeSpec[*pc].format & JOF_DECOMPOSE)
return;
@ -5798,7 +5798,7 @@ JSObject::splicePrototype(JSContext *cx, Handle<TaggedProto> proto)
type->proto = proto.raw();
AutoEnterTypeInference enter(cx);
AutoEnterAnalysis enter(cx);
if (protoType && protoType->unknownProperties() && !type->unknownProperties()) {
type->markUnknown(cx);
@ -5847,7 +5847,7 @@ JSObject::makeLazyType(JSContext *cx)
return type;
}
AutoEnterTypeInference enter(cx);
AutoEnterAnalysis enter(cx);
/* Fill in the type according to the state of this object. */
@ -5997,7 +5997,7 @@ JSCompartment::getNewType(JSContext *cx, TaggedProto proto_, JSFunction *fun_, b
if (!cx->typeInferenceEnabled())
return type;
AutoEnterTypeInference enter(cx);
AutoEnterAnalysis enter(cx);
/*
* Set the special equality flag for types whose prototype also has the
@ -6570,7 +6570,7 @@ TypeCompartment::maybePurgeAnalysis(JSContext *cx, bool force)
return;
}
AutoEnterTypeInference enter(cx);
AutoEnterAnalysis enter(cx);
/* Reset the analysis pool, making its memory available for reuse. */
cx->compartment->analysisLifoAlloc.releaseAll();

View File

@ -347,28 +347,30 @@ IsInlinableCall(jsbytecode *pc)
* and JSScripts won't be collected during GC. Does additional sanity checking
* that inference is not reentrant and that recompilations occur properly.
*/
struct AutoEnterTypeInference
struct AutoEnterAnalysis
{
/* Prevent GC activity in the middle of analysis. */
gc::AutoSuppressGC suppressGC;
FreeOp *freeOp;
JSCompartment *compartment;
bool oldActiveAnalysis;
bool oldActiveInference;
AutoEnterTypeInference(JSContext *cx, bool compiling = false)
AutoEnterAnalysis(JSContext *cx)
: suppressGC(cx)
{
JS_ASSERT_IF(!compiling, cx->compartment->types.inferenceEnabled);
init(cx->runtime->defaultFreeOp(), cx->compartment);
}
AutoEnterTypeInference(FreeOp *fop, JSCompartment *comp)
AutoEnterAnalysis(FreeOp *fop, JSCompartment *comp)
: suppressGC(comp)
{
init(fop, comp);
}
~AutoEnterTypeInference()
~AutoEnterAnalysis()
{
compartment->activeAnalysis = oldActiveAnalysis;
compartment->activeInference = oldActiveInference;
/*
* If there are no more type inference activations on the stack,
@ -376,7 +378,7 @@ struct AutoEnterTypeInference
* invoking any scripted code while type inference is running.
* :TODO: assert this.
*/
if (!compartment->activeInference) {
if (!compartment->activeAnalysis) {
TypeCompartment *types = &compartment->types;
if (types->pendingNukeTypes)
types->nukeTypes(freeOp);
@ -390,9 +392,7 @@ struct AutoEnterTypeInference
freeOp = fop;
compartment = comp;
oldActiveAnalysis = compartment->activeAnalysis;
oldActiveInference = compartment->activeInference;
compartment->activeAnalysis = true;
compartment->activeInference = true;
}
};
@ -995,7 +995,7 @@ TypeScript::SetThis(JSContext *cx, HandleScript script, Type type)
bool analyze = cx->hasRunOption(JSOPTION_METHODJIT_ALWAYS);
if (!ThisTypes(script)->hasType(type) || analyze) {
AutoEnterTypeInference enter(cx);
AutoEnterAnalysis enter(cx);
InferSpew(ISpewOps, "externalType: setThis #%u: %s",
script->id(), TypeString(type));
@ -1021,7 +1021,7 @@ TypeScript::SetLocal(JSContext *cx, HandleScript script, unsigned local, Type ty
JS_ASSERT(script->types);
if (!LocalTypes(script, local)->hasType(type)) {
AutoEnterTypeInference enter(cx);
AutoEnterAnalysis enter(cx);
InferSpew(ISpewOps, "externalType: setLocal #%u %u: %s",
script->id(), local, TypeString(type));
@ -1046,7 +1046,7 @@ TypeScript::SetArgument(JSContext *cx, HandleScript script, unsigned arg, Type t
JS_ASSERT(script->types);
if (!ArgTypes(script, arg)->hasType(type)) {
AutoEnterTypeInference enter(cx);
AutoEnterAnalysis enter(cx);
InferSpew(ISpewOps, "externalType: setArg #%u %u: %s",
script->id(), arg, TypeString(type));
@ -1350,7 +1350,7 @@ TypeSet::clearObjects()
inline void
TypeSet::addType(JSContext *cx, Type type)
{
JS_ASSERT(cx->compartment->activeInference);
JS_ASSERT(cx->compartment->activeAnalysis);
if (unknown())
return;
@ -1537,7 +1537,7 @@ TypeObject::setBasePropertyCount(uint32_t count)
inline HeapTypeSet *
TypeObject::getProperty(JSContext *cx, jsid id, bool own)
{
JS_ASSERT(cx->compartment->activeInference);
JS_ASSERT(cx->compartment->activeAnalysis);
JS_ASSERT(JSID_IS_VOID(id) || JSID_IS_EMPTY(id) || JSID_IS_STRING(id));
JS_ASSERT_IF(!JSID_IS_EMPTY(id), id == MakeTypeId(cx, id));
JS_ASSERT(!unknownProperties());
@ -1730,8 +1730,7 @@ JSScript::ensureHasTypes(JSContext *cx)
/* static */ inline bool
JSScript::ensureRanAnalysis(JSContext *cx, JS::HandleScript script)
{
AssertCanGC();
js::analyze::AutoEnterAnalysis aea(cx->compartment);
js::types::AutoEnterAnalysis aea(cx);
if (!script->ensureHasTypes(cx))
return false;
@ -1744,11 +1743,10 @@ JSScript::ensureRanAnalysis(JSContext *cx, JS::HandleScript script)
/* static */ inline bool
JSScript::ensureRanInference(JSContext *cx, JS::HandleScript script)
{
AssertCanGC();
if (!script->ensureRanAnalysis(cx, script))
return false;
if (!script->analysis()->ranInference()) {
js::types::AutoEnterTypeInference enter(cx);
js::types::AutoEnterAnalysis enter(cx);
script->analysis()->analyzeTypes(cx);
}
return !script->analysis()->OOM() &&

View File

@ -2349,7 +2349,7 @@ JSObject::growSlots(JSContext *cx, HandleObject obj, uint32_t oldCount, uint32_t
gc::AllocKind kind = obj->type()->newScript->allocKind;
unsigned newScriptSlots = gc::GetGCKindSlots(kind);
if (newScriptSlots == obj->numFixedSlots() && gc::TryIncrementAllocKind(&kind)) {
AutoEnterTypeInference enter(cx);
AutoEnterAnalysis enter(cx);
Rooted<TypeObject*> typeObj(cx, obj->type());
RootedShape shape(cx, typeObj->newScript->shape);

View File

@ -2745,7 +2745,7 @@ JSScript::argumentsOptimizationFailed(JSContext *cx, HandleScript script)
#endif
if (script->hasAnalysis() && script->analysis()->ranInference()) {
types::AutoEnterTypeInference enter(cx);
types::AutoEnterAnalysis enter(cx);
types::TypeScript::MonitorUnknown(cx, script, script->argumentsBytecode());
}

View File

@ -539,7 +539,7 @@ mjit::Compiler::performCompilation()
outerScript->debugMode = debugMode();
#endif
JS_ASSERT(cx->compartment->activeInference);
JS_ASSERT(cx->compartment->activeAnalysis);
{
types::AutoEnterCompilation enter(cx, types::CompilerOutput::MethodJIT);
@ -1091,7 +1091,7 @@ mjit::CanMethodJIT(JSContext *cx, HandleScript script, jsbytecode *pc,
CompileStatus status;
{
types::AutoEnterTypeInference enter(cx, true);
types::AutoEnterAnalysis enter(cx);
Compiler cc(cx, script, chunkIndex, construct);
status = cc.compile();

View File

@ -652,7 +652,7 @@ js_InternalThrow(VMFrame &f)
return NULL;
}
analyze::AutoEnterAnalysis enter(cx);
types::AutoEnterAnalysis enter(cx);
/*
* Interpret the ENTERBLOCK and EXCEPTION opcodes, so that we don't go
@ -797,7 +797,9 @@ js_InternalInterpret(void *returnData, void *returnType, void *returnReg, js::VM
return js_InternalThrow(f);
}
analyze::AutoEnterAnalysis enter(cx);
mozilla::Maybe<types::AutoEnterAnalysis> enter;
enter.construct(cx);
analyze::ScriptAnalysis *analysis = script->analysis();
/*
@ -1023,7 +1025,7 @@ js_InternalInterpret(void *returnData, void *returnType, void *returnReg, js::VM
case REJOIN_CALL_SPLAT: {
/* Leave analysis early and do the Invoke which SplatApplyArgs prepared. */
nextDepth = analysis->getCode(nextpc).stackDepth;
enter.leave();
enter.destroy();
f.regs.sp = nextsp + 2 + f.u.call.dynamicArgc;
if (!InvokeKernel(cx, CallArgsFromSp(f.u.call.dynamicArgc, f.regs.sp)))
return js_InternalThrow(f);

View File

@ -415,7 +415,7 @@ class SetPropCompiler : public PICStubCompiler
return false;
if (!type->unknownProperties()) {
types::AutoEnterTypeInference enter(cx);
types::AutoEnterAnalysis enter(cx);
types::TypeSet *types = type->getProperty(cx, types::MakeTypeId(cx, id), true);
if (!types)
return false;

View File

@ -411,7 +411,7 @@ Recompiler::clearStackReferences(FreeOp *fop, JSScript *script)
script->filename, script->lineno, script->length, (int) script->getUseCount());
JSCompartment *comp = script->compartment();
types::AutoEnterTypeInference enter(fop, comp);
types::AutoEnterAnalysis enter(fop, comp);
/*
* The strategy for this goes as follows:

View File

@ -1516,7 +1516,7 @@ stubs::TypeBarrierHelper(VMFrame &f, uint32_t which)
*/
RootedScript fscript(f.cx, f.script());
if (fscript->hasAnalysis() && fscript->analysis()->ranInference()) {
AutoEnterTypeInference enter(f.cx);
AutoEnterAnalysis enter(f.cx);
fscript->analysis()->breakTypeBarriers(f.cx, f.pc() - fscript->code, false);
}
@ -1530,7 +1530,7 @@ stubs::StubTypeHelper(VMFrame &f, int32_t which)
RootedScript fscript(f.cx, f.script());
if (fscript->hasAnalysis() && fscript->analysis()->ranInference()) {
AutoEnterTypeInference enter(f.cx);
AutoEnterAnalysis enter(f.cx);
fscript->analysis()->breakTypeBarriers(f.cx, f.pc() - fscript->code, false);
}
@ -1566,7 +1566,7 @@ stubs::CheckArgumentTypes(VMFrame &f)
{
/* Postpone recompilations until all args have been updated. */
types::AutoEnterTypeInference enter(f.cx);
types::AutoEnterAnalysis enter(f.cx);
if (!f.fp()->isConstructing())
TypeScript::SetThis(f.cx, fscript, fp->thisValue());