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