Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(144)

Unified Diff: sdk/lib/_internal/compiler/implementation/js_backend/constant_emitter.dart

Issue 256453004: Avoid inlining constants that are used via a deferred import. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rebase Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: sdk/lib/_internal/compiler/implementation/js_backend/constant_emitter.dart
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/constant_emitter.dart b/sdk/lib/_internal/compiler/implementation/js_backend/constant_emitter.dart
index d8e92454e8b51b5b74e2f8c802e2126b726a7e38..abf320760fda5c2225c200096a91afce34907ded 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/constant_emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/constant_emitter.dart
@@ -4,14 +4,13 @@
part of js_backend;
-class ConstantEmitter {
+class ConstantEmitter {
ConstantReferenceEmitter _referenceEmitter;
- ConstantInitializerEmitter _initializerEmitter;
+ ConstantLiteralEmitter _literalEmitter;
ConstantEmitter(Compiler compiler, Namer namer) {
- _referenceEmitter = new ConstantReferenceEmitter(compiler, namer);
- _initializerEmitter = new ConstantInitializerEmitter(
- compiler, namer, _referenceEmitter);
+ _literalEmitter = new ConstantLiteralEmitter(compiler, namer, this);
+ _referenceEmitter = new ConstantReferenceEmitter(compiler, namer, this);
}
/**
@@ -24,18 +23,27 @@ class ConstantEmitter {
}
/**
+ * Constructs a literal expression that evaluates to the constant. Uses a
+ * canonical name unless the constant can be emitted multiple times (as for
+ * numbers and strings).
+ */
+ jsAst.Expression literal(Constant constant) {
+ return _literalEmitter.generate(constant);
+ }
+
+ /**
* Constructs an expression like [reference], but the expression is valid
* during isolate initialization.
*/
jsAst.Expression referenceInInitializationContext(Constant constant) {
- return _referenceEmitter.generateInInitializationContext(constant);
+ return _referenceEmitter.generate(constant);
}
/**
* Constructs an expression used to initialize a canonicalized constant.
*/
jsAst.Expression initializationExpression(Constant constant) {
- return _initializerEmitter.generate(constant);
+ return _literalEmitter.generate(constant);
}
}
@@ -47,13 +55,11 @@ class ConstantReferenceEmitter implements ConstantVisitor<jsAst.Expression> {
final Compiler compiler;
final Namer namer;
- ConstantReferenceEmitter(this.compiler, this.namer);
+ final ConstantEmitter constantEmitter;
- jsAst.Expression generate(Constant constant) {
- return _visit(constant);
- }
+ ConstantReferenceEmitter(this.compiler, this.namer, this.constantEmitter);
- jsAst.Expression generateInInitializationContext(Constant constant) {
+ jsAst.Expression generate(Constant constant) {
return _visit(constant);
}
@@ -61,47 +67,38 @@ class ConstantReferenceEmitter implements ConstantVisitor<jsAst.Expression> {
return constant.accept(this);
}
+ jsAst.Expression emitCanonicalVersion(Constant constant) {
+ String name = namer.constantName(constant);
+ return new jsAst.PropertyAccess.field(
+ new jsAst.VariableUse(namer.globalObjectForConstant(constant)), name);
+ }
+
+ jsAst.Expression literal(Constant constant) {
+ return constantEmitter.literal(constant);
+ }
+
jsAst.Expression visitFunction(FunctionConstant constant) {
return namer.isolateStaticClosureAccess(constant.element);
}
jsAst.Expression visitNull(NullConstant constant) {
- return new jsAst.LiteralNull();
+ return literal(constant);
}
jsAst.Expression visitInt(IntConstant constant) {
- return new jsAst.LiteralNumber('${constant.value}');
+ return literal(constant);
}
jsAst.Expression visitDouble(DoubleConstant constant) {
- double value = constant.value;
- if (value.isNaN) {
- return js("0/0");
- } else if (value == double.INFINITY) {
- return js("1/0");
- } else if (value == -double.INFINITY) {
- return js("-1/0");
- } else {
- return new jsAst.LiteralNumber("$value");
- }
+ return literal(constant);
}
jsAst.Expression visitTrue(TrueConstant constant) {
- if (compiler.enableMinification) {
- // Use !0 for true.
- return js("!0");
- } else {
- return js('true');
- }
+ return literal(constant);
}
jsAst.Expression visitFalse(FalseConstant constant) {
- if (compiler.enableMinification) {
- // Use !1 for false.
- return js("!1");
- } else {
- return js('false');
- }
+ return literal(constant);
}
/**
@@ -113,15 +110,7 @@ class ConstantReferenceEmitter implements ConstantVisitor<jsAst.Expression> {
// TODO(sra): If the string is long *and repeated* (and not on a hot path)
// then it should be assigned to a name. We don't have reference counts (or
// profile information) here, so this is the wrong place.
- StringBuffer sb = new StringBuffer();
- writeJsonEscapedCharsOn(constant.value.slowToString(), sb);
- return new jsAst.LiteralString('"$sb"');
- }
-
- jsAst.Expression emitCanonicalVersion(Constant constant) {
- String name = namer.constantName(constant);
- return new jsAst.PropertyAccess.field(
- new jsAst.VariableUse(namer.globalObjectForConstant(constant)), name);
+ return literal(constant);
}
jsAst.Expression visitList(ListConstant constant) {
@@ -145,25 +134,31 @@ class ConstantReferenceEmitter implements ConstantVisitor<jsAst.Expression> {
}
jsAst.Expression visitDummy(DummyConstant constant) {
- return new jsAst.LiteralNumber('0');
+ return literal(constant);
+ }
+
+ jsAst.Expression visitDeferred(DeferredConstant constant) {
+ return emitCanonicalVersion(constant);
}
}
/**
- * Visitor for generating JavaScript expressions to initialize [Constant]s.
- * Do not use directly; use methods from [ConstantEmitter].
+ * Visitor for generating JavaScript expressions that litterally represent
+ * [Constant]s. These can be used for inlining constants or in initializers.
+ * Do not use directly, use methods from [ConstantEmitter].
*/
-class ConstantInitializerEmitter implements ConstantVisitor<jsAst.Expression> {
- final Compiler compiler;
- final Namer namer;
- final ConstantReferenceEmitter referenceEmitter;
+class ConstantLiteralEmitter implements ConstantVisitor<jsAst.Expression> {
// Matches blank lines, comment lines and trailing comments that can't be part
// of a string.
static final RegExp COMMENT_RE =
new RegExp(r'''^ *(//.*)?\n| *//[^''"\n]*$''' , multiLine: true);
- ConstantInitializerEmitter(this.compiler, this.namer, this.referenceEmitter);
+ final Compiler compiler;
+ final Namer namer;
+ final ConstantEmitter constantEmitter;
+
+ ConstantLiteralEmitter(this.compiler, this.namer, this.constantEmitter);
jsAst.Expression generate(Constant constant) {
return _visit(constant);
@@ -173,10 +168,6 @@ class ConstantInitializerEmitter implements ConstantVisitor<jsAst.Expression> {
return constant.accept(this);
}
- jsAst.Expression _reference(Constant constant) {
- return referenceEmitter.generateInInitializationContext(constant);
- }
-
jsAst.Expression visitFunction(FunctionConstant constant) {
compiler.internalError(NO_LOCATION_SPANNABLE,
"The function constant does not need specific JS code.");
@@ -184,28 +175,53 @@ class ConstantInitializerEmitter implements ConstantVisitor<jsAst.Expression> {
}
jsAst.Expression visitNull(NullConstant constant) {
- return _reference(constant);
+ return new jsAst.LiteralNull();
}
jsAst.Expression visitInt(IntConstant constant) {
- return _reference(constant);
+ return new jsAst.LiteralNumber('${constant.value}');
}
jsAst.Expression visitDouble(DoubleConstant constant) {
- return _reference(constant);
+ double value = constant.value;
+ if (value.isNaN) {
+ return js("0/0");
+ } else if (value == double.INFINITY) {
+ return js("1/0");
+ } else if (value == -double.INFINITY) {
+ return js("-1/0");
+ } else {
+ return new jsAst.LiteralNumber("$value");
+ }
}
jsAst.Expression visitTrue(TrueConstant constant) {
- return _reference(constant);
+ if (compiler.enableMinification) {
+ // Use !0 for true.
+ return js("!0");
+ } else {
+ return js('true');
+ }
}
jsAst.Expression visitFalse(FalseConstant constant) {
- return _reference(constant);
+ if (compiler.enableMinification) {
+ // Use !1 for false.
+ return js("!1");
+ } else {
+ return js('false');
+ }
}
+ /**
+ * Write the contents of the quoted string to a [CodeBuffer] in
+ * a form that is valid as JavaScript string literal content.
+ * The string is assumed quoted by double quote characters.
+ */
jsAst.Expression visitString(StringConstant constant) {
- // TODO(sra): Some larger strings are worth sharing.
- return _reference(constant);
+ StringBuffer sb = new StringBuffer();
+ writeJsonEscapedCharsOn(constant.value.slowToString(), sb);
+ return new jsAst.LiteralString('"$sb"');
}
jsAst.Expression visitList(ListConstant constant) {
@@ -231,7 +247,7 @@ class ConstantInitializerEmitter implements ConstantVisitor<jsAst.Expression> {
// Keys in literal maps must be emitted in place.
jsAst.Literal keyExpression = _visit(key);
jsAst.Expression valueExpression =
- _reference(constant.values[i]);
+ constantEmitter.reference(constant.values[i]);
properties.add(new jsAst.Property(keyExpression, valueExpression));
}
return new jsAst.ObjectInitializer(properties);
@@ -241,9 +257,9 @@ class ConstantInitializerEmitter implements ConstantVisitor<jsAst.Expression> {
List<jsAst.Expression> data = <jsAst.Expression>[];
for (int i = 0; i < constant.keys.entries.length; i++) {
jsAst.Expression keyExpression =
- _reference(constant.keys.entries[i]);
+ constantEmitter.reference(constant.keys.entries[i]);
jsAst.Expression valueExpression =
- _reference(constant.values[i]);
+ constantEmitter.reference(constant.values[i]);
data.add(keyExpression);
data.add(valueExpression);
}
@@ -266,10 +282,10 @@ class ConstantInitializerEmitter implements ConstantVisitor<jsAst.Expression> {
} else if (field.name == MapConstant.JS_OBJECT_NAME) {
arguments.add(jsMap());
} else if (field.name == MapConstant.KEYS_NAME) {
- arguments.add(_reference(constant.keys));
+ arguments.add(constantEmitter.reference(constant.keys));
} else if (field.name == MapConstant.PROTO_VALUE) {
assert(constant.protoValue != null);
- arguments.add(_reference(constant.protoValue));
+ arguments.add(constantEmitter.reference(constant.protoValue));
} else if (field.name == MapConstant.JS_DATA_NAME) {
arguments.add(jsGeneralMap());
} else {
@@ -316,7 +332,7 @@ class ConstantInitializerEmitter implements ConstantVisitor<jsAst.Expression> {
}
jsAst.Expression visitDummy(DummyConstant constant) {
- return _reference(constant);
+ return new jsAst.LiteralNumber('0');
}
jsAst.Expression visitConstructed(ConstructedConstant constant) {
@@ -340,7 +356,7 @@ class ConstantInitializerEmitter implements ConstantVisitor<jsAst.Expression> {
List<jsAst.Expression> _array(List<Constant> values) {
List<jsAst.Expression> valueList = <jsAst.Expression>[];
for (int i = 0; i < values.length; i++) {
- valueList.add(_reference(values[i]));
+ valueList.add(constantEmitter.reference(values[i]));
}
return valueList;
}
@@ -363,4 +379,8 @@ class ConstantInitializerEmitter implements ConstantVisitor<jsAst.Expression> {
}
return value;
}
+
+ jsAst.Expression visitDeferred(DeferredConstant constant) {
+ return constantEmitter.reference(constant.referenced);
+ }
}

Powered by Google App Engine
This is Rietveld 408576698