Fix missing write barrier in deserialization. Issue 1783.

Review URL: http://codereview.chromium.org/8352045

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9744 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
erik.corry@gmail.com 2011-10-21 15:20:53 +00:00
parent f464ad61fb
commit 9065e95d45
2 changed files with 38 additions and 6 deletions

View File

@ -68,6 +68,7 @@ inline Heap* _inline_get_heap_();
V(Map, shared_function_info_map, SharedFunctionInfoMap) \
V(Map, meta_map, MetaMap) \
V(Map, ascii_symbol_map, AsciiSymbolMap) \
V(Map, ascii_string_map, AsciiStringMap) \
V(Map, heap_number_map, HeapNumberMap) \
V(Map, global_context_map, GlobalContextMap) \
V(Map, fixed_array_map, FixedArrayMap) \
@ -85,6 +86,9 @@ inline Heap* _inline_get_heap_();
V(Smi, stack_limit, StackLimit) \
V(Oddball, frame_alignment_marker, FrameAlignmentMarker) \
V(Oddball, arguments_marker, ArgumentsMarker) \
/* The first 32 roots above this line should be boring from a GC point of */ \
/* view. This means they are never in new space and never on a page that */ \
/* is being compacted. */ \
V(FixedArray, number_string_cache, NumberStringCache) \
V(Object, instanceof_cache_function, InstanceofCacheFunction) \
V(Object, instanceof_cache_map, InstanceofCacheMap) \
@ -93,7 +97,6 @@ inline Heap* _inline_get_heap_();
V(FixedArray, string_split_cache, StringSplitCache) \
V(Object, termination_exception, TerminationException) \
V(Map, string_map, StringMap) \
V(Map, ascii_string_map, AsciiStringMap) \
V(Map, symbol_map, SymbolMap) \
V(Map, cons_string_map, ConsStringMap) \
V(Map, cons_ascii_string_map, ConsAsciiStringMap) \
@ -1419,6 +1422,9 @@ class Heap {
// 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 +1481,9 @@ class Heap {
#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 and never on a page that is being compacted. */ \
ASSERT(k##camel_name##RootIndex >= kOldSpaceRoots || !InNewSpace(value)); \
roots_[k##camel_name##RootIndex] = value; \
}
ROOT_LIST(ROOT_ACCESSOR)

View File

@ -787,9 +787,19 @@ void Deserializer::ReadChunk(Object** current,
ASSIGN_DEST_SPACE(space_number) \
ReadObject(space_number, dest_space, &new_object); \
} else if (where == kRootArray) { \
if (source_space != CELL_SPACE && \
source_space != CODE_SPACE && \
source_space != OLD_DATA_SPACE) { \
emit_write_barrier = true; \
} \
int root_id = source_->GetInt(); \
new_object = isolate->heap()->roots_array_start()[root_id]; \
} else if (where == kPartialSnapshotCache) { \
if (source_space != CELL_SPACE && \
source_space != CODE_SPACE && \
source_space != OLD_DATA_SPACE) { \
emit_write_barrier = true; \
} \
int cache_index = source_->GetInt(); \
new_object = isolate->serialize_partial_snapshot_cache() \
[cache_index]; \
@ -924,24 +934,30 @@ void Deserializer::ReadChunk(Object** current,
SIXTEEN_CASES(kRootArrayLowConstants)
SIXTEEN_CASES(kRootArrayHighConstants) {
int root_id = RootArrayConstantFromByteCode(data);
*current++ = isolate->heap()->roots_array_start()[root_id];
Object* object = isolate->heap()->roots_array_start()[root_id];
ASSERT(!isolate->heap()->InNewSpace(object));
*current++ = object;
break;
}
case kRepeat: {
int repeats = source_->GetInt();
Object* object = current[-1];
ASSERT(!isolate->heap()->InNewSpace(object));
for (int i = 0; i < repeats; i++) current[i] = object;
current += repeats;
break;
}
STATIC_ASSERT(kRootArrayNumberOfConstantEncodings ==
Heap::kOldSpaceRoots);
STATIC_ASSERT(kMaxRepeats == 12);
FOUR_CASES(kConstantRepeat)
FOUR_CASES(kConstantRepeat + 4)
FOUR_CASES(kConstantRepeat + 8) {
int repeats = RepeatsForCode(data);
Object* object = current[-1];
ASSERT(!isolate->heap()->InNewSpace(object));
for (int i = 0; i < repeats; i++) current[i] = object;
current += repeats;
break;
@ -1430,11 +1446,18 @@ void Serializer::ObjectSerializer::VisitPointers(Object** start,
if (current < end) OutputRawData(reinterpret_cast<Address>(current));
while (current < end && !(*current)->IsSmi()) {
HeapObject* current_contents = HeapObject::cast(*current);
int root_index = serializer_->RootIndex(current_contents);
// Repeats are not subject to the write barrier so there are only some
// objects that can be used in a repeat encoding. These are the early
// ones in the root array that are never in new space.
if (current != start &&
current[0] == current[-1] &&
!HEAP->InNewSpace(*current)) {
root_index != kInvalidRootIndex &&
root_index < kRootArrayNumberOfConstantEncodings &&
current_contents == current[-1]) {
ASSERT(!HEAP->InNewSpace(current_contents));
int repeat_count = 1;
while (current < end - 1 && current[repeat_count] == current[0]) {
while (current < end - 1 && current[repeat_count] == current_contents) {
repeat_count++;
}
current += repeat_count;
@ -1446,7 +1469,7 @@ void Serializer::ObjectSerializer::VisitPointers(Object** start,
sink_->Put(CodeForRepeats(repeat_count), "SerializeRepeats");
}
} else {
serializer_->SerializeObject(*current, kPlain, kStartOfObject);
serializer_->SerializeObject(current_contents, kPlain, kStartOfObject);
bytes_processed_so_far_ += kPointerSize;
current++;
}