| Index: src/serialize.cc
|
| ===================================================================
|
| --- src/serialize.cc (revision 9713)
|
| +++ src/serialize.cc (working copy)
|
| @@ -318,10 +318,10 @@
|
|
|
|
|
| // Miscellaneous
|
| - Add(ExternalReference::roots_address(isolate).address(),
|
| + Add(ExternalReference::roots_array_start(isolate).address(),
|
| UNCLASSIFIED,
|
| 3,
|
| - "Heap::roots_address()");
|
| + "Heap::roots_array_start()");
|
| Add(ExternalReference::address_of_stack_limit(isolate).address(),
|
| UNCLASSIFIED,
|
| 4,
|
| @@ -784,7 +784,7 @@
|
| ReadObject(space_number, dest_space, &new_object); \
|
| } else if (where == kRootArray) { \
|
| int root_id = source_->GetInt(); \
|
| - new_object = isolate->heap()->roots_address()[root_id]; \
|
| + new_object = isolate->heap()->roots_array_start()[root_id]; \
|
| } else if (where == kPartialSnapshotCache) { \
|
| int cache_index = source_->GetInt(); \
|
| new_object = isolate->serialize_partial_snapshot_cache() \
|
| @@ -883,12 +883,18 @@
|
| CASE_STATEMENT(where, how, within, kLargeCode) \
|
| CASE_BODY(where, how, within, kLargeCode, 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)
|
| +#define FOUR_CASES(byte_code) \
|
| + case byte_code: \
|
| + case byte_code + 1: \
|
| + case byte_code + 2: \
|
| + case byte_code + 3:
|
|
|
| +#define SIXTEEN_CASES(byte_code) \
|
| + FOUR_CASES(byte_code) \
|
| + FOUR_CASES(byte_code + 4) \
|
| + FOUR_CASES(byte_code + 8) \
|
| + FOUR_CASES(byte_code + 12)
|
| +
|
| // 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) \
|
| @@ -911,6 +917,32 @@
|
| break;
|
| }
|
|
|
| + SIXTEEN_CASES(kRootArrayLowConstants)
|
| + SIXTEEN_CASES(kRootArrayHighConstants) {
|
| + int root_id = RootArrayConstantFromByteCode(data);
|
| + *current++ = isolate->heap()->roots_array_start()[root_id];
|
| + break;
|
| + }
|
| +
|
| + case kRepeat: {
|
| + int repeats = source_->GetInt();
|
| + Object* object = current[-1];
|
| + for (int i = 0; i < repeats; i++) current[i] = object;
|
| + current += repeats;
|
| + break;
|
| + }
|
| +
|
| + STATIC_ASSERT(kMaxRepeats == 12);
|
| + FOUR_CASES(kConstantRepeat)
|
| + FOUR_CASES(kConstantRepeat + 4)
|
| + FOUR_CASES(kConstantRepeat + 8) {
|
| + int repeats = RepeatsForCode(data);
|
| + Object* object = current[-1];
|
| + for (int i = 0; i < repeats; i++) current[i] = object;
|
| + current += repeats;
|
| + break;
|
| + }
|
| +
|
| // Deserialize a new object and write a pointer to it to the current
|
| // object.
|
| ONE_PER_SPACE(kNewObject, kPlain, kStartOfObject)
|
| @@ -936,9 +968,6 @@
|
| // 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)
|
| @@ -980,7 +1009,6 @@
|
| #undef CASE_BODY
|
| #undef ONE_PER_SPACE
|
| #undef ALL_SPACES
|
| -#undef EMIT_COMMON_REFERENCE_PATTERNS
|
| #undef ASSIGN_DEST_SPACE
|
|
|
| case kNewPage: {
|
| @@ -1067,7 +1095,8 @@
|
| : sink_(sink),
|
| current_root_index_(0),
|
| external_reference_encoder_(new ExternalReferenceEncoder),
|
| - large_object_total_(0) {
|
| + large_object_total_(0),
|
| + root_index_wave_front_(0) {
|
| // The serializer is meant to be used only to generate initial heap images
|
| // from a context in which there is only one isolate.
|
| ASSERT(Isolate::Current()->IsDefaultIsolate());
|
| @@ -1124,6 +1153,9 @@
|
| Isolate* isolate = Isolate::Current();
|
|
|
| for (Object** current = start; current < end; current++) {
|
| + if (start == isolate->heap()->roots_array_start()) {
|
| + root_index_wave_front_ = Max(root_index_wave_front_, current - start);
|
| + }
|
| if (reinterpret_cast<Address>(current) ==
|
| isolate->heap()->store_buffer()->TopAddress()) {
|
| sink_->Put(kSkip, "Skip");
|
| @@ -1191,10 +1223,12 @@
|
| }
|
|
|
|
|
| -int PartialSerializer::RootIndex(HeapObject* heap_object) {
|
| - for (int i = 0; i < Heap::kRootListLength; i++) {
|
| - Object* root = HEAP->roots_address()[i];
|
| - if (root == heap_object) return i;
|
| +int Serializer::RootIndex(HeapObject* heap_object) {
|
| + Heap* heap = HEAP;
|
| + if (heap->InNewSpace(heap_object)) return kInvalidRootIndex;
|
| + for (int i = 0; i < root_index_wave_front_; i++) {
|
| + Object* root = heap->roots_array_start()[i];
|
| + if (!root->IsSmi() && root == heap_object) return i;
|
| }
|
| return kInvalidRootIndex;
|
| }
|
| @@ -1230,18 +1264,8 @@
|
| // all objects) then we should shift out the bits that are always 0.
|
| if (!SpaceIsLarge(space)) address >>= kObjectAlignmentBits;
|
| 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");
|
| - }
|
| + sink_->Put(kFromStart + how_to_code + where_to_point + space, "RefSer");
|
| + sink_->PutInt(address, "address");
|
| } else {
|
| sink_->Put(kBackref + how_to_code + where_to_point + space, "BackRefSer");
|
| sink_->PutInt(address, "address");
|
| @@ -1256,6 +1280,12 @@
|
| CHECK(o->IsHeapObject());
|
| HeapObject* heap_object = HeapObject::cast(o);
|
|
|
| + int root_index;
|
| + if ((root_index = RootIndex(heap_object)) != kInvalidRootIndex) {
|
| + PutRoot(root_index, heap_object, how_to_code, where_to_point);
|
| + return;
|
| + }
|
| +
|
| if (address_mapper_.IsMapped(heap_object)) {
|
| int space = SpaceOfAlreadySerializedObject(heap_object);
|
| int address = address_mapper_.MappedTo(heap_object);
|
| @@ -1286,6 +1316,28 @@
|
| }
|
|
|
|
|
| +void Serializer::PutRoot(int root_index,
|
| + HeapObject* object,
|
| + SerializerDeserializer::HowToCode how_to_code,
|
| + SerializerDeserializer::WhereToPoint where_to_point) {
|
| + if (how_to_code == kPlain &&
|
| + where_to_point == kStartOfObject &&
|
| + root_index < kRootArrayNumberOfConstantEncodings &&
|
| + !HEAP->InNewSpace(object)) {
|
| + if (root_index < kRootArrayNumberOfLowConstantEncodings) {
|
| + sink_->Put(kRootArrayLowConstants + root_index, "RootLoConstant");
|
| + } else {
|
| + sink_->Put(kRootArrayHighConstants + root_index -
|
| + kRootArrayNumberOfLowConstantEncodings,
|
| + "RootHiConstant");
|
| + }
|
| + } else {
|
| + sink_->Put(kRootArray + how_to_code + where_to_point, "RootSerialization");
|
| + sink_->PutInt(root_index, "root_index");
|
| + }
|
| +}
|
| +
|
| +
|
| void PartialSerializer::SerializeObject(
|
| Object* o,
|
| HowToCode how_to_code,
|
| @@ -1295,8 +1347,7 @@
|
|
|
| int root_index;
|
| if ((root_index = RootIndex(heap_object)) != kInvalidRootIndex) {
|
| - sink_->Put(kRootArray + how_to_code + where_to_point, "RootSerialization");
|
| - sink_->PutInt(root_index, "root_index");
|
| + PutRoot(root_index, heap_object, how_to_code, where_to_point);
|
| return;
|
| }
|
|
|
| @@ -1374,9 +1425,26 @@
|
| if (current < end) OutputRawData(reinterpret_cast<Address>(current));
|
|
|
| while (current < end && !(*current)->IsSmi()) {
|
| - serializer_->SerializeObject(*current, kPlain, kStartOfObject);
|
| - bytes_processed_so_far_ += kPointerSize;
|
| - current++;
|
| + if (current != start &&
|
| + current[0] == current[-1] &&
|
| + !HEAP->InNewSpace(*current)) {
|
| + int repeat_count = 1;
|
| + while (current < end - 1 && current[repeat_count] == current[0]) {
|
| + repeat_count++;
|
| + }
|
| + current += repeat_count;
|
| + bytes_processed_so_far_ += repeat_count * kPointerSize;
|
| + if (repeat_count > kMaxRepeats) {
|
| + sink_->Put(kRepeat, "SerializeRepeats");
|
| + sink_->PutInt(repeat_count, "SerializeRepeats");
|
| + } else {
|
| + sink_->Put(CodeForRepeats(repeat_count), "SerializeRepeats");
|
| + }
|
| + } else {
|
| + serializer_->SerializeObject(*current, kPlain, kStartOfObject);
|
| + bytes_processed_so_far_ += kPointerSize;
|
| + current++;
|
| + }
|
| }
|
| }
|
| }
|
|
|