From 16e5c248958fc2e68eae4dae33146331aca827d8 Mon Sep 17 00:00:00 2001 From: mbrandy Date: Fri, 10 Jul 2015 14:02:20 -0700 Subject: [PATCH] PPC: Debugger: use debug break slot to break on call. Port 8965b683ce39bc3c24ed2466d189323d81a70852 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} --- src/ppc/assembler-ppc.h | 2 + src/ppc/debug-ppc.cc | 88 ++++++------------------------------- src/ppc/full-codegen-ppc.cc | 11 ++--- 3 files changed, 22 insertions(+), 79 deletions(-) diff --git a/src/ppc/assembler-ppc.h b/src/ppc/assembler-ppc.h index 82d068503d..7e2192a8e9 100644 --- a/src/ppc/assembler-ppc.h +++ b/src/ppc/assembler-ppc.h @@ -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. diff --git a/src/ppc/debug-ppc.cc b/src/ppc/debug-ppc.cc index 9e734452b8..cdb88b20b2 100644 --- a/src/ppc/debug-ppc.cc +++ b/src/ppc/debug-ppc.cc @@ -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); } diff --git a/src/ppc/full-codegen-ppc.cc b/src/ppc/full-codegen-ppc.cc index ec94a242b4..f67194d407 100644 --- a/src/ppc/full-codegen-ppc.cc +++ b/src/ppc/full-codegen-ppc.cc @@ -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 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* 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);