From: peter.rybin@gmail.com Date: Fri, 13 Aug 2010 13:54:28 +0000 (+0000) Subject: LiveEdit: implement stack manipulations for x64 X-Git-Tag: upstream/4.7.83~21358 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6fa44eb9797c33e8cf9a1d0e7b4f84c7c139765a;p=platform%2Fupstream%2Fv8.git LiveEdit: implement stack manipulations for x64 Review URL: http://codereview.chromium.org/3120011 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5264 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/arm/debug-arm.cc b/src/arm/debug-arm.cc index e87d265..3a94845 100644 --- a/src/arm/debug-arm.cc +++ b/src/arm/debug-arm.cc @@ -293,15 +293,11 @@ void Debug::GenerateFrameDropperLiveEdit(MacroAssembler* masm) { 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) { - UNREACHABLE(); - return NULL; -} -const int Debug::kFrameDropperFrameSize = -1; #endif // ENABLE_DEBUGGER_SUPPORT diff --git a/src/debug.cc b/src/debug.cc index dbf9df9..c13c8c9 100644 --- a/src/debug.cc +++ b/src/debug.cc @@ -582,6 +582,35 @@ int Debug::ArchiveSpacePerThread() { } +// Frame structure (conforms InternalFrame structure): +// -- code +// -- SMI maker +// -- function (slot is called "context") +// -- frame base +Object** Debug::SetUpFrameDropperFrame(StackFrame* bottom_js_frame, + Handle 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(&Memory::Object_at( + fp + StandardFrameConstants::kContextOffset)); +} + +const int Debug::kFrameDropperFrameSize = 4; + + + + + // Default break enabled. bool Debug::disable_break_ = false; diff --git a/src/debug.h b/src/debug.h index b6aba5a..98d1919 100644 --- a/src/debug.h +++ b/src/debug.h @@ -400,6 +400,11 @@ class Debug { 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. @@ -431,13 +436,14 @@ class Debug { // 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); static const int kFrameDropperFrameSize; + // Architecture-specific constant. + static const bool kFrameDropperSupported; + private: static bool CompileDebuggerScript(int index); static void ClearOneShot(); diff --git a/src/ia32/debug-ia32.cc b/src/ia32/debug-ia32.cc index 114bdd7..b57cf3d 100644 --- a/src/ia32/debug-ia32.cc +++ b/src/ia32/debug-ia32.cc @@ -254,15 +254,6 @@ void Debug::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. -// 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()); @@ -286,30 +277,9 @@ void Debug::GenerateFrameDropperLiveEdit(MacroAssembler* masm) { __ 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) { - 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(&Memory::Object_at(fp - 1 * kPointerSize)); -} - -const int Debug::kFrameDropperFrameSize = 4; +const bool Debug::kFrameDropperSupported = true; +#undef __ #endif // ENABLE_DEBUGGER_SUPPORT diff --git a/src/liveedit.cc b/src/liveedit.cc index 2ac24fb..769ac35 100644 --- a/src/liveedit.cc +++ b/src/liveedit.cc @@ -1206,7 +1206,7 @@ static const char* DropFrames(Vector frames, 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."; } diff --git a/src/mips/debug-mips.cc b/src/mips/debug-mips.cc index 47961fa..b8ae68e 100644 --- a/src/mips/debug-mips.cc +++ b/src/mips/debug-mips.cc @@ -114,15 +114,10 @@ void Debug::GenerateFrameDropperLiveEdit(MacroAssembler* masm) { 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) { - UNREACHABLE(); - return NULL; -} -const int Debug::kFrameDropperFrameSize = -1; +#undef __ #endif // ENABLE_DEBUGGER_SUPPORT diff --git a/src/x64/debug-x64.cc b/src/x64/debug-x64.cc index 2aa77e7..d5b7e77 100644 --- a/src/x64/debug-x64.cc +++ b/src/x64/debug-x64.cc @@ -202,23 +202,39 @@ void Debug::GenerateSlotDebugBreak(MacroAssembler* masm) { 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) { - UNREACHABLE(); - return NULL; -} -const int Debug::kFrameDropperFrameSize = -1; void BreakLocationIterator::ClearDebugBreakAtReturn() { diff --git a/test/mjsunit/mjsunit.status b/test/mjsunit/mjsunit.status index ceb5e62..3c8cbdb 100644 --- a/test/mjsunit/mjsunit.status +++ b/test/mjsunit/mjsunit.status @@ -72,8 +72,4 @@ debug-liveedit-check-stack: SKIP # Skip all tests on MIPS. *: SKIP -[ $arch == x64 ] -# Stack manipulations in LiveEdit is implemented for ia32 only. -debug-liveedit-check-stack: SKIP -