Revert "[mjsunit][tools][d8] Full roundtrip tickprocessor test"

This reverts commit ed7e4554db.

Reason for revert: new test fails on Mac: https://ci.chromium.org/ui/p/v8/builders/ci/V8%20Mac64/40407/overview

Original change's description:
> [mjsunit][tools][d8] Full roundtrip tickprocessor test
>
> - Add os.d8Path property
> - Add os.name property
> - Change tickprocssor test to use command line arguments for testing
>   various configurations
> - Change tickprocessor test to create a temporary v8.log and read it
>   back in on linux only
> - Rearrange code in tickprocessor.mjs to allow instantiating the
>   CppEntriesProvider directly
> - Drop complete symbol-list for tickprocessor-test-large.log for better
>   code searching in V8
>
> Change-Id: Ib56dd0a1ba5377282c84c4de6f17e2fd69ee8123
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2929120
> Reviewed-by: Patrick Thier <pthier@chromium.org>
> Commit-Queue: Camillo Bruni <cbruni@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#74892}

Change-Id: I7d7506b370f96365552a21fa767b1c5c608ebb1c
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2929380
Auto-Submit: Clemens Backes <clemensb@chromium.org>
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Cr-Commit-Position: refs/heads/master@{#74894}
This commit is contained in:
Clemens Backes 2021-06-01 18:04:10 +00:00 committed by V8 LUCI CQ
parent 705527f839
commit 72564ba765
9 changed files with 516 additions and 555 deletions

View File

@ -2800,24 +2800,6 @@ Local<ObjectTemplate> Shell::CreateGlobalTemplate(Isolate* isolate) {
Local<ObjectTemplate> Shell::CreateOSTemplate(Isolate* isolate) {
Local<ObjectTemplate> os_template = ObjectTemplate::New(isolate);
AddOSMethods(isolate, os_template);
#if V8_TARGET_OS_LINUX
const char os_name[] = "linux";
#elif V8_TARGET_OS_WIN
const char os_name[] = "windows";
#elif V8_TARGET_OS_MACOSX
const char os_name[] = "macos";
#elif V8_TARGET_OS_ANDROID
const char os_name[] = "android";
#else
const char os_name[] = "unknown";
#endif
os_template->Set(isolate, "name",
v8::String::NewFromUtf8Literal(isolate, os_name),
PropertyAttribute::ReadOnly);
os_template->Set(
isolate, "d8Path",
v8::String::NewFromUtf8(isolate, options.d8_path).ToLocalChecked(),
PropertyAttribute::ReadOnly);
return os_template;
}
@ -4135,7 +4117,6 @@ void Worker::PostMessageOut(const v8::FunctionCallbackInfo<v8::Value>& args) {
bool Shell::SetOptions(int argc, char* argv[]) {
bool logfile_per_isolate = false;
bool no_always_opt = false;
options.d8_path = argv[0];
for (int i = 0; i < argc; i++) {
if (strcmp(argv[i], "--") == 0) {
argv[i] = nullptr;

View File

@ -351,7 +351,6 @@ class ShellOptions {
bool specified_ = false;
};
DisallowReassignment<const char*> d8_path = {"d8-path", ""};
DisallowReassignment<bool> fuzzilli_coverage_statistics = {
"fuzzilli-coverage-statistics", false};
DisallowReassignment<bool> fuzzilli_enable_builtins_coverage = {
@ -542,30 +541,29 @@ class Shell : public i::AllStatic {
// milliseconds on the total running time of the program. Exceptions are
// thrown on timeouts or other errors or if the exit status of the program
// indicates an error.
static void System(const v8::FunctionCallbackInfo<v8::Value>& args);
//
// os.chdir(dir) changes directory to the given directory. Throws an
// exception/ on error.
static void ChangeDirectory(const v8::FunctionCallbackInfo<v8::Value>& args);
//
// os.setenv(variable, value) sets an environment variable. Repeated calls to
// this method leak memory due to the API of setenv in the standard C library.
static void SetEnvironment(const v8::FunctionCallbackInfo<v8::Value>& args);
static void UnsetEnvironment(const v8::FunctionCallbackInfo<v8::Value>& args);
//
// os.umask(alue) calls the umask system call and returns the old umask.
static void SetUMask(const v8::FunctionCallbackInfo<v8::Value>& args);
//
// os.mkdirp(name, mask) creates a directory. The mask (if present) is anded
// with the current umask. Intermediate directories are created if necessary.
// An exception is not thrown if the directory already exists. Analogous to
// the "mkdir -p" command.
static void System(const v8::FunctionCallbackInfo<v8::Value>& args);
static void ChangeDirectory(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetEnvironment(const v8::FunctionCallbackInfo<v8::Value>& args);
static void UnsetEnvironment(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetUMask(const v8::FunctionCallbackInfo<v8::Value>& args);
static void MakeDirectory(const v8::FunctionCallbackInfo<v8::Value>& args);
static void RemoveDirectory(const v8::FunctionCallbackInfo<v8::Value>& args);
static MaybeLocal<Promise> HostImportModuleDynamically(
Local<Context> context, Local<ScriptOrModule> referrer,
Local<String> specifier, Local<FixedArray> import_assertions);
static void ModuleResolutionSuccessCallback(
const v8::FunctionCallbackInfo<v8::Value>& info);
static void ModuleResolutionFailureCallback(

View File

@ -41,10 +41,6 @@ function arg_error(str) {
}
}
const kOsNameValues = ['linux', 'macos', 'windows', 'android', 'unknown'];
assertTrue(kOsNameValues.includes(os.name));
assertTrue(os.d8Path.length > 0);
function str_error(str) {
var e = new Object();

View File

@ -2,30 +2,49 @@ Statistical profiling result from v8.log, (303 ticks, 0 unaccounted, 0 excluded)
[Shared libraries]:
ticks total nonlib name
24 7.9% /usr/local/google/home/cbruni/Documents/v8/v8/out/x64.release/d8
10 3.3% /usr/lib/x86_64-linux-gnu/libc-2.31.so
4 1.3% /usr/lib/x86_64-linux-gnu/libpthread-2.31.so
9 3.0% /usr/local/google/home/cbruni/Documents/v8/v8/out/x64.release/d8
6 2.0% /usr/lib/x86_64-linux-gnu/libc-2.31.so
[JavaScript]:
ticks total nonlib name
102 33.7% 38.5% LazyCompile: *<anonymous> test/mjsunit/tools/tickprocessor-test.js:1:1
25 8.3% 9.4% LazyCompile: *ics test/mjsunit/tools/tickprocessor-test.js:47:13
21 6.9% 7.9% LazyCompile: *loop test/mjsunit/tools/tickprocessor-test.js:10:14
102 33.7% 35.4% LazyCompile: *<anonymous> test/mjsunit/tools/tickprocessor-test.js:1:1
25 8.3% 8.7% LazyCompile: *ics test/mjsunit/tools/tickprocessor-test.js:47:13
21 6.9% 7.3% LazyCompile: *loop test/mjsunit/tools/tickprocessor-test.js:10:14
[C++]:
ticks total nonlib name
99 32.7% 37.4% v8_Default_embedded_blob_code_data_
12 4.0% 4.5% __write
3 1.0% 1.1% fwrite
2 0.7% 0.8% v8::internal::RootScavengeVisitor::VisitRootPointer(v8::internal::Root, char const*, v8::internal::FullObjectSlot)
1 0.3% 0.4% v8::internal::compiler::TopLevelLiveRange::AddUseInterval(v8::internal::compiler::LifetimePosition, v8::internal::compiler::LifetimePosition, v8::internal::Zone*, bool)
99 32.7% 34.4% v8_Default_embedded_blob_code_data_
12 4.0% 4.2% __write
3 1.0% 1.0% fwrite
2 0.7% 0.7% v8::internal::RootScavengeVisitor::VisitRootPointer(v8::internal::Root, char const*, v8::internal::FullObjectSlot)
2 0.7% 0.7% __pthread_mutex_unlock_usercnt
2 0.7% 0.7% __libc_malloc
2 0.7% 0.7% _IO_file_xsputn
1 0.3% 0.3% v8::internal::compiler::TopLevelLiveRange::AddUseInterval(v8::internal::compiler::LifetimePosition, v8::internal::compiler::LifetimePosition, v8::internal::Zone*, bool)
1 0.3% 0.3% v8::internal::compiler::Scheduler::PrepareUses()
1 0.3% 0.3% v8::internal::compiler::CommonOperatorBuilder::CommonOperatorBuilder(v8::internal::Zone*)
1 0.3% 0.3% v8::internal::SpaceWithLinearArea::AdvanceAllocationObservers()
1 0.3% 0.3% v8::internal::SerializerDeserializer::Iterate(v8::internal::Isolate*, v8::internal::RootVisitor*)
1 0.3% 0.3% v8::internal::Log::MessageBuilder::AppendString(char const*, unsigned long, bool)
1 0.3% 0.3% v8::internal::LargeObjectSpace::SizeOfObjects()
1 0.3% 0.3% v8::internal::Heap::Scavenge()
1 0.3% 0.3% v8::internal::Heap::AllocateRawWithRetryOrFailSlowPath(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment)
1 0.3% 0.3% v8::internal::Heap::AllocateRaw(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment)
1 0.3% 0.3% v8::OutputStream::GetChunkSize()
1 0.3% 0.3% std::__1::ostreambuf_iterator<char, std::__1::char_traits<char> > std::__1::__pad_and_output<char, std::__1::char_traits<char> >(std::__1::ostreambuf_iterator<char, std::__1::char_traits<char> >, char const*, char const*, char const*, std::__1::ios_base&, char)
1 0.3% 0.3% std::__1::num_put<char, std::__1::ostreambuf_iterator<char, std::__1::char_traits<char> > >::do_put(std::__1::ostreambuf_iterator<char, std::__1::char_traits<char> >, std::__1::ios_base&, char, long) const
1 0.3% 0.3% std::__1::basic_ostream<char, std::__1::char_traits<char> >::operator<<(unsigned long)
1 0.3% 0.3% int v8::internal::Deserializer::ReadSingleBytecodeData<v8::internal::SlotAccessorForHeapObject>(unsigned char, v8::internal::SlotAccessorForHeapObject)
1 0.3% 0.3% __pthread_cond_wait
1 0.3% 0.3% __pthread_cond_signal
1 0.3% 0.3% Cr_z_inflate_fast_chunk_
[Summary]:
ticks total nonlib name
148 48.8% 55.8% JavaScript
117 38.6% 44.2% C++
20 6.6% 7.5% GC
38 12.5% Shared libraries
148 48.8% 51.4% JavaScript
140 46.2% 48.6% C++
20 6.6% 6.9% GC
15 5.0% Shared libraries
[C++ entry points]:
ticks cpp total name
@ -50,25 +69,17 @@ Statistical profiling result from v8.log, (303 ticks, 0 unaccounted, 0 excluded)
25 8.3% LazyCompile: *ics test/mjsunit/tools/tickprocessor-test.js:47:13
25 100.0% Script: ~<anonymous> test/mjsunit/tools/tickprocessor-test.js:1:1
24 7.9% /usr/local/google/home/cbruni/Documents/v8/v8/out/x64.release/d8
4 16.7% LazyCompile: ~ics test/mjsunit/tools/tickprocessor-test.js:47:13
4 100.0% Script: ~<anonymous> test/mjsunit/tools/tickprocessor-test.js:1:1
3 12.5% v8::internal::Runtime_CompileForOnStackReplacement(int, unsigned long*, v8::internal::Isolate*)
2 66.7% Script: ~<anonymous> test/mjsunit/tools/tickprocessor-test.js:1:1
1 33.3% LazyCompile: ~loop test/mjsunit/tools/tickprocessor-test.js:10:14
1 100.0% Script: ~<anonymous> test/mjsunit/tools/tickprocessor-test.js:1:1
2 8.3% v8::internal::Runtime_AllocateInYoungGeneration(int, unsigned long*, v8::internal::Isolate*)
2 100.0% LazyCompile: *<anonymous> test/mjsunit/tools/tickprocessor-test.js:1:1
2 8.3% Script: ~<anonymous> test/mjsunit/tools/tickprocessor-test.js:1:1
2 8.3% LazyCompile: ~read_megamorphic test/mjsunit/tools/tickprocessor-test.js:35:26
2 100.0% LazyCompile: ~ics test/mjsunit/tools/tickprocessor-test.js:47:13
2 100.0% Script: ~<anonymous> test/mjsunit/tools/tickprocessor-test.js:1:1
21 6.9% LazyCompile: *loop test/mjsunit/tools/tickprocessor-test.js:10:14
21 100.0% Script: ~<anonymous> test/mjsunit/tools/tickprocessor-test.js:1:1
12 4.0% __write
10 3.3% /usr/lib/x86_64-linux-gnu/libc-2.31.so
9 3.0% /usr/local/google/home/cbruni/Documents/v8/v8/out/x64.release/d8
4 44.4% LazyCompile: ~ics test/mjsunit/tools/tickprocessor-test.js:47:13
4 100.0% Script: ~<anonymous> test/mjsunit/tools/tickprocessor-test.js:1:1
2 22.2% Script: ~<anonymous> test/mjsunit/tools/tickprocessor-test.js:1:1
2 22.2% LazyCompile: ~read_megamorphic test/mjsunit/tools/tickprocessor-test.js:35:26
2 100.0% LazyCompile: ~ics test/mjsunit/tools/tickprocessor-test.js:47:13
2 100.0% Script: ~<anonymous> test/mjsunit/tools/tickprocessor-test.js:1:1
4 1.3% /usr/lib/x86_64-linux-gnu/libpthread-2.31.so
6 2.0% /usr/lib/x86_64-linux-gnu/libc-2.31.so

View File

@ -53,6 +53,6 @@ function ics() {
}
}
for (let i = 0; i < 10_000; i++) {
for (let i = 0; i < 100_000; i++) {
ics();
}

File diff suppressed because one or more lines are too long

View File

@ -25,11 +25,9 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --enable-os-system
// Resources: test/mjsunit/tools/tickprocessor-test-func-info.log
// Resources: test/mjsunit/tools/tickprocessor-test-func-info.log.symbols.json
// Resources: test/mjsunit/tools/tickprocessor-test-large.default
// Resources: test/mjsunit/tools/tickprocessor-test-large.js
// Resources: test/mjsunit/tools/tickprocessor-test-large.log
// Resources: test/mjsunit/tools/tickprocessor-test-large.log.symbols.json
// Resources: test/mjsunit/tools/tickprocessor-test.default
@ -42,12 +40,23 @@
// Resources: test/mjsunit/tools/tickprocessor-test.separate-baseline-handlers
// Resources: test/mjsunit/tools/tickprocessor-test.separate-bytecodes
// Resources: test/mjsunit/tools/tickprocessor-test.separate-ic
// Env: TEST_FILE_NAME
import {
TickProcessor, ArgumentsProcessor, UnixCppEntriesProvider,
MacCppEntriesProvider, WindowsCppEntriesProvider
MacCppEntriesProvider, WindowsCppEntriesProvider
} from "../../../tools/tickprocessor.mjs";
// TODO(cbruni): Remove after refactoring
export function readFile(fileName) {
try {
return read(fileName);
} catch (e) {
console.log(fileName + ': ' + (e.message || e));
throw e;
}
}
(function testArgumentsProcessor() {
var p_default = new ArgumentsProcessor([]);
assertTrue(p_default.parse());
@ -363,7 +372,7 @@ import {
class CppEntriesProviderMock {
constructor(filename) {
this.isLoaded = false;
this.symbols = JSON.parse(d8.file.read(filename));
this.symbols = JSON.parse(readFile(filename));
}
parseVmSymbols(name, startAddr, endAddr, slideAddr, symbolAdder) {
if (this.isLoaded) return;
@ -383,17 +392,17 @@ class PrintMonitor {
this.expectedOut = this.loadExpectedOutput(outputOrFileName)
this.outputFile = outputOrFileName;
}
let expectedOut = this.expectedOut;
let outputPos = 0;
let diffs = this.diffs = [];
let realOut = this.realOut = [];
let unexpectedOut = this.unexpectedOut = null;
var expectedOut = this.expectedOut;
var outputPos = 0;
var diffs = this.diffs = [];
var realOut = this.realOut = [];
var unexpectedOut = this.unexpectedOut = null;
this.oldPrint = print;
print = function(str) {
const strSplit = str.split('\n');
for (let i = 0; i < strSplit.length; ++i) {
const s = strSplit[i];
var strSplit = str.split('\n');
for (var i = 0; i < strSplit.length; ++i) {
var s = strSplit[i];
realOut.push(s);
if (outputPos < expectedOut.length) {
if (expectedOut[outputPos] != s) {
@ -409,95 +418,98 @@ class PrintMonitor {
}
loadExpectedOutput(fileName) {
const output = d8.file.read(fileName);
var output = readFile(fileName);
return output.split('\n');
}
finish() {
print = this.oldPrint;
if (this.diffs.length == 0 && this.unexpectedOut == null) return;
console.log("===== actual output: =====");
console.log(this.realOut.join('\n'));
console.log("===== expected output: =====");
if (this.outputFile) {
console.log("===== File: " + this.outputFile + " =====");
if (this.diffs.length > 0 || this.unexpectedOut != null) {
console.log("===== actual output: =====");
console.log(this.realOut.join('\n'));
console.log("===== expected output: =====");
if (this.outputFile) {
console.log("===== File: " + this.outputFile + " =====");
}
console.log(this.expectedOut.join('\n'));
if (this.diffs.length > 0) {
this.diffs.forEach(line => console.log(line))
assertEquals([], this.diffs);
}
assertNull(this.unexpectedOut);
}
console.log(this.expectedOut.join('\n'));
if (this.diffs.length > 0) {
this.diffs.forEach(line => console.log(line))
assertEquals([], this.diffs);
}
assertNull(this.unexpectedOut);
}
}
function driveTickProcessorTest(
separateIc, separateBytecodes, separateBuiltins, separateStubs,
separateBaselineHandlers, ignoreUnknown, stateFilter, logInput,
refOutput, onlySummary) {
// TEST_FILE_NAME must be provided by test runner.
assertEquals('string', typeof TEST_FILE_NAME);
var pathLen = TEST_FILE_NAME.lastIndexOf('/');
if (pathLen == -1) {
pathLen = TEST_FILE_NAME.lastIndexOf('\\');
}
assertTrue(pathLen != -1);
const testsPath = TEST_FILE_NAME.substr(0, pathLen + 1);
const symbolsFile = testsPath + logInput + '.symbols.json';
const tp = new TickProcessor(new CppEntriesProviderMock(symbolsFile),
separateIc,
separateBytecodes,
separateBuiltins,
separateStubs,
separateBaselineHandlers,
TickProcessor.CALL_GRAPH_SIZE,
ignoreUnknown,
stateFilter,
"0",
"auto,auto",
null,
false,
false,
onlySummary);
const pm = new PrintMonitor(testsPath + refOutput);
tp.processLogFileInTest(testsPath + logInput);
tp.printStatistics();
pm.finish();
};
(function testProcessing() {
const testData = {
var testData = {
'Default': [
'tickprocessor-test.log', 'tickprocessor-test.default',
['--separate-ic=false']],
false, false, true, true, false, false, null,
'tickprocessor-test.log', 'tickprocessor-test.default', false],
'SeparateBytecodes': [
'tickprocessor-test.log', 'tickprocessor-test.separate-bytecodes',
['--separate-ic=false', '--separate-bytecodes']],
false, true, true, true, false, false, null,
'tickprocessor-test.log', 'tickprocessor-test.separate-bytecodes', false],
'SeparateBaselineHandlers': [
'tickprocessor-test.log', 'tickprocessor-test.separate-baseline-handlers',
['--separate-ic=false', '--separate-baseline-handlers']],
false, false, true, true, true, false, null,
'tickprocessor-test.log', 'tickprocessor-test.separate-baseline-handlers', false],
'SeparateIc': [
'tickprocessor-test.log', 'tickprocessor-test.separate-ic',
['--separate-ic=true']],
true, false, true, true, false, false, null,
'tickprocessor-test.log', 'tickprocessor-test.separate-ic', false],
'IgnoreUnknown': [
'tickprocessor-test.log', 'tickprocessor-test.ignore-unknown',
['--separate-ic=false', '--ignore-unknown']],
false, false, true, true, false, true, null,
'tickprocessor-test.log', 'tickprocessor-test.ignore-unknown', false],
'GcState': [
'tickprocessor-test.log', 'tickprocessor-test.gc-state', ['-g']],
false, false, true, true, false, false, TickProcessor.VmStates.GC,
'tickprocessor-test.log', 'tickprocessor-test.gc-state', false],
'OnlySummary': [
'tickprocessor-test.log', 'tickprocessor-test.only-summary',
['--separate-ic=false', '--only-summary']],
false, false, true, true, false, false, null,
'tickprocessor-test.log', 'tickprocessor-test.only-summary', true],
'FunctionInfo': [
false, false, true, true, false, false, null,
'tickprocessor-test-func-info.log', 'tickprocessor-test.func-info',
['']
],
false],
'DefaultLarge': [
'tickprocessor-test-large.log', 'tickprocessor-test-large.default'],
false, false, true, true, false, false, null,
'tickprocessor-test-large.log', 'tickprocessor-test-large.default', false],
};
for (var testName in testData) {
console.log('=== testProcessing-' + testName + ' ===');
testTickProcessor(...testData[testName]);
driveTickProcessorTest(...testData[testName]);
}
})();
function testTickProcessor(logInput, refOutput, args=[]) {
// /foo/bar/tickprocesser.mjs => /foo/bar/
const dir = import.meta.url.split("/").slice(0, -1).join('/') + '/';
const params = ArgumentsProcessor.process(args);
testExpectations(dir + logInput, dir + refOutput, params);
testEndToEnd(dir + 'tickprocessor-test-large.js', dir + refOutput, params);
}
function testExpectations(logInput, refOutput, params) {
const symbolsFile = logInput + '.symbols.json';
const cppEntries = new CppEntriesProviderMock(symbolsFile);
const tickProcessor = TickProcessor.fromParams(params, cppEntries);
const printMonitor = new PrintMonitor(refOutput);
tickProcessor.processLogFileInTest(logInput);
tickProcessor.printStatistics();
printMonitor.finish();
};
function testEndToEnd(sourceFile, ignoredRefOutput, params) {
// This test only works on linux.
if (!os?.system) return;
if (os.name !== 'linux' && os.name !== 'macos') return;
params.platform = os.name;
const tmpLogFile= `/var/tmp/${Date.now()}.v8.log`
const result = os.system(
os.d8Path, ['--prof', `--logfile=${tmpLogFile}`, sourceFile]);
const tickProcessor = TickProcessor.fromParams(params);
// We will not always get the same ticks due to timing on bots,
// hence we cannot properly compare output expectations.
// Let's just use a dummy file and only test whether we don't throw.
const printMonitor = new PrintMonitor(ignoredRefOutput);
tickProcessor.processLogFileInTest(tmpLogFile);
tickProcessor.printStatistics();
}

View File

@ -25,11 +25,41 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import { ArgumentsProcessor, TickProcessor } from "./tickprocessor.mjs";
import {
ArgumentsProcessor, TickProcessor, UnixCppEntriesProvider,
WindowsCppEntriesProvider, MacCppEntriesProvider
} from "./tickprocessor.mjs";
// Tick Processor's code flow.
const entriesProviders = {
'unix': UnixCppEntriesProvider,
'windows': WindowsCppEntriesProvider,
'mac': MacCppEntriesProvider
};
const params = ArgumentsProcessor.process(arguments);
const tickProcessor = TickProcessor.fromParams(params);
const tickProcessor = new TickProcessor(
new (entriesProviders[params.platform])(params.nm, params.objdump, params.targetRootFS,
params.apkEmbeddedLibrary),
params.separateIc,
params.separateBytecodes,
params.separateBuiltins,
params.separateStubs,
params.separateBaselineHandlers,
params.callGraphSize,
params.ignoreUnknown,
params.stateFilter,
params.distortion,
params.range,
params.sourceMap,
params.timedRange,
params.pairwiseTimedRange,
params.onlySummary,
params.runtimeTimerFilter,
params.preprocessJson);
tickProcessor.processLogFile(params.logFileName);
if (params.serializeVMSymbols) {
tickProcessor.printVMSymbols();
} else {

View File

@ -59,378 +59,8 @@ class V8Profile extends Profile {
}
}
class CppEntriesProvider {
inRange(funcInfo, start, end) {
return funcInfo.start >= start && funcInfo.end <= end;
}
parseVmSymbols(libName, libStart, libEnd, libASLRSlide, processorFunc) {
this.loadSymbols(libName);
let lastUnknownSize;
let lastAdded;
let addEntry = (funcInfo) => {
// Several functions can be mapped onto the same address. To avoid
// creating zero-sized entries, skip such duplicates.
// Also double-check that function belongs to the library address space.
if (lastUnknownSize &&
lastUnknownSize.start < funcInfo.start) {
// Try to update lastUnknownSize based on new entries start position.
lastUnknownSize.end = funcInfo.start;
if ((!lastAdded ||
!this.inRange(lastUnknownSize, lastAdded.start, lastAdded.end)) &&
this.inRange(lastUnknownSize, libStart, libEnd)) {
processorFunc(
lastUnknownSize.name, lastUnknownSize.start, lastUnknownSize.end);
lastAdded = lastUnknownSize;
}
}
lastUnknownSize = undefined;
if (funcInfo.end) {
// Skip duplicates that have the same start address as the last added.
if ((!lastAdded || lastAdded.start != funcInfo.start) &&
this.inRange(funcInfo, libStart, libEnd)) {
processorFunc(funcInfo.name, funcInfo.start, funcInfo.end);
lastAdded = funcInfo;
}
} else {
// If a funcInfo doesn't have an end, try to match it up with the next
// entry.
lastUnknownSize = funcInfo;
}
}
while (true) {
const funcInfo = this.parseNextLine();
if (funcInfo === null) continue;
if (funcInfo === false) break;
if (funcInfo.start < libStart - libASLRSlide &&
funcInfo.start < libEnd - libStart) {
funcInfo.start += libStart;
} else {
funcInfo.start += libASLRSlide;
}
if (funcInfo.size) {
funcInfo.end = funcInfo.start + funcInfo.size;
}
addEntry(funcInfo);
}
addEntry({ name: '', start: libEnd });
}
loadSymbols(libName) {}
parseNextLine() { return false }
}
export class UnixCppEntriesProvider extends CppEntriesProvider {
constructor(nmExec, objdumpExec, targetRootFS, apkEmbeddedLibrary) {
super();
this.symbols = [];
// File offset of a symbol minus the virtual address of a symbol found in
// the symbol table.
this.fileOffsetMinusVma = 0;
this.parsePos = 0;
this.nmExec = nmExec;
this.objdumpExec = objdumpExec;
this.targetRootFS = targetRootFS;
this.apkEmbeddedLibrary = apkEmbeddedLibrary;
this.FUNC_RE = /^([0-9a-fA-F]{8,16}) ([0-9a-fA-F]{8,16} )?[tTwW] (.*)$/;
}
loadSymbols(libName) {
this.parsePos = 0;
if (this.apkEmbeddedLibrary && libName.endsWith('.apk')) {
libName = this.apkEmbeddedLibrary;
}
if (this.targetRootFS) {
libName = libName.substring(libName.lastIndexOf('/') + 1);
libName = this.targetRootFS + libName;
}
try {
this.symbols = [
os.system(this.nmExec, ['-C', '-n', '-S', libName], -1, -1),
os.system(this.nmExec, ['-C', '-n', '-S', '-D', libName], -1, -1)
];
const objdumpOutput = os.system(this.objdumpExec, ['-h', libName], -1, -1);
for (const line of objdumpOutput.split('\n')) {
const [, sectionName, , vma, , fileOffset] = line.trim().split(/\s+/);
if (sectionName === ".text") {
this.fileOffsetMinusVma = parseInt(fileOffset, 16) - parseInt(vma, 16);
}
}
} catch (e) {
// If the library cannot be found on this system let's not panic.
this.symbols = ['', ''];
}
}
parseNextLine() {
if (this.symbols.length == 0) {
return false;
}
const lineEndPos = this.symbols[0].indexOf('\n', this.parsePos);
if (lineEndPos == -1) {
this.symbols.shift();
this.parsePos = 0;
return this.parseNextLine();
}
const line = this.symbols[0].substring(this.parsePos, lineEndPos);
this.parsePos = lineEndPos + 1;
const fields = line.match(this.FUNC_RE);
let funcInfo = null;
if (fields) {
funcInfo = { name: fields[3], start: parseInt(fields[1], 16) + this.fileOffsetMinusVma };
if (fields[2]) {
funcInfo.size = parseInt(fields[2], 16);
}
}
return funcInfo;
}
}
export class MacCppEntriesProvider extends UnixCppEntriesProvider {
constructor(nmExec, objdumpExec, targetRootFS, apkEmbeddedLibrary) {
super(nmExec, objdumpExec, targetRootFS, apkEmbeddedLibrary);
// Note an empty group. It is required, as UnixCppEntriesProvider expects 3 groups.
this.FUNC_RE = /^([0-9a-fA-F]{8,16})() (.*)$/;
}
loadSymbols(libName) {
this.parsePos = 0;
libName = this.targetRootFS + libName;
// It seems that in OS X `nm` thinks that `-f` is a format option, not a
// "flat" display option flag.
try {
this.symbols = [os.system(this.nmExec, ['-n', libName], -1, -1), ''];
} catch (e) {
// If the library cannot be found on this system let's not panic.
this.symbols = '';
}
}
}
export class WindowsCppEntriesProvider extends CppEntriesProvider {
constructor(_ignored_nmExec, _ignored_objdumpExec, targetRootFS,
_ignored_apkEmbeddedLibrary) {
super();
this.targetRootFS = targetRootFS;
this.symbols = '';
this.parsePos = 0;
}
static FILENAME_RE = /^(.*)\.([^.]+)$/;
static FUNC_RE =
/^\s+0001:[0-9a-fA-F]{8}\s+([_\?@$0-9a-zA-Z]+)\s+([0-9a-fA-F]{8}).*$/;
static IMAGE_BASE_RE =
/^\s+0000:00000000\s+___ImageBase\s+([0-9a-fA-F]{8}).*$/;
// This is almost a constant on Windows.
static EXE_IMAGE_BASE = 0x00400000;
loadSymbols(libName) {
libName = this.targetRootFS + libName;
const fileNameFields = libName.match(WindowsCppEntriesProvider.FILENAME_RE);
if (!fileNameFields) return;
const mapFileName = `${fileNameFields[1]}.map`;
this.moduleType_ = fileNameFields[2].toLowerCase();
try {
this.symbols = read(mapFileName);
} catch (e) {
// If .map file cannot be found let's not panic.
this.symbols = '';
}
}
parseNextLine() {
const lineEndPos = this.symbols.indexOf('\r\n', this.parsePos);
if (lineEndPos == -1) {
return false;
}
const line = this.symbols.substring(this.parsePos, lineEndPos);
this.parsePos = lineEndPos + 2;
// Image base entry is above all other symbols, so we can just
// terminate parsing.
const imageBaseFields = line.match(WindowsCppEntriesProvider.IMAGE_BASE_RE);
if (imageBaseFields) {
const imageBase = parseInt(imageBaseFields[1], 16);
if ((this.moduleType_ == 'exe') !=
(imageBase == WindowsCppEntriesProvider.EXE_IMAGE_BASE)) {
return false;
}
}
const fields = line.match(WindowsCppEntriesProvider.FUNC_RE);
return fields ?
{ name: this.unmangleName(fields[1]), start: parseInt(fields[2], 16) } :
null;
}
/**
* Performs very simple unmangling of C++ names.
*
* Does not handle arguments and template arguments. The mangled names have
* the form:
*
* ?LookupInDescriptor@JSObject@internal@v8@@...arguments info...
*/
unmangleName(name) {
// Empty or non-mangled name.
if (name.length < 1 || name.charAt(0) != '?') return name;
const nameEndPos = name.indexOf('@@');
const components = name.substring(1, nameEndPos).split('@');
components.reverse();
return components.join('::');
}
}
export class ArgumentsProcessor extends BaseArgumentsProcessor {
getArgsDispatch() {
let dispatch = {
__proto__:null,
'-j': ['stateFilter', TickProcessor.VmStates.JS,
'Show only ticks from JS VM state'],
'-g': ['stateFilter', TickProcessor.VmStates.GC,
'Show only ticks from GC VM state'],
'-p': ['stateFilter', TickProcessor.VmStates.PARSER,
'Show only ticks from PARSER VM state'],
'-b': ['stateFilter', TickProcessor.VmStates.BYTECODE_COMPILER,
'Show only ticks from BYTECODE_COMPILER VM state'],
'-c': ['stateFilter', TickProcessor.VmStates.COMPILER,
'Show only ticks from COMPILER VM state'],
'-o': ['stateFilter', TickProcessor.VmStates.OTHER,
'Show only ticks from OTHER VM state'],
'-e': ['stateFilter', TickProcessor.VmStates.EXTERNAL,
'Show only ticks from EXTERNAL VM state'],
'--filter-runtime-timer': ['runtimeTimerFilter', null,
'Show only ticks matching the given runtime timer scope'],
'--call-graph-size': ['callGraphSize', TickProcessor.CALL_GRAPH_SIZE,
'Set the call graph size'],
'--ignore-unknown': ['ignoreUnknown', true,
'Exclude ticks of unknown code entries from processing'],
'--separate-ic': ['separateIc', parseBool,
'Separate IC entries'],
'--separate-bytecodes': ['separateBytecodes', parseBool,
'Separate Bytecode entries'],
'--separate-builtins': ['separateBuiltins', parseBool,
'Separate Builtin entries'],
'--separate-stubs': ['separateStubs', parseBool,
'Separate Stub entries'],
'--separate-baseline-handlers': ['separateBaselineHandlers', parseBool,
'Separate Baseline Handler entries'],
'--linux': ['platform', 'linux',
'Specify that we are running on *nix platform'],
'--windows': ['platform', 'windows',
'Specify that we are running on Windows platform'],
'--mac': ['platform', 'mac',
'Specify that we are running on Mac OS X platform'],
'--nm': ['nm', 'nm',
'Specify the \'nm\' executable to use (e.g. --nm=/my_dir/nm)'],
'--objdump': ['objdump', 'objdump',
'Specify the \'objdump\' executable to use (e.g. --objdump=/my_dir/objdump)'],
'--target': ['targetRootFS', '',
'Specify the target root directory for cross environment'],
'--apk-embedded-library': ['apkEmbeddedLibrary', '',
'Specify the path of the embedded library for Android traces'],
'--range': ['range', 'auto,auto',
'Specify the range limit as [start],[end]'],
'--distortion': ['distortion', 0,
'Specify the logging overhead in picoseconds'],
'--source-map': ['sourceMap', null,
'Specify the source map that should be used for output'],
'--timed-range': ['timedRange', true,
'Ignore ticks before first and after last Date.now() call'],
'--pairwise-timed-range': ['pairwiseTimedRange', true,
'Ignore ticks outside pairs of Date.now() calls'],
'--only-summary': ['onlySummary', true,
'Print only tick summary, exclude other information'],
'--serialize-vm-symbols': ['serializeVMSymbols', true,
'Print all C++ symbols and library addresses as JSON data'],
'--preprocess': ['preprocessJson', true,
'Preprocess for consumption with web interface']
};
dispatch['--js'] = dispatch['-j'];
dispatch['--gc'] = dispatch['-g'];
dispatch['--compiler'] = dispatch['-c'];
dispatch['--other'] = dispatch['-o'];
dispatch['--external'] = dispatch['-e'];
dispatch['--ptr'] = dispatch['--pairwise-timed-range'];
return dispatch;
}
getDefaultResults() {
return {
logFileName: 'v8.log',
platform: 'linux',
stateFilter: null,
callGraphSize: 5,
ignoreUnknown: false,
separateIc: true,
separateBytecodes: false,
separateBuiltins: true,
separateStubs: true,
separateBaselineHandlers: false,
preprocessJson: null,
sourceMap: null,
targetRootFS: '',
nm: 'nm',
objdump: 'objdump',
range: 'auto,auto',
distortion: 0,
timedRange: false,
pairwiseTimedRange: false,
onlySummary: false,
runtimeTimerFilter: null,
serializeVMSymbols: false,
};
}
}
export class TickProcessor extends LogReader {
static EntriesProvider = {
'linux': UnixCppEntriesProvider,
'windows': WindowsCppEntriesProvider,
'mac': MacCppEntriesProvider
};
static fromParams(params, entriesProvider) {
if (entriesProvider == undefined) {
entriesProvider = new this.EntriesProvider[params.platform](
params.nm, params.objdump, params.targetRootFS,
params.apkEmbeddedLibrary);
}
return new TickProcessor(
entriesProvider,
params.separateIc,
params.separateBytecodes,
params.separateBuiltins,
params.separateStubs,
params.separateBaselineHandlers,
params.callGraphSize,
params.ignoreUnknown,
params.stateFilter,
params.distortion,
params.range,
params.sourceMap,
params.timedRange,
params.pairwiseTimedRange,
params.onlySummary,
params.runtimeTimerFilter,
params.preprocessJson);
}
constructor(
cppEntriesProvider,
separateIc,
@ -588,7 +218,7 @@ export class TickProcessor extends LogReader {
if (!sourceMap) return null;
// Overwrite the load function to load scripts synchronously.
WebInspector.SourceMap.load = (sourceMapURL) => {
const content = d8.file.read(sourceMapURL);
const content = this.readFile(sourceMapURL);
const sourceMapObject = JSON.parse(content);
return new SourceMap(sourceMapURL, sourceMapObject);
};
@ -963,3 +593,342 @@ export class TickProcessor extends LogReader {
});
}
}
class CppEntriesProvider {
inRange(funcInfo, start, end) {
return funcInfo.start >= start && funcInfo.end <= end;
}
parseVmSymbols(libName, libStart, libEnd, libASLRSlide, processorFunc) {
this.loadSymbols(libName);
let lastUnknownSize;
let lastAdded;
let addEntry = (funcInfo) => {
// Several functions can be mapped onto the same address. To avoid
// creating zero-sized entries, skip such duplicates.
// Also double-check that function belongs to the library address space.
if (lastUnknownSize &&
lastUnknownSize.start < funcInfo.start) {
// Try to update lastUnknownSize based on new entries start position.
lastUnknownSize.end = funcInfo.start;
if ((!lastAdded ||
!this.inRange(lastUnknownSize, lastAdded.start, lastAdded.end)) &&
this.inRange(lastUnknownSize, libStart, libEnd)) {
processorFunc(
lastUnknownSize.name, lastUnknownSize.start, lastUnknownSize.end);
lastAdded = lastUnknownSize;
}
}
lastUnknownSize = undefined;
if (funcInfo.end) {
// Skip duplicates that have the same start address as the last added.
if ((!lastAdded || lastAdded.start != funcInfo.start) &&
this.inRange(funcInfo, libStart, libEnd)) {
processorFunc(funcInfo.name, funcInfo.start, funcInfo.end);
lastAdded = funcInfo;
}
} else {
// If a funcInfo doesn't have an end, try to match it up with then next
// entry.
lastUnknownSize = funcInfo;
}
}
while (true) {
const funcInfo = this.parseNextLine();
if (funcInfo === null) continue;
if (funcInfo === false) break;
if (funcInfo.start < libStart - libASLRSlide &&
funcInfo.start < libEnd - libStart) {
funcInfo.start += libStart;
} else {
funcInfo.start += libASLRSlide;
}
if (funcInfo.size) {
funcInfo.end = funcInfo.start + funcInfo.size;
}
addEntry(funcInfo);
}
addEntry({ name: '', start: libEnd });
}
loadSymbols(libName) {}
parseNextLine() { return false }
}
export class UnixCppEntriesProvider extends CppEntriesProvider {
constructor(nmExec, objdumpExec, targetRootFS, apkEmbeddedLibrary) {
super();
this.symbols = [];
// File offset of a symbol minus the virtual address of a symbol found in
// the symbol table.
this.fileOffsetMinusVma = 0;
this.parsePos = 0;
this.nmExec = nmExec;
this.objdumpExec = objdumpExec;
this.targetRootFS = targetRootFS;
this.apkEmbeddedLibrary = apkEmbeddedLibrary;
this.FUNC_RE = /^([0-9a-fA-F]{8,16}) ([0-9a-fA-F]{8,16} )?[tTwW] (.*)$/;
}
loadSymbols(libName) {
this.parsePos = 0;
if (this.apkEmbeddedLibrary && libName.endsWith('.apk')) {
libName = this.apkEmbeddedLibrary;
}
if (this.targetRootFS) {
libName = libName.substring(libName.lastIndexOf('/') + 1);
libName = this.targetRootFS + libName;
}
try {
this.symbols = [
os.system(this.nmExec, ['-C', '-n', '-S', libName], -1, -1),
os.system(this.nmExec, ['-C', '-n', '-S', '-D', libName], -1, -1)
];
const objdumpOutput = os.system(this.objdumpExec, ['-h', libName], -1, -1);
for (const line of objdumpOutput.split('\n')) {
const [, sectionName, , vma, , fileOffset] = line.trim().split(/\s+/);
if (sectionName === ".text") {
this.fileOffsetMinusVma = parseInt(fileOffset, 16) - parseInt(vma, 16);
}
}
} catch (e) {
// If the library cannot be found on this system let's not panic.
this.symbols = ['', ''];
}
}
parseNextLine() {
if (this.symbols.length == 0) {
return false;
}
const lineEndPos = this.symbols[0].indexOf('\n', this.parsePos);
if (lineEndPos == -1) {
this.symbols.shift();
this.parsePos = 0;
return this.parseNextLine();
}
const line = this.symbols[0].substring(this.parsePos, lineEndPos);
this.parsePos = lineEndPos + 1;
const fields = line.match(this.FUNC_RE);
let funcInfo = null;
if (fields) {
funcInfo = { name: fields[3], start: parseInt(fields[1], 16) + this.fileOffsetMinusVma };
if (fields[2]) {
funcInfo.size = parseInt(fields[2], 16);
}
}
return funcInfo;
}
}
export class MacCppEntriesProvider extends UnixCppEntriesProvider {
constructor(nmExec, objdumpExec, targetRootFS, apkEmbeddedLibrary) {
super(nmExec, objdumpExec, targetRootFS, apkEmbeddedLibrary);
// Note an empty group. It is required, as UnixCppEntriesProvider expects 3 groups.
this.FUNC_RE = /^([0-9a-fA-F]{8,16})() (.*)$/;
}
loadSymbols(libName) {
this.parsePos = 0;
libName = this.targetRootFS + libName;
// It seems that in OS X `nm` thinks that `-f` is a format option, not a
// "flat" display option flag.
try {
this.symbols = [os.system(this.nmExec, ['-n', libName], -1, -1), ''];
} catch (e) {
// If the library cannot be found on this system let's not panic.
this.symbols = '';
}
}
}
export class WindowsCppEntriesProvider extends CppEntriesProvider {
constructor(_ignored_nmExec, _ignored_objdumpExec, targetRootFS,
_ignored_apkEmbeddedLibrary) {
super();
this.targetRootFS = targetRootFS;
this.symbols = '';
this.parsePos = 0;
}
static FILENAME_RE = /^(.*)\.([^.]+)$/;
static FUNC_RE =
/^\s+0001:[0-9a-fA-F]{8}\s+([_\?@$0-9a-zA-Z]+)\s+([0-9a-fA-F]{8}).*$/;
static IMAGE_BASE_RE =
/^\s+0000:00000000\s+___ImageBase\s+([0-9a-fA-F]{8}).*$/;
// This is almost a constant on Windows.
static EXE_IMAGE_BASE = 0x00400000;
loadSymbols(libName) {
libName = this.targetRootFS + libName;
const fileNameFields = libName.match(WindowsCppEntriesProvider.FILENAME_RE);
if (!fileNameFields) return;
const mapFileName = `${fileNameFields[1]}.map`;
this.moduleType_ = fileNameFields[2].toLowerCase();
try {
this.symbols = read(mapFileName);
} catch (e) {
// If .map file cannot be found let's not panic.
this.symbols = '';
}
}
parseNextLine() {
const lineEndPos = this.symbols.indexOf('\r\n', this.parsePos);
if (lineEndPos == -1) {
return false;
}
const line = this.symbols.substring(this.parsePos, lineEndPos);
this.parsePos = lineEndPos + 2;
// Image base entry is above all other symbols, so we can just
// terminate parsing.
const imageBaseFields = line.match(WindowsCppEntriesProvider.IMAGE_BASE_RE);
if (imageBaseFields) {
const imageBase = parseInt(imageBaseFields[1], 16);
if ((this.moduleType_ == 'exe') !=
(imageBase == WindowsCppEntriesProvider.EXE_IMAGE_BASE)) {
return false;
}
}
const fields = line.match(WindowsCppEntriesProvider.FUNC_RE);
return fields ?
{ name: this.unmangleName(fields[1]), start: parseInt(fields[2], 16) } :
null;
}
/**
* Performs very simple unmangling of C++ names.
*
* Does not handle arguments and template arguments. The mangled names have
* the form:
*
* ?LookupInDescriptor@JSObject@internal@v8@@...arguments info...
*/
unmangleName(name) {
// Empty or non-mangled name.
if (name.length < 1 || name.charAt(0) != '?') return name;
const nameEndPos = name.indexOf('@@');
const components = name.substring(1, nameEndPos).split('@');
components.reverse();
return components.join('::');
}
}
export class ArgumentsProcessor extends BaseArgumentsProcessor {
getArgsDispatch() {
let dispatch = {
__proto__:null,
'-j': ['stateFilter', TickProcessor.VmStates.JS,
'Show only ticks from JS VM state'],
'-g': ['stateFilter', TickProcessor.VmStates.GC,
'Show only ticks from GC VM state'],
'-p': ['stateFilter', TickProcessor.VmStates.PARSER,
'Show only ticks from PARSER VM state'],
'-b': ['stateFilter', TickProcessor.VmStates.BYTECODE_COMPILER,
'Show only ticks from BYTECODE_COMPILER VM state'],
'-c': ['stateFilter', TickProcessor.VmStates.COMPILER,
'Show only ticks from COMPILER VM state'],
'-o': ['stateFilter', TickProcessor.VmStates.OTHER,
'Show only ticks from OTHER VM state'],
'-e': ['stateFilter', TickProcessor.VmStates.EXTERNAL,
'Show only ticks from EXTERNAL VM state'],
'--filter-runtime-timer': ['runtimeTimerFilter', null,
'Show only ticks matching the given runtime timer scope'],
'--call-graph-size': ['callGraphSize', TickProcessor.CALL_GRAPH_SIZE,
'Set the call graph size'],
'--ignore-unknown': ['ignoreUnknown', true,
'Exclude ticks of unknown code entries from processing'],
'--separate-ic': ['separateIc', parseBool,
'Separate IC entries'],
'--separate-bytecodes': ['separateBytecodes', parseBool,
'Separate Bytecode entries'],
'--separate-builtins': ['separateBuiltins', parseBool,
'Separate Builtin entries'],
'--separate-stubs': ['separateStubs', parseBool,
'Separate Stub entries'],
'--separate-baseline-handlers': ['separateBaselineHandlers', parseBool,
'Separate Baseline Handler entries'],
'--unix': ['platform', 'unix',
'Specify that we are running on *nix platform'],
'--windows': ['platform', 'windows',
'Specify that we are running on Windows platform'],
'--mac': ['platform', 'mac',
'Specify that we are running on Mac OS X platform'],
'--nm': ['nm', 'nm',
'Specify the \'nm\' executable to use (e.g. --nm=/my_dir/nm)'],
'--objdump': ['objdump', 'objdump',
'Specify the \'objdump\' executable to use (e.g. --objdump=/my_dir/objdump)'],
'--target': ['targetRootFS', '',
'Specify the target root directory for cross environment'],
'--apk-embedded-library': ['apkEmbeddedLibrary', '',
'Specify the path of the embedded library for Android traces'],
'--range': ['range', 'auto,auto',
'Specify the range limit as [start],[end]'],
'--distortion': ['distortion', 0,
'Specify the logging overhead in picoseconds'],
'--source-map': ['sourceMap', null,
'Specify the source map that should be used for output'],
'--timed-range': ['timedRange', true,
'Ignore ticks before first and after last Date.now() call'],
'--pairwise-timed-range': ['pairwiseTimedRange', true,
'Ignore ticks outside pairs of Date.now() calls'],
'--only-summary': ['onlySummary', true,
'Print only tick summary, exclude other information'],
'--serialize-vm-symbols': ['serializeVMSymbols', true,
'Print all C++ symbols and library addresses as JSON data'],
'--preprocess': ['preprocessJson', true,
'Preprocess for consumption with web interface']
};
dispatch['--js'] = dispatch['-j'];
dispatch['--gc'] = dispatch['-g'];
dispatch['--compiler'] = dispatch['-c'];
dispatch['--other'] = dispatch['-o'];
dispatch['--external'] = dispatch['-e'];
dispatch['--ptr'] = dispatch['--pairwise-timed-range'];
return dispatch;
}
getDefaultResults() {
return {
logFileName: 'v8.log',
platform: 'unix',
stateFilter: null,
callGraphSize: 5,
ignoreUnknown: false,
separateIc: true,
separateBytecodes: false,
separateBuiltins: true,
separateStubs: true,
separateBaselineHandlers: false,
preprocessJson: null,
sourceMap: null,
targetRootFS: '',
nm: 'nm',
objdump: 'objdump',
range: 'auto,auto',
distortion: 0,
timedRange: false,
pairwiseTimedRange: false,
onlySummary: false,
runtimeTimerFilter: null,
serializeVMSymbols: false,
};
}
}