Revision: 3213
Author: [email protected]
Date: Wed Nov  4 06:11:39 2009
Log: Emitting the common return sequence in the top-level compiler in one  
function for each platform.

I factored out the code for emitting the return sequence since we had this  
code duplicated in the top-level compiler.

Review URL: http://codereview.chromium.org/354024
http://code.google.com/p/v8/source/detail?r=3213

Modified:
  /branches/bleeding_edge/src/arm/fast-codegen-arm.cc
  /branches/bleeding_edge/src/fast-codegen.h
  /branches/bleeding_edge/src/ia32/fast-codegen-ia32.cc
  /branches/bleeding_edge/src/x64/fast-codegen-x64.cc

=======================================
--- /branches/bleeding_edge/src/arm/fast-codegen-arm.cc Tue Nov  3 08:08:35  
2009
+++ /branches/bleeding_edge/src/arm/fast-codegen-arm.cc Wed Nov  4 06:11:39  
2009
@@ -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());
  }


=======================================
--- /branches/bleeding_edge/src/fast-codegen.h  Tue Nov  3 06:48:59 2009
+++ /branches/bleeding_edge/src/fast-codegen.h  Wed Nov  4 06:11:39 2009
@@ -73,6 +73,10 @@
    Handle<JSFunction> BuildBoilerplate(FunctionLiteral* fun);
    void DeclareGlobals(Handle<FixedArray> pairs);

+  // Platform-specific return sequence
+  void EmitReturnSequence(int position);
+
+  // Platform-specific code sequences for calls
    void EmitCallWithStub(Call* expr);
    void EmitCallWithIC(Call* expr, RelocInfo::Mode reloc_info);

=======================================
--- /branches/bleeding_edge/src/ia32/fast-codegen-ia32.cc       Tue Nov  3  
06:48:59 2009
+++ /branches/bleeding_edge/src/ia32/fast-codegen-ia32.cc       Wed Nov  4  
06:11:39 2009
@@ -91,30 +91,42 @@
    }

    { Comment cmnt(masm_, "[ return <undefined>;");
-    // Emit a 'return undefined' in case control fell off the end of the
-    // body.
+    // Emit a 'return undefined' in case control fell off the end of the  
body.
      __ mov(eax, Factory::undefined_value());
-  }
-  { Comment cmnt(masm_, "[ Return sequence");
-    SetReturnPosition(fun);
-
-    if (return_label_.is_bound()) {
-      __ jmp(&return_label_);
-    } else {
-      // Common return label
-      __ bind(&return_label_);
-
-      if (FLAG_trace) {
-        __ push(eax);
-        __ CallRuntime(Runtime::kTraceExit, 1);
-      }
-      __ RecordJSReturn();
-      // Do not use the leave instruction here because it is too short to
-      // patch with the code required by the debugger.
-      __ mov(esp, ebp);
-      __ pop(ebp);
-      __ ret((fun->scope()->num_parameters() + 1) * kPointerSize);
-    }
+    EmitReturnSequence(function_->end_position());
+  }
+}
+
+
+void FastCodeGenerator::EmitReturnSequence(int position) {
+  Comment cmnt(masm_, "[ Return sequence");
+  if (return_label_.is_bound()) {
+    __ jmp(&return_label_);
+  } else {
+    // Common return label
+    __ bind(&return_label_);
+    if (FLAG_trace) {
+      __ push(eax);
+      __ 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();
+    // Do not use the leave instruction here because it is too short to
+    // patch with the code required by the debugger.
+    __ mov(esp, ebp);
+    __ pop(ebp);
+    __ ret((function_->scope()->num_parameters() + 1) * kPointerSize);
+#ifdef ENABLE_DEBUGGER_SUPPORT
+    // Check that the size of the code used for returning matches what is
+    // expected by the debugger.
+    ASSERT_EQ(Debug::kIa32JSReturnSequenceLength,
+            masm_->SizeOfCodeGeneratedSince(&check_exit_codesize));
+#endif
    }
  }

@@ -270,7 +282,6 @@

  void FastCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
    Comment cmnt(masm_, "[ ReturnStatement");
-  SetStatementPosition(stmt);
    Expression* expr = stmt->expression();
    if (expr->AsLiteral() != NULL) {
      __ mov(eax, expr->AsLiteral()->handle());
@@ -279,25 +290,7 @@
      Visit(expr);
      __ pop(eax);
    }
-
-  if (return_label_.is_bound()) {
-    __ jmp(&return_label_);
-  } else {
-    __ bind(&return_label_);
-
-      if (FLAG_trace) {
-        __ push(eax);
-        __ CallRuntime(Runtime::kTraceExit, 1);
-      }
-
-    __ RecordJSReturn();
-
-    // Do not use the leave instruction here because it is too short to
-    // patch with the code required by the debugger.
-    __ mov(esp, ebp);
-    __ pop(ebp);
-    __ ret((function_->scope()->num_parameters() + 1) * kPointerSize);
-  }
+  EmitReturnSequence(stmt->statement_pos());
  }


=======================================
--- /branches/bleeding_edge/src/x64/fast-codegen-x64.cc Tue Nov  3 06:48:59  
2009
+++ /branches/bleeding_edge/src/x64/fast-codegen-x64.cc Wed Nov  4 06:11:39  
2009
@@ -90,42 +90,50 @@
    }

    { Comment cmnt(masm_, "[ return <undefined>;");
-    // Emit a 'return undefined' in case control fell off the end of the
-    // body.
+    // Emit a 'return undefined' in case control fell off the end of the  
body.
      __ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
-  }
-  { Comment cmnt(masm_, "Return sequence");
-    SetReturnPosition(fun);
-
-    if (return_label_.is_bound()) {
-      __ jmp(&return_label_);
-    } else {
-      __ bind(&return_label_);
-
-      if (FLAG_trace) {
-        __ push(rax);
-        __ CallRuntime(Runtime::kTraceExit, 1);
-      }
-      __ RecordJSReturn();
-
-      // Do not use the leave instruction here because it is too short to
-      // patch with the code required by the debugger.
-      __ movq(rsp, rbp);
-      __ pop(rbp);
-      __ ret((fun->scope()->num_parameters() + 1) * kPointerSize);
-#ifdef ENABLE_DEBUGGER_SUPPORT
-      // Add padding that will be overwritten by a debugger breakpoint.  We
-      // have just generated "movq rsp, rbp; pop rbp; ret k" with length 7
-      // (3 + 1 + 3).
-      const int kPadding = Debug::kX64JSReturnSequenceLength - 7;
-      for (int i = 0; i < kPadding; ++i) {
-        masm_->int3();
-      }
+    EmitReturnSequence(function_->end_position());
+  }
+}
+
+
+void FastCodeGenerator::EmitReturnSequence(int position) {
+  Comment cmnt(masm_, "[ Return sequence");
+  if (return_label_.is_bound()) {
+    __ jmp(&return_label_);
+  } else {
+    __ bind(&return_label_);
+    if (FLAG_trace) {
+      __ push(rax);
+      __ 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();
+    // Do not use the leave instruction here because it is too short to
+    // patch with the code required by the debugger.
+    __ movq(rsp, rbp);
+    __ pop(rbp);
+    __ ret((function_->scope()->num_parameters() + 1) * kPointerSize);
+#ifdef ENABLE_DEBUGGER_SUPPORT
+    // Add padding that will be overwritten by a debugger breakpoint.  We
+    // have just generated "movq rsp, rbp; pop rbp; ret k" with length 7
+    // (3 + 1 + 3).
+    const int kPadding = Debug::kX64JSReturnSequenceLength - 7;
+    for (int i = 0; i < kPadding; ++i) {
+      masm_->int3();
+    }
+    // Check that the size of the code used for returning matches what is
+    // expected by the debugger.
+    ASSERT_EQ(Debug::Debug::kX64JSReturnSequenceLength,
+            masm_->SizeOfCodeGeneratedSince(&check_exit_codesize));
+#endif
    }
  }
-


  void FastCodeGenerator::Move(Expression::Context context, Register source)  
{
@@ -282,7 +290,6 @@

  void FastCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
    Comment cmnt(masm_, "[ ReturnStatement");
-  SetStatementPosition(stmt);
    Expression* expr = stmt->expression();
    if (expr->AsLiteral() != NULL) {
      __ Move(rax, expr->AsLiteral()->handle());
@@ -291,33 +298,7 @@
      ASSERT_EQ(Expression::kValue, expr->context());
      __ pop(rax);
    }
-
-  if (return_label_.is_bound()) {
-    __ jmp(&return_label_);
-  } else {
-    __ bind(&return_label_);
-
-    if (FLAG_trace) {
-      __ push(rax);
-      __ CallRuntime(Runtime::kTraceExit, 1);
-    }
-
-    __ RecordJSReturn();
-    // Do not use the leave instruction here because it is too short to
-    // patch with the code required by the debugger.
-    __ movq(rsp, rbp);
-    __ pop(rbp);
-    __ ret((function_->scope()->num_parameters() + 1) * kPointerSize);
-#ifdef ENABLE_DEBUGGER_SUPPORT
-    // Add padding that will be overwritten by a debugger breakpoint.  We
-    // have just generated "movq rsp, rbp; pop rbp; ret k" with length 7
-    // (3 + 1 + 3).
-    const int kPadding = Debug::kX64JSReturnSequenceLength - 7;
-    for (int i = 0; i < kPadding; ++i) {
-      masm_->int3();
-    }
-#endif
-  }
+  EmitReturnSequence(stmt->statement_pos());
  }



--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---

Reply via email to