Bug 836274: Disable funapply inlining when typeset of callee is tighter than caller, r=nbp

This commit is contained in:
Hannes Verschore 2013-02-19 11:33:42 +01:00
parent d61fa1ce46
commit 0ea4bcce63
2 changed files with 49 additions and 1 deletions

View File

@ -3194,11 +3194,46 @@ IonBuilder::makeInliningDecision(AutoObjectVector &targets)
return false;
}
JSOp op = JSOp(*pc);
for (size_t i = 0; i < targets.length(); i++) {
if (!canInlineTarget(targets[i]->toFunction())) {
JSFunction *target = targets[i]->toFunction();
if (!canInlineTarget(target)) {
IonSpew(IonSpew_Inlining, "Decided not to inline");
return false;
}
// For fun.apply we need to make sure the types of the argument is a subset
// of the types used in the callee. Because adding a typeset in the callee,
// doesn't update the types in the "apply" function, resulting in missed types.
if (op == JSOP_FUNAPPLY) {
types::TypeSet *calleeType, *callerType;
size_t nargs = Min<size_t>(target->nargs, inlinedArguments_.length());
for (size_t i = 0; i < nargs; i++) {
calleeType = types::TypeScript::ArgTypes(targetScript, i);
// The arguments to this function aren't always available in this script.
// We need to get them from the caller at the position where
// the function gets called.
callerType = oracle->getCallArg(callerBuilder_->script_.get(),
inlinedArguments_.length(),
i+1, callerBuilder_->pc);
if (!callerType->isSubset(calleeType)) {
IonSpew(IonSpew_Inlining, "Funapply inlining failed due to wrong types");
return false;
}
}
// Arguments that weren't provided will be Undefined
for (size_t i = nargs; i < target->nargs; i++) {
calleeType = types::TypeScript::ArgTypes(targetScript, i);
if (calleeType->unknown() ||
!calleeType->hasType(types::Type::UndefinedType()))
{
IonSpew(IonSpew_Inlining, "Funapply inlining failed due to wrong types");
return false;
}
}
}
}
return true;

View File

@ -0,0 +1,13 @@
function dumpArgs6(i) {
if (i == 90)
return funapply6.arguments.length;
return [i];
}
function funapply6() {
return dumpArgs6.apply({}, arguments);
}
function test6(i) {
return funapply6(i,1,2,3);
}
test6(89)[0]
test6(0.2)