mirror of
https://github.com/dart-lang/sdk
synced 2024-09-15 22:00:09 +00:00
[dart2js] Moving runtime allocations to pkg:dart2js_runtime_metrics
* Stores runtime information on `$runtimeMetrics` instead of `$__dart_deferred_initializers__` * Keys each app's runtime allocations onto self.runtimeMetrics.$currentScript Change-Id: I6612fd2a5ac792bfcb7580ffe91d5391b80d5965 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/242507 Reviewed-by: Sigmund Cherem <sigmund@google.com> Reviewed-by: Stephen Adams <sra@google.com> Commit-Queue: Mark Zhou <markzipan@google.com>
This commit is contained in:
parent
f092184371
commit
a0b35de326
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
library dart2js.js_emitter.main_call_stub_generator;
|
library dart2js.js_emitter.main_call_stub_generator;
|
||||||
|
|
||||||
|
import 'package:compiler/src/options.dart';
|
||||||
import 'package:js_runtime/shared/embedded_names.dart' as embeddedNames;
|
import 'package:js_runtime/shared/embedded_names.dart' as embeddedNames;
|
||||||
|
|
||||||
import '../common/elements.dart';
|
import '../common/elements.dart';
|
||||||
|
@ -16,8 +17,12 @@ import '../js/js.dart' show js;
|
||||||
import 'code_emitter_task.dart' show Emitter;
|
import 'code_emitter_task.dart' show Emitter;
|
||||||
|
|
||||||
class MainCallStubGenerator {
|
class MainCallStubGenerator {
|
||||||
static jsAst.Statement generateInvokeMain(CommonElements commonElements,
|
static jsAst.Statement generateInvokeMain(
|
||||||
Emitter emitter, FunctionEntity main, bool requiresStartupMetrics) {
|
CommonElements commonElements,
|
||||||
|
Emitter emitter,
|
||||||
|
FunctionEntity main,
|
||||||
|
bool requiresStartupMetrics,
|
||||||
|
CompilerOptions options) {
|
||||||
jsAst.Expression mainAccess = emitter.staticFunctionAccess(main);
|
jsAst.Expression mainAccess = emitter.staticFunctionAccess(main);
|
||||||
jsAst.Expression currentScriptAccess =
|
jsAst.Expression currentScriptAccess =
|
||||||
emitter.generateEmbeddedGlobalAccess(embeddedNames.CURRENT_SCRIPT);
|
emitter.generateEmbeddedGlobalAccess(embeddedNames.CURRENT_SCRIPT);
|
||||||
|
@ -96,6 +101,10 @@ class MainCallStubGenerator {
|
||||||
if (#startupMetrics) {
|
if (#startupMetrics) {
|
||||||
init.#startupMetricsEmbeddedGlobal.add('callMainMs');
|
init.#startupMetricsEmbeddedGlobal.add('callMainMs');
|
||||||
}
|
}
|
||||||
|
if (#isCollectingRuntimeMetrics) {
|
||||||
|
self.#runtimeMetricsContainer = self.#runtimeMetricsContainer || Object.create(null);
|
||||||
|
self.#runtimeMetricsContainer[currentScript.src] = init.#runtimeMetricsEmbeddedGlobal;
|
||||||
|
}
|
||||||
var callMain = #mainCallClosure;
|
var callMain = #mainCallClosure;
|
||||||
if (typeof dartMainRunner === "function") {
|
if (typeof dartMainRunner === "function") {
|
||||||
dartMainRunner(callMain, []);
|
dartMainRunner(callMain, []);
|
||||||
|
@ -105,6 +114,9 @@ class MainCallStubGenerator {
|
||||||
})''', {
|
})''', {
|
||||||
'currentScript': currentScriptAccess,
|
'currentScript': currentScriptAccess,
|
||||||
'mainCallClosure': mainCallClosure,
|
'mainCallClosure': mainCallClosure,
|
||||||
|
'isCollectingRuntimeMetrics': options.experimentalTrackAllocations,
|
||||||
|
'runtimeMetricsContainer': embeddedNames.RUNTIME_METRICS_CONTAINER,
|
||||||
|
'runtimeMetricsEmbeddedGlobal': embeddedNames.RUNTIME_METRICS,
|
||||||
'startupMetrics': requiresStartupMetrics,
|
'startupMetrics': requiresStartupMetrics,
|
||||||
'startupMetricsEmbeddedGlobal': embeddedNames.STARTUP_METRICS,
|
'startupMetricsEmbeddedGlobal': embeddedNames.STARTUP_METRICS,
|
||||||
});
|
});
|
||||||
|
|
|
@ -296,8 +296,12 @@ class ProgramBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
js.Statement _buildInvokeMain() {
|
js.Statement _buildInvokeMain() {
|
||||||
return MainCallStubGenerator.generateInvokeMain(_commonElements,
|
return MainCallStubGenerator.generateInvokeMain(
|
||||||
_task.emitter, _mainFunction, _backendUsage.requiresStartupMetrics);
|
_commonElements,
|
||||||
|
_task.emitter,
|
||||||
|
_mainFunction,
|
||||||
|
_backendUsage.requiresStartupMetrics,
|
||||||
|
_options);
|
||||||
}
|
}
|
||||||
|
|
||||||
DeferredFragment _buildDeferredFragment(LibrariesMap librariesMap) {
|
DeferredFragment _buildDeferredFragment(LibrariesMap librariesMap) {
|
||||||
|
|
|
@ -46,6 +46,11 @@ if (#startupMetrics) {
|
||||||
.add("dartProgramMs");
|
.add("dartProgramMs");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (#isCollectingRuntimeMetrics) {
|
||||||
|
dartProgram.$RUNTIME_METRICS = Object.create(null);
|
||||||
|
var allocations = dartProgram.$RUNTIME_METRICS['allocations'] = Object.create(null);
|
||||||
|
}
|
||||||
|
|
||||||
// Copies the own properties from [from] to [to].
|
// Copies the own properties from [from] to [to].
|
||||||
function copyProperties(from, to) {
|
function copyProperties(from, to) {
|
||||||
var keys = Object.keys(from);
|
var keys = Object.keys(from);
|
||||||
|
@ -420,10 +425,6 @@ function initializeDeferredHunk(hunk) {
|
||||||
hunk(hunkHelpers, #embeddedGlobalsObject, holders, #staticState);
|
hunk(hunkHelpers, #embeddedGlobalsObject, holders, #staticState);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (#isTrackingAllocations) {
|
|
||||||
var allocations = #deferredGlobal['allocations'] = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Creates the holders.
|
// Creates the holders.
|
||||||
#holders;
|
#holders;
|
||||||
|
|
||||||
|
@ -523,7 +524,9 @@ const String _directAccessTestExpression = r'''
|
||||||
/// This template is used for Dart 2.
|
/// This template is used for Dart 2.
|
||||||
const String _deferredBoilerplate = '''
|
const String _deferredBoilerplate = '''
|
||||||
function(hunkHelpers, #embeddedGlobalsObject, holdersList, #staticState) {
|
function(hunkHelpers, #embeddedGlobalsObject, holdersList, #staticState) {
|
||||||
|
if (#isCollectingRuntimeMetrics) {
|
||||||
|
var allocations = #embeddedGlobalsObject.#runtimeMetrics['allocations'];
|
||||||
|
}
|
||||||
// Builds the holders. They only contain the data for new holders.
|
// Builds the holders. They only contain the data for new holders.
|
||||||
// If names are not set on functions, we do it now. Finally, updates the
|
// If names are not set on functions, we do it now. Finally, updates the
|
||||||
// holders of the main-fragment. Uses the provided holdersList to access the
|
// holders of the main-fragment. Uses the provided holdersList to access the
|
||||||
|
@ -751,8 +754,7 @@ class FragmentEmitter {
|
||||||
//'stubName': js.string(_namer.stubNameField),
|
//'stubName': js.string(_namer.stubNameField),
|
||||||
//'argumentCount': js.string(_namer.fixedNames.requiredParameterField),
|
//'argumentCount': js.string(_namer.fixedNames.requiredParameterField),
|
||||||
//'defaultArgumentValues': js.string(_namer.fixedNames.defaultValuesField),
|
//'defaultArgumentValues': js.string(_namer.fixedNames.defaultValuesField),
|
||||||
'deferredGlobal': ModelEmitter.deferredInitializersGlobal,
|
'isCollectingRuntimeMetrics': _options.experimentalTrackAllocations,
|
||||||
'isTrackingAllocations': _options.experimentalTrackAllocations,
|
|
||||||
'prototypes': emitPrototypes(fragment),
|
'prototypes': emitPrototypes(fragment),
|
||||||
'inheritance': emitInheritance(fragment),
|
'inheritance': emitInheritance(fragment),
|
||||||
'aliases': emitInstanceMethodAliases(fragment),
|
'aliases': emitInstanceMethodAliases(fragment),
|
||||||
|
@ -808,7 +810,9 @@ class FragmentEmitter {
|
||||||
js.Expression code = js.js(_deferredBoilerplate, {
|
js.Expression code = js.js(_deferredBoilerplate, {
|
||||||
// TODO(floitsch): don't just reference 'init'.
|
// TODO(floitsch): don't just reference 'init'.
|
||||||
'embeddedGlobalsObject': js.Parameter('init'),
|
'embeddedGlobalsObject': js.Parameter('init'),
|
||||||
|
'isCollectingRuntimeMetrics': _options.experimentalTrackAllocations,
|
||||||
'staticState': DeferredHolderParameter(),
|
'staticState': DeferredHolderParameter(),
|
||||||
|
'runtimeMetrics': RUNTIME_METRICS,
|
||||||
'updateHolders': updateHolders,
|
'updateHolders': updateHolders,
|
||||||
'prototypes': fragment.classPrototypes,
|
'prototypes': fragment.classPrototypes,
|
||||||
'closures': fragment.closurePrototypes,
|
'closures': fragment.closurePrototypes,
|
||||||
|
@ -1875,6 +1879,12 @@ class FragmentEmitter {
|
||||||
js.string(STARTUP_METRICS), js.js('dartProgram.$STARTUP_METRICS')));
|
js.string(STARTUP_METRICS), js.js('dartProgram.$STARTUP_METRICS')));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_options.experimentalTrackAllocations) {
|
||||||
|
// Copy the metrics object that was stored on the main unit IIFE.
|
||||||
|
globals.add(js.Property(
|
||||||
|
js.string(RUNTIME_METRICS), js.js('dartProgram.$RUNTIME_METRICS')));
|
||||||
|
}
|
||||||
|
|
||||||
js.ObjectInitializer globalsObject =
|
js.ObjectInitializer globalsObject =
|
||||||
js.ObjectInitializer(globals, isOneLiner: false);
|
js.ObjectInitializer(globals, isOneLiner: false);
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ import 'package:js_runtime/shared/embedded_names.dart'
|
||||||
NATIVE_SUPERCLASS_TAG_NAME,
|
NATIVE_SUPERCLASS_TAG_NAME,
|
||||||
RTI_UNIVERSE,
|
RTI_UNIVERSE,
|
||||||
RtiUniverseFieldNames,
|
RtiUniverseFieldNames,
|
||||||
|
RUNTIME_METRICS,
|
||||||
STARTUP_METRICS,
|
STARTUP_METRICS,
|
||||||
TearOffParametersPropertyNames,
|
TearOffParametersPropertyNames,
|
||||||
TYPE_TO_INTERCEPTOR_MAP,
|
TYPE_TO_INTERCEPTOR_MAP,
|
||||||
|
@ -368,19 +369,11 @@ class ModelEmitter {
|
||||||
return js.Comment(generatedBy(_options, flavor: '$flavor'));
|
return js.Comment(generatedBy(_options, flavor: '$flavor'));
|
||||||
}
|
}
|
||||||
|
|
||||||
List<js.Statement> buildDeferredInitializerGlobal() {
|
js.Statement buildDeferredInitializerGlobal() {
|
||||||
return [
|
return js.js.statement(
|
||||||
js.js.statement(
|
'self.#deferredInitializers = '
|
||||||
'self.#deferredInitializers = '
|
'self.#deferredInitializers || Object.create(null);',
|
||||||
'self.#deferredInitializers || Object.create(null);',
|
{'deferredInitializers': deferredInitializersGlobal});
|
||||||
{'deferredInitializers': deferredInitializersGlobal}),
|
|
||||||
if (_options.experimentalTrackAllocations)
|
|
||||||
js.js.statement(
|
|
||||||
'self.#deferredInitializers["allocations"] = '
|
|
||||||
'self.#deferredInitializers["allocations"] '
|
|
||||||
'|| Object.create(null)',
|
|
||||||
{'deferredInitializers': deferredInitializersGlobal})
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
js.Statement buildStartupMetrics() {
|
js.Statement buildStartupMetrics() {
|
||||||
|
@ -431,7 +424,7 @@ var ${startupMetricsGlobal} =
|
||||||
js.Program program = js.Program([
|
js.Program program = js.Program([
|
||||||
buildGeneratedBy(),
|
buildGeneratedBy(),
|
||||||
js.Comment(HOOKS_API_USAGE),
|
js.Comment(HOOKS_API_USAGE),
|
||||||
if (isSplit) ...buildDeferredInitializerGlobal(),
|
if (isSplit) buildDeferredInitializerGlobal(),
|
||||||
if (_closedWorld.backendUsage.requiresStartupMetrics)
|
if (_closedWorld.backendUsage.requiresStartupMetrics)
|
||||||
buildStartupMetrics(),
|
buildStartupMetrics(),
|
||||||
code
|
code
|
||||||
|
@ -566,10 +559,7 @@ var ${startupMetricsGlobal} =
|
||||||
|
|
||||||
js.Program program = js.Program([
|
js.Program program = js.Program([
|
||||||
if (isFirst) buildGeneratedBy(),
|
if (isFirst) buildGeneratedBy(),
|
||||||
if (isFirst) ...buildDeferredInitializerGlobal(),
|
if (isFirst) buildDeferredInitializerGlobal(),
|
||||||
if (_options.experimentalTrackAllocations)
|
|
||||||
js.js.statement("var allocations = #deferredGlobal['allocations']",
|
|
||||||
{'deferredGlobal': deferredInitializersGlobal}),
|
|
||||||
js.js.statement('$deferredInitializersGlobal.current = #', code)
|
js.js.statement('$deferredInitializersGlobal.current = #', code)
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
## 0.2.0
|
||||||
|
|
||||||
|
- Adding `runtimeMetrics`.
|
||||||
|
|
||||||
## 0.1.0
|
## 0.1.0
|
||||||
|
|
||||||
- Initial version.
|
- Initial version.
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
|
||||||
|
// for details. All rights reserved. Use of this source code is governed by a
|
||||||
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
export 'dart:_dart2js_runtime_metrics' show runtimeMetrics;
|
|
@ -0,0 +1,12 @@
|
||||||
|
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
|
||||||
|
// for details. All rights reserved. Use of this source code is governed by a
|
||||||
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
/// A collection of metrics collected during the runtime of a Dart app.
|
||||||
|
///
|
||||||
|
/// The contents of the map depend on the platform. The map values are simple
|
||||||
|
/// objects (strings, numbers, Booleans). There is always an entry for the key
|
||||||
|
/// `'runtime'` with a [String] value.
|
||||||
|
Map<String, Object> get runtimeMetrics {
|
||||||
|
return {'runtime': 'dartdevc'};
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
|
||||||
|
// for details. All rights reserved. Use of this source code is governed by a
|
||||||
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
/// A collection of metrics collected during the runtime of a Dart app.
|
||||||
|
///
|
||||||
|
/// The contents of the map depend on the platform. The map values are simple
|
||||||
|
/// objects (strings, numbers, Booleans). There is always an entry for the key
|
||||||
|
/// `'runtime'` with a [String] value.
|
||||||
|
Map<String, Object> get runtimeMetrics {
|
||||||
|
return {'runtime': 'unknown'};
|
||||||
|
}
|
12
pkg/dart2js_runtime_metrics/lib/_runtime_metrics_vm.dart
Normal file
12
pkg/dart2js_runtime_metrics/lib/_runtime_metrics_vm.dart
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
|
||||||
|
// for details. All rights reserved. Use of this source code is governed by a
|
||||||
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
/// A collection of metrics collected during the runtime of a Dart app.
|
||||||
|
///
|
||||||
|
/// The contents of the map depend on the platform. The map values are simple
|
||||||
|
/// objects (strings, numbers, Booleans). There is always an entry for the key
|
||||||
|
/// `'runtime'` with a [String] value.
|
||||||
|
Map<String, Object> get runtimeMetrics {
|
||||||
|
return {'runtime': 'vm'};
|
||||||
|
}
|
8
pkg/dart2js_runtime_metrics/lib/runtime_metrics.dart
Normal file
8
pkg/dart2js_runtime_metrics/lib/runtime_metrics.dart
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
|
||||||
|
// for details. All rights reserved. Use of this source code is governed by a
|
||||||
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
export '_runtime_metrics_unknown.dart'
|
||||||
|
if (dart.library._dart2js_runtime_metrics) '_runtime_metrics_dart2js.dart'
|
||||||
|
if (dart.library.ffi) '_runtime_metrics_vm.dart'
|
||||||
|
if (dart.library.js) '_runtime_metrics_dartdevc.dart';
|
|
@ -1,7 +1,7 @@
|
||||||
name: dart2js_runtime_metrics
|
name: dart2js_runtime_metrics
|
||||||
# This package is not intended for consumption on pub.dev. DO NOT publish.
|
# This package is not intended for consumption on pub.dev. DO NOT publish.
|
||||||
publish_to: none
|
publish_to: none
|
||||||
version: 0.1.0
|
version: 0.2.0
|
||||||
description: >-
|
description: >-
|
||||||
`dart2js` can generate extra code to measure certain activities.
|
`dart2js` can generate extra code to measure certain activities.
|
||||||
This library provides access to the measurements at runtime.
|
This library provides access to the measurements at runtime.
|
||||||
|
|
51
pkg/dart2js_runtime_metrics/test/runtime_metrics_test.dart
Normal file
51
pkg/dart2js_runtime_metrics/test/runtime_metrics_test.dart
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
|
||||||
|
// for details. All rights reserved. Use of this source code is governed by a
|
||||||
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// dart2jsOptions=--experimental-track-allocations
|
||||||
|
|
||||||
|
import 'package:dart2js_runtime_metrics/runtime_metrics.dart';
|
||||||
|
import 'package:expect/expect.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
Map<String, Object> metrics = runtimeMetrics;
|
||||||
|
|
||||||
|
print('metrics: $metrics');
|
||||||
|
|
||||||
|
String expectedRuntime;
|
||||||
|
if (1.0 is! int) {
|
||||||
|
expectedRuntime = 'vm';
|
||||||
|
} else if (ClassWithLongName().toString().contains('minified:')) {
|
||||||
|
// dart2js minified: "Instance of 'minified:xy'".
|
||||||
|
expectedRuntime = 'dart2js';
|
||||||
|
} else if ('$main' == "Closure 'main'") {
|
||||||
|
// dart2js non-minified.
|
||||||
|
expectedRuntime = 'dart2js';
|
||||||
|
} else if ('$main'.startsWith('Closure: () => void from: function main()')) {
|
||||||
|
expectedRuntime = 'dartdevc';
|
||||||
|
} else {
|
||||||
|
throw 'Cannot feature-test current runtime:'
|
||||||
|
'\nmetrics = $metrics\n main = $main';
|
||||||
|
}
|
||||||
|
|
||||||
|
Expect.isTrue(metrics.containsKey('runtime'), "Has 'runtime' key: $metrics");
|
||||||
|
Expect.equals(expectedRuntime, metrics['runtime'],
|
||||||
|
"Expected 'runtime: $expectedRuntime': $metrics");
|
||||||
|
|
||||||
|
if (expectedRuntime == 'dart2js') {
|
||||||
|
Expect.isTrue(metrics.containsKey('allocations'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expectedRuntime == 'dartdevc') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expectedRuntime == 'vm') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw 'Should not get here.';
|
||||||
|
}
|
||||||
|
|
||||||
|
class ClassWithLongName {}
|
|
@ -179,6 +179,12 @@ const DEFERRED_INITIALIZED = 'deferredInitialized';
|
||||||
/// This embedded global is used for --experiment-new-rti.
|
/// This embedded global is used for --experiment-new-rti.
|
||||||
const RTI_UNIVERSE = 'typeUniverse';
|
const RTI_UNIVERSE = 'typeUniverse';
|
||||||
|
|
||||||
|
/// An embedded global used to collect and access runtime metrics.
|
||||||
|
const RUNTIME_METRICS = 'rm';
|
||||||
|
|
||||||
|
/// Global name that holds runtime metrics Dart2JS apps.
|
||||||
|
const RUNTIME_METRICS_CONTAINER = 'runtimeMetrics';
|
||||||
|
|
||||||
/// An embedded global used to collect and access startup metrics.
|
/// An embedded global used to collect and access startup metrics.
|
||||||
const STARTUP_METRICS = 'sm';
|
const STARTUP_METRICS = 'sm';
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,12 @@
|
||||||
|
|
||||||
library dart2js_runtime_metrics;
|
library dart2js_runtime_metrics;
|
||||||
|
|
||||||
import 'dart:_js_helper' show fillLiteralMap, rawStartupMetrics;
|
import 'dart:_js_helper'
|
||||||
|
show
|
||||||
|
copyAndStringifyProperties,
|
||||||
|
fillLiteralMap,
|
||||||
|
rawRuntimeMetrics,
|
||||||
|
rawStartupMetrics;
|
||||||
|
|
||||||
/// A collection of metrics for events that happen before `main()` is entered.
|
/// A collection of metrics for events that happen before `main()` is entered.
|
||||||
///
|
///
|
||||||
|
@ -35,3 +40,23 @@ Map<String, Object> get startupMetrics {
|
||||||
fillLiteralMap(raw, result);
|
fillLiteralMap(raw, result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A collection of metrics collected during the runtime of a Dart app.
|
||||||
|
///
|
||||||
|
/// The contents of the map depend on the platform. The map values are simple
|
||||||
|
/// objects (strings, numbers, Booleans). There is always an entry for the key
|
||||||
|
/// `'runtime'` with a [String] value.
|
||||||
|
///
|
||||||
|
/// This implementation for dart2js has the content (subject to change):
|
||||||
|
///
|
||||||
|
/// - `runtime`: `'dart2js'`
|
||||||
|
///
|
||||||
|
/// - `allocations`: A string representation of a Json Map<String, Object>,
|
||||||
|
/// which holds every class or closure created at runtime. The key contains
|
||||||
|
/// a resolved path of the class or closure. The value is currently unused.
|
||||||
|
Map<String, Object> get runtimeMetrics {
|
||||||
|
final Map<String, Object> result = {'runtime': 'dart2js'};
|
||||||
|
final raw = rawRuntimeMetrics();
|
||||||
|
copyAndStringifyProperties(raw, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ import 'dart:_js_embedded_names'
|
||||||
JsGetName,
|
JsGetName,
|
||||||
LEAF_TAGS,
|
LEAF_TAGS,
|
||||||
NATIVE_SUPERCLASS_TAG_NAME,
|
NATIVE_SUPERCLASS_TAG_NAME,
|
||||||
|
RUNTIME_METRICS,
|
||||||
STARTUP_METRICS,
|
STARTUP_METRICS,
|
||||||
STATIC_FUNCTION_NAME_PROPERTY_NAME,
|
STATIC_FUNCTION_NAME_PROPERTY_NAME,
|
||||||
TearOffParametersPropertyNames;
|
TearOffParametersPropertyNames;
|
||||||
|
@ -1801,6 +1802,21 @@ fillLiteralSet(values, Set result) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Called by generated code to move and stringify properties from an object
|
||||||
|
/// to a map literal.
|
||||||
|
copyAndStringifyProperties(from, Map to) {
|
||||||
|
if (JS('bool', '!#', from)) return to;
|
||||||
|
List keys = JS('JSArray', r'Object.keys(#)', from);
|
||||||
|
int index = 0;
|
||||||
|
int length = getLength(keys);
|
||||||
|
while (index < length) {
|
||||||
|
var key = getIndex(keys, index++);
|
||||||
|
var value = JS('String', r'JSON.stringify(#[#])', from, key);
|
||||||
|
to[key] = value;
|
||||||
|
}
|
||||||
|
return to;
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the property [index] of the JavaScript array [array].
|
/// Returns the property [index] of the JavaScript array [array].
|
||||||
getIndex(var array, int index) {
|
getIndex(var array, int index) {
|
||||||
return JS('var', r'#[#]', array, index);
|
return JS('var', r'#[#]', array, index);
|
||||||
|
@ -3064,6 +3080,10 @@ Object? rawStartupMetrics() {
|
||||||
return JS('JSArray', '#.a', JS_EMBEDDED_GLOBAL('', STARTUP_METRICS));
|
return JS('JSArray', '#.a', JS_EMBEDDED_GLOBAL('', STARTUP_METRICS));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Object? rawRuntimeMetrics() {
|
||||||
|
return JS('', '#', JS_EMBEDDED_GLOBAL('', RUNTIME_METRICS));
|
||||||
|
}
|
||||||
|
|
||||||
/// Wraps the given [callback] within the current Zone.
|
/// Wraps the given [callback] within the current Zone.
|
||||||
void Function(T)? wrapZoneUnaryCallback<T>(void Function(T)? callback) {
|
void Function(T)? wrapZoneUnaryCallback<T>(void Function(T)? callback) {
|
||||||
// For performance reasons avoid wrapping if we are in the root zone.
|
// For performance reasons avoid wrapping if we are in the root zone.
|
||||||
|
|
|
@ -179,6 +179,12 @@ const DEFERRED_INITIALIZED = 'deferredInitialized';
|
||||||
/// This embedded global is used for --experiment-new-rti.
|
/// This embedded global is used for --experiment-new-rti.
|
||||||
const RTI_UNIVERSE = 'typeUniverse';
|
const RTI_UNIVERSE = 'typeUniverse';
|
||||||
|
|
||||||
|
/// An embedded global used to collect and access runtime metrics.
|
||||||
|
const RUNTIME_METRICS = 'rm';
|
||||||
|
|
||||||
|
/// Global name that holds runtime metrics Dart2JS apps.
|
||||||
|
const RUNTIME_METRICS_CONTAINER = 'runtimeMetrics';
|
||||||
|
|
||||||
/// An embedded global used to collect and access startup metrics.
|
/// An embedded global used to collect and access startup metrics.
|
||||||
const STARTUP_METRICS = 'sm';
|
const STARTUP_METRICS = 'sm';
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue