masm->Abort("LiveEdit frame dropping is not supported on arm");
}
+const bool Debug::kFrameDropperSupported = false;
+
#undef __
-Object** Debug::SetUpFrameDropperFrame(StackFrame* bottom_js_frame,
- Handle<Code> code) {
- UNREACHABLE();
- return NULL;
-}
-const int Debug::kFrameDropperFrameSize = -1;
#endif // ENABLE_DEBUGGER_SUPPORT
}
+// Frame structure (conforms InternalFrame structure):
+// -- code
+// -- SMI maker
+// -- function (slot is called "context")
+// -- frame base
+Object** Debug::SetUpFrameDropperFrame(StackFrame* bottom_js_frame,
+ Handle<Code> code) {
+ ASSERT(bottom_js_frame->is_java_script());
+
+ Address fp = bottom_js_frame->fp();
+
+ // Move function pointer into "context" slot.
+ Memory::Object_at(fp + StandardFrameConstants::kContextOffset) =
+ Memory::Object_at(fp + JavaScriptFrameConstants::kFunctionOffset);
+
+ Memory::Object_at(fp + InternalFrameConstants::kCodeOffset) = *code;
+ Memory::Object_at(fp + StandardFrameConstants::kMarkerOffset) =
+ Smi::FromInt(StackFrame::INTERNAL);
+
+ return reinterpret_cast<Object**>(&Memory::Object_at(
+ fp + StandardFrameConstants::kContextOffset));
+}
+
+const int Debug::kFrameDropperFrameSize = 4;
+
+
+
+
+
// Default break enabled.
bool Debug::disable_break_ = false;
static void GenerateStubNoRegistersDebugBreak(MacroAssembler* masm);
static void GenerateSlotDebugBreak(MacroAssembler* masm);
static void GeneratePlainReturnLiveEdit(MacroAssembler* masm);
+
+ // FrameDropper is a code replacement for a JavaScript frame with possibly
+ // several frames above.
+ // There is no calling conventions here, because it never actually gets
+ // called, it only gets returned to.
static void GenerateFrameDropperLiveEdit(MacroAssembler* masm);
// Called from stub-cache.cc.
// the value that is called 'restarter_frame_function_pointer'. The value
// at this address (possibly updated by GC) may be used later when preparing
// 'step in' operation.
- // The implementation is architecture-specific.
- // TODO(LiveEdit): consider reviewing it as architecture-independent.
static Object** SetUpFrameDropperFrame(StackFrame* bottom_js_frame,
Handle<Code> code);
static const int kFrameDropperFrameSize;
+ // Architecture-specific constant.
+ static const bool kFrameDropperSupported;
+
private:
static bool CompileDebuggerScript(int index);
static void ClearOneShot();
}
-// FrameDropper is a code replacement for a JavaScript frame with possibly
-// several frames above.
-// There is no calling conventions here, because it never actually gets called,
-// it only gets returned to.
-// Frame structure (conforms InternalFrame structure):
-// -- code
-// -- SMI maker
-// -- function (slot is called "context")
-// -- frame base
void Debug::GenerateFrameDropperLiveEdit(MacroAssembler* masm) {
ExternalReference restarter_frame_function_slot =
ExternalReference(Debug_Address::RestarterFrameFunctionPointer());
__ jmp(Operand(edx));
}
-#undef __
-
-
-// TODO(LiveEdit): consider making it platform-independent.
-// TODO(LiveEdit): use more named constants instead of numbers.
-Object** Debug::SetUpFrameDropperFrame(StackFrame* bottom_js_frame,
- Handle<Code> code) {
- ASSERT(bottom_js_frame->is_java_script());
-
- Address fp = bottom_js_frame->fp();
-
- // Move function pointer into slot that is called referenced
- // as StandardFrame::context()
- Memory::Object_at(fp - 1 * kPointerSize) =
- Memory::Object_at(fp - 2 * kPointerSize);
-
- Memory::Object_at(fp - 3 * kPointerSize) = *code;
- Memory::Object_at(fp - 2 * kPointerSize) = Smi::FromInt(StackFrame::INTERNAL);
-
- return reinterpret_cast<Object**>(&Memory::Object_at(fp - 1 * kPointerSize));
-}
-
-const int Debug::kFrameDropperFrameSize = 4;
+const bool Debug::kFrameDropperSupported = true;
+#undef __
#endif // ENABLE_DEBUGGER_SUPPORT
int bottom_js_frame_index,
Debug::FrameDropMode* mode,
Object*** restarter_frame_function_pointer) {
- if (Debug::kFrameDropperFrameSize < 0) {
+ if (!Debug::kFrameDropperSupported) {
return "Stack manipulations are not supported in this architecture.";
}
masm->Abort("LiveEdit frame dropping is not supported on mips");
}
-#undef __
+const bool Debug::kFrameDropperSupported = false;
-Object** Debug::SetUpFrameDropperFrame(StackFrame* bottom_js_frame,
- Handle<Code> code) {
- UNREACHABLE();
- return NULL;
-}
-const int Debug::kFrameDropperFrameSize = -1;
+#undef __
#endif // ENABLE_DEBUGGER_SUPPORT
void Debug::GeneratePlainReturnLiveEdit(MacroAssembler* masm) {
- masm->Abort("LiveEdit frame dropping is not supported on x64");
+ masm->ret(0);
}
void Debug::GenerateFrameDropperLiveEdit(MacroAssembler* masm) {
- masm->Abort("LiveEdit frame dropping is not supported on x64");
+ ExternalReference restarter_frame_function_slot =
+ ExternalReference(Debug_Address::RestarterFrameFunctionPointer());
+ __ movq(rax, restarter_frame_function_slot);
+ __ movq(Operand(rax, 0), Immediate(0));
+
+ // We do not know our frame height, but set rsp based on rbp.
+ __ lea(rsp, Operand(rbp, -1 * kPointerSize));
+
+ __ pop(rdi); // Function.
+ __ pop(rbp);
+
+ // Load context from the function.
+ __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
+
+ // Get function code.
+ __ movq(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
+ __ movq(rdx, FieldOperand(rdx, SharedFunctionInfo::kCodeOffset));
+ __ lea(rdx, FieldOperand(rdx, Code::kHeaderSize));
+
+ // Re-run JSFunction, rdi is function, rsi is context.
+ __ jmp(rdx);
}
+const bool Debug::kFrameDropperSupported = true;
+
#undef __
-Object** Debug::SetUpFrameDropperFrame(StackFrame* bottom_js_frame,
- Handle<Code> code) {
- UNREACHABLE();
- return NULL;
-}
-const int Debug::kFrameDropperFrameSize = -1;
void BreakLocationIterator::ClearDebugBreakAtReturn() {
# Skip all tests on MIPS.
*: SKIP
-[ $arch == x64 ]
-# Stack manipulations in LiveEdit is implemented for ia32 only.
-debug-liveedit-check-stack: SKIP
-