Refactored the recording of source position in the generated code. The code generator...
authorsgjesse@chromium.org <sgjesse@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 17 Dec 2008 08:45:42 +0000 (08:45 +0000)
committersgjesse@chromium.org <sgjesse@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 17 Dec 2008 08:45:42 +0000 (08:45 +0000)
  void CodeForStatement(Node* node)
  void CodeForSourcePosition(int pos)

The first is used to indicate that code is about to be generated for the given statement and the second is used to indicate that code is about to be generated for the given source position.

Added position information for some statements which was missing whem.

Updated the code generator for ARM to emit source position the same way as for IA-32.

Added an assert to ensure that deferred code stubs will always have a source source position as if it has not it will take whatever source position before which makes no sense.

The passing test on ARM has only been tested using the simulator.
Review URL: http://codereview.chromium.org/14170

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@985 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/assembler-arm.cc
src/assembler-arm.h
src/assembler-ia32.cc
src/assembler-ia32.h
src/codegen-arm.cc
src/codegen-arm.h
src/codegen-ia32.cc
src/codegen-ia32.h
src/codegen.cc
src/parser.cc
test/mjsunit/mjsunit.status

index 21cd22527fd9f33f5f58d459d0bfaab7d68169dc..4e3ae1afc0a509375769046f4929125823249301 100644 (file)
@@ -320,8 +320,10 @@ Assembler::Assembler(void* buffer, int buffer_size) {
   no_const_pool_before_ = 0;
   last_const_pool_end_ = 0;
   last_bound_pos_ = 0;
-  last_position_ = RelocInfo::kNoPosition;
-  last_position_is_statement_ = false;
+  current_statement_position_ = RelocInfo::kNoPosition;
+  current_position_ = RelocInfo::kNoPosition;
+  written_statement_position_ = current_statement_position_;
+  written_position_ = current_position_;
 }
 
 
@@ -1306,20 +1308,36 @@ void Assembler::RecordComment(const char* msg) {
 void Assembler::RecordPosition(int pos) {
   if (pos == RelocInfo::kNoPosition) return;
   ASSERT(pos >= 0);
-  if (pos == last_position_) return;
-  CheckBuffer();
-  RecordRelocInfo(RelocInfo::POSITION, pos);
-  last_position_ = pos;
-  last_position_is_statement_ = false;
+  current_position_ = pos;
+  WriteRecordedPositions();
 }
 
 
 void Assembler::RecordStatementPosition(int pos) {
-  if (pos == last_position_) return;
-  CheckBuffer();
-  RecordRelocInfo(RelocInfo::STATEMENT_POSITION, pos);
-  last_position_ = pos;
-  last_position_is_statement_ = true;
+  if (pos == RelocInfo::kNoPosition) return;
+  ASSERT(pos >= 0);
+  current_statement_position_ = pos;
+  WriteRecordedPositions();
+}
+
+
+void Assembler::WriteRecordedPositions() {
+  // Write the statement position if it is different from what was written last
+  // time.
+  if (current_statement_position_ != written_statement_position_) {
+    CheckBuffer();
+    RecordRelocInfo(RelocInfo::STATEMENT_POSITION, current_statement_position_);
+    written_statement_position_ = current_statement_position_;
+  }
+
+  // Write the position if it is different from what was written last time and
+  // also diferent from the written statement position.
+  if (current_position_ != written_position_ &&
+      current_position_ != written_statement_position_) {
+    CheckBuffer();
+    RecordRelocInfo(RelocInfo::POSITION, current_position_);
+    written_position_ = current_position_;
+  }
 }
 
 
index bd7006608a360832963019a11d380b8f7c4eb7f8..faf402a7f90a5c915e6491ab90849fa2d4b228df 100644 (file)
@@ -643,15 +643,11 @@ class Assembler : public Malloced {
 
   void RecordPosition(int pos);
   void RecordStatementPosition(int pos);
+  void WriteRecordedPositions();
 
   int pc_offset() const { return pc_ - buffer_; }
-  int last_position() const { return last_position_; }
-  bool last_position_is_statement() const {
-    return last_position_is_statement_;
-  }
-
-  // Temporary helper function. Used by codegen.cc.
-  int last_statement_position() const { return last_position_; }
+  int current_position() const { return current_position_; }
+  int current_statement_position() const { return current_position_; }
 
  protected:
   int buffer_space() const { return reloc_info_writer.pos() - pc_; }
@@ -754,8 +750,10 @@ class Assembler : public Malloced {
   int last_bound_pos_;
 
   // source position information
-  int last_position_;
-  bool last_position_is_statement_;
+  int current_position_;
+  int current_statement_position_;
+  int written_position_;
+  int written_statement_position_;
 
   // Code emission
   inline void CheckBuffer();
index 051624bb6067f8a2d2e1f05b729ea46be3506b65..c04fd5758bfb16689850a5a90198af355de0bdb4 100644 (file)
@@ -316,8 +316,10 @@ Assembler::Assembler(void* buffer, int buffer_size) {
   reloc_info_writer.Reposition(buffer_ + buffer_size, pc_);
 
   last_pc_ = NULL;
-  last_position_ = RelocInfo::kNoPosition;
-  last_statement_position_ = RelocInfo::kNoPosition;
+  current_statement_position_ = RelocInfo::kNoPosition;
+  current_position_ = RelocInfo::kNoPosition;
+  written_statement_position_ = current_statement_position_;
+  written_position_ = current_position_;
 }
 
 
@@ -1964,31 +1966,36 @@ void Assembler::RecordComment(const char* msg) {
 
 
 void Assembler::RecordPosition(int pos) {
-  if (pos == RelocInfo::kNoPosition) return;
+  ASSERT(pos != RelocInfo::kNoPosition);
   ASSERT(pos >= 0);
-  last_position_ = pos;
+  current_position_ = pos;
 }
 
 
 void Assembler::RecordStatementPosition(int pos) {
-  if (pos == RelocInfo::kNoPosition) return;
+  ASSERT(pos != RelocInfo::kNoPosition);
   ASSERT(pos >= 0);
-  last_statement_position_ = pos;
+  current_statement_position_ = pos;
 }
 
 
 void Assembler::WriteRecordedPositions() {
-  if (last_statement_position_ != RelocInfo::kNoPosition) {
+  // Write the statement position if it is different from what was written last
+  // time.
+  if (current_statement_position_ != written_statement_position_) {
     EnsureSpace ensure_space(this);
-    RecordRelocInfo(RelocInfo::STATEMENT_POSITION, last_statement_position_);
+    RecordRelocInfo(RelocInfo::STATEMENT_POSITION, current_statement_position_);
+    written_statement_position_ = current_statement_position_;
   }
-  if ((last_position_ != RelocInfo::kNoPosition) &&
-      (last_position_ != last_statement_position_)) {
+
+  // Write the position if it is different from what was written last time and
+  // also diferent from the written statement position.
+  if (current_position_ != written_position_ &&
+      current_position_ != written_statement_position_) {
     EnsureSpace ensure_space(this);
-    RecordRelocInfo(RelocInfo::POSITION, last_position_);
+    RecordRelocInfo(RelocInfo::POSITION, current_position_);
+    written_position_ = current_position_;
   }
-  last_statement_position_ = RelocInfo::kNoPosition;
-  last_position_ = RelocInfo::kNoPosition;
 }
 
 
index 1e2f45dbf66f19fac028951d039be72127af9cdb..7db218ef41a671f5d312c46895f44f0f4e1541e5 100644 (file)
@@ -712,8 +712,8 @@ class Assembler : public Malloced {
   void WriteInternalReference(int position, const Label& bound_label);
 
   int pc_offset() const  { return pc_ - buffer_; }
-  int last_statement_position() const  { return last_statement_position_; }
-  int last_position() const  { return last_position_; }
+  int current_statement_position() const { return current_statement_position_; }
+  int current_position() const  { return current_position_; }
 
   // Check if there is less than kGap bytes available in the buffer.
   // If this is the case, we need to grow the buffer before emitting
@@ -800,8 +800,10 @@ class Assembler : public Malloced {
   byte* last_pc_;
 
   // source position information
-  int last_position_;
-  int last_statement_position_;
+  int current_statement_position_;
+  int current_position_;
+  int written_statement_position_;
+  int written_position_;
 };
 
 
index 712a98925c5a1b1c0be4adf9060edfa0f11eb92e..fa2541a6860bf8892e111b51faebb2119aec23b0 100644 (file)
@@ -1043,7 +1043,7 @@ void CodeGenerator::CallWithArguments(ZoneList<Expression*>* args,
   }
 
   // Record the position for debugging purposes.
-  __ RecordPosition(position);
+  CodeForSourcePosition(position);
 
   // Use the shared code stub to call the function.
   CallFunctionStub call_function(args->length());
@@ -1074,7 +1074,7 @@ void CodeGenerator::CheckStack() {
 
 void CodeGenerator::VisitBlock(Block* node) {
   Comment cmnt(masm_, "[ Block");
-  if (FLAG_debug_info) RecordStatementPosition(node);
+  CodeForStatement(node);
   node->set_break_stack_height(break_stack_height_);
   VisitStatements(node->statements());
   __ bind(node->break_target());
@@ -1094,6 +1094,7 @@ void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
 
 void CodeGenerator::VisitDeclaration(Declaration* node) {
   Comment cmnt(masm_, "[ Declaration");
+  CodeForStatement(node);
   Variable* var = node->proxy()->var();
   ASSERT(var != NULL);  // must have been resolved
   Slot* slot = var->slot();
@@ -1159,7 +1160,7 @@ void CodeGenerator::VisitDeclaration(Declaration* node) {
 
 void CodeGenerator::VisitExpressionStatement(ExpressionStatement* node) {
   Comment cmnt(masm_, "[ ExpressionStatement");
-  if (FLAG_debug_info) RecordStatementPosition(node);
+  CodeForStatement(node);
   Expression* expression = node->expression();
   expression->MarkAsStatement();
   Load(expression);
@@ -1169,6 +1170,7 @@ void CodeGenerator::VisitExpressionStatement(ExpressionStatement* node) {
 
 void CodeGenerator::VisitEmptyStatement(EmptyStatement* node) {
   Comment cmnt(masm_, "// EmptyStatement");
+  CodeForStatement(node);
   // nothing to do
 }
 
@@ -1180,7 +1182,7 @@ void CodeGenerator::VisitIfStatement(IfStatement* node) {
   bool has_then_stm = node->HasThenStatement();
   bool has_else_stm = node->HasElseStatement();
 
-  if (FLAG_debug_info) RecordStatementPosition(node);
+  CodeForStatement(node);
 
   Label exit;
   if (has_then_stm && has_else_stm) {
@@ -1245,7 +1247,7 @@ void CodeGenerator::CleanStack(int num_bytes) {
 
 void CodeGenerator::VisitContinueStatement(ContinueStatement* node) {
   Comment cmnt(masm_, "[ ContinueStatement");
-  if (FLAG_debug_info) RecordStatementPosition(node);
+  CodeForStatement(node);
   CleanStack(break_stack_height_ - node->target()->break_stack_height());
   __ b(node->target()->continue_target());
 }
@@ -1253,7 +1255,7 @@ void CodeGenerator::VisitContinueStatement(ContinueStatement* node) {
 
 void CodeGenerator::VisitBreakStatement(BreakStatement* node) {
   Comment cmnt(masm_, "[ BreakStatement");
-  if (FLAG_debug_info) RecordStatementPosition(node);
+  CodeForStatement(node);
   CleanStack(break_stack_height_ - node->target()->break_stack_height());
   __ b(node->target()->break_target());
 }
@@ -1261,7 +1263,7 @@ void CodeGenerator::VisitBreakStatement(BreakStatement* node) {
 
 void CodeGenerator::VisitReturnStatement(ReturnStatement* node) {
   Comment cmnt(masm_, "[ ReturnStatement");
-  if (FLAG_debug_info) RecordStatementPosition(node);
+  CodeForStatement(node);
   Load(node->expression());
   // Move the function result into r0.
   frame_->Pop(r0);
@@ -1272,7 +1274,7 @@ void CodeGenerator::VisitReturnStatement(ReturnStatement* node) {
 
 void CodeGenerator::VisitWithEnterStatement(WithEnterStatement* node) {
   Comment cmnt(masm_, "[ WithEnterStatement");
-  if (FLAG_debug_info) RecordStatementPosition(node);
+  CodeForStatement(node);
   Load(node->expression());
   __ CallRuntime(Runtime::kPushContext, 1);
   if (kDebug) {
@@ -1289,6 +1291,7 @@ void CodeGenerator::VisitWithEnterStatement(WithEnterStatement* node) {
 
 void CodeGenerator::VisitWithExitStatement(WithExitStatement* node) {
   Comment cmnt(masm_, "[ WithExitStatement");
+  CodeForStatement(node);
   // Pop context.
   __ ldr(cp, ContextOperand(cp, Context::PREVIOUS_INDEX));
   // Update context local.
@@ -1355,7 +1358,7 @@ void CodeGenerator::GenerateFastCaseSwitchJumpTable(
 
 void CodeGenerator::VisitSwitchStatement(SwitchStatement* node) {
   Comment cmnt(masm_, "[ SwitchStatement");
-  if (FLAG_debug_info) RecordStatementPosition(node);
+  CodeForStatement(node);
   node->set_break_stack_height(break_stack_height_);
 
   Load(node->tag());
@@ -1423,7 +1426,7 @@ void CodeGenerator::VisitSwitchStatement(SwitchStatement* node) {
 
 void CodeGenerator::VisitLoopStatement(LoopStatement* node) {
   Comment cmnt(masm_, "[ LoopStatement");
-  if (FLAG_debug_info) RecordStatementPosition(node);
+  CodeForStatement(node);
   node->set_break_stack_height(break_stack_height_);
 
   // simple condition analysis
@@ -1463,7 +1466,7 @@ void CodeGenerator::VisitLoopStatement(LoopStatement* node) {
     // Record source position of the statement as this code which is after the
     // code for the body actually belongs to the loop statement and not the
     // body.
-    if (FLAG_debug_info) __ RecordPosition(node->statement_pos());
+    CodeForStatement(node);
     ASSERT(node->type() == LoopStatement::FOR_LOOP);
     Visit(node->next());
   }
@@ -1495,7 +1498,7 @@ void CodeGenerator::VisitLoopStatement(LoopStatement* node) {
 
 void CodeGenerator::VisitForInStatement(ForInStatement* node) {
   Comment cmnt(masm_, "[ ForInStatement");
-  if (FLAG_debug_info) RecordStatementPosition(node);
+  CodeForStatement(node);
 
   // We keep stuff on the stack while the body is executing.
   // Record it, so that a break/continue crossing this statement
@@ -1683,6 +1686,7 @@ void CodeGenerator::VisitForInStatement(ForInStatement* node) {
 
 void CodeGenerator::VisitTryCatch(TryCatch* node) {
   Comment cmnt(masm_, "[ TryCatch");
+  CodeForStatement(node);
 
   Label try_block, exit;
 
@@ -1779,6 +1783,7 @@ void CodeGenerator::VisitTryCatch(TryCatch* node) {
 
 void CodeGenerator::VisitTryFinally(TryFinally* node) {
   Comment cmnt(masm_, "[ TryFinally");
+  CodeForStatement(node);
 
   // State: Used to keep track of reason for entering the finally
   // block. Should probably be extended to hold information for
@@ -1920,7 +1925,7 @@ void CodeGenerator::VisitTryFinally(TryFinally* node) {
 
 void CodeGenerator::VisitDebuggerStatement(DebuggerStatement* node) {
   Comment cmnt(masm_, "[ DebuggerStatament");
-  if (FLAG_debug_info) RecordStatementPosition(node);
+  CodeForStatement(node);
   __ CallRuntime(Runtime::kDebugBreak, 0);
   // Ignore the return value.
 }
@@ -2228,7 +2233,7 @@ void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) {
 
 void CodeGenerator::VisitAssignment(Assignment* node) {
   Comment cmnt(masm_, "[ Assignment");
-  if (FLAG_debug_info) RecordStatementPosition(node);
+  CodeForStatement(node);
 
   Reference target(this, node->target());
   if (target.is_illegal()) return;
@@ -2259,7 +2264,7 @@ void CodeGenerator::VisitAssignment(Assignment* node) {
     // Assignment ignored - leave the value on the stack.
 
   } else {
-    __ RecordPosition(node->position());
+    CodeForSourcePosition(node->position());
     if (node->op() == Token::INIT_CONST) {
       // Dynamic constant initializations must use the function context
       // and initialize the actual constant declared. Dynamic variable
@@ -2276,7 +2281,7 @@ void CodeGenerator::VisitThrow(Throw* node) {
   Comment cmnt(masm_, "[ Throw");
 
   Load(node->exception());
-  __ RecordPosition(node->position());
+  CodeForSourcePosition(node->position());
   __ CallRuntime(Runtime::kThrow, 1);
   frame_->Push(r0);
 }
@@ -2295,7 +2300,7 @@ void CodeGenerator::VisitCall(Call* node) {
 
   ZoneList<Expression*>* args = node->arguments();
 
-  RecordStatementPosition(node);
+  CodeForStatement(node);
   // Standard function call.
 
   // Check if the function is a variable or a property.
@@ -2331,7 +2336,7 @@ void CodeGenerator::VisitCall(Call* node) {
 
     // Setup the receiver register and call the IC initialization code.
     Handle<Code> stub = ComputeCallInitialize(args->length());
-    __ RecordPosition(node->position());
+    CodeForSourcePosition(node->position());
     __ Call(stub, RelocInfo::CODE_TARGET_CONTEXT);
     __ ldr(cp, frame_->Context());
     // Remove the function from the stack.
@@ -2378,7 +2383,7 @@ void CodeGenerator::VisitCall(Call* node) {
 
       // Set the receiver register and call the IC initialization code.
       Handle<Code> stub = ComputeCallInitialize(args->length());
-      __ RecordPosition(node->position());
+      CodeForSourcePosition(node->position());
       __ Call(stub, RelocInfo::CODE_TARGET);
       __ ldr(cp, frame_->Context());
 
@@ -2432,7 +2437,7 @@ void CodeGenerator::VisitCallEval(CallEval* node) {
   ZoneList<Expression*>* args = node->arguments();
   Expression* function = node->expression();
 
-  RecordStatementPosition(node);
+  CodeForStatement(node);
 
   // Prepare stack for call to resolved function.
   Load(function);
@@ -2462,7 +2467,7 @@ void CodeGenerator::VisitCallEval(CallEval* node) {
   __ str(r1, MemOperand(sp, args->length() * kPointerSize));
 
   // Call the function.
-  __ RecordPosition(node->position());
+  CodeForSourcePosition(node->position());
 
   CallFunctionStub call_function(args->length());
   __ CallStub(&call_function);
@@ -2476,6 +2481,7 @@ void CodeGenerator::VisitCallEval(CallEval* node) {
 
 void CodeGenerator::VisitCallNew(CallNew* node) {
   Comment cmnt(masm_, "[ CallNew");
+  CodeForStatement(node);
 
   // According to ECMA-262, section 11.2.2, page 44, the function
   // expression in new calls must be evaluated before the
@@ -2501,7 +2507,7 @@ void CodeGenerator::VisitCallNew(CallNew* node) {
 
   // Call the construct call builtin that handles allocation and
   // constructor invocation.
-  __ RecordPosition(RelocInfo::POSITION);
+  CodeForSourcePosition(node->position());
   __ Call(Handle<Code>(Builtins::builtin(Builtins::JSConstructCall)),
           RelocInfo::CONSTRUCT_CALL);
 
@@ -3207,15 +3213,6 @@ void CodeGenerator::VisitCompareOperation(CompareOperation* node) {
 }
 
 
-void CodeGenerator::RecordStatementPosition(Node* node) {
-  if (FLAG_debug_info) {
-    int statement_pos = node->statement_pos();
-    if (statement_pos == RelocInfo::kNoPosition) return;
-    __ RecordStatementPosition(statement_pos);
-  }
-}
-
-
 #undef __
 #define __ masm->
 
@@ -3243,7 +3240,7 @@ void Reference::GetValue(TypeofState typeof_state) {
   VirtualFrame* frame = cgen_->frame();
   Property* property = expression_->AsProperty();
   if (property != NULL) {
-    __ RecordPosition(property->position());
+    cgen_->CodeForSourcePosition(property->position());
   }
 
   switch (type_) {
@@ -3309,7 +3306,7 @@ void Reference::SetValue(InitState init_state) {
   VirtualFrame* frame = cgen_->frame();
   Property* property = expression_->AsProperty();
   if (property != NULL) {
-    __ RecordPosition(property->position());
+    cgen_->CodeForSourcePosition(property->position());
   }
 
   switch (type_) {
@@ -3412,7 +3409,7 @@ void Reference::SetValue(InitState init_state) {
       Comment cmnt(masm, "[ Store to keyed Property");
       Property* property = expression_->AsProperty();
       ASSERT(property != NULL);
-      __ RecordPosition(property->position());
+      cgen_->CodeForSourcePosition(property->position());
 
       // Call IC code.
       Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
index 904a3b71e1ba0cd61822178ffb9134c43b4414fe..42a05eca6f5edebcefcb0fa1cbffcfe65d7b2b20 100644 (file)
@@ -376,10 +376,11 @@ class CodeGenerator: public AstVisitor {
   bool TryGenerateFastCaseSwitchStatement(SwitchStatement* node);
 
 
-  // Bottle-neck interface to call the Assembler to generate the statement
-  // position. This allows us to easily control whether statement positions
-  // should be generated or not.
-  void RecordStatementPosition(Node* node);
+  // Methods used to indicate which source code is generated for. Source
+  // positions are collected by the assembler and emitted with the relocation
+  // information.
+  void CodeForStatement(Node* node);
+  void CodeForSourcePosition(int pos);
 
   bool is_eval_;  // Tells whether code is generated for eval.
   Handle<Script> script_;
index 82fe877f87f31d685a11361f4180fd90dadbea16..cb8345119f8b25118a0c5d5195998441d6bf1334 100644 (file)
@@ -186,7 +186,7 @@ CodeGenerator::CodeGenerator(int buffer_size, Handle<Script> script,
 
 void CodeGenerator::GenCode(FunctionLiteral* fun) {
   // Record the position for debugging purposes.
-  __ RecordPosition(fun->start_position());
+  CodeForSourcePosition(fun->start_position());
 
   ZoneList<Statement*>* body = fun->body();
 
@@ -1322,14 +1322,14 @@ class CallFunctionStub: public CodeStub {
 // Call the function just below TOS on the stack with the given
 // arguments. The receiver is the TOS.
 void CodeGenerator::CallWithArguments(ZoneList<Expression*>* args,
-                                          int position) {
+                                      int position) {
   // Push the arguments ("left-to-right") on the stack.
   for (int i = 0; i < args->length(); i++) {
     Load(args->at(i));
   }
 
   // Record the position for debugging purposes.
-  __ RecordPosition(position);
+  CodeForSourcePosition(position);
 
   // Use the shared code stub to call the function.
   CallFunctionStub call_function(args->length());
@@ -1365,7 +1365,7 @@ void CodeGenerator::CheckStack() {
 
 void CodeGenerator::VisitBlock(Block* node) {
   Comment cmnt(masm_, "[ Block");
-  RecordStatementPosition(node);
+  CodeForStatement(node);
   node->set_break_stack_height(break_stack_height_);
   VisitStatements(node->statements());
   __ bind(node->break_target());
@@ -1383,6 +1383,7 @@ void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
 
 void CodeGenerator::VisitDeclaration(Declaration* node) {
   Comment cmnt(masm_, "[ Declaration");
+  CodeForStatement(node);
   Variable* var = node->proxy()->var();
   ASSERT(var != NULL);  // must have been resolved
   Slot* slot = var->slot();
@@ -1444,7 +1445,7 @@ void CodeGenerator::VisitDeclaration(Declaration* node) {
 
 void CodeGenerator::VisitExpressionStatement(ExpressionStatement* node) {
   Comment cmnt(masm_, "[ ExpressionStatement");
-  RecordStatementPosition(node);
+  CodeForStatement(node);
   Expression* expression = node->expression();
   expression->MarkAsStatement();
   Load(expression);
@@ -1455,6 +1456,7 @@ void CodeGenerator::VisitExpressionStatement(ExpressionStatement* node) {
 
 void CodeGenerator::VisitEmptyStatement(EmptyStatement* node) {
   Comment cmnt(masm_, "// EmptyStatement");
+  CodeForStatement(node);
   // nothing to do
 }
 
@@ -1466,7 +1468,7 @@ void CodeGenerator::VisitIfStatement(IfStatement* node) {
   bool has_then_stm = node->HasThenStatement();
   bool has_else_stm = node->HasElseStatement();
 
-  RecordStatementPosition(node);
+  CodeForStatement(node);
   Label exit;
   if (has_then_stm && has_else_stm) {
     Label then;
@@ -1528,7 +1530,7 @@ void CodeGenerator::CleanStack(int num_bytes) {
 
 void CodeGenerator::VisitContinueStatement(ContinueStatement* node) {
   Comment cmnt(masm_, "[ ContinueStatement");
-  RecordStatementPosition(node);
+  CodeForStatement(node);
   CleanStack(break_stack_height_ - node->target()->break_stack_height());
   __ jmp(node->target()->continue_target());
 }
@@ -1536,7 +1538,7 @@ void CodeGenerator::VisitContinueStatement(ContinueStatement* node) {
 
 void CodeGenerator::VisitBreakStatement(BreakStatement* node) {
   Comment cmnt(masm_, "[ BreakStatement");
-  RecordStatementPosition(node);
+  CodeForStatement(node);
   CleanStack(break_stack_height_ - node->target()->break_stack_height());
   __ jmp(node->target()->break_target());
 }
@@ -1544,7 +1546,7 @@ void CodeGenerator::VisitBreakStatement(BreakStatement* node) {
 
 void CodeGenerator::VisitReturnStatement(ReturnStatement* node) {
   Comment cmnt(masm_, "[ ReturnStatement");
-  RecordStatementPosition(node);
+  CodeForStatement(node);
   Load(node->expression());
 
   // Move the function result into eax
@@ -1582,7 +1584,7 @@ void CodeGenerator::VisitReturnStatement(ReturnStatement* node) {
 
 void CodeGenerator::VisitWithEnterStatement(WithEnterStatement* node) {
   Comment cmnt(masm_, "[ WithEnterStatement");
-  RecordStatementPosition(node);
+  CodeForStatement(node);
   Load(node->expression());
   __ CallRuntime(Runtime::kPushContext, 1);
 
@@ -1602,6 +1604,7 @@ void CodeGenerator::VisitWithEnterStatement(WithEnterStatement* node) {
 
 void CodeGenerator::VisitWithExitStatement(WithExitStatement* node) {
   Comment cmnt(masm_, "[ WithExitStatement");
+  CodeForStatement(node);
   // Pop context.
   __ mov(esi, ContextOperand(esi, Context::PREVIOUS_INDEX));
   // Update context local.
@@ -1684,7 +1687,7 @@ void CodeGenerator::GenerateFastCaseSwitchJumpTable(
 
 void CodeGenerator::VisitSwitchStatement(SwitchStatement* node) {
   Comment cmnt(masm_, "[ SwitchStatement");
-  RecordStatementPosition(node);
+  CodeForStatement(node);
   node->set_break_stack_height(break_stack_height_);
 
   Load(node->tag());
@@ -1751,7 +1754,7 @@ void CodeGenerator::VisitSwitchStatement(SwitchStatement* node) {
 
 void CodeGenerator::VisitLoopStatement(LoopStatement* node) {
   Comment cmnt(masm_, "[ LoopStatement");
-  RecordStatementPosition(node);
+  CodeForStatement(node);
   node->set_break_stack_height(break_stack_height_);
 
   // simple condition analysis
@@ -1794,8 +1797,7 @@ void CodeGenerator::VisitLoopStatement(LoopStatement* node) {
     // Record source position of the statement as this code which is after the
     // code for the body actually belongs to the loop statement and not the
     // body.
-    RecordStatementPosition(node);
-    __ RecordPosition(node->statement_pos());
+    CodeForStatement(node);
     ASSERT(node->type() == LoopStatement::FOR_LOOP);
     Visit(node->next());
   }
@@ -1824,7 +1826,7 @@ void CodeGenerator::VisitLoopStatement(LoopStatement* node) {
 
 void CodeGenerator::VisitForInStatement(ForInStatement* node) {
   Comment cmnt(masm_, "[ ForInStatement");
-  RecordStatementPosition(node);
+  CodeForStatement(node);
 
   // We keep stuff on the stack while the body is executing.
   // Record it, so that a break/continue crossing this statement
@@ -2012,6 +2014,7 @@ void CodeGenerator::VisitForInStatement(ForInStatement* node) {
 
 void CodeGenerator::VisitTryCatch(TryCatch* node) {
   Comment cmnt(masm_, "[ TryCatch");
+  CodeForStatement(node);
 
   Label try_block, exit;
 
@@ -2116,6 +2119,7 @@ void CodeGenerator::VisitTryCatch(TryCatch* node) {
 
 void CodeGenerator::VisitTryFinally(TryFinally* node) {
   Comment cmnt(masm_, "[ TryFinally");
+  CodeForStatement(node);
 
   // State: Used to keep track of reason for entering the finally
   // block. Should probably be extended to hold information for
@@ -2252,7 +2256,7 @@ void CodeGenerator::VisitTryFinally(TryFinally* node) {
 
 void CodeGenerator::VisitDebuggerStatement(DebuggerStatement* node) {
   Comment cmnt(masm_, "[ DebuggerStatement");
-  RecordStatementPosition(node);
+  CodeForStatement(node);
   __ CallRuntime(Runtime::kDebugBreak, 0);
   // Ignore the return value.
 }
@@ -2608,8 +2612,8 @@ bool CodeGenerator::IsInlineSmi(Literal* literal) {
 
 void CodeGenerator::VisitAssignment(Assignment* node) {
   Comment cmnt(masm_, "[ Assignment");
+  CodeForStatement(node);
 
-  RecordStatementPosition(node);
   Reference target(this, node->target());
   if (target.is_illegal()) return;
 
@@ -2636,7 +2640,7 @@ void CodeGenerator::VisitAssignment(Assignment* node) {
       node->op() != Token::INIT_VAR && node->op() != Token::INIT_CONST) {
     // Assignment ignored - leave the value on the stack.
   } else {
-    __ RecordPosition(node->position());
+    CodeForSourcePosition(node->position());
     if (node->op() == Token::INIT_CONST) {
       // Dynamic constant initializations must use the function context
       // and initialize the actual constant declared. Dynamic variable
@@ -2651,9 +2655,9 @@ void CodeGenerator::VisitAssignment(Assignment* node) {
 
 void CodeGenerator::VisitThrow(Throw* node) {
   Comment cmnt(masm_, "[ Throw");
+  CodeForStatement(node);
 
   Load(node->exception());
-  __ RecordPosition(node->position());
   __ CallRuntime(Runtime::kThrow, 1);
   frame_->Push(eax);
 }
@@ -2672,7 +2676,7 @@ void CodeGenerator::VisitCall(Call* node) {
 
   ZoneList<Expression*>* args = node->arguments();
 
-  RecordStatementPosition(node);
+  CodeForStatement(node);
 
   // Check if the function is a variable or a property.
   Expression* function = node->expression();
@@ -2709,7 +2713,7 @@ void CodeGenerator::VisitCall(Call* node) {
     Handle<Code> stub = (loop_nesting() > 0)
         ? ComputeCallInitializeInLoop(args->length())
         : ComputeCallInitialize(args->length());
-    __ RecordPosition(node->position());
+    CodeForSourcePosition(node->position());
     __ call(stub, RelocInfo::CODE_TARGET_CONTEXT);
     __ mov(esi, frame_->Context());
 
@@ -2755,7 +2759,7 @@ void CodeGenerator::VisitCall(Call* node) {
       Handle<Code> stub = (loop_nesting() > 0)
         ? ComputeCallInitializeInLoop(args->length())
         : ComputeCallInitialize(args->length());
-      __ RecordPosition(node->position());
+      CodeForSourcePosition(node->position());
       __ call(stub, RelocInfo::CODE_TARGET);
       __ mov(esi, frame_->Context());
 
@@ -2798,6 +2802,7 @@ void CodeGenerator::VisitCall(Call* node) {
 
 void CodeGenerator::VisitCallNew(CallNew* node) {
   Comment cmnt(masm_, "[ CallNew");
+  CodeForStatement(node);
 
   // According to ECMA-262, section 11.2.2, page 44, the function
   // expression in new calls must be evaluated before the
@@ -2826,7 +2831,7 @@ void CodeGenerator::VisitCallNew(CallNew* node) {
 
   // Call the construct call builtin that handles allocation and
   // constructor invocation.
-  __ RecordPosition(node->position());
+  CodeForSourcePosition(node->position());
   __ call(Handle<Code>(Builtins::builtin(Builtins::JSConstructCall)),
           RelocInfo::CONSTRUCT_CALL);
   // Discard the function and "push" the newly created object.
@@ -2844,7 +2849,7 @@ void CodeGenerator::VisitCallEval(CallEval* node) {
   ZoneList<Expression*>* args = node->arguments();
   Expression* function = node->expression();
 
-  RecordStatementPosition(node);
+  CodeForStatement(node);
 
   // Prepare stack for call to resolved function.
   Load(function);
@@ -2871,7 +2876,7 @@ void CodeGenerator::VisitCallEval(CallEval* node) {
   __ mov(Operand(esp, args->length() * kPointerSize), edx);
 
   // Call the function.
-  __ RecordPosition(node->position());
+  CodeForSourcePosition(node->position());
 
   CallFunctionStub call_function(args->length());
   __ CallStub(&call_function);
@@ -3769,16 +3774,6 @@ void CodeGenerator::VisitCompareOperation(CompareOperation* node) {
 }
 
 
-void CodeGenerator::RecordStatementPosition(Node* node) {
-  if (FLAG_debug_info) {
-    int pos = node->statement_pos();
-    if (pos != RelocInfo::kNoPosition) {
-      __ RecordStatementPosition(pos);
-    }
-  }
-}
-
-
 #undef __
 #define __ masm->
 
@@ -3792,8 +3787,6 @@ Handle<String> Reference::GetName() {
     ASSERT(proxy->AsVariable()->is_global());
     return proxy->name();
   } else {
-    MacroAssembler* masm = cgen_->masm();
-    __ RecordPosition(property->position());
     Literal* raw_name = property->key()->AsLiteral();
     ASSERT(raw_name != NULL);
     return Handle<String>(String::cast(*raw_name->handle()));
@@ -3844,7 +3837,6 @@ void Reference::GetValue(TypeofState typeof_state) {
       Comment cmnt(masm, "[ Load from keyed Property");
       Property* property = expression_->AsProperty();
       ASSERT(property != NULL);
-      __ RecordPosition(property->position());
       Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
 
       Variable* var = expression_->AsVariableProxy()->AsVariable();
@@ -3963,7 +3955,6 @@ void Reference::SetValue(InitState init_state) {
       Comment cmnt(masm, "[ Store to keyed Property");
       Property* property = expression_->AsProperty();
       ASSERT(property != NULL);
-      __ RecordPosition(property->position());
       // Call IC code.
       Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
       // TODO(1222589): Make the IC grab the values from the stack.
index a1525c70edcff9ec64b7dd86b8bac1890bc9c5dc..3289fa58e3f2410208829ecde47e3afcd49620cb 100644 (file)
@@ -400,11 +400,11 @@ class CodeGenerator: public AstVisitor {
   // Returns true if the fast-case switch was generated, and false if not.
   bool TryGenerateFastCaseSwitchStatement(SwitchStatement* node);
 
-
-  // Bottle-neck interface to call the Assembler to generate the statement
-  // position. This allows us to easily control whether statement positions
-  // should be generated or not.
-  void RecordStatementPosition(Node* node);
+  // Methods used to indicate which source code is generated for. Source
+  // positions are collected by the assembler and emitted with the relocation
+  // information.
+  void CodeForStatement(Node* node);
+  void CodeForSourcePosition(int pos);
 
   bool is_eval_;  // Tells whether code is generated for eval.
   Handle<Script> script_;
index 4df51e71af0f482d27831e9a539b4e1984a1b85b..f340c0c2f6b13c92c1932c0ee33e4b3ad5bbb68e 100644 (file)
@@ -40,9 +40,11 @@ namespace v8 { namespace internal {
 DeferredCode::DeferredCode(CodeGenerator* generator)
   : masm_(generator->masm()),
     generator_(generator),
-    statement_position_(masm_->last_statement_position()),
-    position_(masm_->last_position()) {
+    statement_position_(masm_->current_statement_position()),
+    position_(masm_->current_position()) {
   generator->AddDeferred(this);
+  ASSERT(statement_position_ != RelocInfo::kNoPosition);
+  ASSERT(position_ != RelocInfo::kNoPosition);
 #ifdef DEBUG
   comment_ = "";
 #endif
@@ -54,9 +56,7 @@ void CodeGenerator::ProcessDeferred() {
     DeferredCode* code = deferred_.RemoveLast();
     MacroAssembler* masm = code->masm();
     // Record position of deferred code stub.
-    if (code->statement_position() != RelocInfo::kNoPosition) {
-      masm->RecordStatementPosition(code->statement_position());
-    }
+    masm->RecordStatementPosition(code->statement_position());
     if (code->position() != RelocInfo::kNoPosition) {
       masm->RecordPosition(code->position());
     }
@@ -464,6 +464,26 @@ bool CodeGenerator::TryGenerateFastCaseSwitchStatement(SwitchStatement* node) {
 }
 
 
+void CodeGenerator::CodeForStatement(Node* node) {
+  if (FLAG_debug_info) {
+    int pos = node->statement_pos();
+    if (pos != RelocInfo::kNoPosition) {
+      masm()->RecordStatementPosition(pos);
+      CodeForSourcePosition(pos);
+    }
+  }
+}
+
+
+void CodeGenerator::CodeForSourcePosition(int pos) {
+  if (FLAG_debug_info) {
+    if (pos != RelocInfo::kNoPosition) {
+      masm()->RecordPosition(pos);
+    }
+  }
+}
+
+
 const char* RuntimeStub::GetName() {
   return Runtime::FunctionForId(id_)->stub_name;
 }
index 6c91618587494b6ffe39e15fc6fa2b90657e4004..bc7a78fb258e8dd5dcb1427045b744f32d259b26 100644 (file)
@@ -1320,6 +1320,9 @@ Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) {
       Block* result = NEW(Block(labels, 1, false));
       Target target(this, result);
       TryStatement* statement = ParseTryStatement(CHECK_OK);
+      if (statement) {
+        statement->set_statement_pos(statement_pos);
+      }
       if (result) result->AddStatement(statement);
       return result;
     }
index 6483b4542eadb415574edb30712f1daac6efbee6..e030878f80dade58c8a2a22750722b3dc25293d3 100644 (file)
@@ -47,7 +47,6 @@ debug-scripts-request: PASS, SKIP if $mode == debug
 # Bug number 1020483: Debug tests fail on ARM.
 debug-constructor: CRASH, FAIL
 debug-continue: SKIP
-debug-backtrace: FAIL
 debug-evaluate-recursive: CRASH, FAIL if $mode == debug
 debug-changebreakpoint: CRASH, FAIL if $mode == debug
 debug-clearbreakpoint: CRASH, FAIL if $mode == debug