MIPS: Use keyed-call inline caches in delegating yield.
authorpalfia@homejinni.com <palfia@homejinni.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 13 Jun 2013 16:50:22 +0000 (16:50 +0000)
committerpalfia@homejinni.com <palfia@homejinni.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 13 Jun 2013 16:50:22 +0000 (16:50 +0000)
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

src/mips/full-codegen-mips.cc

index a16e478afa882d4b9f0c5b0af26b1262d2a73b46..57964efdf3dba56173b0e8496c7c4442055e216f 100644 (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);