| Index: src/arm/codegen-arm.cc
|
| ===================================================================
|
| --- src/arm/codegen-arm.cc (revision 2128)
|
| +++ src/arm/codegen-arm.cc (working copy)
|
| @@ -2107,14 +2107,16 @@
|
| // Get an external reference to the handler address.
|
| ExternalReference handler_address(Top::k_handler_address);
|
|
|
| - // The next handler address is at kNextIndex in the stack.
|
| - const int kNextIndex = StackHandlerConstants::kNextOffset / kPointerSize;
|
| // If we can fall off the end of the try block, unlink from try chain.
|
| if (has_valid_frame()) {
|
| - __ ldr(r1, frame_->ElementAt(kNextIndex));
|
| + // The next handler address is on top of the frame. Unlink from
|
| + // the handler list and drop the rest of this handler from the
|
| + // frame.
|
| + ASSERT(StackHandlerConstants::kNextOffset == 0);
|
| + frame_->EmitPop(r1);
|
| __ mov(r3, Operand(handler_address));
|
| __ str(r1, MemOperand(r3));
|
| - frame_->Drop(StackHandlerConstants::kSize / kPointerSize);
|
| + frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1);
|
| if (has_unlinks) {
|
| exit.Jump();
|
| }
|
| @@ -2134,15 +2136,11 @@
|
| // break from (eg, for...in) may have left stuff on the stack.
|
| __ mov(r3, Operand(handler_address));
|
| __ ldr(sp, MemOperand(r3));
|
| - // The stack pointer was restored to just below the code slot
|
| - // (the topmost slot) in the handler.
|
| - frame_->Forget(frame_->height() - handler_height + 1);
|
| + frame_->Forget(frame_->height() - handler_height);
|
|
|
| - // kNextIndex is off by one because the code slot has already
|
| - // been dropped.
|
| - __ ldr(r1, frame_->ElementAt(kNextIndex - 1));
|
| + ASSERT(StackHandlerConstants::kNextOffset == 0);
|
| + frame_->EmitPop(r1);
|
| __ str(r1, MemOperand(r3));
|
| - // The code slot has already been dropped from the handler.
|
| frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1);
|
|
|
| if (!function_return_is_shadowed_ && i == kReturnShadowIndex) {
|
| @@ -2223,15 +2221,15 @@
|
| // Get an external reference to the handler address.
|
| ExternalReference handler_address(Top::k_handler_address);
|
|
|
| - // The next handler address is at kNextIndex in the stack.
|
| - const int kNextIndex = StackHandlerConstants::kNextOffset / kPointerSize;
|
| // If we can fall off the end of the try block, unlink from the try
|
| // chain and set the state on the frame to FALLING.
|
| if (has_valid_frame()) {
|
| - __ ldr(r1, frame_->ElementAt(kNextIndex));
|
| + // The next handler address is on top of the frame.
|
| + ASSERT(StackHandlerConstants::kNextOffset == 0);
|
| + frame_->EmitPop(r1);
|
| __ mov(r3, Operand(handler_address));
|
| __ str(r1, MemOperand(r3));
|
| - frame_->Drop(StackHandlerConstants::kSize / kPointerSize);
|
| + frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1);
|
|
|
| // Fake a top of stack value (unneeded when FALLING) and set the
|
| // state in r2, then jump around the unlink blocks if any.
|
| @@ -2262,17 +2260,14 @@
|
| // stack.
|
| __ mov(r3, Operand(handler_address));
|
| __ ldr(sp, MemOperand(r3));
|
| - // The stack pointer was restored to the address slot in the handler.
|
| - ASSERT(StackHandlerConstants::kNextOffset == 1 * kPointerSize);
|
| - frame_->Forget(frame_->height() - handler_height + 1);
|
| + frame_->Forget(frame_->height() - handler_height);
|
|
|
| // Unlink this handler and drop it from the frame. The next
|
| - // handler address is now on top of the frame.
|
| + // handler address is currently on top of the frame.
|
| + ASSERT(StackHandlerConstants::kNextOffset == 0);
|
| frame_->EmitPop(r1);
|
| __ str(r1, MemOperand(r3));
|
| - // The top (code) and the second (handler) slot have both been
|
| - // dropped already.
|
| - frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 2);
|
| + frame_->Drop(StackHandlerConstants::kSize / kPointerSize - 1);
|
|
|
| if (i == kReturnShadowIndex) {
|
| // If this label shadowed the function return, materialize the
|
| @@ -4679,16 +4674,25 @@
|
|
|
|
|
| void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
|
| - // r0 holds exception
|
| - ASSERT(StackHandlerConstants::kSize == 6 * kPointerSize); // adjust this code
|
| + // r0 holds the exception.
|
| +
|
| + // Adjust this code if not the case.
|
| + ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize);
|
| +
|
| + // Drop the sp to the top of the handler.
|
| __ mov(r3, Operand(ExternalReference(Top::k_handler_address)));
|
| __ ldr(sp, MemOperand(r3));
|
| - __ pop(r2); // pop next in chain
|
| +
|
| + // Restore the next handler and frame pointer, discard handler state.
|
| + ASSERT(StackHandlerConstants::kNextOffset == 0);
|
| + __ pop(r2);
|
| __ str(r2, MemOperand(r3));
|
| - // restore parameter- and frame-pointer and pop state.
|
| - __ ldm(ia_w, sp, r3.bit() | pp.bit() | fp.bit());
|
| - // 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.
|
| + ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize);
|
| + __ ldm(ia_w, sp, r3.bit() | fp.bit()); // r3: discarded 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.
|
| __ cmp(fp, Operand(0));
|
| // Set cp to NULL if fp is NULL.
|
| __ mov(cp, Operand(0), LeaveCC, eq);
|
| @@ -4699,39 +4703,41 @@
|
| __ mov(lr, Operand(pc));
|
| }
|
| #endif
|
| + ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize);
|
| __ pop(pc);
|
| }
|
|
|
|
|
| void CEntryStub::GenerateThrowOutOfMemory(MacroAssembler* masm) {
|
| - // Fetch top stack handler.
|
| + // Adjust this code if not the case.
|
| + ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize);
|
| +
|
| + // Drop sp to the top stack handler.
|
| __ mov(r3, Operand(ExternalReference(Top::k_handler_address)));
|
| - __ ldr(r3, MemOperand(r3));
|
| + __ 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::kAddressDisplacement +
|
| - StackHandlerConstants::kStateOffset;
|
| - __ ldr(r2, MemOperand(r3, kStateOffset));
|
| + 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::kAddressDisplacement +
|
| - StackHandlerConstants::kNextOffset;
|
| - __ ldr(r3, MemOperand(r3, kNextOffset));
|
| + 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.
|
| - __ ldr(r0, MemOperand(r3, kNextOffset));
|
| - __ mov(r2, Operand(ExternalReference(Top::k_handler_address)));
|
| - __ str(r0, MemOperand(r2));
|
| + ASSERT(StackHandlerConstants::kNextOffset == 0);
|
| + __ pop(r0);
|
| + __ str(r0, MemOperand(r3));
|
|
|
| // Set external caught exception to false.
|
| + ExternalReference external_caught(Top::k_external_caught_exception_address);
|
| __ mov(r0, Operand(false));
|
| - ExternalReference external_caught(Top::k_external_caught_exception_address);
|
| __ mov(r2, Operand(external_caught));
|
| __ str(r0, MemOperand(r2));
|
|
|
| @@ -4741,21 +4747,17 @@
|
| __ mov(r2, Operand(ExternalReference(Top::k_pending_exception_address)));
|
| __ str(r0, MemOperand(r2));
|
|
|
| - // Restore the stack to the address of the ENTRY handler
|
| - __ mov(sp, Operand(r3));
|
| + // Stack layout at this point. See also StackHandlerConstants.
|
| + // sp -> state (ENTRY)
|
| + // fp
|
| + // lr
|
|
|
| - // Stack layout at this point. See also PushTryHandler
|
| - // r3, sp -> next handler
|
| - // state (ENTRY)
|
| - // pp
|
| - // fp
|
| - // lr
|
| -
|
| - // Discard ENTRY state (r2 is not used), and restore parameter-
|
| - // and frame-pointer and pop state.
|
| - __ ldm(ia_w, sp, r2.bit() | r3.bit() | pp.bit() | fp.bit());
|
| - // 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.
|
| + // Discard handler state (r2 is not used) and restore frame pointer.
|
| + ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize);
|
| + __ ldm(ia_w, sp, r2.bit() | fp.bit()); // r2: discarded 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.
|
| __ cmp(fp, Operand(0));
|
| // Set cp to NULL if fp is NULL.
|
| __ mov(cp, Operand(0), LeaveCC, eq);
|
| @@ -4766,6 +4768,7 @@
|
| __ mov(lr, Operand(pc));
|
| }
|
| #endif
|
| + ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize);
|
| __ pop(pc);
|
| }
|
|
|
|
|