Commit b7aa85fe authored by Simon Zünd's avatar Simon Zünd Committed by Commit Bot

[js-perf] Add benchmarks for capturing and serializing stack traces

This CL adds two sets of benchmarks. The first measures the effort
needed to walk the stack and create the data structure stored in
Error.stack, while the second measures the serialization of that
Error.stack data structure into a string.

R=petermarshall@chromium.org, yangguo@chromium.org

Bug: v8:8742
Change-Id: Ie7b86da5621cb186a036a3ec99692ec4d2048fba
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1505614
Commit-Queue: Simon Zünd <szuend@chromium.org>
Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Reviewed-by: 's avatarPeter Marshall <petermarshall@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60176}
parent 25865f06
......@@ -1461,6 +1461,24 @@
"tests": [
{"name": "NumberToString"}
]
},
{
"name": "StackTrace",
"path": ["StackTrace"],
"main": "run.js",
"flags": ["--allow-natives-syntax"],
"resources": ["capture.js", "serialize.js"],
"results_regexp": "^%s\\-StackTrace\\(Score\\): (.+)$",
"tests": [
{"name": "Simple-Capture-Error"},
{"name": "Custom-Capture-Error"},
{"name": "Inline-Capture-Error"},
{"name": "Recursive-Capture-Error"},
{"name": "Simple-Serialize-Error.stack"},
{"name": "Custom-Serialize-Error.stack"},
{"name": "Inline-Serialize-Error.stack"},
{"name": "Recursive-Serialize-Error.stack"}
]
}
]
}
// 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.
(function() {
function Simple() {
new Error("Simple Error");
}
class CustomError extends Error {};
function Custom() {
new CustomError("Custom Error");
}
function Inline() {
function Inner() {
new Error("Error from inlined function!");
}
function Middle() { Inner(); }
function Outer() { Middle(); }
Outer();
Outer();
%OptimizeFunctionOnNextCall(Outer);
Outer();
}
const kInitialRecursionValue = 10;
function Recursive() {
function StepOne(val) {
if (val <= 0) return new Error("Error in StepOne!");
StepTwo(val - 3);
StepTwo(val - 4);
}
function StepTwo(val) {
if (val <= 0) return new Error("Error in StepTwo!");
StepOne(val - 1);
StepOne(val - 2);
}
StepOne(kInitialRecursionValue);
}
createSuite('Simple-Capture-Error', 1000, Simple, () => {});
createSuite('Custom-Capture-Error', 1000, Custom, () => {});
createSuite('Inline-Capture-Error', 1000, Inline, () => {});
createSuite('Recursive-Capture-Error', 1000, Recursive, () => {});
})();
// 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.
load('../base.js');
load('serialize.js');
load('capture.js');
function PrintResult(name, result) {
print(name + '-StackTrace(Score): ' + result);
}
function PrintStep(name) {}
function PrintError(name, error) {
PrintResult(name, error);
}
BenchmarkSuite.config.doWarmup = undefined;
BenchmarkSuite.config.doDeterministic = undefined;
BenchmarkSuite.RunSuites({ NotifyResult: PrintResult,
NotifyError: PrintError,
NotifyStep: PrintStep });
// 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.
(function() {
const kErrorCount = 100000;
let errorsCreatedBySetup;
function CreateErrors(fn) {
counter = 0;
errorsCreatedBySetup = [];
for (let i = 0; i < kErrorCount; ++i) {
errorsCreatedBySetup[i] = fn();
}
}
function SimpleSetup() {
CreateErrors(() => new Error("Simple Error"));
}
class CustomError extends Error {};
function CustomSetup() {
CreateErrors(() => new CustomError("Custom Error"));
}
function InlineSetup() {
function Inner() {
return new Error("Throwing from inlined function!");
}
function Middle() { return Inner(); }
function Outer() { return Middle(); }
Outer();
Outer();
%OptimizeFunctionOnNextCall(Outer);
Outer();
CreateErrors(() => Outer());
}
const kInitialRecursionValue = 12;
function RecursiveSetup() {
counter = 0;
errorsCreatedBySetup = [];
function StepOne(val) {
if (val <= 0) {
errorsCreatedBySetup.push(new Error("Error in StepOne!"));
return;
}
StepTwo(val - 3);
StepTwo(val - 4);
}
function StepTwo(val) {
if (val <= 0) {
errorsCreatedBySetup.push(new Error("Error in StepTwo!"));
return;
}
StepOne(val - 1);
StepOne(val - 2);
}
while (errorsCreatedBySetup.length < kErrorCount) {
StepOne(kInitialRecursionValue);
}
}
let counter;
function SerializeStack() {
if (counter < errorsCreatedBySetup.length) {
// Trigger serialization by accessing Error.stack.
%FlattenString(errorsCreatedBySetup[counter++].stack);
} else {
// The counter is reset after hitting the end, although
// Error.stack is cached at this point.
counter = 0;
}
}
createSuite('Simple-Serialize-Error.stack', 1000, SerializeStack, SimpleSetup);
createSuite('Custom-Serialize-Error.stack', 1000, SerializeStack, CustomSetup);
createSuite('Inline-Serialize-Error.stack', 1000, SerializeStack, InlineSetup);
createSuite('Recursive-Serialize-Error.stack', 1000, SerializeStack, RecursiveSetup);
})();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment