Reproduce:
It will run require('v8').getHeapSnapshot() automaticlly after 5s. And in this case, getHeapSnapshot takes too long with this empty application.
Node-version: v12.8.3
Platform: Darwin
https://github.com/nodejs/node/blob/master/deps/v8/src/profiler/heap-snapshot-generator.cc#L575-L576
In fact, I think this is because when obtaining loactions during Takesnapshot, GetLineNumber / GetColumnNumber will trigger too many GetPositionInfoSlow in some cases.
Could we change the ExtractLocationForJSFunction
void V8HeapExplorer::ExtractLocationForJSFunction(HeapEntry* entry,
JSFunction func) {
if (!func.shared().script().IsScript()) return;
Script script = Script::cast(func.shared().script());
int scriptId = script.id();
int start = func.shared().StartPosition();
int line = script.GetLineNumber(start);
int col = script.GetColumnNumber(start);
snapshot_->AddLocation(entry, scriptId, line, col);
}
as
void V8HeapExplorer::ExtractLocationForJSFunction(HeapEntry* entry,
JSFunction func) {
if (!func.shared().script().IsScript()) return;
Script script = Script::cast(func.shared().script());
int scriptId = script.id();
int start = func.shared().StartPosition();
// this is for setting script line ends before getting script position info to
// prevent fallback to GetPositionInfoSlow.
i::Handle<i::Script> script2(i::Script::cast(script), func.shared().GetIsolate());
int line = script.GetLineNumber(script2, start);
int col = script.GetColumnNumber(script2, start);
snapshot_->AddLocation(entry, scriptId, line, col);
}
to speed up TakeSnapshot?
@hyj1991 Fixes to V8 should be sent to the upstream project (see https://v8.dev/docs/contribute) but if it's strictly a performance improvement (no observable changes except speed), it'll almost certainly get accepted.
We can back-port the change to Node.js after it's merged upstream.
Most helpful comment
https://chromium-review.googlesource.com/c/v8/v8/+/2362413