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

Unified Diff: src/serialize.cc

Issue 8404030: Version 3.7.1 (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
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/spaces.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 9808)
+++ 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,
@@ -490,6 +490,10 @@
UNCLASSIFIED,
44,
"canonical_nan");
+ Add(ExternalReference::address_of_the_hole_nan().address(),
+ UNCLASSIFIED,
+ 45,
+ "the_hole_nan");
}
@@ -753,8 +757,13 @@
void Deserializer::ReadChunk(Object** current,
Object** limit,
int source_space,
- Address address) {
+ Address current_object_address) {
Isolate* const isolate = isolate_;
+ bool write_barrier_needed = (current_object_address != NULL &&
+ source_space != NEW_SPACE &&
+ source_space != CELL_SPACE &&
+ source_space != CODE_SPACE &&
+ source_space != OLD_DATA_SPACE);
while (current < limit) {
int data = source_->Get();
switch (data) {
@@ -774,9 +783,7 @@
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 && \
- source_space != CELL_SPACE); \
+ emit_write_barrier = (space_number == NEW_SPACE); \
} else { \
Object* new_object = NULL; /* May not be a real Object pointer. */ \
if (where == kNewObject) { \
@@ -784,27 +791,25 @@
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]; \
+ emit_write_barrier = isolate->heap()->InNewSpace(new_object); \
} else if (where == kPartialSnapshotCache) { \
int cache_index = source_->GetInt(); \
new_object = isolate->serialize_partial_snapshot_cache() \
[cache_index]; \
+ emit_write_barrier = isolate->heap()->InNewSpace(new_object); \
} 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 && \
- source_space != CELL_SPACE); \
+ emit_write_barrier = (space_number == 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 && \
- source_space != CELL_SPACE); \
+ emit_write_barrier = (space_number == NEW_SPACE); \
new_object = GetAddressFromStart(data & kSpaceMask); \
} else { \
Address object_address = pages_[space_number][0] + \
@@ -831,12 +836,14 @@
*current = new_object; \
} \
} \
- if (emit_write_barrier) { \
- isolate->heap()->RecordWrite(address, static_cast<int>( \
- reinterpret_cast<Address>(current) - address)); \
+ if (emit_write_barrier && write_barrier_needed) { \
+ Address current_address = reinterpret_cast<Address>(current); \
+ isolate->heap()->RecordWrite( \
+ current_object_address, \
+ static_cast<int>(current_address - current_object_address)); \
} \
if (!current_was_incremented) { \
- current++; /* Increment current if it wasn't done above. */ \
+ current++; \
} \
break; \
} \
@@ -883,12 +890,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 +924,38 @@
break;
}
+ SIXTEEN_CASES(kRootArrayLowConstants)
+ SIXTEEN_CASES(kRootArrayHighConstants) {
+ int root_id = RootArrayConstantFromByteCode(data);
+ Object* object = isolate->heap()->roots_array_start()[root_id];
+ ASSERT(!isolate->heap()->InNewSpace(object));
+ *current++ = object;
+ break;
+ }
+
+ case kRepeat: {
+ int repeats = source_->GetInt();
+ Object* object = current[-1];
+ ASSERT(!isolate->heap()->InNewSpace(object));
+ for (int i = 0; i < repeats; i++) current[i] = object;
+ current += repeats;
+ break;
+ }
+
+ STATIC_ASSERT(kRootArrayNumberOfConstantEncodings ==
+ Heap::kOldSpaceRoots);
+ STATIC_ASSERT(kMaxRepeats == 12);
+ FOUR_CASES(kConstantRepeat)
+ FOUR_CASES(kConstantRepeat + 4)
+ FOUR_CASES(kConstantRepeat + 8) {
+ int repeats = RepeatsForCode(data);
+ Object* object = current[-1];
+ ASSERT(!isolate->heap()->InNewSpace(object));
+ 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 +981,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 +1022,6 @@
#undef CASE_BODY
#undef ONE_PER_SPACE
#undef ALL_SPACES
-#undef EMIT_COMMON_REFERENCE_PATTERNS
#undef ASSIGN_DEST_SPACE
case kNewPage: {
@@ -1067,7 +1108,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 +1166,10 @@
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_, static_cast<intptr_t>(current - start));
+ }
if (reinterpret_cast<Address>(current) ==
isolate->heap()->store_buffer()->TopAddress()) {
sink_->Put(kSkip, "Skip");
@@ -1191,10 +1237,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 +1278,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 +1294,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 +1330,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 +1361,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 +1439,33 @@
if (current < end) OutputRawData(reinterpret_cast<Address>(current));
while (current < end && !(*current)->IsSmi()) {
- serializer_->SerializeObject(*current, kPlain, kStartOfObject);
- bytes_processed_so_far_ += kPointerSize;
- current++;
+ HeapObject* current_contents = HeapObject::cast(*current);
+ int root_index = serializer_->RootIndex(current_contents);
+ // Repeats are not subject to the write barrier so there are only some
+ // objects that can be used in a repeat encoding. These are the early
+ // ones in the root array that are never in new space.
+ if (current != start &&
+ root_index != kInvalidRootIndex &&
+ root_index < kRootArrayNumberOfConstantEncodings &&
+ current_contents == current[-1]) {
+ ASSERT(!HEAP->InNewSpace(current_contents));
+ int repeat_count = 1;
+ while (current < end - 1 && current[repeat_count] == current_contents) {
+ 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_contents, kPlain, kStartOfObject);
+ bytes_processed_so_far_ += kPointerSize;
+ current++;
+ }
}
}
}
« no previous file with comments | « src/serialize.h ('k') | src/spaces.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698