MIPS: Use keyed-call inline caches in delegating yield.

Port r15111 (7de1a19)

Original commit message:
Since we can't assume anything about the shape of the iterator in a
yield* (delegating yield), use an IC to do the next() and throw()
iterator method calls.

BUG=v8:2691
TEST=mjsunit/regress/regress-2691

Review URL: https://codereview.chromium.org/16923008
Patch from Balazs Kilvady <kilvadyb@homejinni.com>.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15128 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
palfia@homejinni.com 2013-06-13 16:50:22 +00:00
parent 9e1c894a9e
commit 69b43a07ec

View File

@ -2042,18 +2042,14 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
__ LoadRoot(a0, Heap::kUndefinedValueRootIndex);
__ Branch(&l_next);
// catch (e) { receiver = iter; f = iter.throw; arg = e; goto l_call; }
// catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; }
__ bind(&l_catch);
__ mov(a0, v0);
handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos()));
__ LoadRoot(a2, Heap::kthrow_stringRootIndex); // "throw"
__ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter
__ push(a3); // iter
__ push(a0); // exception
__ mov(a0, a3); // iter
__ LoadRoot(a2, Heap::kthrow_stringRootIndex); // "throw"
Handle<Code> throw_ic = isolate()->builtins()->LoadIC_Initialize();
CallIC(throw_ic); // iter.throw in a0
__ mov(a0, v0);
__ jmp(&l_call);
// try { received = yield result.value }
@ -2076,32 +2072,18 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
__ bind(&l_resume); // received in a0
__ PopTryHandler();
// receiver = iter; f = iter.next; arg = received;
// receiver = iter; f = 'next'; arg = received;
__ bind(&l_next);
__ LoadRoot(a2, Heap::knext_stringRootIndex); // "next"
__ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter
__ push(a3); // iter
__ push(a0); // received
__ mov(a0, a3); // iter
__ LoadRoot(a2, Heap::knext_stringRootIndex); // "next"
Handle<Code> next_ic = isolate()->builtins()->LoadIC_Initialize();
CallIC(next_ic); // iter.next in a0
__ mov(a0, v0);
// result = f.call(receiver, arg);
// result = receiver[f](arg);
__ bind(&l_call);
Label l_call_runtime;
__ JumpIfSmi(a0, &l_call_runtime);
__ GetObjectType(a0, a1, a1);
__ Branch(&l_call_runtime, ne, a1, Operand(JS_FUNCTION_TYPE));
__ mov(a1, a0);
ParameterCount count(1);
__ InvokeFunction(a1, count, CALL_FUNCTION,
NullCallWrapper(), CALL_AS_METHOD);
Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize(1);
CallIC(ic);
__ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
__ jmp(&l_loop);
__ bind(&l_call_runtime);
__ push(a0);
__ CallRuntime(Runtime::kCall, 3);
// val = result.value; if (!result.done) goto l_try;
__ bind(&l_loop);