[builtins] Add embedded stats to --serialization-statistics

This adds the option to output statistics about the embedded blob.

On x64 release, the output is currently:

Total size:                         724064
Metadata size:                      6832
Instruction size:                   703427
Padding:                            13805
Embedded builtin count:             852
Instruction size (50th percentile): 222
Instruction size (75th percentile): 749
Instruction size (90th percentile): 1871
Instruction size (99th percentile): 9171

Total size is added to our Memory benchmark.

Drive-by: Fix startup / context regexps for Memory benchmark.

Bug: v8:6666, v8:7898
Change-Id: I90d4458877939d3b48593bd9dd3a33971fe78c44
Reviewed-on: https://chromium-review.googlesource.com/1126104
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Yang Guo <yangguo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54256}
This commit is contained in:
jgruber 2018-07-05 13:44:37 +02:00 committed by Commit Bot
parent 7822145ce6
commit a7dce4fbed
4 changed files with 65 additions and 5 deletions

View File

@ -450,6 +450,8 @@ EmbeddedData EmbeddedData::FromIsolate(Isolate* isolate) {
DCHECK_EQ(hash, d.CreateHash()); DCHECK_EQ(hash, d.CreateHash());
DCHECK_EQ(hash, d.Hash()); DCHECK_EQ(hash, d.Hash());
if (FLAG_serialization_statistics) d.PrintStatistics();
return d; return d;
} }
@ -488,6 +490,48 @@ uint32_t Snapshot::ExtractNumContexts(const v8::StartupData* data) {
return num_contexts; return num_contexts;
} }
void EmbeddedData::PrintStatistics() const {
DCHECK(FLAG_serialization_statistics);
constexpr int kCount = Builtins::builtin_count;
int embedded_count = 0;
int instruction_size = 0;
int sizes[kCount];
for (int i = 0; i < kCount; i++) {
if (!Builtins::IsIsolateIndependent(i)) continue;
const int size = InstructionSizeOfBuiltin(i);
instruction_size += size;
sizes[embedded_count] = size;
embedded_count++;
}
// Sort for percentiles.
std::sort(&sizes[0], &sizes[embedded_count]);
const int k50th = embedded_count * 0.5;
const int k75th = embedded_count * 0.75;
const int k90th = embedded_count * 0.90;
const int k99th = embedded_count * 0.99;
const int metadata_size =
static_cast<int>(HashSize() + OffsetsSize() + LengthsSize());
PrintF("EmbeddedData:\n");
PrintF(" Total size: %d\n",
static_cast<int>(size()));
PrintF(" Metadata size: %d\n", metadata_size);
PrintF(" Instruction size: %d\n", instruction_size);
PrintF(" Padding: %d\n",
static_cast<int>(size() - metadata_size - instruction_size));
PrintF(" Embedded builtin count: %d\n", embedded_count);
PrintF(" Instruction size (50th percentile): %d\n", sizes[k50th]);
PrintF(" Instruction size (75th percentile): %d\n", sizes[k75th]);
PrintF(" Instruction size (90th percentile): %d\n", sizes[k90th]);
PrintF(" Instruction size (99th percentile): %d\n", sizes[k99th]);
PrintF("\n");
}
uint32_t Snapshot::ExtractContextOffset(const v8::StartupData* data, uint32_t Snapshot::ExtractContextOffset(const v8::StartupData* data,
uint32_t index) { uint32_t index) {
// Extract the offset of the context at a given index from the StartupData, // Extract the offset of the context at a given index from the StartupData,

View File

@ -139,6 +139,8 @@ class EmbeddedData final {
} }
const uint8_t* RawData() const { return data_ + RawDataOffset(); } const uint8_t* RawData() const { return data_ + RawDataOffset(); }
void PrintStatistics() const;
const uint8_t* data_; const uint8_t* data_;
uint32_t size_; uint32_t size_;
}; };

View File

@ -3548,11 +3548,21 @@ UNINITIALIZED_TEST(ReinitializeHashSeedRehashable) {
delete[] blob.data; delete[] blob.data;
} }
TEST(SerializationMemoryStats) { TEST(SerializationStats) {
FLAG_profile_deserialization = true; FLAG_profile_deserialization = true;
FLAG_always_opt = false; FLAG_always_opt = false;
v8::StartupData blob = CreateSnapshotDataBlob(); v8::StartupData blob = CreateSnapshotDataBlob();
delete[] blob.data; delete[] blob.data;
// Track the embedded blob size as well.
{
int embedded_blob_size = 0;
if (FLAG_embedded_builtins) {
i::EmbeddedData d = i::EmbeddedData::FromBlob();
embedded_blob_size = static_cast<int>(d.size());
}
PrintF("Embedded blob is %d bytes\n", embedded_blob_size);
}
} }
void CheckSFIsAreWeak(WeakFixedArray* sfis, Isolate* isolate) { void CheckSFIsAreWeak(WeakFixedArray* sfis, Isolate* isolate) {

View File

@ -1,11 +1,11 @@
{ {
"owners": ["yangguo@chromium.org"], "owners": ["yangguo@chromium.org", "jgruber@chromium.org"],
"name": "Memory", "name": "Memory",
"run_count": 5, "run_count": 5,
"units": "bytes", "units": "bytes",
"path" : ["."], "path" : ["."],
"binary": "cctest", "binary": "cctest",
"main": "test-serialize/SerializationMemoryStats", "main": "test-serialize/SerializationStats",
"tests": [ "tests": [
{ {
"name": "ReservedMemoryIsolate", "name": "ReservedMemoryIsolate",
@ -17,7 +17,7 @@
}, },
{ {
"name": "SnapshotSizeStartup", "name": "SnapshotSizeStartup",
"results_regexp": "(\\d+) bytes for startup$" "results_regexp": "(\\d+) bytes in \\d+ chunks for startup$"
}, },
{ {
"name": "SnapshotSizeBuiltins", "name": "SnapshotSizeBuiltins",
@ -25,7 +25,7 @@
}, },
{ {
"name": "SnapshotSizeContext", "name": "SnapshotSizeContext",
"results_regexp": "(\\d+) bytes for context #0$" "results_regexp": "(\\d+) bytes in \\d+ chunks for context #0$"
}, },
{ {
"name": "DeserializationTimeIsolate", "name": "DeserializationTimeIsolate",
@ -34,6 +34,10 @@
{ {
"name": "DeserializationTimeContext", "name": "DeserializationTimeContext",
"results_regexp": "\\[Deserializing context #0 \\(\\d+ bytes\\) took ([\\d.]+) ms\\]" "results_regexp": "\\[Deserializing context #0 \\(\\d+ bytes\\) took ([\\d.]+) ms\\]"
},
{
"name": "EmbeddedBuiltinsSize",
"results_regexp": "^Embedded blob is (\\d+) bytes$"
} }
] ]
} }