Bug 835178: IonMonkey: Enable inlining of functions containing JSOP_SETARG, r=nbp

This commit is contained in:
Hannes Verschore 2013-01-29 16:26:11 +01:00
Родитель 89d6e1d425
Коммит 7784ac141a
5 изменённых файлов: 51 добавлений и 15 удалений

Просмотреть файл

@ -870,7 +870,6 @@ IonBuilder::inspectOpcode(JSOp op)
return true;
case JSOP_SETARG:
JS_ASSERT(inliningDepth == 0);
// To handle this case, we should spill the arguments to the space where
// actual arguments are stored. The tricky part is that if we add a MIR
// to wrap the spilling action, we don't want the spilling to be

Просмотреть файл

@ -15,7 +15,7 @@ namespace ion {
template <class Op>
inline void
SnapshotIterator::readFrameArgs(Op op, const Value *argv, Value *scopeChain, Value *thisv,
SnapshotIterator::readFrameArgs(Op &op, const Value *argv, Value *scopeChain, Value *thisv,
unsigned start, unsigned formalEnd, unsigned iterEnd)
{
if (scopeChain)
@ -62,28 +62,35 @@ InlineFrameIterator::forEachCanonicalActualArg(JSContext *cx, Op op, unsigned st
if (more()) {
// There is still a parent frame of this inlined frame.
// Take arguments of the caller (parent inlined frame) it holds all actual
// arguments, needed in case of overflow, and because the analyze phase
// disable Ion inlining if the function redefine its arguments with JSOP_SETARG.
// The not overflown arguments are taken from the inlined frame,
// because it will have the updated value when JSOP_SETARG is done.
// All arguments (also the overflown) are the last pushed values in the parent frame.
// To get the overflown arguments, we need to take them from there.
// Get the non overflown arguments
unsigned formal_end = (end < nformal) ? end : nformal;
SnapshotIterator s(si_);
s.readFrameArgs(op, NULL, NULL, NULL, start, nformal, formal_end);
// The overflown arguments are not available in current frame.
// They are the last pushed arguments in the parent frame of this inlined frame.
InlineFrameIterator it(cx, this);
++it;
SnapshotIterator s(it.snapshotIterator());
SnapshotIterator parent_s((++it).snapshotIterator());
// Skip over all slots untill we get to the arguments slots
// Skip over all slots untill we get to the last slots (= arguments slots of callee)
// the +2 is for [this] and [scopechain]
JS_ASSERT(s.slots() >= nactual + 2);
unsigned skip = s.slots() - nactual - 2;
JS_ASSERT(parent_s.slots() >= nactual + 2);
unsigned skip = parent_s.slots() - nactual - 2;
for (unsigned j = 0; j < skip; j++)
s.skip();
parent_s.skip();
s.readFrameArgs(op, NULL, NULL, NULL, start, nactual, end);
// Get the overflown arguments
parent_s.readFrameArgs(op, NULL, NULL, NULL, nformal, nactual, end);
} else {
SnapshotIterator s(si_);
Value *argv = frame_->actualArgs();
s.readFrameArgs(op, argv, NULL, NULL, start, nformal, end);
}
}
} // namespace ion

Просмотреть файл

@ -238,7 +238,7 @@ class SnapshotIterator : public SnapshotReader
}
template <class Op>
inline void readFrameArgs(Op op, const Value *argv, Value *scopeChain, Value *thisv,
inline void readFrameArgs(Op &op, const Value *argv, Value *scopeChain, Value *thisv,
unsigned start, unsigned formalEnd, unsigned iterEnd);
Value maybeReadSlotByIndex(size_t index) {

Просмотреть файл

@ -0,0 +1,30 @@
function boo() { return foo.arguments[0] }
function foo(a,b,c) { if (a == 0) {a = 2; return boo();} return a }
function inlined() { return foo.apply({}, arguments); }
function test(a,b,c) { return inlined(a,b,c) }
assertEq(test(1,2,3), 1);
assertEq(test(0,2,3), 2);
function g(a) { if (g.arguments[1]) return true; return false; };
function f() { return g(false, true); };
function h() { return f(false, false); }
assertEq(h(false, false), true);
assertEq(h(false, false), true);
function g2(a) { if (a) { if (g2.arguments[1]) return true; return false; } return true; };
function f2(a) { return g2(a, true); };
function h2(a) { return f2(a, false); }
assertEq(h2(false, false), true);
assertEq(h2(true, false), true);
// Currently disabled for now, but in testsuite to be sure
function g3(a) { return a };
function f3(a) { a = 3; return g3.apply({}, arguments); };
function h3(a) { return f3(a); }
assertEq(h3(0), 3);
assertEq(h3(0), 3);

Просмотреть файл

@ -447,7 +447,7 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx)
case JSOP_SETARG:
modifiesArguments_ = true;
isIonInlineable = isJaegerInlineable = false;
isJaegerInlineable = false;
break;
case JSOP_GETPROP: