Revision: 19940
Author:   [email protected]
Date:     Fri Mar 14 15:11:58 2014 UTC
Log:      Fix deoptimization for out-of-line constant pool.

Ensure that the stack contains the correct constant pool pointer when a
function deopts.

This CL depends on https://codereview.chromium.org/183803022/ landing first.

[email protected]

Review URL: https://codereview.chromium.org/188063002
http://code.google.com/p/v8/source/detail?r=19940

Modified:
 /branches/bleeding_edge/src/a64/deoptimizer-a64.cc
 /branches/bleeding_edge/src/a64/frames-a64.cc
 /branches/bleeding_edge/src/arm/builtins-arm.cc
 /branches/bleeding_edge/src/arm/deoptimizer-arm.cc
 /branches/bleeding_edge/src/deoptimizer.cc
 /branches/bleeding_edge/src/deoptimizer.h
 /branches/bleeding_edge/src/frames-inl.h
 /branches/bleeding_edge/src/frames.cc
 /branches/bleeding_edge/src/frames.h
 /branches/bleeding_edge/src/ia32/deoptimizer-ia32.cc
 /branches/bleeding_edge/src/x64/deoptimizer-x64.cc

=======================================
--- /branches/bleeding_edge/src/a64/deoptimizer-a64.cc Wed Mar 12 15:18:40 2014 UTC +++ /branches/bleeding_edge/src/a64/deoptimizer-a64.cc Fri Mar 14 15:11:58 2014 UTC
@@ -375,6 +375,12 @@
 void FrameDescription::SetCallerFp(unsigned offset, intptr_t value) {
   SetFrameSlot(offset, value);
 }
+
+
+void FrameDescription::SetCallerConstantPool(unsigned offset, intptr_t value) {
+  // No out-of-line constant pool support.
+  UNREACHABLE();
+}


 #undef __
=======================================
--- /branches/bleeding_edge/src/a64/frames-a64.cc Wed Feb 12 09:19:30 2014 UTC +++ /branches/bleeding_edge/src/a64/frames-a64.cc Fri Mar 14 15:11:58 2014 UTC
@@ -40,10 +40,18 @@

 Register JavaScriptFrame::fp_register() { return v8::internal::fp; }
 Register JavaScriptFrame::context_register() { return cp; }
+Register JavaScriptFrame::constant_pool_pointer_register() {
+  UNREACHABLE();
+  return no_reg;
+}


Register StubFailureTrampolineFrame::fp_register() { return v8::internal::fp; }
 Register StubFailureTrampolineFrame::context_register() { return cp; }
+Register StubFailureTrampolineFrame::constant_pool_pointer_register() {
+  UNREACHABLE();
+  return no_reg;
+}


 Object*& ExitFrame::constant_pool_slot() const {
=======================================
--- /branches/bleeding_edge/src/arm/builtins-arm.cc Wed Mar 12 15:56:16 2014 UTC +++ /branches/bleeding_edge/src/arm/builtins-arm.cc Fri Mar 14 15:11:58 2014 UTC
@@ -1353,8 +1353,14 @@
   // then tear down the parameters.
__ ldr(r1, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp +
                               kPointerSize)));
-  __ mov(sp, fp);
-  __ ldm(ia_w, sp, fp.bit() | lr.bit());
+
+  if (FLAG_enable_ool_constant_pool) {
+    __ add(sp, fp, Operand(StandardFrameConstants::kConstantPoolOffset));
+    __ ldm(ia_w, sp, pp.bit() | fp.bit() | lr.bit());
+  } else {
+    __ mov(sp, fp);;
+    __ ldm(ia_w, sp, fp.bit() | lr.bit());
+  }
   __ add(sp, sp, Operand::PointerOffsetFromSmiKey(r1));
   __ add(sp, sp, Operand(kPointerSize));  // adjust for receiver
 }
=======================================
--- /branches/bleeding_edge/src/arm/deoptimizer-arm.cc Mon Mar 3 11:11:39 2014 UTC +++ /branches/bleeding_edge/src/arm/deoptimizer-arm.cc Fri Mar 14 15:11:58 2014 UTC
@@ -371,6 +371,12 @@
 void FrameDescription::SetCallerFp(unsigned offset, intptr_t value) {
   SetFrameSlot(offset, value);
 }
+
+
+void FrameDescription::SetCallerConstantPool(unsigned offset, intptr_t value) {
+  ASSERT(FLAG_enable_ool_constant_pool);
+  SetFrameSlot(offset, value);
+}


 #undef __
=======================================
--- /branches/bleeding_edge/src/deoptimizer.cc  Thu Mar 13 07:17:37 2014 UTC
+++ /branches/bleeding_edge/src/deoptimizer.cc  Fri Mar 14 15:11:58 2014 UTC
@@ -992,24 +992,19 @@

   if (FLAG_enable_ool_constant_pool) {
// For the bottommost output frame the constant pool pointer can be gotten - // from the input frame. For subsequent output frames, it can be gotten from
-    // the function's code.
-    Register constant_pool_reg =
-        JavaScriptFrame::constant_pool_pointer_register();
+ // from the input frame. For subsequent output frames, it can be read from
+    // the previous frame.
     output_offset -= kPointerSize;
     input_offset -= kPointerSize;
     if (is_bottommost) {
       value = input_->GetFrameSlot(input_offset);
     } else {
-      value = reinterpret_cast<intptr_t>(
-                  function->shared()->code()->constant_pool());
+      value = output_[frame_index - 1]->GetConstantPool();
     }
-    output_frame->SetFrameSlot(output_offset, value);
-    output_frame->SetConstantPool(value);
- if (is_topmost) output_frame->SetRegister(constant_pool_reg.code(), value);
+    output_frame->SetCallerConstantPool(output_offset, value);
     if (trace_scope_) {
       PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
-             V8PRIxPTR "; constant_pool\n",
+             V8PRIxPTR "; caller's constant_pool\n",
              top_address + output_offset, output_offset, value);
     }
   }
@@ -1066,6 +1061,18 @@
   unsigned pc_offset = FullCodeGenerator::PcField::decode(pc_and_state);
   intptr_t pc_value = reinterpret_cast<intptr_t>(start + pc_offset);
   output_frame->SetPc(pc_value);
+
+  // Update constant pool.
+  if (FLAG_enable_ool_constant_pool) {
+    intptr_t constant_pool_value =
+        reinterpret_cast<intptr_t>(non_optimized_code->constant_pool());
+    output_frame->SetConstantPool(constant_pool_value);
+    if (is_topmost) {
+      Register constant_pool_reg =
+          JavaScriptFrame::constant_pool_pointer_register();
+ output_frame->SetRegister(constant_pool_reg.code(), constant_pool_value);
+    }
+  }

   FullCodeGenerator::State state =
       FullCodeGenerator::StateField::decode(pc_and_state);
@@ -1150,15 +1157,14 @@
   }

   if (FLAG_enable_ool_constant_pool) {
-    // A marker value is used in place of the constant pool.
+    // Read the caller's constant pool from the previous frame.
     output_offset -= kPointerSize;
-    intptr_t constant_pool = reinterpret_cast<intptr_t>(
-        Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
-    output_frame->SetFrameSlot(output_offset, constant_pool);
+    value = output_[frame_index - 1]->GetConstantPool();
+    output_frame->SetCallerConstantPool(output_offset, value);
     if (trace_scope_) {
       PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
-             V8PRIxPTR " ; constant_pool (adaptor sentinel)\n",
-             top_address + output_offset, output_offset, constant_pool);
+             V8PRIxPTR "; caller's constant_pool\n",
+             top_address + output_offset, output_offset, value);
     }
   }

@@ -1205,6 +1211,11 @@
       adaptor_trampoline->instruction_start() +
       isolate_->heap()->arguments_adaptor_deopt_pc_offset()->value());
   output_frame->SetPc(pc_value);
+  if (FLAG_enable_ool_constant_pool) {
+    intptr_t constant_pool_value =
+        reinterpret_cast<intptr_t>(adaptor_trampoline->constant_pool());
+    output_frame->SetConstantPool(constant_pool_value);
+  }
 }


@@ -1280,13 +1291,13 @@
   }

   if (FLAG_enable_ool_constant_pool) {
-    // The constant pool pointer can be gotten from the previous frame.
+    // Read the caller's constant pool from the previous frame.
     output_offset -= kPointerSize;
     value = output_[frame_index - 1]->GetConstantPool();
-    output_frame->SetFrameSlot(output_offset, value);
+    output_frame->SetCallerConstantPool(output_offset, value);
     if (trace_scope_) {
       PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
-             V8PRIxPTR " ; constant pool\n",
+             V8PRIxPTR " ; caller's constant pool\n",
              top_address + output_offset, output_offset, value);
     }
   }
@@ -1367,6 +1378,11 @@
       construct_stub->instruction_start() +
       isolate_->heap()->construct_stub_deopt_pc_offset()->value());
   output_frame->SetPc(pc);
+  if (FLAG_enable_ool_constant_pool) {
+    intptr_t constant_pool_value =
+        reinterpret_cast<intptr_t>(construct_stub->constant_pool());
+    output_frame->SetConstantPool(constant_pool_value);
+  }
 }


@@ -1438,13 +1454,13 @@
   }

   if (FLAG_enable_ool_constant_pool) {
-    // The constant pool pointer can be gotten from the previous frame.
+    // Read the caller's constant pool from the previous frame.
     output_offset -= kPointerSize;
     value = output_[frame_index - 1]->GetConstantPool();
-    output_frame->SetFrameSlot(output_offset, value);
+    output_frame->SetCallerConstantPool(output_offset, value);
     if (trace_scope_) {
       PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
-             V8PRIxPTR " ; constant pool\n",
+             V8PRIxPTR " ; caller's constant pool\n",
              top_address + output_offset, output_offset, value);
     }
   }
@@ -1506,6 +1522,11 @@
   intptr_t pc = reinterpret_cast<intptr_t>(
       accessor_stub->instruction_start() + offset->value());
   output_frame->SetPc(pc);
+  if (FLAG_enable_ool_constant_pool) {
+    intptr_t constant_pool_value =
+        reinterpret_cast<intptr_t>(accessor_stub->constant_pool());
+    output_frame->SetConstantPool(constant_pool_value);
+  }
 }


@@ -1609,17 +1630,14 @@
   }

   if (FLAG_enable_ool_constant_pool) {
-    // The constant pool pointer can be gotten from the input frame.
-    Register constant_pool_pointer_register =
-        StubFailureTrampolineFrame::constant_pool_pointer_register();
+    // Read the caller's constant pool from the input frame.
     input_frame_offset -= kPointerSize;
     value = input_->GetFrameSlot(input_frame_offset);
- output_frame->SetRegister(constant_pool_pointer_register.code(), value);
     output_frame_offset -= kPointerSize;
-    output_frame->SetFrameSlot(output_frame_offset, value);
+    output_frame->SetCallerConstantPool(output_frame_offset, value);
     if (trace_scope_) {
       PrintF("    0x%08" V8PRIxPTR ": [top + %d] <- 0x%08"
-             V8PRIxPTR " ; constant_pool_pointer\n",
+             V8PRIxPTR " ; caller's constant_pool\n",
top_address + output_frame_offset, output_frame_offset, value);
     }
   }
@@ -1753,6 +1771,14 @@
   ASSERT(trampoline != NULL);
   output_frame->SetPc(reinterpret_cast<intptr_t>(
       trampoline->instruction_start()));
+  if (FLAG_enable_ool_constant_pool) {
+    Register constant_pool_reg =
+        StubFailureTrampolineFrame::constant_pool_pointer_register();
+    intptr_t constant_pool_value =
+        reinterpret_cast<intptr_t>(trampoline->constant_pool());
+    output_frame->SetConstantPool(constant_pool_value);
+ output_frame->SetRegister(constant_pool_reg.code(), constant_pool_value);
+  }
   output_frame->SetState(Smi::FromInt(FullCodeGenerator::NO_REGISTERS));
   Code* notify_failure = NotifyStubFailureBuiltin();
   output_frame->SetContinuation(
=======================================
--- /branches/bleeding_edge/src/deoptimizer.h   Thu Feb 27 15:12:12 2014 UTC
+++ /branches/bleeding_edge/src/deoptimizer.h   Fri Mar 14 15:11:58 2014 UTC
@@ -508,6 +508,8 @@

   void SetCallerFp(unsigned offset, intptr_t value);

+  void SetCallerConstantPool(unsigned offset, intptr_t value);
+
   intptr_t GetRegister(unsigned n) const {
 #if DEBUG
     // This convoluted ASSERT is needed to work around a gcc problem that
=======================================
--- /branches/bleeding_edge/src/frames-inl.h    Wed Feb 12 09:19:30 2014 UTC
+++ /branches/bleeding_edge/src/frames-inl.h    Fri Mar 14 15:11:58 2014 UTC
@@ -199,6 +199,11 @@
 inline Address StandardFrame::ComputePCAddress(Address fp) {
   return fp + StandardFrameConstants::kCallerPCOffset;
 }
+
+
+inline Address StandardFrame::ComputeConstantPoolAddress(Address fp) {
+  return fp + StandardFrameConstants::kConstantPoolOffset;
+}


 inline bool StandardFrame::IsArgumentsAdaptorFrame(Address fp) {
=======================================
--- /branches/bleeding_edge/src/frames.cc       Fri Jan 31 16:52:17 2014 UTC
+++ /branches/bleeding_edge/src/frames.cc       Fri Mar 14 15:11:58 2014 UTC
@@ -531,6 +531,10 @@
state->fp = Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset);
   state->pc_address = ResolveReturnAddressLocation(
reinterpret_cast<Address*>(fp() + ExitFrameConstants::kCallerPCOffset));
+  if (FLAG_enable_ool_constant_pool) {
+    state->constant_pool_address = reinterpret_cast<Address*>(
+        fp() + ExitFrameConstants::kConstantPoolOffset);
+  }
 }


@@ -574,6 +578,8 @@
   state->fp = fp;
   state->pc_address = ResolveReturnAddressLocation(
       reinterpret_cast<Address*>(sp - 1 * kPCOnStackSize));
+  state->constant_pool_address =
+ reinterpret_cast<Address*>(fp + ExitFrameConstants::kConstantPoolOffset);
 }


@@ -610,6 +616,8 @@
   state->fp = caller_fp();
   state->pc_address = ResolveReturnAddressLocation(
       reinterpret_cast<Address*>(ComputePCAddress(fp())));
+  state->constant_pool_address =
+      reinterpret_cast<Address*>(ComputeConstantPoolAddress(fp()));
 }


=======================================
--- /branches/bleeding_edge/src/frames.h        Wed Feb 12 09:19:30 2014 UTC
+++ /branches/bleeding_edge/src/frames.h        Fri Mar 14 15:11:58 2014 UTC
@@ -225,10 +225,12 @@
   };

   struct State {
-    State() : sp(NULL), fp(NULL), pc_address(NULL) { }
+    State() : sp(NULL), fp(NULL), pc_address(NULL),
+              constant_pool_address(NULL) { }
     Address sp;
     Address fp;
     Address* pc_address;
+    Address* constant_pool_address;
   };

   // Copy constructor; it breaks the connection to host iterator
@@ -269,6 +271,11 @@

   Address pc() const { return *pc_address(); }
   void set_pc(Address pc) { *pc_address() = pc; }
+
+  Address constant_pool() const { return *constant_pool_address(); }
+  void set_constant_pool(ConstantPoolArray* constant_pool) {
+    *constant_pool_address() = reinterpret_cast<Address>(constant_pool);
+  }

   virtual void SetCallerFp(Address caller_fp) = 0;

@@ -276,6 +283,10 @@
   void UpdateFp(Address fp) { state_.fp = fp; }

   Address* pc_address() const { return state_.pc_address; }
+
+  Address* constant_pool_address() const {
+    return state_.constant_pool_address;
+  }

   // Get the id of this stack frame.
   Id id() const { return static_cast<Id>(OffsetFrom(caller_sp())); }
@@ -496,6 +507,10 @@
   // by the provided frame pointer.
   static inline Address ComputePCAddress(Address fp);

+  // Computes the address of the constant pool  field in the standard
+  // frame given by the provided frame pointer.
+  static inline Address ComputeConstantPoolAddress(Address fp);
+
   // Iterate over expression stack including stack handlers, locals,
   // and parts of the fixed part including context and code fields.
   void IterateExpressions(ObjectVisitor* v) const;
=======================================
--- /branches/bleeding_edge/src/ia32/deoptimizer-ia32.cc Mon Mar 3 11:11:39 2014 UTC +++ /branches/bleeding_edge/src/ia32/deoptimizer-ia32.cc Fri Mar 14 15:11:58 2014 UTC
@@ -461,6 +461,12 @@
 void FrameDescription::SetCallerFp(unsigned offset, intptr_t value) {
   SetFrameSlot(offset, value);
 }
+
+
+void FrameDescription::SetCallerConstantPool(unsigned offset, intptr_t value) {
+  // No out-of-line constant pool support.
+  UNREACHABLE();
+}


 #undef __
=======================================
--- /branches/bleeding_edge/src/x64/deoptimizer-x64.cc Mon Mar 3 11:11:39 2014 UTC +++ /branches/bleeding_edge/src/x64/deoptimizer-x64.cc Fri Mar 14 15:11:58 2014 UTC
@@ -359,6 +359,12 @@
 void FrameDescription::SetCallerFp(unsigned offset, intptr_t value) {
   SetFrameSlot(offset, value);
 }
+
+
+void FrameDescription::SetCallerConstantPool(unsigned offset, intptr_t value) {
+  // No out-of-line constant pool support.
+  UNREACHABLE();
+}


 #undef __

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to