Tighten the code for MacroAssembler::ThrowUncatchable.
Test at the bottom in the unwind loop. Eliminate the possibility of a useless move to the eax/rax/r0 register (currently impossible because this function has two call sites). Do not explicitly zero the context because we've already saved 0 as the context in the handler. R=fschneider@chromium.org BUG= TEST= Review URL: http://codereview.chromium.org/8493008 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9909 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
59a472a742
commit
aee8ae0548
@ -1258,37 +1258,12 @@ void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type,
|
||||
STATIC_ASSERT(StackHandlerConstants::kContextOffset == 2 * kPointerSize);
|
||||
STATIC_ASSERT(StackHandlerConstants::kFPOffset == 3 * kPointerSize);
|
||||
STATIC_ASSERT(StackHandlerConstants::kPCOffset == 4 * kPointerSize);
|
||||
// r0 is expected to hold the exception.
|
||||
if (!value.is(r0)) {
|
||||
mov(r0, value);
|
||||
}
|
||||
|
||||
// Drop sp to the top stack handler.
|
||||
mov(r3, Operand(ExternalReference(Isolate::kHandlerAddress, isolate())));
|
||||
ldr(sp, MemOperand(r3));
|
||||
|
||||
// Unwind the handlers until the ENTRY handler is found.
|
||||
Label loop, done;
|
||||
bind(&loop);
|
||||
// Load the type of the current stack handler.
|
||||
const int kStateOffset = StackHandlerConstants::kStateOffset;
|
||||
ldr(r2, MemOperand(sp, kStateOffset));
|
||||
cmp(r2, Operand(StackHandler::ENTRY));
|
||||
b(eq, &done);
|
||||
// Fetch the next handler in the list.
|
||||
const int kNextOffset = StackHandlerConstants::kNextOffset;
|
||||
ldr(sp, MemOperand(sp, kNextOffset));
|
||||
jmp(&loop);
|
||||
bind(&done);
|
||||
|
||||
// Set the top handler address to next handler past the current ENTRY handler.
|
||||
pop(r2);
|
||||
str(r2, MemOperand(r3));
|
||||
|
||||
// The exception is expected in r0.
|
||||
if (type == OUT_OF_MEMORY) {
|
||||
// Set external caught exception to false.
|
||||
ExternalReference external_caught(
|
||||
Isolate::kExternalCaughtExceptionAddress, isolate());
|
||||
ExternalReference external_caught(Isolate::kExternalCaughtExceptionAddress,
|
||||
isolate());
|
||||
mov(r0, Operand(false, RelocInfo::NONE));
|
||||
mov(r2, Operand(external_caught));
|
||||
str(r0, MemOperand(r2));
|
||||
@ -1299,21 +1274,33 @@ void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type,
|
||||
mov(r2, Operand(ExternalReference(Isolate::kPendingExceptionAddress,
|
||||
isolate())));
|
||||
str(r0, MemOperand(r2));
|
||||
} else if (!value.is(r0)) {
|
||||
mov(r0, value);
|
||||
}
|
||||
|
||||
// Stack layout at this point. See also StackHandlerConstants.
|
||||
// sp -> state (ENTRY)
|
||||
// cp
|
||||
// fp
|
||||
// lr
|
||||
// Drop the stack pointer to the top of the top stack handler.
|
||||
mov(r3, Operand(ExternalReference(Isolate::kHandlerAddress, isolate())));
|
||||
ldr(sp, MemOperand(r3));
|
||||
|
||||
// Restore context and frame pointer, discard state (r2).
|
||||
// Unwind the handlers until the top ENTRY handler is found.
|
||||
Label fetch_next, check_kind;
|
||||
jmp(&check_kind);
|
||||
bind(&fetch_next);
|
||||
ldr(sp, MemOperand(sp, StackHandlerConstants::kNextOffset));
|
||||
|
||||
bind(&check_kind);
|
||||
ldr(r2, MemOperand(sp, StackHandlerConstants::kStateOffset));
|
||||
cmp(r2, Operand(StackHandler::ENTRY));
|
||||
b(ne, &fetch_next);
|
||||
|
||||
// Set the top handler address to next handler past the top ENTRY handler.
|
||||
pop(r2);
|
||||
str(r2, MemOperand(r3));
|
||||
|
||||
// Clear the context and frame pointer (0 was saved in the handler), and
|
||||
// discard the state (r2).
|
||||
ldm(ia_w, sp, r2.bit() | cp.bit() | fp.bit());
|
||||
#ifdef DEBUG
|
||||
if (emit_debug_code()) {
|
||||
mov(lr, Operand(pc));
|
||||
}
|
||||
#endif
|
||||
|
||||
pop(pc);
|
||||
}
|
||||
|
||||
|
@ -816,52 +816,43 @@ void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type,
|
||||
STATIC_ASSERT(StackHandlerConstants::kStateOffset == 3 * kPointerSize);
|
||||
STATIC_ASSERT(StackHandlerConstants::kPCOffset == 4 * kPointerSize);
|
||||
|
||||
// eax must hold the exception.
|
||||
if (!value.is(eax)) {
|
||||
mov(eax, value);
|
||||
}
|
||||
|
||||
// Drop sp to the top stack handler.
|
||||
ExternalReference handler_address(Isolate::kHandlerAddress,
|
||||
isolate());
|
||||
mov(esp, Operand::StaticVariable(handler_address));
|
||||
|
||||
// Unwind the handlers until the ENTRY handler is found.
|
||||
Label loop, done;
|
||||
bind(&loop);
|
||||
// Load the type of the current stack handler.
|
||||
const int kStateOffset = StackHandlerConstants::kStateOffset;
|
||||
cmp(Operand(esp, kStateOffset), Immediate(StackHandler::ENTRY));
|
||||
j(equal, &done, Label::kNear);
|
||||
// Fetch the next handler in the list.
|
||||
const int kNextOffset = StackHandlerConstants::kNextOffset;
|
||||
mov(esp, Operand(esp, kNextOffset));
|
||||
jmp(&loop);
|
||||
bind(&done);
|
||||
|
||||
// Set the top handler address to next handler past the current ENTRY handler.
|
||||
pop(Operand::StaticVariable(handler_address));
|
||||
|
||||
// The exception is expected in eax.
|
||||
if (type == OUT_OF_MEMORY) {
|
||||
// Set external caught exception to false.
|
||||
ExternalReference external_caught(
|
||||
Isolate::kExternalCaughtExceptionAddress,
|
||||
isolate());
|
||||
mov(eax, false);
|
||||
mov(Operand::StaticVariable(external_caught), eax);
|
||||
ExternalReference external_caught(Isolate::kExternalCaughtExceptionAddress,
|
||||
isolate());
|
||||
mov(Operand::StaticVariable(external_caught), Immediate(false));
|
||||
|
||||
// Set pending exception and eax to out of memory exception.
|
||||
ExternalReference pending_exception(Isolate::kPendingExceptionAddress,
|
||||
isolate());
|
||||
mov(eax, reinterpret_cast<int32_t>(Failure::OutOfMemoryException()));
|
||||
mov(Operand::StaticVariable(pending_exception), eax);
|
||||
} else if (!value.is(eax)) {
|
||||
mov(eax, value);
|
||||
}
|
||||
|
||||
// Discard the context saved in the handler and clear the context pointer.
|
||||
pop(edx);
|
||||
Set(esi, Immediate(0));
|
||||
// Drop the stack pointer to the top of the top stack handler.
|
||||
ExternalReference handler_address(Isolate::kHandlerAddress, isolate());
|
||||
mov(esp, Operand::StaticVariable(handler_address));
|
||||
|
||||
// Restore fp from handler and discard handler state.
|
||||
// Unwind the handlers until the top ENTRY handler is found.
|
||||
Label fetch_next, check_kind;
|
||||
jmp(&check_kind, Label::kNear);
|
||||
bind(&fetch_next);
|
||||
mov(esp, Operand(esp, StackHandlerConstants::kNextOffset));
|
||||
|
||||
bind(&check_kind);
|
||||
cmp(Operand(esp, StackHandlerConstants::kStateOffset),
|
||||
Immediate(StackHandler::ENTRY));
|
||||
j(not_equal, &fetch_next);
|
||||
|
||||
// Set the top handler address to next handler past the top ENTRY handler.
|
||||
pop(Operand::StaticVariable(handler_address));
|
||||
|
||||
// Clear the context and frame pointer (0 was saved in the handler), and
|
||||
// discard the state.
|
||||
pop(esi);
|
||||
pop(ebp);
|
||||
pop(edx); // State.
|
||||
|
||||
|
@ -2509,35 +2509,12 @@ void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type,
|
||||
STATIC_ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize);
|
||||
STATIC_ASSERT(StackHandlerConstants::kStateOffset == 3 * kPointerSize);
|
||||
STATIC_ASSERT(StackHandlerConstants::kPCOffset == 4 * kPointerSize);
|
||||
// Keep thrown value in rax.
|
||||
if (!value.is(rax)) {
|
||||
movq(rax, value);
|
||||
}
|
||||
// Fetch top stack handler.
|
||||
ExternalReference handler_address(Isolate::kHandlerAddress, isolate());
|
||||
Load(rsp, handler_address);
|
||||
|
||||
// Unwind the handlers until the ENTRY handler is found.
|
||||
Label loop, done;
|
||||
bind(&loop);
|
||||
// Load the type of the current stack handler.
|
||||
const int kStateOffset = StackHandlerConstants::kStateOffset;
|
||||
cmpq(Operand(rsp, kStateOffset), Immediate(StackHandler::ENTRY));
|
||||
j(equal, &done, Label::kNear);
|
||||
// Fetch the next handler in the list.
|
||||
const int kNextOffset = StackHandlerConstants::kNextOffset;
|
||||
movq(rsp, Operand(rsp, kNextOffset));
|
||||
jmp(&loop);
|
||||
bind(&done);
|
||||
|
||||
// Set the top handler address to next handler past the current ENTRY handler.
|
||||
Operand handler_operand = ExternalOperand(handler_address);
|
||||
pop(handler_operand);
|
||||
|
||||
// The exception is expected in rax.
|
||||
if (type == OUT_OF_MEMORY) {
|
||||
// Set external caught exception to false.
|
||||
ExternalReference external_caught(
|
||||
Isolate::kExternalCaughtExceptionAddress, isolate());
|
||||
ExternalReference external_caught(Isolate::kExternalCaughtExceptionAddress,
|
||||
isolate());
|
||||
Set(rax, static_cast<int64_t>(false));
|
||||
Store(external_caught, rax);
|
||||
|
||||
@ -2546,14 +2523,33 @@ void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type,
|
||||
isolate());
|
||||
movq(rax, Failure::OutOfMemoryException(), RelocInfo::NONE);
|
||||
Store(pending_exception, rax);
|
||||
} else if (!value.is(rax)) {
|
||||
movq(rax, value);
|
||||
}
|
||||
|
||||
// Discard the context saved in the handler and clear the context pointer.
|
||||
pop(rdx);
|
||||
Set(rsi, 0);
|
||||
// Drop the stack pointer to the top of the top stack handler.
|
||||
ExternalReference handler_address(Isolate::kHandlerAddress, isolate());
|
||||
Load(rsp, handler_address);
|
||||
|
||||
pop(rbp); // Restore frame pointer.
|
||||
pop(rdx); // Discard state.
|
||||
// Unwind the handlers until the top ENTRY handler is found.
|
||||
Label fetch_next, check_kind;
|
||||
jmp(&check_kind, Label::kNear);
|
||||
bind(&fetch_next);
|
||||
movq(rsp, Operand(rsp, StackHandlerConstants::kNextOffset));
|
||||
|
||||
bind(&check_kind);
|
||||
cmpq(Operand(rsp, StackHandlerConstants::kStateOffset),
|
||||
Immediate(StackHandler::ENTRY));
|
||||
j(not_equal, &fetch_next);
|
||||
|
||||
// Set the top handler address to next handler past the top ENTRY handler.
|
||||
pop(ExternalOperand(handler_address));
|
||||
|
||||
// Clear the context and frame pointer (0 was saved in the handler), and
|
||||
// discard the state.
|
||||
pop(rsi);
|
||||
pop(rbp);
|
||||
pop(rdx); // State.
|
||||
|
||||
ret(0);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user