1864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Copyright 2012 the V8 project authors. All rights reserved.
2864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Use of this source code is governed by a BSD-style license that can be
3864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// found in the LICENSE file.
4864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
5196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h"
6864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
7864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#if V8_TARGET_ARCH_X87
8864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/codegen.h"
10196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/debug.h"
11864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
12864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
13864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgnamespace v8 {
14864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgnamespace internal {
15864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
16864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgbool BreakLocationIterator::IsDebugBreakAtReturn() {
17864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  return Debug::IsDebugBreakAtReturn(rinfo());
18864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
19864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
20864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
21864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Patch the JS frame exit code with a debug break call. See
22864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// CodeGenerator::VisitReturnStatement and VirtualFrame::Exit in codegen-x87.cc
23864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// for the precise return instructions sequence.
24864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid BreakLocationIterator::SetDebugBreakAtReturn() {
25e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(Assembler::kJSReturnSequenceLength >=
26864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org         Assembler::kCallInstructionLength);
27864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  rinfo()->PatchCodeWithCall(
28864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      debug_info_->GetIsolate()->builtins()->Return_DebugBreak()->entry(),
29864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      Assembler::kJSReturnSequenceLength - Assembler::kCallInstructionLength);
30864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
31864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
32864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
33864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// Restore the JS frame exit code.
34864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid BreakLocationIterator::ClearDebugBreakAtReturn() {
35864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  rinfo()->PatchCode(original_rinfo()->pc(),
36864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                     Assembler::kJSReturnSequenceLength);
37864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
38864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
39864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
40864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// A debug break in the frame exit code is identified by the JS frame exit code
41864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org// having been patched with a call instruction.
42864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgbool Debug::IsDebugBreakAtReturn(RelocInfo* rinfo) {
43e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(RelocInfo::IsJSReturn(rinfo->rmode()));
44864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  return rinfo->IsPatchedReturnSequence();
45864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
46864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
47864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
48864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgbool BreakLocationIterator::IsDebugBreakAtSlot() {
49e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsDebugBreakSlot());
50864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Check whether the debug break slot instructions have been patched.
51864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  return rinfo()->IsPatchedDebugBreakSlotSequence();
52864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
53864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
54864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
55864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid BreakLocationIterator::SetDebugBreakAtSlot() {
56e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsDebugBreakSlot());
57864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  Isolate* isolate = debug_info_->GetIsolate();
58864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  rinfo()->PatchCodeWithCall(
59864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      isolate->builtins()->Slot_DebugBreak()->entry(),
60864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      Assembler::kDebugBreakSlotLength - Assembler::kCallInstructionLength);
61864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
62864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
63864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
64864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgvoid BreakLocationIterator::ClearDebugBreakAtSlot() {
65e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsDebugBreakSlot());
66864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  rinfo()->PatchCode(original_rinfo()->pc(), Assembler::kDebugBreakSlotLength);
67864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
68864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
69864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
70864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#define __ ACCESS_MASM(masm)
71864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
72864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.orgstatic void Generate_DebugBreakCallHelper(MacroAssembler* masm,
73864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                          RegList object_regs,
74864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                          RegList non_object_regs,
75864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                          bool convert_call_to_jmp) {
76864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Enter an internal frame.
77864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  {
78864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    FrameScope scope(masm, StackFrame::INTERNAL);
79864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
80864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    // Load padding words on stack.
818d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    for (int i = 0; i < LiveEdit::kFramePaddingInitialSize; i++) {
828d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org      __ push(Immediate(Smi::FromInt(LiveEdit::kFramePaddingValue)));
83864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    }
848d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org    __ push(Immediate(Smi::FromInt(LiveEdit::kFramePaddingInitialSize)));
85864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
86864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    // Store the registers containing live values on the expression stack to
87864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    // make sure that these are correctly updated during GC. Non object values
88864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    // 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);
92864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    for (int i = 0; i < kNumJSCallerSaved; i++) {
93864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      int r = JSCallerSavedCode(i);
94864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      Register reg = { r };
95864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      if ((object_regs & (1 << r)) != 0) {
96864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        __ push(reg);
97864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      }
98864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      if ((non_object_regs & (1 << r)) != 0) {
99864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        if (FLAG_debug_code) {
100864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          __ test(reg, Immediate(0xc0000000));
101864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          __ Assert(zero, kUnableToEncodeValueAsSmi);
102864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        }
103864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        __ SmiTag(reg);
104864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        __ push(reg);
105864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      }
106864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    }
107864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
108864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#ifdef DEBUG
109864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    __ RecordComment("// Calling from debug break to runtime - come in - over");
110864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#endif
111864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    __ Move(eax, Immediate(0));  // No arguments.
112864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    __ mov(ebx, Immediate(ExternalReference::debug_break(masm->isolate())));
113864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
114864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    CEntryStub ceb(masm->isolate(), 1);
115864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    __ CallStub(&ceb);
116864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
117864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    // Automatically find register that could be used after register restore.
118864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    // We need one register for padding skip instructions.
119864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    Register unused_reg = { -1 };
120864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
121864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    // Restore the register values containing object pointers from the
122864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    // expression stack.
123864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    for (int i = kNumJSCallerSaved; --i >= 0;) {
124864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      int r = JSCallerSavedCode(i);
125864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      Register reg = { r };
126864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      if (FLAG_debug_code) {
127864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        __ Move(reg, Immediate(kDebugZapValue));
128864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      }
129864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      bool taken = reg.code() == esi.code();
130864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      if ((object_regs & (1 << r)) != 0) {
131864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        __ pop(reg);
132864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        taken = true;
133864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      }
134864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      if ((non_object_regs & (1 << r)) != 0) {
135864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        __ pop(reg);
136864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        __ SmiUntag(reg);
137864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        taken = true;
138864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      }
139864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      if (!taken) {
140864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org        unused_reg = reg;
141864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      }
142864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    }
143864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
144e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(unused_reg.code() != -1);
145864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
146864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    // Read current padding counter and skip corresponding number of words.
147864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    __ pop(unused_reg);
148864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    // We divide stored value by 2 (untagging) and multiply it by word's size.
149864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    STATIC_ASSERT(kSmiTagSize == 1 && kSmiShiftSize == 0);
150864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    __ lea(esp, Operand(esp, unused_reg, times_half_pointer_size, 0));
151864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
152864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    // Get rid of the internal frame.
153864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
154864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
155864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // If this call did not replace a call but patched other code then there will
156864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // be an unwanted return address left on the stack. Here we get rid of that.
157864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  if (convert_call_to_jmp) {
158864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org    __ add(esp, Immediate(kPointerSize));
159864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  }
160864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
161864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Now that the break point has been handled, resume normal execution by
162864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // jumping to the target address intended by the caller and that was
163864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // overwritten by the address of DebugBreakXXX.
164864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  ExternalReference after_break_target =
165864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      ExternalReference::debug_after_break_target_address(masm->isolate());
166864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  __ jmp(Operand::StaticVariable(after_break_target));
167864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
168864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
169864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
170e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgvoid DebugCodegen::GenerateCallICStubDebugBreak(MacroAssembler* masm) {
171864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Register state for CallICStub
172864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // ----------- S t a t e -------------
173864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  //  -- edx    : type feedback slot (smi)
174864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  //  -- edi    : function
175864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // -----------------------------------
176864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  Generate_DebugBreakCallHelper(masm, edx.bit() | edi.bit(),
177864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                0, false);
178864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
179864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
180864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
181e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgvoid DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) {
182864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Register state for IC load call (from ic-x87.cc).
18342ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org  Register receiver = LoadDescriptor::ReceiverRegister();
18442ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org  Register name = LoadDescriptor::NameRegister();
185248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org  Generate_DebugBreakCallHelper(masm, receiver.bit() | name.bit(), 0, false);
186864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
187864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
188864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
189e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgvoid DebugCodegen::GenerateStoreICDebugBreak(MacroAssembler* masm) {
190864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Register state for IC store call (from ic-x87.cc).
19142ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org  Register receiver = StoreDescriptor::ReceiverRegister();
19242ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org  Register name = StoreDescriptor::NameRegister();
19342ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org  Register value = StoreDescriptor::ValueRegister();
194864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  Generate_DebugBreakCallHelper(
195fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org      masm, receiver.bit() | name.bit() | value.bit(), 0, false);
196864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
197864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
198864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
199e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgvoid DebugCodegen::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) {
200864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Register state for keyed IC load call (from ic-x87.cc).
20158a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org  GenerateLoadICDebugBreak(masm);
202864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
203864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
204864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
205e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgvoid DebugCodegen::GenerateKeyedStoreICDebugBreak(MacroAssembler* masm) {
206fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org  // Register state for keyed IC store call (from ic-x87.cc).
20742ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org  Register receiver = StoreDescriptor::ReceiverRegister();
20842ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org  Register name = StoreDescriptor::NameRegister();
20942ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org  Register value = StoreDescriptor::ValueRegister();
210864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  Generate_DebugBreakCallHelper(
211fda8f0c912147597a3060a3d80f557840635ca01machenbach@chromium.org      masm, receiver.bit() | name.bit() | value.bit(), 0, false);
212864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
213864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
214864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
215e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgvoid DebugCodegen::GenerateCompareNilICDebugBreak(MacroAssembler* masm) {
216864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Register state for CompareNil IC
217864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // ----------- S t a t e -------------
218864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  //  -- eax    : value
219864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // -----------------------------------
220864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  Generate_DebugBreakCallHelper(masm, eax.bit(), 0, false);
221864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
222864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
223864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
224e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgvoid DebugCodegen::GenerateReturnDebugBreak(MacroAssembler* masm) {
225864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Register state just before return from JS function (from codegen-x87.cc).
226864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // ----------- S t a t e -------------
227864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  //  -- eax: return value
228864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // -----------------------------------
229864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  Generate_DebugBreakCallHelper(masm, eax.bit(), 0, true);
230864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
231864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
232864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
233e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgvoid DebugCodegen::GenerateCallFunctionStubDebugBreak(MacroAssembler* masm) {
234864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Register state for CallFunctionStub (from code-stubs-x87.cc).
235864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // ----------- S t a t e -------------
236864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  //  -- edi: function
237864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // -----------------------------------
238864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  Generate_DebugBreakCallHelper(masm, edi.bit(), 0, false);
239864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
240864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
241864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
242e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgvoid DebugCodegen::GenerateCallConstructStubDebugBreak(MacroAssembler* masm) {
243864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Register state for CallConstructStub (from code-stubs-x87.cc).
244864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // eax is the actual number of arguments not encoded as a smi see comment
245864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // above IC call.
246864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // ----------- S t a t e -------------
247864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  //  -- eax: number of arguments (not smi)
248864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  //  -- edi: constructor function
249864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // -----------------------------------
250864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // The number of arguments in eax is not smi encoded.
251864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  Generate_DebugBreakCallHelper(masm, edi.bit(), eax.bit(), false);
252864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
253864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
254864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
255e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgvoid DebugCodegen::GenerateCallConstructStubRecordDebugBreak(
256e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org    MacroAssembler* masm) {
257864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Register state for CallConstructStub (from code-stubs-x87.cc).
258864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // eax is the actual number of arguments not encoded as a smi see comment
259864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // above IC call.
260864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // ----------- S t a t e -------------
261864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  //  -- eax: number of arguments (not smi)
262864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  //  -- ebx: feedback array
263864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  //  -- edx: feedback slot (smi)
264864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  //  -- edi: constructor function
265864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // -----------------------------------
266864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // The number of arguments in eax is not smi encoded.
267864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  Generate_DebugBreakCallHelper(masm, ebx.bit() | edx.bit() | edi.bit(),
268864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org                                eax.bit(), false);
269864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
270864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
271864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
272e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgvoid DebugCodegen::GenerateSlot(MacroAssembler* masm) {
273864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Generate enough nop's to make space for a call instruction.
274864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  Label check_codesize;
275864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  __ bind(&check_codesize);
276864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  __ RecordDebugBreakSlot();
277864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  __ Nop(Assembler::kDebugBreakSlotLength);
278e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_EQ(Assembler::kDebugBreakSlotLength,
279864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org            masm->SizeOfCodeGeneratedSince(&check_codesize));
280864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
281864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
282864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
283e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgvoid DebugCodegen::GenerateSlotDebugBreak(MacroAssembler* masm) {
284864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // In the places where a debug break slot is inserted no registers can contain
285864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // object pointers.
286864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  Generate_DebugBreakCallHelper(masm, 0, 0, true);
287864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
288864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
289864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
290e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgvoid DebugCodegen::GeneratePlainReturnLiveEdit(MacroAssembler* masm) {
291864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  masm->ret(0);
292864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
293864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
294864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
295e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgvoid DebugCodegen::GenerateFrameDropperLiveEdit(MacroAssembler* masm) {
296864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  ExternalReference restarter_frame_function_slot =
297864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org      ExternalReference::debug_restarter_frame_function_pointer_address(
298864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org          masm->isolate());
299864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  __ mov(Operand::StaticVariable(restarter_frame_function_slot), Immediate(0));
300864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
301864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // We do not know our frame height, but set esp based on ebp.
302864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  __ lea(esp, Operand(ebp, -1 * kPointerSize));
303864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
304864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  __ pop(edi);  // Function.
305864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  __ pop(ebp);
306864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
307864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Load context from the function.
308864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
309864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
310864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Get function code.
311864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
312864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  __ mov(edx, FieldOperand(edx, SharedFunctionInfo::kCodeOffset));
313864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  __ lea(edx, FieldOperand(edx, Code::kHeaderSize));
314864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
315864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  // Re-run JSFunction, edi is function, esi is context.
316864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org  __ jmp(edx);
317864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org}
318864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
3198d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.org
3208d8413cae4e7eb777aaed22e2901c19f8d5d1297machenbach@chromium.orgconst bool LiveEdit::kFrameDropperSupported = true;
321864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
322864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#undef __
323864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
324864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org} }  // namespace v8::internal
325864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org
326864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org#endif  // V8_TARGET_ARCH_X87
327