debug-ia32.cc revision 62ed631aa0ff23db68a47fd423efa9c019ff2c9e
1// Copyright 2012 the V8 project authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#if V8_TARGET_ARCH_IA32 6 7#include "src/debug/debug.h" 8 9#include "src/codegen.h" 10#include "src/debug/liveedit.h" 11#include "src/ia32/frames-ia32.h" 12 13namespace v8 { 14namespace internal { 15 16#define __ ACCESS_MASM(masm) 17 18 19void EmitDebugBreakSlot(MacroAssembler* masm) { 20 Label check_codesize; 21 __ bind(&check_codesize); 22 __ Nop(Assembler::kDebugBreakSlotLength); 23 DCHECK_EQ(Assembler::kDebugBreakSlotLength, 24 masm->SizeOfCodeGeneratedSince(&check_codesize)); 25} 26 27 28void DebugCodegen::GenerateSlot(MacroAssembler* masm, RelocInfo::Mode mode) { 29 // Generate enough nop's to make space for a call instruction. 30 masm->RecordDebugBreakSlot(mode); 31 EmitDebugBreakSlot(masm); 32} 33 34 35void DebugCodegen::ClearDebugBreakSlot(Isolate* isolate, Address pc) { 36 CodePatcher patcher(isolate, pc, Assembler::kDebugBreakSlotLength); 37 EmitDebugBreakSlot(patcher.masm()); 38} 39 40 41void DebugCodegen::PatchDebugBreakSlot(Isolate* isolate, Address pc, 42 Handle<Code> code) { 43 DCHECK(code->is_debug_stub()); 44 static const int kSize = Assembler::kDebugBreakSlotLength; 45 CodePatcher patcher(isolate, pc, kSize); 46 47 // Add a label for checking the size of the code used for returning. 48 Label check_codesize; 49 patcher.masm()->bind(&check_codesize); 50 patcher.masm()->call(code->entry(), RelocInfo::NONE32); 51 // Check that the size of the code generated is as expected. 52 DCHECK_EQ(kSize, patcher.masm()->SizeOfCodeGeneratedSince(&check_codesize)); 53} 54 55bool DebugCodegen::DebugBreakSlotIsPatched(Address pc) { 56 return !Assembler::IsNop(pc); 57} 58 59void DebugCodegen::GenerateDebugBreakStub(MacroAssembler* masm, 60 DebugBreakCallHelperMode mode) { 61 __ RecordComment("Debug break"); 62 63 // Enter an internal frame. 64 { 65 FrameScope scope(masm, StackFrame::INTERNAL); 66 67 // Push arguments for DebugBreak call. 68 if (mode == SAVE_RESULT_REGISTER) { 69 // Break on return. 70 __ push(eax); 71 } else { 72 // Non-return breaks. 73 __ Push(masm->isolate()->factory()->the_hole_value()); 74 } 75 __ Move(eax, Immediate(1)); 76 __ mov(ebx, 77 Immediate(ExternalReference( 78 Runtime::FunctionForId(Runtime::kDebugBreak), masm->isolate()))); 79 80 CEntryStub ceb(masm->isolate(), 1); 81 __ CallStub(&ceb); 82 83 if (FLAG_debug_code) { 84 for (int i = 0; i < kNumJSCallerSaved; ++i) { 85 Register reg = {JSCallerSavedCode(i)}; 86 // Do not clobber eax if mode is SAVE_RESULT_REGISTER. It will 87 // contain return value of the function. 88 if (!(reg.is(eax) && (mode == SAVE_RESULT_REGISTER))) { 89 __ Move(reg, Immediate(kDebugZapValue)); 90 } 91 } 92 } 93 // Get rid of the internal frame. 94 } 95 96 __ MaybeDropFrames(); 97 98 // Return to caller. 99 __ ret(0); 100} 101 102void DebugCodegen::GenerateHandleDebuggerStatement(MacroAssembler* masm) { 103 { 104 FrameScope scope(masm, StackFrame::INTERNAL); 105 __ CallRuntime(Runtime::kHandleDebuggerStatement, 0); 106 } 107 __ MaybeDropFrames(); 108 109 // Return to caller. 110 __ ret(0); 111} 112 113void DebugCodegen::GenerateFrameDropperTrampoline(MacroAssembler* masm) { 114 // Frame is being dropped: 115 // - Drop to the target frame specified by ebx. 116 // - Look up current function on the frame. 117 // - Leave the frame. 118 // - Restart the frame by calling the function. 119 __ mov(ebp, ebx); 120 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); 121 __ leave(); 122 123 __ mov(ebx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); 124 __ mov(ebx, 125 FieldOperand(ebx, SharedFunctionInfo::kFormalParameterCountOffset)); 126 127 ParameterCount dummy(ebx); 128 __ InvokeFunction(edi, dummy, dummy, JUMP_FUNCTION, 129 CheckDebugStepCallWrapper()); 130} 131 132 133const bool LiveEdit::kFrameDropperSupported = true; 134 135#undef __ 136 137} // namespace internal 138} // namespace v8 139 140#endif // V8_TARGET_ARCH_IA32 141