PPC: Debugger: use debug break slot to break on call.
Port 8965b683ce
Original commit message:
Break point at calls are currently set via IC. To change this, we
need to set debug break slots instead. We also need to distinguish
those debug break slots as calls to support step-in.
To implement this, we add a data field to debug break reloc info to
indicate non-call debug breaks or in case of call debug breaks, the
number of arguments. We can later use this to find the callee on the
evaluation stack in Debug::PrepareStep.
R=yangguo@chromium.org, dstence@us.ibm.com, michael_dawson@ca.ibm.com
BUG=
Review URL: https://codereview.chromium.org/1231173002
Cr-Commit-Position: refs/heads/master@{#29582}
This commit is contained in:
parent
91fcb0081e
commit
16e5c24895
@ -1301,6 +1301,8 @@ class Assembler : public AssemblerBase {
|
||||
|
||||
// Mark address of a debug break slot.
|
||||
void RecordDebugBreakSlot();
|
||||
void RecordDebugBreakSlotForCall(int argc);
|
||||
void RecordDebugBreakSlotForConstructCall();
|
||||
|
||||
// Record the AST id of the CallIC being compiled, so that it can be placed
|
||||
// in the relocation information.
|
||||
|
@ -71,8 +71,7 @@ void BreakLocation::SetDebugBreakAtSlot() {
|
||||
|
||||
|
||||
static void Generate_DebugBreakCallHelper(MacroAssembler* masm,
|
||||
RegList object_regs,
|
||||
RegList non_object_regs) {
|
||||
RegList object_regs) {
|
||||
{
|
||||
FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
|
||||
|
||||
@ -88,21 +87,8 @@ static void Generate_DebugBreakCallHelper(MacroAssembler* masm,
|
||||
// make sure that these are correctly updated during GC. Non object values
|
||||
// are stored as a smi causing it to be untouched by GC.
|
||||
DCHECK((object_regs & ~kJSCallerSaved) == 0);
|
||||
DCHECK((non_object_regs & ~kJSCallerSaved) == 0);
|
||||
DCHECK((object_regs & non_object_regs) == 0);
|
||||
if ((object_regs | non_object_regs) != 0) {
|
||||
for (int i = 0; i < kNumJSCallerSaved; i++) {
|
||||
int r = JSCallerSavedCode(i);
|
||||
Register reg = {r};
|
||||
if ((non_object_regs & (1 << r)) != 0) {
|
||||
if (FLAG_debug_code) {
|
||||
__ TestUnsignedSmiCandidate(reg, r0);
|
||||
__ Assert(eq, kUnableToEncodeValueAsSmi, cr0);
|
||||
}
|
||||
__ SmiTag(reg);
|
||||
}
|
||||
}
|
||||
__ MultiPush(object_regs | non_object_regs);
|
||||
if (object_regs != 0) {
|
||||
__ MultiPush(object_regs);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -115,18 +101,15 @@ static void Generate_DebugBreakCallHelper(MacroAssembler* masm,
|
||||
__ CallStub(&ceb);
|
||||
|
||||
// Restore the register values from the expression stack.
|
||||
if ((object_regs | non_object_regs) != 0) {
|
||||
__ MultiPop(object_regs | non_object_regs);
|
||||
for (int i = 0; i < kNumJSCallerSaved; i++) {
|
||||
int r = JSCallerSavedCode(i);
|
||||
Register reg = {r};
|
||||
if ((non_object_regs & (1 << r)) != 0) {
|
||||
__ SmiUntag(reg);
|
||||
}
|
||||
if (FLAG_debug_code &&
|
||||
(((object_regs | non_object_regs) & (1 << r)) == 0)) {
|
||||
__ mov(reg, Operand(kDebugZapValue));
|
||||
}
|
||||
if (object_regs != 0) {
|
||||
__ MultiPop(object_regs);
|
||||
}
|
||||
|
||||
for (int i = 0; i < kNumJSCallerSaved; i++) {
|
||||
int r = JSCallerSavedCode(i);
|
||||
Register reg = {r};
|
||||
if (FLAG_debug_code && ((object_regs & (1 << r)) == 0)) {
|
||||
__ mov(reg, Operand(kDebugZapValue));
|
||||
}
|
||||
}
|
||||
|
||||
@ -147,53 +130,11 @@ static void Generate_DebugBreakCallHelper(MacroAssembler* masm,
|
||||
}
|
||||
|
||||
|
||||
void DebugCodegen::GenerateCallICStubDebugBreak(MacroAssembler* masm) {
|
||||
// Register state for CallICStub
|
||||
// ----------- S t a t e -------------
|
||||
// -- r4 : function
|
||||
// -- r6 : slot in feedback array (smi)
|
||||
// -----------------------------------
|
||||
Generate_DebugBreakCallHelper(masm, r4.bit() | r6.bit(), 0);
|
||||
}
|
||||
|
||||
|
||||
void DebugCodegen::GenerateReturnDebugBreak(MacroAssembler* masm) {
|
||||
// In places other than IC call sites it is expected that r3 is TOS which
|
||||
// is an object - this is not generally the case so this should be used with
|
||||
// care.
|
||||
Generate_DebugBreakCallHelper(masm, r3.bit(), 0);
|
||||
}
|
||||
|
||||
|
||||
void DebugCodegen::GenerateCallFunctionStubDebugBreak(MacroAssembler* masm) {
|
||||
// Register state for CallFunctionStub (from code-stubs-ppc.cc).
|
||||
// ----------- S t a t e -------------
|
||||
// -- r4 : function
|
||||
// -----------------------------------
|
||||
Generate_DebugBreakCallHelper(masm, r4.bit(), 0);
|
||||
}
|
||||
|
||||
|
||||
void DebugCodegen::GenerateCallConstructStubDebugBreak(MacroAssembler* masm) {
|
||||
// Calling convention for CallConstructStub (from code-stubs-ppc.cc)
|
||||
// ----------- S t a t e -------------
|
||||
// -- r3 : number of arguments (not smi)
|
||||
// -- r4 : constructor function
|
||||
// -----------------------------------
|
||||
Generate_DebugBreakCallHelper(masm, r4.bit(), r3.bit());
|
||||
}
|
||||
|
||||
|
||||
void DebugCodegen::GenerateCallConstructStubRecordDebugBreak(
|
||||
MacroAssembler* masm) {
|
||||
// Calling convention for CallConstructStub (from code-stubs-ppc.cc)
|
||||
// ----------- S t a t e -------------
|
||||
// -- r3 : number of arguments (not smi)
|
||||
// -- r4 : constructor function
|
||||
// -- r5 : feedback array
|
||||
// -- r6 : feedback slot (smi)
|
||||
// -----------------------------------
|
||||
Generate_DebugBreakCallHelper(masm, r4.bit() | r5.bit() | r6.bit(), r3.bit());
|
||||
Generate_DebugBreakCallHelper(masm, r3.bit());
|
||||
}
|
||||
|
||||
|
||||
@ -203,7 +144,6 @@ void DebugCodegen::GenerateSlot(MacroAssembler* masm) {
|
||||
Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm);
|
||||
Label check_codesize;
|
||||
__ bind(&check_codesize);
|
||||
__ RecordDebugBreakSlot();
|
||||
for (int i = 0; i < Assembler::kDebugBreakSlotInstructions; i++) {
|
||||
__ nop(MacroAssembler::DEBUG_BREAK_NOP);
|
||||
}
|
||||
@ -215,7 +155,7 @@ 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);
|
||||
Generate_DebugBreakCallHelper(masm, 0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2236,6 +2236,7 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
|
||||
CallIC(ic, TypeFeedbackId::None());
|
||||
__ mr(r4, r3);
|
||||
__ StoreP(r4, MemOperand(sp, 2 * kPointerSize));
|
||||
SetCallPosition(expr, 1);
|
||||
CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD);
|
||||
__ CallStub(&stub);
|
||||
|
||||
@ -3101,7 +3102,7 @@ void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
|
||||
VisitForStackValue(args->at(i));
|
||||
}
|
||||
|
||||
SetExpressionPosition(expr);
|
||||
SetCallPosition(expr, arg_count);
|
||||
Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code();
|
||||
__ LoadSmiLiteral(r6, SmiFromSlot(expr->CallFeedbackICSlot()));
|
||||
__ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
|
||||
@ -3236,7 +3237,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
|
||||
PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS);
|
||||
|
||||
// Record source position for debugger.
|
||||
SetExpressionPosition(expr);
|
||||
SetCallPosition(expr, arg_count);
|
||||
CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
|
||||
__ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
|
||||
__ CallStub(&stub);
|
||||
@ -3308,7 +3309,7 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
|
||||
|
||||
// Call the construct call builtin that handles allocation and
|
||||
// constructor invocation.
|
||||
SetExpressionPosition(expr);
|
||||
SetConstructCallPosition(expr);
|
||||
|
||||
// Load function and argument count into r4 and r3.
|
||||
__ mov(r3, Operand(arg_count));
|
||||
@ -3351,7 +3352,7 @@ void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
|
||||
|
||||
// Call the construct call builtin that handles allocation and
|
||||
// constructor invocation.
|
||||
SetExpressionPosition(expr);
|
||||
SetConstructCallPosition(expr);
|
||||
|
||||
// Load function and argument count into r1 and r0.
|
||||
__ mov(r3, Operand(arg_count));
|
||||
@ -4760,7 +4761,7 @@ void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) {
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
int arg_count = args->length();
|
||||
|
||||
SetExpressionPosition(expr);
|
||||
SetCallPosition(expr, arg_count);
|
||||
CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
|
||||
__ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
|
||||
__ CallStub(&stub);
|
||||
|
Loading…
Reference in New Issue
Block a user