Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(796)

Side by Side Diff: src/mips/full-codegen-mips.cc

Issue 17291016: MIPS: Generators: Avoid calling into runtime if operand stack is empty (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 1983 matching lines...) Expand 10 before | Expand all | Expand 10 after
1994 // this. It stays on the stack while we update the iterator. 1994 // this. It stays on the stack while we update the iterator.
1995 VisitForStackValue(expr->expression()); 1995 VisitForStackValue(expr->expression());
1996 1996
1997 switch (expr->yield_kind()) { 1997 switch (expr->yield_kind()) {
1998 case Yield::SUSPEND: 1998 case Yield::SUSPEND:
1999 // Pop value from top-of-stack slot; box result into result register. 1999 // Pop value from top-of-stack slot; box result into result register.
2000 EmitCreateIteratorResult(false); 2000 EmitCreateIteratorResult(false);
2001 __ push(result_register()); 2001 __ push(result_register());
2002 // Fall through. 2002 // Fall through.
2003 case Yield::INITIAL: { 2003 case Yield::INITIAL: {
2004 VisitForStackValue(expr->generator_object()); 2004 Label suspend, continuation, post_runtime, resume;
2005
2006 __ jmp(&suspend);
2007
2008 __ bind(&continuation);
2009 __ jmp(&resume);
2010
2011 __ bind(&suspend);
2012 VisitForAccumulatorValue(expr->generator_object());
2013 ASSERT(continuation.pos() > 0 && Smi::IsValid(continuation.pos()));
2014 __ li(a1, Operand(Smi::FromInt(continuation.pos())));
2015 __ sw(a1, FieldMemOperand(v0, JSGeneratorObject::kContinuationOffset));
2016 __ sw(cp, FieldMemOperand(v0, JSGeneratorObject::kContextOffset));
2017 __ mov(a1, cp);
2018 __ RecordWriteField(v0, JSGeneratorObject::kContextOffset, a1, a2,
2019 kRAHasBeenSaved, kDontSaveFPRegs);
2020 __ Addu(a1, fp, Operand(StandardFrameConstants::kExpressionsOffset));
2021 __ Branch(&post_runtime, eq, sp, Operand(a1));
2022 __ push(v0); // generator object
2005 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); 2023 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
2006 __ lw(context_register(), 2024 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2007 MemOperand(fp, StandardFrameConstants::kContextOffset)); 2025 __ bind(&post_runtime);
2008
2009 Label resume;
2010 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
2011 __ Branch(&resume, ne, result_register(), Operand(at));
2012 __ pop(result_register()); 2026 __ pop(result_register());
2013 EmitReturnSequence(); 2027 EmitReturnSequence();
2014 2028
2015 __ bind(&resume); 2029 __ bind(&resume);
2016 context()->Plug(result_register()); 2030 context()->Plug(result_register());
2017 break; 2031 break;
2018 } 2032 }
2019 2033
2020 case Yield::FINAL: { 2034 case Yield::FINAL: {
2021 VisitForAccumulatorValue(expr->generator_object()); 2035 VisitForAccumulatorValue(expr->generator_object());
2022 __ li(a1, Operand(Smi::FromInt(JSGeneratorObject::kGeneratorClosed))); 2036 __ li(a1, Operand(Smi::FromInt(JSGeneratorObject::kGeneratorClosed)));
2023 __ sw(a1, FieldMemOperand(result_register(), 2037 __ sw(a1, FieldMemOperand(result_register(),
2024 JSGeneratorObject::kContinuationOffset)); 2038 JSGeneratorObject::kContinuationOffset));
2025 // Pop value from top-of-stack slot, box result into result register. 2039 // Pop value from top-of-stack slot, box result into result register.
2026 EmitCreateIteratorResult(true); 2040 EmitCreateIteratorResult(true);
2027 EmitUnwindBeforeReturn(); 2041 EmitUnwindBeforeReturn();
2028 EmitReturnSequence(); 2042 EmitReturnSequence();
2029 break; 2043 break;
2030 } 2044 }
2031 2045
2032 case Yield::DELEGATING: { 2046 case Yield::DELEGATING: {
2033 VisitForStackValue(expr->generator_object()); 2047 VisitForStackValue(expr->generator_object());
2034 2048
2035 // Initial stack layout is as follows: 2049 // Initial stack layout is as follows:
2036 // [sp + 1 * kPointerSize] iter 2050 // [sp + 1 * kPointerSize] iter
2037 // [sp + 0 * kPointerSize] g 2051 // [sp + 0 * kPointerSize] g
2038 2052
2039 Label l_catch, l_try, l_resume, l_next, l_call, l_loop; 2053 Label l_catch, l_try, l_suspend, l_continuation, l_resume;
2054 Label l_next, l_call, l_loop;
2040 // Initial send value is undefined. 2055 // Initial send value is undefined.
2041 __ LoadRoot(a0, Heap::kUndefinedValueRootIndex); 2056 __ LoadRoot(a0, Heap::kUndefinedValueRootIndex);
2042 __ Branch(&l_next); 2057 __ Branch(&l_next);
2043 2058
2044 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; } 2059 // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; }
2045 __ bind(&l_catch); 2060 __ bind(&l_catch);
2046 __ mov(a0, v0); 2061 __ mov(a0, v0);
2047 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos())); 2062 handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos()));
2048 __ LoadRoot(a2, Heap::kthrow_stringRootIndex); // "throw" 2063 __ LoadRoot(a2, Heap::kthrow_stringRootIndex); // "throw"
2049 __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter 2064 __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter
2050 __ push(a3); // iter 2065 __ push(a3); // iter
2051 __ push(a0); // exception 2066 __ push(a0); // exception
2052 __ jmp(&l_call); 2067 __ jmp(&l_call);
2053 2068
2054 // try { received = %yield result } 2069 // try { received = %yield result }
2055 // Shuffle the received result above a try handler and yield it without 2070 // Shuffle the received result above a try handler and yield it without
2056 // re-boxing. 2071 // re-boxing.
2057 __ bind(&l_try); 2072 __ bind(&l_try);
2058 __ pop(a0); // result 2073 __ pop(a0); // result
2059 __ PushTryHandler(StackHandler::CATCH, expr->index()); 2074 __ PushTryHandler(StackHandler::CATCH, expr->index());
2060 const int handler_size = StackHandlerConstants::kSize; 2075 const int handler_size = StackHandlerConstants::kSize;
2061 __ push(a0); // result 2076 __ push(a0); // result
2062 __ lw(a3, MemOperand(sp, (0 + 1) * kPointerSize + handler_size)); // g 2077 __ jmp(&l_suspend);
2063 __ push(a3); // g 2078 __ bind(&l_continuation);
2079 __ mov(a0, v0);
2080 __ jmp(&l_resume);
2081 __ bind(&l_suspend);
2082 const int generator_object_depth = kPointerSize + handler_size;
2083 __ lw(a0, MemOperand(sp, generator_object_depth));
2084 __ push(a0); // g
2085 ASSERT(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos()));
2086 __ li(a1, Operand(Smi::FromInt(l_continuation.pos())));
2087 __ sw(a1, FieldMemOperand(a0, JSGeneratorObject::kContinuationOffset));
2088 __ sw(cp, FieldMemOperand(a0, JSGeneratorObject::kContextOffset));
2089 __ mov(a1, cp);
2090 __ RecordWriteField(a0, JSGeneratorObject::kContextOffset, a1, a2,
2091 kRAHasBeenSaved, kDontSaveFPRegs);
2064 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1); 2092 __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
2065 __ mov(a0, v0); 2093 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2066 __ lw(context_register(),
2067 MemOperand(fp, StandardFrameConstants::kContextOffset));
2068 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
2069 __ Branch(&l_resume, ne, a0, Operand(at));
2070 __ pop(v0); // result 2094 __ pop(v0); // result
2071 EmitReturnSequence(); 2095 EmitReturnSequence();
2072 __ mov(a0, v0); 2096 __ mov(a0, v0);
2073 __ bind(&l_resume); // received in a0 2097 __ bind(&l_resume); // received in a0
2074 __ PopTryHandler(); 2098 __ PopTryHandler();
2075 2099
2076 // receiver = iter; f = 'next'; arg = received; 2100 // receiver = iter; f = 'next'; arg = received;
2077 __ bind(&l_next); 2101 __ bind(&l_next);
2078 __ LoadRoot(a2, Heap::knext_stringRootIndex); // "next" 2102 __ LoadRoot(a2, Heap::knext_stringRootIndex); // "next"
2079 __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter 2103 __ lw(a3, MemOperand(sp, 1 * kPointerSize)); // iter
(...skipping 2847 matching lines...) Expand 10 before | Expand all | Expand 10 after
4927 *context_length = 0; 4951 *context_length = 0;
4928 return previous_; 4952 return previous_;
4929 } 4953 }
4930 4954
4931 4955
4932 #undef __ 4956 #undef __
4933 4957
4934 } } // namespace v8::internal 4958 } } // namespace v8::internal
4935 4959
4936 #endif // V8_TARGET_ARCH_MIPS 4960 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698