[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:
parent
ec379ea8a8
commit
226b58341e
@ -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
|
||||
|
@ -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) \
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
5
test/memory/run.js
Normal 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();
|
Loading…
Reference in New Issue
Block a user