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) {
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);
......
......@@ -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);
......
......@@ -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() { }
......
......@@ -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)));
......
......@@ -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);
// ---------------------------------------------------------------------------
......
......@@ -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));
......
......@@ -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);
// ---------------------------------------------------------------------------
......
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