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) \
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) \
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) \
// 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();
#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)
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]; \
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;
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;
sink_->Put(CodeForRepeats(repeat_count), "SerializeRepeats");
}
} else {
- serializer_->SerializeObject(*current, kPlain, kStartOfObject);
+ serializer_->SerializeObject(current_contents, kPlain, kStartOfObject);
bytes_processed_so_far_ += kPointerSize;
current++;
}