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. 45ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org 5196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h" 671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 793a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_X64 89dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/assembler.h" 10196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/codegen.h" 11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/debug.h" 1271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 1371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 1471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 { 1571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal { 1671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 175d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.orgbool BreakLocationIterator::IsDebugBreakAtReturn() { 185d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org return Debug::IsDebugBreakAtReturn(rinfo()); 195d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org} 205d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 215d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 225d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org// Patch the JS frame exit code with a debug break call. See 235d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org// CodeGenerator::VisitReturnStatement and VirtualFrame::Exit in codegen-x64.cc 245d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org// for the precise return instructions sequence. 255d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.orgvoid BreakLocationIterator::SetDebugBreakAtReturn() { 26e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(Assembler::kJSReturnSequenceLength >= Assembler::kCallSequenceLength); 27ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org rinfo()->PatchCodeWithCall( 28af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org debug_info_->GetIsolate()->builtins()->Return_DebugBreak()->entry(), 29594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Assembler::kJSReturnSequenceLength - Assembler::kCallSequenceLength); 305d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org} 315d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 325d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 335d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org// Restore the JS frame exit code. 345d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.orgvoid BreakLocationIterator::ClearDebugBreakAtReturn() { 355d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org rinfo()->PatchCode(original_rinfo()->pc(), 365d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org Assembler::kJSReturnSequenceLength); 375d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org} 385d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 395d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 405d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org// A debug break in the frame exit code is identified by the JS frame exit code 415d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org// having been patched with a call instruction. 4271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgbool Debug::IsDebugBreakAtReturn(v8::internal::RelocInfo* rinfo) { 43e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(RelocInfo::IsJSReturn(rinfo->rmode())); 449d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com return rinfo->IsPatchedReturnSequence(); 4571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} 4671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 475d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 485d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.orgbool BreakLocationIterator::IsDebugBreakAtSlot() { 49e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(IsDebugBreakSlot()); 505d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Check whether the debug break slot instructions have been patched. 51e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org return rinfo()->IsPatchedDebugBreakSlotSequence(); 525d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org} 535d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 545d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 555d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.orgvoid BreakLocationIterator::SetDebugBreakAtSlot() { 56e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(IsDebugBreakSlot()); 575d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org rinfo()->PatchCodeWithCall( 58af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org debug_info_->GetIsolate()->builtins()->Slot_DebugBreak()->entry(), 59594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Assembler::kDebugBreakSlotLength - Assembler::kCallSequenceLength); 605d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org} 615d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 625d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 635d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.orgvoid BreakLocationIterator::ClearDebugBreakAtSlot() { 64e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(IsDebugBreakSlot()); 655d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org rinfo()->PatchCode(original_rinfo()->pc(), Assembler::kDebugBreakSlotLength); 665d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org} 675d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 685d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 69911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org#define __ ACCESS_MASM(masm) 70911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 715d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 72911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgstatic void Generate_DebugBreakCallHelper(MacroAssembler* masm, 73d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org RegList object_regs, 74d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org RegList non_object_regs, 75911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org bool convert_call_to_jmp) { 76911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Enter an internal frame. 77c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com { 78c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FrameScope scope(masm, StackFrame::INTERNAL); 79c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 80d6899c3545b051ec84363203d4235f883b4981bfulan@chromium.org // Load padding words on stack. 81e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org for (int i = 0; i < LiveEdit::kFramePaddingInitialSize; i++) { 82e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org __ Push(Smi::FromInt(LiveEdit::kFramePaddingValue)); 83d6899c3545b051ec84363203d4235f883b4981bfulan@chromium.org } 84e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org __ Push(Smi::FromInt(LiveEdit::kFramePaddingInitialSize)); 85d6899c3545b051ec84363203d4235f883b4981bfulan@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 as two smis 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 }; 95e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!reg.is(kScratchRegister)); 96c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if ((object_regs & (1 << r)) != 0) { 97763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(reg); 98c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 99c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if ((non_object_regs & (1 << r)) != 0) { 1002ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ PushRegisterAsTwoSmis(reg); 101c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 102d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org } 103911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 104911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org#ifdef DEBUG 105c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ RecordComment("// Calling from debug break to runtime - come in - over"); 106911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org#endif 107c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Set(rax, 0); // No arguments (argc == 0). 108e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ Move(rbx, ExternalReference::debug_break(masm->isolate())); 109c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 110f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CEntryStub ceb(masm->isolate(), 1); 111c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ CallStub(&ceb); 112c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 113c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Restore the register values from the expression stack. 114c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (int i = kNumJSCallerSaved - 1; i >= 0; i--) { 115c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int r = JSCallerSavedCode(i); 116c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register reg = { r }; 117c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (FLAG_debug_code) { 118c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Set(reg, kDebugZapValue); 119c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 120c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if ((object_regs & (1 << r)) != 0) { 121763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(reg); 122c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 123c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Reconstruct the 64-bit value from two smis. 124c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if ((non_object_regs & (1 << r)) != 0) { 1252ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org __ PopRegisterAsTwoSmis(reg); 126c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 127d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org } 128911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 129d6899c3545b051ec84363203d4235f883b4981bfulan@chromium.org // Read current padding counter and skip corresponding number of words. 130763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(kScratchRegister); 131d6899c3545b051ec84363203d4235f883b4981bfulan@chromium.org __ SmiToInteger32(kScratchRegister, kScratchRegister); 132895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(rsp, Operand(rsp, kScratchRegister, times_pointer_size, 0)); 133d6899c3545b051ec84363203d4235f883b4981bfulan@chromium.org 134c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Get rid of the internal frame. 135c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 136911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 137911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // If this call did not replace a call but patched other code then there will 138911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // be an unwanted return address left on the stack. Here we get rid of that. 139911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org if (convert_call_to_jmp) { 140fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ addp(rsp, Immediate(kPCOnStackSize)); 141911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 142911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 143911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Now that the break point has been handled, resume normal execution by 144911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // jumping to the target address intended by the caller and that was 145911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // overwritten by the address of DebugBreakXXX. 146911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org ExternalReference after_break_target = 147fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org ExternalReference::debug_after_break_target_address(masm->isolate()); 148e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ Move(kScratchRegister, after_break_target); 149f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org __ Jump(Operand(kScratchRegister, 0)); 150911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 151911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 152911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 153d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid DebugCodegen::GenerateCallICStubDebugBreak(MacroAssembler* masm) { 154a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org // Register state for CallICStub 155a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org // ----------- S t a t e ------------- 156a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org // -- rdx : type feedback slot (smi) 157a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org // -- rdi : function 158a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org // ----------------------------------- 159a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org Generate_DebugBreakCallHelper(masm, rdx.bit() | rdi.bit(), 0, false); 160a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org} 161a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org 162a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org 163d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) { 1645d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Register state for IC load call (from ic-x64.cc). 1659aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Register receiver = LoadDescriptor::ReceiverRegister(); 1669aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Register name = LoadDescriptor::NameRegister(); 167248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org Generate_DebugBreakCallHelper(masm, receiver.bit() | name.bit(), 0, false); 16871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} 16971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 170911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 171d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid DebugCodegen::GenerateStoreICDebugBreak(MacroAssembler* masm) { 1725d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Register state for IC store call (from ic-x64.cc). 1739aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Register receiver = StoreDescriptor::ReceiverRegister(); 1749aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Register name = StoreDescriptor::NameRegister(); 1759aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Register value = StoreDescriptor::ValueRegister(); 1765d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org Generate_DebugBreakCallHelper( 17770d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org masm, receiver.bit() | name.bit() | value.bit(), 0, false); 17871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} 17971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 180911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 181d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid DebugCodegen::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) { 182911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Register state for keyed IC load call (from ic-x64.cc). 1835de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org GenerateLoadICDebugBreak(masm); 18471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} 18571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 186911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 187d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid DebugCodegen::GenerateKeyedStoreICDebugBreak(MacroAssembler* masm) { 18870d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org // Register state for keyed IC store call (from ic-x64.cc). 1899aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Register receiver = StoreDescriptor::ReceiverRegister(); 1909aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Register name = StoreDescriptor::NameRegister(); 1919aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org Register value = StoreDescriptor::ValueRegister(); 192d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org Generate_DebugBreakCallHelper( 19370d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org masm, receiver.bit() | name.bit() | value.bit(), 0, false); 19471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} 19571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 196911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 197d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid DebugCodegen::GenerateCompareNilICDebugBreak(MacroAssembler* masm) { 198f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org // Register state for CompareNil IC 199f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org // ----------- S t a t e ------------- 200f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org // -- rax : value 201f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org // ----------------------------------- 202f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org Generate_DebugBreakCallHelper(masm, rax.bit(), 0, false); 203f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org} 204f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 205f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 206d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid DebugCodegen::GenerateReturnDebugBreak(MacroAssembler* masm) { 2075d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Register state just before return from JS function (from codegen-x64.cc). 208911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // ----------- S t a t e ------------- 2095d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // -- rax: return value 210911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // ----------------------------------- 2115d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org Generate_DebugBreakCallHelper(masm, rax.bit(), 0, true); 21271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} 21371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 214911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 215d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid DebugCodegen::GenerateCallFunctionStubDebugBreak(MacroAssembler* masm) { 216fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // Register state for CallFunctionStub (from code-stubs-x64.cc). 217911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // ----------- S t a t e ------------- 218c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // -- rdi : function 219911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // ----------------------------------- 220c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org Generate_DebugBreakCallHelper(masm, rdi.bit(), 0, false); 22171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} 22271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 223911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 224d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid DebugCodegen::GenerateCallConstructStubDebugBreak(MacroAssembler* masm) { 225fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // Register state for CallConstructStub (from code-stubs-x64.cc). 226fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // rax is the actual number of arguments not encoded as a smi, see comment 227fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // above IC call. 228fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // ----------- S t a t e ------------- 229fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // -- rax: number of arguments 230fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // ----------------------------------- 231fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // The number of arguments in rax is not smi encoded. 232fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org Generate_DebugBreakCallHelper(masm, rdi.bit(), rax.bit(), false); 233fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org} 234fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org 235fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org 236d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid DebugCodegen::GenerateCallConstructStubRecordDebugBreak( 237d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org MacroAssembler* masm) { 238fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // Register state for CallConstructStub (from code-stubs-x64.cc). 239fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // rax is the actual number of arguments not encoded as a smi, see comment 240fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // above IC call. 241fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // ----------- S t a t e ------------- 242fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // -- rax: number of arguments 243f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // -- rbx: feedback array 244f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // -- rdx: feedback slot (smi) 245fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // ----------------------------------- 246fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // The number of arguments in rax is not smi encoded. 247f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Generate_DebugBreakCallHelper(masm, rbx.bit() | rdx.bit() | rdi.bit(), 248f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org rax.bit(), false); 249fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org} 250fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org 251fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org 252d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid DebugCodegen::GenerateSlot(MacroAssembler* masm) { 2532356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org // Generate enough nop's to make space for a call instruction. 2542356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org Label check_codesize; 2552356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org __ bind(&check_codesize); 2562356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org __ RecordDebugBreakSlot(); 25764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ Nop(Assembler::kDebugBreakSlotLength); 258e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(Assembler::kDebugBreakSlotLength, 2592356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org masm->SizeOfCodeGeneratedSince(&check_codesize)); 2602356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org} 2612356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 2622356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 263d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid DebugCodegen::GenerateSlotDebugBreak(MacroAssembler* masm) { 2642356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org // In the places where a debug break slot is inserted no registers can contain 2652356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org // object pointers. 266d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org Generate_DebugBreakCallHelper(masm, 0, 0, true); 2672356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org} 2682356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 2692356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 270d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid DebugCodegen::GeneratePlainReturnLiveEdit(MacroAssembler* masm) { 271ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org masm->ret(0); 272357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org} 273357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org 2742356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 275d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid DebugCodegen::GenerateFrameDropperLiveEdit(MacroAssembler* masm) { 276ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org ExternalReference restarter_frame_function_slot = 277fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org ExternalReference::debug_restarter_frame_function_pointer_address( 278fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org masm->isolate()); 279e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ Move(rax, restarter_frame_function_slot); 28043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(Operand(rax, 0), Immediate(0)); 281ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 282ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org // We do not know our frame height, but set rsp based on rbp. 283895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(rsp, Operand(rbp, -1 * kPointerSize)); 284ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 285763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(rdi); // Function. 286763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ popq(rbp); 287ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 288ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org // Load context from the function. 28943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); 290ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 291ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org // Get function code. 29243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); 29343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rdx, FieldOperand(rdx, SharedFunctionInfo::kCodeOffset)); 294895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(rdx, FieldOperand(rdx, Code::kHeaderSize)); 295ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 296ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org // Re-run JSFunction, rdi is function, rsi is context. 297ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org __ jmp(rdx); 298357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org} 299357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org 300e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgconst bool LiveEdit::kFrameDropperSupported = true; 301ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 302911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org#undef __ 303911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 30471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} } // namespace v8::internal 3059dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 3069dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com#endif // V8_TARGET_ARCH_X64 307