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

Unified Diff: src/snapshot/snapshot-common.cc

Issue 2055203002: [snapshot] support multiple contexts in the same snapshot. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@sinkmember
Patch Set: fix test. again. Created 4 years, 6 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/snapshot/snapshot.h ('k') | src/snapshot/startup-serializer.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/snapshot/snapshot-common.cc
diff --git a/src/snapshot/snapshot-common.cc b/src/snapshot/snapshot-common.cc
index 655563ccd9cafbf7aaf3d43aa5a91601376cec56..5eac4af6eeb08f42e75cdf2359bfa315f88d192b 100644
--- a/src/snapshot/snapshot-common.cc
+++ b/src/snapshot/snapshot-common.cc
@@ -18,8 +18,7 @@ namespace internal {
#ifdef DEBUG
bool Snapshot::SnapshotIsValid(v8::StartupData* snapshot_blob) {
- return !Snapshot::ExtractStartupData(snapshot_blob).is_empty() &&
- !Snapshot::ExtractContextData(snapshot_blob).is_empty();
+ return Snapshot::ExtractNumContexts(snapshot_blob) > 0;
}
#endif // DEBUG
@@ -61,15 +60,16 @@ bool Snapshot::Initialize(Isolate* isolate) {
return success;
}
-
MaybeHandle<Context> Snapshot::NewContextFromSnapshot(
- Isolate* isolate, Handle<JSGlobalProxy> global_proxy) {
+ Isolate* isolate, Handle<JSGlobalProxy> global_proxy,
+ size_t context_index) {
if (!isolate->snapshot_available()) return Handle<Context>();
base::ElapsedTimer timer;
if (FLAG_profile_deserialization) timer.Start();
const v8::StartupData* blob = isolate->snapshot_blob();
- Vector<const byte> context_data = ExtractContextData(blob);
+ Vector<const byte> context_data =
+ ExtractContextData(blob, static_cast<int>(context_index));
SnapshotData snapshot_data(context_data);
Deserializer deserializer(&snapshot_data);
@@ -81,133 +81,163 @@ MaybeHandle<Context> Snapshot::NewContextFromSnapshot(
if (FLAG_profile_deserialization) {
double ms = timer.Elapsed().InMillisecondsF();
int bytes = context_data.length();
- PrintF("[Deserializing context (%d bytes) took %0.3f ms]\n", bytes, ms);
+ PrintF("[Deserializing context #%zu (%d bytes) took %0.3f ms]\n",
+ context_index, bytes, ms);
}
return Handle<Context>::cast(result);
}
+void UpdateMaxRequirementPerPage(
+ uint32_t* requirements,
+ Vector<const SerializedData::Reservation> reservations) {
+ int space = 0;
+ uint32_t current_requirement = 0;
+ for (const auto& reservation : reservations) {
+ current_requirement += reservation.chunk_size();
+ if (reservation.is_last()) {
+ requirements[space] = std::max(requirements[space], current_requirement);
+ current_requirement = 0;
+ space++;
+ }
+ }
+ DCHECK_EQ(i::Serializer::kNumberOfSpaces, space);
+}
+
void CalculateFirstPageSizes(const SnapshotData* startup_snapshot,
- const SnapshotData* context_snapshot,
+ const List<SnapshotData*>* context_snapshots,
uint32_t* sizes_out) {
- Vector<const SerializedData::Reservation> startup_reservations =
- startup_snapshot->Reservations();
- Vector<const SerializedData::Reservation> context_reservations =
- context_snapshot->Reservations();
- int startup_index = 0;
- int context_index = 0;
-
if (FLAG_profile_deserialization) {
int startup_total = 0;
- int context_total = 0;
- for (const auto& reservation : startup_reservations) {
+ PrintF("Deserialization will reserve:\n");
+ for (const auto& reservation : startup_snapshot->Reservations()) {
startup_total += reservation.chunk_size();
}
- for (const auto& reservation : context_reservations) {
- context_total += reservation.chunk_size();
+ PrintF("%10d bytes per isolate\n", startup_total);
+ for (int i = 0; i < context_snapshots->length(); i++) {
+ int context_total = 0;
+ for (const auto& reservation : context_snapshots->at(i)->Reservations()) {
+ context_total += reservation.chunk_size();
+ }
+ PrintF("%10d bytes per context #%d\n", context_total, i);
}
- PrintF(
- "Deserialization will reserve:\n"
- "%10d bytes per isolate\n"
- "%10d bytes per context\n",
- startup_total, context_total);
}
+ uint32_t startup_requirements[i::Serializer::kNumberOfSpaces];
+ uint32_t context_requirements[i::Serializer::kNumberOfSpaces];
for (int space = 0; space < i::Serializer::kNumberOfSpaces; space++) {
- bool single_chunk = true;
- while (!startup_reservations[startup_index].is_last()) {
- single_chunk = false;
- startup_index++;
- }
- while (!context_reservations[context_index].is_last()) {
- single_chunk = false;
- context_index++;
- }
+ startup_requirements[space] = 0;
+ context_requirements[space] = 0;
+ }
- uint32_t required = kMaxUInt32;
- if (single_chunk) {
- // If both the startup snapshot data and the context snapshot data on
- // this space fit in a single page, then we consider limiting the size
- // of the first page. For this, we add the chunk sizes and some extra
- // allowance. This way we achieve a smaller startup memory footprint.
- required = (startup_reservations[startup_index].chunk_size() +
- 2 * context_reservations[context_index].chunk_size()) +
- Page::kObjectStartOffset;
- // Add a small allowance to the code space for small scripts.
- if (space == CODE_SPACE) required += 32 * KB;
- }
+ UpdateMaxRequirementPerPage(startup_requirements,
+ startup_snapshot->Reservations());
+ for (const auto& context_snapshot : *context_snapshots) {
+ UpdateMaxRequirementPerPage(context_requirements,
+ context_snapshot->Reservations());
+ }
+
+ for (int space = 0; space < i::Serializer::kNumberOfSpaces; space++) {
+ // If the space requirement for a page is less than a page size, we consider
+ // limiting the size of the first page in order to save memory on startup.
+ uint32_t required = startup_requirements[space] +
+ 2 * context_requirements[space] +
+ Page::kObjectStartOffset;
+ // Add a small allowance to the code space for small scripts.
+ if (space == CODE_SPACE) required += 32 * KB;
if (space >= FIRST_PAGED_SPACE && space <= LAST_PAGED_SPACE) {
uint32_t max_size =
MemoryAllocator::PageAreaSize(static_cast<AllocationSpace>(space));
- sizes_out[space - FIRST_PAGED_SPACE] = Min(required, max_size);
- } else {
- DCHECK(single_chunk);
+ sizes_out[space - FIRST_PAGED_SPACE] = std::min(required, max_size);
}
- startup_index++;
- context_index++;
}
-
- DCHECK_EQ(startup_reservations.length(), startup_index);
- DCHECK_EQ(context_reservations.length(), context_index);
}
v8::StartupData Snapshot::CreateSnapshotBlob(
- const StartupSerializer* startup_serializer,
- const PartialSerializer* context_serializer) {
- SnapshotData startup_snapshot(startup_serializer);
- SnapshotData context_snapshot(context_serializer);
- Vector<const byte> startup_data = startup_snapshot.RawData();
- Vector<const byte> context_data = context_snapshot.RawData();
+ const SnapshotData* startup_snapshot,
+ const List<SnapshotData*>* context_snapshots) {
+ int num_contexts = context_snapshots->length();
+ int startup_snapshot_offset = StartupSnapshotOffset(num_contexts);
+ int total_length = startup_snapshot_offset;
+ total_length += startup_snapshot->RawData().length();
+ for (const auto& context_snapshot : *context_snapshots) {
+ total_length += context_snapshot->RawData().length();
+ }
uint32_t first_page_sizes[kNumPagedSpaces];
-
- CalculateFirstPageSizes(&startup_snapshot, &context_snapshot,
+ CalculateFirstPageSizes(startup_snapshot, context_snapshots,
first_page_sizes);
- int startup_length = startup_data.length();
- int context_length = context_data.length();
- int context_offset = ContextOffset(startup_length);
-
- int length = context_offset + context_length;
- char* data = new char[length];
-
+ char* data = new char[total_length];
memcpy(data + kFirstPageSizesOffset, first_page_sizes,
kNumPagedSpaces * kInt32Size);
- memcpy(data + kStartupLengthOffset, &startup_length, kInt32Size);
- memcpy(data + kStartupDataOffset, startup_data.begin(), startup_length);
- memcpy(data + context_offset, context_data.begin(), context_length);
- v8::StartupData result = {data, length};
-
+ memcpy(data + kNumberOfContextsOffset, &num_contexts, kInt32Size);
+ int payload_offset = StartupSnapshotOffset(num_contexts);
+ int payload_length = startup_snapshot->RawData().length();
+ memcpy(data + payload_offset, startup_snapshot->RawData().start(),
+ payload_length);
if (FLAG_profile_deserialization) {
- PrintF(
- "Snapshot blob consists of:\n"
- "%10d bytes for startup\n"
- "%10d bytes for context\n",
- startup_length, context_length);
+ PrintF("Snapshot blob consists of:\n%10d bytes for startup\n",
+ payload_length);
}
+ payload_offset += payload_length;
+ for (int i = 0; i < num_contexts; i++) {
+ memcpy(data + ContextSnapshotOffsetOffset(i), &payload_offset, kInt32Size);
+ SnapshotData* context_snapshot = context_snapshots->at(i);
+ payload_length = context_snapshot->RawData().length();
+ memcpy(data + payload_offset, context_snapshot->RawData().start(),
+ payload_length);
+ if (FLAG_profile_deserialization) {
+ PrintF("%10d bytes for context #%d\n", payload_length, i);
+ }
+ payload_offset += payload_length;
+ }
+
+ v8::StartupData result = {data, total_length};
return result;
}
+int Snapshot::ExtractNumContexts(const v8::StartupData* data) {
+ CHECK_LT(kNumberOfContextsOffset, data->raw_size);
+ int num_contexts;
+ memcpy(&num_contexts, data->data + kNumberOfContextsOffset, kInt32Size);
+ return num_contexts;
+}
+
Vector<const byte> Snapshot::ExtractStartupData(const v8::StartupData* data) {
- DCHECK_LT(kIntSize, data->raw_size);
- int startup_length;
- memcpy(&startup_length, data->data + kStartupLengthOffset, kInt32Size);
- DCHECK_LT(startup_length, data->raw_size);
+ int num_contexts = ExtractNumContexts(data);
+ int startup_offset = StartupSnapshotOffset(num_contexts);
+ CHECK_LT(startup_offset, data->raw_size);
+ int first_context_offset;
+ memcpy(&first_context_offset, data->data + ContextSnapshotOffsetOffset(0),
+ kInt32Size);
+ CHECK_LT(first_context_offset, data->raw_size);
+ int startup_length = first_context_offset - startup_offset;
const byte* startup_data =
- reinterpret_cast<const byte*>(data->data + kStartupDataOffset);
+ reinterpret_cast<const byte*>(data->data + startup_offset);
return Vector<const byte>(startup_data, startup_length);
}
+Vector<const byte> Snapshot::ExtractContextData(const v8::StartupData* data,
+ int index) {
+ int num_contexts = ExtractNumContexts(data);
+ CHECK_LT(index, num_contexts);
+
+ int context_offset;
+ memcpy(&context_offset, data->data + ContextSnapshotOffsetOffset(index),
+ kInt32Size);
+ int next_context_offset;
+ if (index == num_contexts - 1) {
+ next_context_offset = data->raw_size;
+ } else {
+ memcpy(&next_context_offset,
+ data->data + ContextSnapshotOffsetOffset(index + 1), kInt32Size);
+ CHECK_LT(next_context_offset, data->raw_size);
+ }
-Vector<const byte> Snapshot::ExtractContextData(const v8::StartupData* data) {
- DCHECK_LT(kIntSize, data->raw_size);
- int startup_length;
- memcpy(&startup_length, data->data + kStartupLengthOffset, kIntSize);
- int context_offset = ContextOffset(startup_length);
const byte* context_data =
reinterpret_cast<const byte*>(data->data + context_offset);
- DCHECK_LT(context_offset, data->raw_size);
- int context_length = data->raw_size - context_offset;
+ int context_length = next_context_offset - context_offset;
return Vector<const byte>(context_data, context_length);
}
« no previous file with comments | « src/snapshot/snapshot.h ('k') | src/snapshot/startup-serializer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698