| Index: src/x64/macro-assembler-x64.cc
|
| diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc
|
| index 2b15553f17ed35a5eeb560296e2e9b7d56ff324a..e4a76270a2189b5a99f3c43ea0b4b9dc01e96726 100644
|
| --- a/src/x64/macro-assembler-x64.cc
|
| +++ b/src/x64/macro-assembler-x64.cc
|
| @@ -2387,18 +2387,15 @@ Operand MacroAssembler::SafepointRegisterSlot(Register reg) {
|
| void MacroAssembler::PushTryHandler(CodeLocation try_location,
|
| HandlerType type) {
|
| // Adjust this code if not the case.
|
| - ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize);
|
| + STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize);
|
| + STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0 * kPointerSize);
|
| + STATIC_ASSERT(StackHandlerConstants::kContextOffset == 1 * kPointerSize);
|
| + STATIC_ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize);
|
| + STATIC_ASSERT(StackHandlerConstants::kStateOffset == 3 * kPointerSize);
|
| + STATIC_ASSERT(StackHandlerConstants::kPCOffset == 4 * kPointerSize);
|
|
|
| // The pc (return address) is already on TOS. This code pushes state,
|
| - // frame pointer and current handler. Check that they are expected
|
| - // next on the stack, in that order.
|
| - ASSERT_EQ(StackHandlerConstants::kStateOffset,
|
| - StackHandlerConstants::kPCOffset - kPointerSize);
|
| - ASSERT_EQ(StackHandlerConstants::kFPOffset,
|
| - StackHandlerConstants::kStateOffset - kPointerSize);
|
| - ASSERT_EQ(StackHandlerConstants::kNextOffset,
|
| - StackHandlerConstants::kFPOffset - kPointerSize);
|
| -
|
| + // frame pointer, context, and current handler.
|
| if (try_location == IN_JAVASCRIPT) {
|
| if (type == TRY_CATCH_HANDLER) {
|
| push(Immediate(StackHandler::TRY_CATCH));
|
| @@ -2406,6 +2403,7 @@ void MacroAssembler::PushTryHandler(CodeLocation try_location,
|
| push(Immediate(StackHandler::TRY_FINALLY));
|
| }
|
| push(rbp);
|
| + push(rsi);
|
| } else {
|
| ASSERT(try_location == IN_JS_ENTRY);
|
| // The frame pointer does not point to a JS frame so we save NULL
|
| @@ -2413,6 +2411,7 @@ void MacroAssembler::PushTryHandler(CodeLocation try_location,
|
| // before dereferencing it to restore the context.
|
| push(Immediate(StackHandler::ENTRY));
|
| push(Immediate(0)); // NULL frame pointer.
|
| + Push(Smi::FromInt(0)); // No context.
|
| }
|
| // Save the current handler.
|
| Operand handler_operand =
|
| @@ -2435,12 +2434,13 @@ void MacroAssembler::PopTryHandler() {
|
|
|
|
|
| void MacroAssembler::Throw(Register value) {
|
| - // Check that stack should contain next handler, frame pointer, state and
|
| - // return address in that order.
|
| - STATIC_ASSERT(StackHandlerConstants::kFPOffset + kPointerSize ==
|
| - StackHandlerConstants::kStateOffset);
|
| - STATIC_ASSERT(StackHandlerConstants::kStateOffset + kPointerSize ==
|
| - StackHandlerConstants::kPCOffset);
|
| + // Adjust this code if not the case.
|
| + STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize);
|
| + STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0 * kPointerSize);
|
| + STATIC_ASSERT(StackHandlerConstants::kContextOffset == 1 * kPointerSize);
|
| + 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);
|
| @@ -2451,23 +2451,32 @@ void MacroAssembler::Throw(Register value) {
|
| movq(rsp, handler_operand);
|
| // get next in chain
|
| pop(handler_operand);
|
| - pop(rbp); // pop frame pointer
|
| - pop(rdx); // remove state
|
| + pop(rsi); // Context.
|
| + pop(rbp); // Frame pointer.
|
| + pop(rdx); // State.
|
|
|
| - // Before returning we restore the context from the frame pointer if not NULL.
|
| - // The frame pointer is NULL in the exception handler of a JS entry frame.
|
| - Set(rsi, 0); // Tentatively set context pointer to NULL
|
| + // If the handler is a JS frame, restore the context to the frame.
|
| + // (rdx == ENTRY) == (rbp == 0) == (rsi == 0), so we could test any
|
| + // of them.
|
| Label skip;
|
| - cmpq(rbp, Immediate(0));
|
| + cmpq(rdx, Immediate(StackHandler::ENTRY));
|
| j(equal, &skip, Label::kNear);
|
| - movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
|
| + movq(Operand(rbp, StandardFrameConstants::kContextOffset), rsi);
|
| bind(&skip);
|
| +
|
| ret(0);
|
| }
|
|
|
|
|
| void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type,
|
| Register value) {
|
| + // Adjust this code if not the case.
|
| + STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize);
|
| + STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0 * kPointerSize);
|
| + STATIC_ASSERT(StackHandlerConstants::kContextOffset == 1 * kPointerSize);
|
| + 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);
|
| @@ -2507,19 +2516,13 @@ void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type,
|
| Store(pending_exception, rax);
|
| }
|
|
|
| - // Clear the context pointer.
|
| + // Discard the context saved in the handler and clear the context pointer.
|
| + pop(rdx);
|
| Set(rsi, 0);
|
|
|
| - // Restore registers from handler.
|
| - STATIC_ASSERT(StackHandlerConstants::kNextOffset + kPointerSize ==
|
| - StackHandlerConstants::kFPOffset);
|
| - pop(rbp); // FP
|
| - STATIC_ASSERT(StackHandlerConstants::kFPOffset + kPointerSize ==
|
| - StackHandlerConstants::kStateOffset);
|
| - pop(rdx); // State
|
| + pop(rbp); // Restore frame pointer.
|
| + pop(rdx); // Discard state.
|
|
|
| - STATIC_ASSERT(StackHandlerConstants::kStateOffset + kPointerSize ==
|
| - StackHandlerConstants::kPCOffset);
|
| ret(0);
|
| }
|
|
|
|
|