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