| Index: src/serialize.cc
|
| ===================================================================
|
| --- src/serialize.cc (revision 4699)
|
| +++ 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++) {
|
|
|