Bug 791611 (part 3) - Exactly root most JSScripts in jsinfer.cpp. r=terrence.

--HG--
extra : rebase_source : c675efbd7e628742e59cd14ae91ab8998d3dfc5c
This commit is contained in:
Nicholas Nethercote 2012-09-16 16:32:06 -07:00
parent cbb7f8ccdc
commit db15e47aa4
39 changed files with 850 additions and 754 deletions

View File

@ -443,7 +443,7 @@ ReflowArgTypes(JSContext *cx)
{
StackFrame *fp = cx->fp();
unsigned nargs = fp->fun()->nargs;
JSScript *script = fp->script();
RootedScript script(cx, fp->script());
types::AutoEnterTypeInference enter(cx);
@ -467,7 +467,7 @@ ion::ReflowTypeInfo(uint32 bailoutResult)
return true;
}
JSScript *script = cx->fp()->script();
RootedScript script(cx, cx->fp()->script());
jsbytecode *pc = activation->bailout()->bailoutPc();
JS_ASSERT(js_CodeSpec[*pc].format & JOF_TYPESET);

View File

@ -150,10 +150,10 @@ IonCompartment::initialize(JSContext *cx)
void
ion::FinishOffThreadBuilder(IonBuilder *builder)
{
if (builder->script->isIonCompilingOffThread()) {
types::TypeCompartment &types = builder->script->compartment()->types;
if (builder->script()->isIonCompilingOffThread()) {
types::TypeCompartment &types = builder->script()->compartment()->types;
builder->recompileInfo.compilerOutput(types)->invalidate();
builder->script->ion = NULL;
builder->script()->ion = NULL;
}
js_delete(builder->temp().lifoAlloc());
}
@ -903,17 +903,17 @@ class AutoDestroyAllocator
bool
TestCompiler(IonBuilder *builder, MIRGraph *graph, AutoDestroyAllocator &autoDestroy)
{
JS_ASSERT(!builder->script->ion);
JS_ASSERT(!builder->script()->ion);
JSContext *cx = GetIonContext()->cx;
IonSpewNewFunction(graph, builder->script);
IonSpewNewFunction(graph, builder->script());
if (!builder->build())
return false;
builder->clearForBackEnd();
if (js_IonOptions.parallelCompilation) {
builder->script->ion = ION_COMPILING_SCRIPT;
builder->script()->ion = ION_COMPILING_SCRIPT;
if (!StartOffThreadIonCompile(cx, builder))
return false;
@ -955,7 +955,7 @@ AttachFinishedCompilations(JSContext *cx)
IonBuilder *builder = compilations.popCopy();
if (builder->lir) {
JSScript *script = builder->script;
JSScript *script = builder->script();
IonContext ictx(cx, cx->compartment, &builder->temp());
CodeGenerator codegen(builder, *builder->lir);

View File

@ -26,7 +26,6 @@ using namespace js::ion;
IonBuilder::IonBuilder(JSContext *cx, TempAllocator *temp, MIRGraph *graph,
TypeOracle *oracle, CompileInfo *info, size_t inliningDepth, uint32 loopDepth)
: MIRGenerator(cx->compartment, temp, graph, info),
script(info->script()),
recompileInfo(cx->compartment->types.compiledInfo),
lir(NULL),
cx(cx),
@ -35,9 +34,10 @@ IonBuilder::IonBuilder(JSContext *cx, TempAllocator *temp, MIRGraph *graph,
callerBuilder_(NULL),
oracle(oracle),
inliningDepth(inliningDepth),
failedBoundsCheck_(script->failedBoundsCheck),
failedBoundsCheck_(info->script()->failedBoundsCheck),
lazyArguments_(NULL)
{
script_.init(info->script());
pc = info->startPC();
}
@ -57,7 +57,7 @@ IonBuilder::abort(const char *message, ...)
va_start(ap, message);
abortFmt(message, ap);
va_end(ap);
IonSpew(IonSpew_Abort, "aborted @ %s:%d", script->filename, PCToLineNumber(script, pc));
IonSpew(IonSpew_Abort, "aborted @ %s:%d", script_->filename, PCToLineNumber(script_, pc));
#endif
return false;
}
@ -67,7 +67,7 @@ IonBuilder::spew(const char *message)
{
// Don't call PCToLineNumber in release builds.
#ifdef DEBUG
IonSpew(IonSpew_MIR, "%s @ %s:%d", message, script->filename, PCToLineNumber(script, pc));
IonSpew(IonSpew_MIR, "%s @ %s:%d", message, script_->filename, PCToLineNumber(script_, pc));
#endif
}
@ -146,7 +146,7 @@ IonBuilder::CFGState::LookupSwitch(jsbytecode *exitpc)
JSFunction *
IonBuilder::getSingleCallTarget(uint32 argc, jsbytecode *pc)
{
types::StackTypeSet *calleeTypes = oracle->getCallTarget(script, argc, pc);
types::StackTypeSet *calleeTypes = oracle->getCallTarget(script(), argc, pc);
if (!calleeTypes)
return NULL;
@ -161,7 +161,7 @@ uint32_t
IonBuilder::getPolyCallTargets(uint32 argc, jsbytecode *pc,
AutoObjectVector &targets, uint32_t maxTargets)
{
types::TypeSet *calleeTypes = oracle->getCallTarget(script, argc, pc);
types::TypeSet *calleeTypes = oracle->getCallTarget(script_, argc, pc);
if (!calleeTypes)
return 0;
@ -191,7 +191,7 @@ IonBuilder::canInlineTarget(JSFunction *target)
return false;
}
if (target->getParent() != &script->global()) {
if (target->getParent() != &script_->global()) {
IonSpew(IonSpew_Inlining, "Cannot inline due to scope mismatch");
return false;
}
@ -206,7 +206,7 @@ IonBuilder::canInlineTarget(JSFunction *target)
// Allow inlining of recursive calls, but only one level deep.
IonBuilder *builder = callerBuilder_;
while (builder) {
if (builder->script == inlineScript) {
if (builder->script() == inlineScript) {
IonSpew(IonSpew_Inlining, "Not inlining recursive call");
return false;
}
@ -216,7 +216,7 @@ IonBuilder::canInlineTarget(JSFunction *target)
bool canInline = oracle->canEnterInlinedFunction(target);
if (!canInline) {
IonSpew(IonSpew_Inlining, "Cannot inline due to oracle veto %d", script->lineno);
IonSpew(IonSpew_Inlining, "Cannot inline due to oracle veto %d", script_->lineno);
return false;
}
@ -265,10 +265,10 @@ IonBuilder::build()
return false;
IonSpew(IonSpew_Scripts, "Analyzing script %s:%d (%p) (usecount=%d) (maxloopcount=%d)",
script->filename, script->lineno, (void *)script, (int)script->getUseCount(),
(int)script->getMaxLoopCount());
script_->filename, script_->lineno, (void *)script_, (int)script_->getUseCount(),
(int)script_->getMaxLoopCount());
if (!graph().addScript(script))
if (!graph().addScript(script_))
return false;
if (!initParameters())
@ -294,7 +294,7 @@ IonBuilder::build()
// Emit the start instruction, so we can begin real instructions.
current->makeStart(MStart::New(MStart::StartType_Default));
if (instrumentedProfiling())
current->add(MFunctionBoundary::New(script, MFunctionBoundary::Enter));
current->add(MFunctionBoundary::New(script_, MFunctionBoundary::Enter));
// Parameters have been checked to correspond to the typeset, now we unbox
// what we can in an infallible manner.
@ -337,7 +337,7 @@ IonBuilder::build()
// Recompile to inline calls if this function is hot.
insertRecompileCheck();
if (script->argumentsHasVarBinding()) {
if (script_->argumentsHasVarBinding()) {
lazyArguments_ = MConstant::New(MagicValue(JS_OPTIMIZED_ARGUMENTS));
current->add(lazyArguments_);
}
@ -391,9 +391,9 @@ IonBuilder::buildInline(IonBuilder *callerBuilder, MResumePoint *callerResumePoi
MDefinition *thisDefn, MDefinitionVector &argv)
{
IonSpew(IonSpew_Scripts, "Inlining script %s:%d (%p)",
script->filename, script->lineno, (void *)script);
script_->filename, script_->lineno, (void *)script_);
if (!graph().addScript(script))
if (!graph().addScript(script_))
return false;
callerBuilder_ = callerBuilder;
@ -418,7 +418,7 @@ IonBuilder::buildInline(IonBuilder *callerBuilder, MResumePoint *callerResumePoi
// keep track of the inlining depth because all scripts inlined on the same
// level contiguously have only one Inline_Exit node.
if (instrumentedProfiling())
predecessor->add(MFunctionBoundary::New(script,
predecessor->add(MFunctionBoundary::New(script_,
MFunctionBoundary::Inline_Enter,
inliningDepth));
@ -442,7 +442,7 @@ IonBuilder::buildInline(IonBuilder *callerBuilder, MResumePoint *callerResumePoi
}
// The Oracle ensures that the inlined script does not use the scope chain.
JS_ASSERT(!script->analysis()->usesScopeChain());
JS_ASSERT(!script_->analysis()->usesScopeChain());
MInstruction *scope = MConstant::New(UndefinedValue());
current->add(scope);
current->initSlot(info().scopeChainSlot(), scope);
@ -533,12 +533,12 @@ IonBuilder::initParameters()
return true;
MParameter *param = MParameter::New(MParameter::THIS_SLOT,
oracle->thisTypeSet(script));
oracle->thisTypeSet(script_));
current->add(param);
current->initSlot(info().thisSlot(), param);
for (uint32 i = 0; i < info().nargs(); i++) {
param = MParameter::New(i, oracle->parameterTypeSet(script, i));
param = MParameter::New(i, oracle->parameterTypeSet(script_, i));
current->add(param);
current->initSlot(info().argSlot(i), param);
}
@ -553,14 +553,14 @@ IonBuilder::initScopeChain()
// If the script doesn't use the scopechain, then it's already initialized
// from earlier.
if (!script->analysis()->usesScopeChain())
if (!script_->analysis()->usesScopeChain())
return true;
// The scope chain is only tracked in scripts that have NAME opcodes which
// will try to access the scope. For other scripts, the scope instructions
// will be held live by resume points and code will still be generated for
// them, so just use a constant undefined value.
if (!script->compileAndGo)
if (!script_->compileAndGo)
return abort("non-CNG global scripts are not supported");
if (JSFunction *fun = info().fun()) {
@ -580,7 +580,7 @@ IonBuilder::initScopeChain()
return false;
}
} else {
scope = MConstant::New(ObjectValue(script->global()));
scope = MConstant::New(ObjectValue(script_->global()));
current->add(scope);
}
@ -743,7 +743,7 @@ IonBuilder::snoopControlFlow(JSOp op)
void
IonBuilder::markPhiBytecodeUses(jsbytecode *pc)
{
unsigned nuses = analyze::GetUseCount(script, pc - script->code);
unsigned nuses = analyze::GetUseCount(script_, pc - script_->code);
for (unsigned i = 0; i < nuses; i++) {
MDefinition *def = current->peek(-(i + 1));
if (def->isPassArg())
@ -947,7 +947,7 @@ IonBuilder::inspectOpcode(JSOp op)
}
case JSOP_BINDGNAME:
return pushConstant(ObjectValue(script->global()));
return pushConstant(ObjectValue(script_->global()));
case JSOP_SETGNAME:
{
@ -2290,7 +2290,7 @@ IonBuilder::lookupSwitch(JSOp op, jssrcnote *sn)
bool prevShared = false;
jsbytecode *prevpc = NULL;
for (unsigned int i = 0; i < ncases; i++) {
Value rval = script->getConst(GET_UINT32_INDEX(pc2));
Value rval = script_->getConst(GET_UINT32_INDEX(pc2));
pc2 += UINT32_INDEX_LEN;
jsbytecode *casepc = pc + GET_JUMP_OFFSET(pc2);
pc2 += JUMP_OFFSET_LEN;
@ -2570,7 +2570,7 @@ IonBuilder::processReturn(JSOp op)
}
if (instrumentedProfiling())
current->add(MFunctionBoundary::New(script, MFunctionBoundary::Exit));
current->add(MFunctionBoundary::New(script_, MFunctionBoundary::Exit));
MReturn *ret = MReturn::New(def);
current->end(ret);
@ -2614,7 +2614,7 @@ IonBuilder::jsop_bitnot()
MBitNot *ins = MBitNot::New(input);
current->add(ins);
ins->infer(oracle->unaryTypes(script, pc));
ins->infer(oracle->unaryTypes(script_, pc));
current->push(ins);
if (ins->isEffectful() && !resumeAfter(ins))
@ -2660,7 +2660,7 @@ IonBuilder::jsop_bitop(JSOp op)
}
current->add(ins);
ins->infer(oracle->binaryTypes(script, pc));
ins->infer(oracle->binaryTypes(script_, pc));
current->push(ins);
if (ins->isEffectful() && !resumeAfter(ins))
@ -2672,7 +2672,7 @@ IonBuilder::jsop_bitop(JSOp op)
bool
IonBuilder::jsop_binary(JSOp op, MDefinition *left, MDefinition *right)
{
TypeOracle::Binary b = oracle->binaryOp(script, pc);
TypeOracle::Binary b = oracle->binaryOp(script_, pc);
if (op == JSOP_ADD && b.rval == MIRType_String &&
(b.lhs == MIRType_String || b.lhs == MIRType_Int32) &&
@ -2711,7 +2711,7 @@ IonBuilder::jsop_binary(JSOp op, MDefinition *left, MDefinition *right)
return false;
}
TypeOracle::BinaryTypes types = oracle->binaryTypes(script, pc);
TypeOracle::BinaryTypes types = oracle->binaryTypes(script_, pc);
current->add(ins);
ins->infer(cx, types);
current->push(ins);
@ -2733,7 +2733,7 @@ IonBuilder::jsop_binary(JSOp op)
bool
IonBuilder::jsop_pos()
{
TypeOracle::Unary types = oracle->unaryOp(script, pc);
TypeOracle::Unary types = oracle->unaryOp(script_, pc);
if (IsNumberType(types.ival)) {
// Already int32 or double.
JS_ASSERT(IsNumberType(types.rval));
@ -2918,12 +2918,12 @@ IonBuilder::makeInliningDecision(AutoObjectVector &targets)
if (allFunctionsAreSmall)
checkUses = js_IonOptions.smallFunctionUsesBeforeInlining;
if (script->getUseCount() < checkUses) {
if (script_->getUseCount() < checkUses) {
IonSpew(IonSpew_Inlining, "Not inlining, caller is not hot");
return false;
}
if (!oracle->canInlineCall(script, pc)) {
if (!oracle->canInlineCall(script_, pc)) {
IonSpew(IonSpew_Inlining, "Cannot inline due to uninlineable call site");
return false;
}
@ -3423,7 +3423,7 @@ IonBuilder::createCallObject(MDefinition *callee, MDefinition *scope)
// Create a template CallObject that we'll use to generate inline object
// creation.
RootedObject templateObj(cx, CallObject::createTemplateObject(cx, script));
RootedObject templateObj(cx, CallObject::createTemplateObject(cx, script_));
if (!templateObj)
return NULL;
@ -3449,7 +3449,7 @@ IonBuilder::createCallObject(MDefinition *callee, MDefinition *scope)
current->add(MStoreFixedSlot::New(callObj, CallObject::enclosingScopeSlot(), scope));
// Initialize argument slots.
for (AliasedFormalIter i(script); i; i++) {
for (AliasedFormalIter i(script_); i; i++) {
unsigned slot = i.scopeSlot();
unsigned formal = i.frameIndex();
MDefinition *param = current->getSlot(info().argSlot(formal));
@ -3573,7 +3573,7 @@ IonBuilder::jsop_funcall(uint32 argc)
return makeCall(native, argc, false);
// Extract call target.
types::StackTypeSet *funTypes = oracle->getCallArg(script, argc, 0, pc);
types::StackTypeSet *funTypes = oracle->getCallArg(script_, argc, 0, pc);
RootedObject funobj(cx, (funTypes) ? funTypes->getSingleton() : NULL);
RootedFunction target(cx, (funobj && funobj->isFunction()) ? funobj->toFunction() : NULL);
@ -3615,7 +3615,7 @@ IonBuilder::jsop_funapply(uint32 argc)
// Disable compilation if the second argument to |apply| cannot be guaranteed
// to be either definitely |arguments| or definitely not |arguments|.
types::StackTypeSet *argObjTypes = oracle->getCallArg(script, argc, 2, pc);
types::StackTypeSet *argObjTypes = oracle->getCallArg(script_, argc, 2, pc);
LazyArgumentsType isArgObj = oracle->isArgumentObject(argObjTypes);
if (isArgObj == MaybeArguments)
return abort("fun.apply with MaybeArguments");
@ -3638,7 +3638,7 @@ IonBuilder::jsop_funapply(uint32 argc)
// argc+2: The native 'apply' function.
// Extract call target.
types::StackTypeSet *funTypes = oracle->getCallArg(script, argc, 0, pc);
types::StackTypeSet *funTypes = oracle->getCallArg(script_, argc, 0, pc);
RootedObject funobj(cx, (funTypes) ? funTypes->getSingleton() : NULL);
RootedFunction target(cx, (funobj && funobj->isFunction()) ? funobj->toFunction() : NULL);
@ -3672,7 +3672,7 @@ IonBuilder::jsop_funapply(uint32 argc)
return false;
types::StackTypeSet *barrier;
types::StackTypeSet *types = oracle->returnTypeSet(script, pc, &barrier);
types::StackTypeSet *types = oracle->returnTypeSet(script_, pc, &barrier);
return pushTypeBarrier(apply, types, barrier);
}
@ -3718,7 +3718,7 @@ IonBuilder::jsop_call(uint32 argc, bool constructing)
AutoObjectVector targets(cx);
uint32_t numTargets = getPolyCallTargets(argc, pc, targets, 4);
types::StackTypeSet *barrier;
types::StackTypeSet *types = oracle->returnTypeSet(script, pc, &barrier);
types::StackTypeSet *types = oracle->returnTypeSet(script_, pc, &barrier);
// Attempt to inline native and scripted functions.
if (inliningEnabled()) {
@ -3747,7 +3747,7 @@ IonBuilder::jsop_call(uint32 argc, bool constructing)
// or will only be used to test for existence.
if (target->maybeNative() == regexp_exec && !CallResultEscapes(pc)) {
JSFunction *newTarget = NULL;
if (!GetBuiltinRegExpTest(cx, script, &newTarget))
if (!GetBuiltinRegExpTest(cx, script_, &newTarget))
return false;
if (newTarget)
target = newTarget;
@ -3848,7 +3848,7 @@ bool
IonBuilder::makeCall(HandleFunction target, uint32 argc, bool constructing)
{
types::StackTypeSet *barrier;
types::StackTypeSet *types = oracle->returnTypeSet(script, pc, &barrier);
types::StackTypeSet *types = oracle->returnTypeSet(script_, pc, &barrier);
return makeCallBarrier(target, argc, constructing, types, barrier);
}
@ -3857,7 +3857,7 @@ IonBuilder::jsop_incslot(JSOp op, uint32 slot)
{
int32 amt = (js_CodeSpec[op].format & JOF_INC) ? 1 : -1;
bool post = !!(js_CodeSpec[op].format & JOF_POST);
TypeOracle::BinaryTypes types = oracle->incslot(script, pc);
TypeOracle::BinaryTypes types = oracle->incslot(script_, pc);
// Grab the value at the local slot, and convert it to a number. Currently,
// we use ToInt32 or ToNumber which are fallible but idempotent. This whole
@ -3918,7 +3918,7 @@ IonBuilder::jsop_compare(JSOp op)
current->add(ins);
current->push(ins);
ins->infer(cx, oracle->binaryTypes(script, pc));
ins->infer(cx, oracle->binaryTypes(script_, pc));
if (ins->isEffectful() && !resumeAfter(ins))
return false;
@ -3932,6 +3932,7 @@ IonBuilder::getNewArrayTemplateObject(uint32 count)
if (!templateObject)
return NULL;
RootedScript script(cx, script_);
if (types::UseNewTypeForInitializer(cx, script, pc, JSProto_Array)) {
if (!JSObject::setSingletonType(cx, templateObject))
return NULL;
@ -3948,7 +3949,7 @@ IonBuilder::getNewArrayTemplateObject(uint32 count)
bool
IonBuilder::jsop_newarray(uint32 count)
{
JS_ASSERT(script->compileAndGo);
JS_ASSERT(script_->compileAndGo);
JSObject *templateObject = getNewArrayTemplateObject(count);
if (!templateObject)
@ -3966,7 +3967,7 @@ bool
IonBuilder::jsop_newobject(HandleObject baseObj)
{
// Don't bake in the TypeObject for non-CNG scripts.
JS_ASSERT(script->compileAndGo);
JS_ASSERT(script_->compileAndGo);
RootedObject templateObject(cx);
@ -3980,6 +3981,7 @@ IonBuilder::jsop_newobject(HandleObject baseObj)
if (!templateObject)
return false;
RootedScript script(cx, script_);
if (types::UseNewTypeForInitializer(cx, script, pc, JSProto_Object)) {
if (!JSObject::setSingletonType(cx, templateObject))
return false;
@ -4001,8 +4003,8 @@ IonBuilder::jsop_newobject(HandleObject baseObj)
bool
IonBuilder::jsop_initelem()
{
if (oracle->propertyWriteCanSpecialize(script, pc)) {
if (oracle->elementWriteIsDenseArray(script, pc))
if (oracle->propertyWriteCanSpecialize(script_, pc)) {
if (oracle->elementWriteIsDenseArray(script_, pc))
return jsop_initelem_dense();
}
@ -4055,7 +4057,7 @@ IonBuilder::jsop_initprop(HandlePropertyName name)
RootedObject templateObject(cx, obj->toNewObject()->templateObject());
if (!oracle->propertyWriteCanSpecialize(script, pc)) {
if (!oracle->propertyWriteCanSpecialize(script_, pc)) {
// This should only happen for a few names like __proto__.
return abort("INITPROP Monitored initprop");
}
@ -4079,7 +4081,7 @@ IonBuilder::jsop_initprop(HandlePropertyName name)
}
bool needsBarrier = true;
TypeOracle::BinaryTypes b = oracle->binaryTypes(script, pc);
TypeOracle::BinaryTypes b = oracle->binaryTypes(script_, pc);
if (b.lhsTypes &&
((jsid)id == types::MakeTypeId(cx, id)) &&
!b.lhsTypes->propertyNeedsBarrier(cx, id))
@ -4373,7 +4375,7 @@ IonBuilder::insertRecompileCheck()
return;
// Don't recompile if we are already inlining.
if (script->getUseCount() >= js_IonOptions.usesBeforeInlining)
if (script_->getUseCount() >= js_IonOptions.usesBeforeInlining)
return;
// Don't recompile if the oracle cannot provide inlining information
@ -4381,7 +4383,7 @@ IonBuilder::insertRecompileCheck()
if (!oracle->canInlineCalls())
return;
uint32_t minUses = UsesBeforeIonRecompile(script, pc);
uint32_t minUses = UsesBeforeIonRecompile(script_, pc);
MRecompileCheck *check = MRecompileCheck::New(minUses);
current->add(check);
}
@ -4632,7 +4634,7 @@ IonBuilder::jsop_getgname(HandlePropertyName name)
if (name == cx->names().Infinity)
return pushConstant(cx->runtime->positiveInfinityValue);
RootedObject globalObj(cx, &script->global());
RootedObject globalObj(cx, &script_->global());
JS_ASSERT(globalObj->isNative());
RootedId id(cx, NameToId(name));
@ -4643,7 +4645,7 @@ IonBuilder::jsop_getgname(HandlePropertyName name)
if (!shape || !shape->hasDefaultGetter() || !shape->hasSlot())
return jsop_getname(name);
types::HeapTypeSet *propertyTypes = oracle->globalPropertyTypeSet(script, pc, id);
types::HeapTypeSet *propertyTypes = oracle->globalPropertyTypeSet(script_, pc, id);
if (propertyTypes && propertyTypes->isOwnProperty(cx, globalObj->getType(cx), true)) {
// The property has been reconfigured as non-configurable, non-enumerable
// or non-writable.
@ -4653,8 +4655,8 @@ IonBuilder::jsop_getgname(HandlePropertyName name)
// If the property is permanent, a shape guard isn't necessary.
JSValueType knownType = JSVAL_TYPE_UNKNOWN;
types::StackTypeSet *barrier = oracle->propertyReadBarrier(script, pc);
types::StackTypeSet *types = oracle->propertyRead(script, pc);
types::StackTypeSet *barrier = oracle->propertyReadBarrier(script_, pc);
types::StackTypeSet *types = oracle->propertyRead(script_, pc);
if (types) {
JSObject *singleton = types->getSingleton();
@ -4703,13 +4705,13 @@ IonBuilder::jsop_getgname(HandlePropertyName name)
bool
IonBuilder::jsop_setgname(HandlePropertyName name)
{
RootedObject globalObj(cx, &script->global());
RootedObject globalObj(cx, &script_->global());
RootedId id(cx, NameToId(name));
JS_ASSERT(globalObj->isNative());
bool canSpecialize;
types::HeapTypeSet *propertyTypes = oracle->globalPropertyWrite(script, pc, id, &canSpecialize);
types::HeapTypeSet *propertyTypes = oracle->globalPropertyWrite(script_, pc, id, &canSpecialize);
// This should only happen for a few names like __proto__.
if (!canSpecialize || globalObj->watched())
@ -4776,7 +4778,7 @@ IonBuilder::jsop_getname(HandlePropertyName name)
{
MDefinition *object;
if (js_CodeSpec[*pc].format & JOF_GNAME) {
MInstruction *global = MConstant::New(ObjectValue(script->global()));
MInstruction *global = MConstant::New(ObjectValue(script_->global()));
current->add(global);
object = global;
} else {
@ -4796,8 +4798,8 @@ IonBuilder::jsop_getname(HandlePropertyName name)
if (!resumeAfter(ins))
return false;
types::StackTypeSet *barrier = oracle->propertyReadBarrier(script, pc);
types::StackTypeSet *types = oracle->propertyRead(script, pc);
types::StackTypeSet *barrier = oracle->propertyReadBarrier(script_, pc);
types::StackTypeSet *types = oracle->propertyRead(script_, pc);
monitorResult(ins, types);
return pushTypeBarrier(ins, types, barrier);
@ -4806,10 +4808,10 @@ IonBuilder::jsop_getname(HandlePropertyName name)
bool
IonBuilder::jsop_bindname(PropertyName *name)
{
JS_ASSERT(script->analysis()->usesScopeChain());
JS_ASSERT(script_->analysis()->usesScopeChain());
MDefinition *scopeChain = current->scopeChain();
MBindNameCache *ins = MBindNameCache::New(scopeChain, name, script, pc);
MBindNameCache *ins = MBindNameCache::New(scopeChain, name, script_, pc);
current->add(ins);
current->push(ins);
@ -4820,17 +4822,17 @@ IonBuilder::jsop_bindname(PropertyName *name)
bool
IonBuilder::jsop_getelem()
{
if (oracle->elementReadIsDenseArray(script, pc))
if (oracle->elementReadIsDenseArray(script_, pc))
return jsop_getelem_dense();
int arrayType = TypedArray::TYPE_MAX;
if (oracle->elementReadIsTypedArray(script, pc, &arrayType))
if (oracle->elementReadIsTypedArray(script_, pc, &arrayType))
return jsop_getelem_typed(arrayType);
if (oracle->elementReadIsString(script, pc))
if (oracle->elementReadIsString(script_, pc))
return jsop_getelem_string();
LazyArgumentsType isArguments = oracle->elementReadMagicArguments(script, pc);
LazyArgumentsType isArguments = oracle->elementReadMagicArguments(script_, pc);
if (isArguments == MaybeArguments)
return abort("Type is not definitely lazy arguments.");
if (isArguments == DefinitelyArguments)
@ -4848,7 +4850,7 @@ IonBuilder::jsop_getelem()
bool mustMonitorResult = false;
bool cacheable = false;
oracle->elementReadGeneric(script, pc, &cacheable, &mustMonitorResult);
oracle->elementReadGeneric(script_, pc, &cacheable, &mustMonitorResult);
if (cacheable)
ins = MGetElementCache::New(lhs, rhs, mustMonitorResult);
@ -4861,8 +4863,8 @@ IonBuilder::jsop_getelem()
if (!resumeAfter(ins))
return false;
types::StackTypeSet *barrier = oracle->propertyReadBarrier(script, pc);
types::StackTypeSet *types = oracle->propertyRead(script, pc);
types::StackTypeSet *barrier = oracle->propertyReadBarrier(script_, pc);
types::StackTypeSet *types = oracle->propertyRead(script_, pc);
if (mustMonitorResult)
monitorResult(ins, types);
@ -4875,9 +4877,9 @@ IonBuilder::jsop_getelem_dense()
if (oracle->arrayPrototypeHasIndexedProperty())
return abort("GETELEM Array proto has indexed properties");
types::StackTypeSet *barrier = oracle->propertyReadBarrier(script, pc);
types::StackTypeSet *types = oracle->propertyRead(script, pc);
bool needsHoleCheck = !oracle->elementReadIsPacked(script, pc);
types::StackTypeSet *barrier = oracle->propertyReadBarrier(script_, pc);
types::StackTypeSet *types = oracle->propertyRead(script_, pc);
bool needsHoleCheck = !oracle->elementReadIsPacked(script_, pc);
bool maybeUndefined = types->hasType(types::Type::UndefinedType());
MDefinition *id = current->pop();
@ -4964,8 +4966,8 @@ GetTypedArrayElements(MDefinition *obj)
bool
IonBuilder::jsop_getelem_typed(int arrayType)
{
types::StackTypeSet *barrier = oracle->propertyReadBarrier(script, pc);
types::StackTypeSet *types = oracle->propertyRead(script, pc);
types::StackTypeSet *barrier = oracle->propertyReadBarrier(script_, pc);
types::StackTypeSet *types = oracle->propertyRead(script_, pc);
MDefinition *id = current->pop();
MDefinition *obj = current->pop();
@ -5074,16 +5076,16 @@ IonBuilder::jsop_getelem_string()
bool
IonBuilder::jsop_setelem()
{
if (oracle->propertyWriteCanSpecialize(script, pc)) {
if (oracle->elementWriteIsDenseArray(script, pc))
if (oracle->propertyWriteCanSpecialize(script_, pc)) {
if (oracle->elementWriteIsDenseArray(script_, pc))
return jsop_setelem_dense();
int arrayType = TypedArray::TYPE_MAX;
if (oracle->elementWriteIsTypedArray(script, pc, &arrayType))
if (oracle->elementWriteIsTypedArray(script_, pc, &arrayType))
return jsop_setelem_typed(arrayType);
}
LazyArgumentsType isArguments = oracle->elementWriteMagicArguments(script, pc);
LazyArgumentsType isArguments = oracle->elementWriteMagicArguments(script_, pc);
if (isArguments == MaybeArguments)
return abort("Type is not definitely lazy arguments.");
if (isArguments == DefinitelyArguments)
@ -5106,8 +5108,8 @@ IonBuilder::jsop_setelem_dense()
if (oracle->arrayPrototypeHasIndexedProperty())
return abort("SETELEM Array proto has indexed properties");
MIRType elementType = oracle->elementWrite(script, pc);
bool packed = oracle->elementWriteIsPacked(script, pc);
MIRType elementType = oracle->elementWrite(script_, pc);
bool packed = oracle->elementWriteIsPacked(script_, pc);
MDefinition *value = current->pop();
MDefinition *id = current->pop();
@ -5126,7 +5128,7 @@ IonBuilder::jsop_setelem_dense()
// indexes in the past. Otherwise, use MStoreElement so that we can hoist
// the initialized length and bounds check.
MStoreElementCommon *store;
if (oracle->setElementHasWrittenHoles(script, pc)) {
if (oracle->setElementHasWrittenHoles(script_, pc)) {
MStoreElementHole *ins = MStoreElementHole::New(obj, elements, id, value);
store = ins;
@ -5152,7 +5154,7 @@ IonBuilder::jsop_setelem_dense()
}
// Determine whether a write barrier is required.
if (oracle->elementWriteNeedsBarrier(script, pc))
if (oracle->elementWriteNeedsBarrier(script_, pc))
store->setNeedsBarrier();
if (elementType != MIRType_None && packed)
@ -5212,7 +5214,7 @@ IonBuilder::jsop_length()
bool
IonBuilder::jsop_length_fastPath()
{
TypeOracle::UnaryTypes sig = oracle->unaryTypes(script, pc);
TypeOracle::UnaryTypes sig = oracle->unaryTypes(script_, pc);
if (!sig.inTypes || !sig.outTypes)
return false;
@ -5282,8 +5284,8 @@ IonBuilder::jsop_arguments_length()
bool
IonBuilder::jsop_arguments_getelem()
{
types::StackTypeSet *barrier = oracle->propertyReadBarrier(script, pc);
types::StackTypeSet *types = oracle->propertyRead(script, pc);
types::StackTypeSet *barrier = oracle->propertyReadBarrier(script_, pc);
types::StackTypeSet *types = oracle->propertyRead(script_, pc);
MDefinition *idx = current->pop();
@ -5747,7 +5749,7 @@ IonBuilder::invalidatedIdempotentCache()
{
IonBuilder *builder = this;
do {
if (builder->script->invalidatedIdempotentCache)
if (builder->script()->invalidatedIdempotentCache)
return true;
builder = builder->callerBuilder_;
} while (builder);
@ -5761,8 +5763,8 @@ IonBuilder::loadSlot(MDefinition *obj, Shape *shape, MIRType rvalType)
JS_ASSERT(shape->hasDefaultGetter());
JS_ASSERT(shape->hasSlot());
types::StackTypeSet *barrier = oracle->propertyReadBarrier(script, pc);
types::StackTypeSet *types = oracle->propertyRead(script, pc);
types::StackTypeSet *barrier = oracle->propertyReadBarrier(script_, pc);
types::StackTypeSet *types = oracle->propertyRead(script_, pc);
if (shape->slot() < shape->numFixedSlots()) {
MLoadFixedSlot *load = MLoadFixedSlot::New(obj, shape->slot());
@ -5814,7 +5816,7 @@ IonBuilder::storeSlot(MDefinition *obj, Shape *shape, MDefinition *value, bool n
bool
IonBuilder::jsop_getprop(HandlePropertyName name)
{
LazyArgumentsType isArguments = oracle->propertyReadMagicArguments(script, pc);
LazyArgumentsType isArguments = oracle->propertyReadMagicArguments(script_, pc);
if (isArguments == MaybeArguments)
return abort("Type is not definitely lazy arguments.");
if (isArguments == DefinitelyArguments) {
@ -5826,18 +5828,18 @@ IonBuilder::jsop_getprop(HandlePropertyName name)
MDefinition *obj = current->pop();
MInstruction *ins;
types::StackTypeSet *barrier = oracle->propertyReadBarrier(script, pc);
types::StackTypeSet *types = oracle->propertyRead(script, pc);
types::StackTypeSet *barrier = oracle->propertyReadBarrier(script_, pc);
types::StackTypeSet *types = oracle->propertyRead(script_, pc);
TypeOracle::Unary unary = oracle->unaryOp(script, pc);
TypeOracle::UnaryTypes unaryTypes = oracle->unaryTypes(script, pc);
TypeOracle::Unary unary = oracle->unaryOp(script_, pc);
TypeOracle::UnaryTypes unaryTypes = oracle->unaryTypes(script_, pc);
RootedId id(cx, NameToId(name));
JSObject *singleton = types ? types->getSingleton() : NULL;
if (singleton && !barrier) {
bool isKnownConstant, testObject;
RootedObject global(cx, &script->global());
RootedObject global(cx, &script_->global());
if (!TestSingletonPropertyTypes(cx, unaryTypes.inTypes,
global, id,
&isKnownConstant, &testObject))
@ -5918,7 +5920,7 @@ IonBuilder::jsop_getprop(HandlePropertyName name)
rvalType = unary.rval;
Shape *objShape;
if ((objShape = mjit::GetPICSingleShape(cx, script, pc, info().constructing())) &&
if ((objShape = mjit::GetPICSingleShape(cx, script_, pc, info().constructing())) &&
!objShape->inDictionary())
{
// The JM IC was monomorphic, so we inline the property access as
@ -5948,7 +5950,7 @@ IonBuilder::jsop_getprop(HandlePropertyName name)
if ((cx->methodJitEnabled || js_IonOptions.eagerCompilation) &&
!invalidatedIdempotentCache())
{
if (oracle->propertyReadIdempotent(script, pc, id))
if (oracle->propertyReadIdempotent(script_, pc, id))
load->setIdempotent();
}
@ -5978,9 +5980,9 @@ IonBuilder::jsop_setprop(HandlePropertyName name)
MDefinition *value = current->pop();
MDefinition *obj = current->pop();
bool monitored = !oracle->propertyWriteCanSpecialize(script, pc);
bool monitored = !oracle->propertyWriteCanSpecialize(script_, pc);
TypeOracle::BinaryTypes binaryTypes = oracle->binaryTypes(script, pc);
TypeOracle::BinaryTypes binaryTypes = oracle->binaryTypes(script_, pc);
if (!monitored) {
if (types::HeapTypeSet *propTypes = GetDefiniteSlot(cx, binaryTypes.lhsTypes, name)) {
@ -6034,14 +6036,14 @@ IonBuilder::jsop_setprop(HandlePropertyName name)
return resumeAfter(call);
}
oracle->binaryOp(script, pc);
oracle->binaryOp(script_, pc);
MSetPropertyInstruction *ins;
if (monitored) {
ins = MCallSetProperty::New(obj, value, name, script->strictModeCode);
ins = MCallSetProperty::New(obj, value, name, script_->strictModeCode);
} else {
Shape *objShape;
if ((objShape = mjit::GetPICSingleShape(cx, script, pc, info().constructing())) &&
if ((objShape = mjit::GetPICSingleShape(cx, script_, pc, info().constructing())) &&
!objShape->inDictionary())
{
// The JM IC was monomorphic, so we inline the property access as
@ -6057,14 +6059,14 @@ IonBuilder::jsop_setprop(HandlePropertyName name)
spew("Inlining monomorphic SETPROP");
jsid typeId = types::MakeTypeId(cx, id);
bool needsBarrier = oracle->propertyWriteNeedsBarrier(script, pc, typeId);
bool needsBarrier = oracle->propertyWriteNeedsBarrier(script_, pc, typeId);
return storeSlot(obj, shape, value, needsBarrier);
}
spew("SETPROP not monomorphic");
ins = MSetPropertyCache::New(obj, value, name, script->strictModeCode);
ins = MSetPropertyCache::New(obj, value, name, script_->strictModeCode);
if (!binaryTypes.lhsTypes || binaryTypes.lhsTypes->propertyNeedsBarrier(cx, id))
ins->setNeedsBarrier();
@ -6092,7 +6094,7 @@ IonBuilder::jsop_delprop(HandlePropertyName name)
bool
IonBuilder::jsop_regexp(RegExpObject *reobj)
{
JSObject *prototype = script->global().getOrCreateRegExpPrototype(cx);
JSObject *prototype = script_->global().getOrCreateRegExpPrototype(cx);
if (!prototype)
return false;
@ -6116,7 +6118,7 @@ IonBuilder::jsop_object(JSObject *obj)
bool
IonBuilder::jsop_lambda(JSFunction *fun)
{
JS_ASSERT(script->analysis()->usesScopeChain());
JS_ASSERT(script_->analysis()->usesScopeChain());
MLambda *ins = MLambda::New(current->scopeChain(), fun);
current->add(ins);
current->push(ins);
@ -6127,7 +6129,7 @@ IonBuilder::jsop_lambda(JSFunction *fun)
bool
IonBuilder::jsop_deflocalfun(uint32 local, JSFunction *fun)
{
JS_ASSERT(script->analysis()->usesScopeChain());
JS_ASSERT(script_->analysis()->usesScopeChain());
MLambda *ins = MLambda::New(current->scopeChain(), fun);
current->add(ins);
@ -6144,7 +6146,7 @@ IonBuilder::jsop_defvar(uint32 index)
{
JS_ASSERT(JSOp(*pc) == JSOP_DEFVAR || JSOp(*pc) == JSOP_DEFCONST);
PropertyName *name = script->getName(index);
PropertyName *name = script_->getName(index);
// Bake in attrs.
unsigned attrs = JSPROP_ENUMERATE | JSPROP_PERMANENT;
@ -6152,7 +6154,7 @@ IonBuilder::jsop_defvar(uint32 index)
attrs |= JSPROP_READONLY;
// Pass the ScopeChain.
JS_ASSERT(script->analysis()->usesScopeChain());
JS_ASSERT(script_->analysis()->usesScopeChain());
// Bake the name pointer into the MDefVar.
MDefVar *defvar = MDefVar::New(name, attrs, current->scopeChain());
@ -6167,12 +6169,12 @@ IonBuilder::jsop_this()
if (!info().fun())
return abort("JSOP_THIS outside of a JSFunction.");
if (script->strictModeCode) {
if (script_->strictModeCode) {
current->pushSlot(info().thisSlot());
return true;
}
types::StackTypeSet *types = oracle->thisTypeSet(script);
types::StackTypeSet *types = oracle->thisTypeSet(script_);
if (types && types->getKnownTypeTag() == JSVAL_TYPE_OBJECT) {
// This is safe, because if the entry type of |this| is an object, it
// will necessarily be an object throughout the entire function. OSR
@ -6187,7 +6189,7 @@ IonBuilder::jsop_this()
bool
IonBuilder::jsop_typeof()
{
TypeOracle::Unary unary = oracle->unaryOp(script, pc);
TypeOracle::Unary unary = oracle->unaryOp(script_, pc);
MDefinition *input = current->pop();
MTypeOf *ins = MTypeOf::New(input, unary.ival);
@ -6204,7 +6206,7 @@ bool
IonBuilder::jsop_toid()
{
// No-op if the index is an integer.
TypeOracle::Unary unary = oracle->unaryOp(script, pc);
TypeOracle::Unary unary = oracle->unaryOp(script_, pc);
if (unary.ival == MIRType_Int32)
return true;
@ -6285,11 +6287,11 @@ bool
IonBuilder::jsop_getaliasedvar(ScopeCoordinate sc)
{
types::StackTypeSet *barrier;
types::StackTypeSet *actual = oracle->aliasedVarBarrier(script, pc, &barrier);
types::StackTypeSet *actual = oracle->aliasedVarBarrier(script_, pc, &barrier);
MDefinition *obj = walkScopeChain(sc.hops);
RootedShape shape(cx, ScopeCoordinateToStaticScope(script, pc).scopeShape());
RootedShape shape(cx, ScopeCoordinateToStaticScope(script_, pc).scopeShape());
MInstruction *load;
if (shape->numFixedSlots() <= sc.slot) {
@ -6323,7 +6325,7 @@ IonBuilder::jsop_setaliasedvar(ScopeCoordinate sc)
MDefinition *rval = current->peek(-1);
MDefinition *obj = walkScopeChain(sc.hops);
RootedShape shape(cx, ScopeCoordinateToStaticScope(script, pc).scopeShape());
RootedShape shape(cx, ScopeCoordinateToStaticScope(script_, pc).scopeShape());
MInstruction *store;
if (shape->numFixedSlots() <= sc.slot) {

View File

@ -415,10 +415,10 @@ class IonBuilder : public MIRGenerator
MBasicBlock *bottom,
Vector<MDefinition *, 8, IonAllocPolicy> &retvalDefns);
public:
// A builder is inextricably tied to a particular script.
JSScript * const script;
HeapPtrScript script_;
public:
// Compilation index for this attempt.
types::RecompileInfo const recompileInfo;
@ -427,6 +427,8 @@ class IonBuilder : public MIRGenerator
void clearForBackEnd();
JSScript *script() const { return script_; }
private:
JSContext *cx;

View File

@ -314,7 +314,7 @@ js::ion::GetPropertyCache(JSContext *cx, size_t cacheIndex, HandleObject obj, Mu
RootedScript script(cx);
jsbytecode *pc;
cache.getScriptedLocation(script.address(), &pc);
cache.getScriptedLocation(&script, &pc);
// Override the return value if we are invalidated (bug 728188).
AutoDetectInvalidation adi(cx, vp.address(), ion);
@ -831,7 +831,7 @@ js::ion::GetElementCache(JSContext *cx, size_t cacheIndex, HandleObject obj, Han
}
}
JSScript *script;
RootedScript script(cx);
jsbytecode *pc;
cache.getScriptedLocation(&script, &pc);
@ -1155,7 +1155,7 @@ js::ion::GetNameCache(JSContext *cx, size_t cacheIndex, HandleObject scopeChain,
IonCacheName &cache = ion->getCache(cacheIndex).toName();
RootedPropertyName name(cx, cache.name());
JSScript *script;
RootedScript script(cx);
jsbytecode *pc;
cache.getScriptedLocation(&script, &pc);

View File

@ -233,8 +233,8 @@ class IonCache
this->pc = pc;
}
void getScriptedLocation(JSScript **pscript, jsbytecode **ppc) {
*pscript = script;
void getScriptedLocation(MutableHandleScript pscript, jsbytecode **ppc) {
pscript.set(script);
*ppc = pc;
}
};

View File

@ -657,7 +657,7 @@ ion::AutoTempAllocatorRooter::trace(JSTracer *trc)
}
void
ion::GetPcScript(JSContext *cx, JSScript **scriptRes, jsbytecode **pcRes)
ion::GetPcScript(JSContext *cx, MutableHandleScript scriptRes, jsbytecode **pcRes)
{
JS_ASSERT(cx->fp()->beginsIonActivation());
IonSpew(IonSpew_Snapshots, "Recover PC & Script from the last frame.");
@ -668,7 +668,7 @@ ion::GetPcScript(JSContext *cx, JSScript **scriptRes, jsbytecode **pcRes)
InlineFrameIterator ifi(&it);
// Set the result.
*scriptRes = ifi.script();
scriptRes.set(ifi.script());
if (pcRes)
*pcRes = ifi.pc();
}

View File

@ -262,7 +262,7 @@ GetTopIonJSScript(JSContext *cx,
void **returnAddrOut = NULL);
void
GetPcScript(JSContext *cx, JSScript **scriptRes, jsbytecode **pcRes);
GetPcScript(JSContext *cx, MutableHandleScript scriptRes, jsbytecode **pcRes);
// Given a slot index, returns the offset, in bytes, of that slot from an
// IonJSFrameLayout. Slot distances are uniform across architectures, however,

View File

@ -99,7 +99,7 @@ types::StackTypeSet *
IonBuilder::getInlineReturnTypeSet()
{
types::StackTypeSet *barrier;
types::StackTypeSet *returnTypes = oracle->returnTypeSet(script, pc, &barrier);
types::StackTypeSet *returnTypes = oracle->returnTypeSet(script_, pc, &barrier);
JS_ASSERT(returnTypes);
return returnTypes;
@ -115,7 +115,7 @@ IonBuilder::getInlineReturnType()
types::StackTypeSet *
IonBuilder::getInlineArgTypeSet(uint32 argc, uint32 arg)
{
types::StackTypeSet *argTypes = oracle->getCallArg(script, argc, arg, pc);
types::StackTypeSet *argTypes = oracle->getCallArg(script_, argc, arg, pc);
JS_ASSERT(argTypes);
return argTypes;
}
@ -245,6 +245,7 @@ IonBuilder::inlineArrayPopShift(MArrayPopShift::Mode mode, uint32 argc, bool con
types::StackTypeSet *thisTypes = getInlineArgTypeSet(argc, 0);
if (thisTypes->hasObjectFlags(cx, unhandledFlags))
return InliningStatus_NotInlined;
RootedScript script(cx, script_);
if (types::ArrayPrototypeHasIndexedProperty(cx, script))
return InliningStatus_NotInlined;
@ -282,6 +283,7 @@ IonBuilder::inlineArrayPush(uint32 argc, bool constructing)
types::StackTypeSet *thisTypes = getInlineArgTypeSet(argc, 0);
if (thisTypes->hasObjectFlags(cx, types::OBJECT_FLAG_NON_DENSE_ARRAY))
return InliningStatus_NotInlined;
RootedScript script(cx, script_);
if (types::ArrayPrototypeHasIndexedProperty(cx, script))
return InliningStatus_NotInlined;

View File

@ -21,7 +21,7 @@ bool
TypeInferenceOracle::init(JSContext *cx, JSScript *script)
{
this->cx = cx;
this->script = script;
this->script_.init(script);
return script->ensureRanInference(cx);
}
@ -66,7 +66,7 @@ TypeInferenceOracle::getMIRType(HeapTypeSet *types)
TypeOracle::UnaryTypes
TypeInferenceOracle::unaryTypes(JSScript *script, jsbytecode *pc)
{
JS_ASSERT(script == this->script);
JS_ASSERT(script == this->script_);
UnaryTypes res;
res.inTypes = script->analysis()->poppedTypes(pc, 0);
@ -77,7 +77,7 @@ TypeInferenceOracle::unaryTypes(JSScript *script, jsbytecode *pc)
TypeOracle::BinaryTypes
TypeInferenceOracle::binaryTypes(JSScript *script, jsbytecode *pc)
{
JS_ASSERT(script == this->script);
JS_ASSERT(script == this->script_);
JSOp op = (JSOp)*pc;
@ -121,7 +121,7 @@ TypeInferenceOracle::incslot(JSScript *script, jsbytecode *pc)
TypeOracle::Unary
TypeInferenceOracle::unaryOp(JSScript *script, jsbytecode *pc)
{
JS_ASSERT(script == this->script);
JS_ASSERT(script == this->script_);
Unary res;
res.ival = getMIRType(script->analysis()->poppedTypes(pc, 0));
@ -132,7 +132,7 @@ TypeInferenceOracle::unaryOp(JSScript *script, jsbytecode *pc)
TypeOracle::Binary
TypeInferenceOracle::binaryOp(JSScript *script, jsbytecode *pc)
{
JS_ASSERT(script == this->script);
JS_ASSERT(script == this->script_);
JSOp op = (JSOp)*pc;
@ -152,7 +152,7 @@ TypeInferenceOracle::binaryOp(JSScript *script, jsbytecode *pc)
StackTypeSet *
TypeInferenceOracle::thisTypeSet(JSScript *script)
{
JS_ASSERT(script == this->script);
JS_ASSERT(script == this->script_);
return TypeScript::ThisTypes(script);
}
@ -160,18 +160,18 @@ bool
TypeInferenceOracle::getOsrTypes(jsbytecode *osrPc, Vector<MIRType> &slotTypes)
{
JS_ASSERT(JSOp(*osrPc) == JSOP_LOOPENTRY);
JS_ASSERT(script->code < osrPc);
JS_ASSERT(osrPc < script->code + script->length);
JS_ASSERT(script_->code < osrPc);
JS_ASSERT(osrPc < script_->code + script_->length);
Vector<types::StackTypeSet *> slotTypeSets(cx);
if (!slotTypeSets.resize(TotalSlots(script)))
if (!slotTypeSets.resize(TotalSlots(script_)))
return false;
for (uint32_t slot = ThisSlot(); slot < TotalSlots(script); slot++)
slotTypeSets[slot] = TypeScript::SlotTypes(script, slot);
for (uint32_t slot = ThisSlot(); slot < TotalSlots(script_); slot++)
slotTypeSets[slot] = TypeScript::SlotTypes(script_, slot);
jsbytecode *pc = script->code;
ScriptAnalysis *analysis = script->analysis();
jsbytecode *pc = script_->code;
ScriptAnalysis *analysis = script_->analysis();
// To determine the slot types at the OSR pc, we have to do a forward walk
// over the bytecode to reconstruct the types.
@ -182,7 +182,7 @@ TypeInferenceOracle::getOsrTypes(jsbytecode *osrPc, Vector<MIRType> &slotTypes)
// Update variable types for all new values at this bytecode.
if (const SlotValue *newv = analysis->newValues(pc)) {
while (newv->slot) {
if (newv->slot < TotalSlots(script))
if (newv->slot < TotalSlots(script_))
slotTypeSets[newv->slot] = analysis->getValueTypes(newv->value);
newv++;
}
@ -190,7 +190,7 @@ TypeInferenceOracle::getOsrTypes(jsbytecode *osrPc, Vector<MIRType> &slotTypes)
}
if (BytecodeUpdatesSlot(JSOp(*pc))) {
uint32_t slot = GetBytecodeSlot(script, pc);
uint32_t slot = GetBytecodeSlot(script_, pc);
if (analysis->trackSlot(slot))
slotTypeSets[slot] = analysis->pushedTypes(pc, 0);
}
@ -213,15 +213,15 @@ TypeInferenceOracle::getOsrTypes(jsbytecode *osrPc, Vector<MIRType> &slotTypes)
uint32_t stackDepth = analysis->getCode(osrPc).stackDepth;
#endif
if (script->function()) {
JS_ASSERT(slotTypes.length() == TotalSlots(script) + stackDepth);
if (script_->function()) {
JS_ASSERT(slotTypes.length() == TotalSlots(script_) + stackDepth);
for (size_t i = ThisSlot(); i < TotalSlots(script); i++)
for (size_t i = ThisSlot(); i < TotalSlots(script_); i++)
slotTypes[i] = getMIRType(slotTypeSets[i]);
} else {
JS_ASSERT(slotTypes.length() == TotalSlots(script) + stackDepth - 1);
JS_ASSERT(slotTypes.length() == TotalSlots(script_) + stackDepth - 1);
for (size_t i = ArgSlot(0); i < TotalSlots(script); i++)
for (size_t i = ArgSlot(0); i < TotalSlots(script_); i++)
slotTypes[i - 1] = getMIRType(slotTypeSets[i]);
}
@ -231,7 +231,7 @@ TypeInferenceOracle::getOsrTypes(jsbytecode *osrPc, Vector<MIRType> &slotTypes)
StackTypeSet *
TypeInferenceOracle::parameterTypeSet(JSScript *script, size_t index)
{
JS_ASSERT(script == this->script);
JS_ASSERT(script == this->script_);
return TypeScript::ArgTypes(script, index);
}
@ -468,13 +468,14 @@ TypeInferenceOracle::elementWrite(JSScript *script, jsbytecode *pc)
bool
TypeInferenceOracle::arrayPrototypeHasIndexedProperty()
{
RootedScript script(cx, script_);
return ArrayPrototypeHasIndexedProperty(cx, script);
}
bool
TypeInferenceOracle::canInlineCalls()
{
return script->analysis()->hasFunctionCalls();
return script_->analysis()->hasFunctionCalls();
}
bool
@ -502,10 +503,10 @@ TypeInferenceOracle::elementWriteNeedsBarrier(JSScript *script, jsbytecode *pc)
StackTypeSet *
TypeInferenceOracle::getCallTarget(JSScript *caller, uint32 argc, jsbytecode *pc)
{
JS_ASSERT(caller == this->script);
JS_ASSERT(caller == this->script_);
JS_ASSERT(js_CodeSpec[*pc].format & JOF_INVOKE && JSOp(*pc) != JSOP_EVAL);
ScriptAnalysis *analysis = script->analysis();
ScriptAnalysis *analysis = script_->analysis();
return analysis->poppedTypes(pc, argc + 1);
}

View File

@ -213,13 +213,13 @@ class DummyOracle : public TypeOracle
class TypeInferenceOracle : public TypeOracle
{
JSContext *cx;
JSScript *script;
HeapPtrScript script_;
MIRType getMIRType(types::StackTypeSet *types);
MIRType getMIRType(types::HeapTypeSet *types);
public:
TypeInferenceOracle() : cx(NULL), script(NULL) {}
TypeInferenceOracle() : cx(NULL), script_(NULL) {}
bool init(JSContext *cx, JSScript *script);

View File

@ -8,6 +8,8 @@
#include "ion/IonMacroAssembler.h"
#include "gc/Marking.h"
#include "jsscriptinlines.h"
using namespace js;
using namespace js::ion;

View File

@ -7,6 +7,8 @@
#include "MoveEmitter-x86-shared.h"
#include "jsscriptinlines.h"
using namespace js;
using namespace js::ion;

View File

@ -8,6 +8,8 @@
#include "Assembler-x64.h"
#include "gc/Marking.h"
#include "jsscriptinlines.h"
using namespace js;
using namespace js::ion;

View File

@ -9,6 +9,8 @@
#include "ion/MoveEmitter.h"
#include "ion/IonFrames.h"
#include "jsscriptinlines.h"
using namespace js;
using namespace js::ion;

View File

@ -14,6 +14,8 @@
#include "ion/VMFunctions.h"
#include "ion/IonSpewer.h"
#include "jsscriptinlines.h"
using namespace js;
using namespace js::ion;

View File

@ -55,7 +55,7 @@ ScriptAnalysis::addJump(JSContext *cx, unsigned offset,
unsigned *currentOffset, unsigned *forwardJump, unsigned *forwardLoop,
unsigned stackDepth)
{
JS_ASSERT(offset < script->length);
JS_ASSERT(offset < script_->length);
Bytecode *&code = codeArray[offset];
if (!code) {
@ -111,9 +111,9 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx)
JS_ASSERT(!ranBytecode());
LifoAlloc &alloc = cx->analysisLifoAlloc();
numSlots = TotalSlots(script);
numSlots = TotalSlots(script_);
unsigned length = script->length;
unsigned length = script_->length;
codeArray = alloc.newArray<Bytecode*>(length);
escapedSlots = alloc.newArray<bool>(numSlots);
@ -138,14 +138,14 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx)
PodZero(escapedSlots, numSlots);
bool allVarsAliased = script->compartment()->debugMode();
bool allArgsAliased = allVarsAliased || script->argumentsHasVarBinding();
bool allVarsAliased = script_->compartment()->debugMode();
bool allArgsAliased = allVarsAliased || script_->argumentsHasVarBinding();
for (BindingIter bi(script->bindings); bi; bi++) {
for (BindingIter bi(script_->bindings); bi; bi++) {
if (bi->kind() == ARGUMENT)
escapedSlots[ArgSlot(bi.frameIndex())] = allArgsAliased || bi->aliased();
else
escapedSlots[LocalSlot(script, bi.frameIndex())] = allVarsAliased || bi->aliased();
escapedSlots[LocalSlot(script_, bi.frameIndex())] = allVarsAliased || bi->aliased();
}
/*
@ -155,12 +155,12 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx)
if (cx->compartment->debugMode())
usesReturnValue_ = true;
bool heavyweight = script->function() && script->function()->isHeavyweight();
bool heavyweight = script_->function() && script_->function()->isHeavyweight();
isJaegerCompileable = true;
isInlineable = true;
if (heavyweight || script->argumentsHasVarBinding() || cx->compartment->debugMode())
if (heavyweight || script_->argumentsHasVarBinding() || cx->compartment->debugMode())
isInlineable = false;
modifiesArguments_ = false;
@ -197,7 +197,7 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx)
/* Number of JOF_TYPESET opcodes we have encountered. */
unsigned nTypeSets = 0;
types::TypeSet *typeArray = script->types->typeArray();
types::TypeSet *typeArray = script_->types->typeArray();
unsigned offset, nextOffset = 0;
while (nextOffset < length) {
@ -212,7 +212,7 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx)
forwardCatch = 0;
Bytecode *code = maybeCode(offset);
jsbytecode *pc = script->code + offset;
jsbytecode *pc = script_->code + offset;
JSOp op = (JSOp)*pc;
JS_ASSERT(op < JSOP_LIMIT);
@ -251,7 +251,7 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx)
if (forwardCatch)
code->inTryBlock = true;
if (script->hasBreakpointsAt(pc)) {
if (script_->hasBreakpointsAt(pc)) {
code->safePoint = true;
isInlineable = canTrackVars = false;
}
@ -266,8 +266,8 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx)
* pick up the stack depths as we go through the decomposed version.
*/
if (!(js_CodeSpec[op].format & JOF_DECOMPOSE)) {
unsigned nuses = GetUseCount(script, offset);
unsigned ndefs = GetDefCount(script, offset);
unsigned nuses = GetUseCount(script_, offset);
unsigned ndefs = GetDefCount(script_, offset);
JS_ASSERT(stackDepth >= nuses);
stackDepth -= nuses;
@ -282,7 +282,7 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx)
* used for the observed types of all ops after the overflow.
*/
if ((js_CodeSpec[op].format & JOF_TYPESET) && cx->typeInferenceEnabled()) {
if (nTypeSets < script->nTypeSets) {
if (nTypeSets < script_->nTypeSets) {
code->observedTypes = typeArray[nTypeSets++].toStackTypeSet();
} else {
JS_ASSERT(nTypeSets == UINT16_MAX);
@ -413,10 +413,10 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx)
* no more code will execute, and it does not matter what is defined.
*/
isInlineable = false;
JSTryNote *tn = script->trynotes()->vector;
JSTryNote *tnlimit = tn + script->trynotes()->length;
JSTryNote *tn = script_->trynotes()->vector;
JSTryNote *tnlimit = tn + script_->trynotes()->length;
for (; tn < tnlimit; tn++) {
unsigned startOffset = script->mainOffset + tn->start;
unsigned startOffset = script_->mainOffset + tn->start;
if (startOffset == offset + 1) {
unsigned catchOffset = startOffset + tn->length;
@ -444,7 +444,7 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx)
jsbytecode *next = pc + JSOP_GETLOCAL_LENGTH;
if (JSOp(*next) != JSOP_POP || jumpTarget(next)) {
uint32_t local = GET_SLOTNO(pc);
if (local >= script->nfixed) {
if (local >= script_->nfixed) {
localsAliasStack_ = true;
break;
}
@ -459,7 +459,7 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx)
case JSOP_LOCALDEC:
case JSOP_SETLOCAL: {
uint32_t local = GET_SLOTNO(pc);
if (local >= script->nfixed) {
if (local >= script_->nfixed) {
localsAliasStack_ = true;
break;
}
@ -614,7 +614,7 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx)
/* Handle any fallthrough from this opcode. */
if (!BytecodeNoFallThrough(op)) {
JS_ASSERT(successorOffset < script->length);
JS_ASSERT(successorOffset < script_->length);
Bytecode *&nextcode = codeArray[successorOffset];
@ -649,7 +649,7 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx)
* entering the script. This allows the functionPrologue to ensure that
* arguments are always created eagerly which simplifies interp logic.
*/
if (!script->analyzedArgsUsage())
if (!script_->analyzedArgsUsage())
analyzeSSA(cx);
/*
@ -662,7 +662,7 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx)
mjit::JITScript *jit = NULL;
for (int constructing = 0; constructing <= 1 && !jit; constructing++) {
for (int barriers = 0; barriers <= 1 && !jit; barriers++)
jit = script->getJIT((bool) constructing, (bool) barriers);
jit = script_->getJIT((bool) constructing, (bool) barriers);
}
if (jit) {
mjit::CrossChunkEdge *edges = jit->edges();
@ -709,8 +709,8 @@ ScriptAnalysis::analyzeLifetimes(JSContext *cx)
LoopAnalysis *loop = NULL;
uint32_t offset = script->length - 1;
while (offset < script->length) {
uint32_t offset = script_->length - 1;
while (offset < script_->length) {
Bytecode *code = maybeCode(offset);
if (!code) {
offset--;
@ -720,7 +720,7 @@ ScriptAnalysis::analyzeLifetimes(JSContext *cx)
if (loop && code->safePoint)
loop->hasSafePoints = true;
jsbytecode *pc = script->code + offset;
jsbytecode *pc = script_->code + offset;
JSOp op = (JSOp) *pc;
@ -748,10 +748,10 @@ ScriptAnalysis::analyzeLifetimes(JSContext *cx)
if (code->exceptionEntry) {
DebugOnly<bool> found = false;
JSTryNote *tn = script->trynotes()->vector;
JSTryNote *tnlimit = tn + script->trynotes()->length;
JSTryNote *tn = script_->trynotes()->vector;
JSTryNote *tnlimit = tn + script_->trynotes()->length;
for (; tn < tnlimit; tn++) {
unsigned startOffset = script->mainOffset + tn->start;
unsigned startOffset = script_->mainOffset + tn->start;
if (startOffset + tn->length == offset) {
/*
* Extend all live variables at exception entry to the start of
@ -775,7 +775,7 @@ ScriptAnalysis::analyzeLifetimes(JSContext *cx)
case JSOP_GETLOCAL:
case JSOP_CALLLOCAL:
case JSOP_THIS: {
uint32_t slot = GetBytecodeSlot(script, pc);
uint32_t slot = GetBytecodeSlot(script_, pc);
if (!slotEscapes(slot))
addVariable(cx, lifetimes[slot], offset, saved, savedCount);
break;
@ -783,7 +783,7 @@ ScriptAnalysis::analyzeLifetimes(JSContext *cx)
case JSOP_SETARG:
case JSOP_SETLOCAL: {
uint32_t slot = GetBytecodeSlot(script, pc);
uint32_t slot = GetBytecodeSlot(script_, pc);
if (!slotEscapes(slot))
killVariable(cx, lifetimes[slot], offset, saved, savedCount);
break;
@ -797,7 +797,7 @@ ScriptAnalysis::analyzeLifetimes(JSContext *cx)
case JSOP_DECLOCAL:
case JSOP_LOCALINC:
case JSOP_LOCALDEC: {
uint32_t slot = GetBytecodeSlot(script, pc);
uint32_t slot = GetBytecodeSlot(script_, pc);
if (!slotEscapes(slot)) {
killVariable(cx, lifetimes[slot], offset, saved, savedCount);
addVariable(cx, lifetimes[slot], offset, saved, savedCount);
@ -855,7 +855,7 @@ ScriptAnalysis::analyzeLifetimes(JSContext *cx)
* their target offset --- the variables live before the jump are
* the union of those live at the fallthrough and at the target.
*/
uint32_t targetOffset = FollowBranch(cx, script, offset);
uint32_t targetOffset = FollowBranch(cx, script_, offset);
/*
* Watch for 'continue' statements in the loop body, which are
@ -868,7 +868,7 @@ ScriptAnalysis::analyzeLifetimes(JSContext *cx)
/* This is a loop back edge, no lifetime to pull in yet. */
#ifdef DEBUG
JSOp nop = JSOp(script->code[targetOffset]);
JSOp nop = JSOp(script_->code[targetOffset]);
JS_ASSERT(nop == JSOP_LOOPHEAD);
#endif
@ -911,7 +911,7 @@ ScriptAnalysis::analyzeLifetimes(JSContext *cx)
entry--;
} while (!maybeCode(entry));
jsbytecode *entrypc = script->code + entry;
jsbytecode *entrypc = script_->code + entry;
if (JSOp(*entrypc) == JSOP_GOTO || JSOp(*entrypc) == JSOP_FILTER)
loop->entry = entry + GET_JUMP_OFFSET(entrypc);
@ -921,8 +921,8 @@ ScriptAnalysis::analyzeLifetimes(JSContext *cx)
/* Do-while loop at the start of the script. */
loop->entry = targetOffset;
}
JS_ASSERT(script->code[loop->entry] == JSOP_LOOPHEAD ||
script->code[loop->entry] == JSOP_LOOPENTRY);
JS_ASSERT(script_->code[loop->entry] == JSOP_LOOPHEAD ||
script_->code[loop->entry] == JSOP_LOOPENTRY);
} else {
for (unsigned i = 0; i < savedCount; i++) {
LifetimeVariable &var = *saved[i];
@ -1186,7 +1186,7 @@ ScriptAnalysis::clearAllocations()
* that compilation has finished. Register allocations are only used for
* a single compilation.
*/
for (unsigned i = 0; i < script->length; i++) {
for (unsigned i = 0; i < script_->length; i++) {
Bytecode *code = maybeCode(i);
if (code)
code->allocation = NULL;
@ -1209,7 +1209,7 @@ ScriptAnalysis::analyzeSSA(JSContext *cx)
}
LifoAlloc &alloc = cx->analysisLifoAlloc();
unsigned maxDepth = script->nslots - script->nfixed;
unsigned maxDepth = script_->nslots - script_->nfixed;
/*
* Current value of each variable and stack value. Empty for missing or
@ -1251,8 +1251,8 @@ ScriptAnalysis::analyzeSSA(JSContext *cx)
Vector<uint32_t> exceptionTargets(cx);
uint32_t offset = 0;
while (offset < script->length) {
jsbytecode *pc = script->code + offset;
while (offset < script_->length) {
jsbytecode *pc = script_->code + offset;
JSOp op = (JSOp)*pc;
uint32_t successorOffset = offset + GetBytecodeLength(pc);
@ -1384,8 +1384,8 @@ ScriptAnalysis::analyzeSSA(JSContext *cx)
continue;
}
unsigned nuses = GetUseCount(script, offset);
unsigned ndefs = GetDefCount(script, offset);
unsigned nuses = GetUseCount(script_, offset);
unsigned ndefs = GetDefCount(script_, offset);
JS_ASSERT(stackDepth >= nuses);
unsigned xuses = ExtendedUse(pc) ? nuses + 1 : nuses;
@ -1406,7 +1406,7 @@ ScriptAnalysis::analyzeSSA(JSContext *cx)
* For SETLOCAL, INCLOCAL, etc. opcodes, add an extra popped
* value holding the value of the local before the op.
*/
uint32_t slot = GetBytecodeSlot(script, pc);
uint32_t slot = GetBytecodeSlot(script_, pc);
if (trackSlot(slot))
code->poppedValues[nuses] = values[slot].v;
else
@ -1452,7 +1452,7 @@ ScriptAnalysis::analyzeSSA(JSContext *cx)
stackDepth += ndefs;
if (BytecodeUpdatesSlot(op)) {
uint32_t slot = GetBytecodeSlot(script, pc);
uint32_t slot = GetBytecodeSlot(script_, pc);
if (trackSlot(slot)) {
mergeBranchTarget(cx, values[slot], slot, branchTargets, offset);
mergeExceptionTarget(cx, values[slot].v, slot, exceptionTargets);
@ -1463,7 +1463,7 @@ ScriptAnalysis::analyzeSSA(JSContext *cx)
switch (op) {
case JSOP_GETARG:
case JSOP_GETLOCAL: {
uint32_t slot = GetBytecodeSlot(script, pc);
uint32_t slot = GetBytecodeSlot(script_, pc);
if (trackSlot(slot)) {
/*
* Propagate the current value of the local to the pushed value,
@ -1555,10 +1555,10 @@ ScriptAnalysis::analyzeSSA(JSContext *cx)
}
case JSOP_TRY: {
JSTryNote *tn = script->trynotes()->vector;
JSTryNote *tnlimit = tn + script->trynotes()->length;
JSTryNote *tn = script_->trynotes()->vector;
JSTryNote *tnlimit = tn + script_->trynotes()->length;
for (; tn < tnlimit; tn++) {
unsigned startOffset = script->mainOffset + tn->start;
unsigned startOffset = script_->mainOffset + tn->start;
if (startOffset == offset + 1) {
unsigned catchOffset = startOffset + tn->length;
@ -1582,7 +1582,7 @@ ScriptAnalysis::analyzeSSA(JSContext *cx)
}
if (IsJumpOpcode(op)) {
unsigned targetOffset = FollowBranch(cx, script, offset);
unsigned targetOffset = FollowBranch(cx, script_, offset);
checkBranchTarget(cx, targetOffset, branchTargets, values, stackDepth);
/*
@ -1602,8 +1602,8 @@ ScriptAnalysis::analyzeSSA(JSContext *cx)
* Now that we have full SSA information for the script, analyze whether
* we can avoid creating the arguments object.
*/
if (!script->analyzedArgsUsage())
script->setNeedsArgsObj(needsArgsObj(cx));
if (!script_->analyzedArgsUsage())
script_->setNeedsArgsObj(needsArgsObj(cx));
}
/* Get a phi node's capacity for a given length. */
@ -1755,7 +1755,7 @@ ScriptAnalysis::checkBranchTarget(JSContext *cx, uint32_t targetOffset,
* pushing values in each opcode.
*/
for (unsigned i = 0; i < targetDepth; i++) {
uint32_t slot = StackSlot(script, i);
uint32_t slot = StackSlot(script_, i);
checkPendingValue(cx, values[slot].v, slot, pending);
}
}
@ -1922,7 +1922,7 @@ ScriptAnalysis::needsArgsObj(JSContext *cx, SeenVector &seen, SSAUseChain *use)
if (!use->popped)
return needsArgsObj(cx, seen, SSAValue::PhiValue(use->offset, use->u.phi));
jsbytecode *pc = script->code + use->offset;
jsbytecode *pc = script_->code + use->offset;
JSOp op = JSOp(*pc);
if (op == JSOP_POP || op == JSOP_POPN)
@ -1947,7 +1947,7 @@ ScriptAnalysis::needsArgsObj(JSContext *cx, SeenVector &seen, SSAUseChain *use)
/* Allow assignments to non-closed locals (but not arguments). */
if (op == JSOP_SETLOCAL) {
uint32_t slot = GetBytecodeSlot(script, pc);
uint32_t slot = GetBytecodeSlot(script_, pc);
if (!trackSlot(slot))
return true;
return needsArgsObj(cx, seen, SSAValue::PushedValue(use->offset, 0)) ||
@ -1963,20 +1963,20 @@ ScriptAnalysis::needsArgsObj(JSContext *cx, SeenVector &seen, SSAUseChain *use)
bool
ScriptAnalysis::needsArgsObj(JSContext *cx)
{
JS_ASSERT(script->argumentsHasVarBinding());
JS_ASSERT(script_->argumentsHasVarBinding());
/*
* Since let variables and dynamic name access are not tracked, we cannot
* soundly perform this analysis in their presence. Generators can be
* suspended when the speculation fails, so disallow it also.
*/
if (script->bindingsAccessedDynamically || script->funHasAnyAliasedFormal ||
localsAliasStack() || cx->compartment->debugMode() || script->isGenerator)
if (script_->bindingsAccessedDynamically || script_->funHasAnyAliasedFormal ||
localsAliasStack() || cx->compartment->debugMode() || script_->isGenerator)
{
return true;
}
unsigned pcOff = script->argumentsBytecode() - script->code;
unsigned pcOff = script_->argumentsBytecode() - script_->code;
SeenVector seen(cx);
return needsArgsObj(cx, seen, SSAValue::PushedValue(pcOff, 0));
@ -2073,14 +2073,14 @@ ScriptAnalysis::printSSA(JSContext *cx)
printf("\n");
for (unsigned offset = 0; offset < script->length; offset++) {
for (unsigned offset = 0; offset < script_->length; offset++) {
Bytecode *code = maybeCode(offset);
if (!code)
continue;
jsbytecode *pc = script->code + offset;
jsbytecode *pc = script_->code + offset;
PrintBytecode(cx, script, pc);
PrintBytecode(cx, script_, pc);
SlotValue *newv = code->newValues;
if (newv) {
@ -2102,7 +2102,7 @@ ScriptAnalysis::printSSA(JSContext *cx)
}
}
unsigned nuses = GetUseCount(script, offset);
unsigned nuses = GetUseCount(script_, offset);
unsigned xuses = ExtendedUse(pc) ? nuses + 1 : nuses;
for (unsigned i = 0; i < xuses; i++) {
@ -2147,7 +2147,7 @@ SSAValue::print() const
void
ScriptAnalysis::assertMatchingDebugMode()
{
JS_ASSERT(!!script->compartment()->debugMode() == !!originalDebugMode_);
JS_ASSERT(!!script_->compartment()->debugMode() == !!originalDebugMode_);
}
#endif /* DEBUG */

View File

@ -839,7 +839,7 @@ class ScriptAnalysis
{
friend class Bytecode;
JSScript *script;
JSScript *script_;
Bytecode **codeArray;
@ -885,9 +885,9 @@ class ScriptAnalysis
ScriptAnalysis(JSScript *script) {
PodZero(this);
this->script = script;
this->script_ = script;
#ifdef DEBUG
this->originalDebugMode_ = script->compartment()->debugMode();
this->originalDebugMode_ = script_->compartment()->debugMode();
#endif
}
@ -907,7 +907,7 @@ class ScriptAnalysis
bool OOM() const { return outOfMemory; }
bool failed() const { return hadFailure; }
bool inlineable() const { return isInlineable; }
bool inlineable(uint32_t argc) const { return isInlineable && argc == script->function()->nargs; }
bool inlineable(uint32_t argc) const { return isInlineable && argc == script_->function()->nargs; }
bool jaegerCompileable() { return isJaegerCompileable; }
/* Number of property read opcodes in the script. */
@ -933,30 +933,30 @@ class ScriptAnalysis
/*
* True if there are any LOCAL opcodes aliasing values on the stack (above
* script->nfixed).
* script_->nfixed).
*/
bool localsAliasStack() { return localsAliasStack_; }
/* Accessors for bytecode information. */
Bytecode& getCode(uint32_t offset) {
JS_ASSERT(offset < script->length);
JS_ASSERT(offset < script_->length);
JS_ASSERT(codeArray[offset]);
return *codeArray[offset];
}
Bytecode& getCode(const jsbytecode *pc) { return getCode(pc - script->code); }
Bytecode& getCode(const jsbytecode *pc) { return getCode(pc - script_->code); }
Bytecode* maybeCode(uint32_t offset) {
JS_ASSERT(offset < script->length);
JS_ASSERT(offset < script_->length);
return codeArray[offset];
}
Bytecode* maybeCode(const jsbytecode *pc) { return maybeCode(pc - script->code); }
Bytecode* maybeCode(const jsbytecode *pc) { return maybeCode(pc - script_->code); }
bool jumpTarget(uint32_t offset) {
JS_ASSERT(offset < script->length);
JS_ASSERT(offset < script_->length);
return codeArray[offset] && codeArray[offset]->jumpTarget;
}
bool jumpTarget(const jsbytecode *pc) { return jumpTarget(pc - script->code); }
bool jumpTarget(const jsbytecode *pc) { return jumpTarget(pc - script_->code); }
bool popGuaranteed(jsbytecode *pc) {
jsbytecode *next = pc + GetBytecodeLength(pc);
@ -974,31 +974,31 @@ class ScriptAnalysis
}
const SSAValue &poppedValue(uint32_t offset, uint32_t which) {
JS_ASSERT(offset < script->length);
JS_ASSERT(which < GetUseCount(script, offset) +
(ExtendedUse(script->code + offset) ? 1 : 0));
JS_ASSERT(offset < script_->length);
JS_ASSERT(which < GetUseCount(script_, offset) +
(ExtendedUse(script_->code + offset) ? 1 : 0));
return getCode(offset).poppedValues[which];
}
const SSAValue &poppedValue(const jsbytecode *pc, uint32_t which) {
return poppedValue(pc - script->code, which);
return poppedValue(pc - script_->code, which);
}
const SlotValue *newValues(uint32_t offset) {
JS_ASSERT(offset < script->length);
JS_ASSERT(offset < script_->length);
return getCode(offset).newValues;
}
const SlotValue *newValues(const jsbytecode *pc) { return newValues(pc - script->code); }
const SlotValue *newValues(const jsbytecode *pc) { return newValues(pc - script_->code); }
types::StackTypeSet *pushedTypes(uint32_t offset, uint32_t which = 0) {
JS_ASSERT(offset < script->length);
JS_ASSERT(which < GetDefCount(script, offset) +
(ExtendedDef(script->code + offset) ? 1 : 0));
JS_ASSERT(offset < script_->length);
JS_ASSERT(which < GetDefCount(script_, offset) +
(ExtendedDef(script_->code + offset) ? 1 : 0));
types::StackTypeSet *array = getCode(offset).pushedTypes;
JS_ASSERT(array);
return array + which;
}
types::StackTypeSet *pushedTypes(const jsbytecode *pc, uint32_t which) {
return pushedTypes(pc - script->code, which);
return pushedTypes(pc - script_->code, which);
}
bool hasPushedTypes(const jsbytecode *pc) { return getCode(pc).pushedTypes != NULL; }
@ -1009,7 +1009,7 @@ class ScriptAnalysis
return getCode(offset).typeBarriers;
}
types::TypeBarrier *typeBarriers(JSContext *cx, const jsbytecode *pc) {
return typeBarriers(cx, pc - script->code);
return typeBarriers(cx, pc - script_->code);
}
void addTypeBarrier(JSContext *cx, const jsbytecode *pc,
types::TypeSet *target, types::Type type);
@ -1038,7 +1038,7 @@ class ScriptAnalysis
case SSAValue::VAR:
JS_ASSERT(!slotEscapes(v.varSlot()));
if (v.varInitial()) {
return types::TypeScript::SlotTypes(script, v.varSlot());
return types::TypeScript::SlotTypes(script_, v.varSlot());
} else {
/*
* Results of intermediate assignments have the same type as
@ -1082,31 +1082,31 @@ class ScriptAnalysis
if (v.kind() == SSAValue::PUSHED)
return getCode(v.pushedOffset()).pushedUses[v.pushedIndex()];
if (v.kind() == SSAValue::VAR)
return getCode(v.varOffset()).pushedUses[GetDefCount(script, v.varOffset())];
return getCode(v.varOffset()).pushedUses[GetDefCount(script_, v.varOffset())];
return v.phiNode()->uses;
}
mjit::RegisterAllocation *&getAllocation(uint32_t offset) {
JS_ASSERT(offset < script->length);
JS_ASSERT(offset < script_->length);
return getCode(offset).allocation;
}
mjit::RegisterAllocation *&getAllocation(const jsbytecode *pc) {
return getAllocation(pc - script->code);
return getAllocation(pc - script_->code);
}
LoopAnalysis *getLoop(uint32_t offset) {
JS_ASSERT(offset < script->length);
JS_ASSERT(offset < script_->length);
return getCode(offset).loop;
}
LoopAnalysis *getLoop(const jsbytecode *pc) { return getLoop(pc - script->code); }
LoopAnalysis *getLoop(const jsbytecode *pc) { return getLoop(pc - script_->code); }
/* For a JSOP_CALL* op, get the pc of the corresponding JSOP_CALL/NEW/etc. */
jsbytecode *getCallPC(jsbytecode *pc)
{
SSAUseChain *uses = useChain(SSAValue::PushedValue(pc - script->code, 0));
SSAUseChain *uses = useChain(SSAValue::PushedValue(pc - script_->code, 0));
JS_ASSERT(uses && uses->popped);
JS_ASSERT(js_CodeSpec[script->code[uses->offset]].format & JOF_INVOKE);
return script->code + uses->offset;
JS_ASSERT(js_CodeSpec[script_->code[uses->offset]].format & JOF_INVOKE);
return script_->code + uses->offset;
}
/* Accessors for local variable information. */
@ -1119,7 +1119,7 @@ class ScriptAnalysis
* containing script (which does not imply the variable is closed).
*/
bool slotEscapes(uint32_t slot) {
JS_ASSERT(script->compartment()->activeAnalysis);
JS_ASSERT(script_->compartment()->activeAnalysis);
if (slot >= numSlots)
return true;
return escapedSlots[slot];
@ -1134,7 +1134,7 @@ class ScriptAnalysis
bool trackSlot(uint32_t slot) { return !slotEscapes(slot) && canTrackVars && slot < 1000; }
const LifetimeVariable & liveness(uint32_t slot) {
JS_ASSERT(script->compartment()->activeAnalysis);
JS_ASSERT(script_->compartment()->activeAnalysis);
JS_ASSERT(!slotEscapes(slot));
return lifetimes[slot];
}

View File

@ -580,7 +580,7 @@ JSCompartment::sweep(FreeOp *fop, bool releaseTypes)
gcstats::AutoPhase ap2(rt->gcStats, gcstats::PHASE_DISCARD_TI);
for (CellIterUnderGC i(this, FINALIZE_SCRIPT); !i.done(); i.next()) {
JSScript *script = i.get<JSScript>();
RawScript script = i.get<JSScript>();
if (script->types) {
types::TypeScript::Sweep(fop, script);

File diff suppressed because it is too large Load Diff

View File

@ -540,19 +540,19 @@ class StackTypeSet : public TypeSet
/* Constraints for type inference. */
void addSubset(JSContext *cx, TypeSet *target);
void addGetProperty(JSContext *cx, JSScript *script, jsbytecode *pc,
void addGetProperty(JSContext *cx, HandleScript script, jsbytecode *pc,
StackTypeSet *target, jsid id);
void addSetProperty(JSContext *cx, JSScript *script, jsbytecode *pc,
void addSetProperty(JSContext *cx, HandleScript script, jsbytecode *pc,
StackTypeSet *target, jsid id);
void addSetElement(JSContext *cx, JSScript *script, jsbytecode *pc,
void addSetElement(JSContext *cx, HandleScript script, jsbytecode *pc,
StackTypeSet *objectTypes, StackTypeSet *valueTypes);
void addCall(JSContext *cx, TypeCallsite *site);
void addArith(JSContext *cx, JSScript *script, jsbytecode *pc,
void addArith(JSContext *cx, HandleScript script, jsbytecode *pc,
TypeSet *target, TypeSet *other = NULL);
void addTransformThis(JSContext *cx, JSScript *script, TypeSet *target);
void addPropagateThis(JSContext *cx, JSScript *script, jsbytecode *pc,
void addTransformThis(JSContext *cx, HandleScript script, TypeSet *target);
void addPropagateThis(JSContext *cx, HandleScript script, jsbytecode *pc,
Type type, StackTypeSet *types = NULL);
void addSubsetBarrier(JSContext *cx, JSScript *script, jsbytecode *pc, TypeSet *target);
void addSubsetBarrier(JSContext *cx, HandleScript script, jsbytecode *pc, TypeSet *target);
/*
* Constraints for JIT compilation.
@ -606,18 +606,17 @@ class HeapTypeSet : public TypeSet
/* Constraints for type inference. */
void addSubset(JSContext *cx, TypeSet *target);
void addGetProperty(JSContext *cx, JSScript *script, jsbytecode *pc,
void addGetProperty(JSContext *cx, HandleScript script, jsbytecode *pc,
StackTypeSet *target, jsid id);
void addCallProperty(JSContext *cx, JSScript *script, jsbytecode *pc, jsid id);
void addCallProperty(JSContext *cx, HandleScript script, jsbytecode *pc, jsid id);
void addFilterPrimitives(JSContext *cx, TypeSet *target);
void addSubsetBarrier(JSContext *cx, JSScript *script, jsbytecode *pc, TypeSet *target);
void addSubsetBarrier(JSContext *cx, HandleScript script, jsbytecode *pc, TypeSet *target);
/* Constraints for JIT compilation. */
/* Completely freeze the contents of this type set. */
void addFreeze(JSContext *cx);
/*
* Watch for a generic object state change on a type object. This currently
* includes reallocations of slot pointers for global objects, and changes
@ -1054,18 +1053,18 @@ typedef HashSet<ReadBarriered<TypeObject>, TypeObjectEntry, SystemAllocPolicy> T
/* Whether to use a new type object when calling 'new' at script/pc. */
bool
UseNewType(JSContext *cx, JSScript *script, jsbytecode *pc);
UseNewType(JSContext *cx, HandleScript script, jsbytecode *pc);
/* Whether to use a new type object for an initializer opcode at script/pc. */
bool
UseNewTypeForInitializer(JSContext *cx, JSScript *script, jsbytecode *pc, JSProtoKey key);
UseNewTypeForInitializer(JSContext *cx, HandleScript script, jsbytecode *pc, JSProtoKey key);
/*
* Whether Array.prototype, or an object on its proto chain, has an
* indexed property.
*/
bool
ArrayPrototypeHasIndexedProperty(JSContext *cx, JSScript *script);
ArrayPrototypeHasIndexedProperty(JSContext *cx, HandleScript script);
/*
* Type information about a callsite. this is separated from the bytecode
@ -1116,36 +1115,38 @@ class TypeScript
/* Array of type type sets for variables and JOF_TYPESET ops. */
TypeSet *typeArray() { return (TypeSet *) (uintptr_t(this) + sizeof(TypeScript)); }
static inline unsigned NumTypeSets(JSScript *script);
static inline unsigned NumTypeSets(RawScript script);
static inline HeapTypeSet *ReturnTypes(JSScript *script);
static inline StackTypeSet *ThisTypes(JSScript *script);
static inline StackTypeSet *ArgTypes(JSScript *script, unsigned i);
static inline StackTypeSet *LocalTypes(JSScript *script, unsigned i);
static inline HeapTypeSet *ReturnTypes(RawScript script);
static inline StackTypeSet *ThisTypes(RawScript script);
static inline StackTypeSet *ArgTypes(RawScript script, unsigned i);
static inline StackTypeSet *LocalTypes(RawScript script, unsigned i);
/* Follows slot layout in jsanalyze.h, can get this/arg/local type sets. */
static inline StackTypeSet *SlotTypes(JSScript *script, unsigned slot);
static inline StackTypeSet *SlotTypes(RawScript script, unsigned slot);
#ifdef DEBUG
/* Check that correct types were inferred for the values pushed by this bytecode. */
static void CheckBytecode(JSContext *cx, JSScript *script, jsbytecode *pc, const js::Value *sp);
static void CheckBytecode(JSContext *cx, HandleScript script, jsbytecode *pc,
const js::Value *sp);
#endif
/* Get the default 'new' object for a given standard class, per the script's global. */
static inline TypeObject *StandardType(JSContext *cx, JSScript *script, JSProtoKey kind);
static inline TypeObject *StandardType(JSContext *cx, HandleScript script, JSProtoKey kind);
/* Get a type object for an allocation site in this script. */
static inline TypeObject *InitObject(JSContext *cx, JSScript *script, jsbytecode *pc, JSProtoKey kind);
static inline TypeObject *InitObject(JSContext *cx, HandleScript script, jsbytecode *pc,
JSProtoKey kind);
/*
* Monitor a bytecode pushing a value which is not accounted for by the
* inference type constraints, such as integer overflow.
*/
static inline void MonitorOverflow(JSContext *cx, JSScript *script, jsbytecode *pc);
static inline void MonitorString(JSContext *cx, JSScript *script, jsbytecode *pc);
static inline void MonitorUnknown(JSContext *cx, JSScript *script, jsbytecode *pc);
static inline void MonitorOverflow(JSContext *cx, HandleScript script, jsbytecode *pc);
static inline void MonitorString(JSContext *cx, HandleScript script, jsbytecode *pc);
static inline void MonitorUnknown(JSContext *cx, HandleScript script, jsbytecode *pc);
static inline void GetPcScript(JSContext *cx, JSScript **script, jsbytecode **pc);
static inline void GetPcScript(JSContext *cx, MutableHandleScript script, jsbytecode **pc);
static inline void MonitorOverflow(JSContext *cx);
static inline void MonitorString(JSContext *cx);
static inline void MonitorUnknown(JSContext *cx);
@ -1157,7 +1158,7 @@ class TypeScript
* always monitor JOF_TYPESET opcodes in the interpreter and stub calls,
* and only look at barriers when generating JIT code for the script.
*/
static inline void Monitor(JSContext *cx, JSScript *script, jsbytecode *pc,
static inline void Monitor(JSContext *cx, HandleScript script, jsbytecode *pc,
const js::Value &val);
static inline void Monitor(JSContext *cx, const js::Value &rval);
@ -1165,17 +1166,19 @@ class TypeScript
static inline void MonitorAssign(JSContext *cx, HandleObject obj, jsid id);
/* Add a type for a variable in a script. */
static inline void SetThis(JSContext *cx, JSScript *script, Type type);
static inline void SetThis(JSContext *cx, JSScript *script, const js::Value &value);
static inline void SetLocal(JSContext *cx, JSScript *script, unsigned local, Type type);
static inline void SetLocal(JSContext *cx, JSScript *script, unsigned local, const js::Value &value);
static inline void SetArgument(JSContext *cx, JSScript *script, unsigned arg, Type type);
static inline void SetArgument(JSContext *cx, JSScript *script, unsigned arg, const js::Value &value);
static inline void SetThis(JSContext *cx, HandleScript script, Type type);
static inline void SetThis(JSContext *cx, HandleScript script, const js::Value &value);
static inline void SetLocal(JSContext *cx, HandleScript script, unsigned local, Type type);
static inline void SetLocal(JSContext *cx, HandleScript script, unsigned local,
const js::Value &value);
static inline void SetArgument(JSContext *cx, HandleScript script, unsigned arg, Type type);
static inline void SetArgument(JSContext *cx, HandleScript script, unsigned arg,
const js::Value &value);
static void AddFreezeConstraints(JSContext *cx, JSScript *script);
static void Purge(JSContext *cx, JSScript *script);
static void AddFreezeConstraints(JSContext *cx, HandleScript script);
static void Purge(JSContext *cx, HandleScript script);
static void Sweep(FreeOp *fop, JSScript *script);
static void Sweep(FreeOp *fop, RawScript script);
void destroy();
};
@ -1348,10 +1351,10 @@ struct TypeCompartment
/* Mark a script as needing recompilation once inference has finished. */
void addPendingRecompile(JSContext *cx, const RecompileInfo &info);
void addPendingRecompile(JSContext *cx, JSScript *script, jsbytecode *pc);
void addPendingRecompile(JSContext *cx, HandleScript script, jsbytecode *pc);
/* Monitor future effects on a bytecode. */
void monitorBytecode(JSContext *cx, JSScript *script, uint32_t offset,
void monitorBytecode(JSContext *cx, HandleScript script, uint32_t offset,
bool returnOnly = false);
/* Mark any type set containing obj as having a generic object type. */

View File

@ -479,7 +479,7 @@ GetTypeCallerInitObject(JSContext *cx, JSProtoKey key)
{
if (cx->typeInferenceEnabled()) {
jsbytecode *pc;
JSScript *script = cx->stack.currentScript(&pc);
RootedScript script(cx, cx->stack.currentScript(&pc));
if (script)
return TypeScript::InitObject(cx, script, pc, key);
}
@ -636,14 +636,20 @@ FixObjectType(JSContext *cx, HandleObject obj)
}
/* Interface helpers for JSScript */
extern void TypeMonitorResult(JSContext *cx, JSScript *script, jsbytecode *pc, const js::Value &rval);
extern void TypeDynamicResult(JSContext *cx, JSScript *script, jsbytecode *pc, js::types::Type type);
extern void TypeMonitorResult(JSContext *cx, HandleScript script, jsbytecode *pc,
const js::Value &rval);
extern void TypeDynamicResult(JSContext *cx, HandleScript script, jsbytecode *pc,
js::types::Type type);
inline bool
UseNewTypeAtEntry(JSContext *cx, StackFrame *fp)
{
return fp->isConstructing() && cx->typeInferenceEnabled() &&
fp->prev() && UseNewType(cx, fp->prev()->script(), fp->prevpc());
if (!fp->isConstructing() || !cx->typeInferenceEnabled() || !fp->prev())
return false;
RootedScript prevScript(cx, fp->prev()->script());
return UseNewType(cx, prevScript, fp->prevpc());
}
inline bool
@ -676,7 +682,7 @@ UseNewTypeForClone(JSFunction *fun)
* instance a singleton type and clone the underlying script.
*/
JSScript *script = fun->script();
RawScript script = fun->script();
if (script->length >= 50)
return false;
@ -705,20 +711,20 @@ UseNewTypeForClone(JSFunction *fun)
/////////////////////////////////////////////////////////////////////
/* static */ inline unsigned
TypeScript::NumTypeSets(JSScript *script)
TypeScript::NumTypeSets(RawScript script)
{
return script->nTypeSets + analyze::TotalSlots(script);
}
/* static */ inline HeapTypeSet *
TypeScript::ReturnTypes(JSScript *script)
TypeScript::ReturnTypes(RawScript script)
{
TypeSet *types = script->types->typeArray() + script->nTypeSets + js::analyze::CalleeSlot();
return types->toHeapTypeSet();
}
/* static */ inline StackTypeSet *
TypeScript::ThisTypes(JSScript *script)
TypeScript::ThisTypes(RawScript script)
{
TypeSet *types = script->types->typeArray() + script->nTypeSets + js::analyze::ThisSlot();
return types->toStackTypeSet();
@ -731,7 +737,7 @@ TypeScript::ThisTypes(JSScript *script)
*/
/* static */ inline StackTypeSet *
TypeScript::ArgTypes(JSScript *script, unsigned i)
TypeScript::ArgTypes(RawScript script, unsigned i)
{
JS_ASSERT(i < script->function()->nargs);
TypeSet *types = script->types->typeArray() + script->nTypeSets + js::analyze::ArgSlot(i);
@ -739,7 +745,7 @@ TypeScript::ArgTypes(JSScript *script, unsigned i)
}
/* static */ inline StackTypeSet *
TypeScript::LocalTypes(JSScript *script, unsigned i)
TypeScript::LocalTypes(RawScript script, unsigned i)
{
JS_ASSERT(i < script->nfixed);
TypeSet *types = script->types->typeArray() + script->nTypeSets + js::analyze::LocalSlot(script, i);
@ -747,7 +753,7 @@ TypeScript::LocalTypes(JSScript *script, unsigned i)
}
/* static */ inline StackTypeSet *
TypeScript::SlotTypes(JSScript *script, unsigned slot)
TypeScript::SlotTypes(RawScript script, unsigned slot)
{
JS_ASSERT(slot < js::analyze::TotalSlots(script));
TypeSet *types = script->types->typeArray() + script->nTypeSets + slot;
@ -755,7 +761,7 @@ TypeScript::SlotTypes(JSScript *script, unsigned slot)
}
/* static */ inline TypeObject *
TypeScript::StandardType(JSContext *cx, JSScript *script, JSProtoKey key)
TypeScript::StandardType(JSContext *cx, HandleScript script, JSProtoKey key)
{
js::RootedObject proto(cx);
if (!js_GetClassPrototype(cx, key, &proto, NULL))
@ -785,7 +791,7 @@ struct AllocationSiteKey {
};
/* static */ inline TypeObject *
TypeScript::InitObject(JSContext *cx, JSScript *script, jsbytecode *pc, JSProtoKey kind)
TypeScript::InitObject(JSContext *cx, HandleScript script, jsbytecode *pc, JSProtoKey kind)
{
JS_ASSERT(!UseNewTypeForInitializer(cx, script, pc, kind));
@ -841,35 +847,35 @@ SetInitializerObjectType(JSContext *cx, HandleScript script, jsbytecode *pc, Han
}
/* static */ inline void
TypeScript::Monitor(JSContext *cx, JSScript *script, jsbytecode *pc, const js::Value &rval)
TypeScript::Monitor(JSContext *cx, HandleScript script, jsbytecode *pc, const js::Value &rval)
{
if (cx->typeInferenceEnabled())
TypeMonitorResult(cx, script, pc, rval);
}
/* static */ inline void
TypeScript::MonitorOverflow(JSContext *cx, JSScript *script, jsbytecode *pc)
TypeScript::MonitorOverflow(JSContext *cx, HandleScript script, jsbytecode *pc)
{
if (cx->typeInferenceEnabled())
TypeDynamicResult(cx, script, pc, Type::DoubleType());
}
/* static */ inline void
TypeScript::MonitorString(JSContext *cx, JSScript *script, jsbytecode *pc)
TypeScript::MonitorString(JSContext *cx, HandleScript script, jsbytecode *pc)
{
if (cx->typeInferenceEnabled())
TypeDynamicResult(cx, script, pc, Type::StringType());
}
/* static */ inline void
TypeScript::MonitorUnknown(JSContext *cx, JSScript *script, jsbytecode *pc)
TypeScript::MonitorUnknown(JSContext *cx, HandleScript script, jsbytecode *pc)
{
if (cx->typeInferenceEnabled())
TypeDynamicResult(cx, script, pc, Type::UnknownType());
}
/* static */ inline void
TypeScript::GetPcScript(JSContext *cx, JSScript **script, jsbytecode **pc)
TypeScript::GetPcScript(JSContext *cx, MutableHandleScript script, jsbytecode **pc)
{
#ifdef JS_ION
if (cx->fp()->beginsIonActivation()) {
@ -877,14 +883,14 @@ TypeScript::GetPcScript(JSContext *cx, JSScript **script, jsbytecode **pc)
return;
}
#endif
*script = cx->fp()->script();
script.set(cx->fp()->script());
*pc = cx->regs().pc;
}
/* static */ inline void
TypeScript::MonitorOverflow(JSContext *cx)
{
JSScript *script;
RootedScript script(cx);
jsbytecode *pc;
GetPcScript(cx, &script, &pc);
MonitorOverflow(cx, script, pc);
@ -893,7 +899,7 @@ TypeScript::MonitorOverflow(JSContext *cx)
/* static */ inline void
TypeScript::MonitorString(JSContext *cx)
{
JSScript *script;
RootedScript script(cx);
jsbytecode *pc;
GetPcScript(cx, &script, &pc);
MonitorString(cx, script, pc);
@ -902,7 +908,7 @@ TypeScript::MonitorString(JSContext *cx)
/* static */ inline void
TypeScript::MonitorUnknown(JSContext *cx)
{
JSScript *script;
RootedScript script(cx);
jsbytecode *pc;
GetPcScript(cx, &script, &pc);
MonitorUnknown(cx, script, pc);
@ -911,7 +917,7 @@ TypeScript::MonitorUnknown(JSContext *cx)
/* static */ inline void
TypeScript::Monitor(JSContext *cx, const js::Value &rval)
{
JSScript *script;
RootedScript script(cx);
jsbytecode *pc;
GetPcScript(cx, &script, &pc);
Monitor(cx, script, pc, rval);
@ -937,7 +943,7 @@ TypeScript::MonitorAssign(JSContext *cx, HandleObject obj, jsid id)
}
/* static */ inline void
TypeScript::SetThis(JSContext *cx, JSScript *script, Type type)
TypeScript::SetThis(JSContext *cx, HandleScript script, Type type)
{
if (!cx->typeInferenceEnabled())
return;
@ -959,14 +965,14 @@ TypeScript::SetThis(JSContext *cx, JSScript *script, Type type)
}
/* static */ inline void
TypeScript::SetThis(JSContext *cx, JSScript *script, const js::Value &value)
TypeScript::SetThis(JSContext *cx, HandleScript script, const js::Value &value)
{
if (cx->typeInferenceEnabled())
SetThis(cx, script, GetValueType(cx, value));
}
/* static */ inline void
TypeScript::SetLocal(JSContext *cx, JSScript *script, unsigned local, Type type)
TypeScript::SetLocal(JSContext *cx, HandleScript script, unsigned local, Type type)
{
if (!cx->typeInferenceEnabled())
return;
@ -982,7 +988,7 @@ TypeScript::SetLocal(JSContext *cx, JSScript *script, unsigned local, Type type)
}
/* static */ inline void
TypeScript::SetLocal(JSContext *cx, JSScript *script, unsigned local, const js::Value &value)
TypeScript::SetLocal(JSContext *cx, HandleScript script, unsigned local, const js::Value &value)
{
if (cx->typeInferenceEnabled()) {
Type type = GetValueType(cx, value);
@ -991,7 +997,7 @@ TypeScript::SetLocal(JSContext *cx, JSScript *script, unsigned local, const js::
}
/* static */ inline void
TypeScript::SetArgument(JSContext *cx, JSScript *script, unsigned arg, Type type)
TypeScript::SetArgument(JSContext *cx, HandleScript script, unsigned arg, Type type)
{
if (!cx->typeInferenceEnabled())
return;
@ -1007,7 +1013,7 @@ TypeScript::SetArgument(JSContext *cx, JSScript *script, unsigned arg, Type type
}
/* static */ inline void
TypeScript::SetArgument(JSContext *cx, JSScript *script, unsigned arg, const js::Value &value)
TypeScript::SetArgument(JSContext *cx, HandleScript script, unsigned arg, const js::Value &value)
{
if (cx->typeInferenceEnabled()) {
Type type = GetValueType(cx, value);

View File

@ -1048,11 +1048,13 @@ IteratorNext(JSContext *cx, HandleObject iterobj, MutableHandleValue rval)
* types of the pushed values are consistent with type inference information.
*/
static inline void
TypeCheckNextBytecode(JSContext *cx, JSScript *script, unsigned n, const FrameRegs &regs)
TypeCheckNextBytecode(JSContext *cx, JSScript *script_, unsigned n, const FrameRegs &regs)
{
#ifdef DEBUG
if (cx->typeInferenceEnabled() &&
n == GetBytecodeLength(regs.pc)) {
n == GetBytecodeLength(regs.pc))
{
RootedScript script(cx, script_);
TypeScript::CheckBytecode(cx, script, regs.pc, regs.sp);
}
#endif

View File

@ -706,7 +706,7 @@ GetObjectElementOperation(JSContext *cx, JSOp op, HandleObject obj, const Value
if (!cx->fp()->beginsIonActivation()) {
// Don't update getStringElement if called from Ion code, since
// ion::GetPcScript is expensive.
JSScript *script;
RootedScript script(cx);
jsbytecode *pc;
types::TypeScript::GetPcScript(cx, &script, &pc);
@ -809,7 +809,7 @@ SetObjectElementOperation(JSContext *cx, Handle<JSObject*> obj, HandleId id, con
return true;
} else {
if (!cx->fp()->beginsIonActivation()) {
JSScript *script;
RootedScript script(cx);
jsbytecode *pc;
types::TypeScript::GetPcScript(cx, &script, &pc);

View File

@ -2368,8 +2368,10 @@ js_CreateThisForFunctionWithProto(JSContext *cx, HandleObject callee, JSObject *
res = NewObjectWithClassProto(cx, &ObjectClass, proto, callee->getParent(), kind);
}
if (res && cx->typeInferenceEnabled())
TypeScript::SetThis(cx, callee->toFunction()->script(), types::Type::ObjectType(res));
if (res && cx->typeInferenceEnabled()) {
RootedScript script(cx, callee->toFunction()->script());
TypeScript::SetThis(cx, script, types::Type::ObjectType(res));
}
return res;
}
@ -2398,7 +2400,7 @@ js_CreateThisForFunction(JSContext *cx, HandleObject callee, bool newType)
if (!JSObject::setSingletonType(cx, nobj))
return NULL;
JSScript *calleeScript = callee->toFunction()->script();
RootedScript calleeScript(cx, callee->toFunction()->script());
TypeScript::SetThis(cx, calleeScript, types::Type::ObjectType(nobj));
return nobj;

View File

@ -39,7 +39,7 @@ js::StartOffThreadIonCompile(JSContext *cx, ion::IonBuilder *builder)
static void
FinishOffThreadIonCompile(ion::IonBuilder *builder)
{
JSCompartment *compartment = builder->script->compartment();
JSCompartment *compartment = builder->script()->compartment();
JS_ASSERT(compartment->rt->workerThreadState->isLocked());
compartment->ionCompartment()->finishedOffThreadCompilations().append(builder);
@ -67,7 +67,7 @@ js::CancelOffThreadIonCompile(JSCompartment *compartment, JSScript *script)
/* Cancel any pending entries for which processing hasn't started. */
for (size_t i = 0; i < state.ionWorklist.length(); i++) {
ion::IonBuilder *builder = state.ionWorklist[i];
if (CompiledScriptMatches(compartment, script, builder->script)) {
if (CompiledScriptMatches(compartment, script, builder->script())) {
FinishOffThreadIonCompile(builder);
state.ionWorklist[i--] = state.ionWorklist.back();
state.ionWorklist.popBack();
@ -86,7 +86,7 @@ js::CancelOffThreadIonCompile(JSCompartment *compartment, JSScript *script)
/* Cancel code generation for any completed entries. */
for (size_t i = 0; i < compilations.length(); i++) {
ion::IonBuilder *builder = compilations[i];
if (CompiledScriptMatches(compartment, script, builder->script)) {
if (CompiledScriptMatches(compartment, script, builder->script())) {
ion::FinishOffThreadBuilder(builder);
compilations[i--] = compilations.back();
compilations.popBack();
@ -261,7 +261,7 @@ WorkerThread::threadLoop()
}
ion::IonBuilder *builder = state.ionWorklist.popCopy();
ionScript = builder->script;
ionScript = builder->script();
JS_ASSERT(ionScript->ion == ION_COMPILING_SCRIPT);

File diff suppressed because it is too large Load Diff

View File

@ -406,7 +406,7 @@ private:
ActiveFrame *a;
ActiveFrame *outer;
JSScript *script;
JSScript *script_;
analyze::ScriptAnalysis *analysis;
jsbytecode *PC;

View File

@ -170,6 +170,7 @@ mjit::Compiler::jsop_binary(JSOp op, VoidStub stub, JSValueType type, types::Typ
* itself. Note that monitorOverflow will propagate the type as
* necessary if a *INC operation overflowed.
*/
RootedScript script(cx, script_);
types::TypeScript::MonitorOverflow(cx, script, PC);
return false;
}
@ -197,7 +198,7 @@ mjit::Compiler::jsop_binary(JSOp op, VoidStub stub, JSValueType type, types::Typ
* from ignored overflows are not live across points where the interpreter
* can join into JIT code (loop heads and safe points).
*/
CrossSSAValue pushv(a->inlineIndex, SSAValue::PushedValue(PC - script->code, 0));
CrossSSAValue pushv(a->inlineIndex, SSAValue::PushedValue(PC - script_->code, 0));
bool cannotOverflow = loop && loop->cannotIntegerOverflow(pushv);
bool ignoreOverflow = loop && loop->ignoreIntegerOverflow(pushv);
@ -910,6 +911,7 @@ mjit::Compiler::jsop_mod()
if (tryBinaryConstantFold(cx, frame, JSOP_MOD, lhs, rhs, &v)) {
types::TypeSet *pushed = pushedTypeSet(0);
if (!v.isInt32() && pushed && !pushed->hasType(types::Type::DoubleType())) {
RootedScript script(cx, script_);
types::TypeScript::MonitorOverflow(cx, script, PC);
return false;
}

View File

@ -703,6 +703,7 @@ mjit::Compiler::compileArrayWithLength(uint32_t argc)
return Compile_InlineAbort;
}
RootedScript script(cx, script_);
types::TypeObject *type = types::TypeScript::InitObject(cx, script, PC, JSProto_Array);
if (!type)
return Compile_Error;
@ -744,6 +745,7 @@ mjit::Compiler::compileArrayWithArgs(uint32_t argc)
if (argc > maxArraySlots)
return Compile_InlineAbort;
RootedScript script(cx, script_);
types::TypeObject *type = types::TypeScript::InitObject(cx, script, PC, JSProto_Array);
if (!type)
return Compile_Error;

View File

@ -723,7 +723,7 @@ mjit::Compiler::jsop_typeof()
JSOp op = JSOp(PC[JSOP_TYPEOF_LENGTH + JSOP_STRING_LENGTH]);
if (op == JSOP_STRICTEQ || op == JSOP_EQ || op == JSOP_STRICTNE || op == JSOP_NE) {
JSAtom *atom = script->getAtom(GET_UINT32_INDEX(PC + JSOP_TYPEOF_LENGTH));
JSAtom *atom = script_->getAtom(GET_UINT32_INDEX(PC + JSOP_TYPEOF_LENGTH));
JSRuntime *rt = cx->runtime;
JSValueType type = JSVAL_TYPE_UNKNOWN;
Assembler::Condition cond = (op == JSOP_STRICTEQ || op == JSOP_EQ)
@ -967,7 +967,7 @@ mjit::Compiler::jsop_arginc(JSOp op, uint32_t slot)
if (!analysis->incrementInitialValueObserved(PC)) {
// Before:
// After: V
if (script->argsObjAliasesFormals())
if (script_->argsObjAliasesFormals())
jsop_aliasedArg(slot, /* get = */ true);
else
frame.pushArg(slot);
@ -985,14 +985,14 @@ mjit::Compiler::jsop_arginc(JSOp op, uint32_t slot)
// Before: N+1
// After: N+1
bool popGuaranteed = analysis->popGuaranteed(PC);
if (script->argsObjAliasesFormals())
if (script_->argsObjAliasesFormals())
jsop_aliasedArg(slot, /* get = */ false, popGuaranteed);
else
frame.storeArg(slot, popGuaranteed);
} else {
// Before:
// After: V
if (script->argsObjAliasesFormals())
if (script_->argsObjAliasesFormals())
jsop_aliasedArg(slot, /* get = */ true);
else
frame.pushArg(slot);
@ -1016,7 +1016,7 @@ mjit::Compiler::jsop_arginc(JSOp op, uint32_t slot)
// Before: N N+1
// After: N N+1
if (script->argsObjAliasesFormals())
if (script_->argsObjAliasesFormals())
jsop_aliasedArg(slot, /* get = */ false, true);
else
frame.storeArg(slot, true);
@ -1219,7 +1219,7 @@ mjit::Compiler::jsop_setelem_dense()
masm.storeValue(vr, BaseIndex(slotsReg, key.reg(), masm.JSVAL_SCALE));
stubcc.leave();
OOL_STUBCALL(STRICT_VARIANT(script, stubs::SetElem), REJOIN_FALLTHROUGH);
OOL_STUBCALL(STRICT_VARIANT(script_, stubs::SetElem), REJOIN_FALLTHROUGH);
if (!hoisted)
frame.freeReg(slotsReg);
@ -1493,7 +1493,7 @@ mjit::Compiler::jsop_setelem_typed(int atype)
frame.freeReg(objReg);
stubcc.leave();
OOL_STUBCALL(STRICT_VARIANT(script, stubs::SetElem), REJOIN_FALLTHROUGH);
OOL_STUBCALL(STRICT_VARIANT(script_, stubs::SetElem), REJOIN_FALLTHROUGH);
frame.shimmy(2);
stubcc.rejoin(Changes(2));
@ -1538,8 +1538,8 @@ mjit::Compiler::jsop_setelem(bool popGuaranteed)
FrameEntry *value = frame.peek(-1);
if (!IsCacheableSetElem(obj, id, value) || monitored(PC)) {
if (monitored(PC) && script == outerScript)
monitoredBytecodes.append(PC - script->code);
if (monitored(PC) && script_ == outerScript)
monitoredBytecodes.append(PC - script_->code);
jsop_setelem_slow();
return true;
@ -1697,9 +1697,9 @@ mjit::Compiler::jsop_setelem(bool popGuaranteed)
stubcc.leave();
#if defined JS_POLYIC
passICAddress(&ic);
ic.slowPathCall = OOL_STUBCALL(STRICT_VARIANT(script, ic::SetElement), REJOIN_FALLTHROUGH);
ic.slowPathCall = OOL_STUBCALL(STRICT_VARIANT(script_, ic::SetElement), REJOIN_FALLTHROUGH);
#else
OOL_STUBCALL(STRICT_VARIANT(script, stubs::SetElem), REJOIN_FALLTHROUGH);
OOL_STUBCALL(STRICT_VARIANT(script_, stubs::SetElem), REJOIN_FALLTHROUGH);
#endif
ic.fastPathRejoin = masm.label();
@ -2684,13 +2684,13 @@ mjit::Compiler::jsop_initprop()
{
FrameEntry *obj = frame.peek(-2);
FrameEntry *fe = frame.peek(-1);
PropertyName *name = script->getName(GET_UINT32_INDEX(PC));
PropertyName *name = script_->getName(GET_UINT32_INDEX(PC));
RootedObject baseobj(cx, frame.extra(obj).initObject);
if (!baseobj || monitored(PC) || cx->compartment->compileBarriers()) {
if (monitored(PC) && script == outerScript)
monitoredBytecodes.append(PC - script->code);
if (monitored(PC) && script_ == outerScript)
monitoredBytecodes.append(PC - script_->code);
prepareStubCall(Uses(2));
masm.move(ImmPtr(name), Registers::ArgReg1);

View File

@ -136,7 +136,8 @@ stubs::SlowCall(VMFrame &f, uint32_t argc)
if (!InvokeKernel(f.cx, args))
THROW();
types::TypeScript::Monitor(f.cx, f.script(), f.pc(), args.rval());
RootedScript fscript(f.cx, f.script());
types::TypeScript::Monitor(f.cx, fscript, f.pc(), args.rval());
}
void JS_FASTCALL
@ -146,7 +147,8 @@ stubs::SlowNew(VMFrame &f, uint32_t argc)
if (!InvokeConstructorKernel(f.cx, args))
THROW();
types::TypeScript::Monitor(f.cx, f.script(), f.pc(), args.rval());
RootedScript fscript(f.cx, f.script());
types::TypeScript::Monitor(f.cx, fscript, f.pc(), args.rval());
}
static inline bool
@ -282,8 +284,9 @@ UncachedInlineCall(VMFrame &f, InitialFrameFlags initial,
bool construct = InitialFrameFlagsAreConstructing(initial);
RootedScript fscript(cx, f.script());
bool newType = construct && cx->typeInferenceEnabled() &&
types::UseNewType(cx, f.script(), f.pc());
types::UseNewType(cx, fscript, f.pc());
if (!types::TypeMonitorCall(cx, args, construct))
return false;
@ -360,8 +363,10 @@ UncachedInlineCall(VMFrame &f, InitialFrameFlags initial,
bool ok = RunScript(cx, script, cx->fp());
f.cx->stack.popInlineFrame(regs);
if (ok)
types::TypeScript::Monitor(f.cx, f.script(), f.pc(), args.rval());
if (ok) {
RootedScript fscript(cx, f.script());
types::TypeScript::Monitor(f.cx, fscript, f.pc(), args.rval());
}
*pret = NULL;
return ok;
@ -389,7 +394,8 @@ stubs::UncachedNewHelper(VMFrame &f, uint32_t argc, UncachedCallResult &ucr)
} else {
if (!InvokeConstructorKernel(cx, args))
THROW();
types::TypeScript::Monitor(f.cx, f.script(), f.pc(), args.rval());
RootedScript fscript(cx, f.script());
types::TypeScript::Monitor(f.cx, fscript, f.pc(), args.rval());
}
}
@ -418,7 +424,8 @@ stubs::Eval(VMFrame &f, uint32_t argc)
if (!InvokeKernel(f.cx, args))
THROW();
types::TypeScript::Monitor(f.cx, f.script(), f.pc(), args.rval());
RootedScript fscript(f.cx, f.script());
types::TypeScript::Monitor(f.cx, fscript, f.pc(), args.rval());
return;
}
@ -426,7 +433,8 @@ stubs::Eval(VMFrame &f, uint32_t argc)
if (!DirectEval(f.cx, args))
THROW();
types::TypeScript::Monitor(f.cx, f.script(), f.pc(), args.rval());
RootedScript fscript(f.cx, f.script());
types::TypeScript::Monitor(f.cx, fscript, f.pc(), args.rval());
}
void
@ -448,7 +456,8 @@ stubs::UncachedCallHelper(VMFrame &f, uint32_t argc, bool lowered, UncachedCallR
if (ucr.fun->isNative()) {
if (!CallJSNative(cx, ucr.fun->native(), args))
THROW();
types::TypeScript::Monitor(f.cx, f.script(), f.pc(), args.rval());
RootedScript fscript(cx, f.script());
types::TypeScript::Monitor(f.cx, fscript, f.pc(), args.rval());
return;
}
}
@ -456,7 +465,8 @@ stubs::UncachedCallHelper(VMFrame &f, uint32_t argc, bool lowered, UncachedCallR
if (!InvokeKernel(f.cx, args))
THROW();
types::TypeScript::Monitor(f.cx, f.script(), f.pc(), args.rval());
RootedScript fscript(cx, f.script());
types::TypeScript::Monitor(f.cx, fscript, f.pc(), args.rval());
return;
}
@ -730,8 +740,10 @@ FinishVarIncOp(VMFrame &f, RejoinState rejoin, Value ov, Value nv, Value *vp)
if (rejoin == REJOIN_POS) {
double d = ov.toNumber();
double N = (cs->format & JOF_INC) ? 1 : -1;
if (!nv.setNumber(d + N))
types::TypeScript::MonitorOverflow(cx, f.script(), f.pc());
if (!nv.setNumber(d + N)) {
RootedScript fscript(cx, f.script());
types::TypeScript::MonitorOverflow(cx, fscript, f.pc());
}
}
unsigned i = GET_SLOTNO(f.pc());
@ -762,7 +774,7 @@ js_InternalInterpret(void *returnData, void *returnType, void *returnReg, js::VM
JSContext *cx = f.cx;
StackFrame *fp = f.regs.fp();
JSScript *script = fp->script();
RootedScript script(cx, fp->script());
jsbytecode *pc = f.regs.pc;

View File

@ -1648,7 +1648,8 @@ LoopState::definiteArrayAccess(const SSAValue &obj, const SSAValue &index)
if (objTypes->hasObjectFlags(cx, OBJECT_FLAG_NON_DENSE_ARRAY))
return false;
if (ArrayPrototypeHasIndexedProperty(cx, outerScript))
RootedScript rOuterScript(cx, outerScript);
if (ArrayPrototypeHasIndexedProperty(cx, rOuterScript))
return false;
uint32_t objSlot;

View File

@ -1061,7 +1061,8 @@ class CallCompiler : public BaseCompiler
if (!CallJSNative(cx, fun->native(), args))
THROWV(true);
types::TypeScript::Monitor(f.cx, f.script(), f.pc(), args.rval());
RootedScript fscript(cx, f.script());
types::TypeScript::Monitor(f.cx, fscript, f.pc(), args.rval());
/*
* Native stubs are not generated for inline frames. The overhead of

View File

@ -175,8 +175,10 @@ stubs::ToId(VMFrame &f)
if (!FetchElementId(f.cx, obj, idval, id.address(), idval))
THROW();
if (!idval.isInt32())
TypeScript::MonitorUnknown(f.cx, f.script(), f.pc());
if (!idval.isInt32()) {
RootedScript fscript(f.cx, f.script());
TypeScript::MonitorUnknown(f.cx, fscript, f.pc());
}
}
void JS_FASTCALL
@ -277,8 +279,10 @@ stubs::Ursh(VMFrame &f)
u >>= (j & 31);
if (!f.regs.sp[-2].setNumber(uint32_t(u)))
TypeScript::MonitorOverflow(f.cx, f.script(), f.pc());
if (!f.regs.sp[-2].setNumber(uint32_t(u))) {
RootedScript fscript(f.cx, f.script());
TypeScript::MonitorOverflow(f.cx, fscript, f.pc());
}
}
template<JSBool strict>
@ -591,7 +595,8 @@ stubs::Add(VMFrame &f)
THROW();
regs.sp[-2] = rval;
regs.sp--;
TypeScript::MonitorUnknown(cx, f.script(), f.pc());
RootedScript fscript(cx, f.script());
TypeScript::MonitorUnknown(cx, fscript, f.pc());
} else
#endif
{
@ -617,8 +622,10 @@ stubs::Add(VMFrame &f)
THROW();
regs.sp[-1].setString(rstr);
}
if (lIsObject || rIsObject)
TypeScript::MonitorString(cx, f.script(), f.pc());
if (lIsObject || rIsObject) {
RootedScript fscript(cx, f.script());
TypeScript::MonitorString(cx, fscript, f.pc());
}
goto string_concat;
} else {
@ -628,7 +635,8 @@ stubs::Add(VMFrame &f)
l += r;
if (!regs.sp[-2].setNumber(l) &&
(lIsObject || rIsObject || (!lval.isDouble() && !rval.isDouble()))) {
TypeScript::MonitorOverflow(cx, f.script(), f.pc());
RootedScript fscript(cx, f.script());
TypeScript::MonitorOverflow(cx, fscript, f.pc());
}
}
}
@ -652,8 +660,10 @@ stubs::Sub(VMFrame &f)
if (!ToNumber(cx, regs.sp[-2], &d1) || !ToNumber(cx, regs.sp[-1], &d2))
THROW();
double d = d1 - d2;
if (!regs.sp[-2].setNumber(d))
TypeScript::MonitorOverflow(cx, f.script(), f.pc());
if (!regs.sp[-2].setNumber(d)) {
RootedScript fscript(cx, f.script());
TypeScript::MonitorOverflow(cx, fscript, f.pc());
}
}
void JS_FASTCALL
@ -665,8 +675,10 @@ stubs::Mul(VMFrame &f)
if (!ToNumber(cx, regs.sp[-2], &d1) || !ToNumber(cx, regs.sp[-1], &d2))
THROW();
double d = d1 * d2;
if (!regs.sp[-2].setNumber(d))
TypeScript::MonitorOverflow(cx, f.script(), f.pc());
if (!regs.sp[-2].setNumber(d)) {
RootedScript fscript(cx, f.script());
TypeScript::MonitorOverflow(cx, fscript, f.pc());
}
}
void JS_FASTCALL
@ -694,11 +706,14 @@ stubs::Div(VMFrame &f)
else
vp = &rt->positiveInfinityValue;
regs.sp[-2] = *vp;
TypeScript::MonitorOverflow(cx, f.script(), f.pc());
RootedScript fscript(cx, f.script());
TypeScript::MonitorOverflow(cx, fscript, f.pc());
} else {
d1 /= d2;
if (!regs.sp[-2].setNumber(d1))
TypeScript::MonitorOverflow(cx, f.script(), f.pc());
if (!regs.sp[-2].setNumber(d1)) {
RootedScript fscript(cx, f.script());
TypeScript::MonitorOverflow(cx, fscript, f.pc());
}
}
}
@ -725,7 +740,8 @@ stubs::Mod(VMFrame &f)
d1 = js_fmod(d1, d2);
regs.sp[-2].setDouble(d1);
}
TypeScript::MonitorOverflow(cx, f.script(), f.pc());
RootedScript fscript(cx, f.script());
TypeScript::MonitorOverflow(cx, fscript, f.pc());
}
}
@ -890,8 +906,10 @@ stubs::Neg(VMFrame &f)
if (!ToNumber(f.cx, f.regs.sp[-1], &d))
THROW();
d = -d;
if (!f.regs.sp[-1].setNumber(d))
TypeScript::MonitorOverflow(f.cx, f.script(), f.pc());
if (!f.regs.sp[-1].setNumber(d)) {
RootedScript fscript(f.cx, f.script());
TypeScript::MonitorOverflow(f.cx, fscript, f.pc());
}
}
void JS_FASTCALL
@ -905,8 +923,8 @@ stubs::NewInitArray(VMFrame &f, uint32_t count)
if (type) {
obj->setType(type);
} else {
RootedScript script(f.cx, f.script());
if (!SetInitializerObjectType(f.cx, script, f.pc(), obj))
RootedScript fscript(f.cx, f.script());
if (!SetInitializerObjectType(f.cx, fscript, f.pc(), obj))
THROW();
}
@ -934,8 +952,8 @@ stubs::NewInitObject(VMFrame &f, JSObject *baseobj)
if (type) {
obj->setType(type);
} else {
RootedScript script(f.cx, f.script());
if (!SetInitializerObjectType(cx, script, f.pc(), obj))
RootedScript fscript(f.cx, f.script());
if (!SetInitializerObjectType(cx, fscript, f.pc(), obj))
THROW();
}
@ -1382,8 +1400,10 @@ stubs::Pos(VMFrame &f)
{
if (!ToNumber(f.cx, &f.regs.sp[-1]))
THROW();
if (!f.regs.sp[-1].isInt32())
TypeScript::MonitorOverflow(f.cx, f.script(), f.pc());
if (!f.regs.sp[-1].isInt32()) {
RootedScript fscript(f.cx, f.script());
TypeScript::MonitorOverflow(f.cx, fscript, f.pc());
}
}
void JS_FASTCALL
@ -1531,7 +1551,8 @@ stubs::TypeBarrierHelper(VMFrame &f, uint32_t which)
f.script()->analysis()->breakTypeBarriers(f.cx, f.pc() - f.script()->code, false);
}
TypeScript::Monitor(f.cx, f.script(), f.pc(), result);
RootedScript fscript(f.cx, f.script());
TypeScript::Monitor(f.cx, fscript, f.pc(), result);
}
void JS_FASTCALL
@ -1544,7 +1565,8 @@ stubs::StubTypeHelper(VMFrame &f, int32_t which)
f.script()->analysis()->breakTypeBarriers(f.cx, f.pc() - f.script()->code, false);
}
TypeScript::Monitor(f.cx, f.script(), f.pc(), result);
RootedScript fscript(f.cx, f.script());
TypeScript::Monitor(f.cx, fscript, f.pc(), result);
}
/*
@ -1554,14 +1576,16 @@ stubs::StubTypeHelper(VMFrame &f, int32_t which)
void JS_FASTCALL
stubs::TypeBarrierReturn(VMFrame &f, Value *vp)
{
TypeScript::Monitor(f.cx, f.script(), f.pc(), vp[0]);
RootedScript fscript(f.cx, f.script());
TypeScript::Monitor(f.cx, fscript, f.pc(), vp[0]);
}
void JS_FASTCALL
stubs::NegZeroHelper(VMFrame &f)
{
f.regs.sp[-1].setDouble(-0.0);
TypeScript::MonitorOverflow(f.cx, f.script(), f.pc());
RootedScript fscript(f.cx, f.script());
TypeScript::MonitorOverflow(f.cx, fscript, f.pc());
}
void JS_FASTCALL
@ -1569,7 +1593,7 @@ stubs::CheckArgumentTypes(VMFrame &f)
{
StackFrame *fp = f.fp();
JSFunction *fun = fp->fun();
JSScript *script = fun->script();
RootedScript fscript(f.cx, fun->script());
RecompilationMonitor monitor(f.cx);
{
@ -1577,9 +1601,9 @@ stubs::CheckArgumentTypes(VMFrame &f)
types::AutoEnterTypeInference enter(f.cx);
if (!f.fp()->isConstructing())
TypeScript::SetThis(f.cx, script, fp->thisValue());
TypeScript::SetThis(f.cx, fscript, fp->thisValue());
for (unsigned i = 0; i < fun->nargs; i++)
TypeScript::SetArgument(f.cx, script, i, fp->unaliasedFormal(i, DONT_CHECK_ALIASING));
TypeScript::SetArgument(f.cx, fscript, i, fp->unaliasedFormal(i, DONT_CHECK_ALIASING));
}
if (monitor.recompiled())

View File

@ -147,7 +147,7 @@ JSC::MacroAssembler::Call
StubCompiler::emitStubCall(void *ptr, RejoinState rejoin, Uses uses, int32_t slots)
{
JaegerSpew(JSpew_Insns, " ---- BEGIN SLOW CALL CODE ---- \n");
masm.bumpStubCount(cc.script, cc.PC, Registers::tempCallReg());
masm.bumpStubCount(cc.script_, cc.PC, Registers::tempCallReg());
DataLabelPtr inlinePatch;
Call cl = masm.fallibleVMCall(cx->typeInferenceEnabled(),
ptr, cc.outerPC(), &inlinePatch, slots);

View File

@ -169,7 +169,7 @@ ArgSetter(JSContext *cx, HandleObject obj, HandleId id, JSBool strict, MutableHa
attrs &= (JSPROP_ENUMERATE | JSPROP_PERMANENT); /* only valid attributes */
NormalArgumentsObject &argsobj = obj->asNormalArguments();
JSScript *script = argsobj.containingScript();
RootedScript script(cx, argsobj.containingScript());
if (JSID_IS_INT(id)) {
unsigned arg = unsigned(JSID_TO_INT(id));

View File

@ -1119,7 +1119,7 @@ class DebugScopeProxy : public BaseProxyHandler
/* Handle unaliased formals, vars, and consts at function scope. */
if (scope->isCall() && !scope->asCall().isForEval()) {
CallObject &callobj = scope->asCall();
JSScript *script = callobj.callee().script();
RootedScript script(cx, callobj.callee().script());
if (!script->ensureHasTypes(cx))
return false;

View File

@ -524,13 +524,13 @@ ContextStack::currentScript(jsbytecode **ppc,
if (!hasfp())
return NULL;
FrameRegs &regs = this->regs();
StackFrame *fp = regs.fp();
#ifdef JS_ION
if (fp->beginsIonActivation()) {
JSScript *script = NULL;
RootedScript script(cx_);
ion::GetPcScript(cx_, &script, ppc);
if (!allowCrossCompartment && script->compartment() != cx_->compartment)
return NULL;