1212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 25ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// Redistribution and use in source and binary forms, with or without 35ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// modification, are permitted provided that the following conditions are 45ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// met: 55ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// 65ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// * Redistributions of source code must retain the above copyright 75ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// notice, this list of conditions and the following disclaimer. 85ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// * Redistributions in binary form must reproduce the above 95ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// copyright notice, this list of conditions and the following 105ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// disclaimer in the documentation and/or other materials provided 115ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// with the distribution. 125ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// * Neither the name of Google Inc. nor the names of its 135ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// contributors may be used to endorse or promote products derived 145ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// from this software without specific prior written permission. 155ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// 165ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 175ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 185ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 195ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 205ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 215ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 225ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 235ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 245ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 255ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 265ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 275ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org 2871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org#include "v8.h" 2971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 3093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_X64 319dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 3244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org#include "assembler.h" 3344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org#include "codegen.h" 3471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org#include "debug.h" 3571affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 3671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 3771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 { 3871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal { 3971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 4071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org#ifdef ENABLE_DEBUGGER_SUPPORT 4171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 425d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.orgbool BreakLocationIterator::IsDebugBreakAtReturn() { 435d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org return Debug::IsDebugBreakAtReturn(rinfo()); 445d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org} 455d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 465d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 475d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org// Patch the JS frame exit code with a debug break call. See 485d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org// CodeGenerator::VisitReturnStatement and VirtualFrame::Exit in codegen-x64.cc 495d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org// for the precise return instructions sequence. 505d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.orgvoid BreakLocationIterator::SetDebugBreakAtReturn() { 51594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org ASSERT(Assembler::kJSReturnSequenceLength >= Assembler::kCallSequenceLength); 52ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org rinfo()->PatchCodeWithCall( 53ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Isolate::Current()->debug()->debug_break_return()->entry(), 54594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Assembler::kJSReturnSequenceLength - Assembler::kCallSequenceLength); 555d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org} 565d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 575d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 585d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org// Restore the JS frame exit code. 595d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.orgvoid BreakLocationIterator::ClearDebugBreakAtReturn() { 605d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org rinfo()->PatchCode(original_rinfo()->pc(), 615d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org Assembler::kJSReturnSequenceLength); 625d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org} 635d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 645d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 655d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org// A debug break in the frame exit code is identified by the JS frame exit code 665d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org// having been patched with a call instruction. 6771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgbool Debug::IsDebugBreakAtReturn(v8::internal::RelocInfo* rinfo) { 68defbd109bb9bd556bb8ece103c3b340d3552155ekasperl@chromium.org ASSERT(RelocInfo::IsJSReturn(rinfo->rmode())); 699d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com return rinfo->IsPatchedReturnSequence(); 7071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} 7171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 725d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 735d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.orgbool BreakLocationIterator::IsDebugBreakAtSlot() { 745d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org ASSERT(IsDebugBreakSlot()); 755d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Check whether the debug break slot instructions have been patched. 765d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org return !Assembler::IsNop(rinfo()->pc()); 775d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org} 785d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 795d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 805d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.orgvoid BreakLocationIterator::SetDebugBreakAtSlot() { 815d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org ASSERT(IsDebugBreakSlot()); 825d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org rinfo()->PatchCodeWithCall( 83ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Isolate::Current()->debug()->debug_break_slot()->entry(), 84594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org Assembler::kDebugBreakSlotLength - Assembler::kCallSequenceLength); 855d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org} 865d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 875d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 885d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.orgvoid BreakLocationIterator::ClearDebugBreakAtSlot() { 895d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org ASSERT(IsDebugBreakSlot()); 905d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org rinfo()->PatchCode(original_rinfo()->pc(), Assembler::kDebugBreakSlotLength); 915d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org} 925d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 93d6899c3545b051ec84363203d4235f883b4981bfulan@chromium.orgconst bool Debug::FramePaddingLayout::kIsSupported = true; 94212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org 955d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 96911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org#define __ ACCESS_MASM(masm) 97911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 985d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 99911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.orgstatic void Generate_DebugBreakCallHelper(MacroAssembler* masm, 100d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org RegList object_regs, 101d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org RegList non_object_regs, 102911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org bool convert_call_to_jmp) { 103911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Enter an internal frame. 104c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com { 105c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FrameScope scope(masm, StackFrame::INTERNAL); 106c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 107d6899c3545b051ec84363203d4235f883b4981bfulan@chromium.org // Load padding words on stack. 108d6899c3545b051ec84363203d4235f883b4981bfulan@chromium.org for (int i = 0; i < Debug::FramePaddingLayout::kInitialSize; i++) { 109d6899c3545b051ec84363203d4235f883b4981bfulan@chromium.org __ Push(Smi::FromInt(Debug::FramePaddingLayout::kPaddingValue)); 110d6899c3545b051ec84363203d4235f883b4981bfulan@chromium.org } 111d6899c3545b051ec84363203d4235f883b4981bfulan@chromium.org __ Push(Smi::FromInt(Debug::FramePaddingLayout::kInitialSize)); 112d6899c3545b051ec84363203d4235f883b4981bfulan@chromium.org 113c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Store the registers containing live values on the expression stack to 114c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // make sure that these are correctly updated during GC. Non object values 115c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // are stored as as two smis causing it to be untouched by GC. 116c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT((object_regs & ~kJSCallerSaved) == 0); 117c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT((non_object_regs & ~kJSCallerSaved) == 0); 118c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT((object_regs & non_object_regs) == 0); 119c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (int i = 0; i < kNumJSCallerSaved; i++) { 120c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int r = JSCallerSavedCode(i); 121c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register reg = { r }; 122c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(!reg.is(kScratchRegister)); 123c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if ((object_regs & (1 << r)) != 0) { 124c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ push(reg); 125c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 126c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Store the 64-bit value as two smis. 127c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if ((non_object_regs & (1 << r)) != 0) { 128c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ movq(kScratchRegister, reg); 129c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Integer32ToSmi(reg, reg); 130c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ push(reg); 131c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ sar(kScratchRegister, Immediate(32)); 132c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Integer32ToSmi(kScratchRegister, kScratchRegister); 133c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ push(kScratchRegister); 134c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 135d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org } 136911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 137911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org#ifdef DEBUG 138c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ RecordComment("// Calling from debug break to runtime - come in - over"); 139911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org#endif 140c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Set(rax, 0); // No arguments (argc == 0). 141c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ movq(rbx, ExternalReference::debug_break(masm->isolate())); 142c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 143c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com CEntryStub ceb(1); 144c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ CallStub(&ceb); 145c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 146c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Restore the register values from the expression stack. 147c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com for (int i = kNumJSCallerSaved - 1; i >= 0; i--) { 148c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com int r = JSCallerSavedCode(i); 149c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Register reg = { r }; 150c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (FLAG_debug_code) { 151c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Set(reg, kDebugZapValue); 152c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 153c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if ((object_regs & (1 << r)) != 0) { 154c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ pop(reg); 155c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 156c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Reconstruct the 64-bit value from two smis. 157c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if ((non_object_regs & (1 << r)) != 0) { 158c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ pop(kScratchRegister); 159c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ SmiToInteger32(kScratchRegister, kScratchRegister); 160c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ shl(kScratchRegister, Immediate(32)); 161c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ pop(reg); 162c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ SmiToInteger32(reg, reg); 163c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ or_(reg, kScratchRegister); 164c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 165d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org } 166911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 167d6899c3545b051ec84363203d4235f883b4981bfulan@chromium.org // Read current padding counter and skip corresponding number of words. 168d6899c3545b051ec84363203d4235f883b4981bfulan@chromium.org __ pop(kScratchRegister); 169d6899c3545b051ec84363203d4235f883b4981bfulan@chromium.org __ SmiToInteger32(kScratchRegister, kScratchRegister); 170d6899c3545b051ec84363203d4235f883b4981bfulan@chromium.org __ lea(rsp, Operand(rsp, kScratchRegister, times_pointer_size, 0)); 171d6899c3545b051ec84363203d4235f883b4981bfulan@chromium.org 172c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Get rid of the internal frame. 173c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 174911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 175911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // If this call did not replace a call but patched other code then there will 176911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // be an unwanted return address left on the stack. Here we get rid of that. 177911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org if (convert_call_to_jmp) { 178d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org __ addq(rsp, Immediate(kPointerSize)); 179911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org } 180911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 181911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Now that the break point has been handled, resume normal execution by 182911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // jumping to the target address intended by the caller and that was 183911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // overwritten by the address of DebugBreakXXX. 184911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org ExternalReference after_break_target = 185ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ExternalReference(Debug_Address::AfterBreakTarget(), masm->isolate()); 186911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ movq(kScratchRegister, after_break_target); 187911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org __ jmp(Operand(kScratchRegister, 0)); 188911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org} 189911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 190911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 1915d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.orgvoid Debug::GenerateLoadICDebugBreak(MacroAssembler* masm) { 1925d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Register state for IC load call (from ic-x64.cc). 193911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // ----------- S t a t e ------------- 1945d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // -- rax : receiver 1955d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // -- rcx : name 196911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // ----------------------------------- 1975d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org Generate_DebugBreakCallHelper(masm, rax.bit() | rcx.bit(), 0, false); 19871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} 19971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 200911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 2015d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.orgvoid Debug::GenerateStoreICDebugBreak(MacroAssembler* masm) { 2025d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Register state for IC store call (from ic-x64.cc). 203911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // ----------- S t a t e ------------- 2045d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // -- rax : value 2055d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // -- rcx : name 2065d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // -- rdx : receiver 207911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // ----------------------------------- 2085d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org Generate_DebugBreakCallHelper( 2095d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org masm, rax.bit() | rcx.bit() | rdx.bit(), 0, false); 21071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} 21171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 212911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 21371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgvoid Debug::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) { 214911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Register state for keyed IC load call (from ic-x64.cc). 215911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // ----------- S t a t e ------------- 2161af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org // -- rax : key 2171af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org // -- rdx : receiver 218911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // ----------------------------------- 219d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org Generate_DebugBreakCallHelper(masm, rax.bit() | rdx.bit(), 0, false); 22071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} 22171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 222911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 22371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgvoid Debug::GenerateKeyedStoreICDebugBreak(MacroAssembler* masm) { 224911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // Register state for keyed IC load call (from ic-x64.cc). 225911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // ----------- S t a t e ------------- 226911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // -- rax : value 2279dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // -- rcx : key 2289dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com // -- rdx : receiver 229911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // ----------------------------------- 230d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org Generate_DebugBreakCallHelper( 231d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org masm, rax.bit() | rcx.bit() | rdx.bit(), 0, false); 23271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} 23371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 234911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 235f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.orgvoid Debug::GenerateCompareNilICDebugBreak(MacroAssembler* masm) { 236f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org // Register state for CompareNil IC 237f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org // ----------- S t a t e ------------- 238f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org // -- rax : value 239f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org // ----------------------------------- 240f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org Generate_DebugBreakCallHelper(masm, rax.bit(), 0, false); 241f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org} 242f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 243f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 2445d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.orgvoid Debug::GenerateCallICDebugBreak(MacroAssembler* masm) { 2455d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Register state for IC call call (from ic-x64.cc) 246911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // ----------- S t a t e ------------- 2475d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // -- rcx: function name 248911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // ----------------------------------- 2495d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org Generate_DebugBreakCallHelper(masm, rcx.bit(), 0, false); 25071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} 25171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 252911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 2535d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.orgvoid Debug::GenerateReturnDebugBreak(MacroAssembler* masm) { 2545d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Register state just before return from JS function (from codegen-x64.cc). 255911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // ----------- S t a t e ------------- 2565d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // -- rax: return value 257911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // ----------------------------------- 2585d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org Generate_DebugBreakCallHelper(masm, rax.bit(), 0, true); 25971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} 26071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 261911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 262c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.orgvoid Debug::GenerateCallFunctionStubDebugBreak(MacroAssembler* masm) { 263fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // Register state for CallFunctionStub (from code-stubs-x64.cc). 264911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // ----------- S t a t e ------------- 265c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // -- rdi : function 266911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org // ----------------------------------- 267c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org Generate_DebugBreakCallHelper(masm, rdi.bit(), 0, false); 26871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} 26971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 270911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 271fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.orgvoid Debug::GenerateCallFunctionStubRecordDebugBreak(MacroAssembler* masm) { 272fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // Register state for CallFunctionStub (from code-stubs-x64.cc). 273fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // ----------- S t a t e ------------- 274fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // -- rdi : function 275fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // -- rbx: cache cell for call target 276fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // ----------------------------------- 277fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org Generate_DebugBreakCallHelper(masm, rbx.bit() | rdi.bit(), 0, false); 278fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org} 279fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org 280fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org 281fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.orgvoid Debug::GenerateCallConstructStubDebugBreak(MacroAssembler* masm) { 282fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // Register state for CallConstructStub (from code-stubs-x64.cc). 283fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // rax is the actual number of arguments not encoded as a smi, see comment 284fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // above IC call. 285fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // ----------- S t a t e ------------- 286fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // -- rax: number of arguments 287fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // ----------------------------------- 288fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // The number of arguments in rax is not smi encoded. 289fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org Generate_DebugBreakCallHelper(masm, rdi.bit(), rax.bit(), false); 290fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org} 291fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org 292fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org 293fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.orgvoid Debug::GenerateCallConstructStubRecordDebugBreak(MacroAssembler* masm) { 294fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // Register state for CallConstructStub (from code-stubs-x64.cc). 295fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // rax is the actual number of arguments not encoded as a smi, see comment 296fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // above IC call. 297fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // ----------- S t a t e ------------- 298fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // -- rax: number of arguments 299fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // -- rbx: cache cell for call target 300fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // ----------------------------------- 301fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // The number of arguments in rax is not smi encoded. 302fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org Generate_DebugBreakCallHelper(masm, rbx.bit() | rdi.bit(), rax.bit(), false); 303fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org} 304fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org 305fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org 3062356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.orgvoid Debug::GenerateSlot(MacroAssembler* masm) { 3072356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org // Generate enough nop's to make space for a call instruction. 3082356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org Label check_codesize; 3092356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org __ bind(&check_codesize); 3102356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org __ RecordDebugBreakSlot(); 31164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ Nop(Assembler::kDebugBreakSlotLength); 3122356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org ASSERT_EQ(Assembler::kDebugBreakSlotLength, 3132356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org masm->SizeOfCodeGeneratedSince(&check_codesize)); 3142356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org} 3152356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 3162356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 3172356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.orgvoid Debug::GenerateSlotDebugBreak(MacroAssembler* masm) { 3182356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org // In the places where a debug break slot is inserted no registers can contain 3192356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org // object pointers. 320d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org Generate_DebugBreakCallHelper(masm, 0, 0, true); 3212356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org} 3222356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 3232356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 324357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.orgvoid Debug::GeneratePlainReturnLiveEdit(MacroAssembler* masm) { 325ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org masm->ret(0); 326357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org} 327357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org 3282356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org 329357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.orgvoid Debug::GenerateFrameDropperLiveEdit(MacroAssembler* masm) { 330ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org ExternalReference restarter_frame_function_slot = 331ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ExternalReference(Debug_Address::RestarterFrameFunctionPointer(), 332ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org masm->isolate()); 333ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org __ movq(rax, restarter_frame_function_slot); 334ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org __ movq(Operand(rax, 0), Immediate(0)); 335ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 336ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org // We do not know our frame height, but set rsp based on rbp. 337ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org __ lea(rsp, Operand(rbp, -1 * kPointerSize)); 338ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 339ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org __ pop(rdi); // Function. 340ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org __ pop(rbp); 341ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 342ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org // Load context from the function. 343ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); 344ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 345ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org // Get function code. 346ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org __ movq(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); 347ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org __ movq(rdx, FieldOperand(rdx, SharedFunctionInfo::kCodeOffset)); 348ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org __ lea(rdx, FieldOperand(rdx, Code::kHeaderSize)); 349ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 350ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org // Re-run JSFunction, rdi is function, rsi is context. 351ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org __ jmp(rdx); 352357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org} 353357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org 354ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.orgconst bool Debug::kFrameDropperSupported = true; 355ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 356911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org#undef __ 357911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org 35871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org#endif // ENABLE_DEBUGGER_SUPPORT 35971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 36071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} } // namespace v8::internal 3619dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 3629dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com#endif // V8_TARGET_ARCH_X64 363