Commit 9065e95d authored by erik.corry@gmail.com's avatar erik.corry@gmail.com

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
parent f464ad61
...@@ -68,6 +68,7 @@ inline Heap* _inline_get_heap_(); ...@@ -68,6 +68,7 @@ inline Heap* _inline_get_heap_();
V(Map, shared_function_info_map, SharedFunctionInfoMap) \ V(Map, shared_function_info_map, SharedFunctionInfoMap) \
V(Map, meta_map, MetaMap) \ V(Map, meta_map, MetaMap) \
V(Map, ascii_symbol_map, AsciiSymbolMap) \ V(Map, ascii_symbol_map, AsciiSymbolMap) \
V(Map, ascii_string_map, AsciiStringMap) \
V(Map, heap_number_map, HeapNumberMap) \ V(Map, heap_number_map, HeapNumberMap) \
V(Map, global_context_map, GlobalContextMap) \ V(Map, global_context_map, GlobalContextMap) \
V(Map, fixed_array_map, FixedArrayMap) \ V(Map, fixed_array_map, FixedArrayMap) \
...@@ -85,6 +86,9 @@ inline Heap* _inline_get_heap_(); ...@@ -85,6 +86,9 @@ inline Heap* _inline_get_heap_();
V(Smi, stack_limit, StackLimit) \ V(Smi, stack_limit, StackLimit) \
V(Oddball, frame_alignment_marker, FrameAlignmentMarker) \ V(Oddball, frame_alignment_marker, FrameAlignmentMarker) \
V(Oddball, arguments_marker, ArgumentsMarker) \ 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(FixedArray, number_string_cache, NumberStringCache) \
V(Object, instanceof_cache_function, InstanceofCacheFunction) \ V(Object, instanceof_cache_function, InstanceofCacheFunction) \
V(Object, instanceof_cache_map, InstanceofCacheMap) \ V(Object, instanceof_cache_map, InstanceofCacheMap) \
...@@ -93,7 +97,6 @@ inline Heap* _inline_get_heap_(); ...@@ -93,7 +97,6 @@ inline Heap* _inline_get_heap_();
V(FixedArray, string_split_cache, StringSplitCache) \ V(FixedArray, string_split_cache, StringSplitCache) \
V(Object, termination_exception, TerminationException) \ V(Object, termination_exception, TerminationException) \
V(Map, string_map, StringMap) \ V(Map, string_map, StringMap) \
V(Map, ascii_string_map, AsciiStringMap) \
V(Map, symbol_map, SymbolMap) \ V(Map, symbol_map, SymbolMap) \
V(Map, cons_string_map, ConsStringMap) \ V(Map, cons_string_map, ConsStringMap) \
V(Map, cons_ascii_string_map, ConsAsciiStringMap) \ V(Map, cons_ascii_string_map, ConsAsciiStringMap) \
...@@ -1419,6 +1422,9 @@ class Heap { ...@@ -1419,6 +1422,9 @@ class Heap {
// around a GC). // around a GC).
inline void CompletelyClearInstanceofCache(); inline void CompletelyClearInstanceofCache();
// The roots that have an index less than this are always in old space.
static const int kOldSpaceRoots = 0x20;
private: private:
Heap(); Heap();
...@@ -1475,6 +1481,9 @@ class Heap { ...@@ -1475,6 +1481,9 @@ class Heap {
#define ROOT_ACCESSOR(type, name, camel_name) \ #define ROOT_ACCESSOR(type, name, camel_name) \
inline void set_##name(type* value) { \ 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; \ roots_[k##camel_name##RootIndex] = value; \
} }
ROOT_LIST(ROOT_ACCESSOR) ROOT_LIST(ROOT_ACCESSOR)
......
...@@ -787,9 +787,19 @@ void Deserializer::ReadChunk(Object** current, ...@@ -787,9 +787,19 @@ void Deserializer::ReadChunk(Object** current,
ASSIGN_DEST_SPACE(space_number) \ ASSIGN_DEST_SPACE(space_number) \
ReadObject(space_number, dest_space, &new_object); \ ReadObject(space_number, dest_space, &new_object); \
} else if (where == kRootArray) { \ } 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(); \ int root_id = source_->GetInt(); \
new_object = isolate->heap()->roots_array_start()[root_id]; \ new_object = isolate->heap()->roots_array_start()[root_id]; \
} else if (where == kPartialSnapshotCache) { \ } 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(); \ int cache_index = source_->GetInt(); \
new_object = isolate->serialize_partial_snapshot_cache() \ new_object = isolate->serialize_partial_snapshot_cache() \
[cache_index]; \ [cache_index]; \
...@@ -924,24 +934,30 @@ void Deserializer::ReadChunk(Object** current, ...@@ -924,24 +934,30 @@ void Deserializer::ReadChunk(Object** current,
SIXTEEN_CASES(kRootArrayLowConstants) SIXTEEN_CASES(kRootArrayLowConstants)
SIXTEEN_CASES(kRootArrayHighConstants) { SIXTEEN_CASES(kRootArrayHighConstants) {
int root_id = RootArrayConstantFromByteCode(data); 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; break;
} }
case kRepeat: { case kRepeat: {
int repeats = source_->GetInt(); int repeats = source_->GetInt();
Object* object = current[-1]; Object* object = current[-1];
ASSERT(!isolate->heap()->InNewSpace(object));
for (int i = 0; i < repeats; i++) current[i] = object; for (int i = 0; i < repeats; i++) current[i] = object;
current += repeats; current += repeats;
break; break;
} }
STATIC_ASSERT(kRootArrayNumberOfConstantEncodings ==
Heap::kOldSpaceRoots);
STATIC_ASSERT(kMaxRepeats == 12); STATIC_ASSERT(kMaxRepeats == 12);
FOUR_CASES(kConstantRepeat) FOUR_CASES(kConstantRepeat)
FOUR_CASES(kConstantRepeat + 4) FOUR_CASES(kConstantRepeat + 4)
FOUR_CASES(kConstantRepeat + 8) { FOUR_CASES(kConstantRepeat + 8) {
int repeats = RepeatsForCode(data); int repeats = RepeatsForCode(data);
Object* object = current[-1]; Object* object = current[-1];
ASSERT(!isolate->heap()->InNewSpace(object));
for (int i = 0; i < repeats; i++) current[i] = object; for (int i = 0; i < repeats; i++) current[i] = object;
current += repeats; current += repeats;
break; break;
...@@ -1430,11 +1446,18 @@ void Serializer::ObjectSerializer::VisitPointers(Object** start, ...@@ -1430,11 +1446,18 @@ void Serializer::ObjectSerializer::VisitPointers(Object** start,
if (current < end) OutputRawData(reinterpret_cast<Address>(current)); if (current < end) OutputRawData(reinterpret_cast<Address>(current));
while (current < end && !(*current)->IsSmi()) { 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 && if (current != start &&
current[0] == current[-1] && root_index != kInvalidRootIndex &&
!HEAP->InNewSpace(*current)) { root_index < kRootArrayNumberOfConstantEncodings &&
current_contents == current[-1]) {
ASSERT(!HEAP->InNewSpace(current_contents));
int repeat_count = 1; int repeat_count = 1;
while (current < end - 1 && current[repeat_count] == current[0]) { while (current < end - 1 && current[repeat_count] == current_contents) {
repeat_count++; repeat_count++;
} }
current += repeat_count; current += repeat_count;
...@@ -1446,7 +1469,7 @@ void Serializer::ObjectSerializer::VisitPointers(Object** start, ...@@ -1446,7 +1469,7 @@ void Serializer::ObjectSerializer::VisitPointers(Object** start,
sink_->Put(CodeForRepeats(repeat_count), "SerializeRepeats"); sink_->Put(CodeForRepeats(repeat_count), "SerializeRepeats");
} }
} else { } else {
serializer_->SerializeObject(*current, kPlain, kStartOfObject); serializer_->SerializeObject(current_contents, kPlain, kStartOfObject);
bytes_processed_so_far_ += kPointerSize; bytes_processed_so_far_ += kPointerSize;
current++; current++;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment