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:
parent
f464ad61fb
commit
9065e95d45
11
src/heap.h
11
src/heap.h
@ -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)
|
||||
|
@ -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++;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user