Commit e4a82f24 authored by kasperl@chromium.org's avatar kasperl@chromium.org

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
parent 6d47b297
...@@ -1629,8 +1629,8 @@ void CEntryStub::GenerateThrowOutOfMemory(MacroAssembler* masm) { ...@@ -1629,8 +1629,8 @@ void CEntryStub::GenerateThrowOutOfMemory(MacroAssembler* masm) {
void CEntryStub::GenerateCore(MacroAssembler* masm, void CEntryStub::GenerateCore(MacroAssembler* masm,
Label* throw_normal_exception, Label* throw_normal_exception,
Label* throw_out_of_memory_exception, Label* throw_out_of_memory_exception,
bool do_gc, StackFrame::Type frame_type,
bool do_restore) { bool do_gc) {
// r0: result parameter for PerformGC, if any // r0: result parameter for PerformGC, if any
// r4: number of arguments including receiver (C callee-saved) // r4: number of arguments including receiver (C callee-saved)
// r5: pointer to builtin function (C callee-saved) // r5: pointer to builtin function (C callee-saved)
...@@ -1671,22 +1671,12 @@ void CEntryStub::GenerateCore(MacroAssembler* masm, ...@@ -1671,22 +1671,12 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
__ tst(r2, Operand(kFailureTagMask)); __ tst(r2, Operand(kFailureTagMask));
__ b(eq, &failure_returned); __ b(eq, &failure_returned);
// Restore the memory copy of the registers by digging them out from // Exit C frame and return.
// 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
// r0:r1: result // r0:r1: result
// sp: stack pointer // sp: stack pointer
// fp: frame pointer // fp: frame pointer
// pp: caller's parameter pointer pp (restored as C callee-saved) // pp: caller's parameter pointer pp (restored as C callee-saved)
__ LeaveExitFrame(); __ LeaveExitFrame(frame_type);
// check if we should retry or throw exception // check if we should retry or throw exception
Label retry; Label retry;
...@@ -1741,17 +1731,9 @@ void CEntryStub::GenerateBody(MacroAssembler* masm, bool is_debug_break) { ...@@ -1741,17 +1731,9 @@ void CEntryStub::GenerateBody(MacroAssembler* masm, bool is_debug_break) {
// Enter the exit frame that transitions from JavaScript to C++. // Enter the exit frame that transitions from JavaScript to C++.
__ EnterExitFrame(frame_type); __ EnterExitFrame(frame_type);
if (is_debug_break) { // r4: number of arguments (C callee-saved)
// 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) // r5: pointer to builtin function (C callee-saved)
// r6: pointer to first argument (C callee-saved)
Label entry;
__ bind(&entry);
Label throw_out_of_memory_exception; Label throw_out_of_memory_exception;
Label throw_normal_exception; Label throw_normal_exception;
...@@ -1764,20 +1746,20 @@ void CEntryStub::GenerateBody(MacroAssembler* masm, bool is_debug_break) { ...@@ -1764,20 +1746,20 @@ void CEntryStub::GenerateBody(MacroAssembler* masm, bool is_debug_break) {
GenerateCore(masm, GenerateCore(masm,
&throw_normal_exception, &throw_normal_exception,
&throw_out_of_memory_exception, &throw_out_of_memory_exception,
FLAG_gc_greedy, frame_type,
is_debug_break); FLAG_gc_greedy);
#else #else
GenerateCore(masm, GenerateCore(masm,
&throw_normal_exception, &throw_normal_exception,
&throw_out_of_memory_exception, &throw_out_of_memory_exception,
false, frame_type,
is_debug_break); false);
#endif #endif
GenerateCore(masm, GenerateCore(masm,
&throw_normal_exception, &throw_normal_exception,
&throw_out_of_memory_exception, &throw_out_of_memory_exception,
true, frame_type,
is_debug_break); true);
__ bind(&throw_out_of_memory_exception); __ bind(&throw_out_of_memory_exception);
GenerateThrowOutOfMemory(masm); GenerateThrowOutOfMemory(masm);
......
...@@ -5204,19 +5204,6 @@ void Ia32CodeGenerator::ExitJSFrame() { ...@@ -5204,19 +5204,6 @@ void Ia32CodeGenerator::ExitJSFrame() {
#define __ masm-> #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) { void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
ASSERT(StackHandlerConstants::kSize == 6 * kPointerSize); // adjust this code ASSERT(StackHandlerConstants::kSize == 6 * kPointerSize); // adjust this code
ExternalReference handler_address(Top::k_handler_address); ExternalReference handler_address(Top::k_handler_address);
...@@ -5245,8 +5232,8 @@ void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) { ...@@ -5245,8 +5232,8 @@ void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
void CEntryStub::GenerateCore(MacroAssembler* masm, void CEntryStub::GenerateCore(MacroAssembler* masm,
Label* throw_normal_exception, Label* throw_normal_exception,
Label* throw_out_of_memory_exception, Label* throw_out_of_memory_exception,
bool do_gc, StackFrame::Type frame_type,
bool do_restore) { bool do_gc) {
// eax: result parameter for PerformGC, if any // eax: result parameter for PerformGC, if any
// ebx: pointer to C function (C callee-saved) // ebx: pointer to C function (C callee-saved)
// ebp: frame pointer (restored after C call) // ebp: frame pointer (restored after C call)
...@@ -5273,22 +5260,11 @@ void CEntryStub::GenerateCore(MacroAssembler* masm, ...@@ -5273,22 +5260,11 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
__ test(ecx, Immediate(kFailureTagMask)); __ test(ecx, Immediate(kFailureTagMask));
__ j(zero, &failure_returned, not_taken); __ j(zero, &failure_returned, not_taken);
// Restore the memory copy of the registers by digging them out from // Exit the JavaScript to C++ exit frame.
// the stack. __ LeaveExitFrame(frame_type);
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();
__ ret(0); __ ret(0);
// Handling of Failure. // Handling of failure.
__ bind(&failure_returned); __ bind(&failure_returned);
Label retry; Label retry;
...@@ -5392,31 +5368,12 @@ void CEntryStub::GenerateBody(MacroAssembler* masm, bool is_debug_break) { ...@@ -5392,31 +5368,12 @@ void CEntryStub::GenerateBody(MacroAssembler* masm, bool is_debug_break) {
// Enter the exit frame that transitions from JavaScript to C++. // Enter the exit frame that transitions from JavaScript to C++.
__ EnterExitFrame(frame_type); __ 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) // eax: result parameter for PerformGC, if any (setup below)
// ebx: pointer to builtin function (C callee-saved) // ebx: pointer to builtin function (C callee-saved)
// ebp: frame pointer (restored after C call) // ebp: frame pointer (restored after C call)
// esp: stack pointer (restored after C call) // esp: stack pointer (restored after C call)
// edi: number of arguments including receiver (C callee-saved) // edi: number of arguments including receiver (C callee-saved)
// esi: argv pointer (C callee-saved)
Label entry;
__ bind(&entry);
Label throw_out_of_memory_exception; Label throw_out_of_memory_exception;
Label throw_normal_exception; Label throw_normal_exception;
...@@ -5428,20 +5385,21 @@ void CEntryStub::GenerateBody(MacroAssembler* masm, bool is_debug_break) { ...@@ -5428,20 +5385,21 @@ void CEntryStub::GenerateBody(MacroAssembler* masm, bool is_debug_break) {
} }
GenerateCore(masm, &throw_normal_exception, GenerateCore(masm, &throw_normal_exception,
&throw_out_of_memory_exception, &throw_out_of_memory_exception,
FLAG_gc_greedy, frame_type,
is_debug_break); FLAG_gc_greedy);
#else #else
GenerateCore(masm, GenerateCore(masm,
&throw_normal_exception, &throw_normal_exception,
&throw_out_of_memory_exception, &throw_out_of_memory_exception,
false, frame_type,
is_debug_break); false);
#endif #endif
GenerateCore(masm, GenerateCore(masm,
&throw_normal_exception, &throw_normal_exception,
&throw_out_of_memory_exception, &throw_out_of_memory_exception,
true, frame_type,
is_debug_break); true);
__ bind(&throw_out_of_memory_exception); __ bind(&throw_out_of_memory_exception);
GenerateThrowOutOfMemory(masm); GenerateThrowOutOfMemory(masm);
......
...@@ -248,10 +248,10 @@ class CEntryStub : public CodeStub { ...@@ -248,10 +248,10 @@ class CEntryStub : public CodeStub {
void GenerateCore(MacroAssembler* masm, void GenerateCore(MacroAssembler* masm,
Label* throw_normal_exception, Label* throw_normal_exception,
Label* throw_out_of_memory_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 GenerateThrowTOS(MacroAssembler* masm);
void GenerateThrowOutOfMemory(MacroAssembler* masm); void GenerateThrowOutOfMemory(MacroAssembler* masm);
void GenerateReserveCParameterSpace(MacroAssembler* masm, int num_parameters);
private: private:
Major MajorKey() { return CEntry; } Major MajorKey() { return CEntry; }
...@@ -274,7 +274,6 @@ class CEntryDebugBreakStub : public CEntryStub { ...@@ -274,7 +274,6 @@ class CEntryDebugBreakStub : public CEntryStub {
}; };
class JSEntryStub : public CodeStub { class JSEntryStub : public CodeStub {
public: public:
JSEntryStub() { } JSEntryStub() { }
......
...@@ -306,10 +306,27 @@ void MacroAssembler::EnterExitFrame(StackFrame::Type type) { ...@@ -306,10 +306,27 @@ void MacroAssembler::EnterExitFrame(StackFrame::Type type) {
// Compute the argv pointer and keep it in a callee-saved register. // Compute the argv pointer and keep it in a callee-saved register.
add(r6, fp, Operand(r4, LSL, kPointerSizeLog2)); add(r6, fp, Operand(r4, LSL, kPointerSizeLog2));
add(r6, r6, Operand(ExitFrameConstants::kPPDisplacement - kPointerSize)); 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. // Clear top frame.
mov(r3, Operand(0)); mov(r3, Operand(0));
mov(ip, Operand(ExternalReference(Top::k_c_entry_fp_address))); mov(ip, Operand(ExternalReference(Top::k_c_entry_fp_address)));
......
...@@ -108,7 +108,7 @@ class MacroAssembler: public Assembler { ...@@ -108,7 +108,7 @@ class MacroAssembler: public Assembler {
void EnterExitFrame(StackFrame::Type type); void EnterExitFrame(StackFrame::Type type);
// Leave the current exit frame. Expects the return value in r0. // Leave the current exit frame. Expects the return value in r0.
void LeaveExitFrame(); void LeaveExitFrame(StackFrame::Type type);
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
......
...@@ -361,10 +361,46 @@ void MacroAssembler::EnterExitFrame(StackFrame::Type type) { ...@@ -361,10 +361,46 @@ void MacroAssembler::EnterExitFrame(StackFrame::Type type) {
int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize; int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize;
mov(edi, Operand(eax)); mov(edi, Operand(eax));
lea(esi, Operand(ebp, eax, times_4, offset)); 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. // Get the return address from the stack and restore the frame pointer.
mov(ecx, Operand(ebp, 1 * kPointerSize)); mov(ecx, Operand(ebp, 1 * kPointerSize));
mov(ebp, Operand(ebp, 0 * kPointerSize)); mov(ebp, Operand(ebp, 0 * kPointerSize));
......
...@@ -98,7 +98,7 @@ class MacroAssembler: public Assembler { ...@@ -98,7 +98,7 @@ class MacroAssembler: public Assembler {
// Leave the current exit frame. Expects the return value in // Leave the current exit frame. Expects the return value in
// register eax:edx (untouched) and the pointer to the first // register eax:edx (untouched) and the pointer to the first
// argument in register esi. // argument in register esi.
void LeaveExitFrame(); void LeaveExitFrame(StackFrame::Type type);
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment