Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(956)

Unified Diff: src/serialize.cc

Issue 8344079: Shave 39% from snapshot size. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/serialize.h ('k') | src/x64/macro-assembler-x64.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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++;
+ }
}
}
}
« no previous file with comments | « src/serialize.h ('k') | src/x64/macro-assembler-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698