Repository navigation
Description
Is your feature request related to a problem? Please describe.
The runtime ships a legacy profiler, added in 2016 (d81045c), next to the Chrome DevTools profiler:
Profiler.cppalways installs three globals:__startCPUProfiler(name)and__stopCPUProfiler(name)wrap V8'sCpuProfiler, and stopping writes<profilerOutputDir>/<app>-<name>-<time>.cpuprofile.__heapSnapshot()writes a.heapsnapshotfile to the same directory.
- Setting
android.profilerOutputDiralso turns onMetadataNode::Wrap. That compiles a named JS wrapper around every Java class constructor and every Java method (function getAlpha() { return getAlpha.__func.apply(this, arguments); }) so that profiles show Java member names. The wrappers add a JS frame to every call and replace the functions apps see. In that mode a wrapper'sprototype.constructoris the inner function, not the class the app sees.
As far as I can tell nobody uses it:
- nothing in core, the CLI, the plugins or angular sets
profilerOutputDir; - with the default empty value,
Writebuilds a path at/and fails, so the globals produce nothing unless the option is set.
The only consumers I found are @nativescript/core/profiling's startCPUProfile/stopCPUProfile, which call these globals on Android, and the profilerOutputDir entries in core's config.interface.ts and the CLI's project.d.ts.
The DevTools CPU and heap profilers cover the same ground through the inspector, with a better workflow. The one thing the legacy profiler does that they don't is to start and stop from app code with no inspector attached.
Describe the solution you'd like
-
Deprecate the legacy profiler.
- Log a deprecation warning when
profilerOutputDiris set. - Remove
MetadataNode::Wrapands_profilerEnabledin the next major release. - Decide what happens to
__startCPUProfiler/__stopCPUProfiler/__heapSnapshot, and to core'sstartCPUProfile/stopCPUProfile:- remove them along with the profiler;
- or keep them as thin helpers that write to the app's files directory by default, for profiling a release build without an inspector.
- Deprecate
profilerOutputDirin core's config types and the CLI's typings at the same time.
- Log a deprecation warning when
-
Make V8/DevTools profiles more informative instead. Java members should show up under useful names in a DevTools CPU profile without wrapper functions. Start by checking what a profile shows today for:
- Java class constructors (
FunctionTemplate::SetClassNameis already set to the dotted Java name); - instance and static methods (prototype template functions);
- field accessors and static members;
- functions created by
extendand interface implementations.
Then fill the gaps with V8's naming APIs:
FunctionTemplate::SetClassName,Function::SetName, or naming the template functions after their property keys. Where a name alone is ambiguous across overloads or same-named methods of different classes, include the declaring class, e.g.android.view.View.getAlpha.- Optionally, label the time spent in the JS↔Java bridge: callback dispatch from Java, argument conversion and
ObjectManagerwrapper creation. A DevTools profile could then tell bridge overhead apart from app JS. V8's CPU profiler supports embedder states and trace events that could carry this.
- Java class constructors (
Describe alternatives you've considered
- Keep the profiler as is. It costs little at runtime when off:
Wrapreturns the function unchanged unlessprofilerOutputDiris set. But it is unmaintained, undocumented, and has semantic quirks when on. - Keep only the wrapper naming. It changes the functions apps see and adds a frame per call, so it distorts the very profiles it is meant to label.
Additional context
This came up while optimizing JS wrapper creation for Java objects, in the follow-up to #2099. Dropping a wrapper's own constructor property only made a difference in this profiler mode, where wrapper.constructor now resolves to the inner, unwrapped constructor, as new-created instances already did.
Activity