Reviewers: Vyacheslav Egorov,

Description:
Fix missing write barrier in deserialization.  Issue 1783.

Please review this at http://codereview.chromium.org/8352045/

SVN Base: http://v8.googlecode.com/svn/branches/bleeding_edge/

Affected files:
  M     src/heap.h
  M     src/serialize.cc


Index: src/heap.h
===================================================================
--- src/heap.h  (revision 9722)
+++ src/heap.h  (working copy)
@@ -1419,6 +1419,9 @@
   // around a GC).
   inline void CompletelyClearInstanceofCache();

+  // The roots that have an index less than this are always in old space.
+  static const int kOldSpaceRoots = 0x20;
+
  private:
   Heap();

@@ -1475,6 +1478,10 @@

#define ROOT_ACCESSOR(type, name, camel_name) \ inline void set_##name(type* value) { \ + /* The deserializer makes use of the fact that these common roots are */ \ + /* never in new space. */ \ + ASSERT(k##camel_name##RootIndex >= kOldSpaceRoots | | \ + !HEAP->InNewSpace(value)); \ roots_[k##camel_name##RootIndex] = value; \
   }
   ROOT_LIST(ROOT_ACCESSOR)
Index: src/serialize.cc
===================================================================
--- src/serialize.cc    (revision 9722)
+++ src/serialize.cc    (working copy)
@@ -757,6 +757,7 @@
   Isolate* const isolate = isolate_;
   while (current < limit) {
     int data = source_->Get();
+    int repeats;
     switch (data) {
#define CASE_STATEMENT(where, how, within, space_number) \ case where + how + within + space_number: \
@@ -785,6 +786,9 @@
} else if (where == kRootArray) { \ int root_id = source_->GetInt(); \ new_object = isolate->heap()->roots_array_start()[root_id]; \ + if (isolate->heap()->InNewSpace(new_object)) { \ + emit_write_barrier = true; \ + } \ } else if (where == kPartialSnapshotCache) { \ int cache_index = source_->GetInt(); \ new_object = isolate->serialize_partial_snapshot_cache() \
@@ -919,30 +923,38 @@

       SIXTEEN_CASES(kRootArrayLowConstants)
       SIXTEEN_CASES(kRootArrayHighConstants) {
+        STATIC_ASSERT(kRootArrayNumberOfConstantEncodings ==
+                      Heap::kOldSpaceRoots);
         int root_id = RootArrayConstantFromByteCode(data);
         *current++ = isolate->heap()->roots_array_start()[root_id];
         break;
       }

       case kRepeat: {
-        int repeats = source_->GetInt();
-        Object* object = current[-1];
-        for (int i = 0; i < repeats; i++) current[i] = object;
+        repeats = source_->GetInt();
+        // Skip the other case statements and the setting of repeats.
+        if (false) {
+          STATIC_ASSERT(kMaxRepeats == 12);
+          FOUR_CASES(kConstantRepeat)
+          FOUR_CASES(kConstantRepeat + 4)
+          FOUR_CASES(kConstantRepeat + 8)
+          repeats = RepeatsForCode(data);
+        }
+        HeapObject* object = HeapObject::cast(current[-1]);
+        AssertNoAllocation no_gc;
+        WriteBarrierMode mode(object->GetWriteBarrierMode(no_gc));
+        for (int i = 0; i < repeats; i++) {
+          current[i] = object;
+          if (mode == UPDATE_WRITE_BARRIER) {
+            Address address = object->address();
+            isolate->heap()->RecordWrite(address, static_cast<int>(
+                reinterpret_cast<Address>(current + i) - address));
+          }
+        }
         current += repeats;
         break;
       }

-      STATIC_ASSERT(kMaxRepeats == 12);
-      FOUR_CASES(kConstantRepeat)
-      FOUR_CASES(kConstantRepeat + 4)
-      FOUR_CASES(kConstantRepeat + 8) {
-        int repeats = RepeatsForCode(data);
-        Object* object = current[-1];
-        for (int i = 0; i < repeats; i++) current[i] = object;
-        current += repeats;
-        break;
-      }
-
       // Deserialize a new object and write a pointer to it to the current
       // object.
       ONE_PER_SPACE(kNewObject, kPlain, kStartOfObject)


--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to