| Index: src/serialize.cc
|
| diff --git a/src/serialize.cc b/src/serialize.cc
|
| index 784992d92b869972834c954f211b5d635510294c..1d33f4f0623e3a38f2f46247b06a6e64eb93f60b 100644
|
| --- a/src/serialize.cc
|
| +++ b/src/serialize.cc
|
| @@ -840,7 +840,7 @@ void Deserializer::ReadData(Object** current, Object** limit, int source_space,
|
| switch (data) {
|
| #define CASE_STATEMENT(where, how, within, space_number) \
|
| case where + how + within + space_number: \
|
| - STATIC_ASSERT((where & ~kPointedToMask) == 0); \
|
| + STATIC_ASSERT((where & ~kWhereMask) == 0); \
|
| STATIC_ASSERT((how & ~kHowToCodeMask) == 0); \
|
| STATIC_ASSERT((within & ~kWhereToPointMask) == 0); \
|
| STATIC_ASSERT((space_number & ~kSpaceMask) == 0);
|
| @@ -859,6 +859,15 @@ void Deserializer::ReadData(Object** current, Object** limit, int source_space,
|
| Object* new_object = NULL; /* May not be a real Object pointer. */ \
|
| if (where == kNewObject) { \
|
| ReadObject(space_number, &new_object); \
|
| + } else if (where == kBackref) { \
|
| + emit_write_barrier = (space_number == NEW_SPACE); \
|
| + new_object = GetBackReferencedObject(data & kSpaceMask); \
|
| + } else if (where == kBackrefWithSkip) { \
|
| + int skip = source_.GetInt(); \
|
| + current = reinterpret_cast<Object**>( \
|
| + reinterpret_cast<Address>(current) + skip); \
|
| + emit_write_barrier = (space_number == NEW_SPACE); \
|
| + new_object = GetBackReferencedObject(data & kSpaceMask); \
|
| } else if (where == kRootArray) { \
|
| int root_id = source_.GetInt(); \
|
| new_object = isolate->heap()->roots_array_start()[root_id]; \
|
| @@ -874,10 +883,13 @@ void Deserializer::ReadData(Object** current, Object** limit, int source_space,
|
| int reference_id = source_.GetInt(); \
|
| Address address = external_reference_table_->address(reference_id); \
|
| new_object = reinterpret_cast<Object*>(address); \
|
| - } else if (where == kBackref) { \
|
| - emit_write_barrier = (space_number == NEW_SPACE); \
|
| - new_object = GetBackReferencedObject(data & kSpaceMask); \
|
| - } else if (where == kBuiltin) { \
|
| + } else if (where == kAttachedReference) { \
|
| + int index = source_.GetInt(); \
|
| + DCHECK(deserializing_user_code() || index == kGlobalProxyReference); \
|
| + new_object = *attached_objects_[index]; \
|
| + emit_write_barrier = isolate->heap()->InNewSpace(new_object); \
|
| + } else { \
|
| + DCHECK(where == kBuiltin); \
|
| DCHECK(deserializing_user_code()); \
|
| int builtin_id = source_.GetInt(); \
|
| DCHECK_LE(0, builtin_id); \
|
| @@ -885,18 +897,6 @@ void Deserializer::ReadData(Object** current, Object** limit, int source_space,
|
| Builtins::Name name = static_cast<Builtins::Name>(builtin_id); \
|
| new_object = isolate->builtins()->builtin(name); \
|
| emit_write_barrier = false; \
|
| - } else if (where == kAttachedReference) { \
|
| - int index = source_.GetInt(); \
|
| - DCHECK(deserializing_user_code() || index == kGlobalProxyReference); \
|
| - new_object = *attached_objects_[index]; \
|
| - emit_write_barrier = isolate->heap()->InNewSpace(new_object); \
|
| - } else { \
|
| - DCHECK(where == kBackrefWithSkip); \
|
| - int skip = source_.GetInt(); \
|
| - current = reinterpret_cast<Object**>( \
|
| - reinterpret_cast<Address>(current) + skip); \
|
| - emit_write_barrier = (space_number == NEW_SPACE); \
|
| - new_object = GetBackReferencedObject(data & kSpaceMask); \
|
| } \
|
| if (within == kInnerPointer) { \
|
| if (space_number != CODE_SPACE || new_object->IsCode()) { \
|
| @@ -959,106 +959,6 @@ void Deserializer::ReadData(Object** current, Object** limit, int source_space,
|
| FOUR_CASES(byte_code + 8) \
|
| FOUR_CASES(byte_code + 12)
|
|
|
| -#define COMMON_RAW_LENGTHS(f) \
|
| - f(1) \
|
| - f(2) \
|
| - f(3) \
|
| - f(4) \
|
| - f(5) \
|
| - f(6) \
|
| - f(7) \
|
| - f(8) \
|
| - f(9) \
|
| - f(10) \
|
| - f(11) \
|
| - f(12) \
|
| - f(13) \
|
| - f(14) \
|
| - f(15) \
|
| - f(16) \
|
| - f(17) \
|
| - f(18) \
|
| - f(19) \
|
| - f(20) \
|
| - f(21) \
|
| - f(22) \
|
| - f(23) \
|
| - f(24) \
|
| - f(25) \
|
| - f(26) \
|
| - f(27) \
|
| - f(28) \
|
| - f(29) \
|
| - f(30) \
|
| - f(31)
|
| -
|
| - // 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) \
|
| - case kRawData + index: { \
|
| - byte* raw_data_out = reinterpret_cast<byte*>(current); \
|
| - source_.CopyRaw(raw_data_out, index* kPointerSize); \
|
| - current = reinterpret_cast<Object**>(raw_data_out + index * kPointerSize); \
|
| - break; \
|
| - }
|
| - COMMON_RAW_LENGTHS(RAW_CASE)
|
| -#undef RAW_CASE
|
| -
|
| - // 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);
|
| - break;
|
| - }
|
| -
|
| - SIXTEEN_CASES(kRootArrayConstants + kNoSkipDistance)
|
| - SIXTEEN_CASES(kRootArrayConstants + kNoSkipDistance + 16) {
|
| - int root_id = RootArrayConstantFromByteCode(data);
|
| - Object* object = isolate->heap()->roots_array_start()[root_id];
|
| - DCHECK(!isolate->heap()->InNewSpace(object));
|
| - UnalignedCopy(current++, &object);
|
| - break;
|
| - }
|
| -
|
| - SIXTEEN_CASES(kRootArrayConstants + kHasSkipDistance)
|
| - SIXTEEN_CASES(kRootArrayConstants + kHasSkipDistance + 16) {
|
| - int root_id = RootArrayConstantFromByteCode(data);
|
| - int skip = source_.GetInt();
|
| - current = reinterpret_cast<Object**>(
|
| - reinterpret_cast<intptr_t>(current) + skip);
|
| - Object* object = isolate->heap()->roots_array_start()[root_id];
|
| - DCHECK(!isolate->heap()->InNewSpace(object));
|
| - UnalignedCopy(current++, &object);
|
| - break;
|
| - }
|
| -
|
| - case kVariableRepeat: {
|
| - int repeats = source_.GetInt();
|
| - Object* object = current[-1];
|
| - DCHECK(!isolate->heap()->InNewSpace(object));
|
| - for (int i = 0; i < repeats; i++) UnalignedCopy(current++, &object);
|
| - break;
|
| - }
|
| -
|
| - STATIC_ASSERT(kRootArrayNumberOfConstantEncodings ==
|
| - Heap::kOldSpaceRoots);
|
| - STATIC_ASSERT(kMaxFixedRepeats == 15);
|
| - FOUR_CASES(kFixedRepeat)
|
| - FOUR_CASES(kFixedRepeat + 4)
|
| - FOUR_CASES(kFixedRepeat + 8)
|
| - case kFixedRepeat + 12:
|
| - case kFixedRepeat + 13:
|
| - case kFixedRepeat + 14: {
|
| - int repeats = RepeatsForCode(data);
|
| - Object* object;
|
| - UnalignedCopy(&object, current - 1);
|
| - DCHECK(!isolate->heap()->InNewSpace(object));
|
| - for (int i = 0; i < repeats; i++) UnalignedCopy(current++, &object);
|
| - break;
|
| - }
|
| -
|
| // Deserialize a new object and write a pointer to it to the current
|
| // object.
|
| ALL_SPACES(kNewObject, kPlain, kStartOfObject)
|
| @@ -1108,38 +1008,19 @@ void Deserializer::ReadData(Object** current, Object** limit, int source_space,
|
| // 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)
|
| + CASE_BODY(kPartialSnapshotCache, kPlain, kStartOfObject, 0)
|
| // Find an code entry in the partial snapshots cache and
|
| // write a pointer to it to the current object.
|
| CASE_STATEMENT(kPartialSnapshotCache, kPlain, kInnerPointer, 0)
|
| - CASE_BODY(kPartialSnapshotCache,
|
| - kPlain,
|
| - kInnerPointer,
|
| - 0)
|
| + CASE_BODY(kPartialSnapshotCache, kPlain, kInnerPointer, 0)
|
| // 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)
|
| + CASE_BODY(kExternalReference, kPlain, kStartOfObject, 0)
|
| // 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)
|
| - // Find a builtin and write a pointer to it to the current object.
|
| - CASE_STATEMENT(kBuiltin, kPlain, kStartOfObject, 0)
|
| - CASE_BODY(kBuiltin, kPlain, kStartOfObject, 0)
|
| - CASE_STATEMENT(kBuiltin, kPlain, kInnerPointer, 0)
|
| - CASE_BODY(kBuiltin, kPlain, kInnerPointer, 0)
|
| - CASE_STATEMENT(kBuiltin, kFromCode, kInnerPointer, 0)
|
| - CASE_BODY(kBuiltin, kFromCode, kInnerPointer, 0)
|
| + CASE_BODY(kExternalReference, kFromCode, kStartOfObject, 0)
|
| // Find an object in the attached references and write a pointer to it to
|
| // the current object.
|
| CASE_STATEMENT(kAttachedReference, kPlain, kStartOfObject, 0)
|
| @@ -1148,6 +1029,13 @@ void Deserializer::ReadData(Object** current, Object** limit, int source_space,
|
| CASE_BODY(kAttachedReference, kPlain, kInnerPointer, 0)
|
| CASE_STATEMENT(kAttachedReference, kFromCode, kInnerPointer, 0)
|
| CASE_BODY(kAttachedReference, kFromCode, kInnerPointer, 0)
|
| + // Find a builtin and write a pointer to it to the current object.
|
| + CASE_STATEMENT(kBuiltin, kPlain, kStartOfObject, 0)
|
| + CASE_BODY(kBuiltin, kPlain, kStartOfObject, 0)
|
| + CASE_STATEMENT(kBuiltin, kPlain, kInnerPointer, 0)
|
| + CASE_BODY(kBuiltin, kPlain, kInnerPointer, 0)
|
| + CASE_STATEMENT(kBuiltin, kFromCode, kInnerPointer, 0)
|
| + CASE_BODY(kBuiltin, kFromCode, kInnerPointer, 0)
|
|
|
| #undef CASE_STATEMENT
|
| #undef CASE_BODY
|
| @@ -1175,17 +1063,8 @@ void Deserializer::ReadData(Object** current, Object** limit, int source_space,
|
| break;
|
| }
|
|
|
| - case kNativesStringResource: {
|
| - DCHECK(!isolate_->heap()->deserialization_complete());
|
| - int index = source_.Get();
|
| - Vector<const char> source_vector = Natives::GetScriptSource(index);
|
| - NativesExternalStringResource* resource =
|
| - new NativesExternalStringResource(source_vector.start(),
|
| - source_vector.length());
|
| - Object* resource_obj = reinterpret_cast<Object*>(resource);
|
| - UnalignedCopy(current++, &resource_obj);
|
| + case kNop:
|
| break;
|
| - }
|
|
|
| case kNextChunk: {
|
| int space = source_.Get();
|
| @@ -1201,6 +1080,60 @@ void Deserializer::ReadData(Object** current, Object** limit, int source_space,
|
| break;
|
| }
|
|
|
| + case kSynchronize:
|
| + // If we get here then that indicates that you have a mismatch between
|
| + // the number of GC roots when serializing and deserializing.
|
| + CHECK(false);
|
| + break;
|
| +
|
| + case kNativesStringResource: {
|
| + DCHECK(!isolate_->heap()->deserialization_complete());
|
| + int index = source_.Get();
|
| + Vector<const char> source_vector = Natives::GetScriptSource(index);
|
| + NativesExternalStringResource* resource =
|
| + new NativesExternalStringResource(source_vector.start(),
|
| + source_vector.length());
|
| + Object* resource_obj = reinterpret_cast<Object*>(resource);
|
| + UnalignedCopy(current++, &resource_obj);
|
| + break;
|
| + }
|
| +
|
| + // Deserialize raw data of variable length.
|
| + case kVariableRawData: {
|
| + int size_in_bytes = source_.GetInt();
|
| + byte* raw_data_out = reinterpret_cast<byte*>(current);
|
| + source_.CopyRaw(raw_data_out, size_in_bytes);
|
| + break;
|
| + }
|
| +
|
| + case kVariableRepeat: {
|
| + int repeats = source_.GetInt();
|
| + Object* object = current[-1];
|
| + DCHECK(!isolate->heap()->InNewSpace(object));
|
| + for (int i = 0; i < repeats; i++) UnalignedCopy(current++, &object);
|
| + break;
|
| + }
|
| +
|
| + STATIC_ASSERT(kNumberOfRootArrayConstants == Heap::kOldSpaceRoots);
|
| + STATIC_ASSERT(kNumberOfRootArrayConstants == 32);
|
| + SIXTEEN_CASES(kRootArrayConstantsWithSkip)
|
| + SIXTEEN_CASES(kRootArrayConstantsWithSkip + 16) {
|
| + int skip = source_.GetInt();
|
| + current = reinterpret_cast<Object**>(
|
| + reinterpret_cast<intptr_t>(current) + skip);
|
| + // Fall through.
|
| + }
|
| +
|
| + SIXTEEN_CASES(kRootArrayConstants)
|
| + SIXTEEN_CASES(kRootArrayConstants + 16) {
|
| + int root_id = data & kRootArrayConstantsMask;
|
| + Object* object = isolate->heap()->roots_array_start()[root_id];
|
| + DCHECK(!isolate->heap()->InNewSpace(object));
|
| + UnalignedCopy(current++, &object);
|
| + break;
|
| + }
|
| +
|
| + STATIC_ASSERT(kNumberOfHotObjects == 8);
|
| FOUR_CASES(kHotObjectWithSkip)
|
| FOUR_CASES(kHotObjectWithSkip + 4) {
|
| int skip = source_.GetInt();
|
| @@ -1208,9 +1141,10 @@ void Deserializer::ReadData(Object** current, Object** limit, int source_space,
|
| reinterpret_cast<Address>(current) + skip);
|
| // Fall through.
|
| }
|
| +
|
| FOUR_CASES(kHotObject)
|
| FOUR_CASES(kHotObject + 4) {
|
| - int index = data & kHotObjectIndexMask;
|
| + int index = data & kHotObjectMask;
|
| Object* hot_object = hot_objects_.Get(index);
|
| UnalignedCopy(current, &hot_object);
|
| if (write_barrier_needed && isolate->heap()->InNewSpace(hot_object)) {
|
| @@ -1223,12 +1157,30 @@ void Deserializer::ReadData(Object** current, Object** limit, int source_space,
|
| break;
|
| }
|
|
|
| - case kSynchronize: {
|
| - // If we get here then that indicates that you have a mismatch between
|
| - // the number of GC roots when serializing and deserializing.
|
| - CHECK(false);
|
| + // Deserialize raw data of fixed length from 1 to 32 words.
|
| + STATIC_ASSERT(kNumberOfFixedRawData == 32);
|
| + SIXTEEN_CASES(kFixedRawData)
|
| + SIXTEEN_CASES(kFixedRawData + 16) {
|
| + byte* raw_data_out = reinterpret_cast<byte*>(current);
|
| + int size_in_bytes = (data - kFixedRawDataStart) << kPointerSizeLog2;
|
| + source_.CopyRaw(raw_data_out, size_in_bytes);
|
| + current = reinterpret_cast<Object**>(raw_data_out + size_in_bytes);
|
| + break;
|
| }
|
|
|
| + STATIC_ASSERT(kNumberOfFixedRepeat == 16);
|
| + SIXTEEN_CASES(kFixedRepeat) {
|
| + int repeats = data - kFixedRepeatStart;
|
| + Object* object;
|
| + UnalignedCopy(&object, current - 1);
|
| + DCHECK(!isolate->heap()->InNewSpace(object));
|
| + for (int i = 0; i < repeats; i++) UnalignedCopy(current++, &object);
|
| + break;
|
| + }
|
| +
|
| +#undef SIXTEEN_CASES
|
| +#undef FOUR_CASES
|
| +
|
| default:
|
| CHECK(false);
|
| }
|
| @@ -1446,7 +1398,7 @@ bool Serializer::SerializeKnownObject(HeapObject* obj, HowToCode how_to_code,
|
| // Encode a reference to a hot object by its index in the working set.
|
| int index = hot_objects_.Find(obj);
|
| if (index != HotObjectsList::kNotFound) {
|
| - DCHECK(index >= 0 && index <= kMaxHotObjectIndex);
|
| + DCHECK(index >= 0 && index < kNumberOfHotObjects);
|
| if (FLAG_trace_serializer) {
|
| PrintF(" Encoding hot object %d:", index);
|
| obj->ShortPrint();
|
| @@ -1557,16 +1509,13 @@ void Serializer::PutRoot(int root_index,
|
| PrintF("\n");
|
| }
|
|
|
| - if (how_to_code == kPlain &&
|
| - where_to_point == kStartOfObject &&
|
| - root_index < kRootArrayNumberOfConstantEncodings &&
|
| + if (how_to_code == kPlain && where_to_point == kStartOfObject &&
|
| + root_index < kNumberOfRootArrayConstants &&
|
| !isolate()->heap()->InNewSpace(object)) {
|
| if (skip == 0) {
|
| - sink_->Put(kRootArrayConstants + kNoSkipDistance + root_index,
|
| - "RootConstant");
|
| + sink_->Put(kRootArrayConstants + root_index, "RootConstant");
|
| } else {
|
| - sink_->Put(kRootArrayConstants + kHasSkipDistance + root_index,
|
| - "RootConstant");
|
| + sink_->Put(kRootArrayConstantsWithSkip + root_index, "RootConstant");
|
| sink_->PutInt(skip, "SkipInPutRoot");
|
| }
|
| } else {
|
| @@ -1717,7 +1666,7 @@ void Serializer::ObjectSerializer::SerializeExternalString() {
|
| int bytes_to_output = allocation_size - HeapObject::kHeaderSize;
|
|
|
| // Output raw data header. Do not bother with common raw length cases here.
|
| - sink_->Put(kRawData, "RawDataForString");
|
| + sink_->Put(kVariableRawData, "RawDataForString");
|
| sink_->PutInt(bytes_to_output, "length");
|
|
|
| // Serialize string header (except for map).
|
| @@ -1808,11 +1757,11 @@ void Serializer::ObjectSerializer::VisitPointers(Object** start,
|
| }
|
| current += repeat_count;
|
| bytes_processed_so_far_ += repeat_count * kPointerSize;
|
| - if (repeat_count > kMaxFixedRepeats) {
|
| - sink_->Put(kVariableRepeat, "SerializeRepeats");
|
| - sink_->PutInt(repeat_count, "SerializeRepeats");
|
| + if (repeat_count > kNumberOfFixedRepeat) {
|
| + sink_->Put(kVariableRepeat, "VariableRepeat");
|
| + sink_->PutInt(repeat_count, "repeat count");
|
| } else {
|
| - sink_->Put(CodeForRepeats(repeat_count), "SerializeRepeats");
|
| + sink_->Put(kFixedRepeatStart + repeat_count, "FixedRepeat");
|
| }
|
| } else {
|
| serializer_->SerializeObject(
|
| @@ -1997,17 +1946,15 @@ int Serializer::ObjectSerializer::OutputRawData(
|
| code_has_been_output_ = true;
|
| }
|
| if (bytes_to_output != 0 && (!is_code_object_ || outputting_code)) {
|
| -#define RAW_CASE(index) \
|
| - if (!outputting_code && bytes_to_output == index * kPointerSize && \
|
| - index * kPointerSize == to_skip) { \
|
| - sink_->PutSection(kRawData + index, "RawDataFixed"); \
|
| - to_skip = 0; /* This insn already skips. */ \
|
| - } else /* NOLINT */
|
| - COMMON_RAW_LENGTHS(RAW_CASE)
|
| -#undef RAW_CASE
|
| - { /* NOLINT */
|
| + if (!outputting_code && bytes_to_output == to_skip &&
|
| + IsAligned(bytes_to_output, kPointerAlignment) &&
|
| + bytes_to_output <= kNumberOfFixedRawData * kPointerSize) {
|
| + int size_in_words = bytes_to_output >> kPointerSizeLog2;
|
| + sink_->PutSection(kFixedRawDataStart + size_in_words, "FixedRawData");
|
| + to_skip = 0; // This instruction includes skip.
|
| + } else {
|
| // We always end up here if we are outputting the code of a code object.
|
| - sink_->Put(kRawData, "RawData");
|
| + sink_->Put(kVariableRawData, "VariableRawData");
|
| sink_->PutInt(bytes_to_output, "length");
|
| }
|
|
|
|
|