Fix some out-of-line constant pool garbage collection bugs.
authorrmcilroy@chromium.org <rmcilroy@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 7 Jan 2014 15:53:54 +0000 (15:53 +0000)
committerrmcilroy@chromium.org <rmcilroy@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 7 Jan 2014 15:53:54 +0000 (15:53 +0000)
This CL fixes some bugs in the out of line constant pool implementation when
constant pools are GCed.  Namely:
  - Push/Pop pp register in exit frames and VisitPointer on it to ensure it is
    updated if the ConstantPoolArray is moved by GC.
  - Mark pp as a SafePoint Register for optimized functions.
  - Ensure that StandardFrame::IterateExpressions also iterates over the
    constant pool pointer in the stackframe.
  - Fix calculation of last_ptr_offset in ConstantPoolArray body iterator.
  - Make ensure that CONSTANT_POOL_ARRAY_TYPE is a pointer object InstanceType.

R=ulan@chromium.org

Review URL: https://codereview.chromium.org/123263005

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

15 files changed:
src/arm/frames-arm.cc
src/arm/frames-arm.h
src/arm/lithium-codegen-arm.cc
src/arm/macro-assembler-arm.cc
src/frames.cc
src/frames.h
src/ia32/frames-ia32.cc
src/ia32/frames-ia32.h
src/mips/frames-mips.cc
src/mips/frames-mips.h
src/objects-visiting-inl.h
src/objects.cc
src/objects.h
src/x64/frames-x64.cc
src/x64/frames-x64.h

index 8c3e9883908bf937e4236da84a727b8342405c8f..780b48a8ef5252d97527c3e6197512a91a0d9fd4 100644 (file)
@@ -56,6 +56,13 @@ Register StubFailureTrampolineFrame::constant_pool_pointer_register() {
 }
 
 
+Object*& ExitFrame::constant_pool_slot() const {
+  ASSERT(FLAG_enable_ool_constant_pool);
+  const int offset = ExitFrameConstants::kConstantPoolOffset;
+  return Memory::Object_at(fp() + offset);
+}
+
+
 } }  // namespace v8::internal
 
 #endif  // V8_TARGET_ARCH_ARM
index e6ecda1fb533b54da7cd29da32e6819dca2181ec..29000ca3ab52e98604827aba682505aeaaa1c503 100644 (file)
@@ -109,8 +109,13 @@ class EntryFrameConstants : public AllStatic {
 
 class ExitFrameConstants : public AllStatic {
  public:
-  static const int kCodeOffset = -2 * kPointerSize;
-  static const int kSPOffset = -1 * kPointerSize;
+  static const int kFrameSize          = FLAG_enable_ool_constant_pool ?
+                                         3 * kPointerSize : 2 * kPointerSize;
+
+  static const int kConstantPoolOffset = FLAG_enable_ool_constant_pool ?
+                                         -3 * kPointerSize : 0;
+  static const int kCodeOffset         = -2 * kPointerSize;
+  static const int kSPOffset           = -1 * kPointerSize;
 
   // The caller fields are below the frame pointer on the stack.
   static const int kCallerFPOffset = 0 * kPointerSize;
index caeee042da417ff6af7af9dff7611c2737faa10a..aa8784c9b16f9df4f21bc2d6ca9506375814afbe 100644 (file)
@@ -979,6 +979,10 @@ void LCodeGen::RecordSafepoint(
       safepoint.DefinePointerRegister(ToRegister(pointer), zone());
     }
   }
+  if (FLAG_enable_ool_constant_pool && (kind & Safepoint::kWithRegisters)) {
+    // Register pp always contains a pointer to the constant pool.
+    safepoint.DefinePointerRegister(pp, zone());
+  }
 }
 
 
index a9acdd5ab4783ea51318e5f29589bf71f4833154..97d05a60225c33758d8153b5bf6b80c8186c1b95 100644 (file)
@@ -967,11 +967,14 @@ void MacroAssembler::EnterExitFrame(bool save_doubles, int stack_space) {
   Push(lr, fp);
   mov(fp, Operand(sp));  // Set up new frame pointer.
   // Reserve room for saved entry sp and code object.
-  sub(sp, sp, Operand(2 * kPointerSize));
+  sub(sp, sp, Operand(ExitFrameConstants::kFrameSize));
   if (emit_debug_code()) {
     mov(ip, Operand::Zero());
     str(ip, MemOperand(fp, ExitFrameConstants::kSPOffset));
   }
+  if (FLAG_enable_ool_constant_pool) {
+    str(pp, MemOperand(fp, ExitFrameConstants::kConstantPoolOffset));
+  }
   mov(ip, Operand(CodeObject()));
   str(ip, MemOperand(fp, ExitFrameConstants::kCodeOffset));
 
@@ -985,8 +988,10 @@ void MacroAssembler::EnterExitFrame(bool save_doubles, int stack_space) {
   if (save_doubles) {
     SaveFPRegs(sp, ip);
     // Note that d0 will be accessible at
-    //   fp - 2 * kPointerSize - DwVfpRegister::kMaxNumRegisters * kDoubleSize,
-    // since the sp slot and code slot were pushed after the fp.
+    //   fp - ExitFrameConstants::kFrameSize -
+    //   DwVfpRegister::kMaxNumRegisters * kDoubleSize,
+    // since the sp slot, code slot and constant pool slot (if
+    // FLAG_enable_ool_constant_pool) were pushed after the fp.
   }
 
   // Reserve place for the return address and stack space and align the frame
@@ -1042,7 +1047,7 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles,
   // Optionally restore all double registers.
   if (save_doubles) {
     // Calculate the stack location of the saved doubles and restore them.
-    const int offset = 2 * kPointerSize;
+    const int offset = ExitFrameConstants::kFrameSize;
     sub(r3, fp,
         Operand(offset + DwVfpRegister::kMaxNumRegisters * kDoubleSize));
     RestoreFPRegs(r3, ip);
@@ -1065,6 +1070,9 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles,
 #endif
 
   // Tear down the exit frame, pop the arguments, and return.
+  if (FLAG_enable_ool_constant_pool) {
+    ldr(pp, MemOperand(fp, ExitFrameConstants::kConstantPoolOffset));
+  }
   mov(sp, Operand(fp));
   ldm(ia_w, sp, fp.bit() | lr.bit());
   if (argument_count.is_valid()) {
index bcf675b49d378c8c424b7fa17807bdf8d77eaa16..adc7d3afda8183cd77bd8890e12fc008c91ed0a6 100644 (file)
@@ -544,6 +544,9 @@ void ExitFrame::Iterate(ObjectVisitor* v) const {
   // the calling frame.
   IteratePc(v, pc_address(), LookupCode());
   v->VisitPointer(&code_slot());
+  if (FLAG_enable_ool_constant_pool) {
+    v->VisitPointer(&constant_pool_slot());
+  }
 }
 
 
@@ -1343,7 +1346,7 @@ void EntryFrame::Iterate(ObjectVisitor* v) const {
 
 
 void StandardFrame::IterateExpressions(ObjectVisitor* v) const {
-  const int offset = StandardFrameConstants::kContextOffset;
+  const int offset = StandardFrameConstants::kLastObjectOffset;
   Object** base = &Memory::Object_at(sp());
   Object** limit = &Memory::Object_at(fp() + offset) + 1;
   for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) {
@@ -1381,7 +1384,7 @@ void StubFailureTrampolineFrame::Iterate(ObjectVisitor* v) const {
                                       kFirstRegisterParameterFrameOffset);
   v->VisitPointers(base, limit);
   base = &Memory::Object_at(fp() + StandardFrameConstants::kMarkerOffset);
-  const int offset = StandardFrameConstants::kContextOffset;
+  const int offset = StandardFrameConstants::kLastObjectOffset;
   limit = &Memory::Object_at(fp() + offset) + 1;
   v->VisitPointers(base, limit);
   IteratePc(v, pc_address(), LookupCode());
index 5da3f8f96ad337d473b584145a511a204dbc9166..e5b6d3dd02b20548b478d1774aa26f194e6178ad 100644 (file)
@@ -143,6 +143,7 @@ class StackHandler BASE_EMBEDDED {
   inline Kind kind() const;
   inline unsigned index() const;
 
+  inline Object** constant_pool_address() const;
   inline Object** context_address() const;
   inline Object** code_address() const;
   inline void SetFp(Address slot, Address fp);
@@ -168,8 +169,8 @@ class StandardFrameConstants : public AllStatic {
  public:
   // Fixed part of the frame consists of return address, caller fp,
   // constant pool (if FLAG_enable_ool_constant_pool), context, and function.
-  // StandardFrame::IterateExpressions assumes that kContextOffset is the last
-  // object pointer.
+  // StandardFrame::IterateExpressions assumes that kLastObjectOffset is the
+  // last object pointer.
   static const int kCPSlotSize =
       FLAG_enable_ool_constant_pool ? kPointerSize : 0;
   static const int kFixedFrameSizeFromFp =  2 * kPointerSize + kCPSlotSize;
@@ -183,6 +184,9 @@ class StandardFrameConstants : public AllStatic {
   static const int kCallerFPOffset       =  0 * kPointerSize;
   static const int kCallerPCOffset       = +1 * kFPOnStackSize;
   static const int kCallerSPOffset       = kCallerPCOffset + 1 * kPCOnStackSize;
+
+  static const int kLastObjectOffset     = FLAG_enable_ool_constant_pool ?
+                                           kConstantPoolOffset : kContextOffset;
 };
 
 
@@ -423,6 +427,7 @@ class ExitFrame: public StackFrame {
   virtual Code* unchecked_code() const;
 
   Object*& code_slot() const;
+  Object*& constant_pool_slot() const;
 
   // Garbage collection support.
   virtual void Iterate(ObjectVisitor* v) const;
index 3733013ddabaddc1f92385816544f3a5b92a23f6..9859ebb0e5ba01ef2a8f21748deda75afc8a19eb 100644 (file)
@@ -54,6 +54,12 @@ Register StubFailureTrampolineFrame::constant_pool_pointer_register() {
 }
 
 
+Object*& ExitFrame::constant_pool_slot() const {
+  UNREACHABLE();
+  return Memory::Object_at(NULL);
+}
+
+
 } }  // namespace v8::internal
 
 #endif  // V8_TARGET_ARCH_IA32
index 8606125101856fcfd4624bad6c5464442025fce9..e0f3e32f7cd244ff19f43ee1f3f2692704465cbf 100644 (file)
@@ -73,6 +73,8 @@ class EntryFrameConstants : public AllStatic {
 
 class ExitFrameConstants : public AllStatic {
  public:
+  static const int kFrameSize      = 2 * kPointerSize;
+
   static const int kCodeOffset     = -2 * kPointerSize;
   static const int kSPOffset       = -1 * kPointerSize;
 
index 8612196c06079eab165c8114934726db39873fcb..20f0712666b018d97f40289cc6c52cb061488491 100644 (file)
@@ -54,6 +54,12 @@ Register StubFailureTrampolineFrame::constant_pool_pointer_register() {
 }
 
 
+Object*& ExitFrame::constant_pool_slot() const {
+  UNREACHABLE();
+  return Memory::Object_at(NULL);
+}
+
+
 } }  // namespace v8::internal
 
 #endif  // V8_TARGET_ARCH_MIPS
index 55951b58c47d9c6ba8c542e1e3e81dbe09e89e64..d9c0c798a34d2ab0491679be9c597398d302bd8e 100644 (file)
@@ -161,12 +161,9 @@ class EntryFrameConstants : public AllStatic {
 
 class ExitFrameConstants : public AllStatic {
  public:
-  // See some explanation in MacroAssembler::EnterExitFrame.
-  // This marks the top of the extra allocated stack space.
-  static const int kStackSpaceOffset = -3 * kPointerSize;
+  static const int kFrameSize = 2 * kPointerSize;
 
   static const int kCodeOffset = -2 * kPointerSize;
-
   static const int kSPOffset = -1 * kPointerSize;
 
   // The caller fields are below the frame pointer on the stack.
index b18a721e60ddad8c3885725fb5cd252ba2d7c760..d7bc6e242b598b7cc9fec0bca1f5bcbe4cb9374e 100644 (file)
@@ -482,7 +482,7 @@ void StaticMarkingVisitor<StaticVisitor>::VisitConstantPoolArray(
         constant_pool->first_ptr_index());
     int last_ptr_offset = constant_pool->OffsetOfElementAt(
         constant_pool->first_ptr_index() +
-        constant_pool->count_of_ptr_entries());
+        constant_pool->count_of_ptr_entries() - 1);
     StaticVisitor::VisitPointers(
         heap,
         HeapObject::RawField(object, first_ptr_offset),
index a55556de4466adf820ff3b2753b91f5c37b7258f..481cdc69e935a038881b8bec60d1c59124ea2434 100644 (file)
@@ -9460,7 +9460,7 @@ void ConstantPoolArray::ConstantPoolIterateBody(ObjectVisitor* v) {
   if (count_of_ptr_entries() > 0) {
     int first_ptr_offset = OffsetOfElementAt(first_ptr_index());
     int last_ptr_offset =
-        OffsetOfElementAt(first_ptr_index() + count_of_ptr_entries());
+        OffsetOfElementAt(first_ptr_index() + count_of_ptr_entries() - 1);
     v->VisitPointers(
         HeapObject::RawField(this, first_ptr_offset),
         HeapObject::RawField(this, last_ptr_offset));
index 76c2426ad404644e88313e5b7f730e07a1a10830..f98c025ddd3ec0de5ac66198180dd0765406d3cc 100644 (file)
@@ -721,7 +721,6 @@ enum InstanceType {
   EXTERNAL_DOUBLE_ARRAY_TYPE,
   EXTERNAL_PIXEL_ARRAY_TYPE,  // LAST_EXTERNAL_ARRAY_TYPE
   FIXED_DOUBLE_ARRAY_TYPE,
-  CONSTANT_POOL_ARRAY_TYPE,
   FILLER_TYPE,  // LAST_DATA_TYPE
 
   // Structs.
@@ -752,6 +751,7 @@ enum InstanceType {
   BREAK_POINT_INFO_TYPE,
 
   FIXED_ARRAY_TYPE,
+  CONSTANT_POOL_ARRAY_TYPE,
   SHARED_FUNCTION_INFO_TYPE,
 
   JS_MESSAGE_OBJECT_TYPE,
index dd9ebdcae23050cb569ee2033ccaf85599565fb4..3154d80a60125175fd2c541598acf316ef278d39 100644 (file)
@@ -54,6 +54,12 @@ Register StubFailureTrampolineFrame::constant_pool_pointer_register() {
 }
 
 
+Object*& ExitFrame::constant_pool_slot() const {
+  UNREACHABLE();
+  return Memory::Object_at(NULL);
+}
+
+
 } }  // namespace v8::internal
 
 #endif  // V8_TARGET_ARCH_X64
index fb17964adae7abb03b462ccb40bc61bfd7d98817..6eb02a9179c64f3fca37202878b2765c3041071e 100644 (file)
@@ -66,6 +66,8 @@ class EntryFrameConstants : public AllStatic {
 
 class ExitFrameConstants : public AllStatic {
  public:
+  static const int kFrameSize       = 2 * kPointerSize;
+
   static const int kCodeOffset      = -2 * kPointerSize;
   static const int kSPOffset        = -1 * kPointerSize;