[dart2js] Add dart:_dart2js_runtime_metrics library and package

The internal dart:_dart2js_runtime_metrics library is accessed via
package:dart2js_runtime_metrics.

There is currently one API: startupMetrics.

On non-dart2js configurations the API is stubbed for ease-of-use.

Change-Id: I80c56a83fd166ec19c3846fb6937cf0440ed2c6b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/208563
Commit-Queue: Stephen Adams <sra@google.com>
Reviewed-by: Sigmund Cherem <sigmund@google.com>
This commit is contained in:
Stephen Adams 2021-08-03 18:25:00 +00:00 committed by commit-bot@chromium.org
parent 3fb85e4342
commit 23b50dfa7d
29 changed files with 329 additions and 12 deletions

View file

@ -11,7 +11,7 @@
"constraint, update this by running tools/generate_package_config.dart."
],
"configVersion": 2,
"generated": "2021-07-27T19:27:52.638315",
"generated": "2021-07-30T20:37:49.663747",
"generator": "tools/generate_package_config.dart",
"packages": [
{
@ -204,6 +204,12 @@
"packageUri": "lib/",
"languageVersion": "2.3"
},
{
"name": "dart2js_runtime_metrics",
"rootUri": "../pkg/dart2js_runtime_metrics",
"packageUri": "lib/",
"languageVersion": "2.14"
},
{
"name": "dart2js_tools",
"rootUri": "../pkg/dart2js_tools",

View file

@ -30,6 +30,7 @@ convert:third_party/pkg/convert/lib
crypto:third_party/pkg/crypto/lib
csslib:third_party/pkg/csslib/lib
dart2js_info:third_party/pkg/dart2js_info/lib
dart2js_runtime_metrics:pkg/dart2js_runtime_metrics/lib
dart2js_tools:pkg/dart2js_tools/lib
dart2native:pkg/dart2native/lib
dart_internal:pkg/dart_internal/lib

View file

@ -388,6 +388,9 @@ abstract class CommonElements {
/// Holds the method "requiresPreamble" in _js_helper.
FunctionEntity get requiresPreambleMarker;
/// Holds the method "_rawStartupMetrics" in _js_helper.
FunctionEntity get rawStartupMetrics;
FunctionEntity get loadLibraryWrapper;
FunctionEntity get loadDeferredLibrary;
@ -1665,6 +1668,11 @@ class CommonElementsImpl
FunctionEntity get requiresPreambleMarker =>
_requiresPreambleMarker ??= _findHelperFunction('requiresPreamble');
FunctionEntity _rawStartupMetrics;
@override
FunctionEntity get rawStartupMetrics =>
_rawStartupMetrics ??= _findHelperFunction('rawStartupMetrics');
@override
FunctionEntity get loadLibraryWrapper =>
_findHelperFunction("_loadLibraryWrapper");

View file

@ -51,6 +51,9 @@ abstract class BackendUsage {
/// `true` if 'dart:mirrors' features are used.
bool get isMirrorsUsed;
/// `true` if startup timestamps are used.
bool get requiresStartupMetrics;
/// `true` if `noSuchMethod` is used.
bool get isNoSuchMethodUsed;
@ -120,6 +123,9 @@ class BackendUsageBuilderImpl implements BackendUsageBuilder {
/// `true` if a core-library function requires the preamble file to function.
bool requiresPreamble = false;
/// `true` if a core-library function accesses startup timestamps.
bool requiresStartupMetrics = false;
@override
bool isFunctionApplyUsed = false;
@ -242,6 +248,8 @@ class BackendUsageBuilderImpl implements BackendUsageBuilder {
isFunctionApplyUsed = true;
} else if (member.library == _commonElements.mirrorsLibrary) {
isMirrorsUsed = true;
} else if (member == _commonElements.rawStartupMetrics) {
requiresStartupMetrics = true;
}
}
@ -275,7 +283,7 @@ class BackendUsageBuilderImpl implements BackendUsageBuilder {
@override
BackendUsage close() {
return new BackendUsageImpl(
return BackendUsageImpl(
globalFunctionDependencies: _globalFunctionDependencies,
globalClassDependencies: _globalClassDependencies,
helperFunctionsUsed: _helperFunctionsUsed,
@ -283,6 +291,7 @@ class BackendUsageBuilderImpl implements BackendUsageBuilder {
needToInitializeIsolateAffinityTag: _needToInitializeIsolateAffinityTag,
needToInitializeDispatchProperty: _needToInitializeDispatchProperty,
requiresPreamble: requiresPreamble,
requiresStartupMetrics: requiresStartupMetrics,
runtimeTypeUses: _runtimeTypeUses,
isFunctionApplyUsed: isFunctionApplyUsed,
isMirrorsUsed: isMirrorsUsed,
@ -316,6 +325,9 @@ class BackendUsageImpl implements BackendUsage {
@override
final bool requiresPreamble;
@override
final bool requiresStartupMetrics;
@override
final bool isFunctionApplyUsed;
@ -336,6 +348,7 @@ class BackendUsageImpl implements BackendUsage {
this.needToInitializeIsolateAffinityTag,
this.needToInitializeDispatchProperty,
this.requiresPreamble,
this.requiresStartupMetrics,
Set<RuntimeTypeUse> runtimeTypeUses,
this.isFunctionApplyUsed,
this.isMirrorsUsed,
@ -364,12 +377,13 @@ class BackendUsageImpl implements BackendUsage {
bool needToInitializeIsolateAffinityTag = source.readBool();
bool needToInitializeDispatchProperty = source.readBool();
bool requiresPreamble = source.readBool();
bool requiresStartupMetrics = source.readBool();
bool isFunctionApplyUsed = source.readBool();
bool isMirrorsUsed = source.readBool();
bool isNoSuchMethodUsed = source.readBool();
bool isHtmlLoaded = source.readBool();
source.end(tag);
return new BackendUsageImpl(
return BackendUsageImpl(
globalFunctionDependencies: globalFunctionDependencies,
globalClassDependencies: globalClassDependencies,
helperFunctionsUsed: helperFunctionsUsed,
@ -378,6 +392,7 @@ class BackendUsageImpl implements BackendUsage {
needToInitializeIsolateAffinityTag: needToInitializeIsolateAffinityTag,
needToInitializeDispatchProperty: needToInitializeDispatchProperty,
requiresPreamble: requiresPreamble,
requiresStartupMetrics: requiresStartupMetrics,
isFunctionApplyUsed: isFunctionApplyUsed,
isMirrorsUsed: isMirrorsUsed,
isNoSuchMethodUsed: isNoSuchMethodUsed,
@ -399,6 +414,7 @@ class BackendUsageImpl implements BackendUsage {
sink.writeBool(needToInitializeIsolateAffinityTag);
sink.writeBool(needToInitializeDispatchProperty);
sink.writeBool(requiresPreamble);
sink.writeBool(requiresStartupMetrics);
sink.writeBool(isFunctionApplyUsed);
sink.writeBool(isMirrorsUsed);
sink.writeBool(isNoSuchMethodUsed);

View file

@ -14,8 +14,8 @@ import '../common_elements.dart';
import 'code_emitter_task.dart' show Emitter;
class MainCallStubGenerator {
static jsAst.Statement generateInvokeMain(
CommonElements commonElements, Emitter emitter, FunctionEntity main) {
static jsAst.Statement generateInvokeMain(CommonElements commonElements,
Emitter emitter, FunctionEntity main, bool requiresStartupMetrics) {
jsAst.Expression mainAccess = emitter.staticFunctionAccess(main);
jsAst.Expression currentScriptAccess =
emitter.generateEmbeddedGlobalAccess(embeddedNames.CURRENT_SCRIPT);
@ -90,6 +90,10 @@ class MainCallStubGenerator {
}
})(function(currentScript) {
#currentScript = currentScript;
if (#startupMetrics) {
init.#startupMetricsEmbeddedGlobal.add('callMainMs');
}
var callMain = #mainCallClosure;
if (typeof dartMainRunner === "function") {
dartMainRunner(callMain, []);
@ -98,7 +102,9 @@ class MainCallStubGenerator {
}
})''', {
'currentScript': currentScriptAccess,
'mainCallClosure': mainCallClosure
'mainCallClosure': mainCallClosure,
'startupMetrics': requiresStartupMetrics,
'startupMetricsEmbeddedGlobal': embeddedNames.STARTUP_METRICS,
});
}
}

View file

@ -294,8 +294,8 @@ class ProgramBuilder {
}
js.Statement _buildInvokeMain() {
return MainCallStubGenerator.generateInvokeMain(
_commonElements, _task.emitter, _mainFunction);
return MainCallStubGenerator.generateInvokeMain(_commonElements,
_task.emitter, _mainFunction, _backendUsage.requiresStartupMetrics);
}
DeferredFragment _buildDeferredFragment(LibrariesMap librariesMap) {

View file

@ -35,6 +35,15 @@ part of dart2js.js_emitter.startup_emitter.model_emitter;
// reducing their size.
const String _mainBoilerplate = '''
(function dartProgram() {
if (#startupMetrics) {
// Stash the metrics on the main unit IIFE.
// TODO(sra): When the JavaScript local renamer is more intelligent, we can
// simply use a local variable.
(dartProgram.$STARTUP_METRICS = ${ModelEmitter.startupMetricsGlobal})
.add("dartProgramMs");
}
// Copies the own properties from [from] to [to].
function copyProperties(from, to) {
var keys = Object.keys(from);
@ -469,7 +478,7 @@ convertToFastObject(#staticState);
// Invokes main (making sure that it records the 'current-script' value).
#invokeMain;
})()
})();
''';
/// An expression that returns `true` if `__proto__` can be assigned to stitch
@ -720,6 +729,7 @@ class FragmentEmitter {
'staticStateDeclaration': DeferredHolderParameter(),
'staticState': DeferredHolderParameter(),
'holders': holderDeclaration,
'startupMetrics': _closedWorld.backendUsage.requiresStartupMetrics,
// Tearoff parameters:
'tpContainer': js.string(TearOffParametersPropertyNames.container),
@ -1847,6 +1857,12 @@ class FragmentEmitter {
r' : "$ti"')
: js.js(r'Symbol("$ti")')));
if (_closedWorld.backendUsage.requiresStartupMetrics) {
// Copy the metrics object that was stored on the main unit IIFE.
globals.add(js.Property(
js.string(STARTUP_METRICS), js.js('dartProgram.$STARTUP_METRICS')));
}
js.ObjectInitializer globalsObject =
js.ObjectInitializer(globals, isOneLiner: false);

View file

@ -25,6 +25,7 @@ import 'package:js_runtime/shared/embedded_names.dart'
NATIVE_SUPERCLASS_TAG_NAME,
RTI_UNIVERSE,
RtiUniverseFieldNames,
STARTUP_METRICS,
TearOffParametersPropertyNames,
TYPE_TO_INTERCEPTOR_MAP,
TYPES;
@ -136,6 +137,8 @@ class ModelEmitter {
static const String deferredInitializersGlobal =
r"$__dart_deferred_initializers__";
static const String startupMetricsGlobal = r'$__dart_startupMetrics';
static const String partExtension = "part";
static const String deferredExtension = "part.js";
@ -372,6 +375,32 @@ class ModelEmitter {
{'deferredInitializers': deferredInitializersGlobal});
}
js.Statement buildStartupMetrics() {
// We want the code that initializes the startup metrics to execute as early
// as possible, so it is placed ahead of the main program IIFE instead of,
// e.g. as a parameter of the IIFE. It is OK to use a top-level variable,
// since the IIFE immediately reads the variable.
return js.js.statement('''
var ${startupMetricsGlobal} =
(function(){
// The timestamp metrics use `performance.now()`. We feature-detect and
// fall back on `Date.now()` for JavaScript run in a non-browser evironment.
var _performance =
(typeof performance == "object" &&
performance != null &&
typeof performance.now == "function")
? performance
: Date;
var metrics = {
a: [],
now: function() { return _performance.now() },
add: function(name) { this.a.push(name, this.now()); }
};
metrics.add('firstMs');
return metrics;
})();''');
}
// Writes the given [fragment]'s [code] into a file.
//
// Updates the shared [outputBuffers] field with the output.
@ -395,6 +424,8 @@ class ModelEmitter {
buildGeneratedBy(),
js.Comment(HOOKS_API_USAGE),
if (isSplit) buildDeferredInitializerGlobal(),
if (_closedWorld.backendUsage.requiresStartupMetrics)
buildStartupMetrics(),
code
]);

View file

@ -256,7 +256,7 @@ class JsClosedWorldBuilder {
map.toBackendType(runtimeTypeUse.argumentType));
}).toSet();
return new BackendUsageImpl(
return BackendUsageImpl(
globalFunctionDependencies: globalFunctionDependencies,
globalClassDependencies: globalClassDependencies,
helperFunctionsUsed: helperFunctionsUsed,
@ -266,6 +266,7 @@ class JsClosedWorldBuilder {
needToInitializeDispatchProperty:
backendUsage.needToInitializeDispatchProperty,
requiresPreamble: backendUsage.requiresPreamble,
requiresStartupMetrics: backendUsage.requiresStartupMetrics,
runtimeTypeUses: runtimeTypeUses,
isFunctionApplyUsed: backendUsage.isFunctionApplyUsed,
isMirrorsUsed: backendUsage.isMirrorsUsed,

View file

@ -131,7 +131,9 @@ class Dart2jsTarget extends Target {
@override
bool allowPlatformPrivateLibraryAccess(Uri importer, Uri imported) =>
super.allowPlatformPrivateLibraryAccess(importer, imported) ||
maybeEnableNative(importer);
maybeEnableNative(importer) ||
(importer.scheme == 'package' &&
importer.path.startsWith('dart2js_runtime_metrics/'));
@override
bool enableNative(Uri uri) => maybeEnableNative(uri);
@ -235,6 +237,7 @@ class Dart2jsTarget extends Target {
// compile-platform should just specify which libraries to compile instead.
const _requiredLibraries = const <String, List<String>>{
'dart2js': const <String>[
'dart:_dart2js_runtime_metrics',
'dart:_foreign_helper',
'dart:_interceptors',
'dart:_internal',
@ -258,6 +261,7 @@ const _requiredLibraries = const <String, List<String>>{
'dart:web_sql',
],
'dart2js_server': const <String>[
'dart:_dart2js_runtime_metrics',
'dart:_foreign_helper',
'dart:_interceptors',
'dart:_internal',

View file

@ -0,0 +1,3 @@
## 0.1.0
- Initial version.

View file

@ -0,0 +1,27 @@
Copyright 2021, the Dart project authors.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of Google LLC nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View file

@ -0,0 +1,13 @@
☠☠ **Warning: This package is experimental and may be removed in a future
version of Dart.** ☠☠
`dart2js` can generate extra code to measure certain activities.
This library provides access to the measurements at runtime.
An application might make timings and other measurements and report them back to
a server in order to collect information on how the application is working in
production. The APIs in this library provide access to measurements that require
help from dart2js. For example, `startupMetrics` accesses measurements of
activities that happen as the program is loaded, before `main()`.
The APIs are stubbed so that dummy values are returned on the VM and dartdevc.

View file

@ -0,0 +1,5 @@
analyzer:
errors:
import_internal_library: ignore
strong-mode:
implicit-casts: false

View file

@ -0,0 +1,5 @@
// Copyright (c) 2021, 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 startupMetrics;

View file

@ -0,0 +1,12 @@
// Copyright (c) 2021, 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 for events that happen before `main()` is entered.
///
/// 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 startupMetrics {
return {'runtime': 'dartdevc'};
}

View file

@ -0,0 +1,12 @@
// Copyright (c) 2021, 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 for events that happen before `main()` is entered.
///
/// 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 startupMetrics {
return {'runtime': 'unknown'};
}

View file

@ -0,0 +1,12 @@
// Copyright (c) 2021, 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 for events that happen before `main()` is entered.
///
/// 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 startupMetrics {
return {'runtime': 'vm'};
}

View file

@ -0,0 +1,8 @@
// Copyright (c) 2021, 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 '_startup_metrics_unknown.dart'
if (dart.library._dart2js_runtime_metrics) '_startup_metrics_dart2js.dart'
if (dart.library.ffi) '_startup_metrics_vm.dart'
if (dart.library.js) '_startup_metrics_dartdevc.dart';

View file

@ -0,0 +1,18 @@
name: dart2js_runtime_metrics
# This package is not intended for consumption on pub.dev. DO NOT publish.
publish_to: none
version: 0.1.0
repository: https://github.com/dart-lang/sdk/tree/master/pkg/dart2js_runtime_metrics
description: >-
`dart2js` can generate extra code to measure certain activities.
This library provides access to the measurements at runtime.
environment:
# Restrict the upper bound so that we can remove support for this in
# a later version of the SDK without it being a breaking change.
sdk: ">=2.14.0 <2.15.0"
dev_dependencies:
# Unpublished packages that can be used via path dependency
expect:
path: ../expect

View file

@ -0,0 +1,51 @@
// Copyright (c) 2021, 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.
import 'package:dart2js_runtime_metrics/startup_metrics.dart';
import 'package:expect/expect.dart';
void main() {
Map<String, Object> metrics = startupMetrics;
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('callMainMs'));
return;
}
if (expectedRuntime == 'dartdevc') {
Expect.equals(1, metrics.length);
return;
}
if (expectedRuntime == 'vm') {
Expect.equals(1, metrics.length);
return;
}
throw 'Should not get here.';
}
class ClassWithLongName {}

View file

@ -1866,6 +1866,8 @@ met
metadata
method
methods
metric
metrics
microseconds
microtask
mid

View file

@ -179,6 +179,9 @@ const DEFERRED_INITIALIZED = 'deferredInitialized';
/// This embedded global is used for --experiment-new-rti.
const RTI_UNIVERSE = 'typeUniverse';
/// An embedded global used to collect and access startup metrics.
const STARTUP_METRICS = 'sm';
/// Names that are supported by [JS_GET_NAME].
// TODO(herhut): Make entries lower case (as in fields) and find a better name.
enum JsGetName {

View file

@ -0,0 +1,32 @@
// Copyright (c) 2021, 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.
library dart2js_runtime_metrics;
import 'dart:_js_helper' show fillLiteralMap, rawStartupMetrics;
/// A collection of metrics for events that happen before `main()` is entered.
///
/// 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'`
///
/// - `firstMs`: first performance.now() reading in the main.dart.js file.
///
/// - `dartMainProgramMs`: performance.now() immediately inside the function
/// wrapping all the Dart code
///
/// - `callMainMs`: performance.now() just before calling main()
///
/// The injected code uses `Date.now()` if `performance.now()` is not defined.
Map<String, Object> get startupMetrics {
final Map<String, Object> result = {'runtime': 'dart2js'};
final raw = rawStartupMetrics();
fillLiteralMap(raw, result);
return result;
}

View file

@ -21,6 +21,7 @@ import 'dart:_js_embedded_names'
JsGetName,
LEAF_TAGS,
NATIVE_SUPERCLASS_TAG_NAME,
STARTUP_METRICS,
STATIC_FUNCTION_NAME_PROPERTY_NAME,
TearOffParametersPropertyNames;
@ -3005,3 +3006,7 @@ void assertInteropArgs(List<Object?> args) {
assert(args.every((arg) => arg is! Function || isJSFunction(arg)),
'Dart function requires `allowInterop` to be passed to JavaScript.');
}
Object? rawStartupMetrics() {
return JS('JSArray', '#.a', JS_EMBEDDED_GLOBAL('', STARTUP_METRICS));
}

View file

@ -179,6 +179,9 @@ const DEFERRED_INITIALIZED = 'deferredInitialized';
/// This embedded global is used for --experiment-new-rti.
const RTI_UNIVERSE = 'typeUniverse';
/// An embedded global used to collect and access startup metrics.
const STARTUP_METRICS = 'sm';
/// Names that are supported by [JS_GET_NAME].
// TODO(herhut): Make entries lower case (as in fields) and find a better name.
enum JsGetName {

View file

@ -153,6 +153,11 @@ const Map<String, LibraryInfo> libraries = const {
categories: "", documented: false, platforms: DART2JS_PLATFORM),
"_rti": const LibraryInfo("_internal/js_runtime/lib/rti.dart",
categories: "", documented: false, platforms: DART2JS_PLATFORM),
"_dart2js_runtime_metrics": const LibraryInfo(
"_internal/js_runtime/lib/dart2js_runtime_metrics.dart",
categories: "",
documented: false,
platforms: DART2JS_PLATFORM),
"_interceptors": const LibraryInfo(
"_internal/js_runtime/lib/interceptors.dart",
categories: "",

View file

@ -235,6 +235,9 @@
"web_sql": {
"uri": "web_sql/dart2js/web_sql_dart2js.dart"
},
"_dart2js_runtime_metrics": {
"uri": "_internal/js_runtime/lib/dart2js_runtime_metrics.dart"
},
"_internal": {
"uri": "internal/internal.dart",
"patches": "_internal/js_runtime/lib/internal_patch.dart"
@ -338,6 +341,9 @@
"uri": "internal/internal.dart",
"patches": "_internal/js_runtime/lib/internal_patch.dart"
},
"_dart2js_runtime_metrics": {
"uri": "_internal/js_runtime/lib/dart2js_runtime_metrics.dart"
},
"_js_helper": {
"uri": "_internal/js_runtime/lib/js_helper.dart"
},
@ -477,4 +483,4 @@
}
}
}
}
}

View file

@ -233,6 +233,9 @@ dart2js:
web_sql:
uri: "web_sql/dart2js/web_sql_dart2js.dart"
_dart2js_runtime_metrics:
uri: "_internal/js_runtime/lib/dart2js_runtime_metrics.dart"
_internal:
uri: "internal/internal.dart"
patches: "_internal/js_runtime/lib/internal_patch.dart"
@ -334,6 +337,9 @@ dart2js_server:
uri: "internal/internal.dart"
patches: "_internal/js_runtime/lib/internal_patch.dart"
_dart2js_runtime_metrics:
uri: "_internal/js_runtime/lib/dart2js_runtime_metrics.dart"
_js_helper:
uri: "_internal/js_runtime/lib/js_helper.dart"