1864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 2864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Use of this source code is governed by a BSD-style license that can be 3864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// found in the LICENSE file. 4864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 5196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h" 6864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 7864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#if V8_TARGET_ARCH_X87 8864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/codegen.h" 10196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/debug.h" 11864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 12864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 13864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgnamespace v8 { 14864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgnamespace internal { 15864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 16864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgbool BreakLocationIterator::IsDebugBreakAtReturn() { 17864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return Debug::IsDebugBreakAtReturn(rinfo()); 18864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 19864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 20864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 21864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Patch the JS frame exit code with a debug break call. See 22864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// CodeGenerator::VisitReturnStatement and VirtualFrame::Exit in codegen-x87.cc 23864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// for the precise return instructions sequence. 24864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid BreakLocationIterator::SetDebugBreakAtReturn() { 25e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(Assembler::kJSReturnSequenceLength >= 26864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Assembler::kCallInstructionLength); 27864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org rinfo()->PatchCodeWithCall( 28864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org debug_info_->GetIsolate()->builtins()->Return_DebugBreak()->entry(), 29864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Assembler::kJSReturnSequenceLength - Assembler::kCallInstructionLength); 30864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 31864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 32864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 33864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Restore the JS frame exit code. 34864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid BreakLocationIterator::ClearDebugBreakAtReturn() { 35864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org rinfo()->PatchCode(original_rinfo()->pc(), 36864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Assembler::kJSReturnSequenceLength); 37864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 38864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 39864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 40864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// A debug break in the frame exit code is identified by the JS frame exit code 41864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// having been patched with a call instruction. 42864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgbool Debug::IsDebugBreakAtReturn(RelocInfo* rinfo) { 43e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(RelocInfo::IsJSReturn(rinfo->rmode())); 44864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return rinfo->IsPatchedReturnSequence(); 45864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 46864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 47864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 48864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgbool BreakLocationIterator::IsDebugBreakAtSlot() { 49e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(IsDebugBreakSlot()); 50864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check whether the debug break slot instructions have been patched. 51864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org return rinfo()->IsPatchedDebugBreakSlotSequence(); 52864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 53864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 54864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 55864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid BreakLocationIterator::SetDebugBreakAtSlot() { 56e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(IsDebugBreakSlot()); 57864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Isolate* isolate = debug_info_->GetIsolate(); 58864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org rinfo()->PatchCodeWithCall( 59864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org isolate->builtins()->Slot_DebugBreak()->entry(), 60864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Assembler::kDebugBreakSlotLength - Assembler::kCallInstructionLength); 61864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 62864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 63864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 64864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid BreakLocationIterator::ClearDebugBreakAtSlot() { 65e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(IsDebugBreakSlot()); 66864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org rinfo()->PatchCode(original_rinfo()->pc(), Assembler::kDebugBreakSlotLength); 67864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 68864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 69864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 70864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#define __ ACCESS_MASM(masm) 71864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 72864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstatic void Generate_DebugBreakCallHelper(MacroAssembler* masm, 73864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RegList object_regs, 74864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org RegList non_object_regs, 75864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool convert_call_to_jmp) { 76864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Enter an internal frame. 77864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org { 78864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org FrameScope scope(masm, StackFrame::INTERNAL); 79864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 80864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Load padding words on stack. 818d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org for (int i = 0; i < LiveEdit::kFramePaddingInitialSize; i++) { 828d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org __ push(Immediate(Smi::FromInt(LiveEdit::kFramePaddingValue))); 83864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 848d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org __ push(Immediate(Smi::FromInt(LiveEdit::kFramePaddingInitialSize))); 85864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 86864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Store the registers containing live values on the expression stack to 87864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // make sure that these are correctly updated during GC. Non object values 88864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // are stored as a smi causing it to be untouched by GC. 89e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK((object_regs & ~kJSCallerSaved) == 0); 90e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK((non_object_regs & ~kJSCallerSaved) == 0); 91e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK((object_regs & non_object_regs) == 0); 92864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = 0; i < kNumJSCallerSaved; i++) { 93864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int r = JSCallerSavedCode(i); 94864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register reg = { r }; 95864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if ((object_regs & (1 << r)) != 0) { 96864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(reg); 97864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 98864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if ((non_object_regs & (1 << r)) != 0) { 99864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (FLAG_debug_code) { 100864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ test(reg, Immediate(0xc0000000)); 101864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Assert(zero, kUnableToEncodeValueAsSmi); 102864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 103864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiTag(reg); 104864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ push(reg); 105864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 106864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 107864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 108864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#ifdef DEBUG 109864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ RecordComment("// Calling from debug break to runtime - come in - over"); 110864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#endif 111864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Move(eax, Immediate(0)); // No arguments. 112864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(ebx, Immediate(ExternalReference::debug_break(masm->isolate()))); 113864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 114864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org CEntryStub ceb(masm->isolate(), 1); 115864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ CallStub(&ceb); 116864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 117864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Automatically find register that could be used after register restore. 118864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // We need one register for padding skip instructions. 119864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register unused_reg = { -1 }; 120864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 121864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Restore the register values containing object pointers from the 122864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // expression stack. 123864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org for (int i = kNumJSCallerSaved; --i >= 0;) { 124864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org int r = JSCallerSavedCode(i); 125864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Register reg = { r }; 126864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (FLAG_debug_code) { 127864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Move(reg, Immediate(kDebugZapValue)); 128864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 129864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org bool taken = reg.code() == esi.code(); 130864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if ((object_regs & (1 << r)) != 0) { 131864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(reg); 132864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org taken = true; 133864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 134864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if ((non_object_regs & (1 << r)) != 0) { 135864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(reg); 136864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ SmiUntag(reg); 137864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org taken = true; 138864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 139864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!taken) { 140864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org unused_reg = reg; 141864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 142864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 143864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 144e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(unused_reg.code() != -1); 145864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 146864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Read current padding counter and skip corresponding number of words. 147864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(unused_reg); 148864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // We divide stored value by 2 (untagging) and multiply it by word's size. 149864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org STATIC_ASSERT(kSmiTagSize == 1 && kSmiShiftSize == 0); 150864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ lea(esp, Operand(esp, unused_reg, times_half_pointer_size, 0)); 151864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 152864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Get rid of the internal frame. 153864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 154864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 155864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // If this call did not replace a call but patched other code then there will 156864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // be an unwanted return address left on the stack. Here we get rid of that. 157864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (convert_call_to_jmp) { 158864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ add(esp, Immediate(kPointerSize)); 159864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 160864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 161864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Now that the break point has been handled, resume normal execution by 162864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // jumping to the target address intended by the caller and that was 163864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // overwritten by the address of DebugBreakXXX. 164864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference after_break_target = 165864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference::debug_after_break_target_address(masm->isolate()); 166864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(Operand::StaticVariable(after_break_target)); 167864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 168864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 169864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 170e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgvoid DebugCodegen::GenerateCallICStubDebugBreak(MacroAssembler* masm) { 171864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Register state for CallICStub 172864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // ----------- S t a t e ------------- 173864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // -- edx : type feedback slot (smi) 174864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // -- edi : function 175864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // ----------------------------------- 176864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Generate_DebugBreakCallHelper(masm, edx.bit() | edi.bit(), 177864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 0, false); 178864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 179864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 180864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 181e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgvoid DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) { 182864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Register state for IC load call (from ic-x87.cc). 18342ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org Register receiver = LoadDescriptor::ReceiverRegister(); 18442ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org Register name = LoadDescriptor::NameRegister(); 185248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org Generate_DebugBreakCallHelper(masm, receiver.bit() | name.bit(), 0, false); 186864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 187864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 188864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 189e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgvoid DebugCodegen::GenerateStoreICDebugBreak(MacroAssembler* masm) { 190864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Register state for IC store call (from ic-x87.cc). 19142ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org Register receiver = StoreDescriptor::ReceiverRegister(); 19242ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org Register name = StoreDescriptor::NameRegister(); 19342ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org Register value = StoreDescriptor::ValueRegister(); 194864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Generate_DebugBreakCallHelper( 195fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org masm, receiver.bit() | name.bit() | value.bit(), 0, false); 196864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 197864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 198864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 199e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgvoid DebugCodegen::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) { 200864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Register state for keyed IC load call (from ic-x87.cc). 20158a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org GenerateLoadICDebugBreak(masm); 202864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 203864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 204864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 205e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgvoid DebugCodegen::GenerateKeyedStoreICDebugBreak(MacroAssembler* masm) { 206fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org // Register state for keyed IC store call (from ic-x87.cc). 20742ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org Register receiver = StoreDescriptor::ReceiverRegister(); 20842ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org Register name = StoreDescriptor::NameRegister(); 20942ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org Register value = StoreDescriptor::ValueRegister(); 210864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Generate_DebugBreakCallHelper( 211fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org masm, receiver.bit() | name.bit() | value.bit(), 0, false); 212864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 213864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 214864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 215e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgvoid DebugCodegen::GenerateCompareNilICDebugBreak(MacroAssembler* masm) { 216864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Register state for CompareNil IC 217864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // ----------- S t a t e ------------- 218864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // -- eax : value 219864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // ----------------------------------- 220864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Generate_DebugBreakCallHelper(masm, eax.bit(), 0, false); 221864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 222864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 223864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 224e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgvoid DebugCodegen::GenerateReturnDebugBreak(MacroAssembler* masm) { 225864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Register state just before return from JS function (from codegen-x87.cc). 226864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // ----------- S t a t e ------------- 227864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // -- eax: return value 228864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // ----------------------------------- 229864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Generate_DebugBreakCallHelper(masm, eax.bit(), 0, true); 230864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 231864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 232864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 233e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgvoid DebugCodegen::GenerateCallFunctionStubDebugBreak(MacroAssembler* masm) { 234864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Register state for CallFunctionStub (from code-stubs-x87.cc). 235864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // ----------- S t a t e ------------- 236864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // -- edi: function 237864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // ----------------------------------- 238864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Generate_DebugBreakCallHelper(masm, edi.bit(), 0, false); 239864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 240864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 241864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 242e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgvoid DebugCodegen::GenerateCallConstructStubDebugBreak(MacroAssembler* masm) { 243864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Register state for CallConstructStub (from code-stubs-x87.cc). 244864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // eax is the actual number of arguments not encoded as a smi see comment 245864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // above IC call. 246864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // ----------- S t a t e ------------- 247864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // -- eax: number of arguments (not smi) 248864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // -- edi: constructor function 249864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // ----------------------------------- 250864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The number of arguments in eax is not smi encoded. 251864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Generate_DebugBreakCallHelper(masm, edi.bit(), eax.bit(), false); 252864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 253864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 254864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 255e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgvoid DebugCodegen::GenerateCallConstructStubRecordDebugBreak( 256e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org MacroAssembler* masm) { 257864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Register state for CallConstructStub (from code-stubs-x87.cc). 258864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // eax is the actual number of arguments not encoded as a smi see comment 259864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // above IC call. 260864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // ----------- S t a t e ------------- 261864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // -- eax: number of arguments (not smi) 262864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // -- ebx: feedback array 263864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // -- edx: feedback slot (smi) 264864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // -- edi: constructor function 265864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // ----------------------------------- 266864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // The number of arguments in eax is not smi encoded. 267864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Generate_DebugBreakCallHelper(masm, ebx.bit() | edx.bit() | edi.bit(), 268864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org eax.bit(), false); 269864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 270864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 271864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 272e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgvoid DebugCodegen::GenerateSlot(MacroAssembler* masm) { 273864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Generate enough nop's to make space for a call instruction. 274864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label check_codesize; 275864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&check_codesize); 276864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ RecordDebugBreakSlot(); 277864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Nop(Assembler::kDebugBreakSlotLength); 278e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(Assembler::kDebugBreakSlotLength, 279864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org masm->SizeOfCodeGeneratedSince(&check_codesize)); 280864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 281864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 282864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 283e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgvoid DebugCodegen::GenerateSlotDebugBreak(MacroAssembler* masm) { 284864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // In the places where a debug break slot is inserted no registers can contain 285864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // object pointers. 286864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Generate_DebugBreakCallHelper(masm, 0, 0, true); 287864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 288864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 289864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 290e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgvoid DebugCodegen::GeneratePlainReturnLiveEdit(MacroAssembler* masm) { 291864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org masm->ret(0); 292864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 293864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 294864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 295e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgvoid DebugCodegen::GenerateFrameDropperLiveEdit(MacroAssembler* masm) { 296864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference restarter_frame_function_slot = 297864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org ExternalReference::debug_restarter_frame_function_pointer_address( 298864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org masm->isolate()); 299864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(Operand::StaticVariable(restarter_frame_function_slot), Immediate(0)); 300864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 301864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // We do not know our frame height, but set esp based on ebp. 302864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ lea(esp, Operand(ebp, -1 * kPointerSize)); 303864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 304864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(edi); // Function. 305864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ pop(ebp); 306864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 307864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Load context from the function. 308864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); 309864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 310864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Get function code. 311864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); 312864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(edx, FieldOperand(edx, SharedFunctionInfo::kCodeOffset)); 313864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ lea(edx, FieldOperand(edx, Code::kHeaderSize)); 314864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 315864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Re-run JSFunction, edi is function, esi is context. 316864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ jmp(edx); 317864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} 318864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 3198d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org 3208d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.orgconst bool LiveEdit::kFrameDropperSupported = true; 321864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 322864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#undef __ 323864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 324864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} } // namespace v8::internal 325864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 326864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#endif // V8_TARGET_ARCH_X87 327