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

Unified Diff: src/serialize.cc

Issue 780833002: Revert of Encode reservation meta data in the snapshot blob. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@snapshotformat
Patch Set: Created 6 years 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/snapshot.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/serialize.cc
diff --git a/src/serialize.cc b/src/serialize.cc
index f0bd68e659bc1a0377011bce6b544e2dcdc61ed5..e6aae7fe8de90260da6f3e1e1463ab3544de8cea 100644
--- a/src/serialize.cc
+++ b/src/serialize.cc
@@ -611,16 +611,12 @@
};
-void Deserializer::DecodeReservation(
- Vector<const SerializedData::Reservation> res) {
- DCHECK_EQ(0, reservations_[NEW_SPACE].length());
- STATIC_ASSERT(NEW_SPACE == 0);
- int current_space = NEW_SPACE;
- for (const auto& r : res) {
- reservations_[current_space].Add({r.chunk_size(), NULL, NULL});
- if (r.is_last()) current_space++;
- }
- DCHECK_EQ(kNumberOfSpaces, current_space);
+Deserializer::Deserializer(SnapshotByteSource* source)
+ : isolate_(NULL),
+ attached_objects_(NULL),
+ source_(source),
+ external_reference_decoder_(NULL),
+ deserialized_large_objects_(0) {
for (int i = 0; i < kNumberOfPreallocatedSpaces; i++) current_chunk_[i] = 0;
}
@@ -720,7 +716,7 @@
Deserializer::~Deserializer() {
// TODO(svenpanne) Re-enable this assertion when v8 initialization is fixed.
- // DCHECK(source_.AtEOF());
+ // DCHECK(source_->AtEOF());
if (external_reference_decoder_) {
delete external_reference_decoder_;
external_reference_decoder_ = NULL;
@@ -801,10 +797,10 @@
HeapObject* Deserializer::GetBackReferencedObject(int space) {
HeapObject* obj;
if (space == LO_SPACE) {
- uint32_t index = source_.GetInt();
+ uint32_t index = source_->GetInt();
obj = deserialized_large_objects_[index];
} else {
- BackReference back_reference(source_.GetInt());
+ BackReference back_reference(source_->GetInt());
DCHECK(space < kNumberOfPreallocatedSpaces);
uint32_t chunk_index = back_reference.chunk_index();
DCHECK_LE(chunk_index, current_chunk_[space]);
@@ -828,12 +824,12 @@
void Deserializer::ReadObject(int space_number, Object** write_back) {
Address address;
HeapObject* obj;
- int next_int = source_.GetInt();
+ int next_int = source_->GetInt();
bool double_align = false;
#ifndef V8_HOST_ARCH_64_BIT
double_align = next_int == kDoubleAlignmentSentinel;
- if (double_align) next_int = source_.GetInt();
+ if (double_align) next_int = source_->GetInt();
#endif
DCHECK_NE(kDoubleAlignmentSentinel, next_int);
@@ -850,7 +846,7 @@
Object** current = reinterpret_cast<Object**>(address);
Object** limit = current + (size >> kPointerSizeLog2);
if (FLAG_log_snapshot_positions) {
- LOG(isolate_, SnapshotPositionEvent(address, source_.position()));
+ LOG(isolate_, SnapshotPositionEvent(address, source_->position()));
}
ReadData(current, limit, space_number, address);
@@ -888,7 +884,7 @@
if (space_index == LO_SPACE) {
AlwaysAllocateScope scope(isolate_);
LargeObjectSpace* lo_space = isolate_->heap()->lo_space();
- Executability exec = static_cast<Executability>(source_.Get());
+ Executability exec = static_cast<Executability>(source_->Get());
AllocationResult result = lo_space->AllocateRaw(size, exec);
HeapObject* obj = HeapObject::cast(result.ToObjectChecked());
deserialized_large_objects_.Add(obj);
@@ -922,7 +918,7 @@
source_space != CODE_SPACE &&
source_space != OLD_DATA_SPACE);
while (current < limit) {
- byte data = source_.Get();
+ byte data = source_->Get();
switch (data) {
#define CASE_STATEMENT(where, how, within, space_number) \
case where + how + within + space_number: \
@@ -946,18 +942,18 @@
if (where == kNewObject) { \
ReadObject(space_number, &new_object); \
} else if (where == kRootArray) { \
- int root_id = source_.GetInt(); \
+ int root_id = source_->GetInt(); \
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(); \
+ 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 skip = source_.GetInt(); \
+ int skip = source_->GetInt(); \
current = reinterpret_cast<Object**>( \
reinterpret_cast<Address>(current) + skip); \
- int reference_id = source_.GetInt(); \
+ int reference_id = source_->GetInt(); \
Address address = external_reference_decoder_->Decode(reference_id); \
new_object = reinterpret_cast<Object*>(address); \
} else if (where == kBackref) { \
@@ -965,7 +961,7 @@
new_object = GetBackReferencedObject(data & kSpaceMask); \
} else if (where == kBuiltin) { \
DCHECK(deserializing_user_code()); \
- int builtin_id = source_.GetInt(); \
+ int builtin_id = source_->GetInt(); \
DCHECK_LE(0, builtin_id); \
DCHECK_LT(builtin_id, Builtins::builtin_count); \
Builtins::Name name = static_cast<Builtins::Name>(builtin_id); \
@@ -973,12 +969,12 @@
emit_write_barrier = false; \
} else if (where == kAttachedReference) { \
DCHECK(deserializing_user_code()); \
- int index = source_.GetInt(); \
+ int index = source_->GetInt(); \
new_object = *attached_objects_->at(index); \
emit_write_barrier = isolate->heap()->InNewSpace(new_object); \
} else { \
DCHECK(where == kBackrefWithSkip); \
- int skip = source_.GetInt(); \
+ int skip = source_->GetInt(); \
current = reinterpret_cast<Object**>( \
reinterpret_cast<Address>(current) + skip); \
emit_write_barrier = (space_number == NEW_SPACE); \
@@ -1082,22 +1078,23 @@
// 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; \
- }
+#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();
+ int size = source_->GetInt();
byte* raw_data_out = reinterpret_cast<byte*>(current);
- source_.CopyRaw(raw_data_out, size);
+ source_->CopyRaw(raw_data_out, size);
break;
}
@@ -1113,7 +1110,7 @@
SIXTEEN_CASES(kRootArrayConstants + kHasSkipDistance)
SIXTEEN_CASES(kRootArrayConstants + kHasSkipDistance + 16) {
int root_id = RootArrayConstantFromByteCode(data);
- int skip = source_.GetInt();
+ int skip = source_->GetInt();
current = reinterpret_cast<Object**>(
reinterpret_cast<intptr_t>(current) + skip);
Object* object = isolate->heap()->roots_array_start()[root_id];
@@ -1123,7 +1120,7 @@
}
case kVariableRepeat: {
- int repeats = source_.GetInt();
+ int repeats = source_->GetInt();
Object* object = current[-1];
DCHECK(!isolate->heap()->InNewSpace(object));
for (int i = 0; i < repeats; i++) current[i] = object;
@@ -1243,14 +1240,14 @@
#undef ALL_SPACES
case kSkip: {
- int size = source_.GetInt();
+ int size = source_->GetInt();
current = reinterpret_cast<Object**>(
reinterpret_cast<intptr_t>(current) + size);
break;
}
case kNativesStringResource: {
- int index = source_.Get();
+ int index = source_->Get();
Vector<const char> source_vector = Natives::GetRawScriptSource(index);
NativesExternalStringResource* resource =
new NativesExternalStringResource(isolate->bootstrapper(),
@@ -1261,7 +1258,7 @@
}
case kNextChunk: {
- int space = source_.Get();
+ int space = source_->Get();
DCHECK(space < kNumberOfPreallocatedSpaces);
int chunk_index = current_chunk_[space];
const Heap::Reservation& reservation = reservations_[space];
@@ -1276,7 +1273,7 @@
FOUR_CASES(kHotObjectWithSkip)
FOUR_CASES(kHotObjectWithSkip + 4) {
- int skip = source_.GetInt();
+ int skip = source_->GetInt();
current = reinterpret_cast<Object**>(
reinterpret_cast<Address>(current) + skip);
// Fall through.
@@ -1397,21 +1394,15 @@
}
-void Serializer::EncodeReservations(
- List<SerializedData::Reservation>* out) const {
+void Serializer::FinalizeAllocation() {
for (int i = 0; i < kNumberOfPreallocatedSpaces; i++) {
- for (int j = 0; j < completed_chunks_[i].length(); j++) {
- out->Add(SerializedData::Reservation(completed_chunks_[i][j]));
- }
-
+ // Complete the last pending chunk and if there are no completed chunks,
+ // make sure there is at least one empty chunk.
if (pending_chunk_[i] > 0 || completed_chunks_[i].length() == 0) {
- out->Add(SerializedData::Reservation(pending_chunk_[i]));
- }
- out->last().mark_as_last();
- }
-
- out->Add(SerializedData::Reservation(large_objects_total_size_));
- out->last().mark_as_last();
+ completed_chunks_[i].Add(pending_chunk_[i]);
+ pending_chunk_[i] = 0;
+ }
+ }
}
@@ -1727,7 +1718,7 @@
}
// Serialize string content.
- sink_->PutRaw(resource, content_size, "StringContent");
+ sink_->PutRaw(const_cast<byte*>(resource), content_size, "StringContent");
// Since the allocation size is rounded up to object alignment, there
// maybe left-over bytes that need to be padded.
@@ -2030,7 +2021,6 @@
sink_->Put(kNextChunk, "NextChunk");
sink_->Put(space, "NextChunkSpace");
completed_chunks_[space].Add(pending_chunk_[space]);
- DCHECK_LE(completed_chunks_[space].length(), BackReference::kMaxChunkIndex);
pending_chunk_[space] = 0;
new_chunk_size = size;
}
@@ -2075,8 +2065,16 @@
Object** location = Handle<Object>::cast(info).location();
cs.VisitPointer(location);
cs.Pad();
-
- SerializedCodeData data(sink.data(), cs);
+ cs.FinalizeAllocation();
+
+ for (int i = 0; i < kNumberOfPreallocatedSpaces; i++) {
+ // Fail if any chunk index exceeds the limit.
+ if (cs.FinalAllocationChunks(i).length() > BackReference::kMaxChunkIndex) {
+ return NULL;
+ }
+ }
+
+ SerializedCodeData data(sink.data(), &cs);
ScriptData* script_data = data.GetScriptData();
if (FLAG_profile_deserialization) {
@@ -2277,10 +2275,22 @@
DCHECK(cached_data->rejected());
return MaybeHandle<SharedFunctionInfo>();
}
+ SnapshotByteSource payload(scd->Payload(), scd->PayloadLength());
+ Deserializer deserializer(&payload);
// Eagerly expand string table to avoid allocations during deserialization.
StringTable::EnsureCapacityForDeserialization(
isolate, scd->NumInternalizedStrings());
+
+ // Set reservations.
+ STATIC_ASSERT(NEW_SPACE == 0);
+ int current_space = NEW_SPACE;
+ Vector<const SerializedCodeData::Reservation> res = scd->Reservations();
+ for (const auto& r : res) {
+ deserializer.AddReservation(current_space, r.chunk_size());
+ if (r.is_last_chunk()) current_space++;
+ }
+ DCHECK_EQ(kNumberOfSpaces, current_space);
// Prepare and register list of attached objects.
Vector<const uint32_t> code_stub_keys = scd->CodeStubKeys();
@@ -2291,8 +2301,6 @@
attached_objects[i + kCodeStubsBaseIndex] =
CodeStub::GetCode(isolate, code_stub_keys[i]).ToHandleChecked();
}
-
- Deserializer deserializer(scd.get());
deserializer.SetAttachedObjects(&attached_objects);
// Deserialize.
@@ -2328,152 +2336,65 @@
}
-void SerializedData::AllocateData(int size) {
- DCHECK(!owns_data_);
- data_ = NewArray<byte>(size);
- size_ = size;
- owns_data_ = true;
- DCHECK(IsAligned(reinterpret_cast<intptr_t>(data_), kPointerAlignment));
-}
-
-
-SnapshotData::SnapshotData(const SnapshotByteSink& sink,
- const Serializer& ser) {
+SerializedCodeData::SerializedCodeData(const List<byte>& payload,
+ CodeSerializer* cs)
+ : script_data_(NULL), owns_script_data_(true) {
DisallowHeapAllocation no_gc;
- List<Reservation> reservations;
- ser.EncodeReservations(&reservations);
- const List<byte>& payload = sink.data();
-
- // Calculate sizes.
- int reservation_size = reservations.length() * kInt32Size;
- int size = kHeaderSize + reservation_size + payload.length();
-
- // Allocate backing store and create result data.
- AllocateData(size);
-
- // Set header values.
- SetHeaderValue(kCheckSumOffset, Version::Hash());
- SetHeaderValue(kReservationsOffset, reservations.length());
- SetHeaderValue(kPayloadLengthOffset, payload.length());
-
- // Copy reservation chunk sizes.
- CopyBytes(data_ + kHeaderSize, reinterpret_cast<byte*>(reservations.begin()),
- reservation_size);
-
- // Copy serialized data.
- CopyBytes(data_ + kHeaderSize + reservation_size, payload.begin(),
- static_cast<size_t>(payload.length()));
-}
-
-
-bool SnapshotData::IsSane() {
- return GetHeaderValue(kCheckSumOffset) == Version::Hash();
-}
-
-
-Vector<const SerializedData::Reservation> SnapshotData::Reservations() const {
- return Vector<const Reservation>(
- reinterpret_cast<const Reservation*>(data_ + kHeaderSize),
- GetHeaderValue(kReservationsOffset));
-}
-
-
-Vector<const byte> SnapshotData::Payload() const {
- int reservations_size = GetHeaderValue(kReservationsOffset) * kInt32Size;
- const byte* payload = data_ + kHeaderSize + reservations_size;
- int length = GetHeaderValue(kPayloadLengthOffset);
- DCHECK_EQ(data_ + size_, payload + length);
- return Vector<const byte>(payload, length);
-}
-
-
-SerializedCodeData::SerializedCodeData(const List<byte>& payload,
- const CodeSerializer& cs) {
- DisallowHeapAllocation no_gc;
- const List<uint32_t>* stub_keys = cs.stub_keys();
-
- List<Reservation> reservations;
- cs.EncodeReservations(&reservations);
+ List<uint32_t>* stub_keys = cs->stub_keys();
+
+ // Gather reservation chunk sizes.
+ List<uint32_t> reservations(SerializerDeserializer::kNumberOfSpaces);
+ STATIC_ASSERT(NEW_SPACE == 0);
+ for (int i = 0; i < SerializerDeserializer::kNumberOfSpaces; i++) {
+ Vector<const uint32_t> chunks = cs->FinalAllocationChunks(i);
+ for (int j = 0; j < chunks.length(); j++) {
+ uint32_t chunk = ChunkSizeBits::encode(chunks[j]) |
+ IsLastChunkBits::encode(j == chunks.length() - 1);
+ reservations.Add(chunk);
+ }
+ }
// Calculate sizes.
int reservation_size = reservations.length() * kInt32Size;
int num_stub_keys = stub_keys->length();
int stub_keys_size = stub_keys->length() * kInt32Size;
- int size = kHeaderSize + reservation_size + stub_keys_size + payload.length();
+ int data_length =
+ kHeaderSize + reservation_size + stub_keys_size + payload.length();
// Allocate backing store and create result data.
- AllocateData(size);
+ byte* data = NewArray<byte>(data_length);
+ DCHECK(IsAligned(reinterpret_cast<intptr_t>(data), kPointerAlignment));
+ script_data_ = new ScriptData(data, data_length);
+ script_data_->AcquireDataOwnership();
// Set header values.
- SetHeaderValue(kCheckSumOffset, CheckSum(cs.source()));
- SetHeaderValue(kNumInternalizedStringsOffset, cs.num_internalized_strings());
+ SetHeaderValue(kCheckSumOffset, CheckSum(cs->source()));
+ SetHeaderValue(kNumInternalizedStringsOffset, cs->num_internalized_strings());
SetHeaderValue(kReservationsOffset, reservations.length());
SetHeaderValue(kNumCodeStubKeysOffset, num_stub_keys);
SetHeaderValue(kPayloadLengthOffset, payload.length());
// Copy reservation chunk sizes.
- CopyBytes(data_ + kHeaderSize, reinterpret_cast<byte*>(reservations.begin()),
+ CopyBytes(data + kHeaderSize, reinterpret_cast<byte*>(reservations.begin()),
reservation_size);
// Copy code stub keys.
- CopyBytes(data_ + kHeaderSize + reservation_size,
+ CopyBytes(data + kHeaderSize + reservation_size,
reinterpret_cast<byte*>(stub_keys->begin()), stub_keys_size);
// Copy serialized data.
- CopyBytes(data_ + kHeaderSize + reservation_size + stub_keys_size,
+ CopyBytes(data + kHeaderSize + reservation_size + stub_keys_size,
payload.begin(), static_cast<size_t>(payload.length()));
}
bool SerializedCodeData::IsSane(String* source) {
return GetHeaderValue(kCheckSumOffset) == CheckSum(source) &&
- Payload().length() >= SharedFunctionInfo::kSize;
+ PayloadLength() >= SharedFunctionInfo::kSize;
}
int SerializedCodeData::CheckSum(String* string) {
return Version::Hash() ^ string->length();
}
-
-
-// Return ScriptData object and relinquish ownership over it to the caller.
-ScriptData* SerializedCodeData::GetScriptData() {
- DCHECK(owns_data_);
- ScriptData* result = new ScriptData(data_, size_);
- result->AcquireDataOwnership();
- owns_data_ = false;
- data_ = NULL;
- return result;
-}
-
-
-Vector<const SerializedData::Reservation> SerializedCodeData::Reservations()
- const {
- return Vector<const Reservation>(
- reinterpret_cast<const Reservation*>(data_ + kHeaderSize),
- GetHeaderValue(kReservationsOffset));
-}
-
-
-Vector<const byte> SerializedCodeData::Payload() const {
- int reservations_size = GetHeaderValue(kReservationsOffset) * kInt32Size;
- int code_stubs_size = GetHeaderValue(kNumCodeStubKeysOffset) * kInt32Size;
- const byte* payload =
- data_ + kHeaderSize + reservations_size + code_stubs_size;
- int length = GetHeaderValue(kPayloadLengthOffset);
- DCHECK_EQ(data_ + size_, payload + length);
- return Vector<const byte>(payload, length);
-}
-
-
-int SerializedCodeData::NumInternalizedStrings() const {
- return GetHeaderValue(kNumInternalizedStringsOffset);
-}
-
-Vector<const uint32_t> SerializedCodeData::CodeStubKeys() const {
- int reservations_size = GetHeaderValue(kReservationsOffset) * kInt32Size;
- const byte* start = data_ + kHeaderSize + reservations_size;
- return Vector<const uint32_t>(reinterpret_cast<const uint32_t*>(start),
- GetHeaderValue(kNumCodeStubKeysOffset));
-}
} } // namespace v8::internal
« no previous file with comments | « src/serialize.h ('k') | src/snapshot.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698