1212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be 33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file. 48bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org 5196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h" 68bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org 793a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_IA32 89dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/codegen.h" 10196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/debug.h" 118bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org 128bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org 1371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 { 1471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal { 158bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org 16245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.orgbool BreakLocationIterator::IsDebugBreakAtReturn() { 17381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org return Debug::IsDebugBreakAtReturn(rinfo()); 18245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org} 19245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org 20245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org 21245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org// Patch the JS frame exit code with a debug break call. See 22245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org// CodeGenerator::VisitReturnStatement and VirtualFrame::Exit in codegen-ia32.cc 23245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org// for the precise return instructions sequence. 24245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.orgvoid BreakLocationIterator::SetDebugBreakAtReturn() { 25e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(Assembler::kJSReturnSequenceLength >= 26ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Assembler::kCallInstructionLength); 27e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org rinfo()->PatchCodeWithCall( 28af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org debug_info_->GetIsolate()->builtins()->Return_DebugBreak()->entry(), 29ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Assembler::kJSReturnSequenceLength - Assembler::kCallInstructionLength); 30245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org} 31245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org 32245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org 33245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org// Restore the JS frame exit code. 34245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.orgvoid BreakLocationIterator::ClearDebugBreakAtReturn() { 35245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org rinfo()->PatchCode(original_rinfo()->pc(), 36ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org Assembler::kJSReturnSequenceLength); 37245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org} 38245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org 39245aa859d34fd516161c48ef4c69d38d9b889284iposva@chromium.org 40a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org// A debug break in the frame exit code is identified by the JS frame exit code 41a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org// having been patched with a call instruction. 42381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.orgbool Debug::IsDebugBreakAtReturn(RelocInfo* rinfo) { 43e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(RelocInfo::IsJSReturn(rinfo->rmode())); 449d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com return rinfo->IsPatchedReturnSequence(); 45381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org} 46381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 47381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org 482356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.orgbool BreakLocationIterator::IsDebugBreakAtSlot() { 49e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(IsDebugBreakSlot()); 502356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org // Check whether the debug break slot instructions have been patched. 512356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org return rinfo()->IsPatchedDebugBreakSlotSequence(); 522356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org} 532356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 542356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 552356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.orgvoid BreakLocationIterator::SetDebugBreakAtSlot() { 56e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(IsDebugBreakSlot()); 57e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org Isolate* isolate = debug_info_->GetIsolate(); 582356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org rinfo()->PatchCodeWithCall( 59af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org isolate->builtins()->Slot_DebugBreak()->entry(), 602356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org Assembler::kDebugBreakSlotLength - Assembler::kCallInstructionLength); 612356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org} 622356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 632356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 642356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.orgvoid BreakLocationIterator::ClearDebugBreakAtSlot() { 65e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(IsDebugBreakSlot()); 662356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org rinfo()->PatchCode(original_rinfo()->pc(), Assembler::kDebugBreakSlotLength); 672356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org} 682356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 69e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 70212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org#define __ ACCESS_MASM(masm) 718bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org 728bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.orgstatic void Generate_DebugBreakCallHelper(MacroAssembler* masm, 73d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org RegList object_regs, 74d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org RegList non_object_regs, 758bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org bool convert_call_to_jmp) { 768bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org // Enter an internal frame. 77c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com { 78c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FrameScope scope(masm, StackFrame::INTERNAL); 79c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 80212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org // Load padding words on stack. 81e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org for (int i = 0; i < LiveEdit::kFramePaddingInitialSize; i++) { 82e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org __ push(Immediate(Smi::FromInt(LiveEdit::kFramePaddingValue))); 83212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org } 84e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org __ push(Immediate(Smi::FromInt(LiveEdit::kFramePaddingInitialSize))); 85212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org 86c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Store the registers containing live values on the expression stack to 87c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // make sure that these are correctly updated during GC. Non object values 88c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // 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); 92c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (int i = 0; i < kNumJSCallerSaved; i++) { 93c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int r = JSCallerSavedCode(i); 94c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register reg = { r }; 95c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if ((object_regs & (1 << r)) != 0) { 96c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ push(reg); 97c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 98c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if ((non_object_regs & (1 << r)) != 0) { 99c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (FLAG_debug_code) { 100c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ test(reg, Immediate(0xc0000000)); 101594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Assert(zero, kUnableToEncodeValueAsSmi); 102c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 103c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ SmiTag(reg); 104c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ push(reg); 105d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org } 106d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org } 1078bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org 1088bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org#ifdef DEBUG 109c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ RecordComment("// Calling from debug break to runtime - come in - over"); 1108bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org#endif 111a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org __ Move(eax, Immediate(0)); // No arguments. 112c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ mov(ebx, Immediate(ExternalReference::debug_break(masm->isolate()))); 113c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 114f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CEntryStub ceb(masm->isolate(), 1); 115c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ CallStub(&ceb); 116c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 117212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org // Automatically find register that could be used after register restore. 118212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org // We need one register for padding skip instructions. 119212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org Register unused_reg = { -1 }; 120212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org 121c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Restore the register values containing object pointers from the 122c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // expression stack. 123c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (int i = kNumJSCallerSaved; --i >= 0;) { 124c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int r = JSCallerSavedCode(i); 125c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register reg = { r }; 126c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (FLAG_debug_code) { 127a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org __ Move(reg, Immediate(kDebugZapValue)); 128c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 129212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org bool taken = reg.code() == esi.code(); 130c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if ((object_regs & (1 << r)) != 0) { 131c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ pop(reg); 132212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org taken = true; 133c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 134c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if ((non_object_regs & (1 << r)) != 0) { 135c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ pop(reg); 136c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ SmiUntag(reg); 137212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org taken = true; 138212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org } 139212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org if (!taken) { 140212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org unused_reg = reg; 141c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 142d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org } 1438bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org 144e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(unused_reg.code() != -1); 145212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org 146212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org // Read current padding counter and skip corresponding number of words. 147212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org __ pop(unused_reg); 148212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org // We divide stored value by 2 (untagging) and multiply it by word's size. 149d6899c3545b051ec84363203d4235f883b4981bfulan@chromium.org STATIC_ASSERT(kSmiTagSize == 1 && kSmiShiftSize == 0); 150212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org __ lea(esp, Operand(esp, unused_reg, times_half_pointer_size, 0)); 151212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org 152c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Get rid of the internal frame. 153c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 1548bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org 1558bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org // If this call did not replace a call but patched other code then there will 1568bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org // be an unwanted return address left on the stack. Here we get rid of that. 1578bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org if (convert_call_to_jmp) { 158c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ add(esp, Immediate(kPointerSize)); 1598bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org } 1608bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org 1618bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org // Now that the break point has been handled, resume normal execution by 1628bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org // jumping to the target address intended by the caller and that was 1638bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org // overwritten by the address of DebugBreakXXX. 1648bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org ExternalReference after_break_target = 165fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org ExternalReference::debug_after_break_target_address(masm->isolate()); 1668bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org __ jmp(Operand::StaticVariable(after_break_target)); 1678bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org} 1688bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org 1698bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org 170d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid DebugCodegen::GenerateCallICStubDebugBreak(MacroAssembler* masm) { 171a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org // Register state for CallICStub 172a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org // ----------- S t a t e ------------- 173a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org // -- edx : type feedback slot (smi) 174a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org // -- edi : function 175a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org // ----------------------------------- 176a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org Generate_DebugBreakCallHelper(masm, edx.bit() | edi.bit(), 177a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org 0, false); 178a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org} 179a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org 180a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org 181d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) { 1828bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org // Register state for IC load call (from ic-ia32.cc). 1839aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Register receiver = LoadDescriptor::ReceiverRegister(); 1849aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Register name = LoadDescriptor::NameRegister(); 185248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org Generate_DebugBreakCallHelper(masm, receiver.bit() | name.bit(), 0, false); 1868bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org} 1878bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org 1888bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org 189d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid DebugCodegen::GenerateStoreICDebugBreak(MacroAssembler* masm) { 190b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Register state for IC store call (from ic-ia32.cc). 1919aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Register receiver = StoreDescriptor::ReceiverRegister(); 1929aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Register name = StoreDescriptor::NameRegister(); 1939aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Register value = StoreDescriptor::ValueRegister(); 194d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org Generate_DebugBreakCallHelper( 19570d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org masm, receiver.bit() | name.bit() | value.bit(), 0, false); 1968bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org} 1978bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org 1988bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org 199d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid DebugCodegen::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) { 2008bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org // Register state for keyed IC load call (from ic-ia32.cc). 2015de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org GenerateLoadICDebugBreak(masm); 2028bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org} 2038bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org 2048bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org 205d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid DebugCodegen::GenerateKeyedStoreICDebugBreak(MacroAssembler* masm) { 20670d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org // Register state for keyed IC store call (from ic-ia32.cc). 2079aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Register receiver = StoreDescriptor::ReceiverRegister(); 2089aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Register name = StoreDescriptor::NameRegister(); 2099aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Register value = StoreDescriptor::ValueRegister(); 210d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org Generate_DebugBreakCallHelper( 21170d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org masm, receiver.bit() | name.bit() | value.bit(), 0, false); 2128bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org} 2138bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org 2148bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org 215d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid DebugCodegen::GenerateCompareNilICDebugBreak(MacroAssembler* masm) { 216f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org // Register state for CompareNil IC 217f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org // ----------- S t a t e ------------- 218f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org // -- eax : value 219f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org // ----------------------------------- 220f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org Generate_DebugBreakCallHelper(masm, eax.bit(), 0, false); 221f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org} 222f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 223f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 224d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid DebugCodegen::GenerateReturnDebugBreak(MacroAssembler* masm) { 2258bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org // Register state just before return from JS function (from codegen-ia32.cc). 2268bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org // ----------- S t a t e ------------- 2278bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org // -- eax: return value 2288bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org // ----------------------------------- 229d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org Generate_DebugBreakCallHelper(masm, eax.bit(), 0, true); 2308bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org} 2318bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org 2328bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org 233d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid DebugCodegen::GenerateCallFunctionStubDebugBreak(MacroAssembler* masm) { 234fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // Register state for CallFunctionStub (from code-stubs-ia32.cc). 2358bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org // ----------- S t a t e ------------- 236c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // -- edi: function 2378bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org // ----------------------------------- 238c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org Generate_DebugBreakCallHelper(masm, edi.bit(), 0, false); 2398bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org} 2408bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org 2418bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org 242d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid DebugCodegen::GenerateCallConstructStubDebugBreak(MacroAssembler* masm) { 243fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // Register state for CallConstructStub (from code-stubs-ia32.cc). 244fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // eax is the actual number of arguments not encoded as a smi see comment 245fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // above IC call. 246fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // ----------- S t a t e ------------- 247fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // -- eax: number of arguments (not smi) 248fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // -- edi: constructor function 249fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // ----------------------------------- 250fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // The number of arguments in eax is not smi encoded. 251fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org Generate_DebugBreakCallHelper(masm, edi.bit(), eax.bit(), false); 252fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org} 253fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org 254fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org 255d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid DebugCodegen::GenerateCallConstructStubRecordDebugBreak( 256d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org MacroAssembler* masm) { 257fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // Register state for CallConstructStub (from code-stubs-ia32.cc). 258fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // eax is the actual number of arguments not encoded as a smi see comment 259fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // above IC call. 260fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // ----------- S t a t e ------------- 261fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // -- eax: number of arguments (not smi) 262f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // -- ebx: feedback array 263f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // -- edx: feedback slot (smi) 264fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // -- edi: constructor function 265fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // ----------------------------------- 266fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // The number of arguments in eax is not smi encoded. 267f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Generate_DebugBreakCallHelper(masm, ebx.bit() | edx.bit() | edi.bit(), 268f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org eax.bit(), false); 269fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org} 270fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org 271fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org 272d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid DebugCodegen::GenerateSlot(MacroAssembler* masm) { 2732356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org // Generate enough nop's to make space for a call instruction. 2742356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org Label check_codesize; 2752356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org __ bind(&check_codesize); 2762356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org __ RecordDebugBreakSlot(); 27764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ Nop(Assembler::kDebugBreakSlotLength); 278e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(Assembler::kDebugBreakSlotLength, 2792356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org masm->SizeOfCodeGeneratedSince(&check_codesize)); 2802356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org} 2812356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 2822356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 283d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid DebugCodegen::GenerateSlotDebugBreak(MacroAssembler* masm) { 2842356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org // In the places where a debug break slot is inserted no registers can contain 2852356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org // object pointers. 286d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org Generate_DebugBreakCallHelper(masm, 0, 0, true); 2872356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org} 2882356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 2892356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 290d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid DebugCodegen::GeneratePlainReturnLiveEdit(MacroAssembler* masm) { 291357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org masm->ret(0); 292357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org} 293357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org 2942356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 295d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid DebugCodegen::GenerateFrameDropperLiveEdit(MacroAssembler* masm) { 296e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org ExternalReference restarter_frame_function_slot = 297fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org ExternalReference::debug_restarter_frame_function_pointer_address( 298fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org masm->isolate()); 299e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org __ mov(Operand::StaticVariable(restarter_frame_function_slot), Immediate(0)); 300e90029b96bc4097e0f14d33cc086030d7ad5007awhesse@chromium.org 301357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org // We do not know our frame height, but set esp based on ebp. 302ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org __ lea(esp, Operand(ebp, -1 * kPointerSize)); 303357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org 304ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org __ pop(edi); // Function. 305357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org __ pop(ebp); 306357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org 307ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org // Load context from the function. 308ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); 309ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 310357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org // Get function code. 311357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); 312357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org __ mov(edx, FieldOperand(edx, SharedFunctionInfo::kCodeOffset)); 313357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org __ lea(edx, FieldOperand(edx, Code::kHeaderSize)); 314357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org 315357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org // Re-run JSFunction, edi is function, esi is context. 316c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ jmp(edx); 317357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org} 318357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org 319e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org 320e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgconst bool LiveEdit::kFrameDropperSupported = true; 321357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org 322ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org#undef __ 323357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org 3248bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org} } // namespace v8::internal 3259dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 3269dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com#endif // V8_TARGET_ARCH_IA32 327