[perf] Refactor the Memory benchmark to use d8

Until this CL, the Memory benchmark was the only one to be based on a
cctest runner; all others use d8. Besides being a tedious exception to
the rule, this caused issues such as described in the linked bug
(summary: refbuilds are built with v8_static_library, and neither
cctests nor unittests support this configuration).

Here, we move the Memory benchmark into a d8 runner.

Bug: v8:9189, chromium:957029
Change-Id: I9b45ff36f4842cb0bdef2c1c4b0184c5509d3385
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1588464
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Sigurd Schneider <sigurds@chromium.org>
Reviewed-by: Michael Achenbach <machenbach@chromium.org>
Reviewed-by: Sergiy Belozorov <sergiyb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#61245}
This commit is contained in:
Jakob Gruber 2019-04-30 14:43:23 +02:00 committed by Commit Bot
parent ec379ea8a8
commit 226b58341e
7 changed files with 116 additions and 53 deletions

View File

@ -823,5 +823,35 @@ RUNTIME_FUNCTION(Runtime_PerformSideEffectCheckForObject) {
return ReadOnlyRoots(isolate).undefined_value();
}
RUNTIME_FUNCTION(Runtime_ProfileCreateSnapshotDataBlob) {
HandleScope scope(isolate);
DCHECK_EQ(0, args.length());
// Used only by the test/memory/Memory.json benchmark. This creates a snapshot
// blob and outputs various statistics around it.
DCHECK(FLAG_profile_deserialization);
DisableEmbeddedBlobRefcounting();
v8::StartupData blob = CreateSnapshotDataBlobInternal(
v8::SnapshotCreator::FunctionCodeHandling::kClear, nullptr);
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);
}
FreeCurrentEmbeddedBlob();
return ReadOnlyRoots(isolate).undefined_value();
}
} // namespace internal
} // namespace v8

View File

@ -119,6 +119,9 @@ namespace internal {
#define FOR_EACH_INTRINSIC_DEBUG(F, I) \
F(ClearStepping, 0, 1) \
F(CollectGarbage, 1, 1) \
F(DebugAsyncFunctionEntered, 1, 1) \
F(DebugAsyncFunctionFinished, 2, 1) \
F(DebugAsyncFunctionSuspended, 1, 1) \
F(DebugBreakAtEntry, 1, 1) \
F(DebugCollectCoverage, 0, 1) \
F(DebugGetLoadedScriptIds, 0, 1) \
@ -126,9 +129,6 @@ namespace internal {
F(DebugPopPromise, 0, 1) \
F(DebugPrepareStepInSuspendedGenerator, 0, 1) \
F(DebugPushPromise, 1, 1) \
F(DebugAsyncFunctionEntered, 1, 1) \
F(DebugAsyncFunctionFinished, 2, 1) \
F(DebugAsyncFunctionSuspended, 1, 1) \
F(DebugToggleBlockCoverage, 1, 1) \
F(DebugTogglePreciseCoverage, 1, 1) \
F(FunctionGetInferredName, 1, 1) \
@ -137,12 +137,13 @@ namespace internal {
F(GetGeneratorScopeDetails, 2, 1) \
F(GetHeapUsage, 0, 1) \
F(HandleDebuggerStatement, 0, 1) \
I(IncBlockCounter, 2, 1) \
F(IsBreakOnException, 1, 1) \
F(LiveEditPatchScript, 2, 1) \
F(ProfileCreateSnapshotDataBlob, 0, 1) \
F(ScheduleBreak, 0, 1) \
F(ScriptLocationFromLine2, 4, 1) \
F(SetGeneratorScopeVariableValue, 4, 1) \
F(LiveEditPatchScript, 2, 1)
I(IncBlockCounter, 2, 1)
#define FOR_EACH_INTRINSIC_FORIN(F, I) \
F(ForInEnumerate, 1, 1) \

View File

@ -354,5 +354,56 @@ Vector<const byte> SnapshotData::Payload() const {
return Vector<const byte>(payload, length);
}
namespace {
bool RunExtraCode(v8::Isolate* isolate, v8::Local<v8::Context> context,
const char* utf8_source, const char* name) {
v8::Context::Scope context_scope(context);
v8::TryCatch try_catch(isolate);
v8::Local<v8::String> source_string;
if (!v8::String::NewFromUtf8(isolate, utf8_source, v8::NewStringType::kNormal)
.ToLocal(&source_string)) {
return false;
}
v8::Local<v8::String> resource_name =
v8::String::NewFromUtf8(isolate, name, v8::NewStringType::kNormal)
.ToLocalChecked();
v8::ScriptOrigin origin(resource_name);
v8::ScriptCompiler::Source source(source_string, origin);
v8::Local<v8::Script> script;
if (!v8::ScriptCompiler::Compile(context, &source).ToLocal(&script))
return false;
if (script->Run(context).IsEmpty()) return false;
CHECK(!try_catch.HasCaught());
return true;
}
} // namespace
// TODO(jgruber): Merge with related code in mksnapshot.cc and
// inspector-test.cc.
v8::StartupData CreateSnapshotDataBlobInternal(
v8::SnapshotCreator::FunctionCodeHandling function_code_handling,
const char* embedded_source) {
// Create a new isolate and a new context from scratch, optionally run
// a script to embed, and serialize to create a snapshot blob.
v8::StartupData result = {nullptr, 0};
{
v8::SnapshotCreator snapshot_creator;
v8::Isolate* isolate = snapshot_creator.GetIsolate();
{
v8::HandleScope scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
if (embedded_source != nullptr &&
!RunExtraCode(isolate, context, embedded_source, "<embedded>")) {
return result;
}
snapshot_creator.SetDefaultContext(context);
}
result = snapshot_creator.CreateBlob(function_code_handling);
}
return result;
}
} // namespace internal
} // namespace v8

View File

@ -158,6 +158,12 @@ class Snapshot : public AllStatic {
DISALLOW_IMPLICIT_CONSTRUCTORS(Snapshot);
};
// Convenience wrapper around snapshot data blob creation used e.g. by tests and
// mksnapshot.
V8_EXPORT_PRIVATE v8::StartupData CreateSnapshotDataBlobInternal(
v8::SnapshotCreator::FunctionCodeHandling function_code_handling,
const char* embedded_source);
#ifdef V8_USE_EXTERNAL_STARTUP_DATA
void SetSnapshotFromFile(StartupData* snapshot_blob);
#endif

View File

@ -169,32 +169,8 @@ bool RunExtraCode(v8::Isolate* isolate, v8::Local<v8::Context> context,
return true;
}
v8::StartupData CreateSnapshotDataBlob(
v8::SnapshotCreator::FunctionCodeHandling function_code_handling,
const char* embedded_source) {
// Create a new isolate and a new context from scratch, optionally run
// a script to embed, and serialize to create a snapshot blob.
DisableEmbeddedBlobRefcounting();
v8::StartupData result = {nullptr, 0};
{
v8::SnapshotCreator snapshot_creator;
v8::Isolate* isolate = snapshot_creator.GetIsolate();
{
v8::HandleScope scope(isolate);
v8::Local<v8::Context> context = v8::Context::New(isolate);
if (embedded_source != nullptr &&
!RunExtraCode(isolate, context, embedded_source, "<embedded>")) {
return result;
}
snapshot_creator.SetDefaultContext(context);
}
result = snapshot_creator.CreateBlob(function_code_handling);
}
return result;
}
v8::StartupData CreateSnapshotDataBlob(const char* embedded_source = nullptr) {
return CreateSnapshotDataBlob(
return CreateSnapshotDataBlobInternal(
v8::SnapshotCreator::FunctionCodeHandling::kClear, embedded_source);
}
@ -770,6 +746,7 @@ UNINITIALIZED_TEST(CustomSnapshotDataBlob1) {
DisableAlwaysOpt();
const char* source1 = "function f() { return 42; }";
DisableEmbeddedBlobRefcounting();
v8::StartupData data1 = CreateSnapshotDataBlob(source1);
v8::Isolate::CreateParams params1;
@ -801,6 +778,7 @@ UNINITIALIZED_TEST(CustomSnapshotDataBlobOverwriteGlobal) {
DisableAlwaysOpt();
const char* source1 = "function f() { return 42; }";
DisableEmbeddedBlobRefcounting();
v8::StartupData data1 = CreateSnapshotDataBlob(source1);
v8::Isolate::CreateParams params1;
@ -839,6 +817,7 @@ UNINITIALIZED_TEST(CustomSnapshotDataBlobStringNotInternalized) {
function f() { return global; }
)javascript";
DisableEmbeddedBlobRefcounting();
v8::StartupData data1 = CreateSnapshotDataBlob(source1);
v8::Isolate::CreateParams params1;
@ -878,8 +857,9 @@ void TestCustomSnapshotDataBlobWithIrregexpCode(
"function i() { return '/* a comment */'.search(re2); }\n"
"f(); f(); g(); g(); h(); h(); i(); i();\n";
DisableEmbeddedBlobRefcounting();
v8::StartupData data1 =
CreateSnapshotDataBlob(function_code_handling, source);
CreateSnapshotDataBlobInternal(function_code_handling, source);
v8::Isolate::CreateParams params1;
params1.snapshot_blob = &data1;
@ -945,6 +925,7 @@ UNINITIALIZED_TEST(SnapshotChecksum) {
DisableAlwaysOpt();
const char* source1 = "function f() { return 42; }";
DisableEmbeddedBlobRefcounting();
v8::StartupData data1 = CreateSnapshotDataBlob(source1);
CHECK(i::Snapshot::VerifyChecksum(&data1));
const_cast<char*>(data1.data)[142] = data1.data[142] ^ 4; // Flip a bit.
@ -1302,6 +1283,7 @@ UNINITIALIZED_TEST(CustomSnapshotDataBlob2) {
"function g() { return 43; }"
"/./.test('a')";
DisableEmbeddedBlobRefcounting();
v8::StartupData data2 = CreateSnapshotDataBlob(source2);
v8::Isolate::CreateParams params2;
@ -1346,6 +1328,7 @@ UNINITIALIZED_TEST(CustomSnapshotDataBlobOutdatedContextWithOverflow) {
const char* source2 = "o.a(42)";
DisableEmbeddedBlobRefcounting();
v8::StartupData data = CreateSnapshotDataBlob(source1);
v8::Isolate::CreateParams params;
@ -1397,6 +1380,7 @@ UNINITIALIZED_TEST(CustomSnapshotDataBlobWithLocker) {
const char* source1 = "function f() { return 42; }";
DisableEmbeddedBlobRefcounting();
v8::StartupData data1 = CreateSnapshotDataBlob(source1);
v8::Isolate::CreateParams params1;
@ -1430,6 +1414,7 @@ UNINITIALIZED_TEST(CustomSnapshotDataBlobStackOverflow) {
" b = c;"
"}";
DisableEmbeddedBlobRefcounting();
v8::StartupData data = CreateSnapshotDataBlob(source);
v8::Isolate::CreateParams params;
@ -1470,6 +1455,7 @@ UNINITIALIZED_TEST(SnapshotDataBlobWithWarmup) {
DisableAlwaysOpt();
const char* warmup = "Math.abs(1); Math.random = 1;";
DisableEmbeddedBlobRefcounting();
v8::StartupData cold = CreateSnapshotDataBlob();
v8::StartupData warm = WarmUpSnapshotDataBlob(cold, warmup);
delete[] cold.data;
@ -1505,6 +1491,7 @@ UNINITIALIZED_TEST(CustomSnapshotDataBlobWithWarmup) {
"var a = 5";
const char* warmup = "a = f()";
DisableEmbeddedBlobRefcounting();
v8::StartupData cold = CreateSnapshotDataBlob(source);
v8::StartupData warm = WarmUpSnapshotDataBlob(cold, warmup);
delete[] cold.data;
@ -1544,6 +1531,7 @@ UNINITIALIZED_TEST(CustomSnapshotDataBlobImmortalImmovableRoots) {
StaticCharVector("a.push(function() {return 7});"),
StaticCharVector("\0"), 10000);
DisableEmbeddedBlobRefcounting();
v8::StartupData data =
CreateSnapshotDataBlob(reinterpret_cast<const char*>(source.begin()));
@ -3818,25 +3806,6 @@ UNINITIALIZED_TEST(ReinitializeHashSeedRehashable) {
FreeCurrentEmbeddedBlob();
}
UNINITIALIZED_TEST(SerializationStats) {
FLAG_profile_deserialization = true;
FLAG_always_opt = false;
v8::StartupData blob = CreateSnapshotDataBlob();
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);
}
FreeCurrentEmbeddedBlob();
}
void CheckSFIsAreWeak(WeakFixedArray sfis, Isolate* isolate) {
CHECK_GT(sfis->length(), 0);
int no_of_weak = 0;

View File

@ -3,9 +3,10 @@
"name": "Memory",
"run_count": 5,
"units": "bytes",
"path" : ["."],
"binary": "cctest",
"main": "test-serialize/SerializationStats",
"resources": ["run.js"],
"main": "run.js",
"path": ["."],
"flags": ["--allow-natives-syntax", "--profile-deserialization"],
"tests": [
{
"name": "ReservedMemoryIsolate",

5
test/memory/run.js Normal file
View File

@ -0,0 +1,5 @@
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
%ProfileCreateSnapshotDataBlob();