зеркало из https://github.com/mozilla/gecko-dev.git
Bug 826148 - Part 2: TI changes (r=bhackett)
This commit is contained in:
Родитель
23f0319215
Коммит
8c3510746e
|
@ -689,6 +689,7 @@ class TypeConstraintCall : public TypeConstraint
|
|||
const char *kind() { return "call"; }
|
||||
|
||||
void newType(JSContext *cx, TypeSet *source, Type type);
|
||||
bool newCallee(JSContext *cx, HandleFunction callee, HandleScript script);
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -772,6 +773,7 @@ class TypeConstraintPropagateThis : public TypeConstraint
|
|||
const char *kind() { return "propagatethis"; }
|
||||
|
||||
void newType(JSContext *cx, TypeSet *source, Type type);
|
||||
bool newCallee(JSContext *cx, HandleFunction callee);
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -1256,6 +1258,23 @@ TypeConstraintSetElement::newType(JSContext *cx, TypeSet *source, Type type)
|
|||
}
|
||||
}
|
||||
|
||||
static inline RawFunction
|
||||
CloneCallee(JSContext *cx, HandleFunction fun, HandleScript script, jsbytecode *pc)
|
||||
{
|
||||
/*
|
||||
* Clone called functions at appropriate callsites to match interpreter
|
||||
* behavior.
|
||||
*/
|
||||
RawFunction callee = CloneFunctionAtCallsite(cx, fun, script, pc);
|
||||
if (!callee)
|
||||
return NULL;
|
||||
|
||||
InferSpew(ISpewOps, "callsiteCloneType: #%u:%05u: %s",
|
||||
script->id(), pc - script->code, TypeString(Type::ObjectType(callee)));
|
||||
|
||||
return callee;
|
||||
}
|
||||
|
||||
void
|
||||
TypeConstraintCall::newType(JSContext *cx, TypeSet *source, Type type)
|
||||
{
|
||||
|
@ -1348,11 +1367,30 @@ TypeConstraintCall::newType(JSContext *cx, TypeSet *source, Type type)
|
|||
return;
|
||||
}
|
||||
|
||||
RootedScript calleeScript(cx, JSFunction::getOrCreateScript(cx, callee));
|
||||
if (!calleeScript)
|
||||
if (callee->isInterpretedLazy() && !JSFunction::getOrCreateScript(cx, callee))
|
||||
return;
|
||||
|
||||
/*
|
||||
* As callsite cloning is a hint, we must propagate to both the original
|
||||
* and the clone.
|
||||
*/
|
||||
if (callee->isCloneAtCallsite()) {
|
||||
RootedFunction clone(cx, CloneCallee(cx, callee, script, pc));
|
||||
if (!clone)
|
||||
return;
|
||||
if (!newCallee(cx, clone, script))
|
||||
return;
|
||||
}
|
||||
|
||||
newCallee(cx, callee, script);
|
||||
}
|
||||
|
||||
bool
|
||||
TypeConstraintCall::newCallee(JSContext *cx, HandleFunction callee, HandleScript script)
|
||||
{
|
||||
RootedScript calleeScript(cx, callee->nonLazyScript());
|
||||
if (!calleeScript->ensureHasTypes(cx))
|
||||
return;
|
||||
return false;
|
||||
|
||||
unsigned nargs = callee->nargs;
|
||||
|
||||
|
@ -1360,7 +1398,7 @@ TypeConstraintCall::newType(JSContext *cx, TypeSet *source, Type type)
|
|||
for (unsigned i = 0; i < callsite->argumentCount && i < nargs; i++) {
|
||||
StackTypeSet *argTypes = callsite->argumentTypes[i];
|
||||
StackTypeSet *types = TypeScript::ArgTypes(calleeScript, i);
|
||||
argTypes->addSubsetBarrier(cx, script, pc, types);
|
||||
argTypes->addSubsetBarrier(cx, script, callsite->pc, types);
|
||||
}
|
||||
|
||||
/* Add void type for any formals in the callee not supplied at the call site. */
|
||||
|
@ -1392,6 +1430,8 @@ TypeConstraintCall::newType(JSContext *cx, TypeSet *source, Type type)
|
|||
*/
|
||||
returnTypes->addSubset(cx, callsite->returnTypes);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1399,6 +1439,7 @@ TypeConstraintPropagateThis::newType(JSContext *cx, TypeSet *source, Type type)
|
|||
{
|
||||
AssertCanGC();
|
||||
|
||||
RootedScript script(cx, script_);
|
||||
if (type.isUnknown() || type.isAnyObject()) {
|
||||
/*
|
||||
* The callee is unknown, make sure the call is monitored so we pick up
|
||||
|
@ -1406,7 +1447,6 @@ TypeConstraintPropagateThis::newType(JSContext *cx, TypeSet *source, Type type)
|
|||
* CALLPROP, for other calls we are past the type barrier and a
|
||||
* TypeConstraintCall will also monitor the call.
|
||||
*/
|
||||
RootedScript script(cx, script_);
|
||||
cx->compartment->types.monitorBytecode(cx, script, callpc - script->code);
|
||||
return;
|
||||
}
|
||||
|
@ -1429,14 +1469,37 @@ TypeConstraintPropagateThis::newType(JSContext *cx, TypeSet *source, Type type)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!(JSFunction::getOrCreateScript(cx, callee) && callee->nonLazyScript()->ensureHasTypes(cx)))
|
||||
if (callee->isInterpretedLazy() && !JSFunction::getOrCreateScript(cx, callee))
|
||||
return;
|
||||
|
||||
/*
|
||||
* As callsite cloning is a hint, we must propagate to both the original
|
||||
* and the clone.
|
||||
*/
|
||||
if (callee->isCloneAtCallsite()) {
|
||||
RootedFunction clone(cx, CloneCallee(cx, callee, script, callpc));
|
||||
if (!clone)
|
||||
return;
|
||||
if (!newCallee(cx, clone))
|
||||
return;
|
||||
}
|
||||
|
||||
newCallee(cx, callee);
|
||||
}
|
||||
|
||||
bool
|
||||
TypeConstraintPropagateThis::newCallee(JSContext *cx, HandleFunction callee)
|
||||
{
|
||||
if (!callee->nonLazyScript()->ensureHasTypes(cx))
|
||||
return false;
|
||||
|
||||
TypeSet *thisTypes = TypeScript::ThisTypes(callee->nonLazyScript());
|
||||
if (this->types)
|
||||
this->types->addSubset(cx, thisTypes);
|
||||
else
|
||||
thisTypes->addType(cx, this->type);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Загрузка…
Ссылка в новой задаче