Revision: 19773
Author:   [email protected]
Date:     Mon Mar 10 19:05:43 2014 UTC
Log: Differentate between code target pointers and heap pointers in constant pools.

Separate out code target pointers from normal heap pointer entries in constant
pool arrays so that the GC can correctly relocate these pointers using the
appropriate mechanism.

[email protected]

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

Modified:
 /branches/bleeding_edge/src/factory.cc
 /branches/bleeding_edge/src/factory.h
 /branches/bleeding_edge/src/heap.cc
 /branches/bleeding_edge/src/heap.h
 /branches/bleeding_edge/src/mark-compact.cc
 /branches/bleeding_edge/src/mark-compact.h
 /branches/bleeding_edge/src/objects-debug.cc
 /branches/bleeding_edge/src/objects-inl.h
 /branches/bleeding_edge/src/objects-printer.cc
 /branches/bleeding_edge/src/objects-visiting-inl.h
 /branches/bleeding_edge/src/objects.cc
 /branches/bleeding_edge/src/objects.h
 /branches/bleeding_edge/test/cctest/test-constantpool.cc

=======================================
--- /branches/bleeding_edge/src/factory.cc      Fri Mar  7 10:12:17 2014 UTC
+++ /branches/bleeding_edge/src/factory.cc      Mon Mar 10 19:05:43 2014 UTC
@@ -81,14 +81,16 @@

 Handle<ConstantPoolArray> Factory::NewConstantPoolArray(
     int number_of_int64_entries,
-    int number_of_ptr_entries,
+    int number_of_code_ptr_entries,
+    int number_of_heap_ptr_entries,
     int number_of_int32_entries) {
-  ASSERT(number_of_int64_entries > 0 || number_of_ptr_entries > 0 ||
-         number_of_int32_entries > 0);
+  ASSERT(number_of_int64_entries > 0 || number_of_code_ptr_entries > 0 ||
+         number_of_heap_ptr_entries > 0 || number_of_int32_entries > 0);
   CALL_HEAP_FUNCTION(
       isolate(),
       isolate()->heap()->AllocateConstantPoolArray(number_of_int64_entries,
-                                                   number_of_ptr_entries,
+ number_of_code_ptr_entries, + number_of_heap_ptr_entries, number_of_int32_entries),
       ConstantPoolArray);
 }
=======================================
--- /branches/bleeding_edge/src/factory.h       Fri Mar  7 10:12:17 2014 UTC
+++ /branches/bleeding_edge/src/factory.h       Mon Mar 10 19:05:43 2014 UTC
@@ -61,7 +61,8 @@

   Handle<ConstantPoolArray> NewConstantPoolArray(
       int number_of_int64_entries,
-      int number_of_ptr_entries,
+      int number_of_code_ptr_entries,
+      int number_of_heap_ptr_entries,
       int number_of_int32_entries);

   Handle<SeededNumberDictionary> NewSeededNumberDictionary(
=======================================
--- /branches/bleeding_edge/src/heap.cc Fri Mar  7 10:12:17 2014 UTC
+++ /branches/bleeding_edge/src/heap.cc Mon Mar 10 19:05:43 2014 UTC
@@ -5084,20 +5084,23 @@
 MaybeObject* Heap::CopyConstantPoolArrayWithMap(ConstantPoolArray* src,
                                                 Map* map) {
   int int64_entries = src->count_of_int64_entries();
-  int ptr_entries = src->count_of_ptr_entries();
+  int code_ptr_entries = src->count_of_code_ptr_entries();
+  int heap_ptr_entries = src->count_of_heap_ptr_entries();
   int int32_entries = src->count_of_int32_entries();
   Object* obj;
   { MaybeObject* maybe_obj =
- AllocateConstantPoolArray(int64_entries, ptr_entries, int32_entries);
+        AllocateConstantPoolArray(int64_entries, code_ptr_entries,
+                                  heap_ptr_entries, int32_entries);
     if (!maybe_obj->ToObject(&obj)) return maybe_obj;
   }
   HeapObject* dst = HeapObject::cast(obj);
   dst->set_map_no_write_barrier(map);
+  int size = ConstantPoolArray::SizeFor(
+        int64_entries, code_ptr_entries, heap_ptr_entries, int32_entries);
   CopyBlock(
       dst->address() + ConstantPoolArray::kLengthOffset,
       src->address() + ConstantPoolArray::kLengthOffset,
-      ConstantPoolArray::SizeFor(int64_entries, ptr_entries, int32_entries)
-          - ConstantPoolArray::kLengthOffset);
+      size - ConstantPoolArray::kLengthOffset);
   return obj;
 }

@@ -5234,12 +5237,14 @@


 MaybeObject* Heap::AllocateConstantPoolArray(int number_of_int64_entries,
-                                             int number_of_ptr_entries,
+ int number_of_code_ptr_entries, + int number_of_heap_ptr_entries,
                                              int number_of_int32_entries) {
-  ASSERT(number_of_int64_entries > 0 || number_of_ptr_entries > 0 ||
-         number_of_int32_entries > 0);
+  ASSERT(number_of_int64_entries > 0 || number_of_code_ptr_entries > 0 ||
+         number_of_heap_ptr_entries > 0 || number_of_int32_entries > 0);
   int size = ConstantPoolArray::SizeFor(number_of_int64_entries,
-                                        number_of_ptr_entries,
+                                        number_of_code_ptr_entries,
+                                        number_of_heap_ptr_entries,
                                         number_of_int32_entries);
 #ifndef V8_HOST_ARCH_64_BIT
   size += kPointerSize;
@@ -5256,29 +5261,38 @@
   ConstantPoolArray* constant_pool =
       reinterpret_cast<ConstantPoolArray*>(object);
   constant_pool->SetEntryCounts(number_of_int64_entries,
-                                number_of_ptr_entries,
+                                number_of_code_ptr_entries,
+                                number_of_heap_ptr_entries,
                                 number_of_int32_entries);
-  if (number_of_ptr_entries > 0) {
+  if (number_of_code_ptr_entries > 0) {
+    int offset =
+ constant_pool->OffsetOfElementAt(constant_pool->first_code_ptr_index());
+    MemsetPointer(
+ reinterpret_cast<Address*>(HeapObject::RawField(constant_pool, offset)),
+        isolate()->builtins()->builtin(Builtins::kIllegal)->entry(),
+        number_of_code_ptr_entries);
+  }
+  if (number_of_heap_ptr_entries > 0) {
+    int offset =
+ constant_pool->OffsetOfElementAt(constant_pool->first_code_ptr_index());
     MemsetPointer(
-        HeapObject::RawField(
-            constant_pool,
- constant_pool->OffsetOfElementAt(constant_pool->first_ptr_index())),
+        HeapObject::RawField(constant_pool, offset),
         undefined_value(),
-        number_of_ptr_entries);
+        number_of_heap_ptr_entries);
   }
   return constant_pool;
 }


 MaybeObject* Heap::AllocateEmptyConstantPoolArray() {
-  int size = ConstantPoolArray::SizeFor(0, 0, 0);
+  int size = ConstantPoolArray::SizeFor(0, 0, 0, 0);
   Object* result;
   { MaybeObject* maybe_result =
         AllocateRaw(size, OLD_DATA_SPACE, OLD_DATA_SPACE);
     if (!maybe_result->ToObject(&result)) return maybe_result;
   }
HeapObject::cast(result)->set_map_no_write_barrier(constant_pool_array_map());
-  ConstantPoolArray::cast(result)->SetEntryCounts(0, 0, 0);
+  ConstantPoolArray::cast(result)->SetEntryCounts(0, 0, 0, 0);
   return result;
 }

=======================================
--- /branches/bleeding_edge/src/heap.h  Fri Mar  7 09:10:18 2014 UTC
+++ /branches/bleeding_edge/src/heap.h  Mon Mar 10 19:05:43 2014 UTC
@@ -1012,9 +1012,10 @@
       PretenureFlag pretenure = NOT_TENURED);

   MUST_USE_RESULT MaybeObject* AllocateConstantPoolArray(
-      int first_int64_index,
-      int first_ptr_index,
-      int first_int32_index);
+      int number_of_int64_entries,
+      int number_of_code_ptr_entries,
+      int number_of_heap_ptr_entries,
+      int number_of_int32_entries);

   // Allocates a fixed double array with uninitialized values. Returns
// Failure::RetryAfterGC(requested_bytes, space) if the allocation failed.
=======================================
--- /branches/bleeding_edge/src/mark-compact.cc Mon Mar 10 18:47:57 2014 UTC
+++ /branches/bleeding_edge/src/mark-compact.cc Mon Mar 10 19:05:43 2014 UTC
@@ -2076,8 +2076,8 @@
       }
       Object* target = allocation->ToObjectUnchecked();

-      MigrateObject(HeapObject::cast(target)->address(),
-                    object->address(),
+      MigrateObject(HeapObject::cast(target),
+                    object,
                     size,
                     NEW_SPACE);
     }
@@ -2819,19 +2819,21 @@
// pointer iteration. This is an issue if the store buffer overflows and we
 // have to scan the entire old space, including dead objects, looking for
 // pointers to new space.
-void MarkCompactCollector::MigrateObject(Address dst,
-                                         Address src,
+void MarkCompactCollector::MigrateObject(HeapObject* dst,
+                                         HeapObject* src,
                                          int size,
                                          AllocationSpace dest) {
+  Address dst_addr = dst->address();
+  Address src_addr = src->address();
   HeapProfiler* heap_profiler = heap()->isolate()->heap_profiler();
   if (heap_profiler->is_tracking_object_moves()) {
-    heap_profiler->ObjectMoveEvent(src, dst, size);
+    heap_profiler->ObjectMoveEvent(src_addr, dst_addr, size);
   }
-  ASSERT(heap()->AllowedToBeMigrated(HeapObject::FromAddress(src), dest));
+  ASSERT(heap()->AllowedToBeMigrated(src, dest));
   ASSERT(dest != LO_SPACE && size <= Page::kMaxRegularHeapObjectSize);
   if (dest == OLD_POINTER_SPACE) {
-    Address src_slot = src;
-    Address dst_slot = dst;
+    Address src_slot = src_addr;
+    Address dst_slot = dst_addr;
     ASSERT(IsAligned(size, kPointerSize));

     for (int remaining = size / kPointerSize; remaining > 0; remaining--) {
@@ -2852,8 +2854,8 @@
       dst_slot += kPointerSize;
     }

-    if (compacting_ && HeapObject::FromAddress(dst)->IsJSFunction()) {
-      Address code_entry_slot = dst + JSFunction::kCodeEntryOffset;
+    if (compacting_ && dst->IsJSFunction()) {
+      Address code_entry_slot = dst_addr + JSFunction::kCodeEntryOffset;
       Address code_entry = Memory::Address_at(code_entry_slot);

       if (Page::FromAddress(code_entry)->IsEvacuationCandidate()) {
@@ -2863,21 +2865,36 @@
                            code_entry_slot,
                            SlotsBuffer::IGNORE_OVERFLOW);
       }
+    } else if (compacting_ && dst->IsConstantPoolArray()) {
+      ConstantPoolArray* constant_pool = ConstantPoolArray::cast(dst);
+ for (int i = 0; i < constant_pool->count_of_code_ptr_entries(); i++) {
+        Address code_entry_slot =
+            dst_addr + constant_pool->OffsetOfElementAt(i);
+        Address code_entry = Memory::Address_at(code_entry_slot);
+
+        if (Page::FromAddress(code_entry)->IsEvacuationCandidate()) {
+          SlotsBuffer::AddTo(&slots_buffer_allocator_,
+                             &migration_slots_buffer_,
+                             SlotsBuffer::CODE_ENTRY_SLOT,
+                             code_entry_slot,
+                             SlotsBuffer::IGNORE_OVERFLOW);
+        }
+      }
     }
   } else if (dest == CODE_SPACE) {
-    PROFILE(isolate(), CodeMoveEvent(src, dst));
-    heap()->MoveBlock(dst, src, size);
+    PROFILE(isolate(), CodeMoveEvent(src_addr, dst_addr));
+    heap()->MoveBlock(dst_addr, src_addr, size);
     SlotsBuffer::AddTo(&slots_buffer_allocator_,
                        &migration_slots_buffer_,
                        SlotsBuffer::RELOCATED_CODE_OBJECT,
-                       dst,
+                       dst_addr,
                        SlotsBuffer::IGNORE_OVERFLOW);
-    Code::cast(HeapObject::FromAddress(dst))->Relocate(dst - src);
+    Code::cast(dst)->Relocate(dst_addr - src_addr);
   } else {
     ASSERT(dest == OLD_DATA_SPACE || dest == NEW_SPACE);
-    heap()->MoveBlock(dst, src, size);
+    heap()->MoveBlock(dst_addr, src_addr, size);
   }
-  Memory::Address_at(src) = dst;
+  Memory::Address_at(src_addr) = dst_addr;
 }


@@ -3012,8 +3029,8 @@
   MaybeObject* maybe_result = target_space->AllocateRaw(object_size);
   if (maybe_result->ToObject(&result)) {
     HeapObject* target = HeapObject::cast(result);
-    MigrateObject(target->address(),
-                  object->address(),
+    MigrateObject(target,
+                  object,
                   object_size,
                   target_space->identity());
     heap()->mark_compact_collector()->tracer()->
@@ -3091,8 +3108,8 @@

       Object* target_object = target->ToObjectUnchecked();

-      MigrateObject(HeapObject::cast(target_object)->address(),
-                    object_addr,
+      MigrateObject(HeapObject::cast(target_object),
+                    object,
                     size,
                     space->identity());
       ASSERT(object->map_word().IsForwardingAddress());
=======================================
--- /branches/bleeding_edge/src/mark-compact.h  Wed Mar  5 14:04:21 2014 UTC
+++ /branches/bleeding_edge/src/mark-compact.h  Mon Mar 10 19:05:43 2014 UTC
@@ -696,8 +696,8 @@
                          SlotsBuffer::AdditionMode mode =
                              SlotsBuffer::FAIL_ON_OVERFLOW));

-  void MigrateObject(Address dst,
-                     Address src,
+  void MigrateObject(HeapObject* dst,
+                     HeapObject* src,
                      int size,
                      AllocationSpace to_old_space);

=======================================
--- /branches/bleeding_edge/src/objects-debug.cc Fri Mar 7 10:12:17 2014 UTC +++ /branches/bleeding_edge/src/objects-debug.cc Mon Mar 10 19:05:43 2014 UTC
@@ -403,6 +403,13 @@

 void ConstantPoolArray::ConstantPoolArrayVerify() {
   CHECK(IsConstantPoolArray());
+  for (int i = 0; i < count_of_code_ptr_entries(); i++) {
+    Address code_entry = get_code_ptr_entry(first_code_ptr_index() + i);
+    VerifyPointer(Code::GetCodeFromTargetAddress(code_entry));
+  }
+  for (int i = 0; i < count_of_heap_ptr_entries(); i++) {
+    VerifyObjectField(OffsetOfElementAt(first_heap_ptr_index() + i));
+  }
 }


=======================================
--- /branches/bleeding_edge/src/objects-inl.h   Mon Mar 10 14:50:01 2014 UTC
+++ /branches/bleeding_edge/src/objects-inl.h   Mon Mar 10 19:05:43 2014 UTC
@@ -2198,8 +2198,12 @@
 }


-SMI_ACCESSORS(ConstantPoolArray, first_ptr_index, kFirstPointerIndexOffset)
-SMI_ACCESSORS(ConstantPoolArray, first_int32_index, kFirstInt32IndexOffset)
+SMI_ACCESSORS(
+    ConstantPoolArray, first_code_ptr_index, kFirstCodePointerIndexOffset)
+SMI_ACCESSORS(
+    ConstantPoolArray, first_heap_ptr_index, kFirstHeapPointerIndexOffset)
+SMI_ACCESSORS(
+    ConstantPoolArray, first_int32_index, kFirstInt32IndexOffset)


 int ConstantPoolArray::first_int64_index() {
@@ -2208,12 +2212,17 @@


 int ConstantPoolArray::count_of_int64_entries() {
-  return first_ptr_index();
+  return first_code_ptr_index();
 }


-int ConstantPoolArray::count_of_ptr_entries() {
-  return first_int32_index() - first_ptr_index();
+int ConstantPoolArray::count_of_code_ptr_entries() {
+  return first_heap_ptr_index() - first_code_ptr_index();
+}
+
+
+int ConstantPoolArray::count_of_heap_ptr_entries() {
+  return first_int32_index() - first_heap_ptr_index();
 }


@@ -2223,32 +2232,44 @@


 void ConstantPoolArray::SetEntryCounts(int number_of_int64_entries,
-                                       int number_of_ptr_entries,
+                                       int number_of_code_ptr_entries,
+                                       int number_of_heap_ptr_entries,
                                        int number_of_int32_entries) {
-  set_first_ptr_index(number_of_int64_entries);
-  set_first_int32_index(number_of_int64_entries + number_of_ptr_entries);
-  set_length(number_of_int64_entries + number_of_ptr_entries +
-             number_of_int32_entries);
+  int current_index = number_of_int64_entries;
+  set_first_code_ptr_index(current_index);
+  current_index += number_of_code_ptr_entries;
+  set_first_heap_ptr_index(current_index);
+  current_index += number_of_heap_ptr_entries;
+  set_first_int32_index(current_index);
+  current_index += number_of_int32_entries;
+  set_length(current_index);
 }


 int64_t ConstantPoolArray::get_int64_entry(int index) {
   ASSERT(map() == GetHeap()->constant_pool_array_map());
-  ASSERT(index >= 0 && index < first_ptr_index());
+  ASSERT(index >= 0 && index < first_code_ptr_index());
   return READ_INT64_FIELD(this, OffsetOfElementAt(index));
 }

 double ConstantPoolArray::get_int64_entry_as_double(int index) {
   STATIC_ASSERT(kDoubleSize == kInt64Size);
   ASSERT(map() == GetHeap()->constant_pool_array_map());
-  ASSERT(index >= 0 && index < first_ptr_index());
+  ASSERT(index >= 0 && index < first_code_ptr_index());
   return READ_DOUBLE_FIELD(this, OffsetOfElementAt(index));
 }


-Object* ConstantPoolArray::get_ptr_entry(int index) {
+Address ConstantPoolArray::get_code_ptr_entry(int index) {
   ASSERT(map() == GetHeap()->constant_pool_array_map());
-  ASSERT(index >= first_ptr_index() && index < first_int32_index());
+ ASSERT(index >= first_code_ptr_index() && index < first_heap_ptr_index()); + return reinterpret_cast<Address>(READ_FIELD(this, OffsetOfElementAt(index)));
+}
+
+
+Object* ConstantPoolArray::get_heap_ptr_entry(int index) {
+  ASSERT(map() == GetHeap()->constant_pool_array_map());
+  ASSERT(index >= first_heap_ptr_index() && index < first_int32_index());
   return READ_FIELD(this, OffsetOfElementAt(index));
 }

@@ -2258,11 +2279,18 @@
   ASSERT(index >= first_int32_index() && index < length());
   return READ_INT32_FIELD(this, OffsetOfElementAt(index));
 }
+
+
+void ConstantPoolArray::set(int index, Address value) {
+  ASSERT(map() == GetHeap()->constant_pool_array_map());
+ ASSERT(index >= first_code_ptr_index() && index < first_heap_ptr_index()); + WRITE_FIELD(this, OffsetOfElementAt(index), reinterpret_cast<Object*>(value));
+}


 void ConstantPoolArray::set(int index, Object* value) {
   ASSERT(map() == GetHeap()->constant_pool_array_map());
-  ASSERT(index >= first_ptr_index() && index < first_int32_index());
+  ASSERT(index >= first_code_ptr_index() && index < first_int32_index());
   WRITE_FIELD(this, OffsetOfElementAt(index), value);
   WRITE_BARRIER(GetHeap(), this, OffsetOfElementAt(index), value);
 }
@@ -2270,7 +2298,7 @@

 void ConstantPoolArray::set(int index, int64_t value) {
   ASSERT(map() == GetHeap()->constant_pool_array_map());
-  ASSERT(index >= first_int64_index() && index < first_ptr_index());
+  ASSERT(index >= first_int64_index() && index < first_code_ptr_index());
   WRITE_INT64_FIELD(this, OffsetOfElementAt(index), value);
 }

@@ -2278,7 +2306,7 @@
 void ConstantPoolArray::set(int index, double value) {
   STATIC_ASSERT(kDoubleSize == kInt64Size);
   ASSERT(map() == GetHeap()->constant_pool_array_map());
-  ASSERT(index >= first_int64_index() && index < first_ptr_index());
+  ASSERT(index >= first_int64_index() && index < first_code_ptr_index());
   WRITE_DOUBLE_FIELD(this, OffsetOfElementAt(index), value);
 }

@@ -3846,7 +3874,8 @@
   if (instance_type == CONSTANT_POOL_ARRAY_TYPE) {
     return ConstantPoolArray::SizeFor(
reinterpret_cast<ConstantPoolArray*>(this)->count_of_int64_entries(),
-        reinterpret_cast<ConstantPoolArray*>(this)->count_of_ptr_entries(),
+ reinterpret_cast<ConstantPoolArray*>(this)->count_of_code_ptr_entries(), + reinterpret_cast<ConstantPoolArray*>(this)->count_of_heap_ptr_entries(), reinterpret_cast<ConstantPoolArray*>(this)->count_of_int32_entries());
   }
   if (instance_type >= FIRST_FIXED_TYPED_ARRAY_TYPE &&
=======================================
--- /branches/bleeding_edge/src/objects-printer.cc Fri Mar 7 10:12:17 2014 UTC +++ /branches/bleeding_edge/src/objects-printer.cc Mon Mar 10 19:05:43 2014 UTC
@@ -604,11 +604,14 @@
   HeapObject::PrintHeader(out, "ConstantPoolArray");
   PrintF(out, " - length: %d", length());
   for (int i = 0; i < length(); i++) {
-    if (i < first_ptr_index()) {
+    if (i < first_code_ptr_index()) {
       PrintF(out, "\n  [%d]: double: %g", i, get_int64_entry_as_double(i));
+    } else if (i < first_heap_ptr_index()) {
+      PrintF(out, "\n  [%d]: code target pointer: %p", i,
+             reinterpret_cast<void*>(get_code_ptr_entry(i)));
     } else if (i < first_int32_index()) {
-      PrintF(out, "\n  [%d]: pointer: %p", i,
-             reinterpret_cast<void*>(get_ptr_entry(i)));
+      PrintF(out, "\n  [%d]: heap pointer: %p", i,
+             reinterpret_cast<void*>(get_heap_ptr_entry(i)));
     } else {
       PrintF(out, "\n  [%d]: int32: %d", i, get_int32_entry(i));
     }
=======================================
--- /branches/bleeding_edge/src/objects-visiting-inl.h Fri Mar 7 10:12:17 2014 UTC +++ /branches/bleeding_edge/src/objects-visiting-inl.h Mon Mar 10 19:05:43 2014 UTC
@@ -489,16 +489,16 @@
     Map* map, HeapObject* object) {
   Heap* heap = map->GetHeap();
   ConstantPoolArray* constant_pool = ConstantPoolArray::cast(object);
-  if (constant_pool->count_of_ptr_entries() > 0) {
-    int first_ptr_offset = constant_pool->OffsetOfElementAt(
-        constant_pool->first_ptr_index());
-    int last_ptr_offset = constant_pool->OffsetOfElementAt(
-        constant_pool->first_ptr_index() +
-        constant_pool->count_of_ptr_entries() - 1);
-    StaticVisitor::VisitPointers(
-        heap,
-        HeapObject::RawField(object, first_ptr_offset),
-        HeapObject::RawField(object, last_ptr_offset));
+  for (int i = 0; i < constant_pool->count_of_code_ptr_entries(); i++) {
+    int index = constant_pool->first_code_ptr_index() + i;
+    Address code_entry =
+ reinterpret_cast<Address>(constant_pool->RawFieldOfElementAt(index));
+    StaticVisitor::VisitCodeEntry(heap, code_entry);
+  }
+  for (int i = 0; i < constant_pool->count_of_heap_ptr_entries(); i++) {
+    int index = constant_pool->first_heap_ptr_index() + i;
+    StaticVisitor::VisitPointer(heap,
+                                constant_pool->RawFieldOfElementAt(index));
   }
 }

=======================================
--- /branches/bleeding_edge/src/objects.cc      Mon Mar 10 16:05:29 2014 UTC
+++ /branches/bleeding_edge/src/objects.cc      Mon Mar 10 19:05:43 2014 UTC
@@ -9452,13 +9452,13 @@


 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() - 1);
-    v->VisitPointers(
-        HeapObject::RawField(this, first_ptr_offset),
-        HeapObject::RawField(this, last_ptr_offset));
+  for (int i = 0; i < count_of_code_ptr_entries(); i++) {
+    int index = first_code_ptr_index() + i;
+ v->VisitCodeEntry(reinterpret_cast<Address>(RawFieldOfElementAt(index)));
+  }
+  for (int i = 0; i < count_of_heap_ptr_entries(); i++) {
+    int index = first_heap_ptr_index() + i;
+    v->VisitPointer(RawFieldOfElementAt(index));
   }
 }

=======================================
--- /branches/bleeding_edge/src/objects.h       Mon Mar 10 12:23:05 2014 UTC
+++ /branches/bleeding_edge/src/objects.h       Mon Mar 10 19:05:43 2014 UTC
@@ -3158,29 +3158,35 @@
 // ConstantPoolArray describes a fixed-sized array containing constant pool
 // entires.
 // The format of the pool is:
-//   [0]: Field holding the first index which is a pointer entry
-//   [1]: Field holding the first index which is a int32 entry
-//   [2] ... [first_ptr_index() - 1]: 64 bit entries
-//   [first_ptr_index()] ... [first_int32_index() - 1]: pointer entries
-//   [first_int32_index()] ... [length - 1]: 32 bit entries
+// [0]: Field holding the first index which is a raw code target pointer entry
+//   [1]: Field holding the first index which is a heap pointer entry
+//   [2]: Field holding the first index which is a int32 entry
+// [3] ... [first_code_ptr_index() - 1] : 64 bit entries +// [first_code_ptr_index()] ... [first_heap_ptr_index() - 1] : code pointers +// [first_heap_ptr_index()] ... [first_int32_index() - 1] : heap pointers +// [first_int32_index()] ... [length - 1] : 32 bit entries
 class ConstantPoolArray: public FixedArrayBase {
  public:
// Getters for the field storing the first index for different type entries.
-  inline int first_ptr_index();
+  inline int first_code_ptr_index();
+  inline int first_heap_ptr_index();
   inline int first_int64_index();
   inline int first_int32_index();

   // Getters for counts of different type entries.
-  inline int count_of_ptr_entries();
+  inline int count_of_code_ptr_entries();
+  inline int count_of_heap_ptr_entries();
   inline int count_of_int64_entries();
   inline int count_of_int32_entries();

   // Setter and getter for pool elements.
-  inline Object* get_ptr_entry(int index);
+  inline Address get_code_ptr_entry(int index);
+  inline Object* get_heap_ptr_entry(int index);
   inline int64_t get_int64_entry(int index);
   inline int32_t get_int32_entry(int index);
   inline double get_int64_entry_as_double(int index);

+  inline void set(int index, Address value);
   inline void set(int index, Object* value);
   inline void set(int index, int64_t value);
   inline void set(int index, double value);
@@ -3188,7 +3194,8 @@

   // Set up initial state.
   inline void SetEntryCounts(int number_of_int64_entries,
-                             int number_of_ptr_entries,
+                             int number_of_code_ptr_entries,
+                             int number_of_heap_ptr_entries,
                              int number_of_int32_entries);

   // Copy operations
@@ -3196,10 +3203,12 @@

   // Garbage collection support.
   inline static int SizeFor(int number_of_int64_entries,
-                            int number_of_ptr_entries,
+                            int number_of_code_ptr_entries,
+                            int number_of_heap_ptr_entries,
                             int number_of_int32_entries) {
     return RoundUp(OffsetAt(number_of_int64_entries,
-                            number_of_ptr_entries,
+                            number_of_code_ptr_entries,
+                            number_of_heap_ptr_entries,
                             number_of_int32_entries),
                    kPointerSize);
   }
@@ -3208,22 +3217,33 @@
   inline int OffsetOfElementAt(int index) {
     ASSERT(index < length());
     if (index >= first_int32_index()) {
-      return OffsetAt(count_of_int64_entries(), count_of_ptr_entries(),
-                      index - first_int32_index());
-    } else if (index >= first_ptr_index()) {
- return OffsetAt(count_of_int64_entries(), index - first_ptr_index(), 0); + return OffsetAt(count_of_int64_entries(), count_of_code_ptr_entries(), + count_of_heap_ptr_entries(), index - first_int32_index());
+    } else if (index >= first_heap_ptr_index()) {
+ return OffsetAt(count_of_int64_entries(), count_of_code_ptr_entries(),
+                      index - first_heap_ptr_index(), 0);
+    } else if (index >= first_code_ptr_index()) {
+ return OffsetAt(count_of_int64_entries(), index - first_code_ptr_index(),
+                      0, 0);
     } else {
-      return OffsetAt(index, 0, 0);
+      return OffsetAt(index, 0, 0, 0);
     }
   }

   // Casting.
   static inline ConstantPoolArray* cast(Object* obj);
+
+  // Garbage collection support.
+  Object** RawFieldOfElementAt(int index) {
+    return HeapObject::RawField(this, OffsetOfElementAt(index));
+  }

   // Layout description.
-  static const int kFirstPointerIndexOffset = FixedArray::kHeaderSize;
+  static const int kFirstCodePointerIndexOffset = FixedArray::kHeaderSize;
+  static const int kFirstHeapPointerIndexOffset =
+      kFirstCodePointerIndexOffset + kPointerSize;
   static const int kFirstInt32IndexOffset =
-      kFirstPointerIndexOffset + kPointerSize;
+      kFirstHeapPointerIndexOffset + kPointerSize;
   static const int kFirstOffset = kFirstInt32IndexOffset + kPointerSize;

   // Dispatched behavior.
@@ -3233,15 +3253,18 @@
   DECLARE_VERIFIER(ConstantPoolArray)

  private:
-  inline void set_first_ptr_index(int value);
+  inline void set_first_code_ptr_index(int value);
+  inline void set_first_heap_ptr_index(int value);
   inline void set_first_int32_index(int value);

   inline static int OffsetAt(int number_of_int64_entries,
-                             int number_of_ptr_entries,
+                             int number_of_code_ptr_entries,
+                             int number_of_heap_ptr_entries,
                              int number_of_int32_entries) {
     return kFirstOffset
         + (number_of_int64_entries * kInt64Size)
-        + (number_of_ptr_entries * kPointerSize)
+        + (number_of_code_ptr_entries * kPointerSize)
+        + (number_of_heap_ptr_entries * kPointerSize)
         + (number_of_int32_entries * kInt32Size);
   }

=======================================
--- /branches/bleeding_edge/test/cctest/test-constantpool.cc Mon Oct 14 13:35:06 2013 UTC +++ /branches/bleeding_edge/test/cctest/test-constantpool.cc Mon Mar 10 19:05:43 2014 UTC
@@ -11,6 +11,15 @@
 using namespace v8::internal;


+Code* DummyCode(LocalContext* context) {
+  CompileRun("function foo() {};");
+  i::Handle<i::JSFunction> fun = v8::Utils::OpenHandle(
+      *v8::Local<v8::Function>::Cast(
+          (*context)->Global()->Get(v8_str("foo"))));
+  return fun->code();
+}
+
+
 TEST(ConstantPool) {
   LocalContext context;
   Isolate* isolate = CcTest::i_isolate();
@@ -19,32 +28,41 @@
   v8::HandleScope scope(context->GetIsolate());

   // Check construction.
-  Handle<ConstantPoolArray> array = factory->NewConstantPoolArray(3, 2, 1);
+ Handle<ConstantPoolArray> array = factory->NewConstantPoolArray(3, 1, 2, 1);
   CHECK_EQ(array->count_of_int64_entries(), 3);
-  CHECK_EQ(array->count_of_ptr_entries(), 2);
+  CHECK_EQ(array->count_of_code_ptr_entries(), 1);
+  CHECK_EQ(array->count_of_heap_ptr_entries(), 2);
   CHECK_EQ(array->count_of_int32_entries(), 1);
-  CHECK_EQ(array->length(), 6);
+  CHECK_EQ(array->length(), 7);
   CHECK_EQ(array->first_int64_index(), 0);
-  CHECK_EQ(array->first_ptr_index(), 3);
-  CHECK_EQ(array->first_int32_index(), 5);
+  CHECK_EQ(array->first_code_ptr_index(), 3);
+  CHECK_EQ(array->first_heap_ptr_index(), 4);
+  CHECK_EQ(array->first_int32_index(), 6);

   // Check getters and setters.
   int64_t big_number = V8_2PART_UINT64_C(0x12345678, 9ABCDEF0);
   Handle<Object> object = factory->NewHeapNumber(4.0);
+  Code* code = DummyCode(&context);
   array->set(0, big_number);
   array->set(1, 0.5);
-  array->set(3, *object);
-  array->set(5, 50);
+  array->set(2, 3e-24);
+  array->set(3, code->entry());
+  array->set(4, code);
+  array->set(5, *object);
+  array->set(6, 50);
   CHECK_EQ(array->get_int64_entry(0), big_number);
   CHECK_EQ(array->get_int64_entry_as_double(1), 0.5);
-  CHECK_EQ(array->get_ptr_entry(3), *object);
-  CHECK_EQ(array->get_int32_entry(5), 50);
+  CHECK_EQ(array->get_int64_entry_as_double(2), 3e-24);
+  CHECK_EQ(array->get_code_ptr_entry(3), code->entry());
+  CHECK_EQ(array->get_heap_ptr_entry(4), code);
+  CHECK_EQ(array->get_heap_ptr_entry(5), *object);
+  CHECK_EQ(array->get_int32_entry(6), 50);

   // Check pointers are updated on GC.
-  Object* old_ptr = array->get_ptr_entry(3);
+  Object* old_ptr = array->get_heap_ptr_entry(5);
   CHECK_EQ(*object, old_ptr);
   heap->CollectGarbage(NEW_SPACE);
-  Object* new_ptr = array->get_ptr_entry(3);
+  Object* new_ptr = array->get_heap_ptr_entry(5);
   CHECK_NE(*object, old_ptr);
   CHECK_EQ(*object, new_ptr);
 }

--
--
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