Skip to content

Commit 64e65a7

Browse files
rakudramacommit-bot@chromium.org
authored andcommitted
[dart2js] new-rti: Use local in setting up type$
Saves 0.05% on CM. Should be slightly faster too - fewer tokens to parse. Change-Id: I9ce674525817e215e868a616729a465a60b8ef20 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/124468 Reviewed-by: Mayank Patke <fishythefish@google.com> Commit-Queue: Stephen Adams <sra@google.com>
1 parent 8f1be54 commit 64e65a7

File tree

1 file changed

+33
-13
lines changed

1 file changed

+33
-13
lines changed

pkg/compiler/lib/src/js_backend/type_reference.dart

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ import 'package:front_end/src/api_unstable/dart2js.dart'
6565
show $0, $9, $A, $Z, $_, $a, $z;
6666

6767
import '../common_elements.dart' show CommonElements;
68-
import '../elements/entities.dart' show FunctionEntity;
6968
import '../elements/types.dart';
7069
import '../js/js.dart' as js;
7170
import '../js_emitter/code_emitter_task.dart' show Emitter;
@@ -261,19 +260,20 @@ class TypeReferenceFinalizerImpl implements TypeReferenceFinalizer {
261260
}
262261

263262
void _updateReferences() {
264-
js.Expression loadTypeCall(TypeRecipe recipe) {
265-
FunctionEntity helperElement = _commonElements.findType;
263+
js.Expression helperAccess =
264+
_emitter.staticFunctionAccess(_commonElements.findType);
265+
266+
js.Expression loadTypeCall(TypeRecipe recipe, String helperLocal) {
266267
js.Expression recipeExpression =
267268
_recipeEncoder.encodeGroundRecipe(_emitter, recipe);
268-
js.Expression helper = _emitter.staticFunctionAccess(helperElement);
269-
return js.js(r'#(#)', [helper, recipeExpression]);
269+
return js.js(r'#(#)', [helperLocal ?? helperAccess, recipeExpression]);
270270
}
271271

272272
// Emit generate-at-use references.
273273
for (_ReferenceSet referenceSet in _referencesByRecipe.values) {
274274
if (referenceSet.generateAtUse) {
275275
TypeRecipe recipe = referenceSet.recipe;
276-
js.Expression reference = loadTypeCall(recipe);
276+
js.Expression reference = loadTypeCall(recipe, null);
277277
for (TypeReference ref in referenceSet._references) {
278278
ref.value = reference;
279279
}
@@ -287,23 +287,43 @@ class TypeReferenceFinalizerImpl implements TypeReferenceFinalizer {
287287
// are grouped together.
288288
referenceSetsUsingProperties.sort((a, b) => a.name.compareTo(b.name));
289289

290+
// We can generate a literal with calls to H.findType (minified to typically
291+
// e.g. H.xy) or cache H.findType in a local in a scope created by an IIFE.
292+
// Doing so saves 2-3 bytes per entry, but with an overhead of 30+ bytes for
293+
// the IIFE. So it is smaller to use the IIFE only for over 10 or so types.
294+
const minUseIIFE = 10;
295+
String helperLocal =
296+
referenceSetsUsingProperties.length < minUseIIFE ? null : 'findType';
297+
290298
List<js.Property> properties = [];
291299
for (_ReferenceSet referenceSet in referenceSetsUsingProperties) {
292300
TypeRecipe recipe = referenceSet.recipe;
293301
var propertyName = js.string(referenceSet.propertyName);
294-
properties.add(js.Property(propertyName, loadTypeCall(recipe)));
302+
properties
303+
.add(js.Property(propertyName, loadTypeCall(recipe, helperLocal)));
295304
var access = js.js('#.#', [typesHolderLocalName, propertyName]);
296305
for (TypeReference ref in referenceSet._references) {
297306
ref.value = access;
298307
}
299308
}
300-
var initializer = js.ObjectInitializer(properties, isOneLiner: false);
301309

302-
var function = js.js(r'function rtii(){return #}', initializer);
303-
_resource.value = js.js(r'var # = #()', [
304-
js.VariableDeclaration(typesHolderLocalName),
305-
js.Parentheses(function)
306-
]);
310+
if (properties.isEmpty) {
311+
// We don't have a deferred statement sequence. "0;" is the smallest we
312+
// can do with an expression statement.
313+
// TODO(sra): Add deferred expression statement sequences.
314+
_resource.value = js.js('0');
315+
} else {
316+
js.Expression initializer =
317+
js.ObjectInitializer(properties, isOneLiner: false);
318+
if (helperLocal != null) {
319+
// A named IIFE helps attribute startup time in profiling.
320+
var function = js.js(r'function rtii(){var # = #; return #}',
321+
[js.VariableDeclaration(helperLocal), helperAccess, initializer]);
322+
initializer = js.js('#()', js.Parentheses(function));
323+
}
324+
_resource.value = js.js(r'var # = #',
325+
[js.VariableDeclaration(typesHolderLocalName), initializer]);
326+
}
307327
}
308328

309329
// This is a top-level local name in the generated JavaScript top-level

0 commit comments

Comments
 (0)