Comment cmnt(masm_, "[ DebuggerStatament");
CodeForStatementPosition(node);
#ifdef ENABLE_DEBUGGER_SUPPORT
- DebuggerStatementStub ces;
- frame_->CallStub(&ces, 0);
+ frame_->DebugBreak();
#endif
// Ignore the return value.
ASSERT(frame_->height() == original_height);
// Push in reverse order: caller_fp, sp_on_exit, and caller_pc.
stm(db_w, sp, fp.bit() | ip.bit() | lr.bit());
- mov(fp, Operand(sp)); // setup new frame pointer
+ mov(fp, Operand(sp)); // Setup new frame pointer.
- if (mode == ExitFrame::MODE_DEBUG) {
- mov(ip, Operand(Smi::FromInt(0)));
- } else {
- mov(ip, Operand(CodeObject()));
- }
- push(ip);
+ mov(ip, Operand(CodeObject()));
+ push(ip); // Accessed from ExitFrame::code_slot.
// Save the frame pointer and the context in top.
mov(ip, Operand(ExternalReference(Top::k_c_entry_fp_address)));
}
}
}
+
+
+void MacroAssembler::DebugBreak() {
+ ASSERT(allow_stub_calls());
+ mov(r0, Operand(0));
+ mov(r1, Operand(ExternalReference(Runtime::kDebugBreak)));
+ CEntryStub ces(1);
+ Call(ces.GetCode(), RelocInfo::DEBUG_BREAK);
+}
#endif
void CopyRegistersFromStackToMemory(Register base,
Register scratch,
RegList regs);
+ void DebugBreak();
#endif
// ---------------------------------------------------------------------------
}
+#ifdef ENABLE_DEBUGGER_SUPPORT
+void VirtualFrame::DebugBreak() {
+ ASSERT(cgen()->HasValidEntryRegisters());
+ __ DebugBreak();
+}
+#endif
+
+
void VirtualFrame::InvokeBuiltin(Builtins::JavaScript id,
InvokeJSFlags flags,
int arg_count) {
void CallRuntime(Runtime::Function* f, int arg_count);
void CallRuntime(Runtime::FunctionId id, int arg_count);
+#ifdef ENABLE_DEBUGGER_SUPPORT
+ void DebugBreak();
+#endif
+
// Invoke builtin given the number of arguments it expects on (and
// removes from) the stack.
void InvokeBuiltin(Builtins::JavaScript id,
return "code target (js construct call)";
case RelocInfo::CODE_TARGET_CONTEXT:
return "code target (context)";
+ case RelocInfo::DEBUG_BREAK:
+#ifndef ENABLE_DEBUGGER_SUPPORT
+ UNREACHABLE();
+#endif
+ return "debug break";
case RelocInfo::CODE_TARGET:
return "code target";
case RelocInfo::RUNTIME_ENTRY:
case EMBEDDED_OBJECT:
Object::VerifyPointer(target_object());
break;
+ case DEBUG_BREAK:
+#ifndef ENABLE_DEBUGGER_SUPPORT
+ UNREACHABLE();
+ break;
+#endif
case CONSTRUCT_CALL:
case CODE_TARGET_CONTEXT:
case CODE_TARGET: {
// Please note the order is important (see IsCodeTarget, IsGCRelocMode).
CONSTRUCT_CALL, // code target that is a call to a JavaScript constructor.
CODE_TARGET_CONTEXT, // code target used for contextual loads.
+ DEBUG_BREAK,
CODE_TARGET, // code target which is not any of the above.
EMBEDDED_OBJECT,
EMBEDDED_STRING,
info()->set_load_stub_cache(value);
}
-#ifdef ENABLE_DEBUGGER_SUPPORT
-void DebuggerStatementStub::Generate(MacroAssembler* masm) {
- Runtime::Function* f = Runtime::FunctionForId(Runtime::kDebugBreak);
- masm->TailCallRuntime(ExternalReference(f), 0, f->result_size);
-}
-#endif
-
} } // namespace v8::internal
};
-// Mark the debugger statement to be recognized by debugger (by the MajorKey)
-class DebuggerStatementStub : public CodeStub {
- public:
- DebuggerStatementStub() { }
-
- void Generate(MacroAssembler* masm);
-
- private:
- Major MajorKey() { return DebuggerStatement; }
- int MinorKey() { return 0; }
-
- const char* GetName() { return "DebuggerStatementStub"; }
-};
-
-
class JSEntryStub : public CodeStub {
public:
JSEntryStub() { }
bool BreakLocationIterator::IsDebuggerStatement() {
- if (RelocInfo::IsCodeTarget(rmode())) {
- Address target = original_rinfo()->target_address();
- Code* code = Code::GetCodeFromTargetAddress(target);
- if (code->kind() == Code::STUB) {
- CodeStub::Major major_key = code->major_key();
- return (major_key == CodeStub::DebuggerStatement);
- }
- }
- return false;
+ return RelocInfo::DEBUG_BREAK == rmode();
}
Code* ExitFrame::code() const {
- Object* code = code_slot();
- if (code->IsSmi()) {
- return Heap::debugger_statement_code();
- } else {
- return Code::cast(code);
- }
+ return Code::cast(code_slot());
}
Comment cmnt(masm_, "[ DebuggerStatement");
SetStatementPosition(stmt);
- DebuggerStatementStub ces;
- __ CallStub(&ces);
+ __ DebugBreak();
// Ignore the return value.
#endif
}
#endif
-#ifdef ENABLE_DEBUGGER_SUPPORT
-void Heap::CreateCEntryDebugBreakStub() {
- DebuggerStatementStub stub;
- set_debugger_statement_code(*stub.GetCode());
-}
-#endif
-
-
void Heap::CreateJSEntryStub() {
JSEntryStub stub;
set_js_entry_code(*stub.GetCode());
// }
// To workaround the problem, make separate functions without inlining.
Heap::CreateCEntryStub();
-#ifdef ENABLE_DEBUGGER_SUPPORT
- Heap::CreateCEntryDebugBreakStub();
-#endif
Heap::CreateJSEntryStub();
Heap::CreateJSConstructEntryStub();
#if V8_TARGET_ARCH_ARM && V8_NATIVE_REGEXP
V(Code, js_entry_code, JsEntryCode) \
V(Code, js_construct_entry_code, JsConstructEntryCode) \
V(Code, c_entry_code, CEntryCode) \
- V(Code, debugger_statement_code, DebuggerStatementCode) \
V(FixedArray, number_string_cache, NumberStringCache) \
V(FixedArray, single_character_string_cache, SingleCharacterStringCache) \
V(FixedArray, natives_source_cache, NativesSourceCache) \
// These four Create*EntryStub functions are here because of a gcc-4.4 bug
// that assigns wrong vtable entries.
static void CreateCEntryStub();
- static void CreateCEntryDebugBreakStub();
static void CreateJSEntryStub();
static void CreateJSConstructEntryStub();
static void CreateRegExpCEntryStub();
// Spill everything, even constants, to the frame.
frame_->SpillAll();
- DebuggerStatementStub ces;
- frame_->CallStub(&ces, 0);
+ frame_->DebugBreak();
// Ignore the return value.
#endif
}
}
}
}
+
+void MacroAssembler::DebugBreak() {
+ Set(eax, Immediate(0));
+ mov(ebx, Immediate(ExternalReference(Runtime::kDebugBreak)));
+ CEntryStub ces(1);
+ call(ces.GetCode(), RelocInfo::DEBUG_BREAK);
+}
#endif
void MacroAssembler::Set(Register dst, const Immediate& x) {
// Reserve room for entry stack pointer and push the debug marker.
ASSERT(ExitFrameConstants::kSPOffset == -1 * kPointerSize);
- push(Immediate(0)); // saved entry sp, patched before call
- if (mode == ExitFrame::MODE_DEBUG) {
- push(Immediate(0));
- } else {
- push(Immediate(CodeObject()));
- }
+ push(Immediate(0)); // Saved entry sp, patched before call.
+ push(Immediate(CodeObject())); // Accessed from ExitFrame::code_slot.
// Save the frame pointer and the context in top.
ExternalReference c_entry_fp_address(Top::k_c_entry_fp_address);
void CopyRegistersFromStackToMemory(Register base,
Register scratch,
RegList regs);
+ void DebugBreak();
#endif
// ---------------------------------------------------------------------------
}
+#ifdef ENABLE_DEBUGGER_SUPPORT
+void VirtualFrame::DebugBreak() {
+ PrepareForCall(0, 0);
+ ASSERT(cgen()->HasValidEntryRegisters());
+ __ DebugBreak();
+ Result result = cgen()->allocator()->Allocate(eax);
+ ASSERT(result.is_valid());
+}
+#endif
+
+
Result VirtualFrame::InvokeBuiltin(Builtins::JavaScript id,
InvokeFlag flag,
int arg_count) {
Result CallRuntime(Runtime::Function* f, int arg_count);
Result CallRuntime(Runtime::FunctionId id, int arg_count);
+#ifdef ENABLE_DEBUGGER_SUPPORT
+ void DebugBreak();
+#endif
+
// Invoke builtin given the number of arguments it expects on (and
// removes from) the stack.
Result InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag, int arg_count);
// Spill everything, even constants, to the frame.
frame_->SpillAll();
- DebuggerStatementStub ces;
- frame_->CallStub(&ces, 0);
+ frame_->DebugBreak();
// Ignore the return value.
#endif
}
}
}
+void MacroAssembler::DebugBreak() {
+ ASSERT(allow_stub_calls());
+ xor_(rax, rax); // no arguments
+ movq(rbx, ExternalReference(Runtime::kDebugBreak));
+ CEntryStub ces(1);
+ Call(ces.GetCode(), RelocInfo::DEBUG_BREAK);
+}
#endif // ENABLE_DEBUGGER_SUPPORT
// Reserve room for entry stack pointer and push the debug marker.
ASSERT(ExitFrameConstants::kSPOffset == -1 * kPointerSize);
- push(Immediate(0)); // saved entry sp, patched before call
- if (mode == ExitFrame::MODE_DEBUG) {
- push(Immediate(0));
- } else {
- movq(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT);
- push(kScratchRegister);
- }
+ push(Immediate(0)); // Saved entry sp, patched before call.
+ movq(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT);
+ push(kScratchRegister); // Accessed from EditFrame::code_slot.
// Save the frame pointer and the context in top.
ExternalReference c_entry_fp_address(Top::k_c_entry_fp_address);
void CopyRegistersFromStackToMemory(Register base,
Register scratch,
RegList regs);
+ void DebugBreak();
#endif
// ---------------------------------------------------------------------------
}
+#ifdef ENABLE_DEBUGGER_SUPPORT
+void VirtualFrame::DebugBreak() {
+ PrepareForCall(0, 0);
+ ASSERT(cgen()->HasValidEntryRegisters());
+ __ DebugBreak();
+ Result result = cgen()->allocator()->Allocate(rax);
+ ASSERT(result.is_valid());
+}
+#endif
+
+
Result VirtualFrame::CallLoadIC(RelocInfo::Mode mode) {
// Name and receiver are on the top of the frame. The IC expects
// name in rcx and receiver on the stack. It does not drop the
Result CallRuntime(Runtime::Function* f, int arg_count);
Result CallRuntime(Runtime::FunctionId id, int arg_count);
+#ifdef ENABLE_DEBUGGER_SUPPORT
+ void DebugBreak();
+#endif
+
// Invoke builtin given the number of arguments it expects on (and
// removes from) the stack.
Result InvokeBuiltin(Builtins::JavaScript id,