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

Unified Diff: pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart

Issue 947333004: dart2js: simplify constant expression generation. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix long line. Created 5 years, 10 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: pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart
diff --git a/pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart b/pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart
index 3e913abf59d5bb9d27ed5607fc42fef7ffaaee84..2849e84d0030b07c22d4c14883348877cdf81dbc 100644
--- a/pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart
@@ -4,10 +4,10 @@
library dart2js.new_js_emitter.model_emitter;
-import '../../constants/values.dart' show ConstantValue;
+import '../../constants/values.dart' show ConstantValue, FunctionConstantValue;
import '../../dart2jslib.dart' show Compiler;
import '../../dart_types.dart' show DartType;
-import '../../elements/elements.dart' show ClassElement;
+import '../../elements/elements.dart' show ClassElement, FunctionElement;
import '../../js/js.dart' as js;
import '../../js_backend/js_backend.dart' show
JavaScriptBackend,
@@ -38,7 +38,7 @@ import '../model.dart';
class ModelEmitter {
final Compiler compiler;
final Namer namer;
- final ConstantEmitter constantEmitter;
+ ConstantEmitter constantEmitter;
final NativeEmitter nativeEmitter;
JavaScriptBackend get backend => compiler.backend;
@@ -51,15 +51,76 @@ class ModelEmitter {
ModelEmitter(Compiler compiler, Namer namer, this.nativeEmitter)
: this.compiler = compiler,
- this.namer = namer,
- constantEmitter =
- new ConstantEmitter(compiler, namer, makeConstantListTemplate);
+ this.namer = namer {
+ // TODO(floitsch): remove hard-coded name.
+ // TODO(floitsch): there is no harm in caching the template.
+ js.Template makeConstantListTemplate =
+ js.js.uncachedExpressionTemplate('makeConstList(#)');
+
+ this.constantEmitter = new ConstantEmitter(
+ compiler, namer, this.generateConstantReference,
+ makeConstantListTemplate);
+ }
js.Expression generateEmbeddedGlobalAccess(String global) {
// TODO(floitsch): We should not use "init" for globals.
return js.js("init.$global");
}
+ bool isConstantInlinedOrAlreadyEmitted(ConstantValue constant) {
+ if (constant.isFunction) return true; // Already emitted.
+ if (constant.isPrimitive) return true; // Inlined.
+ if (constant.isDummy) return true; // Inlined.
+ // The name is null when the constant is already a JS constant.
+ // TODO(floitsch): every constant should be registered, so that we can
+ // share the ones that take up too much space (like some strings).
+ if (namer.constantName(constant) == null) return true;
+ return false;
+ }
+
+ // TODO(floitsch): copied from OldEmitter. Adjust or share.
+ int compareConstants(ConstantValue a, ConstantValue b) {
+ // Inlined constants don't affect the order and sometimes don't even have
+ // names.
+ int cmp1 = isConstantInlinedOrAlreadyEmitted(a) ? 0 : 1;
+ int cmp2 = isConstantInlinedOrAlreadyEmitted(b) ? 0 : 1;
+ if (cmp1 + cmp2 < 2) return cmp1 - cmp2;
+
+ // Emit constant interceptors first. Constant interceptors for primitives
+ // might be used by code that builds other constants. See Issue 18173.
+ if (a.isInterceptor != b.isInterceptor) {
+ return a.isInterceptor ? -1 : 1;
+ }
+
+ // Sorting by the long name clusters constants with the same constructor
+ // which compresses a tiny bit better.
+ int r = namer.constantLongName(a).compareTo(namer.constantLongName(b));
+ if (r != 0) return r;
+ // Resolve collisions in the long name by using the constant name (i.e. JS
+ // name) which is unique.
+ return namer.constantName(a).compareTo(namer.constantName(b));
+ }
+
+ js.Expression generateStaticClosureAccess(FunctionElement element) {
+ return js.js('#.#()',
+ [namer.globalObjectFor(element), namer.getStaticClosureName(element)]);
+ }
+
+ js.Expression generateConstantReference(ConstantValue value) {
+ if (value.isFunction) {
+ FunctionConstantValue functionConstant = value;
+ return generateStaticClosureAccess(functionConstant.element);
+ }
+
+ // We are only interested in the "isInlined" part, but it does not hurt to
+ // test for the other predicates.
+ if (isConstantInlinedOrAlreadyEmitted(value)) {
+ return constantEmitter.generate(value);
+ }
+ return js.js('#.#', [namer.globalObjectForConstant(value),
+ namer.constantName(value)]);
+ }
+
int emitProgram(Program program) {
List<Fragment> fragments = program.fragments;
MainFragment mainFragment = fragments.first;
@@ -205,12 +266,6 @@ class ModelEmitter {
return new js.Block(statements);
}
- static js.Template get makeConstantListTemplate {
- // TODO(floitsch): remove hard-coded name.
- // TODO(floitsch): there is no harm in caching the template.
- return js.js.uncachedExpressionTemplate('makeConstList(#)');
- }
-
js.Block emitEmbeddedGlobals(Program program) {
List<js.Property> globals = <js.Property>[];
@@ -386,8 +441,7 @@ class ModelEmitter {
js.Block emitConstants(List<Constant> constants) {
Iterable<js.Statement> statements = constants.map((Constant constant) {
- js.Expression code =
- constantEmitter.initializationExpression(constant.value);
+ js.Expression code = constantEmitter.generate(constant.value);
return js.js.statement("#.# = #;",
[constant.holder.name, constant.name, code]);
});
@@ -632,18 +686,19 @@ function parseFunctionDescriptor(proto, name, descriptor) {
""";
js.Expression _encodeOptionalParameterDefaultValues(DartMethod method) {
- js.Expression result;
// TODO(herhut): Replace [js.LiteralNull] with [js.ArrayHole].
if (method.optionalParameterDefaultValues is List) {
- List<ConstantValue> defs = method.optionalParameterDefaultValues;
- Iterable<js.Expression> elements = defs.map(constantEmitter.reference);
+ List<ConstantValue> defaultValues = method.optionalParameterDefaultValues;
+ Iterable<js.Expression> elements =
+ defaultValues.map(generateConstantReference);
return new js.ArrayInitializer(elements.toList());
} else {
- Map<String, ConstantValue> defs = method.optionalParameterDefaultValues;
+ Map<String, ConstantValue> defaultValues =
+ method.optionalParameterDefaultValues;
List<js.Property> properties = <js.Property>[];
- defs.forEach((String name, ConstantValue value) {
+ defaultValues.forEach((String name, ConstantValue value) {
properties.add(new js.Property(js.string(name),
- constantEmitter.reference(value)));
+ generateConstantReference(value)));
});
return new js.ObjectInitializer(properties);
}
« no previous file with comments | « pkg/compiler/lib/src/js_emitter/new_emitter/emitter.dart ('k') | pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698