Index: src/arm/fast-codegen-arm.cc |
=================================================================== |
--- src/arm/fast-codegen-arm.cc (revision 3211) |
+++ src/arm/fast-codegen-arm.cc (working copy) |
@@ -102,26 +102,51 @@ |
// body. |
__ LoadRoot(r0, Heap::kUndefinedValueRootIndex); |
} |
- { Comment cmnt(masm_, "Return sequence"); |
- if (return_label_.is_bound()) { |
- __ b(&return_label_); |
- } else { |
- __ bind(&return_label_); |
- SetReturnPosition(fun); |
- if (FLAG_trace) { |
- // Push the return value on the stack as the parameter. |
- // Runtime::TraceExit returns its parameter in r0. |
- __ push(r0); |
- __ CallRuntime(Runtime::kTraceExit, 1); |
- } |
- __ RecordJSReturn(); |
- __ mov(sp, fp); |
- __ ldm(ia_w, sp, fp.bit() | lr.bit()); |
- int num_parameters = function_->scope()->num_parameters(); |
- __ add(sp, sp, Operand((num_parameters + 1) * kPointerSize)); |
- __ Jump(lr); |
+ EmitReturnSequence(function_->end_position()); |
+} |
+ |
+ |
+void FastCodeGenerator::EmitReturnSequence(int position) { |
+ Comment cmnt(masm_, "[ Return sequence"); |
+ if (return_label_.is_bound()) { |
+ __ b(&return_label_); |
+ } else { |
+ __ bind(&return_label_); |
+ if (FLAG_trace) { |
+ // Push the return value on the stack as the parameter. |
+ // Runtime::TraceExit returns its parameter in r0. |
+ __ push(r0); |
+ __ CallRuntime(Runtime::kTraceExit, 1); |
} |
+#ifdef DEBUG |
+ // Add a label for checking the size of the code used for returning. |
+ Label check_exit_codesize; |
+ masm_->bind(&check_exit_codesize); |
+#endif |
+ CodeGenerator::RecordPositions(masm_, position); |
+ __ RecordJSReturn(); |
+ __ mov(sp, fp); |
+ __ ldm(ia_w, sp, fp.bit() | lr.bit()); |
+ int num_parameters = function_->scope()->num_parameters(); |
+ __ add(sp, sp, Operand((num_parameters + 1) * kPointerSize)); |
+ __ Jump(lr); |
} |
+#ifdef DEBUG |
+ // Check that the size of the code used for returning matches what is |
+ // expected by the debugger. The add instruction above is an addressing |
+ // mode 1 instruction where there are restrictions on which immediate values |
+ // can be encoded in the instruction and which immediate values requires |
+ // use of an additional instruction for moving the immediate to a temporary |
+ // register. |
+ int expected_return_sequence_length = CodeGenerator::kJSReturnSequenceLength; |
+ if (!masm_->ImmediateFitsAddrMode1Instruction((num_parameters + 1) * |
+ kPointerSize)) { |
+ // Additional mov instruction generated. |
+ expected_return_sequence_length++; |
+ } |
+ ASSERT_EQ(expected_return_sequence_length, |
+ masm_->InstructionsGeneratedSince(&check_exit_codesize)); |
+#endif |
} |
@@ -259,7 +284,6 @@ |
void FastCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { |
Comment cmnt(masm_, "[ ReturnStatement"); |
- SetStatementPosition(stmt); |
Expression* expr = stmt->expression(); |
// Complete the statement based on the type of the subexpression. |
if (expr->AsLiteral() != NULL) { |
@@ -269,21 +293,7 @@ |
Visit(expr); |
__ pop(r0); |
} |
- if (return_label_.is_bound()) { |
- __ b(&return_label_); |
- } else { |
- __ bind(&return_label_); |
- if (FLAG_trace) { |
- __ push(r0); |
- __ CallRuntime(Runtime::kTraceExit, 1); |
- } |
- __ RecordJSReturn(); |
- __ mov(sp, fp); |
- __ ldm(ia_w, sp, fp.bit() | lr.bit()); |
- int num_parameters = function_->scope()->num_parameters(); |
- __ add(sp, sp, Operand((num_parameters + 1) * kPointerSize)); |
- __ Jump(lr); |
- } |
+ EmitReturnSequence(stmt->statement_pos()); |
} |