From e4a82f24402359bab119b8b157593a4693bf9deb Mon Sep 17 00:00:00 2001 From: "kasperl@chromium.org" Date: Tue, 23 Sep 2008 12:21:54 +0000 Subject: [PATCH] Move more functionality from CEntryStub to the helper functions in the macro assembler. Review URL: http://codereview.chromium.org/4402 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@363 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/codegen-arm.cc | 44 +++++++++-------------------- src/codegen-ia32.cc | 68 +++++++++------------------------------------ src/codegen.h | 5 ++-- src/macro-assembler-arm.cc | 19 ++++++++++++- src/macro-assembler-arm.h | 2 +- src/macro-assembler-ia32.cc | 38 ++++++++++++++++++++++++- src/macro-assembler-ia32.h | 2 +- 7 files changed, 85 insertions(+), 93 deletions(-) diff --git a/src/codegen-arm.cc b/src/codegen-arm.cc index 4d08e55..dfe5745 100644 --- a/src/codegen-arm.cc +++ b/src/codegen-arm.cc @@ -1629,8 +1629,8 @@ void CEntryStub::GenerateThrowOutOfMemory(MacroAssembler* masm) { void CEntryStub::GenerateCore(MacroAssembler* masm, Label* throw_normal_exception, Label* throw_out_of_memory_exception, - bool do_gc, - bool do_restore) { + StackFrame::Type frame_type, + bool do_gc) { // r0: result parameter for PerformGC, if any // r4: number of arguments including receiver (C callee-saved) // r5: pointer to builtin function (C callee-saved) @@ -1671,22 +1671,12 @@ void CEntryStub::GenerateCore(MacroAssembler* masm, __ tst(r2, Operand(kFailureTagMask)); __ b(eq, &failure_returned); - // Restore the memory copy of the registers by digging them out from - // the stack. - if (do_restore) { - // Ok to clobber r2 and r3. - const int kCallerSavedSize = kNumJSCallerSaved * kPointerSize; - const int kOffset = ExitFrameConstants::kDebugMarkOffset - kCallerSavedSize; - __ add(r3, fp, Operand(kOffset)); - __ CopyRegistersFromStackToMemory(r3, r2, kJSCallerSaved); - } - - // Exit C frame and return + // Exit C frame and return. // r0:r1: result // sp: stack pointer // fp: frame pointer // pp: caller's parameter pointer pp (restored as C callee-saved) - __ LeaveExitFrame(); + __ LeaveExitFrame(frame_type); // check if we should retry or throw exception Label retry; @@ -1741,17 +1731,9 @@ void CEntryStub::GenerateBody(MacroAssembler* masm, bool is_debug_break) { // Enter the exit frame that transitions from JavaScript to C++. __ EnterExitFrame(frame_type); - if (is_debug_break) { - // Save the state of all registers to the stack from the memory location. - // Use sp as base to push. - __ CopyRegistersFromMemoryToStack(sp, kJSCallerSaved); - } - - // r4: number of arguments - // r5: pointer to builtin function (C callee-saved) - - Label entry; - __ bind(&entry); + // r4: number of arguments (C callee-saved) + // r5: pointer to builtin function (C callee-saved) + // r6: pointer to first argument (C callee-saved) Label throw_out_of_memory_exception; Label throw_normal_exception; @@ -1764,20 +1746,20 @@ void CEntryStub::GenerateBody(MacroAssembler* masm, bool is_debug_break) { GenerateCore(masm, &throw_normal_exception, &throw_out_of_memory_exception, - FLAG_gc_greedy, - is_debug_break); + frame_type, + FLAG_gc_greedy); #else GenerateCore(masm, &throw_normal_exception, &throw_out_of_memory_exception, - false, - is_debug_break); + frame_type, + false); #endif GenerateCore(masm, &throw_normal_exception, &throw_out_of_memory_exception, - true, - is_debug_break); + frame_type, + true); __ bind(&throw_out_of_memory_exception); GenerateThrowOutOfMemory(masm); diff --git a/src/codegen-ia32.cc b/src/codegen-ia32.cc index 76c0cb2..6a522c5 100644 --- a/src/codegen-ia32.cc +++ b/src/codegen-ia32.cc @@ -5204,19 +5204,6 @@ void Ia32CodeGenerator::ExitJSFrame() { #define __ masm-> -void CEntryStub::GenerateReserveCParameterSpace(MacroAssembler* masm, - int num_parameters) { - if (num_parameters > 0) { - __ sub(Operand(esp), Immediate(num_parameters * kPointerSize)); - } - static const int kFrameAlignment = OS::ActivationFrameAlignment(); - if (kFrameAlignment > 0) { - ASSERT(IsPowerOf2(kFrameAlignment)); - __ and_(esp, -kFrameAlignment); - } -} - - void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) { ASSERT(StackHandlerConstants::kSize == 6 * kPointerSize); // adjust this code ExternalReference handler_address(Top::k_handler_address); @@ -5245,8 +5232,8 @@ void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) { void CEntryStub::GenerateCore(MacroAssembler* masm, Label* throw_normal_exception, Label* throw_out_of_memory_exception, - bool do_gc, - bool do_restore) { + StackFrame::Type frame_type, + bool do_gc) { // eax: result parameter for PerformGC, if any // ebx: pointer to C function (C callee-saved) // ebp: frame pointer (restored after C call) @@ -5273,22 +5260,11 @@ void CEntryStub::GenerateCore(MacroAssembler* masm, __ test(ecx, Immediate(kFailureTagMask)); __ j(zero, &failure_returned, not_taken); - // Restore the memory copy of the registers by digging them out from - // the stack. - if (do_restore) { - // Ok to clobber ebx and edi - function pointer and number of arguments not - // needed anymore. - const int kCallerSavedSize = kNumJSCallerSaved * kPointerSize; - int kOffset = ExitFrameConstants::kDebugMarkOffset - kCallerSavedSize; - __ lea(ebx, Operand(ebp, kOffset)); - __ CopyRegistersFromStackToMemory(ebx, ecx, kJSCallerSaved); - } - - // Exit C frame. - __ LeaveExitFrame(); + // Exit the JavaScript to C++ exit frame. + __ LeaveExitFrame(frame_type); __ ret(0); - // Handling of Failure. + // Handling of failure. __ bind(&failure_returned); Label retry; @@ -5392,31 +5368,12 @@ void CEntryStub::GenerateBody(MacroAssembler* masm, bool is_debug_break) { // Enter the exit frame that transitions from JavaScript to C++. __ EnterExitFrame(frame_type); - if (is_debug_break) { - // Save the state of all registers to the stack from the memory - // location. - - // TODO(1243899): This should be symmetric to - // CopyRegistersFromStackToMemory() but it isn't! esp is assumed - // correct here, but computed for the other call. Very error - // prone! FIX THIS. Actually there are deeper problems with - // register saving than this asymmetry (see the bug report - // associated with this issue). - __ PushRegistersFromMemory(kJSCallerSaved); - } - - // Allocate stack space for 2 arguments (argc, argv). - GenerateReserveCParameterSpace(masm, 2); - __ mov(Operand(ebp, ExitFrameConstants::kSPOffset), esp); // save entry sp - // eax: result parameter for PerformGC, if any (setup below) // ebx: pointer to builtin function (C callee-saved) // ebp: frame pointer (restored after C call) // esp: stack pointer (restored after C call) // edi: number of arguments including receiver (C callee-saved) - - Label entry; - __ bind(&entry); + // esi: argv pointer (C callee-saved) Label throw_out_of_memory_exception; Label throw_normal_exception; @@ -5428,20 +5385,21 @@ void CEntryStub::GenerateBody(MacroAssembler* masm, bool is_debug_break) { } GenerateCore(masm, &throw_normal_exception, &throw_out_of_memory_exception, - FLAG_gc_greedy, - is_debug_break); + frame_type, + FLAG_gc_greedy); #else GenerateCore(masm, &throw_normal_exception, &throw_out_of_memory_exception, - false, - is_debug_break); + frame_type, + false); #endif + GenerateCore(masm, &throw_normal_exception, &throw_out_of_memory_exception, - true, - is_debug_break); + frame_type, + true); __ bind(&throw_out_of_memory_exception); GenerateThrowOutOfMemory(masm); diff --git a/src/codegen.h b/src/codegen.h index 7dc6bfb..3ec6b47 100644 --- a/src/codegen.h +++ b/src/codegen.h @@ -248,10 +248,10 @@ class CEntryStub : public CodeStub { void GenerateCore(MacroAssembler* masm, Label* throw_normal_exception, Label* throw_out_of_memory_exception, - bool do_gc, bool do_restore); + StackFrame::Type frame_type, + bool do_gc); void GenerateThrowTOS(MacroAssembler* masm); void GenerateThrowOutOfMemory(MacroAssembler* masm); - void GenerateReserveCParameterSpace(MacroAssembler* masm, int num_parameters); private: Major MajorKey() { return CEntry; } @@ -274,7 +274,6 @@ class CEntryDebugBreakStub : public CEntryStub { }; - class JSEntryStub : public CodeStub { public: JSEntryStub() { } diff --git a/src/macro-assembler-arm.cc b/src/macro-assembler-arm.cc index 58011e0..5e5b9c9 100644 --- a/src/macro-assembler-arm.cc +++ b/src/macro-assembler-arm.cc @@ -306,10 +306,27 @@ void MacroAssembler::EnterExitFrame(StackFrame::Type type) { // Compute the argv pointer and keep it in a callee-saved register. add(r6, fp, Operand(r4, LSL, kPointerSizeLog2)); add(r6, r6, Operand(ExitFrameConstants::kPPDisplacement - kPointerSize)); + + // Save the state of all registers to the stack from the memory + // location. This is needed to allow nested break points. + if (type == StackFrame::EXIT_DEBUG) { + // Use sp as base to push. + CopyRegistersFromMemoryToStack(sp, kJSCallerSaved); + } } -void MacroAssembler::LeaveExitFrame() { +void MacroAssembler::LeaveExitFrame(StackFrame::Type type) { + // Restore the memory copy of the registers by digging them out from + // the stack. This is needed to allow nested break points. + if (type == StackFrame::EXIT_DEBUG) { + // This code intentionally clobbers r2 and r3. + const int kCallerSavedSize = kNumJSCallerSaved * kPointerSize; + const int kOffset = ExitFrameConstants::kDebugMarkOffset - kCallerSavedSize; + add(r3, fp, Operand(kOffset)); + CopyRegistersFromStackToMemory(r3, r2, kJSCallerSaved); + } + // Clear top frame. mov(r3, Operand(0)); mov(ip, Operand(ExternalReference(Top::k_c_entry_fp_address))); diff --git a/src/macro-assembler-arm.h b/src/macro-assembler-arm.h index 9e1bf3f..9c046ac 100644 --- a/src/macro-assembler-arm.h +++ b/src/macro-assembler-arm.h @@ -108,7 +108,7 @@ class MacroAssembler: public Assembler { void EnterExitFrame(StackFrame::Type type); // Leave the current exit frame. Expects the return value in r0. - void LeaveExitFrame(); + void LeaveExitFrame(StackFrame::Type type); // --------------------------------------------------------------------------- diff --git a/src/macro-assembler-ia32.cc b/src/macro-assembler-ia32.cc index a4564f3..dab6778 100644 --- a/src/macro-assembler-ia32.cc +++ b/src/macro-assembler-ia32.cc @@ -361,10 +361,46 @@ void MacroAssembler::EnterExitFrame(StackFrame::Type type) { int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize; mov(edi, Operand(eax)); lea(esi, Operand(ebp, eax, times_4, offset)); + + // Save the state of all registers to the stack from the memory + // location. This is needed to allow nested break points. + if (type == StackFrame::EXIT_DEBUG) { + // TODO(1243899): This should be symmetric to + // CopyRegistersFromStackToMemory() but it isn't! esp is assumed + // correct here, but computed for the other call. Very error + // prone! FIX THIS. Actually there are deeper problems with + // register saving than this asymmetry (see the bug report + // associated with this issue). + PushRegistersFromMemory(kJSCallerSaved); + } + + // Reserve space for two arguments: argc and argv. + sub(Operand(esp), Immediate(2 * kPointerSize)); + + // Get the required frame alignment for the OS. + static const int kFrameAlignment = OS::ActivationFrameAlignment(); + if (kFrameAlignment > 0) { + ASSERT(IsPowerOf2(kFrameAlignment)); + and_(esp, -kFrameAlignment); + } + + // Patch the saved entry sp. + mov(Operand(ebp, ExitFrameConstants::kSPOffset), esp); } -void MacroAssembler::LeaveExitFrame() { +void MacroAssembler::LeaveExitFrame(StackFrame::Type type) { + // Restore the memory copy of the registers by digging them out from + // the stack. This is needed to allow nested break points. + if (type == StackFrame::EXIT_DEBUG) { + // It's okay to clobber register ebx below because we don't need + // the function pointer after this. + const int kCallerSavedSize = kNumJSCallerSaved * kPointerSize; + int kOffset = ExitFrameConstants::kDebugMarkOffset - kCallerSavedSize; + lea(ebx, Operand(ebp, kOffset)); + CopyRegistersFromStackToMemory(ebx, ecx, kJSCallerSaved); + } + // Get the return address from the stack and restore the frame pointer. mov(ecx, Operand(ebp, 1 * kPointerSize)); mov(ebp, Operand(ebp, 0 * kPointerSize)); diff --git a/src/macro-assembler-ia32.h b/src/macro-assembler-ia32.h index 7cca56c..9a923e4 100644 --- a/src/macro-assembler-ia32.h +++ b/src/macro-assembler-ia32.h @@ -98,7 +98,7 @@ class MacroAssembler: public Assembler { // Leave the current exit frame. Expects the return value in // register eax:edx (untouched) and the pointer to the first // argument in register esi. - void LeaveExitFrame(); + void LeaveExitFrame(StackFrame::Type type); // --------------------------------------------------------------------------- -- 2.7.4