18b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch// Copyright 2011 the V8 project authors. All rights reserved.
2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without
3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met:
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions of source code must retain the above copyright
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       notice, this list of conditions and the following disclaimer.
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions in binary form must reproduce the above
9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       copyright notice, this list of conditions and the following
10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       disclaimer in the documentation and/or other materials provided
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       with the distribution.
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Neither the name of Google Inc. nor the names of its
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       contributors may be used to endorse or promote products derived
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       from this software without specific prior written permission.
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "v8.h"
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
30f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#if defined(V8_TARGET_ARCH_IA32)
31f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
328b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch#include "codegen.h"
33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "debug.h"
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT
40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool BreakLocationIterator::IsDebugBreakAtReturn() {
42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Debug::IsDebugBreakAtReturn(rinfo());
43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Patch the JS frame exit code with a debug break call. See
47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// CodeGenerator::VisitReturnStatement and VirtualFrame::Exit in codegen-ia32.cc
48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// for the precise return instructions sequence.
49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid BreakLocationIterator::SetDebugBreakAtReturn() {
50d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  ASSERT(Assembler::kJSReturnSequenceLength >=
51d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block         Assembler::kCallInstructionLength);
5244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* isolate = Isolate::Current();
5344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  rinfo()->PatchCodeWithCall(isolate->debug()->debug_break_return()->entry(),
54d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      Assembler::kJSReturnSequenceLength - Assembler::kCallInstructionLength);
55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Restore the JS frame exit code.
59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid BreakLocationIterator::ClearDebugBreakAtReturn() {
60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  rinfo()->PatchCode(original_rinfo()->pc(),
61d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                     Assembler::kJSReturnSequenceLength);
62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A debug break in the frame exit code is identified by the JS frame exit code
66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// having been patched with a call instruction.
67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Debug::IsDebugBreakAtReturn(RelocInfo* rinfo) {
68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(RelocInfo::IsJSReturn(rinfo->rmode()));
693ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  return rinfo->IsPatchedReturnSequence();
70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochbool BreakLocationIterator::IsDebugBreakAtSlot() {
747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  ASSERT(IsDebugBreakSlot());
757f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Check whether the debug break slot instructions have been patched.
767f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  return rinfo()->IsPatchedDebugBreakSlotSequence();
777f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
787f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
797f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakLocationIterator::SetDebugBreakAtSlot() {
817f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  ASSERT(IsDebugBreakSlot());
8244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* isolate = Isolate::Current();
837f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  rinfo()->PatchCodeWithCall(
8444f0eee88ff00398ff7f715fab053374d808c90dSteve Block      isolate->debug()->debug_break_slot()->entry(),
857f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch      Assembler::kDebugBreakSlotLength - Assembler::kCallInstructionLength);
867f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
877f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
897f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakLocationIterator::ClearDebugBreakAtSlot() {
907f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  ASSERT(IsDebugBreakSlot());
917f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  rinfo()->PatchCode(original_rinfo()->pc(), Assembler::kDebugBreakSlotLength);
927f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
937f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
947f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define __ ACCESS_MASM(masm)
96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_DebugBreakCallHelper(MacroAssembler* masm,
9980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                          RegList object_regs,
10080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen                                          RegList non_object_regs,
101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                          bool convert_call_to_jmp) {
102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Enter an internal frame.
1033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  {
1043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    FrameScope scope(masm, StackFrame::INTERNAL);
1053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Store the registers containing live values on the expression stack to
1073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // make sure that these are correctly updated during GC. Non object values
1083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // are stored as a smi causing it to be untouched by GC.
1093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ASSERT((object_regs & ~kJSCallerSaved) == 0);
1103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ASSERT((non_object_regs & ~kJSCallerSaved) == 0);
1113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ASSERT((object_regs & non_object_regs) == 0);
1123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    for (int i = 0; i < kNumJSCallerSaved; i++) {
1133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      int r = JSCallerSavedCode(i);
1143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Register reg = { r };
1153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if ((object_regs & (1 << r)) != 0) {
1163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        __ push(reg);
1173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
1183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if ((non_object_regs & (1 << r)) != 0) {
1193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        if (FLAG_debug_code) {
1203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          __ test(reg, Immediate(0xc0000000));
1213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          __ Assert(zero, "Unable to encode value as smi");
1223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        }
1233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        __ SmiTag(reg);
1243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        __ push(reg);
12580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen      }
12680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    }
127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG
1293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    __ RecordComment("// Calling from debug break to runtime - come in - over");
130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
1313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    __ Set(eax, Immediate(0));  // No arguments.
1323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    __ mov(ebx, Immediate(ExternalReference::debug_break(masm->isolate())));
1333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    CEntryStub ceb(1);
1353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    __ CallStub(&ceb);
1363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Restore the register values containing object pointers from the
1383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // expression stack.
1393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    for (int i = kNumJSCallerSaved; --i >= 0;) {
1403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      int r = JSCallerSavedCode(i);
1413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      Register reg = { r };
1423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if (FLAG_debug_code) {
1433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        __ Set(reg, Immediate(kDebugZapValue));
1443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
1453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if ((object_regs & (1 << r)) != 0) {
1463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        __ pop(reg);
1473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
1483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      if ((non_object_regs & (1 << r)) != 0) {
1493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        __ pop(reg);
1503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        __ SmiUntag(reg);
1513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
15280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    }
153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    // Get rid of the internal frame.
1553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
15685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If this call did not replace a call but patched other code then there will
158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // be an unwanted return address left on the stack. Here we get rid of that.
159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (convert_call_to_jmp) {
1603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    __ add(esp, Immediate(kPointerSize));
161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Now that the break point has been handled, resume normal execution by
164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // jumping to the target address intended by the caller and that was
165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // overwritten by the address of DebugBreakXXX.
166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ExternalReference after_break_target =
16744f0eee88ff00398ff7f715fab053374d808c90dSteve Block      ExternalReference(Debug_Address::AfterBreakTarget(), masm->isolate());
168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  __ jmp(Operand::StaticVariable(after_break_target));
169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debug::GenerateLoadICDebugBreak(MacroAssembler* masm) {
173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Register state for IC load call (from ic-ia32.cc).
174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ----------- S t a t e -------------
175402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  //  -- eax    : receiver
176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  //  -- ecx    : name
177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // -----------------------------------
17880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  Generate_DebugBreakCallHelper(masm, eax.bit() | ecx.bit(), 0, false);
179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debug::GenerateStoreICDebugBreak(MacroAssembler* masm) {
1834515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  // Register state for IC store call (from ic-ia32.cc).
184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ----------- S t a t e -------------
185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  //  -- eax    : value
186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  //  -- ecx    : name
1874515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  //  -- edx    : receiver
188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // -----------------------------------
18980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  Generate_DebugBreakCallHelper(
19080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen      masm, eax.bit() | ecx.bit() | edx.bit(), 0, false);
191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debug::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) {
195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Register state for keyed IC load call (from ic-ia32.cc).
196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ----------- S t a t e -------------
1976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  //  -- edx    : receiver
1986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  //  -- eax    : key
199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // -----------------------------------
20080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  Generate_DebugBreakCallHelper(masm, eax.bit() | edx.bit(), 0, false);
201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debug::GenerateKeyedStoreICDebugBreak(MacroAssembler* masm) {
205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Register state for keyed IC load call (from ic-ia32.cc).
206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ----------- S t a t e -------------
207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  //  -- eax    : value
2086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  //  -- ecx    : key
2096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  //  -- edx    : receiver
210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // -----------------------------------
21180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  Generate_DebugBreakCallHelper(
21280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen      masm, eax.bit() | ecx.bit() | edx.bit(), 0, false);
213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Debug::GenerateCallICDebugBreak(MacroAssembler* masm) {
217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Register state for keyed IC call call (from ic-ia32.cc)
218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ----------- S t a t e -------------
21980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  //  -- ecx: name
220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // -----------------------------------
22180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  Generate_DebugBreakCallHelper(masm, ecx.bit(), 0, false);
222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid Debug::GenerateReturnDebugBreak(MacroAssembler* masm) {
226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Register state just before return from JS function (from codegen-ia32.cc).
2273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // ----------- S t a t e -------------
2283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //  -- eax: return value
2293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // -----------------------------------
2303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Generate_DebugBreakCallHelper(masm, eax.bit(), 0, true);
2313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
2323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid Debug::GenerateCallFunctionStubDebugBreak(MacroAssembler* masm) {
2353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Register state for CallFunctionStub (from code-stubs-ia32.cc).
2363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // ----------- S t a t e -------------
2373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //  -- edi: function
2383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // -----------------------------------
2393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Generate_DebugBreakCallHelper(masm, edi.bit(), 0, false);
2403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
2413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid Debug::GenerateCallFunctionStubRecordDebugBreak(MacroAssembler* masm) {
2443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Register state for CallFunctionStub (from code-stubs-ia32.cc).
2453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // ----------- S t a t e -------------
2463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //  -- ebx: cache cell for call target
2473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //  -- edi: function
2483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // -----------------------------------
2493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Generate_DebugBreakCallHelper(masm, ebx.bit() | edi.bit(), 0, false);
2503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
2513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid Debug::GenerateCallConstructStubDebugBreak(MacroAssembler* masm) {
2543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Register state for CallConstructStub (from code-stubs-ia32.cc).
2555d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch  // eax is the actual number of arguments not encoded as a smi see comment
2565d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch  // above IC call.
2575d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch  // ----------- S t a t e -------------
2585d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch  //  -- eax: number of arguments (not smi)
2595d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch  //  -- edi: constructor function
2605d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch  // -----------------------------------
2615d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch  // The number of arguments in eax is not smi encoded.
2625d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch  Generate_DebugBreakCallHelper(masm, edi.bit(), eax.bit(), false);
2635d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch}
2645d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch
2655d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch
2663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid Debug::GenerateCallConstructStubRecordDebugBreak(MacroAssembler* masm) {
2673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Register state for CallConstructStub (from code-stubs-ia32.cc).
2683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // eax is the actual number of arguments not encoded as a smi see comment
2693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // above IC call.
27085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  // ----------- S t a t e -------------
2713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //  -- eax: number of arguments (not smi)
2723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //  -- ebx: cache cell for call target
2733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  //  -- edi: constructor function
27485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  // -----------------------------------
2753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // The number of arguments in eax is not smi encoded.
2763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Generate_DebugBreakCallHelper(masm, ebx.bit() | edi.bit(), eax.bit(), false);
2775d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch}
2785d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch
2795d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch
2807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid Debug::GenerateSlot(MacroAssembler* masm) {
2817f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Generate enough nop's to make space for a call instruction.
2827f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  Label check_codesize;
2837f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  __ bind(&check_codesize);
2847f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  __ RecordDebugBreakSlot();
2853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ Nop(Assembler::kDebugBreakSlotLength);
2867f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  ASSERT_EQ(Assembler::kDebugBreakSlotLength,
2877f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch            masm->SizeOfCodeGeneratedSince(&check_codesize));
2887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
2897f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
2907f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
2917f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid Debug::GenerateSlotDebugBreak(MacroAssembler* masm) {
2927f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // In the places where a debug break slot is inserted no registers can contain
2937f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // object pointers.
29480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  Generate_DebugBreakCallHelper(masm, 0, 0, true);
2957f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
2967f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
2977f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
2986ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid Debug::GeneratePlainReturnLiveEdit(MacroAssembler* masm) {
2996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  masm->ret(0);
3006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
3016ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
3027f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
3036ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid Debug::GenerateFrameDropperLiveEdit(MacroAssembler* masm) {
304bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  ExternalReference restarter_frame_function_slot =
30544f0eee88ff00398ff7f715fab053374d808c90dSteve Block      ExternalReference(Debug_Address::RestarterFrameFunctionPointer(),
30644f0eee88ff00398ff7f715fab053374d808c90dSteve Block                        masm->isolate());
307bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  __ mov(Operand::StaticVariable(restarter_frame_function_slot), Immediate(0));
308bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch
3096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // We do not know our frame height, but set esp based on ebp.
310756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  __ lea(esp, Operand(ebp, -1 * kPointerSize));
3116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
312756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  __ pop(edi);  // Function.
3136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  __ pop(ebp);
3146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
315756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  // Load context from the function.
316756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
317756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
3186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Get function code.
3196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
3206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  __ mov(edx, FieldOperand(edx, SharedFunctionInfo::kCodeOffset));
3216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  __ lea(edx, FieldOperand(edx, Code::kHeaderSize));
3226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
3236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Re-run JSFunction, edi is function, esi is context.
3243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  __ jmp(edx);
3256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
3266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
327756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrickconst bool Debug::kFrameDropperSupported = true;
3286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
329756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick#undef __
3306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif  // ENABLE_DEBUGGER_SUPPORT
332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} }  // namespace v8::internal
334f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
335f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#endif  // V8_TARGET_ARCH_IA32
336