[dart2js] Cache globalThis
Feature-test for `self` and `globalThis`, and cache the result. The cached access has smaller minified code size than either `self` or `globalThis`. All older browsers that we have supported that don't have `globalThis` do have `self`. We prioritize `self` over `globalThis`. They are usually the same but it is possible that there are programs which run in an environment that has replaced `self`, for example, a test might do that. We don't want to break existing tests. Bug: #59982 Change-Id: I11d19183d85a73e9552b66a2f49ac99be10c3c83 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/417912 Reviewed-by: Srujan Gaddam <srujzs@google.com> Commit-Queue: Stephen Adams <sra@google.com>
This commit is contained in:
committed by
Commit Queue
parent
82420ba66c
commit
2d21ca796a
@@ -2011,6 +2011,12 @@ class FragmentEmitter {
|
||||
) {
|
||||
List<js.Property> globals = [];
|
||||
|
||||
globals.add(
|
||||
js.Property(
|
||||
js.string(CACHED_GLOBAL_THIS),
|
||||
js.js(r'typeof self != "undefined" ? self : globalThis'),
|
||||
),
|
||||
);
|
||||
if (fragmentsToLoad.isNotEmpty) {
|
||||
globals.addAll(
|
||||
emitEmbeddedGlobalsForDeferredLoading(
|
||||
|
||||
@@ -10,6 +10,7 @@ import 'package:js_runtime/synced/array_flags.dart' show ArrayFlags;
|
||||
|
||||
import 'package:js_runtime/synced/embedded_names.dart'
|
||||
show
|
||||
CACHED_GLOBAL_THIS,
|
||||
DEFERRED_INITIALIZED,
|
||||
DEFERRED_LIBRARY_PARTS,
|
||||
DEFERRED_PART_URIS,
|
||||
|
||||
@@ -654,6 +654,10 @@ class NativeBehavior {
|
||||
behavior.sideEffects.setTo(newEffects);
|
||||
}
|
||||
|
||||
void setUseGvn(bool useGvn) {
|
||||
behavior.useGvn = useGvn;
|
||||
}
|
||||
|
||||
processSpecString(
|
||||
commonElements.dartTypes,
|
||||
reporter,
|
||||
@@ -662,6 +666,7 @@ class NativeBehavior {
|
||||
validTags: validTags,
|
||||
lookupType: lookupType,
|
||||
setSideEffects: setSideEffects,
|
||||
setUseGvn: setUseGvn,
|
||||
typesReturned: behavior.typesReturned,
|
||||
typesInstantiated: behavior.typesInstantiated,
|
||||
objectType: commonElements.objectType,
|
||||
@@ -709,7 +714,7 @@ class NativeBehavior {
|
||||
lookupType,
|
||||
reporter,
|
||||
commonElements,
|
||||
validTags: ['returns', 'creates'],
|
||||
validTags: ['returns', 'creates', 'depends', 'effects', 'gvn'],
|
||||
);
|
||||
return behavior;
|
||||
}
|
||||
|
||||
@@ -2723,8 +2723,13 @@ class HForeignCode extends HForeign {
|
||||
bool typeEquals(other) => other is HForeignCode;
|
||||
@override
|
||||
bool dataEquals(HForeignCode other) {
|
||||
return codeTemplate.source != null &&
|
||||
codeTemplate.source == other.codeTemplate.source;
|
||||
if (codeTemplate.source == null) {
|
||||
return other.codeTemplate.source == null &&
|
||||
// The ASTs will be equal if identical, and in some limited other
|
||||
// cases, like a ModularExpression.
|
||||
codeTemplate.ast == other.codeTemplate.ast;
|
||||
}
|
||||
return codeTemplate.source == other.codeTemplate.source;
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -183,6 +183,10 @@ const STARTUP_METRICS = 'sm';
|
||||
// TODO(51016): This might be moved to improve deferred loading.
|
||||
const RECORD_TYPE_TEST_COMBINATORS_PROPERTY = 'rttc';
|
||||
|
||||
/// An embedded global that contains the value of `globalThis`. Unlike many
|
||||
/// embedded globals, this one has many references, so we choose short name.
|
||||
const CACHED_GLOBAL_THIS = 'G';
|
||||
|
||||
/// Names of fields of collected tear-off parameters object.
|
||||
///
|
||||
/// Tear-off getters are created before the Dart classes are initialized, so a
|
||||
|
||||
@@ -6,6 +6,7 @@ library _js_helper;
|
||||
|
||||
import 'dart:_js_embedded_names'
|
||||
show
|
||||
CACHED_GLOBAL_THIS,
|
||||
CURRENT_SCRIPT,
|
||||
DEFERRED_LIBRARY_PARTS,
|
||||
DEFERRED_PART_URIS,
|
||||
@@ -3953,8 +3954,17 @@ abstract class TrustedGetRuntimeType {}
|
||||
/// `pkg/_js_interop_checks/lib/src/js_util_optimizer.dart`.
|
||||
///
|
||||
/// This should match the global context that non-static interop members use.
|
||||
@pragma('dart2js:prefer-inline')
|
||||
// Unlike `JS<T>(...)`, `JS_EMBEDDED_GLOBAL` is not generic. So we need to cast
|
||||
// the dynamic result to the desired type. We know the result is some kind of
|
||||
// non-null, non-Dart object.
|
||||
@pragma('dart2js:as:trust')
|
||||
Object get staticInteropGlobalContext =>
|
||||
JS('creates:;returns:Object;depends:none;effects:none;gvn:true', 'self');
|
||||
JS_EMBEDDED_GLOBAL(
|
||||
'creates:;returns:JSObject;depends:none;effects:none;gvn:true',
|
||||
CACHED_GLOBAL_THIS,
|
||||
)
|
||||
as Object;
|
||||
|
||||
/// Return a fresh object literal.
|
||||
T createObjectLiteral<T>() => JS('PlainJavaScriptObject', '{}');
|
||||
|
||||
@@ -183,6 +183,10 @@ const STARTUP_METRICS = 'sm';
|
||||
// TODO(51016): This might be moved to improve deferred loading.
|
||||
const RECORD_TYPE_TEST_COMBINATORS_PROPERTY = 'rttc';
|
||||
|
||||
/// An embedded global that contains the value of `globalThis`. Unlike many
|
||||
/// embedded globals, this one has many references, so we choose short name.
|
||||
const CACHED_GLOBAL_THIS = 'G';
|
||||
|
||||
/// Names of fields of collected tear-off parameters object.
|
||||
///
|
||||
/// Tear-off getters are created before the Dart classes are initialized, so a
|
||||
|
||||
Reference in New Issue
Block a user