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_;
}
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_;
+ }
}
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_; }
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();
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_;
}
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;
}
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
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_;
};
}
// Record the position for debugging purposes.
- __ RecordPosition(position);
+ CodeForSourcePosition(position);
// Use the shared code stub to call the function.
CallFunctionStub call_function(args->length());
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());
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();
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);
void CodeGenerator::VisitEmptyStatement(EmptyStatement* node) {
Comment cmnt(masm_, "// EmptyStatement");
+ CodeForStatement(node);
// nothing to do
}
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) {
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());
}
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());
}
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);
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) {
void CodeGenerator::VisitWithExitStatement(WithExitStatement* node) {
Comment cmnt(masm_, "[ WithExitStatement");
+ CodeForStatement(node);
// Pop context.
__ ldr(cp, ContextOperand(cp, Context::PREVIOUS_INDEX));
// Update context local.
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());
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
// 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());
}
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
void CodeGenerator::VisitTryCatch(TryCatch* node) {
Comment cmnt(masm_, "[ TryCatch");
+ CodeForStatement(node);
Label try_block, exit;
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
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.
}
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;
// 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
Comment cmnt(masm_, "[ Throw");
Load(node->exception());
- __ RecordPosition(node->position());
+ CodeForSourcePosition(node->position());
__ CallRuntime(Runtime::kThrow, 1);
frame_->Push(r0);
}
ZoneList<Expression*>* args = node->arguments();
- RecordStatementPosition(node);
+ CodeForStatement(node);
// Standard function call.
// Check if the function is a variable or a property.
// 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.
// 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());
ZoneList<Expression*>* args = node->arguments();
Expression* function = node->expression();
- RecordStatementPosition(node);
+ CodeForStatement(node);
// Prepare stack for call to resolved function.
Load(function);
__ str(r1, MemOperand(sp, args->length() * kPointerSize));
// Call the function.
- __ RecordPosition(node->position());
+ CodeForSourcePosition(node->position());
CallFunctionStub call_function(args->length());
__ CallStub(&call_function);
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
// 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);
}
-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->
VirtualFrame* frame = cgen_->frame();
Property* property = expression_->AsProperty();
if (property != NULL) {
- __ RecordPosition(property->position());
+ cgen_->CodeForSourcePosition(property->position());
}
switch (type_) {
VirtualFrame* frame = cgen_->frame();
Property* property = expression_->AsProperty();
if (property != NULL) {
- __ RecordPosition(property->position());
+ cgen_->CodeForSourcePosition(property->position());
}
switch (type_) {
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));
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_;
void CodeGenerator::GenCode(FunctionLiteral* fun) {
// Record the position for debugging purposes.
- __ RecordPosition(fun->start_position());
+ CodeForSourcePosition(fun->start_position());
ZoneList<Statement*>* body = fun->body();
// 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());
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());
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();
void CodeGenerator::VisitExpressionStatement(ExpressionStatement* node) {
Comment cmnt(masm_, "[ ExpressionStatement");
- RecordStatementPosition(node);
+ CodeForStatement(node);
Expression* expression = node->expression();
expression->MarkAsStatement();
Load(expression);
void CodeGenerator::VisitEmptyStatement(EmptyStatement* node) {
Comment cmnt(masm_, "// EmptyStatement");
+ CodeForStatement(node);
// nothing to do
}
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;
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());
}
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());
}
void CodeGenerator::VisitReturnStatement(ReturnStatement* node) {
Comment cmnt(masm_, "[ ReturnStatement");
- RecordStatementPosition(node);
+ CodeForStatement(node);
Load(node->expression());
// Move the function result into eax
void CodeGenerator::VisitWithEnterStatement(WithEnterStatement* node) {
Comment cmnt(masm_, "[ WithEnterStatement");
- RecordStatementPosition(node);
+ CodeForStatement(node);
Load(node->expression());
__ CallRuntime(Runtime::kPushContext, 1);
void CodeGenerator::VisitWithExitStatement(WithExitStatement* node) {
Comment cmnt(masm_, "[ WithExitStatement");
+ CodeForStatement(node);
// Pop context.
__ mov(esi, ContextOperand(esi, Context::PREVIOUS_INDEX));
// Update context local.
void CodeGenerator::VisitSwitchStatement(SwitchStatement* node) {
Comment cmnt(masm_, "[ SwitchStatement");
- RecordStatementPosition(node);
+ CodeForStatement(node);
node->set_break_stack_height(break_stack_height_);
Load(node->tag());
void CodeGenerator::VisitLoopStatement(LoopStatement* node) {
Comment cmnt(masm_, "[ LoopStatement");
- RecordStatementPosition(node);
+ CodeForStatement(node);
node->set_break_stack_height(break_stack_height_);
// simple condition analysis
// 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());
}
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
void CodeGenerator::VisitTryCatch(TryCatch* node) {
Comment cmnt(masm_, "[ TryCatch");
+ CodeForStatement(node);
Label try_block, exit;
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
void CodeGenerator::VisitDebuggerStatement(DebuggerStatement* node) {
Comment cmnt(masm_, "[ DebuggerStatement");
- RecordStatementPosition(node);
+ CodeForStatement(node);
__ CallRuntime(Runtime::kDebugBreak, 0);
// Ignore the return value.
}
void CodeGenerator::VisitAssignment(Assignment* node) {
Comment cmnt(masm_, "[ Assignment");
+ CodeForStatement(node);
- RecordStatementPosition(node);
Reference target(this, node->target());
if (target.is_illegal()) return;
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
void CodeGenerator::VisitThrow(Throw* node) {
Comment cmnt(masm_, "[ Throw");
+ CodeForStatement(node);
Load(node->exception());
- __ RecordPosition(node->position());
__ CallRuntime(Runtime::kThrow, 1);
frame_->Push(eax);
}
ZoneList<Expression*>* args = node->arguments();
- RecordStatementPosition(node);
+ CodeForStatement(node);
// Check if the function is a variable or a property.
Expression* function = node->expression();
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());
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());
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
// 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.
ZoneList<Expression*>* args = node->arguments();
Expression* function = node->expression();
- RecordStatementPosition(node);
+ CodeForStatement(node);
// Prepare stack for call to resolved function.
Load(function);
__ mov(Operand(esp, args->length() * kPointerSize), edx);
// Call the function.
- __ RecordPosition(node->position());
+ CodeForSourcePosition(node->position());
CallFunctionStub call_function(args->length());
__ CallStub(&call_function);
}
-void CodeGenerator::RecordStatementPosition(Node* node) {
- if (FLAG_debug_info) {
- int pos = node->statement_pos();
- if (pos != RelocInfo::kNoPosition) {
- __ RecordStatementPosition(pos);
- }
- }
-}
-
-
#undef __
#define __ masm->
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()));
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();
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.
// 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_;
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
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());
}
}
+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;
}
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;
}
# 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