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));
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));
+
+ // 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));
- // Restore context and frame pointer, discard state (r2).
+ 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);
}
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));
+
+ // 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));
- // Restore fp from handler and discard handler state.
+ // Clear the context and frame pointer (0 was saved in the handler), and
+ // discard the state.
+ pop(esi);
pop(ebp);
pop(edx); // State.
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);
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);
+
+ // 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));
- pop(rbp); // Restore frame pointer.
- pop(rdx); // Discard state.
+ 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);
}