mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-07 20:17:37 +00:00
Bug 791611 (part 3) - Exactly root most JSScripts in jsinfer.cpp. r=terrence.
--HG-- extra : rebase_source : c675efbd7e628742e59cd14ae91ab8998d3dfc5c
This commit is contained in:
parent
cbb7f8ccdc
commit
db15e47aa4
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -8,6 +8,8 @@
|
||||
#include "ion/IonMacroAssembler.h"
|
||||
#include "gc/Marking.h"
|
||||
|
||||
#include "jsscriptinlines.h"
|
||||
|
||||
using namespace js;
|
||||
using namespace js::ion;
|
||||
|
||||
|
@ -7,6 +7,8 @@
|
||||
|
||||
#include "MoveEmitter-x86-shared.h"
|
||||
|
||||
#include "jsscriptinlines.h"
|
||||
|
||||
using namespace js;
|
||||
using namespace js::ion;
|
||||
|
||||
|
@ -8,6 +8,8 @@
|
||||
#include "Assembler-x64.h"
|
||||
#include "gc/Marking.h"
|
||||
|
||||
#include "jsscriptinlines.h"
|
||||
|
||||
using namespace js;
|
||||
using namespace js::ion;
|
||||
|
||||
|
@ -9,6 +9,8 @@
|
||||
#include "ion/MoveEmitter.h"
|
||||
#include "ion/IonFrames.h"
|
||||
|
||||
#include "jsscriptinlines.h"
|
||||
|
||||
using namespace js;
|
||||
using namespace js::ion;
|
||||
|
||||
|
@ -14,6 +14,8 @@
|
||||
#include "ion/VMFunctions.h"
|
||||
#include "ion/IonSpewer.h"
|
||||
|
||||
#include "jsscriptinlines.h"
|
||||
|
||||
using namespace js;
|
||||
using namespace js::ion;
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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];
|
||||
}
|
||||
|
@ -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
@ -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. */
|
||||
|
@ -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);
|
||||
|
@ -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 ®s)
|
||||
TypeCheckNextBytecode(JSContext *cx, JSScript *script_, unsigned n, const FrameRegs ®s)
|
||||
{
|
||||
#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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
@ -406,7 +406,7 @@ private:
|
||||
ActiveFrame *a;
|
||||
ActiveFrame *outer;
|
||||
|
||||
JSScript *script;
|
||||
JSScript *script_;
|
||||
analyze::ScriptAnalysis *analysis;
|
||||
jsbytecode *PC;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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())
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
|
||||
|
@ -524,13 +524,13 @@ ContextStack::currentScript(jsbytecode **ppc,
|
||||
|
||||
if (!hasfp())
|
||||
return NULL;
|
||||
|
||||
|
||||
FrameRegs ®s = 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;
|
||||
|
Loading…
Reference in New Issue
Block a user