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