Debugger: use debug break slots instead of ICs (except for calls).

BUG=v8:3147,v8:4269
LOG=N

Review URL: https://codereview.chromium.org/1218493005

Cr-Commit-Position: refs/heads/master@{#29487}
This commit is contained in:
yangguo 2015-07-06 04:15:52 -07:00 committed by Commit bot
parent ef661b0804
commit a8a4c364c2
30 changed files with 378 additions and 1243 deletions

View File

@ -140,50 +140,6 @@ void DebugCodegen::GenerateCallICStubDebugBreak(MacroAssembler* masm) {
}
void DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) {
// Calling convention for IC load (from ic-arm.cc).
Register receiver = LoadDescriptor::ReceiverRegister();
Register name = LoadDescriptor::NameRegister();
Register slot = LoadDescriptor::SlotRegister();
RegList regs = receiver.bit() | name.bit() | slot.bit();
Generate_DebugBreakCallHelper(masm, regs, 0);
}
void DebugCodegen::GenerateStoreICDebugBreak(MacroAssembler* masm) {
// Calling convention for IC store (from ic-arm.cc).
Register receiver = StoreDescriptor::ReceiverRegister();
Register name = StoreDescriptor::NameRegister();
Register value = StoreDescriptor::ValueRegister();
RegList regs = receiver.bit() | name.bit() | value.bit();
if (FLAG_vector_stores) {
regs |= VectorStoreICDescriptor::SlotRegister().bit();
}
Generate_DebugBreakCallHelper(masm, regs, 0);
}
void DebugCodegen::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) {
// Calling convention for keyed IC load (from ic-arm.cc).
GenerateLoadICDebugBreak(masm);
}
void DebugCodegen::GenerateKeyedStoreICDebugBreak(MacroAssembler* masm) {
// Calling convention for IC keyed store call (from ic-arm.cc).
GenerateStoreICDebugBreak(masm);
}
void DebugCodegen::GenerateCompareNilICDebugBreak(MacroAssembler* masm) {
// Register state for CompareNil IC
// ----------- S t a t e -------------
// -- r0 : value
// -----------------------------------
Generate_DebugBreakCallHelper(masm, r0.bit(), 0);
}
void DebugCodegen::GenerateReturnDebugBreak(MacroAssembler* masm) {
// In places other than IC call sites it is expected that r0 is TOS which
// is an object - this is not generally the case so this should be used with

View File

@ -508,7 +508,7 @@ void FullCodeGenerator::EmitReturnSequence() {
{ Assembler::BlockConstPoolScope block_const_pool(masm_);
int32_t arg_count = info_->scope()->num_parameters() + 1;
int32_t sp_delta = arg_count * kPointerSize;
CodeGenerator::RecordPositions(masm_, function()->end_position() - 1);
SetReturnPosition(function());
// TODO(svenpanne) The code below is sometimes 4 words, sometimes 5!
PredictableCodeSizeScope predictable(masm_, -1);
__ RecordJSReturn();
@ -1080,7 +1080,7 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
}
// Record position before stub call for type feedback.
SetSourcePosition(clause->position());
SetExpressionPosition(clause);
Handle<Code> ic = CodeFactory::CompareIC(isolate(), Token::EQ_STRICT,
strength(language_mode())).code();
CallIC(ic, clause->CompareId());
@ -1128,8 +1128,9 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
Comment cmnt(masm_, "[ ForInStatement");
SetStatementPosition(stmt, SKIP_BREAK);
FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
SetStatementPosition(stmt);
Label loop, exit;
ForIn loop_statement(this, stmt);
@ -1137,7 +1138,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
// Get the object to enumerate over. If the object is null or undefined, skip
// over the loop. See ECMA-262 version 5, section 12.6.4.
SetExpressionPosition(stmt->enumerable());
SetExpressionAsStatementPosition(stmt->enumerable());
VisitForAccumulatorValue(stmt->enumerable());
__ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
__ cmp(r0, ip);
@ -1241,7 +1242,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
// Generate code for doing the condition check.
PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS);
__ bind(&loop);
SetExpressionPosition(stmt->each());
SetExpressionAsStatementPosition(stmt->each());
// Load the current count to r0, load the length to r1.
__ Ldrd(r0, r1, MemOperand(sp, 0 * kPointerSize));
@ -1491,7 +1492,7 @@ void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
// Record position before possible IC call.
SetSourcePosition(proxy->position());
SetExpressionPosition(proxy);
PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS);
Variable* var = proxy->var();
@ -1986,6 +1987,7 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
DCHECK(expr->target()->IsValidReferenceExpression());
Comment cmnt(masm_, "[ Assignment");
SetExpressionPosition(expr, INSERT_BREAK);
Property* property = expr->target()->AsProperty();
LhsKind assign_type = Property::GetAssignType(property);
@ -2079,7 +2081,6 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
__ push(r0); // Left operand goes on the stack.
VisitForAccumulatorValue(expr->value());
SetSourcePosition(expr->position() + 1);
AccumulatorValueContext context(this);
if (ShouldInlineSmiCase(op)) {
EmitInlineSmiBinaryOp(expr->binary_operation(),
@ -2096,8 +2097,7 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
VisitForAccumulatorValue(expr->value());
}
// Record source position before possible IC call.
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
// Store the value.
switch (assign_type) {
@ -2127,6 +2127,8 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
void FullCodeGenerator::VisitYield(Yield* expr) {
Comment cmnt(masm_, "[ Yield");
SetExpressionPosition(expr);
// Evaluate yielded value first; the initial iterator definition depends on
// this. It stays on the stack while we update the iterator.
VisitForStackValue(expr->expression());
@ -2422,7 +2424,7 @@ void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
SetExpressionPosition(prop);
Literal* key = prop->key()->AsLiteral();
DCHECK(!prop->IsSuperAccess());
@ -2435,7 +2437,7 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
// Stack: receiver, home_object.
SetSourcePosition(prop->position());
SetExpressionPosition(prop);
Literal* key = prop->key()->AsLiteral();
DCHECK(!key->value()->IsSmi());
DCHECK(prop->IsSuperAccess());
@ -2447,7 +2449,7 @@ void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
SetExpressionPosition(prop);
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code();
__ mov(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
@ -2457,9 +2459,8 @@ void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
// Stack: receiver, home_object, key.
SetExpressionPosition(prop);
__ Push(Smi::FromInt(language_mode()));
SetSourcePosition(prop->position());
__ CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
}
@ -2832,8 +2833,6 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
DCHECK(prop != NULL);
DCHECK(prop->key()->IsLiteral());
// Record source code position before IC call.
SetSourcePosition(expr->position());
__ mov(StoreDescriptor::NameRegister(),
Operand(prop->key()->AsLiteral()->value()));
__ pop(StoreDescriptor::ReceiverRegister());
@ -2881,9 +2880,6 @@ void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) {
void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
// Assignment to a property, using a keyed store IC.
// Record source code position before IC call.
SetSourcePosition(expr->position());
__ Pop(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister());
DCHECK(StoreDescriptor::ValueRegister().is(r0));
@ -2903,6 +2899,8 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
void FullCodeGenerator::VisitProperty(Property* expr) {
Comment cmnt(masm_, "[ Property");
SetExpressionPosition(expr);
Expression* key = expr->key();
if (key->IsPropertyName()) {
@ -2985,8 +2983,8 @@ void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
DCHECK(callee->IsProperty());
Property* prop = callee->AsProperty();
DCHECK(prop->IsSuperAccess());
SetExpressionPosition(prop);
SetSourcePosition(prop->position());
Literal* key = prop->key()->AsLiteral();
DCHECK(!key->value()->IsSmi());
// Load the function from the receiver.
@ -3050,7 +3048,7 @@ void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
Property* prop = callee->AsProperty();
DCHECK(prop->IsSuperAccess());
SetSourcePosition(prop->position());
SetExpressionPosition(prop);
// Load the function from the receiver.
const Register scratch = r1;
SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference();
@ -3086,14 +3084,11 @@ void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
// Load the arguments.
ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length();
{ PreservePositionScope scope(masm()->positions_recorder());
for (int i = 0; i < arg_count; i++) {
VisitForStackValue(args->at(i));
}
for (int i = 0; i < arg_count; i++) {
VisitForStackValue(args->at(i));
}
// Record source position of the IC call.
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code();
__ mov(r3, Operand(SmiFromSlot(expr->CallFeedbackICSlot())));
__ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
@ -3152,13 +3147,10 @@ void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
VariableProxy* callee = expr->expression()->AsVariableProxy();
if (callee->var()->IsLookupSlot()) {
Label slow, done;
SetSourcePosition(callee->position());
{
PreservePositionScope scope(masm()->positions_recorder());
// Generate code for loading from variables potentially shadowed
// by eval-introduced variables.
EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
}
SetExpressionPosition(callee);
// Generate code for loading from variables potentially shadowed
// by eval-introduced variables.
EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
__ bind(&slow);
// Call the runtime to find the function to call (returned in r0)
@ -3212,28 +3204,26 @@ void FullCodeGenerator::VisitCall(Call* expr) {
ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length();
{ PreservePositionScope pos_scope(masm()->positions_recorder());
PushCalleeAndWithBaseObject(expr);
PushCalleeAndWithBaseObject(expr);
// Push the arguments.
for (int i = 0; i < arg_count; i++) {
VisitForStackValue(args->at(i));
}
// Push a copy of the function (found below the arguments) and
// resolve eval.
__ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
__ push(r1);
EmitResolvePossiblyDirectEval(arg_count);
// Touch up the stack with the resolved function.
__ str(r0, MemOperand(sp, (arg_count + 1) * kPointerSize));
PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
// Push the arguments.
for (int i = 0; i < arg_count; i++) {
VisitForStackValue(args->at(i));
}
// Push a copy of the function (found below the arguments) and
// resolve eval.
__ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
__ push(r1);
EmitResolvePossiblyDirectEval(arg_count);
// Touch up the stack with the resolved function.
__ str(r0, MemOperand(sp, (arg_count + 1) * kPointerSize));
PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
// Record source position for debugger.
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
__ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
__ CallStub(&stub);
@ -3258,10 +3248,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
EmitKeyedSuperCallWithLoadIC(expr);
}
} else {
{
PreservePositionScope scope(masm()->positions_recorder());
VisitForStackValue(property->obj());
}
if (is_named_call) {
EmitCallWithLoadIC(expr);
} else {
@ -3273,9 +3260,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
} else {
DCHECK(call_type == Call::OTHER_CALL);
// Call to an arbitrary expression not handled specially above.
{ PreservePositionScope scope(masm()->positions_recorder());
VisitForStackValue(callee);
}
VisitForStackValue(callee);
__ LoadRoot(r1, Heap::kUndefinedValueRootIndex);
__ push(r1);
// Emit function call.
@ -3310,7 +3295,7 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
// Call the construct call builtin that handles allocation and
// constructor invocation.
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
// Load function and argument count into r1 and r0.
__ mov(r0, Operand(arg_count));
@ -3353,7 +3338,7 @@ void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
// Call the construct call builtin that handles allocation and
// constructor invocation.
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
// Load function and argument count into r1 and r0.
__ mov(r0, Operand(arg_count));
@ -4732,8 +4717,7 @@ void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length();
// Record source position of the IC call.
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
__ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
__ CallStub(&stub);
@ -4911,7 +4895,6 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
DCHECK(expr->expression()->IsValidReferenceExpression());
Comment cmnt(masm_, "[ CountOperation");
SetSourcePosition(expr->position());
Property* prop = expr->expression()->AsProperty();
LhsKind assign_type = Property::GetAssignType(prop);
@ -5067,8 +5050,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
__ mov(r1, r0);
__ mov(r0, Operand(Smi::FromInt(count_value)));
// Record position before stub call.
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), Token::ADD,
strength(language_mode())).code();
@ -5284,7 +5266,7 @@ void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
Comment cmnt(masm_, "[ CompareOperation");
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
// First we try a fast inlined version of the compare when one of
// the operands is a literal.
@ -5338,8 +5320,6 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
__ bind(&slow_case);
}
// Record position and call the compare IC.
SetSourcePosition(expr->position());
Handle<Code> ic = CodeFactory::CompareIC(
isolate(), op, strength(language_mode())).code();
CallIC(ic, expr->CompareOperationFeedbackId());

View File

@ -203,50 +203,6 @@ void DebugCodegen::GenerateCallICStubDebugBreak(MacroAssembler* masm) {
}
void DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) {
// Calling convention for IC load (from ic-arm.cc).
Register receiver = LoadDescriptor::ReceiverRegister();
Register name = LoadDescriptor::NameRegister();
Register slot = LoadDescriptor::SlotRegister();
RegList regs = receiver.Bit() | name.Bit() | slot.Bit();
Generate_DebugBreakCallHelper(masm, regs, 0, x10);
}
void DebugCodegen::GenerateStoreICDebugBreak(MacroAssembler* masm) {
// Calling convention for IC store (from ic-arm64.cc).
Register receiver = StoreDescriptor::ReceiverRegister();
Register name = StoreDescriptor::NameRegister();
Register value = StoreDescriptor::ValueRegister();
RegList regs = receiver.Bit() | name.Bit() | value.Bit();
if (FLAG_vector_stores) {
regs |= VectorStoreICDescriptor::SlotRegister().Bit();
}
Generate_DebugBreakCallHelper(masm, regs, 0, x10);
}
void DebugCodegen::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) {
// Calling convention for keyed IC load (from ic-arm.cc).
GenerateLoadICDebugBreak(masm);
}
void DebugCodegen::GenerateKeyedStoreICDebugBreak(MacroAssembler* masm) {
// Calling convention for IC keyed store call (from ic-arm64.cc).
GenerateStoreICDebugBreak(masm);
}
void DebugCodegen::GenerateCompareNilICDebugBreak(MacroAssembler* masm) {
// Register state for CompareNil IC
// ----------- S t a t e -------------
// -- r0 : value
// -----------------------------------
Generate_DebugBreakCallHelper(masm, x0.Bit(), 0, x10);
}
void DebugCodegen::GenerateReturnDebugBreak(MacroAssembler* masm) {
// In places other than IC call sites it is expected that r0 is TOS which
// is an object - this is not generally the case so this should be used with

View File

@ -498,7 +498,7 @@ void FullCodeGenerator::EmitReturnSequence() {
{
InstructionAccurateScope scope(masm_,
Assembler::kJSReturnSequenceInstructions);
CodeGenerator::RecordPositions(masm_, function()->end_position() - 1);
SetReturnPosition(function());
__ RecordJSReturn();
// This code is generated using Assembler methods rather than Macro
// Assembler methods because it will be patched later on, and so the size
@ -1080,7 +1080,7 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
}
// Record position before stub call for type feedback.
SetSourcePosition(clause->position());
SetExpressionPosition(clause);
Handle<Code> ic = CodeFactory::CompareIC(isolate(), Token::EQ_STRICT,
strength(language_mode())).code();
CallIC(ic, clause->CompareId());
@ -1126,9 +1126,11 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
ASM_LOCATION("FullCodeGenerator::VisitForInStatement");
Comment cmnt(masm_, "[ ForInStatement");
SetStatementPosition(stmt, SKIP_BREAK);
FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
// TODO(all): This visitor probably needs better comments and a revisit.
SetStatementPosition(stmt);
Label loop, exit;
ForIn loop_statement(this, stmt);
@ -1136,7 +1138,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
// Get the object to enumerate over. If the object is null or undefined, skip
// over the loop. See ECMA-262 version 5, section 12.6.4.
SetExpressionPosition(stmt->enumerable());
SetExpressionAsStatementPosition(stmt->enumerable());
VisitForAccumulatorValue(stmt->enumerable());
__ JumpIfRoot(x0, Heap::kUndefinedValueRootIndex, &exit);
Register null_value = x15;
@ -1230,7 +1232,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
// Generate code for doing the condition check.
PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS);
__ Bind(&loop);
SetExpressionPosition(stmt->each());
SetExpressionAsStatementPosition(stmt->each());
// Load the current count to x0, load the length to x1.
__ PeekPair(x0, x1, 0);
@ -1469,7 +1471,7 @@ void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
// Record position before possible IC call.
SetSourcePosition(proxy->position());
SetExpressionPosition(proxy);
PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS);
Variable* var = proxy->var();
@ -1959,6 +1961,7 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
DCHECK(expr->target()->IsValidReferenceExpression());
Comment cmnt(masm_, "[ Assignment");
SetExpressionPosition(expr, INSERT_BREAK);
Property* property = expr->target()->AsProperty();
LhsKind assign_type = Property::GetAssignType(property);
@ -2049,7 +2052,6 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
__ Push(x0); // Left operand goes on the stack.
VisitForAccumulatorValue(expr->value());
SetSourcePosition(expr->position() + 1);
AccumulatorValueContext context(this);
if (ShouldInlineSmiCase(op)) {
EmitInlineSmiBinaryOp(expr->binary_operation(),
@ -2066,8 +2068,7 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
VisitForAccumulatorValue(expr->value());
}
// Record source position before possible IC call.
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
// Store the value.
switch (assign_type) {
@ -2096,7 +2097,7 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
SetExpressionPosition(prop);
Literal* key = prop->key()->AsLiteral();
DCHECK(!prop->IsSuperAccess());
@ -2109,7 +2110,7 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
// Stack: receiver, home_object.
SetSourcePosition(prop->position());
SetExpressionPosition(prop);
Literal* key = prop->key()->AsLiteral();
DCHECK(!key->value()->IsSmi());
DCHECK(prop->IsSuperAccess());
@ -2121,7 +2122,7 @@ void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
SetExpressionPosition(prop);
// Call keyed load IC. It has arguments key and receiver in x0 and x1.
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code();
__ Mov(LoadDescriptor::SlotRegister(),
@ -2132,9 +2133,8 @@ void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
// Stack: receiver, home_object, key.
SetExpressionPosition(prop);
__ Push(Smi::FromInt(language_mode()));
SetSourcePosition(prop->position());
__ CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
}
@ -2518,8 +2518,6 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
DCHECK(prop != NULL);
DCHECK(prop->key()->IsLiteral());
// Record source code position before IC call.
SetSourcePosition(expr->position());
__ Mov(StoreDescriptor::NameRegister(),
Operand(prop->key()->AsLiteral()->value()));
__ Pop(StoreDescriptor::ReceiverRegister());
@ -2569,8 +2567,6 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
ASM_LOCATION("FullCodeGenerator::EmitKeyedPropertyAssignment");
// Assignment to a property, using a keyed store IC.
// Record source code position before IC call.
SetSourcePosition(expr->position());
// TODO(all): Could we pass this in registers rather than on the stack?
__ Pop(StoreDescriptor::NameRegister(), StoreDescriptor::ReceiverRegister());
DCHECK(StoreDescriptor::ValueRegister().is(x0));
@ -2591,6 +2587,7 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
void FullCodeGenerator::VisitProperty(Property* expr) {
Comment cmnt(masm_, "[ Property");
SetExpressionPosition(expr);
Expression* key = expr->key();
if (key->IsPropertyName()) {
@ -2675,8 +2672,8 @@ void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
DCHECK(callee->IsProperty());
Property* prop = callee->AsProperty();
DCHECK(prop->IsSuperAccess());
SetExpressionPosition(prop);
SetSourcePosition(prop->position());
Literal* key = prop->key()->AsLiteral();
DCHECK(!key->value()->IsSmi());
@ -2738,8 +2735,7 @@ void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
DCHECK(callee->IsProperty());
Property* prop = callee->AsProperty();
DCHECK(prop->IsSuperAccess());
SetSourcePosition(prop->position());
SetExpressionPosition(prop);
// Load the function from the receiver.
const Register scratch = x10;
@ -2776,13 +2772,10 @@ void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
// Load the arguments.
ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length();
{ PreservePositionScope scope(masm()->positions_recorder());
for (int i = 0; i < arg_count; i++) {
VisitForStackValue(args->at(i));
}
}
// Record source position of the IC call.
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code();
__ Mov(x3, SmiFromSlot(expr->CallFeedbackICSlot()));
@ -2843,13 +2836,10 @@ void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
VariableProxy* callee = expr->expression()->AsVariableProxy();
if (callee->var()->IsLookupSlot()) {
Label slow, done;
SetSourcePosition(callee->position());
{
PreservePositionScope scope(masm()->positions_recorder());
SetExpressionPosition(callee);
// Generate code for loading from variables potentially shadowed
// by eval-introduced variables.
EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
}
__ Bind(&slow);
// Call the runtime to find the function to call (returned in x0)
@ -2901,8 +2891,6 @@ void FullCodeGenerator::VisitCall(Call* expr) {
ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length();
{
PreservePositionScope pos_scope(masm()->positions_recorder());
PushCalleeAndWithBaseObject(expr);
// Push the arguments.
@ -2920,10 +2908,9 @@ void FullCodeGenerator::VisitCall(Call* expr) {
__ Poke(x0, (arg_count + 1) * kPointerSize);
PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
}
// Record source position for debugger.
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
// Call the evaluated function.
CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
@ -2951,10 +2938,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
EmitKeyedSuperCallWithLoadIC(expr);
}
} else {
{
PreservePositionScope scope(masm()->positions_recorder());
VisitForStackValue(property->obj());
}
if (is_named_call) {
EmitCallWithLoadIC(expr);
} else {
@ -2966,9 +2950,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
} else {
DCHECK(call_type == Call::OTHER_CALL);
// Call to an arbitrary expression not handled specially above.
{ PreservePositionScope scope(masm()->positions_recorder());
VisitForStackValue(callee);
}
__ LoadRoot(x1, Heap::kUndefinedValueRootIndex);
__ Push(x1);
// Emit function call.
@ -3003,7 +2985,7 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
// Call the construct call builtin that handles allocation and
// constructor invocation.
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
// Load function and argument count into x1 and x0.
__ Mov(x0, arg_count);
@ -3046,7 +3028,7 @@ void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
// Call the construct call builtin that handles allocation and
// constructor invocation.
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
// Load function and argument count into x1 and x0.
__ Mov(x0, arg_count);
@ -4426,8 +4408,7 @@ void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length();
// Record source position of the IC call.
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
__ Peek(x1, (arg_count + 1) * kPointerSize);
__ CallStub(&stub);
@ -4602,7 +4583,6 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
DCHECK(expr->expression()->IsValidReferenceExpression());
Comment cmnt(masm_, "[ CountOperation");
SetSourcePosition(expr->position());
Property* prop = expr->expression()->AsProperty();
LhsKind assign_type = Property::GetAssignType(prop);
@ -4753,8 +4733,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
__ Mov(x1, x0);
__ Mov(x0, Smi::FromInt(count_value));
// Record position before stub call.
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
{
Assembler::BlockPoolsScope scope(masm_);
@ -4981,7 +4960,7 @@ void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
Comment cmnt(masm_, "[ CompareOperation");
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
// Try to generate an optimized comparison with a literal value.
// TODO(jbramley): This only checks common values like NaN or undefined.
@ -5036,8 +5015,6 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
__ Bind(&slow_case);
}
// Record position and call the compare IC.
SetSourcePosition(expr->position());
Handle<Code> ic = CodeFactory::CompareIC(
isolate(), op, strength(language_mode())).code();
CallIC(ic, expr->CompareOperationFeedbackId());
@ -5091,6 +5068,8 @@ void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) {
void FullCodeGenerator::VisitYield(Yield* expr) {
Comment cmnt(masm_, "[ Yield");
SetExpressionPosition(expr);
// Evaluate yielded value first; the initial iterator definition depends on
// this. It stays on the stack while we update the iterator.
VisitForStackValue(expr->expression());

View File

@ -1617,20 +1617,19 @@ bool PositionsRecorder::WriteRecordedPositions() {
EnsureSpace ensure_space(assembler_);
assembler_->RecordRelocInfo(RelocInfo::STATEMENT_POSITION,
state_.current_statement_position);
state_.written_position = state_.current_statement_position;
state_.written_statement_position = state_.current_statement_position;
written = true;
}
state_.written_statement_position = state_.current_statement_position;
// Write the position if it is different from what was written last time and
// also different from the statement position that was just written.
if (state_.current_position != state_.written_position &&
(state_.current_position != state_.written_statement_position ||
!written)) {
if (state_.current_position != state_.written_position) {
EnsureSpace ensure_space(assembler_);
assembler_->RecordRelocInfo(RelocInfo::POSITION, state_.current_position);
state_.written_position = state_.current_position;
written = true;
}
state_.written_position = state_.current_position;
// Return whether something was written.
return written;
@ -1869,7 +1868,6 @@ void Assembler::RecordJSReturn() {
void Assembler::RecordDebugBreakSlot() {
positions_recorder()->WriteRecordedPositions();
EnsureSpace ensure_space(this);
RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT);
}

View File

@ -1085,34 +1085,11 @@ class PositionsRecorder BASE_EMBEDDED {
// Currently jit_handler_data_ is used to store JITHandler-specific data
// over the lifetime of a PositionsRecorder
void* jit_handler_data_;
friend class PreservePositionScope;
DISALLOW_COPY_AND_ASSIGN(PositionsRecorder);
};
class PreservePositionScope BASE_EMBEDDED {
public:
explicit PreservePositionScope(PositionsRecorder* positions_recorder)
: positions_recorder_(positions_recorder),
saved_state_(positions_recorder->state_) {
// Reset positions so that previous ones do not accidentally get
// recorded within this scope.
positions_recorder->state_ = PositionState();
}
~PreservePositionScope() {
positions_recorder_->state_ = saved_state_;
}
private:
PositionsRecorder* positions_recorder_;
const PositionState saved_state_;
DISALLOW_COPY_AND_ASSIGN(PreservePositionScope);
};
// -----------------------------------------------------------------------------
// Utility functions

View File

@ -1374,31 +1374,6 @@ static void Generate_CallICStub_DebugBreak(MacroAssembler* masm) {
}
static void Generate_LoadIC_DebugBreak(MacroAssembler* masm) {
DebugCodegen::GenerateLoadICDebugBreak(masm);
}
static void Generate_StoreIC_DebugBreak(MacroAssembler* masm) {
DebugCodegen::GenerateStoreICDebugBreak(masm);
}
static void Generate_KeyedLoadIC_DebugBreak(MacroAssembler* masm) {
DebugCodegen::GenerateKeyedLoadICDebugBreak(masm);
}
static void Generate_KeyedStoreIC_DebugBreak(MacroAssembler* masm) {
DebugCodegen::GenerateKeyedStoreICDebugBreak(masm);
}
static void Generate_CompareNilIC_DebugBreak(MacroAssembler* masm) {
DebugCodegen::GenerateCompareNilICDebugBreak(masm);
}
static void Generate_Return_DebugBreak(MacroAssembler* masm) {
DebugCodegen::GenerateReturnDebugBreak(masm);
}

View File

@ -151,16 +151,6 @@ enum BuiltinExtraArguments {
DEBUG_BREAK) \
V(CallICStub_DebugBreak, CALL_IC, DEBUG_STUB, \
DEBUG_BREAK) \
V(LoadIC_DebugBreak, LOAD_IC, DEBUG_STUB, \
DEBUG_BREAK) \
V(KeyedLoadIC_DebugBreak, KEYED_LOAD_IC, DEBUG_STUB, \
DEBUG_BREAK) \
V(StoreIC_DebugBreak, STORE_IC, DEBUG_STUB, \
DEBUG_BREAK) \
V(KeyedStoreIC_DebugBreak, KEYED_STORE_IC, DEBUG_STUB, \
DEBUG_BREAK) \
V(CompareNilIC_DebugBreak, COMPARE_NIL_IC, DEBUG_STUB, \
DEBUG_BREAK) \
V(Slot_DebugBreak, BUILTIN, DEBUG_STUB, \
DEBUG_BREAK) \
V(PlainReturn_LiveEdit, BUILTIN, DEBUG_STUB, \

View File

@ -239,19 +239,5 @@ void CodeGenerator::PrintCode(Handle<Code> code, CompilationInfo* info) {
#endif // ENABLE_DISASSEMBLER
}
bool CodeGenerator::RecordPositions(MacroAssembler* masm,
int pos,
bool right_here) {
if (pos != RelocInfo::kNoPosition) {
masm->positions_recorder()->RecordStatementPosition(pos);
masm->positions_recorder()->RecordPosition(pos);
if (right_here) {
return masm->positions_recorder()->WriteRecordedPositions();
}
}
return false;
}
} // namespace internal
} // namespace v8

View File

@ -84,10 +84,6 @@ class CodeGenerator {
// Print the code after compiling it.
static void PrintCode(Handle<Code> code, CompilationInfo* info);
static bool RecordPositions(MacroAssembler* masm,
int pos,
bool right_here = false);
private:
DISALLOW_COPY_AND_ASSIGN(CodeGenerator);
};

View File

@ -84,8 +84,7 @@ BreakLocation::Iterator::Iterator(Handle<DebugInfo> debug_info,
~RelocInfo::ModeMask(RelocInfo::CODE_AGE_SEQUENCE)),
break_index_(-1),
position_(1),
statement_position_(1),
has_immediate_position_(false) {
statement_position_(1) {
Next();
}
@ -115,7 +114,6 @@ void BreakLocation::Iterator::Next() {
debug_info_->shared()->start_position());
DCHECK(position_ >= 0);
DCHECK(statement_position_ >= 0);
has_immediate_position_ = true;
continue;
}
@ -145,25 +143,19 @@ void BreakLocation::Iterator::Next() {
break;
}
// Skip below if we only want locations for calls and returns.
if (type_ == CALLS_AND_RETURNS) continue;
// Only break at an inline cache if it has an immediate position attached.
if (has_immediate_position_ &&
(code->is_inline_cache_stub() && !code->is_binary_op_stub() &&
!code->is_compare_ic_stub() && !code->is_to_boolean_ic_stub())) {
if (code->kind() == Code::STUB &&
CodeStub::GetMajorKey(code) == CodeStub::CallFunction) {
break_index_++;
break;
}
if (code->kind() == Code::STUB) {
if (RelocInfo::IsDebuggerStatement(rmode())) {
break_index_++;
break;
} else if (CodeStub::GetMajorKey(code) == CodeStub::CallFunction) {
break_index_++;
break;
}
}
}
// Skip below if we only want locations for calls and returns.
if (type_ == CALLS_AND_RETURNS) continue;
if (RelocInfo::IsDebuggerStatement(rmode())) {
break_index_++;
break;
}
if (RelocInfo::IsDebugBreakSlot(rmode()) && type_ != CALLS_AND_RETURNS) {
@ -172,7 +164,6 @@ void BreakLocation::Iterator::Next() {
break;
}
}
has_immediate_position_ = false;
}
@ -385,28 +376,8 @@ static Handle<Code> DebugBreakForIC(Handle<Code> code, RelocInfo::Mode mode) {
// Find the builtin debug break function matching the calling convention
// used by the call site.
if (code->is_inline_cache_stub()) {
switch (code->kind()) {
case Code::CALL_IC:
return isolate->builtins()->CallICStub_DebugBreak();
case Code::LOAD_IC:
return isolate->builtins()->LoadIC_DebugBreak();
case Code::STORE_IC:
return isolate->builtins()->StoreIC_DebugBreak();
case Code::KEYED_LOAD_IC:
return isolate->builtins()->KeyedLoadIC_DebugBreak();
case Code::KEYED_STORE_IC:
return isolate->builtins()->KeyedStoreIC_DebugBreak();
case Code::COMPARE_NIL_IC:
return isolate->builtins()->CompareNilIC_DebugBreak();
default:
UNREACHABLE();
}
DCHECK(code->kind() == Code::CALL_IC);
return isolate->builtins()->CallICStub_DebugBreak();
}
if (RelocInfo::IsConstructCall(mode)) {
if (code->has_function_cache()) {
@ -1258,8 +1229,6 @@ void Debug::PrepareStep(StepAction step_action,
Handle<DebugInfo> debug_info = GetDebugInfo(shared);
// Compute whether or not the target is a call target.
bool is_load_or_store = false;
bool is_inline_cache_stub = false;
bool is_at_restarted_function = false;
Handle<Code> call_function_stub;
@ -1272,8 +1241,6 @@ void Debug::PrepareStep(StepAction step_action,
if (thread_local_.restarter_frame_function_pointer_ == NULL) {
if (location.IsCodeTarget()) {
Handle<Code> target_code = location.CodeTarget();
is_inline_cache_stub = target_code->is_inline_cache_stub();
is_load_or_store = is_inline_cache_stub && !target_code->is_call_stub();
// Check if target code is CallFunction stub.
Handle<Code> maybe_call_function_stub = target_code;
@ -1320,21 +1287,10 @@ void Debug::PrepareStep(StepAction step_action,
// Set target frame pointer.
ActivateStepOut(frames_it.frame());
}
} else if (!(is_inline_cache_stub || location.IsConstructCall() ||
!call_function_stub.is_null() || is_at_restarted_function) ||
step_action == StepNext || step_action == StepMin) {
// Step next or step min.
return;
}
// Fill the current function with one-shot break points.
// If we are stepping into another frame, only fill calls and returns.
FloodWithOneShot(function, step_action == StepFrame ? CALLS_AND_RETURNS
: ALL_BREAK_LOCATIONS);
// Remember source position and frame to handle step next.
thread_local_.last_statement_position_ =
debug_info->code()->SourceStatementPosition(summary.pc());
thread_local_.last_fp_ = frame->UnpaddedFP();
} else {
if (step_action != StepNext && step_action != StepMin) {
// If there's restarter frame on top of the stack, just get the pointer
// to function which is going to be restarted.
if (is_at_restarted_function) {
@ -1395,36 +1351,21 @@ void Debug::PrepareStep(StepAction step_action,
}
}
// Fill the current function with one-shot break points even for step in on
// a call target as the function called might be a native function for
// which step in will not stop. It also prepares for stepping in
// getters/setters.
// If we are stepping into another frame, only fill calls and returns.
FloodWithOneShot(function, step_action == StepFrame ? CALLS_AND_RETURNS
: ALL_BREAK_LOCATIONS);
if (is_load_or_store) {
// Remember source position and frame to handle step in getter/setter. If
// there is a custom getter/setter it will be handled in
// Object::Get/SetPropertyWithAccessor, otherwise the step action will be
// propagated on the next Debug::Break.
thread_local_.last_statement_position_ =
debug_info->code()->SourceStatementPosition(summary.pc());
thread_local_.last_fp_ = frame->UnpaddedFP();
}
// Step in or Step in min
// Step in through construct call requires no changes to the running code.
// Step in through getters/setters should already be prepared as well
// because caller of this function (Debug::PrepareStep) is expected to
// flood the top frame's function with one shot breakpoints.
// Step in through CallFunction stub should also be prepared by caller of
// this function (Debug::PrepareStep) which should flood target function
// with breakpoints.
DCHECK(location.IsConstructCall() || is_inline_cache_stub ||
!call_function_stub.is_null() || is_at_restarted_function);
ActivateStepIn(frame);
}
// Fill the current function with one-shot break points even for step in on
// a call target as the function called might be a native function for
// which step in will not stop. It also prepares for stepping in
// getters/setters.
// If we are stepping into another frame, only fill calls and returns.
FloodWithOneShot(function, step_action == StepFrame ? CALLS_AND_RETURNS
: ALL_BREAK_LOCATIONS);
// Remember source position and frame to handle step next.
thread_local_.last_statement_position_ =
debug_info->code()->SourceStatementPosition(summary.pc());
thread_local_.last_fp_ = frame->UnpaddedFP();
}

View File

@ -177,7 +177,6 @@ class BreakLocation {
int break_index_;
int position_;
int statement_position_;
bool has_immediate_position_;
DisallowHeapAllocation no_gc_;

View File

@ -21,269 +21,6 @@
namespace v8 {
namespace internal {
void BreakableStatementChecker::Check(Statement* stmt) {
Visit(stmt);
}
void BreakableStatementChecker::Check(Expression* expr) {
Visit(expr);
}
void BreakableStatementChecker::VisitVariableDeclaration(
VariableDeclaration* decl) {
}
void BreakableStatementChecker::VisitFunctionDeclaration(
FunctionDeclaration* decl) {
}
void BreakableStatementChecker::VisitImportDeclaration(
ImportDeclaration* decl) {
}
void BreakableStatementChecker::VisitExportDeclaration(
ExportDeclaration* decl) {
}
void BreakableStatementChecker::VisitBlock(Block* stmt) {
}
void BreakableStatementChecker::VisitExpressionStatement(
ExpressionStatement* stmt) {
// Check if expression is breakable.
Visit(stmt->expression());
}
void BreakableStatementChecker::VisitEmptyStatement(EmptyStatement* stmt) {
}
void BreakableStatementChecker::VisitIfStatement(IfStatement* stmt) {
// If the condition is breakable the if statement is breakable.
Visit(stmt->condition());
}
void BreakableStatementChecker::VisitContinueStatement(
ContinueStatement* stmt) {
}
void BreakableStatementChecker::VisitBreakStatement(BreakStatement* stmt) {
}
void BreakableStatementChecker::VisitReturnStatement(ReturnStatement* stmt) {
// Return is breakable if the expression is.
Visit(stmt->expression());
}
void BreakableStatementChecker::VisitWithStatement(WithStatement* stmt) {
Visit(stmt->expression());
}
void BreakableStatementChecker::VisitSwitchStatement(SwitchStatement* stmt) {
// Switch statements breakable if the tag expression is.
Visit(stmt->tag());
}
void BreakableStatementChecker::VisitDoWhileStatement(DoWhileStatement* stmt) {
// Mark do while as breakable to avoid adding a break slot in front of it.
is_breakable_ = true;
}
void BreakableStatementChecker::VisitWhileStatement(WhileStatement* stmt) {
// Mark while statements breakable if the condition expression is.
Visit(stmt->cond());
}
void BreakableStatementChecker::VisitForStatement(ForStatement* stmt) {
// We set positions for both init and condition, if they exist.
if (stmt->cond() != NULL || stmt->init() != NULL) is_breakable_ = true;
}
void BreakableStatementChecker::VisitForInStatement(ForInStatement* stmt) {
// For-in is breakable because we set the position for the enumerable.
is_breakable_ = true;
}
void BreakableStatementChecker::VisitForOfStatement(ForOfStatement* stmt) {
// For-of is breakable because we set the position for the next() call.
is_breakable_ = true;
}
void BreakableStatementChecker::VisitTryCatchStatement(
TryCatchStatement* stmt) {
// Mark try catch as breakable to avoid adding a break slot in front of it.
is_breakable_ = true;
}
void BreakableStatementChecker::VisitTryFinallyStatement(
TryFinallyStatement* stmt) {
// Mark try finally as breakable to avoid adding a break slot in front of it.
is_breakable_ = true;
}
void BreakableStatementChecker::VisitDebuggerStatement(
DebuggerStatement* stmt) {
// The debugger statement is breakable.
is_breakable_ = true;
}
void BreakableStatementChecker::VisitCaseClause(CaseClause* clause) {
}
void BreakableStatementChecker::VisitFunctionLiteral(FunctionLiteral* expr) {
}
void BreakableStatementChecker::VisitClassLiteral(ClassLiteral* expr) {
if (expr->extends() != NULL) {
Visit(expr->extends());
}
}
void BreakableStatementChecker::VisitNativeFunctionLiteral(
NativeFunctionLiteral* expr) {
}
void BreakableStatementChecker::VisitConditional(Conditional* expr) {
}
void BreakableStatementChecker::VisitVariableProxy(VariableProxy* expr) {
}
void BreakableStatementChecker::VisitLiteral(Literal* expr) {
}
void BreakableStatementChecker::VisitRegExpLiteral(RegExpLiteral* expr) {
}
void BreakableStatementChecker::VisitObjectLiteral(ObjectLiteral* expr) {
}
void BreakableStatementChecker::VisitArrayLiteral(ArrayLiteral* expr) {
}
void BreakableStatementChecker::VisitAssignment(Assignment* expr) {
// If assigning to a property (including a global property) the assignment is
// breakable.
VariableProxy* proxy = expr->target()->AsVariableProxy();
Property* prop = expr->target()->AsProperty();
if (prop != NULL || (proxy != NULL && proxy->var()->IsUnallocated())) {
is_breakable_ = true;
return;
}
// Otherwise the assignment is breakable if the assigned value is.
Visit(expr->value());
}
void BreakableStatementChecker::VisitYield(Yield* expr) {
// Yield is breakable if the expression is.
Visit(expr->expression());
}
void BreakableStatementChecker::VisitThrow(Throw* expr) {
// Throw is breakable if the expression is.
Visit(expr->exception());
}
void BreakableStatementChecker::VisitProperty(Property* expr) {
// Property load is breakable.
is_breakable_ = true;
}
void BreakableStatementChecker::VisitCall(Call* expr) {
// Function calls both through IC and call stub are breakable.
is_breakable_ = true;
}
void BreakableStatementChecker::VisitCallNew(CallNew* expr) {
// Function calls through new are breakable.
is_breakable_ = true;
}
void BreakableStatementChecker::VisitCallRuntime(CallRuntime* expr) {
}
void BreakableStatementChecker::VisitUnaryOperation(UnaryOperation* expr) {
Visit(expr->expression());
}
void BreakableStatementChecker::VisitCountOperation(CountOperation* expr) {
Visit(expr->expression());
}
void BreakableStatementChecker::VisitBinaryOperation(BinaryOperation* expr) {
Visit(expr->left());
if (expr->op() != Token::AND &&
expr->op() != Token::OR) {
Visit(expr->right());
}
}
void BreakableStatementChecker::VisitCompareOperation(CompareOperation* expr) {
Visit(expr->left());
Visit(expr->right());
}
void BreakableStatementChecker::VisitSpread(Spread* expr) {
Visit(expr->expression());
}
void BreakableStatementChecker::VisitThisFunction(ThisFunction* expr) {
}
void BreakableStatementChecker::VisitSuperPropertyReference(
SuperPropertyReference* expr) {}
void BreakableStatementChecker::VisitSuperCallReference(
SuperCallReference* expr) {}
#define __ ACCESS_MASM(masm())
bool FullCodeGenerator::MakeCode(CompilationInfo* info) {
@ -670,38 +407,59 @@ int FullCodeGenerator::DeclareGlobalsFlags() {
}
bool RecordStatementPosition(MacroAssembler* masm, int pos) {
if (pos == RelocInfo::kNoPosition) return false;
masm->positions_recorder()->RecordStatementPosition(pos);
masm->positions_recorder()->RecordPosition(pos);
return masm->positions_recorder()->WriteRecordedPositions();
}
bool RecordPosition(MacroAssembler* masm, int pos) {
if (pos == RelocInfo::kNoPosition) return false;
masm->positions_recorder()->RecordPosition(pos);
return masm->positions_recorder()->WriteRecordedPositions();
}
void FullCodeGenerator::SetFunctionPosition(FunctionLiteral* fun) {
CodeGenerator::RecordPositions(masm_, fun->start_position());
RecordPosition(masm_, fun->start_position());
}
void FullCodeGenerator::SetReturnPosition(FunctionLiteral* fun) {
CodeGenerator::RecordPositions(masm_, fun->end_position() - 1);
RecordStatementPosition(masm_, fun->end_position() - 1);
}
void FullCodeGenerator::SetStatementPosition(Statement* stmt) {
if (!info_->is_debug()) {
CodeGenerator::RecordPositions(masm_, stmt->position());
} else {
// Check if the statement will be breakable without adding a debug break
// slot.
BreakableStatementChecker checker(info_->isolate(), zone());
checker.Check(stmt);
// Record the statement position right here if the statement is not
// breakable. For breakable statements the actual recording of the
// position will be postponed to the breakable code (typically an IC).
bool position_recorded = CodeGenerator::RecordPositions(
masm_, stmt->position(), !checker.is_breakable());
// If the position recording did record a new position generate a debug
// break slot to make the statement breakable.
if (position_recorded) {
DebugCodegen::GenerateSlot(masm_);
}
void FullCodeGenerator::SetStatementPosition(
Statement* stmt, FullCodeGenerator::InsertBreak insert_break) {
if (stmt->position() == RelocInfo::kNoPosition) return;
bool recorded = RecordStatementPosition(masm_, stmt->position());
if (recorded && insert_break == INSERT_BREAK && info_->is_debug() &&
!stmt->IsDebuggerStatement()) {
DebugCodegen::GenerateSlot(masm_);
}
}
void FullCodeGenerator::SetExpressionPosition(
Expression* expr, FullCodeGenerator::InsertBreak insert_break) {
if (expr->position() == RelocInfo::kNoPosition) return;
bool recorded = RecordPosition(masm_, expr->position());
if (recorded && insert_break == INSERT_BREAK && info_->is_debug()) {
DebugCodegen::GenerateSlot(masm_);
}
}
void FullCodeGenerator::SetExpressionAsStatementPosition(Expression* expr) {
if (expr->position() == RelocInfo::kNoPosition) return;
bool recorded = RecordStatementPosition(masm_, expr->position());
if (recorded && info_->is_debug()) DebugCodegen::GenerateSlot(masm_);
}
void FullCodeGenerator::VisitSuperPropertyReference(
SuperPropertyReference* super) {
__ CallRuntime(Runtime::kThrowUnsupportedSuperError, 0);
@ -713,39 +471,6 @@ void FullCodeGenerator::VisitSuperCallReference(SuperCallReference* super) {
}
void FullCodeGenerator::SetExpressionPosition(Expression* expr) {
if (!info_->is_debug()) {
CodeGenerator::RecordPositions(masm_, expr->position());
} else {
// Check if the expression will be breakable without adding a debug break
// slot.
BreakableStatementChecker checker(info_->isolate(), zone());
checker.Check(expr);
// Record a statement position right here if the expression is not
// breakable. For breakable expressions the actual recording of the
// position will be postponed to the breakable code (typically an IC).
// NOTE this will record a statement position for something which might
// not be a statement. As stepping in the debugger will only stop at
// statement positions this is used for e.g. the condition expression of
// a do while loop.
bool position_recorded = CodeGenerator::RecordPositions(
masm_, expr->position(), !checker.is_breakable());
// If the position recording did record a new position generate a debug
// break slot to make the statement breakable.
if (position_recorded) {
DebugCodegen::GenerateSlot(masm_);
}
}
}
void FullCodeGenerator::SetSourcePosition(int pos) {
if (pos != RelocInfo::kNoPosition) {
masm_->positions_recorder()->RecordPosition(pos);
}
}
void FullCodeGenerator::EmitGeneratorNext(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK(args->length() == 2);
@ -878,7 +603,7 @@ void FullCodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) {
VisitForStackValue(left);
VisitForAccumulatorValue(right);
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
if (ShouldInlineSmiCase(op)) {
EmitInlineSmiBinaryOp(expr, op, left, right);
} else {
@ -1060,7 +785,9 @@ void FullCodeGenerator::VisitWithStatement(WithStatement* stmt) {
void FullCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
Comment cmnt(masm_, "[ DoWhileStatement");
SetStatementPosition(stmt);
// Do not insert break location as we do that below.
SetStatementPosition(stmt, SKIP_BREAK);
Label body, book_keeping;
Iteration loop_statement(this, stmt);
@ -1073,7 +800,9 @@ void FullCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) {
// possible to break on the condition.
__ bind(loop_statement.continue_label());
PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS);
SetExpressionPosition(stmt->cond());
// Here is the actual 'while' keyword.
SetExpressionAsStatementPosition(stmt->cond());
VisitForControl(stmt->cond(),
&book_keeping,
loop_statement.break_label(),
@ -1100,7 +829,7 @@ void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
__ bind(&loop);
SetExpressionPosition(stmt->cond());
SetExpressionAsStatementPosition(stmt->cond());
VisitForControl(stmt->cond(),
&body,
loop_statement.break_label(),
@ -1124,13 +853,13 @@ void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
void FullCodeGenerator::VisitForStatement(ForStatement* stmt) {
Comment cmnt(masm_, "[ ForStatement");
// Do not insert break location as we do it below.
SetStatementPosition(stmt, SKIP_BREAK);
Label test, body;
Iteration loop_statement(this, stmt);
// Set statement position for a break slot before entering the for-body.
SetStatementPosition(stmt);
if (stmt->init() != NULL) {
SetStatementPosition(stmt->init());
Visit(stmt->init());
@ -1151,16 +880,12 @@ void FullCodeGenerator::VisitForStatement(ForStatement* stmt) {
Visit(stmt->next());
}
// Emit the statement position here as this is where the for
// statement code starts.
SetStatementPosition(stmt);
// Check stack before looping.
EmitBackEdgeBookkeeping(stmt, &body);
__ bind(&test);
if (stmt->cond() != NULL) {
SetExpressionPosition(stmt->cond());
SetExpressionAsStatementPosition(stmt->cond());
VisitForControl(stmt->cond(),
&body,
loop_statement.break_label(),
@ -1177,7 +902,6 @@ void FullCodeGenerator::VisitForStatement(ForStatement* stmt) {
void FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
Comment cmnt(masm_, "[ ForOfStatement");
SetStatementPosition(stmt);
Iteration loop_statement(this, stmt);
increment_loop_depth();
@ -1189,7 +913,7 @@ void FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
__ bind(loop_statement.continue_label());
// result = iterator.next()
SetExpressionPosition(stmt->next_result());
SetExpressionAsStatementPosition(stmt->next_result());
VisitForEffect(stmt->next_result());
// if (result.done) break;
@ -1218,7 +942,8 @@ void FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
Comment cmnt(masm_, "[ TryCatchStatement");
SetStatementPosition(stmt);
SetStatementPosition(stmt, SKIP_BREAK);
// The try block adds a handler to the exception handler chain before
// entering, and removes it again when exiting normally. If an exception
// is thrown during execution of the try block, the handler is consumed
@ -1271,7 +996,8 @@ void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
void FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
Comment cmnt(masm_, "[ TryFinallyStatement");
SetStatementPosition(stmt);
SetStatementPosition(stmt, SKIP_BREAK);
// Try finally is compiled by setting up a try-handler on the stack while
// executing the try body, and removing it again afterwards.
//
@ -1487,7 +1213,7 @@ void FullCodeGenerator::VisitNativeFunctionLiteral(
void FullCodeGenerator::VisitThrow(Throw* expr) {
Comment cmnt(masm_, "[ Throw");
VisitForStackValue(expr->exception());
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
__ CallRuntime(Runtime::kThrow, 1);
// Never returns here.
}

View File

@ -24,35 +24,6 @@ namespace internal {
// Forward declarations.
class JumpPatchSite;
// AST node visitor which can tell whether a given statement will be breakable
// when the code is compiled by the full compiler in the debugger. This means
// that there will be an IC (load/store/call) in the code generated for the
// debugger to piggybag on.
class BreakableStatementChecker: public AstVisitor {
public:
BreakableStatementChecker(Isolate* isolate, Zone* zone)
: is_breakable_(false) {
InitializeAstVisitor(isolate, zone);
}
void Check(Statement* stmt);
void Check(Expression* stmt);
bool is_breakable() { return is_breakable_; }
private:
// AST node visit functions.
#define DECLARE_VISIT(type) virtual void Visit##type(type* node) override;
AST_NODE_LIST(DECLARE_VISIT)
#undef DECLARE_VISIT
bool is_breakable_;
DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
DISALLOW_COPY_AND_ASSIGN(BreakableStatementChecker);
};
// -----------------------------------------------------------------------------
// Full code generator.
@ -688,9 +659,21 @@ class FullCodeGenerator: public AstVisitor {
void SetFunctionPosition(FunctionLiteral* fun);
void SetReturnPosition(FunctionLiteral* fun);
void SetStatementPosition(Statement* stmt);
void SetExpressionPosition(Expression* expr);
void SetSourcePosition(int pos);
enum InsertBreak { INSERT_BREAK, SKIP_BREAK };
// During stepping we want to be able to break at each statement, but not at
// every (sub-)expression. That is why by default we insert breaks at every
// statement position, but not at every expression position, unless stated
// otherwise.
void SetStatementPosition(Statement* stmt,
InsertBreak insert_break = INSERT_BREAK);
void SetExpressionPosition(Expression* expr,
InsertBreak insert_break = SKIP_BREAK);
// Consider an expression a statement. As such, we also insert a break.
// This is used in loop headers where we want to break for each iteration.
void SetExpressionAsStatementPosition(Expression* expr);
// Non-local control flow support.
void EnterTryBlock(int handler_index, Label* handler);

View File

@ -179,50 +179,6 @@ void DebugCodegen::GenerateCallICStubDebugBreak(MacroAssembler* masm) {
}
void DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) {
// Register state for IC load call (from ic-ia32.cc).
Register receiver = LoadDescriptor::ReceiverRegister();
Register name = LoadDescriptor::NameRegister();
Register slot = LoadDescriptor::SlotRegister();
RegList regs = receiver.bit() | name.bit() | slot.bit();
Generate_DebugBreakCallHelper(masm, regs, 0, false);
}
void DebugCodegen::GenerateStoreICDebugBreak(MacroAssembler* masm) {
// Register state for IC store call (from ic-ia32.cc).
Register receiver = StoreDescriptor::ReceiverRegister();
Register name = StoreDescriptor::NameRegister();
Register value = StoreDescriptor::ValueRegister();
RegList regs = receiver.bit() | name.bit() | value.bit();
if (FLAG_vector_stores) {
regs |= VectorStoreICDescriptor::SlotRegister().bit();
}
Generate_DebugBreakCallHelper(masm, regs, 0, false);
}
void DebugCodegen::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) {
// Register state for keyed IC load call (from ic-ia32.cc).
GenerateLoadICDebugBreak(masm);
}
void DebugCodegen::GenerateKeyedStoreICDebugBreak(MacroAssembler* masm) {
// Register state for keyed IC store call (from ic-ia32.cc).
GenerateStoreICDebugBreak(masm);
}
void DebugCodegen::GenerateCompareNilICDebugBreak(MacroAssembler* masm) {
// Register state for CompareNil IC
// ----------- S t a t e -------------
// -- eax : value
// -----------------------------------
Generate_DebugBreakCallHelper(masm, eax.bit(), 0, false);
}
void DebugCodegen::GenerateReturnDebugBreak(MacroAssembler* masm) {
// Register state just before return from JS function (from codegen-ia32.cc).
// ----------- S t a t e -------------
@ -283,8 +239,6 @@ void DebugCodegen::GenerateSlot(MacroAssembler* masm) {
void DebugCodegen::GenerateSlotDebugBreak(MacroAssembler* masm) {
// In the places where a debug break slot is inserted no registers can contain
// object pointers.
Generate_DebugBreakCallHelper(masm, 0, 0, true);
}

View File

@ -469,7 +469,7 @@ void FullCodeGenerator::EmitReturnSequence() {
Label check_exit_codesize;
masm_->bind(&check_exit_codesize);
#endif
SetSourcePosition(function()->end_position() - 1);
SetReturnPosition(function());
__ RecordJSReturn();
// Do not use the leave instruction here because it is too short to
// patch with the code required by the debugger.
@ -1022,8 +1022,7 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
__ bind(&slow_case);
}
// Record position before stub call for type feedback.
SetSourcePosition(clause->position());
SetExpressionPosition(clause);
Handle<Code> ic = CodeFactory::CompareIC(isolate(), Token::EQ_STRICT,
strength(language_mode())).code();
CallIC(ic, clause->CompareId());
@ -1070,9 +1069,9 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
Comment cmnt(masm_, "[ ForInStatement");
FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
SetStatementPosition(stmt, SKIP_BREAK);
SetStatementPosition(stmt);
FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
Label loop, exit;
ForIn loop_statement(this, stmt);
@ -1080,7 +1079,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
// Get the object to enumerate over. If the object is null or undefined, skip
// over the loop. See ECMA-262 version 5, section 12.6.4.
SetExpressionPosition(stmt->enumerable());
SetExpressionAsStatementPosition(stmt->enumerable());
VisitForAccumulatorValue(stmt->enumerable());
__ cmp(eax, isolate()->factory()->undefined_value());
__ j(equal, &exit);
@ -1175,7 +1174,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
// Generate code for doing the condition check.
PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS);
__ bind(&loop);
SetExpressionPosition(stmt->each());
SetExpressionAsStatementPosition(stmt->each());
__ mov(eax, Operand(esp, 0 * kPointerSize)); // Get the current index.
__ cmp(eax, Operand(esp, 1 * kPointerSize)); // Compare to the array length.
@ -1420,8 +1419,7 @@ void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
// Record position before possible IC call.
SetSourcePosition(proxy->position());
SetExpressionPosition(proxy);
PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS);
Variable* var = proxy->var();
@ -1919,6 +1917,7 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
DCHECK(expr->target()->IsValidReferenceExpression());
Comment cmnt(masm_, "[ Assignment");
SetExpressionPosition(expr, INSERT_BREAK);
Property* property = expr->target()->AsProperty();
LhsKind assign_type = Property::GetAssignType(property);
@ -2008,7 +2007,6 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
__ push(eax); // Left operand goes on the stack.
VisitForAccumulatorValue(expr->value());
SetSourcePosition(expr->position() + 1);
if (ShouldInlineSmiCase(op)) {
EmitInlineSmiBinaryOp(expr->binary_operation(),
op,
@ -2024,8 +2022,7 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
VisitForAccumulatorValue(expr->value());
}
// Record source position before possible IC call.
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
// Store the value.
switch (assign_type) {
@ -2055,6 +2052,8 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
void FullCodeGenerator::VisitYield(Yield* expr) {
Comment cmnt(masm_, "[ Yield");
SetExpressionPosition(expr);
// Evaluate yielded value first; the initial iterator definition depends on
// this. It stays on the stack while we update the iterator.
VisitForStackValue(expr->expression());
@ -2340,7 +2339,7 @@ void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
SetExpressionPosition(prop);
Literal* key = prop->key()->AsLiteral();
DCHECK(!key->value()->IsSmi());
DCHECK(!prop->IsSuperAccess());
@ -2354,7 +2353,7 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
// Stack: receiver, home_object.
SetSourcePosition(prop->position());
SetExpressionPosition(prop);
Literal* key = prop->key()->AsLiteral();
DCHECK(!key->value()->IsSmi());
DCHECK(prop->IsSuperAccess());
@ -2366,7 +2365,7 @@ void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
SetExpressionPosition(prop);
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code();
__ mov(LoadDescriptor::SlotRegister(),
Immediate(SmiFromSlot(prop->PropertyFeedbackSlot())));
@ -2376,9 +2375,8 @@ void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
// Stack: receiver, home_object, key.
SetExpressionPosition(prop);
__ push(Immediate(Smi::FromInt(language_mode())));
SetSourcePosition(prop->position());
__ CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
}
@ -2738,13 +2736,10 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
// Assignment to a property, using a named store IC.
// eax : value
// esp[0] : receiver
Property* prop = expr->target()->AsProperty();
DCHECK(prop != NULL);
DCHECK(prop->key()->IsLiteral());
// Record source code position before IC call.
SetSourcePosition(expr->position());
__ mov(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value());
__ pop(StoreDescriptor::ReceiverRegister());
if (FLAG_vector_stores) {
@ -2796,8 +2791,6 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
__ pop(StoreDescriptor::NameRegister()); // Key.
__ pop(StoreDescriptor::ReceiverRegister());
DCHECK(StoreDescriptor::ValueRegister().is(eax));
// Record source code position before IC call.
SetSourcePosition(expr->position());
Handle<Code> ic =
CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
if (FLAG_vector_stores) {
@ -2814,6 +2807,8 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
void FullCodeGenerator::VisitProperty(Property* expr) {
Comment cmnt(masm_, "[ Property");
SetExpressionPosition(expr);
Expression* key = expr->key();
if (key->IsPropertyName()) {
@ -2886,12 +2881,12 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
SetExpressionPosition(expr);
Expression* callee = expr->expression();
DCHECK(callee->IsProperty());
Property* prop = callee->AsProperty();
DCHECK(prop->IsSuperAccess());
SetSourcePosition(prop->position());
Literal* key = prop->key()->AsLiteral();
DCHECK(!key->value()->IsSmi());
// Load the function from the receiver.
@ -2951,7 +2946,7 @@ void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
Property* prop = callee->AsProperty();
DCHECK(prop->IsSuperAccess());
SetSourcePosition(prop->position());
SetExpressionPosition(prop);
// Load the function from the receiver.
SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference();
VisitForStackValue(super_ref->home_object());
@ -2984,14 +2979,11 @@ void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
// Load the arguments.
ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length();
{ PreservePositionScope scope(masm()->positions_recorder());
for (int i = 0; i < arg_count; i++) {
VisitForStackValue(args->at(i));
}
for (int i = 0; i < arg_count; i++) {
VisitForStackValue(args->at(i));
}
// Record source position of the IC call.
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code();
__ Move(edx, Immediate(SmiFromSlot(expr->CallFeedbackICSlot())));
__ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
@ -3051,13 +3043,11 @@ void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
VariableProxy* callee = expr->expression()->AsVariableProxy();
if (callee->var()->IsLookupSlot()) {
Label slow, done;
SetSourcePosition(callee->position());
{
PreservePositionScope scope(masm()->positions_recorder());
// Generate code for loading from variables potentially shadowed by
// eval-introduced variables.
EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
}
SetExpressionPosition(callee);
// Generate code for loading from variables potentially shadowed by
// eval-introduced variables.
EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
__ bind(&slow);
// Call the runtime to find the function to call (returned in eax) and
// the object holding it (returned in edx).
@ -3106,26 +3096,25 @@ void FullCodeGenerator::VisitCall(Call* expr) {
// function using the given arguments.
ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length();
{ PreservePositionScope pos_scope(masm()->positions_recorder());
PushCalleeAndWithBaseObject(expr);
// Push the arguments.
for (int i = 0; i < arg_count; i++) {
VisitForStackValue(args->at(i));
}
PushCalleeAndWithBaseObject(expr);
// Push a copy of the function (found below the arguments) and
// resolve eval.
__ push(Operand(esp, (arg_count + 1) * kPointerSize));
EmitResolvePossiblyDirectEval(arg_count);
// Touch up the stack with the resolved function.
__ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax);
PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
// Push the arguments.
for (int i = 0; i < arg_count; i++) {
VisitForStackValue(args->at(i));
}
// Record source position for debugger.
SetSourcePosition(expr->position());
// Push a copy of the function (found below the arguments) and
// resolve eval.
__ push(Operand(esp, (arg_count + 1) * kPointerSize));
EmitResolvePossiblyDirectEval(arg_count);
// Touch up the stack with the resolved function.
__ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax);
PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
SetExpressionPosition(expr);
CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
__ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
__ CallStub(&stub);
@ -3150,10 +3139,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
EmitKeyedSuperCallWithLoadIC(expr);
}
} else {
{
PreservePositionScope scope(masm()->positions_recorder());
VisitForStackValue(property->obj());
}
VisitForStackValue(property->obj());
if (is_named_call) {
EmitCallWithLoadIC(expr);
} else {
@ -3165,9 +3151,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
} else {
DCHECK(call_type == Call::OTHER_CALL);
// Call to an arbitrary expression not handled specially above.
{ PreservePositionScope scope(masm()->positions_recorder());
VisitForStackValue(callee);
}
VisitForStackValue(callee);
__ push(Immediate(isolate()->factory()->undefined_value()));
// Emit function call.
EmitCall(expr);
@ -3201,7 +3185,7 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
// Call the construct call builtin that handles allocation and
// constructor invocation.
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
// Load function and argument count into edi and eax.
__ Move(eax, Immediate(arg_count));
@ -3244,7 +3228,7 @@ void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
// Call the construct call builtin that handles allocation and
// constructor invocation.
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
// Load function and argument count into edi and eax.
__ Move(eax, Immediate(arg_count));
@ -4667,8 +4651,7 @@ void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length();
// Record source position of the IC call.
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
__ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
__ CallStub(&stub);
@ -4848,7 +4831,6 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
DCHECK(expr->expression()->IsValidReferenceExpression());
Comment cmnt(masm_, "[ CountOperation");
SetSourcePosition(expr->position());
Property* prop = expr->expression()->AsProperty();
LhsKind assign_type = Property::GetAssignType(prop);
@ -4999,8 +4981,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
}
}
// Record position before stub call.
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
// Call stub for +1/-1.
__ bind(&stub_call);
@ -5221,7 +5202,7 @@ void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
Comment cmnt(masm_, "[ CompareOperation");
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
// First we try a fast inlined version of the compare when one of
// the operands is a literal.
@ -5275,8 +5256,6 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
__ bind(&slow_case);
}
// Record position and call the compare IC.
SetSourcePosition(expr->position());
Handle<Code> ic = CodeFactory::CompareIC(
isolate(), op, strength(language_mode())).code();
CallIC(ic, expr->CompareOperationFeedbackId());

View File

@ -150,49 +150,6 @@ void DebugCodegen::GenerateCallICStubDebugBreak(MacroAssembler* masm) {
}
void DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) {
Register receiver = LoadDescriptor::ReceiverRegister();
Register name = LoadDescriptor::NameRegister();
Register slot = LoadDescriptor::SlotRegister();
RegList regs = receiver.bit() | name.bit() | slot.bit();
Generate_DebugBreakCallHelper(masm, regs, 0);
}
void DebugCodegen::GenerateStoreICDebugBreak(MacroAssembler* masm) {
// Calling convention for IC store (from ic-mips.cc).
Register receiver = StoreDescriptor::ReceiverRegister();
Register name = StoreDescriptor::NameRegister();
Register value = StoreDescriptor::ValueRegister();
RegList regs = receiver.bit() | name.bit() | value.bit();
if (FLAG_vector_stores) {
regs |= VectorStoreICDescriptor::SlotRegister().bit();
}
Generate_DebugBreakCallHelper(masm, regs, 0);
}
void DebugCodegen::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) {
// Calling convention for keyed IC load (from ic-mips.cc).
GenerateLoadICDebugBreak(masm);
}
void DebugCodegen::GenerateKeyedStoreICDebugBreak(MacroAssembler* masm) {
// Calling convention for IC keyed store call (from ic-mips.cc).
GenerateStoreICDebugBreak(masm);
}
void DebugCodegen::GenerateCompareNilICDebugBreak(MacroAssembler* masm) {
// Register state for CompareNil IC
// ----------- S t a t e -------------
// -- a0 : value
// -----------------------------------
Generate_DebugBreakCallHelper(masm, a0.bit(), 0);
}
void DebugCodegen::GenerateReturnDebugBreak(MacroAssembler* masm) {
// In places other than IC call sites it is expected that v0 is TOS which
// is an object - this is not generally the case so this should be used with

View File

@ -506,7 +506,7 @@ void FullCodeGenerator::EmitReturnSequence() {
// tool from instrumenting as we rely on the code size here.
int32_t arg_count = info_->scope()->num_parameters() + 1;
int32_t sp_delta = arg_count * kPointerSize;
CodeGenerator::RecordPositions(masm_, function()->end_position() - 1);
SetReturnPosition(function());
__ RecordJSReturn();
masm_->mov(sp, fp);
int no_frame_start = masm_->pc_offset();
@ -1082,7 +1082,7 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
}
// Record position before stub call for type feedback.
SetSourcePosition(clause->position());
SetExpressionPosition(clause);
Handle<Code> ic = CodeFactory::CompareIC(isolate(), Token::EQ_STRICT,
strength(language_mode())).code();
CallIC(ic, clause->CompareId());
@ -1128,8 +1128,9 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
Comment cmnt(masm_, "[ ForInStatement");
SetStatementPosition(stmt, SKIP_BREAK);
FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
SetStatementPosition(stmt);
Label loop, exit;
ForIn loop_statement(this, stmt);
@ -1137,7 +1138,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
// Get the object to enumerate over. If the object is null or undefined, skip
// over the loop. See ECMA-262 version 5, section 12.6.4.
SetExpressionPosition(stmt->enumerable());
SetExpressionAsStatementPosition(stmt->enumerable());
VisitForAccumulatorValue(stmt->enumerable());
__ mov(a0, result_register()); // Result as param to InvokeBuiltin below.
__ LoadRoot(at, Heap::kUndefinedValueRootIndex);
@ -1237,7 +1238,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
// Generate code for doing the condition check.
PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS);
__ bind(&loop);
SetExpressionPosition(stmt->each());
SetExpressionAsStatementPosition(stmt->each());
// Load the current count to a0, load the length to a1.
__ lw(a0, MemOperand(sp, 0 * kPointerSize));
@ -1483,7 +1484,7 @@ void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
// Record position before possible IC call.
SetSourcePosition(proxy->position());
SetExpressionPosition(proxy);
PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS);
Variable* var = proxy->var();
@ -1980,6 +1981,7 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
DCHECK(expr->target()->IsValidReferenceExpression());
Comment cmnt(masm_, "[ Assignment");
SetExpressionPosition(expr, INSERT_BREAK);
Property* property = expr->target()->AsProperty();
LhsKind assign_type = Property::GetAssignType(property);
@ -2073,7 +2075,6 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
__ push(v0); // Left operand goes on the stack.
VisitForAccumulatorValue(expr->value());
SetSourcePosition(expr->position() + 1);
AccumulatorValueContext context(this);
if (ShouldInlineSmiCase(op)) {
EmitInlineSmiBinaryOp(expr->binary_operation(),
@ -2090,8 +2091,7 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
VisitForAccumulatorValue(expr->value());
}
// Record source position before possible IC call.
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
// Store the value.
switch (assign_type) {
@ -2121,6 +2121,8 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
void FullCodeGenerator::VisitYield(Yield* expr) {
Comment cmnt(masm_, "[ Yield");
SetExpressionPosition(expr);
// Evaluate yielded value first; the initial iterator definition depends on
// this. It stays on the stack while we update the iterator.
VisitForStackValue(expr->expression());
@ -2408,7 +2410,7 @@ void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
SetExpressionPosition(prop);
Literal* key = prop->key()->AsLiteral();
DCHECK(!prop->IsSuperAccess());
@ -2421,7 +2423,8 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
// Stack: receiver, home_object.
SetSourcePosition(prop->position());
SetExpressionPosition(prop);
Literal* key = prop->key()->AsLiteral();
DCHECK(!key->value()->IsSmi());
DCHECK(prop->IsSuperAccess());
@ -2433,7 +2436,7 @@ void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
SetExpressionPosition(prop);
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code();
__ li(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
@ -2443,9 +2446,8 @@ void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
// Stack: receiver, home_object, key.
SetExpressionPosition(prop);
__ Push(Smi::FromInt(language_mode()));
SetSourcePosition(prop->position());
__ CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
}
@ -2816,8 +2818,6 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
DCHECK(prop != NULL);
DCHECK(prop->key()->IsLiteral());
// Record source code position before IC call.
SetSourcePosition(expr->position());
__ mov(StoreDescriptor::ValueRegister(), result_register());
__ li(StoreDescriptor::NameRegister(),
Operand(prop->key()->AsLiteral()->value()));
@ -2866,9 +2866,6 @@ void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) {
void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
// Assignment to a property, using a keyed store IC.
// Record source code position before IC call.
SetSourcePosition(expr->position());
// Call keyed store IC.
// The arguments are:
// - a0 is the value,
@ -2894,6 +2891,8 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
void FullCodeGenerator::VisitProperty(Property* expr) {
Comment cmnt(masm_, "[ Property");
SetExpressionPosition(expr);
Expression* key = expr->key();
if (key->IsPropertyName()) {
@ -2969,12 +2968,12 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
SetExpressionPosition(expr);
Expression* callee = expr->expression();
DCHECK(callee->IsProperty());
Property* prop = callee->AsProperty();
DCHECK(prop->IsSuperAccess());
SetSourcePosition(prop->position());
Literal* key = prop->key()->AsLiteral();
DCHECK(!key->value()->IsSmi());
// Load the function from the receiver.
@ -3036,7 +3035,7 @@ void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
Property* prop = callee->AsProperty();
DCHECK(prop->IsSuperAccess());
SetSourcePosition(prop->position());
SetExpressionPosition(prop);
// Load the function from the receiver.
const Register scratch = a1;
SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference();
@ -3070,14 +3069,12 @@ void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
// Load the arguments.
ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length();
{ PreservePositionScope scope(masm()->positions_recorder());
for (int i = 0; i < arg_count; i++) {
VisitForStackValue(args->at(i));
}
for (int i = 0; i < arg_count; i++) {
VisitForStackValue(args->at(i));
}
// Record source position of the IC call.
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code();
__ li(a3, Operand(SmiFromSlot(expr->CallFeedbackICSlot())));
__ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
@ -3136,13 +3133,11 @@ void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
VariableProxy* callee = expr->expression()->AsVariableProxy();
if (callee->var()->IsLookupSlot()) {
Label slow, done;
SetSourcePosition(callee->position());
{
PreservePositionScope scope(masm()->positions_recorder());
// Generate code for loading from variables potentially shadowed
// by eval-introduced variables.
EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
}
SetExpressionPosition(callee);
// Generate code for loading from variables potentially shadowed by
// eval-introduced variables.
EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
__ bind(&slow);
// Call the runtime to find the function to call (returned in v0)
@ -3195,8 +3190,6 @@ void FullCodeGenerator::VisitCall(Call* expr) {
// function using the given arguments.
ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length();
{ PreservePositionScope pos_scope(masm()->positions_recorder());
PushCalleeAndWithBaseObject(expr);
// Push the arguments.
@ -3214,9 +3207,8 @@ void FullCodeGenerator::VisitCall(Call* expr) {
__ sw(v0, MemOperand(sp, (arg_count + 1) * kPointerSize));
PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
}
// Record source position for debugger.
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
__ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
__ CallStub(&stub);
@ -3240,10 +3232,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
EmitKeyedSuperCallWithLoadIC(expr);
}
} else {
{
PreservePositionScope scope(masm()->positions_recorder());
VisitForStackValue(property->obj());
}
if (is_named_call) {
EmitCallWithLoadIC(expr);
} else {
@ -3255,9 +3244,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
} else {
DCHECK(call_type == Call::OTHER_CALL);
// Call to an arbitrary expression not handled specially above.
{ PreservePositionScope scope(masm()->positions_recorder());
VisitForStackValue(callee);
}
__ LoadRoot(a1, Heap::kUndefinedValueRootIndex);
__ push(a1);
// Emit function call.
@ -3292,7 +3279,7 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
// Call the construct call builtin that handles allocation and
// constructor invocation.
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
// Load function and argument count into a1 and a0.
__ li(a0, Operand(arg_count));
@ -3335,7 +3322,7 @@ void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
// Call the construct call builtin that handles allocation and
// constructor invocation.
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
// Load function and argument count into a1 and a0.
__ li(a0, Operand(arg_count));
@ -4749,8 +4736,7 @@ void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length();
// Record source position of the IC call.
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
__ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
__ CallStub(&stub);
@ -4928,7 +4914,6 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
DCHECK(expr->expression()->IsValidReferenceExpression());
Comment cmnt(masm_, "[ CountOperation");
SetSourcePosition(expr->position());
Property* prop = expr->expression()->AsProperty();
LhsKind assign_type = Property::GetAssignType(prop);
@ -5085,8 +5070,8 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
__ mov(a1, v0);
__ li(a0, Operand(Smi::FromInt(count_value)));
// Record position before stub call.
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), Token::ADD,
strength(language_mode())).code();
@ -5302,7 +5287,7 @@ void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
Comment cmnt(masm_, "[ CompareOperation");
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
// First we try a fast inlined version of the compare when one of
// the operands is a literal.
@ -5353,8 +5338,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
Split(cc, a1, Operand(a0), if_true, if_false, NULL);
__ bind(&slow_case);
}
// Record position and call the compare IC.
SetSourcePosition(expr->position());
Handle<Code> ic = CodeFactory::CompareIC(
isolate(), op, strength(language_mode())).code();
CallIC(ic, expr->CompareOperationFeedbackId());

View File

@ -153,48 +153,6 @@ void DebugCodegen::GenerateCallICStubDebugBreak(MacroAssembler* masm) {
}
void DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) {
Register receiver = LoadDescriptor::ReceiverRegister();
Register name = LoadDescriptor::NameRegister();
Register slot = LoadDescriptor::SlotRegister();
RegList regs = receiver.bit() | name.bit() | slot.bit();
Generate_DebugBreakCallHelper(masm, regs, 0);
}
void DebugCodegen::GenerateStoreICDebugBreak(MacroAssembler* masm) {
Register receiver = StoreDescriptor::ReceiverRegister();
Register name = StoreDescriptor::NameRegister();
Register value = StoreDescriptor::ValueRegister();
RegList regs = receiver.bit() | name.bit() | value.bit();
if (FLAG_vector_stores) {
regs |= VectorStoreICDescriptor::SlotRegister().bit();
}
Generate_DebugBreakCallHelper(masm, regs, 0);
}
void DebugCodegen::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) {
// Calling convention for keyed IC load (from ic-mips64.cc).
GenerateLoadICDebugBreak(masm);
}
void DebugCodegen::GenerateKeyedStoreICDebugBreak(MacroAssembler* masm) {
// Calling convention for IC keyed store call (from ic-mips64.cc).
GenerateStoreICDebugBreak(masm);
}
void DebugCodegen::GenerateCompareNilICDebugBreak(MacroAssembler* masm) {
// Register state for CompareNil IC
// ----------- S t a t e -------------
// -- a0 : value
// -----------------------------------
Generate_DebugBreakCallHelper(masm, a0.bit(), 0);
}
void DebugCodegen::GenerateReturnDebugBreak(MacroAssembler* masm) {
// In places other than IC call sites it is expected that v0 is TOS which
// is an object - this is not generally the case so this should be used with

View File

@ -495,6 +495,7 @@ void FullCodeGenerator::EmitReturnSequence() {
Label check_exit_codesize;
masm_->bind(&check_exit_codesize);
#endif
// Make sure that the constant pool is not emitted inside of the return
// sequence.
{ Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
@ -502,7 +503,7 @@ void FullCodeGenerator::EmitReturnSequence() {
// tool from instrumenting as we rely on the code size here.
int32_t arg_count = info_->scope()->num_parameters() + 1;
int32_t sp_delta = arg_count * kPointerSize;
CodeGenerator::RecordPositions(masm_, function()->end_position() - 1);
SetReturnPosition(function());
__ RecordJSReturn();
masm_->mov(sp, fp);
int no_frame_start = masm_->pc_offset();
@ -1078,7 +1079,7 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
}
// Record position before stub call for type feedback.
SetSourcePosition(clause->position());
SetExpressionPosition(clause);
Handle<Code> ic = CodeFactory::CompareIC(isolate(), Token::EQ_STRICT,
strength(language_mode())).code();
CallIC(ic, clause->CompareId());
@ -1124,8 +1125,9 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
Comment cmnt(masm_, "[ ForInStatement");
SetStatementPosition(stmt, SKIP_BREAK);
FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
SetStatementPosition(stmt);
Label loop, exit;
ForIn loop_statement(this, stmt);
@ -1133,7 +1135,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
// Get the object to enumerate over. If the object is null or undefined, skip
// over the loop. See ECMA-262 version 5, section 12.6.4.
SetExpressionPosition(stmt->enumerable());
SetExpressionAsStatementPosition(stmt->enumerable());
VisitForAccumulatorValue(stmt->enumerable());
__ mov(a0, result_register()); // Result as param to InvokeBuiltin below.
__ LoadRoot(at, Heap::kUndefinedValueRootIndex);
@ -1233,7 +1235,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
// Generate code for doing the condition check.
PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS);
__ bind(&loop);
SetExpressionPosition(stmt->each());
SetExpressionAsStatementPosition(stmt->each());
// Load the current count to a0, load the length to a1.
__ ld(a0, MemOperand(sp, 0 * kPointerSize));
@ -1479,7 +1481,7 @@ void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
// Record position before possible IC call.
SetSourcePosition(proxy->position());
SetExpressionPosition(proxy);
PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS);
Variable* var = proxy->var();
@ -1978,6 +1980,7 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
DCHECK(expr->target()->IsValidReferenceExpression());
Comment cmnt(masm_, "[ Assignment");
SetExpressionPosition(expr, INSERT_BREAK);
Property* property = expr->target()->AsProperty();
LhsKind assign_type = Property::GetAssignType(property);
@ -2071,7 +2074,6 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
__ push(v0); // Left operand goes on the stack.
VisitForAccumulatorValue(expr->value());
SetSourcePosition(expr->position() + 1);
AccumulatorValueContext context(this);
if (ShouldInlineSmiCase(op)) {
EmitInlineSmiBinaryOp(expr->binary_operation(),
@ -2088,8 +2090,7 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
VisitForAccumulatorValue(expr->value());
}
// Record source position before possible IC call.
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
// Store the value.
switch (assign_type) {
@ -2119,6 +2120,8 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
void FullCodeGenerator::VisitYield(Yield* expr) {
Comment cmnt(masm_, "[ Yield");
SetExpressionPosition(expr);
// Evaluate yielded value first; the initial iterator definition depends on
// this. It stays on the stack while we update the iterator.
VisitForStackValue(expr->expression());
@ -2406,7 +2409,7 @@ void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
SetExpressionPosition(prop);
Literal* key = prop->key()->AsLiteral();
DCHECK(!prop->IsSuperAccess());
@ -2419,7 +2422,8 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
// Stack: receiver, home_object.
SetSourcePosition(prop->position());
SetExpressionPosition(prop);
Literal* key = prop->key()->AsLiteral();
DCHECK(!key->value()->IsSmi());
DCHECK(prop->IsSuperAccess());
@ -2431,8 +2435,9 @@ void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
// Call keyed load IC. It has register arguments receiver and key.
SetExpressionPosition(prop);
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code();
__ li(LoadDescriptor::SlotRegister(),
Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
@ -2442,9 +2447,8 @@ void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
// Stack: receiver, home_object, key.
SetExpressionPosition(prop);
__ Push(Smi::FromInt(language_mode()));
SetSourcePosition(prop->position());
__ CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
}
@ -2818,8 +2822,6 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
DCHECK(prop != NULL);
DCHECK(prop->key()->IsLiteral());
// Record source code position before IC call.
SetSourcePosition(expr->position());
__ mov(StoreDescriptor::ValueRegister(), result_register());
__ li(StoreDescriptor::NameRegister(),
Operand(prop->key()->AsLiteral()->value()));
@ -2868,9 +2870,6 @@ void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) {
void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
// Assignment to a property, using a keyed store IC.
// Record source code position before IC call.
SetSourcePosition(expr->position());
// Call keyed store IC.
// The arguments are:
// - a0 is the value,
@ -2896,6 +2895,8 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
void FullCodeGenerator::VisitProperty(Property* expr) {
Comment cmnt(masm_, "[ Property");
SetExpressionPosition(expr);
Expression* key = expr->key();
if (key->IsPropertyName()) {
@ -2971,12 +2972,12 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
SetExpressionPosition(expr);
Expression* callee = expr->expression();
DCHECK(callee->IsProperty());
Property* prop = callee->AsProperty();
DCHECK(prop->IsSuperAccess());
SetSourcePosition(prop->position());
Literal* key = prop->key()->AsLiteral();
DCHECK(!key->value()->IsSmi());
// Load the function from the receiver.
@ -3038,7 +3039,7 @@ void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
Property* prop = callee->AsProperty();
DCHECK(prop->IsSuperAccess());
SetSourcePosition(prop->position());
SetExpressionPosition(prop);
// Load the function from the receiver.
const Register scratch = a1;
SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference();
@ -3072,14 +3073,12 @@ void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
// Load the arguments.
ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length();
{ PreservePositionScope scope(masm()->positions_recorder());
for (int i = 0; i < arg_count; i++) {
VisitForStackValue(args->at(i));
}
for (int i = 0; i < arg_count; i++) {
VisitForStackValue(args->at(i));
}
// Record source position of the IC call.
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code();
__ li(a3, Operand(SmiFromSlot(expr->CallFeedbackICSlot())));
__ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
@ -3137,13 +3136,11 @@ void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
VariableProxy* callee = expr->expression()->AsVariableProxy();
if (callee->var()->IsLookupSlot()) {
Label slow, done;
SetSourcePosition(callee->position());
{
PreservePositionScope scope(masm()->positions_recorder());
// Generate code for loading from variables potentially shadowed
// by eval-introduced variables.
EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
}
SetExpressionPosition(callee);
// Generate code for loading from variables potentially shadowed by
// eval-introduced variables.
EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
__ bind(&slow);
// Call the runtime to find the function to call (returned in v0)
@ -3196,8 +3193,6 @@ void FullCodeGenerator::VisitCall(Call* expr) {
// function using the given arguments.
ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length();
{ PreservePositionScope pos_scope(masm()->positions_recorder());
PushCalleeAndWithBaseObject(expr);
// Push the arguments.
@ -3215,9 +3210,8 @@ void FullCodeGenerator::VisitCall(Call* expr) {
__ sd(v0, MemOperand(sp, (arg_count + 1) * kPointerSize));
PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
}
// Record source position for debugger.
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
__ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
__ CallStub(&stub);
@ -3241,10 +3235,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
EmitKeyedSuperCallWithLoadIC(expr);
}
} else {
{
PreservePositionScope scope(masm()->positions_recorder());
VisitForStackValue(property->obj());
}
if (is_named_call) {
EmitCallWithLoadIC(expr);
} else {
@ -3256,9 +3247,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
} else {
DCHECK(call_type == Call::OTHER_CALL);
// Call to an arbitrary expression not handled specially above.
{ PreservePositionScope scope(masm()->positions_recorder());
VisitForStackValue(callee);
}
__ LoadRoot(a1, Heap::kUndefinedValueRootIndex);
__ push(a1);
// Emit function call.
@ -3293,7 +3282,7 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
// Call the construct call builtin that handles allocation and
// constructor invocation.
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
// Load function and argument count into a1 and a0.
__ li(a0, Operand(arg_count));
@ -3336,7 +3325,7 @@ void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
// Call the construct call builtin that handles allocation and
// constructor invocation.
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
// Load function and argument count into a1 and a0.
__ li(a0, Operand(arg_count));
@ -4752,8 +4741,7 @@ void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length();
// Record source position of the IC call.
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
__ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
__ CallStub(&stub);
@ -4930,7 +4918,6 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
DCHECK(expr->expression()->IsValidReferenceExpression());
Comment cmnt(masm_, "[ CountOperation");
SetSourcePosition(expr->position());
Property* prop = expr->expression()->AsProperty();
LhsKind assign_type = Property::GetAssignType(prop);
@ -5087,8 +5074,8 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
__ mov(a1, v0);
__ li(a0, Operand(Smi::FromInt(count_value)));
// Record position before stub call.
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), Token::ADD,
strength(language_mode())).code();
@ -5304,7 +5291,7 @@ void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
Comment cmnt(masm_, "[ CompareOperation");
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
// First we try a fast inlined version of the compare when one of
// the operands is a literal.
@ -5355,8 +5342,7 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
Split(cc, a1, Operand(a0), if_true, if_false, NULL);
__ bind(&slow_case);
}
// Record position and call the compare IC.
SetSourcePosition(expr->position());
Handle<Code> ic = CodeFactory::CompareIC(
isolate(), op, strength(language_mode())).code();
CallIC(ic, expr->CompareOperationFeedbackId());

View File

@ -3208,7 +3208,7 @@ void Parser::InitializeForEachStatement(ForEachStatement* stmt,
Expression* result_value = factory()->NewProperty(
result_proxy, value_literal, RelocInfo::kNoPosition);
assign_each = factory()->NewAssignment(Token::ASSIGN, each, result_value,
each->position());
RelocInfo::kNoPosition);
}
for_of->Initialize(each, subject, body,
@ -3592,6 +3592,7 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
parsing_result.declarations[0];
auto descriptor = parsing_result.descriptor;
descriptor.declaration_pos = RelocInfo::kNoPosition;
descriptor.initialization_pos = RelocInfo::kNoPosition;
decl.initializer = factory()->NewVariableProxy(temp);
PatternRewriter::DeclareAndInitializeVariables(
@ -3688,7 +3689,8 @@ Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
return loop;
} else {
init = factory()->NewExpressionStatement(expression, position());
init =
factory()->NewExpressionStatement(expression, lhs_location.beg_pos);
}
}
}

View File

@ -159,50 +159,6 @@ void DebugCodegen::GenerateCallICStubDebugBreak(MacroAssembler* masm) {
}
void DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) {
// Register state for IC load call (from ic-x64.cc).
Register receiver = LoadDescriptor::ReceiverRegister();
Register name = LoadDescriptor::NameRegister();
Register slot = LoadDescriptor::SlotRegister();
RegList regs = receiver.bit() | name.bit() | slot.bit();
Generate_DebugBreakCallHelper(masm, regs, 0, false);
}
void DebugCodegen::GenerateStoreICDebugBreak(MacroAssembler* masm) {
// Register state for IC store call (from ic-x64.cc).
Register receiver = StoreDescriptor::ReceiverRegister();
Register name = StoreDescriptor::NameRegister();
Register value = StoreDescriptor::ValueRegister();
RegList regs = receiver.bit() | name.bit() | value.bit();
if (FLAG_vector_stores) {
regs |= VectorStoreICDescriptor::SlotRegister().bit();
}
Generate_DebugBreakCallHelper(masm, regs, 0, false);
}
void DebugCodegen::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) {
// Register state for keyed IC load call (from ic-x64.cc).
GenerateLoadICDebugBreak(masm);
}
void DebugCodegen::GenerateKeyedStoreICDebugBreak(MacroAssembler* masm) {
// Register state for keyed IC store call (from ic-x64.cc).
GenerateStoreICDebugBreak(masm);
}
void DebugCodegen::GenerateCompareNilICDebugBreak(MacroAssembler* masm) {
// Register state for CompareNil IC
// ----------- S t a t e -------------
// -- rax : value
// -----------------------------------
Generate_DebugBreakCallHelper(masm, rax.bit(), 0, false);
}
void DebugCodegen::GenerateReturnDebugBreak(MacroAssembler* masm) {
// Register state just before return from JS function (from codegen-x64.cc).
// ----------- S t a t e -------------

View File

@ -472,7 +472,7 @@ void FullCodeGenerator::EmitReturnSequence() {
Label check_exit_codesize;
masm_->bind(&check_exit_codesize);
#endif
CodeGenerator::RecordPositions(masm_, function()->end_position() - 1);
SetReturnPosition(function());
__ RecordJSReturn();
// Do not use the leave instruction here because it is too short to
// patch with the code required by the debugger.
@ -1046,7 +1046,7 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
}
// Record position before stub call for type feedback.
SetSourcePosition(clause->position());
SetExpressionPosition(clause);
Handle<Code> ic = CodeFactory::CompareIC(isolate(), Token::EQ_STRICT,
strength(language_mode())).code();
CallIC(ic, clause->CompareId());
@ -1093,8 +1093,9 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
Comment cmnt(masm_, "[ ForInStatement");
SetStatementPosition(stmt, SKIP_BREAK);
FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
SetStatementPosition(stmt);
Label loop, exit;
ForIn loop_statement(this, stmt);
@ -1102,7 +1103,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
// Get the object to enumerate over. If the object is null or undefined, skip
// over the loop. See ECMA-262 version 5, section 12.6.4.
SetExpressionPosition(stmt->enumerable());
SetExpressionAsStatementPosition(stmt->enumerable());
VisitForAccumulatorValue(stmt->enumerable());
__ CompareRoot(rax, Heap::kUndefinedValueRootIndex);
__ j(equal, &exit);
@ -1206,7 +1207,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
// Generate code for doing the condition check.
PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS);
__ bind(&loop);
SetExpressionPosition(stmt->each());
SetExpressionAsStatementPosition(stmt->each());
__ movp(rax, Operand(rsp, 0 * kPointerSize)); // Get the current index.
__ cmpp(rax, Operand(rsp, 1 * kPointerSize)); // Compare to the array length.
@ -1455,7 +1456,7 @@ void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
// Record position before possible IC call.
SetSourcePosition(proxy->position());
SetExpressionPosition(proxy);
PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS);
Variable* var = proxy->var();
@ -1949,6 +1950,7 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
DCHECK(expr->target()->IsValidReferenceExpression());
Comment cmnt(masm_, "[ Assignment");
SetExpressionPosition(expr, INSERT_BREAK);
Property* property = expr->target()->AsProperty();
LhsKind assign_type = Property::GetAssignType(property);
@ -2037,7 +2039,6 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
__ Push(rax); // Left operand goes on the stack.
VisitForAccumulatorValue(expr->value());
SetSourcePosition(expr->position() + 1);
AccumulatorValueContext context(this);
if (ShouldInlineSmiCase(op)) {
EmitInlineSmiBinaryOp(expr->binary_operation(),
@ -2053,8 +2054,7 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
VisitForAccumulatorValue(expr->value());
}
// Record source position before possible IC call.
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
// Store the value.
switch (assign_type) {
@ -2084,6 +2084,8 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
void FullCodeGenerator::VisitYield(Yield* expr) {
Comment cmnt(masm_, "[ Yield");
SetExpressionPosition(expr);
// Evaluate yielded value first; the initial iterator definition depends on
// this. It stays on the stack while we update the iterator.
VisitForStackValue(expr->expression());
@ -2370,7 +2372,7 @@ void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
SetExpressionPosition(prop);
Literal* key = prop->key()->AsLiteral();
DCHECK(!prop->IsSuperAccess());
@ -2383,7 +2385,7 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
// Stack: receiver, home_object
SetSourcePosition(prop->position());
SetExpressionPosition(prop);
Literal* key = prop->key()->AsLiteral();
DCHECK(!key->value()->IsSmi());
DCHECK(prop->IsSuperAccess());
@ -2395,7 +2397,7 @@ void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position());
SetExpressionPosition(prop);
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code();
__ Move(LoadDescriptor::SlotRegister(),
SmiFromSlot(prop->PropertyFeedbackSlot()));
@ -2405,9 +2407,8 @@ void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
// Stack: receiver, home_object, key.
SetExpressionPosition(prop);
__ Push(Smi::FromInt(language_mode()));
SetSourcePosition(prop->position());
__ CallRuntime(Runtime::kLoadKeyedFromSuper, 4);
}
@ -2738,8 +2739,6 @@ void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
DCHECK(prop != NULL);
DCHECK(prop->key()->IsLiteral());
// Record source code position before IC call.
SetSourcePosition(expr->position());
__ Move(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value());
__ Pop(StoreDescriptor::ReceiverRegister());
if (FLAG_vector_stores) {
@ -2786,12 +2785,9 @@ void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) {
void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
// Assignment to a property, using a keyed store IC.
__ Pop(StoreDescriptor::NameRegister()); // Key.
__ Pop(StoreDescriptor::ReceiverRegister());
DCHECK(StoreDescriptor::ValueRegister().is(rax));
// Record source code position before IC call.
SetSourcePosition(expr->position());
Handle<Code> ic =
CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
if (FLAG_vector_stores) {
@ -2808,6 +2804,8 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
void FullCodeGenerator::VisitProperty(Property* expr) {
Comment cmnt(masm_, "[ Property");
SetExpressionPosition(expr);
Expression* key = expr->key();
if (key->IsPropertyName()) {
@ -2885,8 +2883,8 @@ void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
DCHECK(callee->IsProperty());
Property* prop = callee->AsProperty();
DCHECK(prop->IsSuperAccess());
SetExpressionPosition(prop);
SetSourcePosition(prop->position());
Literal* key = prop->key()->AsLiteral();
DCHECK(!key->value()->IsSmi());
// Load the function from the receiver.
@ -2947,7 +2945,7 @@ void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
Property* prop = callee->AsProperty();
DCHECK(prop->IsSuperAccess());
SetSourcePosition(prop->position());
SetExpressionPosition(prop);
// Load the function from the receiver.
SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference();
VisitForStackValue(super_ref->home_object());
@ -2981,14 +2979,11 @@ void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
// Load the arguments.
ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length();
{ PreservePositionScope scope(masm()->positions_recorder());
for (int i = 0; i < arg_count; i++) {
VisitForStackValue(args->at(i));
}
for (int i = 0; i < arg_count; i++) {
VisitForStackValue(args->at(i));
}
// Record source position of the IC call.
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code();
__ Move(rdx, SmiFromSlot(expr->CallFeedbackICSlot()));
__ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize));
@ -3047,13 +3042,10 @@ void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) {
VariableProxy* callee = expr->expression()->AsVariableProxy();
if (callee->var()->IsLookupSlot()) {
Label slow, done;
SetSourcePosition(callee->position());
{
PreservePositionScope scope(masm()->positions_recorder());
// Generate code for loading from variables potentially shadowed by
// eval-introduced variables.
EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
}
SetExpressionPosition(callee);
// Generate code for loading from variables potentially shadowed by
// eval-introduced variables.
EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done);
__ bind(&slow);
// Call the runtime to find the function to call (returned in rax) and
// the object holding it (returned in rdx).
@ -3103,7 +3095,6 @@ void FullCodeGenerator::VisitCall(Call* expr) {
// function using the given arguments.
ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length();
{ PreservePositionScope pos_scope(masm()->positions_recorder());
PushCalleeAndWithBaseObject(expr);
// Push the arguments.
@ -3120,9 +3111,8 @@ void FullCodeGenerator::VisitCall(Call* expr) {
__ movp(Operand(rsp, (arg_count + 1) * kPointerSize), rax);
PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
}
// Record source position for debugger.
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
__ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize));
__ CallStub(&stub);
@ -3147,10 +3137,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
EmitKeyedSuperCallWithLoadIC(expr);
}
} else {
{
PreservePositionScope scope(masm()->positions_recorder());
VisitForStackValue(property->obj());
}
if (is_named_call) {
EmitCallWithLoadIC(expr);
} else {
@ -3162,9 +3149,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
} else {
DCHECK(call_type == Call::OTHER_CALL);
// Call to an arbitrary expression not handled specially above.
{ PreservePositionScope scope(masm()->positions_recorder());
VisitForStackValue(callee);
}
__ PushRoot(Heap::kUndefinedValueRootIndex);
// Emit function call.
EmitCall(expr);
@ -3198,7 +3183,7 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
// Call the construct call builtin that handles allocation and
// constructor invocation.
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
// Load function and argument count into rdi and rax.
__ Set(rax, arg_count);
@ -3241,7 +3226,7 @@ void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
// Call the construct call builtin that handles allocation and
// constructor invocation.
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
// Load function and argument count into edi and eax.
__ Set(rax, arg_count);
@ -4690,8 +4675,7 @@ void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length();
// Record source position of the IC call.
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
__ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize));
__ CallStub(&stub);
@ -4872,7 +4856,6 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
DCHECK(expr->expression()->IsValidReferenceExpression());
Comment cmnt(masm_, "[ CountOperation");
SetSourcePosition(expr->position());
Property* prop = expr->expression()->AsProperty();
LhsKind assign_type = Property::GetAssignType(prop);
@ -5019,8 +5002,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
}
}
// Record position before stub call.
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
// Call stub for +1/-1.
__ bind(&stub_call);
@ -5240,7 +5222,7 @@ void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
Comment cmnt(masm_, "[ CompareOperation");
SetSourcePosition(expr->position());
SetExpressionPosition(expr);
// First we try a fast inlined version of the compare when one of
// the operands is a literal.
@ -5294,8 +5276,6 @@ void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
__ bind(&slow_case);
}
// Record position and call the compare IC.
SetSourcePosition(expr->position());
Handle<Code> ic = CodeFactory::CompareIC(
isolate(), op, strength(language_mode())).code();
CallIC(ic, expr->CompareOperationFeedbackId());

View File

@ -969,82 +969,6 @@ static void MessageCallbackCount(v8::Handle<v8::Message> message,
// --- T h e A c t u a l T e s t s
// Test that the debug break function is the expected one for different kinds
// of break locations.
TEST(DebugStub) {
using ::v8::internal::Builtins;
using ::v8::internal::Isolate;
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
CheckDebugBreakFunction(&env,
"function f1(){}", "f1",
0,
v8::internal::RelocInfo::JS_RETURN,
NULL);
CheckDebugBreakFunction(&env,
"function f2(){x=1;}", "f2",
0,
v8::internal::RelocInfo::CODE_TARGET,
CcTest::i_isolate()->builtins()->builtin(
Builtins::kStoreIC_DebugBreak));
CheckDebugBreakFunction(
&env, "function f3(){x();}", "f3", 0,
v8::internal::RelocInfo::CODE_TARGET,
CcTest::i_isolate()->builtins()->builtin(Builtins::kLoadIC_DebugBreak));
// TODO(1240753): Make the test architecture independent or split
// parts of the debugger into architecture dependent files. This
// part currently disabled as it is not portable between IA32/ARM.
// Currently on ICs for keyed store/load on ARM.
#if !defined (__arm__) && !defined(__thumb__)
CheckDebugBreakFunction(
&env,
"function f4(){var index='propertyName'; var a={}; a[index] = 'x';}",
"f4", 39, v8::internal::RelocInfo::CODE_TARGET,
CcTest::i_isolate()->builtins()->builtin(
Builtins::kKeyedStoreIC_DebugBreak));
CheckDebugBreakFunction(
&env,
"function f5(){var index='propertyName'; var a={}; return a[index];}",
"f5", 39, v8::internal::RelocInfo::CODE_TARGET,
CcTest::i_isolate()->builtins()->builtin(
Builtins::kKeyedLoadIC_DebugBreak));
#endif
CheckDebugBreakFunction(&env, "function f6(){(0==null)()}", "f6", 0,
v8::internal::RelocInfo::CODE_TARGET,
CcTest::i_isolate()->builtins()->builtin(
Builtins::kCompareNilIC_DebugBreak));
// Check the debug break code stubs for call ICs with different number of
// parameters.
// TODO(verwaest): XXX update test.
// Handle<Code> debug_break_0 = v8::internal::ComputeCallDebugBreak(0);
// Handle<Code> debug_break_1 = v8::internal::ComputeCallDebugBreak(1);
// Handle<Code> debug_break_4 = v8::internal::ComputeCallDebugBreak(4);
// CheckDebugBreakFunction(&env,
// "function f4_0(){x();}", "f4_0",
// 0,
// v8::internal::RelocInfo::CODE_TARGET,
// *debug_break_0);
// CheckDebugBreakFunction(&env,
// "function f4_1(){x(1);}", "f4_1",
// 0,
// v8::internal::RelocInfo::CODE_TARGET,
// *debug_break_1);
// CheckDebugBreakFunction(&env,
// "function f4_4(){x(1,2,3,4);}", "f4_4",
// 0,
// v8::internal::RelocInfo::CODE_TARGET,
// *debug_break_4);
}
// Test that the debug info in the VM is in sync with the functions being
// debugged.
TEST(DebugInfo) {
@ -2346,7 +2270,7 @@ TEST(DebuggerStatementBreakpoint) {
v8::Local<v8::Function> foo = v8::Local<v8::Function>::Cast(
env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "foo")));
// The debugger statement triggers breakpint hit
// The debugger statement triggers breakpoint hit
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(1, break_point_hit_count);
@ -3270,6 +3194,13 @@ TEST(DebugStepDoWhile) {
v8::Local<v8::Function> foo = CompileFunction(&env, src, "foo");
SetBreakPoint(foo, 8); // "var a = 0;"
// Looping 0 times.
step_action = StepIn;
break_point_hit_count = 0;
v8::Handle<v8::Value> argv_0[argc] = {v8::Number::New(isolate, 0)};
foo->Call(env->Global(), argc, argv_0);
CHECK_EQ(4, break_point_hit_count);
// Looping 10 times.
step_action = StepIn;
break_point_hit_count = 0;
@ -3312,19 +3243,26 @@ TEST(DebugStepFor) {
SetBreakPoint(foo, 8); // "a = 1;"
// Looping 0 times.
step_action = StepIn;
break_point_hit_count = 0;
v8::Handle<v8::Value> argv_0[argc] = {v8::Number::New(isolate, 0)};
foo->Call(env->Global(), argc, argv_0);
CHECK_EQ(4, break_point_hit_count);
// Looping 10 times.
step_action = StepIn;
break_point_hit_count = 0;
v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(isolate, 10) };
foo->Call(env->Global(), argc, argv_10);
CHECK_EQ(45, break_point_hit_count);
CHECK_EQ(34, break_point_hit_count);
// Looping 100 times.
step_action = StepIn;
break_point_hit_count = 0;
v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(isolate, 100) };
foo->Call(env->Global(), argc, argv_100);
CHECK_EQ(405, break_point_hit_count);
CHECK_EQ(304, break_point_hit_count);
// Get rid of the debug event listener.
v8::Debug::SetDebugEventListener(NULL);
@ -3539,14 +3477,14 @@ TEST(DebugConditional) {
step_action = StepIn;
break_point_hit_count = 0;
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(5, break_point_hit_count);
CHECK_EQ(4, break_point_hit_count);
step_action = StepIn;
break_point_hit_count = 0;
const int argc = 1;
v8::Handle<v8::Value> argv_true[argc] = { v8::True(isolate) };
foo->Call(env->Global(), argc, argv_true);
CHECK_EQ(5, break_point_hit_count);
CHECK_EQ(4, break_point_hit_count);
// Get rid of the debug event listener.
v8::Debug::SetDebugEventListener(NULL);

View File

@ -165,7 +165,7 @@ function listener(event, exec_state, event_data, data) {
assertEquals("f", response.lookup(frame.func.ref).name);
assertTrue(frame.constructCall);
assertEquals(31, frame.line);
assertEquals(3, frame.column);
assertEquals(2, frame.column);
assertEquals(2, frame.arguments.length);
assertEquals('x', frame.arguments[0].name);
assertEquals('number', response.lookup(frame.arguments[0].value.ref).type);
@ -179,7 +179,7 @@ function listener(event, exec_state, event_data, data) {
assertEquals(0, frame.index);
assertEquals("f", response.lookup(frame.func.ref).name);
assertEquals(31, frame.line);
assertEquals(3, frame.column);
assertEquals(2, frame.column);
assertEquals(2, frame.arguments.length);
assertEquals('x', frame.arguments[0].name);
assertEquals('number', response.lookup(frame.arguments[0].value.ref).type);

View File

@ -211,7 +211,6 @@ assertTrue(Debug.showBreakPoints(g).indexOf("[B0]") < 0);
// (This may be sensitive to compiler break position map generation).
function h() {a=f(f2(1,2),f3())+f3();b=f3();}
var scenario = [
[5, "{a[B0]=f"],
[6, "{a=[B0]f("],
[7, "{a=f([B0]f2("],
[16, "f2(1,2),[B0]f3()"],

View File

@ -11,7 +11,7 @@ function f0() {
try {
throw 1;
} catch (e) {
try{
try {
f1();
} catch (e) {
var v02 = 2; // Break 13
@ -19,6 +19,8 @@ function f0() {
}
var v03 = 3;
var v04 = 4;
eval('var v05 = 5; // Break 14');
var v06 = 6; // Break 15
}
function f1() {
@ -104,7 +106,7 @@ for (step_size = 1; step_size < 6; step_size++) {
Debug.setListener(listener);
debugger; // Break 0
f0();
Debug.setListener(null); // Break 14
Debug.setListener(null); // Break 16
assertTrue(break_count > 14);
}

View File

@ -14,6 +14,7 @@ function listener(event, execState, eventData, data) {
if (!done) {
execState.prepareStep(Debug.StepAction.StepInto);
var s = execState.frame().sourceLineText();
print(s);
assertTrue(s.indexOf('// ' + stepCount + '.') !== -1);
stepCount++;
}
@ -24,10 +25,10 @@ Debug.setListener(listener);
class Base {
constructor() {
var x = 1; // 1.
var y = 2; // 2.
done = true; // 3.
constructor() { // 1.
var x = 1; // 2.
var y = 2; // 3.
done = true; // 4.
}
}
@ -40,7 +41,7 @@ class Derived extends Base {}
var bp = Debug.setBreakPoint(Base, 0);
new Base();
assertEquals(4, stepCount);
assertEquals(5, stepCount);
Debug.clearBreakPoint(bp);
})();
@ -52,7 +53,7 @@ class Derived extends Base {}
var bp = Debug.setBreakPoint(Base, 0);
new Derived();
assertEquals(4, stepCount);
assertEquals(5, stepCount);
Debug.clearBreakPoint(bp);
})();
@ -68,7 +69,7 @@ class Derived extends Base {}
var bp = Debug.setBreakPoint(f, 0);
f();
assertEquals(4, stepCount);
assertEquals(5, stepCount);
Debug.clearBreakPoint(bp);
})();
@ -86,7 +87,7 @@ class Derived extends Base {}
var bp = Debug.setBreakPoint(f, 0);
f();
assertEquals(4, stepCount);
assertEquals(5, stepCount);
Debug.clearBreakPoint(bp);
})();
@ -104,7 +105,7 @@ class Derived extends Base {}
var bp = Debug.setBreakPoint(f, 0);
f();
assertEquals(4, stepCount);
assertEquals(5, stepCount);
Debug.clearBreakPoint(bp);
})();

View File

@ -106,7 +106,7 @@ var expected = [
// For-var: var decl, condition, body, next, condition, body, ...
"k7","k20","K4","k23","k20","K4","k23","k20","K4","k23","k20",
// For: init, condition, body, next, condition, body, ...
"l11","l16","L4","l19","l16","L4","l19","l16","L4","l19","l16",
"l7","l16","L4","l19","l16","L4","l19","l16","L4","l19","l16",
// Exit.
"y0","z0",
]

View File

@ -354,9 +354,6 @@
'regress/regress-2185-2': [PASS, TIMEOUT],
'whitespaces': [PASS, TIMEOUT, SLOW],
# BUG(v8:3147). It works on other architectures by accident.
'regress/regress-conditional-position': [FAIL],
# BUG(v8:3457).
'deserialize-reference': [PASS, FAIL],