Cleanup of ARM exception handlers. Remove the unused code and
authorkmillikin@chromium.org <kmillikin@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 10 Jun 2009 09:00:07 +0000 (09:00 +0000)
committerkmillikin@chromium.org <kmillikin@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 10 Jun 2009 09:00:07 +0000 (09:00 +0000)
parameter pointer slots.  Change it so that the handler address no
longer points into the middle of the handler.

Review URL: http://codereview.chromium.org/119414

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2129 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

13 files changed:
src/arm/codegen-arm.cc
src/arm/frames-arm.h
src/arm/macro-assembler-arm.cc
src/arm/virtual-frame-arm.cc
src/frames-inl.h
src/frames.h
src/ia32/codegen-ia32.cc
src/ia32/frames-ia32.h
src/ia32/macro-assembler-ia32.cc
src/x64/codegen-x64.cc
src/x64/frames-x64.h
src/x64/macro-assembler-x64.cc
src/x64/macro-assembler-x64.h

index 4353b3b0d2cf569f71c1a1654d65d75b33dac7a3..183c97587271176db47c2c499ddf040cec0da58a 100644 (file)
@@ -2107,14 +2107,16 @@ void CodeGenerator::VisitTryCatch(TryCatch* node) {
   // 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 @@ void CodeGenerator::VisitTryCatch(TryCatch* node) {
       // 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 @@ void CodeGenerator::VisitTryFinally(TryFinally* node) {
   // 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 @@ void CodeGenerator::VisitTryFinally(TryFinally* node) {
       // 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 UnarySubStub::Generate(MacroAssembler* masm) {
 
 
 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 @@ void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
     __ 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.
-  __ mov(r0, Operand(false));
   ExternalReference external_caught(Top::k_external_caught_exception_address);
+  __ mov(r0, Operand(false));
   __ mov(r2, Operand(external_caught));
   __ str(r0, MemOperand(r2));
 
@@ -4741,21 +4747,17 @@ void CEntryStub::GenerateThrowOutOfMemory(MacroAssembler* masm) {
   __ 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 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.
+  // Stack layout at this point. See also StackHandlerConstants.
+  // sp ->   state (ENTRY)
+  //         fp
+  //         lr
+
+  // 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 @@ void CEntryStub::GenerateThrowOutOfMemory(MacroAssembler* masm) {
     __ mov(lr, Operand(pc));
   }
 #endif
+  ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize);
   __ pop(pc);
 }
 
index a67b18a2b6cb685ffc51bfa55666717c503f81d6..2a04192b75df3a1870634af52850fefe581a46ac 100644 (file)
@@ -79,15 +79,11 @@ static const int kNumCalleeSaved = 7 + kR9Available;
 
 class StackHandlerConstants : public AllStatic {
  public:
-  // TODO(1233780): Get rid of the code slot in stack handlers.
-  static const int kCodeOffset  = 0 * kPointerSize;
-  static const int kNextOffset  = 1 * kPointerSize;
-  static const int kStateOffset = 2 * kPointerSize;
-  static const int kPPOffset    = 3 * kPointerSize;
-  static const int kFPOffset    = 4 * kPointerSize;
-  static const int kPCOffset    = 5 * kPointerSize;
-
-  static const int kAddressDisplacement = -1 * kPointerSize;
+  static const int kNextOffset  = 0 * kPointerSize;
+  static const int kStateOffset = 1 * kPointerSize;
+  static const int kFPOffset    = 2 * kPointerSize;
+  static const int kPCOffset    = 3 * kPointerSize;
+
   static const int kSize = kPCOffset + kPointerSize;
 };
 
@@ -161,220 +157,6 @@ inline Object* JavaScriptFrame::function_slot_object() const {
 }
 
 
-// ----------------------------------------------------
-
-
-
-
-  //    lower    |    Stack    |
-  //  addresses  |      ^      |
-  //             |      |      |
-  //             |             |
-  //             |  JS frame   |
-  //             |             |
-  //             |             |
-  // ----------- +=============+ <--- sp (stack pointer)
-  //             |  function   |
-  //             +-------------+
-  //             +-------------+
-  //             |             |
-  //             | expressions |
-  //             |             |
-  //             +-------------+
-  //             |             |
-  //      a      |   locals    |
-  //      c      |             |
-  //      t      +- - - - - - -+ <---
-  //      i   -4 |   local0    |   ^
-  //      v      +-------------+   |
-  //      a   -3 |    code     |   |
-  //      t      +-------------+   | kLocal0Offset
-  //      i   -2 |   context   |   |
-  //      o      +-------------+   |
-  //      n   -1 | args_length |   v
-  //             +-------------+ <--- fp (frame pointer)
-  //           0 |  caller_pp  |
-  //      f      +-------------+
-  //      r    1 |  caller_fp  |
-  //      a      +-------------+
-  //      m    2 |  sp_on_exit |  (pp if return, caller_sp if no return)
-  //      e      +-------------+
-  //           3 |  caller_pc  |
-  //             +-------------+ <--- caller_sp (incl. parameters)
-  //             |             |
-  //             | parameters  |
-  //             |             |
-  //             +- - - - - - -+ <---
-  //          -2 | parameter0  |   ^
-  //             +-------------+   | kParam0Offset
-  //          -1 |  receiver   |   v
-  // ----------- +=============+ <--- pp (parameter pointer, r10)
-  //           0 |  function   |
-  //             +-------------+
-  //             |             |
-  //             |caller-saved |  (must be valid JS values, traversed during GC)
-  //             |    regs     |
-  //             |             |
-  //             +-------------+
-  //             |             |
-  //             |   caller    |
-  //   higher    | expressions |
-  //  addresses  |             |
-  //             |             |
-  //             |  JS frame   |
-
-
-
-  // Handler frames (part of expressions of JS frames):
-
-  //    lower    |    Stack    |
-  //  addresses  |      ^      |
-  //             |      |      |
-  //             |             |
-  //      h      | expressions |
-  //      a      |             |
-  //      n      +-------------+
-  //      d   -1 |    code     |
-  //      l      +-------------+ <--- handler sp
-  //      e    0 |   next_sp   |  link to next handler (next handler's sp)
-  //      r      +-------------+
-  //           1 |    state    |
-  //      f      +-------------+
-  //      r    2 |     pp      |
-  //      a      +-------------+
-  //      m    3 |     fp      |
-  //      e      +-------------+
-  //           4 |     pc      |
-  //             +-------------+
-  //             |             |
-  //   higher    | expressions |
-  //  addresses  |             |
-
-
-
-  // JS entry frames: When calling from C to JS, we construct two extra
-  // frames: An entry frame (C) and a trampoline frame (JS). The
-  // following pictures shows the two frames:
-
-  //    lower    |    Stack    |
-  //  addresses  |      ^      |
-  //             |      |      |
-  //             |             |
-  //             |  JS frame   |
-  //             |             |
-  //             |             |
-  // ----------- +=============+ <--- sp (stack pointer)
-  //             |             |
-  //             | parameters  |
-  //      t      |             |
-  //      r      +- - - - - - -+
-  //      a      | parameter0  |
-  //      m      +-------------+
-  //      p      |  receiver   |
-  //      o      +-------------+
-  //      l      |  function   |
-  //      i      +-------------+
-  //      n   -3 |    code     |
-  //      e      +-------------+
-  //          -2 |    NULL     |  context is always NULL
-  //             +-------------+
-  //      f   -1 |      0      |  args_length is always zero
-  //      r      +-------------+ <--- fp (frame pointer)
-  //      a    0 |    NULL     |  caller pp is always NULL for entries
-  //      m      +-------------+
-  //      e    1 |  caller_fp  |
-  //             +-------------+
-  //           2 |  sp_on_exit |  (caller_sp)
-  //             +-------------+
-  //           3 |  caller_pc  |
-  // ----------- +=============+ <--- caller_sp == pp
-  //                    .          ^
-  //                    .          |  try-handler, fake, not GC'ed
-  //                    .          v
-  //             +-------------+ <---
-  //          -2 | next top pp |
-  //             +-------------+
-  //          -1 | next top fp |
-  //             +-------------+ <--- fp
-  //             |     r4      |  r4-r9 holding non-JS values must be preserved
-  //             +-------------+
-  //      J      |     r5      |  before being initialized not to confuse GC
-  //      S      +-------------+
-  //             |     r6      |
-  //             +-------------+
-  //      e      |     r7      |
-  //      n      +-------------+
-  //      t      |     r8      |
-  //      r      +-------------+
-  //      y    [ |     r9      | ]  only if r9 available
-  //             +-------------+
-  //             |     r10     |
-  //      f      +-------------+
-  //      r      |     r11     |
-  //      a      +-------------+
-  //      m      |  caller_sp  |
-  //      e      +-------------+
-  //             |  caller_pc  |
-  //             +-------------+ <--- caller_sp
-  //             |    argv     |    passed on stack from C code
-  //             +-------------+
-  //             |             |
-  //   higher    |             |
-  //  addresses  |   C frame   |
-
-
-  // The first 4 args are passed from C in r0-r3 and are not spilled on entry:
-  // r0: code entry
-  // r1: function
-  // r2: receiver
-  // r3: argc
-  // [sp+0]: argv
-
-
-  // C entry frames: When calling from JS to C, we construct one extra
-  // frame:
-
-  //    lower    |    Stack    |
-  //  addresses  |      ^      |
-  //             |      |      |
-  //             |             |
-  //             |   C frame   |
-  //             |             |
-  //             |             |
-  // ----------- +=============+ <--- sp (stack pointer)
-  //             |             |
-  //             | parameters  |  (first 4 args are passed in r0-r3)
-  //             |             |
-  //             +-------------+ <--- fp (frame pointer)
-  //      f  4/5 |  caller_fp  |
-  //      r      +-------------+
-  //      a  5/6 |  sp_on_exit |  (pp)
-  //      m      +-------------+
-  //      e  6/7 |  caller_pc  |
-  //             +-------------+ <--- caller_sp (incl. parameters)
-  //         7/8 |             |
-  //             | parameters  |
-  //             |             |
-  //             +- - - - - - -+ <---
-  //          -2 | parameter0  |   ^
-  //             +-------------+   | kParam0Offset
-  //          -1 |  receiver   |   v
-  // ----------- +=============+ <--- pp (parameter pointer, r10)
-  //           0 |  function   |
-  //             +-------------+
-  //             |             |
-  //             |caller-saved |
-  //             |    regs     |
-  //             |             |
-  //             +-------------+
-  //             |             |
-  //             |   caller    |
-  //             | expressions |
-  //             |             |
-  //   higher    |             |
-  //  addresses  |  JS frame   |
-
-
 } }  // namespace v8::internal
 
 #endif  // V8_ARM_FRAMES_ARM_H_
index 80cdac935ab0e858cc76a55fcb8e348522a1e133..633a9a18dfe85d5e153b51c1ab015828000d1b96 100644 (file)
@@ -557,41 +557,48 @@ void MacroAssembler::CopyRegistersFromStackToMemory(Register base,
 }
 #endif
 
+
 void MacroAssembler::PushTryHandler(CodeLocation try_location,
                                     HandlerType type) {
-  ASSERT(StackHandlerConstants::kSize == 6 * kPointerSize);  // adjust this code
+  // Adjust this code if not the case.
+  ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize);
   // The pc (return address) is passed in register lr.
   if (try_location == IN_JAVASCRIPT) {
-    stm(db_w, sp, pp.bit() | fp.bit() | lr.bit());
     if (type == TRY_CATCH_HANDLER) {
       mov(r3, Operand(StackHandler::TRY_CATCH));
     } else {
       mov(r3, Operand(StackHandler::TRY_FINALLY));
     }
-    push(r3);  // state
+    ASSERT(StackHandlerConstants::kStateOffset == 1 * kPointerSize
+           && StackHandlerConstants::kFPOffset == 2 * kPointerSize
+           && StackHandlerConstants::kPCOffset == 3 * kPointerSize);
+    stm(db_w, sp, r3.bit() | fp.bit() | lr.bit());
+    // Save the current handler as the next handler.
     mov(r3, Operand(ExternalReference(Top::k_handler_address)));
     ldr(r1, MemOperand(r3));
-    push(r1);  // next sp
-    str(sp, MemOperand(r3));  // chain handler
-    mov(r0, Operand(Smi::FromInt(StackHandler::kCodeNotPresent)));  // new TOS
-    push(r0);
+    ASSERT(StackHandlerConstants::kNextOffset == 0);
+    push(r1);
+    // Link this handler as the new current one.
+    str(sp, MemOperand(r3));
   } else {
     // Must preserve r0-r4, r5-r7 are available.
     ASSERT(try_location == IN_JS_ENTRY);
-    // The parameter pointer is meaningless here and fp does not point to a JS
-    // frame. So we save NULL for both pp and fp. We expect the code throwing an
-    // exception to check fp before dereferencing it to restore the context.
-    mov(pp, Operand(0));  // set pp to NULL
-    mov(ip, Operand(0));  // to save a NULL fp
-    stm(db_w, sp, pp.bit() | ip.bit() | lr.bit());
+    // The frame pointer does not point to a JS frame so we save NULL
+    // for fp. We expect the code throwing an exception to check fp
+    // before dereferencing it to restore the context.
+    mov(ip, Operand(0));  // To save a NULL frame pointer.
     mov(r6, Operand(StackHandler::ENTRY));
-    push(r6);  // state
+    ASSERT(StackHandlerConstants::kStateOffset == 1 * kPointerSize
+           && StackHandlerConstants::kFPOffset == 2 * kPointerSize
+           && StackHandlerConstants::kPCOffset == 3 * kPointerSize);
+    stm(db_w, sp, r6.bit() | ip.bit() | lr.bit());
+    // Save the current handler as the next handler.
     mov(r7, Operand(ExternalReference(Top::k_handler_address)));
     ldr(r6, MemOperand(r7));
-    push(r6);  // next sp
-    str(sp, MemOperand(r7));  // chain handler
-    mov(r5, Operand(Smi::FromInt(StackHandler::kCodeNotPresent)));  // new TOS
-    push(r5);  // flush TOS
+    ASSERT(StackHandlerConstants::kNextOffset == 0);
+    push(r6);
+    // Link this handler as the new current one.
+    str(sp, MemOperand(r7));
   }
 }
 
index 952738329b69621075dba4fa19757eed6ddbdcd4..50718b1e6320c14eaa32bf09e0a2a34585c302e1 100644 (file)
@@ -230,8 +230,8 @@ void VirtualFrame::StoreToFrameSlotAt(int index) {
 
 
 void VirtualFrame::PushTryHandler(HandlerType type) {
-  // Grow the expression stack by handler size less one (the return address
-  // is already pushed by a call instruction).
+  // Grow the expression stack by handler size less one (the return
+  // address in lr is already counted by a call instruction).
   Adjust(kHandlerSize - 1);
   __ PushTryHandler(IN_JAVASCRIPT, type);
 }
index b48829bb1fb85b08129717ba065ff7d48333c5bf..53034f676a988ed62dddd900eb4ad7b5d91cae25 100644 (file)
@@ -43,13 +43,7 @@ namespace internal {
 
 
 inline Address StackHandler::address() const {
-  // NOTE: There's an obvious problem with the address of the NULL
-  // stack handler. Right now, it benefits us that the subtraction
-  // leads to a very high address (above everything else on the
-  // stack), but maybe we should stop relying on it?
-  const int displacement = StackHandlerConstants::kAddressDisplacement;
-  Address address = reinterpret_cast<Address>(const_cast<StackHandler*>(this));
-  return address + displacement;
+  return reinterpret_cast<Address>(const_cast<StackHandler*>(this));
 }
 
 
index e250609fd9a8ec7b0305aac9f91c0566e1cbfb1d..0d32b579d61b46dded674613f87be485d8b01249 100644 (file)
@@ -78,9 +78,6 @@ class StackHandler BASE_EMBEDDED {
   void Cook(Code* code);
   void Uncook(Code* code);
 
-  // TODO(1233780): Get rid of the code slot in stack handlers.
-  static const int kCodeNotPresent = 0;
-
  private:
   // Accessors.
   inline State state() const;
index 7037bf0e8faaba7d37cb0fcb629096b336abe4f5..a506193485774c46b0392a9e0ceb0ec837115ab3 100644 (file)
@@ -3252,7 +3252,6 @@ void CodeGenerator::VisitTryCatch(TryCatch* node) {
   // Make sure that there's nothing left on the stack above the
   // handler structure.
   if (FLAG_debug_code) {
-    ASSERT(StackHandlerConstants::kAddressDisplacement == 0);
     __ mov(eax, Operand::StaticVariable(handler_address));
     __ cmp(esp, Operand(eax));
     __ Assert(equal, "stack pointer should point to top handler");
@@ -3291,7 +3290,6 @@ void CodeGenerator::VisitTryCatch(TryCatch* node) {
 
       // Reload sp from the top handler, because some statements that we
       // break from (eg, for...in) may have left stuff on the stack.
-      ASSERT(StackHandlerConstants::kAddressDisplacement == 0);
       __ mov(esp, Operand::StaticVariable(handler_address));
       frame_->Forget(frame_->height() - handler_height);
 
@@ -3416,7 +3414,6 @@ void CodeGenerator::VisitTryFinally(TryFinally* node) {
       // Reload sp from the top handler, because some statements that
       // we break from (eg, for...in) may have left stuff on the
       // stack.
-      ASSERT(StackHandlerConstants::kAddressDisplacement == 0);
       __ mov(esp, Operand::StaticVariable(handler_address));
       frame_->Forget(frame_->height() - handler_height);
 
@@ -6955,11 +6952,12 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
 
 
 void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
+  // eax holds the exception.
+
   // Adjust this code if not the case.
   ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize);
 
   // Drop the sp to the top of the handler.
-  ASSERT(StackHandlerConstants::kAddressDisplacement == 0);
   ExternalReference handler_address(Top::k_handler_address);
   __ mov(esp, Operand::StaticVariable(handler_address));
 
@@ -6970,9 +6968,10 @@ void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
   __ pop(ebp);
   __ pop(edx);  // Remove 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.
-  __ xor_(esi, Operand(esi));  // tentatively set context pointer to NULL
+  // 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.
+  __ xor_(esi, Operand(esi));  // Tentatively set context pointer to NULL.
   Label skip;
   __ cmp(ebp, 0);
   __ j(equal, &skip, not_taken);
@@ -7069,7 +7068,6 @@ void CEntryStub::GenerateThrowOutOfMemory(MacroAssembler* masm) {
   ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize);
 
   // Drop sp to the top stack handler.
-  ASSERT(StackHandlerConstants::kAddressDisplacement == 0);
   ExternalReference handler_address(Top::k_handler_address);
   __ mov(esp, Operand::StaticVariable(handler_address));
 
index c0e617c2897efdef52f403691bbce3c9da0782f4..eabcf589b9e0e0719190f5a7945fb9357ddeb793 100644 (file)
@@ -59,7 +59,6 @@ class StackHandlerConstants : public AllStatic {
   static const int kStateOffset = 2 * kPointerSize;
   static const int kPCOffset    = 3 * kPointerSize;
 
-  static const int kAddressDisplacement = 0;
   static const int kSize = kPCOffset + kPointerSize;
 };
 
index 39ed8309dc1bd2a278588fff21dec2ebca21b602..a22a5296a9ecf8a3b12bac39b75579d7606e244f 100644 (file)
@@ -460,12 +460,11 @@ void MacroAssembler::PushTryHandler(CodeLocation try_location,
     push(ebp);
   } else {
     ASSERT(try_location == IN_JS_ENTRY);
-    // The parameter pointer is meaningless here and ebp does not
-    // point to a JS frame. So we save NULL for both pp and ebp. We
-    // expect the code throwing an exception to check ebp before
-    // dereferencing it to restore the context.
+    // The frame pointer does not point to a JS frame so we save NULL
+    // for ebp. We expect the code throwing an exception to check ebp
+    // before dereferencing it to restore the context.
     push(Immediate(StackHandler::ENTRY));
-    push(Immediate(0));  // NULL frame pointer
+    push(Immediate(0));  // NULL frame pointer.
   }
   // Save the current handler as the next handler.
   push(Operand::StaticVariable(ExternalReference(Top::k_handler_address)));
index ca58e09a75f7fb5dfb98d66c36c82f49d345c5f7..9bafb11476aef344439398a4ffaebf135e7e1651 100644 (file)
@@ -281,7 +281,6 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
   // Invoke: Link this frame into the handler chain.
   __ bind(&invoke);
   __ PushTryHandler(IN_JS_ENTRY, JS_ENTRY_HANDLER);
-  __ push(rax);  // flush TOS
 
   // Clear any pending exceptions.
   __ load_rax(ExternalReference::the_hole_value_location());
index 3416f51dea3584fc1550f15702c69e35444de8ff..9a28b611dac55b652b62bc0e61fe0da5f11392ed 100644 (file)
@@ -42,16 +42,11 @@ typedef Object* JSCallerSavedBuffer[kNumJSCallerSaved];
 class StackHandlerConstants : public AllStatic {
  public:
   static const int kNextOffset  = 0 * kPointerSize;
-  static const int kPPOffset    = 1 * kPointerSize;
-  static const int kFPOffset    = 2 * kPointerSize;
+  static const int kFPOffset    = 1 * kPointerSize;
+  static const int kStateOffset = 2 * kPointerSize;
+  static const int kPCOffset    = 3 * kPointerSize;
 
-  static const int kCodeOffset  = 3 * kPointerSize;
-
-  static const int kStateOffset = 4 * kPointerSize;
-  static const int kPCOffset    = 5 * kPointerSize;
-
-  static const int kAddressDisplacement = -1 * kPointerSize;
-  static const int kSize = 6 * kPointerSize;
+  static const int kSize = 4 * kPointerSize;
 };
 
 
index 54c299dbfae9894ff96cec5b59fbf835d3a99c57..e5de25efd0706c94f5d8f29335a10a0deffd380d 100644 (file)
@@ -73,16 +73,17 @@ void MacroAssembler::Set(const Operand& dst, int64_t x) {
 
 void MacroAssembler::PushTryHandler(CodeLocation try_location,
                                     HandlerType type) {
-  // The pc (return address) is already on TOS.
-  // This code pushes state, code, frame pointer and parameter pointer.
-  // Check that they are expected next on the stack, int that order.
+  // Adjust this code if not the case.
+  ASSERT(StackHandlerConstants::kSize == 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::kCodeOffset,
-            StackHandlerConstants::kStateOffset - kPointerSize);
   ASSERT_EQ(StackHandlerConstants::kFPOffset,
-            StackHandlerConstants::kCodeOffset - kPointerSize);
-  ASSERT_EQ(StackHandlerConstants::kPPOffset,
+            StackHandlerConstants::kStateOffset - kPointerSize);
+  ASSERT_EQ(StackHandlerConstants::kNextOffset,
             StackHandlerConstants::kFPOffset - kPointerSize);
 
   if (try_location == IN_JAVASCRIPT) {
@@ -91,23 +92,18 @@ void MacroAssembler::PushTryHandler(CodeLocation try_location,
     } else {
       push(Immediate(StackHandler::TRY_FINALLY));
     }
-    push(Immediate(Smi::FromInt(StackHandler::kCodeNotPresent)));
     push(rbp);
-    push(rdi);
   } else {
     ASSERT(try_location == IN_JS_ENTRY);
-    // The parameter pointer is meaningless here and ebp does not
-    // point to a JS frame. So we save NULL for both pp and ebp. We
-    // expect the code throwing an exception to check ebp before
-    // dereferencing it to restore the context.
+    // The frame pointer does not point to a JS frame so we save NULL
+    // for rbp. We expect the code throwing an exception to check rbp
+    // before dereferencing it to restore the context.
     push(Immediate(StackHandler::ENTRY));
-    push(Immediate(Smi::FromInt(StackHandler::kCodeNotPresent)));
-    push(Immediate(0));  // NULL frame pointer
-    push(Immediate(0));  // NULL parameter pointer
+    push(Immediate(0));  // NULL frame pointer.
   }
+  // Save the current handler.
   movq(kScratchRegister, ExternalReference(Top::k_handler_address));
-  // Cached TOS.
-  movq(rax, Operand(kScratchRegister, 0));
+  push(Operand(kScratchRegister, 0));
   // Link this handler.
   movq(Operand(kScratchRegister, 0), rsp);
 }
index 4af372a81a3eae3ed4742337b15fab141467a42e..958d5a02c2ec55bfeac71430243d0a26460e06c2 100644 (file)
@@ -159,9 +159,8 @@ class MacroAssembler: public Assembler {
   // ---------------------------------------------------------------------------
   // Exception handling
 
-  // Push a new try handler and link into try handler chain.
-  // The return address must be pushed before calling this helper.
-  // On exit, rax contains TOS (next_sp).
+  // Push a new try handler and link into try handler chain.  The return
+  // address must be pushed before calling this helper.
   void PushTryHandler(CodeLocation try_location, HandlerType type);