Index: src/serialize.cc |
=================================================================== |
--- src/serialize.cc (revision 4681) |
+++ src/serialize.cc (working copy) |
@@ -660,27 +660,164 @@ |
} |
-#define ONE_CASE_PER_SPACE(base_tag) \ |
- case (base_tag) + NEW_SPACE: /* NOLINT */ \ |
- case (base_tag) + OLD_POINTER_SPACE: /* NOLINT */ \ |
- case (base_tag) + OLD_DATA_SPACE: /* NOLINT */ \ |
- case (base_tag) + CODE_SPACE: /* NOLINT */ \ |
- case (base_tag) + MAP_SPACE: /* NOLINT */ \ |
- case (base_tag) + CELL_SPACE: /* NOLINT */ \ |
- case (base_tag) + kLargeData: /* NOLINT */ \ |
- case (base_tag) + kLargeCode: /* NOLINT */ \ |
- case (base_tag) + kLargeFixedArray: /* NOLINT */ |
+// This macro is always used with a constant argument so it should all fold |
+// away to almost nothing in the generated code. It might be nicer to do this |
+// with the ternary operator but there are type issues with that. |
+#define ASSIGN_DEST_SPACE(space_number) \ |
+ Space* dest_space; \ |
+ if (space_number == NEW_SPACE) { \ |
+ dest_space = Heap::new_space(); \ |
+ } else if (space_number == OLD_POINTER_SPACE) { \ |
+ dest_space = Heap::old_pointer_space(); \ |
+ } else if (space_number == OLD_DATA_SPACE) { \ |
+ dest_space = Heap::old_data_space(); \ |
+ } else if (space_number == CODE_SPACE) { \ |
+ dest_space = Heap::code_space(); \ |
+ } else if (space_number == MAP_SPACE) { \ |
+ dest_space = Heap::map_space(); \ |
+ } else if (space_number == CELL_SPACE) { \ |
+ dest_space = Heap::cell_space(); \ |
+ } else { \ |
+ ASSERT(space_number >= LO_SPACE); \ |
+ dest_space = Heap::lo_space(); \ |
+ } |
+static const int kUnknownOffsetFromStart = -1; |
+ |
+ |
void Deserializer::ReadChunk(Object** current, |
Object** limit, |
- int space, |
+ int source_space, |
Address address) { |
while (current < limit) { |
int data = source_->Get(); |
switch (data) { |
+#define CASE_STATEMENT(where, how, within, space_number) \ |
+ case where + how + within + space_number: \ |
+ ASSERT((where & ~kPointedToMask) == 0); \ |
+ ASSERT((how & ~kHowToCodeMask) == 0); \ |
+ ASSERT((within & ~kWhereToPointMask) == 0); \ |
+ ASSERT((space_number & ~kSpaceMask) == 0); |
+ |
+#define CASE_BODY(where, how, within, space_number_if_any, offset_from_start) \ |
+ { \ |
+ bool emit_write_barrier = false; \ |
+ bool current_was_incremented = false; \ |
+ int space_number = space_number_if_any == kAnyOldSpace ? \ |
+ (data & kSpaceMask) : space_number_if_any; \ |
+ if (where == kNewObject && how == kPlain && within == kStartOfObject) {\ |
+ ASSIGN_DEST_SPACE(space_number) \ |
+ ReadObject(space_number, dest_space, current); \ |
+ emit_write_barrier = \ |
+ (space_number == NEW_SPACE && source_space != NEW_SPACE); \ |
+ } else { \ |
+ Object* new_object = NULL; /* May not be a real Object pointer. */ \ |
+ if (where == kNewObject) { \ |
+ ASSIGN_DEST_SPACE(space_number) \ |
+ ReadObject(space_number, dest_space, &new_object); \ |
+ } else if (where == kRootArray) { \ |
+ int root_id = source_->GetInt(); \ |
+ new_object = Heap::roots_address()[root_id]; \ |
+ } else if (where == kPartialSnapshotCache) { \ |
+ int cache_index = source_->GetInt(); \ |
+ new_object = partial_snapshot_cache_[cache_index]; \ |
+ } else if (where == kExternalReference) { \ |
+ int reference_id = source_->GetInt(); \ |
+ Address address = \ |
+ external_reference_decoder_->Decode(reference_id); \ |
+ new_object = reinterpret_cast<Object*>(address); \ |
+ } else if (where == kBackref) { \ |
+ emit_write_barrier = \ |
+ (space_number == NEW_SPACE && source_space != NEW_SPACE); \ |
+ new_object = GetAddressFromEnd(data & kSpaceMask); \ |
+ } else { \ |
+ ASSERT(where == kFromStart); \ |
+ if (offset_from_start == kUnknownOffsetFromStart) { \ |
+ emit_write_barrier = \ |
+ (space_number == NEW_SPACE && source_space != NEW_SPACE); \ |
+ new_object = GetAddressFromStart(data & kSpaceMask); \ |
+ } else { \ |
+ Address object_address = pages_[space_number][0] + \ |
+ (offset_from_start << kObjectAlignmentBits); \ |
+ new_object = HeapObject::FromAddress(object_address); \ |
+ } \ |
+ } \ |
+ if (within == kFirstInstruction) { \ |
+ Code* new_code_object = reinterpret_cast<Code*>(new_object); \ |
+ new_object = reinterpret_cast<Object*>( \ |
+ new_code_object->instruction_start()); \ |
+ } \ |
+ if (how == kFromCode) { \ |
+ Address location_of_branch_data = \ |
+ reinterpret_cast<Address>(current); \ |
+ Assembler::set_target_at(location_of_branch_data, \ |
+ reinterpret_cast<Address>(new_object)); \ |
+ if (within == kFirstInstruction) { \ |
+ location_of_branch_data += Assembler::kCallTargetSize; \ |
+ current = reinterpret_cast<Object**>(location_of_branch_data); \ |
+ current_was_incremented = true; \ |
+ } \ |
+ } else { \ |
+ *current = new_object; \ |
+ } \ |
+ } \ |
+ if (emit_write_barrier) { \ |
+ Heap::RecordWrite(address, static_cast<int>( \ |
+ reinterpret_cast<Address>(current) - address)); \ |
+ } \ |
+ if (!current_was_incremented) { \ |
+ current++; /* Increment current if it wasn't done above. */ \ |
+ } \ |
+ break; \ |
+ } \ |
+ |
+// This generates a case and a body for each space. The large object spaces are |
+// very rare in snapshots so they are grouped in one body. |
+#define ONE_PER_SPACE(where, how, within) \ |
+ CASE_STATEMENT(where, how, within, NEW_SPACE) \ |
+ CASE_BODY(where, how, within, NEW_SPACE, kUnknownOffsetFromStart) \ |
+ CASE_STATEMENT(where, how, within, OLD_DATA_SPACE) \ |
+ CASE_BODY(where, how, within, OLD_DATA_SPACE, kUnknownOffsetFromStart) \ |
+ CASE_STATEMENT(where, how, within, OLD_POINTER_SPACE) \ |
+ CASE_BODY(where, how, within, OLD_POINTER_SPACE, kUnknownOffsetFromStart) \ |
+ CASE_STATEMENT(where, how, within, CODE_SPACE) \ |
+ CASE_BODY(where, how, within, CODE_SPACE, kUnknownOffsetFromStart) \ |
+ CASE_STATEMENT(where, how, within, CELL_SPACE) \ |
+ CASE_BODY(where, how, within, CELL_SPACE, kUnknownOffsetFromStart) \ |
+ CASE_STATEMENT(where, how, within, MAP_SPACE) \ |
+ CASE_BODY(where, how, within, MAP_SPACE, kUnknownOffsetFromStart) \ |
+ CASE_STATEMENT(where, how, within, kLargeData) \ |
+ CASE_STATEMENT(where, how, within, kLargeCode) \ |
+ CASE_STATEMENT(where, how, within, kLargeFixedArray) \ |
+ CASE_BODY(where, how, within, kAnyOldSpace, kUnknownOffsetFromStart) |
+ |
+// This generates a case and a body for the new space (which has to do extra |
+// write barrier handling) and handles the other spaces with 8 fall-through |
+// cases and one body. |
+#define ALL_SPACES(where, how, within) \ |
+ CASE_STATEMENT(where, how, within, NEW_SPACE) \ |
+ CASE_BODY(where, how, within, NEW_SPACE, kUnknownOffsetFromStart) \ |
+ CASE_STATEMENT(where, how, within, OLD_DATA_SPACE) \ |
+ CASE_STATEMENT(where, how, within, OLD_POINTER_SPACE) \ |
+ CASE_STATEMENT(where, how, within, CODE_SPACE) \ |
+ CASE_STATEMENT(where, how, within, CELL_SPACE) \ |
+ CASE_STATEMENT(where, how, within, MAP_SPACE) \ |
+ CASE_STATEMENT(where, how, within, kLargeData) \ |
+ CASE_STATEMENT(where, how, within, kLargeCode) \ |
+ CASE_STATEMENT(where, how, within, kLargeFixedArray) \ |
+ CASE_BODY(where, how, within, kAnyOldSpace, kUnknownOffsetFromStart) |
+ |
+#define EMIT_COMMON_REFERENCE_PATTERNS(pseudo_space_number, \ |
+ space_number, \ |
+ offset_from_start) \ |
+ CASE_STATEMENT(kFromStart, kPlain, kStartOfObject, pseudo_space_number) \ |
+ CASE_BODY(kFromStart, kPlain, kStartOfObject, space_number, offset_from_start) |
+ |
+ // We generate 15 cases and bodies that process special tags that combine |
+ // the raw data tag and the length into one byte. |
#define RAW_CASE(index, size) \ |
- case RAW_DATA_SERIALIZATION + index: { \ |
+ case kRawData + index: { \ |
byte* raw_data_out = reinterpret_cast<byte*>(current); \ |
source_->CopyRaw(raw_data_out, size); \ |
current = reinterpret_cast<Object**>(raw_data_out + size); \ |
@@ -688,144 +825,77 @@ |
} |
COMMON_RAW_LENGTHS(RAW_CASE) |
#undef RAW_CASE |
- case RAW_DATA_SERIALIZATION: { |
+ |
+ // Deserialize a chunk of raw data that doesn't have one of the popular |
+ // lengths. |
+ case kRawData: { |
int size = source_->GetInt(); |
byte* raw_data_out = reinterpret_cast<byte*>(current); |
source_->CopyRaw(raw_data_out, size); |
current = reinterpret_cast<Object**>(raw_data_out + size); |
break; |
} |
- case OBJECT_SERIALIZATION + NEW_SPACE: { |
- ReadObject(NEW_SPACE, Heap::new_space(), current); |
- if (space != NEW_SPACE) { |
- Heap::RecordWrite(address, static_cast<int>( |
- reinterpret_cast<Address>(current) - address)); |
- } |
- current++; |
- break; |
- } |
- case OBJECT_SERIALIZATION + OLD_DATA_SPACE: |
- ReadObject(OLD_DATA_SPACE, Heap::old_data_space(), current++); |
- break; |
- case OBJECT_SERIALIZATION + OLD_POINTER_SPACE: |
- ReadObject(OLD_POINTER_SPACE, Heap::old_pointer_space(), current++); |
- break; |
- case OBJECT_SERIALIZATION + MAP_SPACE: |
- ReadObject(MAP_SPACE, Heap::map_space(), current++); |
- break; |
- case OBJECT_SERIALIZATION + CODE_SPACE: |
- ReadObject(CODE_SPACE, Heap::code_space(), current++); |
- break; |
- case OBJECT_SERIALIZATION + CELL_SPACE: |
- ReadObject(CELL_SPACE, Heap::cell_space(), current++); |
- break; |
- case OBJECT_SERIALIZATION + kLargeData: |
- ReadObject(kLargeData, Heap::lo_space(), current++); |
- break; |
- case OBJECT_SERIALIZATION + kLargeCode: |
- ReadObject(kLargeCode, Heap::lo_space(), current++); |
- break; |
- case OBJECT_SERIALIZATION + kLargeFixedArray: |
- ReadObject(kLargeFixedArray, Heap::lo_space(), current++); |
- break; |
- case CODE_OBJECT_SERIALIZATION + kLargeCode: { |
- Object* new_code_object = NULL; |
- ReadObject(kLargeCode, Heap::lo_space(), &new_code_object); |
- Code* code_object = reinterpret_cast<Code*>(new_code_object); |
- // Setting a branch/call to another code object from code. |
- Address location_of_branch_data = reinterpret_cast<Address>(current); |
- Assembler::set_target_at(location_of_branch_data, |
- code_object->instruction_start()); |
- location_of_branch_data += Assembler::kCallTargetSize; |
- current = reinterpret_cast<Object**>(location_of_branch_data); |
- break; |
- } |
- case CODE_OBJECT_SERIALIZATION + CODE_SPACE: { |
- Object* new_code_object = NULL; |
- ReadObject(CODE_SPACE, Heap::code_space(), &new_code_object); |
- Code* code_object = reinterpret_cast<Code*>(new_code_object); |
- // Setting a branch/call to another code object from code. |
- Address location_of_branch_data = reinterpret_cast<Address>(current); |
- Assembler::set_target_at(location_of_branch_data, |
- code_object->instruction_start()); |
- location_of_branch_data += Assembler::kCallTargetSize; |
- current = reinterpret_cast<Object**>(location_of_branch_data); |
- break; |
- } |
- ONE_CASE_PER_SPACE(BACKREF_SERIALIZATION) { |
- // Write a backreference to an object we unpacked earlier. |
- int backref_space = (data & kSpaceMask); |
- if (backref_space == NEW_SPACE && space != NEW_SPACE) { |
- Heap::RecordWrite(address, static_cast<int>( |
- reinterpret_cast<Address>(current) - address)); |
- } |
- *current++ = GetAddressFromEnd(backref_space); |
- break; |
- } |
- ONE_CASE_PER_SPACE(REFERENCE_SERIALIZATION) { |
- // Write a reference to an object we unpacked earlier. |
- int reference_space = (data & kSpaceMask); |
- if (reference_space == NEW_SPACE && space != NEW_SPACE) { |
- Heap::RecordWrite(address, static_cast<int>( |
- reinterpret_cast<Address>(current) - address)); |
- } |
- *current++ = GetAddressFromStart(reference_space); |
- break; |
- } |
-#define COMMON_REFS_CASE(index, reference_space, address) \ |
- case REFERENCE_SERIALIZATION + index: { \ |
- ASSERT(SpaceIsPaged(reference_space)); \ |
- Address object_address = \ |
- pages_[reference_space][0] + (address << kObjectAlignmentBits); \ |
- *current++ = HeapObject::FromAddress(object_address); \ |
- break; \ |
- } |
- COMMON_REFERENCE_PATTERNS(COMMON_REFS_CASE) |
-#undef COMMON_REFS_CASE |
- ONE_CASE_PER_SPACE(CODE_BACKREF_SERIALIZATION) { |
- int backref_space = (data & kSpaceMask); |
- // Can't use Code::cast because heap is not set up yet and assertions |
- // will fail. |
- Code* code_object = |
- reinterpret_cast<Code*>(GetAddressFromEnd(backref_space)); |
- // Setting a branch/call to previously decoded code object from code. |
- Address location_of_branch_data = reinterpret_cast<Address>(current); |
- Assembler::set_target_at(location_of_branch_data, |
- code_object->instruction_start()); |
- location_of_branch_data += Assembler::kCallTargetSize; |
- current = reinterpret_cast<Object**>(location_of_branch_data); |
- break; |
- } |
- ONE_CASE_PER_SPACE(CODE_REFERENCE_SERIALIZATION) { |
- int backref_space = (data & kSpaceMask); |
- // Can't use Code::cast because heap is not set up yet and assertions |
- // will fail. |
- Code* code_object = |
- reinterpret_cast<Code*>(GetAddressFromStart(backref_space)); |
- // Setting a branch/call to previously decoded code object from code. |
- Address location_of_branch_data = reinterpret_cast<Address>(current); |
- Assembler::set_target_at(location_of_branch_data, |
- code_object->instruction_start()); |
- location_of_branch_data += Assembler::kCallTargetSize; |
- current = reinterpret_cast<Object**>(location_of_branch_data); |
- break; |
- } |
- case EXTERNAL_REFERENCE_SERIALIZATION: { |
- int reference_id = source_->GetInt(); |
- Address address = external_reference_decoder_->Decode(reference_id); |
- *current++ = reinterpret_cast<Object*>(address); |
- break; |
- } |
- case EXTERNAL_BRANCH_TARGET_SERIALIZATION: { |
- int reference_id = source_->GetInt(); |
- Address address = external_reference_decoder_->Decode(reference_id); |
- Address location_of_branch_data = reinterpret_cast<Address>(current); |
- Assembler::set_external_target_at(location_of_branch_data, address); |
- location_of_branch_data += Assembler::kExternalTargetSize; |
- current = reinterpret_cast<Object**>(location_of_branch_data); |
- break; |
- } |
- case START_NEW_PAGE_SERIALIZATION: { |
+ |
+ // Deserialize a new object and write a pointer to it to the current |
+ // object. |
+ ONE_PER_SPACE(kNewObject, kPlain, kStartOfObject) |
+ // Deserialize a new code object and write a pointer to its first |
+ // instruction to the current code object. |
+ ONE_PER_SPACE(kNewObject, kFromCode, kFirstInstruction) |
+ // Find a recently deserialized object using its offset from the current |
+ // allocation point and write a pointer to it to the current object. |
+ ALL_SPACES(kBackref, kPlain, kStartOfObject) |
+ // Find a recently deserialized code object using its offset from the |
+ // current allocation point and write a pointer to its first instruction |
+ // to the current code object. |
+ ALL_SPACES(kBackref, kFromCode, kFirstInstruction) |
+ // Find an already deserialized object using its offset from the start |
+ // and write a pointer to it to the current object. |
+ ALL_SPACES(kFromStart, kPlain, kStartOfObject) |
+ // Find an already deserialized code object using its offset from the |
+ // start and write a pointer to its first instruction to the current code |
+ // object. |
+ ALL_SPACES(kFromStart, kFromCode, kFirstInstruction) |
+ // Find an already deserialized object at one of the predetermined popular |
+ // offsets from the start and write a pointer to it in the current object. |
+ COMMON_REFERENCE_PATTERNS(EMIT_COMMON_REFERENCE_PATTERNS) |
+ // Find an object in the roots array and write a pointer to it to the |
+ // current object. |
+ CASE_STATEMENT(kRootArray, kPlain, kStartOfObject, 0) |
+ CASE_BODY(kRootArray, kPlain, kStartOfObject, 0, kUnknownOffsetFromStart) |
+ // Find an object in the partial snapshots cache and write a pointer to it |
+ // to the current object. |
+ CASE_STATEMENT(kPartialSnapshotCache, kPlain, kStartOfObject, 0) |
+ CASE_BODY(kPartialSnapshotCache, |
+ kPlain, |
+ kStartOfObject, |
+ 0, |
+ kUnknownOffsetFromStart) |
+ // Find an external reference and write a pointer to it to the current |
+ // object. |
+ CASE_STATEMENT(kExternalReference, kPlain, kStartOfObject, 0) |
+ CASE_BODY(kExternalReference, |
+ kPlain, |
+ kStartOfObject, |
+ 0, |
+ kUnknownOffsetFromStart) |
+ // Find an external reference and write a pointer to it in the current |
+ // code object. |
+ CASE_STATEMENT(kExternalReference, kFromCode, kStartOfObject, 0) |
+ CASE_BODY(kExternalReference, |
+ kFromCode, |
+ kStartOfObject, |
+ 0, |
+ kUnknownOffsetFromStart) |
+ |
+#undef CASE_STATEMENT |
+#undef CASE_BODY |
+#undef ONE_PER_SPACE |
+#undef ALL_SPACES |
+#undef EMIT_COMMON_REFERENCE_PATTERNS |
+#undef ASSIGN_DEST_SPACE |
+ |
+ case kNewPage: { |
int space = source_->Get(); |
pages_[space].Add(last_object_address_); |
if (space == CODE_SPACE) { |
@@ -833,7 +903,8 @@ |
} |
break; |
} |
- case NATIVES_STRING_RESOURCE: { |
+ |
+ case kNativesStringResource: { |
int index = source_->Get(); |
Vector<const char> source_vector = Natives::GetScriptSource(index); |
NativesExternalStringResource* resource = |
@@ -841,21 +912,13 @@ |
*current++ = reinterpret_cast<Object*>(resource); |
break; |
} |
- case ROOT_SERIALIZATION: { |
- int root_id = source_->GetInt(); |
- *current++ = Heap::roots_address()[root_id]; |
- break; |
- } |
- case PARTIAL_SNAPSHOT_CACHE_ENTRY: { |
- int cache_index = source_->GetInt(); |
- *current++ = partial_snapshot_cache_[cache_index]; |
- break; |
- } |
- case SYNCHRONIZE: { |
+ |
+ case kSynchronize: { |
// If we get here then that indicates that you have a mismatch between |
// the number of GC roots when serializing and deserializing. |
UNREACHABLE(); |
} |
+ |
default: |
UNREACHABLE(); |
} |
@@ -880,7 +943,7 @@ |
int data = source_->Get(); |
// If this assert fails then that indicates that you have a mismatch between |
// the number of GC roots when serializing and deserializing. |
- ASSERT_EQ(SYNCHRONIZE, data); |
+ ASSERT_EQ(kSynchronize, data); |
do { |
int character = source_->Get(); |
if (character == 0) break; |
@@ -895,7 +958,7 @@ |
void Serializer::Synchronize(const char* tag) { |
- sink_->Put(SYNCHRONIZE, tag); |
+ sink_->Put(kSynchronize, tag); |
int character; |
do { |
character = *tag++; |
@@ -957,13 +1020,13 @@ |
void Serializer::VisitPointers(Object** start, Object** end) { |
for (Object** current = start; current < end; current++) { |
if ((*current)->IsSmi()) { |
- sink_->Put(RAW_DATA_SERIALIZATION, "RawData"); |
+ sink_->Put(kRawData, "RawData"); |
sink_->PutInt(kPointerSize, "length"); |
for (int i = 0; i < kPointerSize; i++) { |
sink_->Put(reinterpret_cast<byte*>(current)[i], "Byte"); |
} |
} else { |
- SerializeObject(*current, TAGGED_REPRESENTATION); |
+ SerializeObject(*current, kPlain, kStartOfObject); |
} |
} |
} |
@@ -1033,7 +1096,8 @@ |
void Serializer::SerializeReferenceToPreviousObject( |
int space, |
int address, |
- ReferenceRepresentation reference_representation) { |
+ HowToCode how_to_code, |
+ WhereToPoint where_to_point) { |
int offset = CurrentAllocationAddress(space) - address; |
bool from_start = true; |
if (SpaceIsPaged(space)) { |
@@ -1054,43 +1118,30 @@ |
// If we are actually dealing with real offsets (and not a numbering of |
// all objects) then we should shift out the bits that are always 0. |
if (!SpaceIsLarge(space)) address >>= kObjectAlignmentBits; |
- // On some architectures references between code objects are encoded |
- // specially (as relative offsets). Such references have their own |
- // special tags to simplify the deserializer. |
- if (reference_representation == CODE_TARGET_REPRESENTATION) { |
- if (from_start) { |
- sink_->Put(CODE_REFERENCE_SERIALIZATION + space, "RefCodeSer"); |
+ if (from_start) { |
+#define COMMON_REFS_CASE(pseudo_space, actual_space, offset) \ |
+ if (space == actual_space && address == offset && \ |
+ how_to_code == kPlain && where_to_point == kStartOfObject) { \ |
+ sink_->Put(kFromStart + how_to_code + where_to_point + \ |
+ pseudo_space, "RefSer"); \ |
+ } else /* NOLINT */ |
+ COMMON_REFERENCE_PATTERNS(COMMON_REFS_CASE) |
+#undef COMMON_REFS_CASE |
+ { /* NOLINT */ |
+ sink_->Put(kFromStart + how_to_code + where_to_point + space, "RefSer"); |
sink_->PutInt(address, "address"); |
- } else { |
- sink_->Put(CODE_BACKREF_SERIALIZATION + space, "BackRefCodeSer"); |
- sink_->PutInt(address, "address"); |
} |
} else { |
- // Regular absolute references. |
- CHECK_EQ(TAGGED_REPRESENTATION, reference_representation); |
- if (from_start) { |
- // There are some common offsets that have their own specialized encoding. |
-#define COMMON_REFS_CASE(tag, common_space, common_offset) \ |
- if (space == common_space && address == common_offset) { \ |
- sink_->PutSection(tag + REFERENCE_SERIALIZATION, "RefSer"); \ |
- } else /* NOLINT */ |
- COMMON_REFERENCE_PATTERNS(COMMON_REFS_CASE) |
-#undef COMMON_REFS_CASE |
- { /* NOLINT */ |
- sink_->Put(REFERENCE_SERIALIZATION + space, "RefSer"); |
- sink_->PutInt(address, "address"); |
- } |
- } else { |
- sink_->Put(BACKREF_SERIALIZATION + space, "BackRefSer"); |
- sink_->PutInt(address, "address"); |
- } |
+ sink_->Put(kBackref + how_to_code + where_to_point + space, "BackRefSer"); |
+ sink_->PutInt(address, "address"); |
} |
} |
void StartupSerializer::SerializeObject( |
Object* o, |
- ReferenceRepresentation reference_representation) { |
+ HowToCode how_to_code, |
+ WhereToPoint where_to_point) { |
CHECK(o->IsHeapObject()); |
HeapObject* heap_object = HeapObject::cast(o); |
@@ -1099,13 +1150,15 @@ |
int address = address_mapper_.MappedTo(heap_object); |
SerializeReferenceToPreviousObject(space, |
address, |
- reference_representation); |
+ how_to_code, |
+ where_to_point); |
} else { |
// Object has not yet been serialized. Serialize it here. |
ObjectSerializer object_serializer(this, |
heap_object, |
sink_, |
- reference_representation); |
+ how_to_code, |
+ where_to_point); |
object_serializer.Serialize(); |
} |
} |
@@ -1115,7 +1168,7 @@ |
for (int i = partial_snapshot_cache_length_; |
i < kPartialSnapshotCacheCapacity; |
i++) { |
- sink_->Put(ROOT_SERIALIZATION, "RootSerialization"); |
+ sink_->Put(kRootArray + kPlain + kStartOfObject, "RootSerialization"); |
sink_->PutInt(Heap::kUndefinedValueRootIndex, "root_index"); |
} |
Heap::IterateWeakRoots(this, VISIT_ALL); |
@@ -1124,20 +1177,22 @@ |
void PartialSerializer::SerializeObject( |
Object* o, |
- ReferenceRepresentation reference_representation) { |
+ HowToCode how_to_code, |
+ WhereToPoint where_to_point) { |
CHECK(o->IsHeapObject()); |
HeapObject* heap_object = HeapObject::cast(o); |
int root_index; |
if ((root_index = RootIndex(heap_object)) != kInvalidRootIndex) { |
- sink_->Put(ROOT_SERIALIZATION, "RootSerialization"); |
+ sink_->Put(kRootArray + how_to_code + where_to_point, "RootSerialization"); |
sink_->PutInt(root_index, "root_index"); |
return; |
} |
if (ShouldBeInThePartialSnapshotCache(heap_object)) { |
int cache_index = PartialSnapshotCacheIndex(heap_object); |
- sink_->Put(PARTIAL_SNAPSHOT_CACHE_ENTRY, "PartialSnapshotCache"); |
+ sink_->Put(kPartialSnapshotCache + how_to_code + where_to_point, |
+ "PartialSnapshotCache"); |
sink_->PutInt(cache_index, "partial_snapshot_cache_index"); |
return; |
} |
@@ -1155,13 +1210,15 @@ |
int address = address_mapper_.MappedTo(heap_object); |
SerializeReferenceToPreviousObject(space, |
address, |
- reference_representation); |
+ how_to_code, |
+ where_to_point); |
} else { |
// Object has not yet been serialized. Serialize it here. |
ObjectSerializer serializer(this, |
heap_object, |
sink_, |
- reference_representation); |
+ how_to_code, |
+ where_to_point); |
serializer.Serialize(); |
} |
} |
@@ -1171,12 +1228,8 @@ |
int space = Serializer::SpaceOfObject(object_); |
int size = object_->Size(); |
- if (reference_representation_ == TAGGED_REPRESENTATION) { |
- sink_->Put(OBJECT_SERIALIZATION + space, "ObjectSerialization"); |
- } else { |
- CHECK_EQ(CODE_TARGET_REPRESENTATION, reference_representation_); |
- sink_->Put(CODE_OBJECT_SERIALIZATION + space, "ObjectSerialization"); |
- } |
+ sink_->Put(kNewObject + reference_representation_ + space, |
+ "ObjectSerialization"); |
sink_->PutInt(size >> kObjectAlignmentBits, "Size in words"); |
LOG(SnapshotPositionEvent(object_->address(), sink_->Position())); |
@@ -1186,12 +1239,12 @@ |
int offset = serializer_->Allocate(space, size, &start_new_page); |
serializer_->address_mapper()->AddMapping(object_, offset); |
if (start_new_page) { |
- sink_->Put(START_NEW_PAGE_SERIALIZATION, "NewPage"); |
+ sink_->Put(kNewPage, "NewPage"); |
sink_->PutSection(space, "NewPageSpace"); |
} |
// Serialize the map (first word of the object). |
- serializer_->SerializeObject(object_->map(), TAGGED_REPRESENTATION); |
+ serializer_->SerializeObject(object_->map(), kPlain, kStartOfObject); |
// Serialize the rest of the object. |
CHECK_EQ(0, bytes_processed_so_far_); |
@@ -1209,7 +1262,7 @@ |
if (current < end) OutputRawData(reinterpret_cast<Address>(current)); |
while (current < end && !(*current)->IsSmi()) { |
- serializer_->SerializeObject(*current, TAGGED_REPRESENTATION); |
+ serializer_->SerializeObject(*current, kPlain, kStartOfObject); |
bytes_processed_so_far_ += kPointerSize; |
current++; |
} |
@@ -1223,7 +1276,7 @@ |
OutputRawData(references_start); |
for (Address* current = start; current < end; current++) { |
- sink_->Put(EXTERNAL_REFERENCE_SERIALIZATION, "ExternalReference"); |
+ sink_->Put(kExternalReference + kPlain + kStartOfObject, "ExternalRef"); |
int reference_id = serializer_->EncodeExternalReference(*current); |
sink_->PutInt(reference_id, "reference id"); |
} |
@@ -1237,7 +1290,14 @@ |
Address target = rinfo->target_address(); |
uint32_t encoding = serializer_->EncodeExternalReference(target); |
CHECK(target == NULL ? encoding == 0 : encoding != 0); |
- sink_->Put(EXTERNAL_BRANCH_TARGET_SERIALIZATION, "ExternalReference"); |
+ int representation; |
+ // Can't use a ternary operator because of gcc. |
+ if (rinfo->IsCodedSpecially()) { |
+ representation = kStartOfObject + kFromCode; |
+ } else { |
+ representation = kStartOfObject + kPlain; |
+ } |
+ sink_->Put(kExternalReference + representation, "ExternalReference"); |
sink_->PutInt(encoding, "reference id"); |
bytes_processed_so_far_ += Assembler::kExternalTargetSize; |
} |
@@ -1248,7 +1308,7 @@ |
Address target_start = rinfo->target_address_address(); |
OutputRawData(target_start); |
Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); |
- serializer_->SerializeObject(target, CODE_TARGET_REPRESENTATION); |
+ serializer_->SerializeObject(target, kFromCode, kFirstInstruction); |
bytes_processed_so_far_ += Assembler::kCallTargetSize; |
} |
@@ -1264,7 +1324,7 @@ |
typedef v8::String::ExternalAsciiStringResource Resource; |
Resource* resource = string->resource(); |
if (resource == *resource_pointer) { |
- sink_->Put(NATIVES_STRING_RESOURCE, "NativesStringResource"); |
+ sink_->Put(kNativesStringResource, "NativesStringResource"); |
sink_->PutSection(i, "NativesStringResourceEnd"); |
bytes_processed_so_far_ += sizeof(resource); |
return; |
@@ -1288,12 +1348,12 @@ |
Address base = object_start + bytes_processed_so_far_; |
#define RAW_CASE(index, length) \ |
if (skipped == length) { \ |
- sink_->PutSection(RAW_DATA_SERIALIZATION + index, "RawDataFixed"); \ |
+ sink_->PutSection(kRawData + index, "RawDataFixed"); \ |
} else /* NOLINT */ |
COMMON_RAW_LENGTHS(RAW_CASE) |
#undef RAW_CASE |
{ /* NOLINT */ |
- sink_->Put(RAW_DATA_SERIALIZATION, "RawData"); |
+ sink_->Put(kRawData, "RawData"); |
sink_->PutInt(skipped, "length"); |
} |
for (int i = 0; i < skipped; i++) { |