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

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

Issue 11453032: Reapply class/method/field minification (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Review feedback Created 8 years 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/emitter.dart
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
index 4d25e3a6beee49848c4bc94adbf2546da46d74ba..8a1d51734affbbb56b2080bf07c2f19a3a70eccd 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
@@ -92,50 +92,72 @@ class CodeEmitterTask extends CompilerTask {
String get name => 'CodeEmitter';
String get defineClassName
- => '${namer.ISOLATE}.\$defineClass';
+ => '${namer.isolateName}.\$defineClass';
String get currentGenerateAccessorName
=> '${namer.CURRENT_ISOLATE}.\$generateAccessor';
String get generateAccessorHolder
=> '$isolatePropertiesName.\$generateAccessor';
String get finishClassesName
- => '${namer.ISOLATE}.\$finishClasses';
+ => '${namer.isolateName}.\$finishClasses';
String get finishIsolateConstructorName
- => '${namer.ISOLATE}.\$finishIsolateConstructor';
+ => '${namer.isolateName}.\$finishIsolateConstructor';
String get pendingClassesName
- => '${namer.ISOLATE}.\$pendingClasses';
+ => '${namer.isolateName}.\$pendingClasses';
String get isolatePropertiesName
- => '${namer.ISOLATE}.${namer.ISOLATE_PROPERTIES}';
+ => '${namer.isolateName}.${namer.isolatePropertiesName}';
String get supportsProtoName
=> 'supportsProto';
String get lazyInitializerName
- => '${namer.ISOLATE}.\$lazy';
-
- final String GETTER_SUFFIX = "?";
- final String SETTER_SUFFIX = "!";
- final String GETTER_SETTER_SUFFIX = "=";
+ => '${namer.isolateName}.\$lazy';
+
+ // Property name suffixes. If the accessors are renaming then the format
+ // is <accessorName>:<fieldName><suffix>. We use the suffix to know whether
+ // to look for the ':' separator in order to avoid doing the indexOf operation
+ // on every single property (they are quite rare). None of these characters
+ // are legal in an identifier and they are related by bit patterns.
+ // setter < 0x3c
+ // both = 0x3d
+ // getter > 0x3e
+ // renaming setter | 0x7c
+ // renaming both } 0x7d
+ // renaming getter ~ 0x7e
+ const SUFFIX_MASK = 0x3f;
+ const FIRST_SUFFIX_CODE = 0x3c;
+ const SETTER_CODE = 0x3c;
+ const GETTER_SETTER_CODE = 0x3d;
+ const GETTER_CODE = 0x3e;
+ const RENAMING_FLAG = 0x40;
+ String needsGetterCode(String variable) => '($variable & 3) > 0';
+ String needsSetterCode(String variable) => '($variable & 2) == 0';
+ String isRenaming(String variable) => '($variable & $RENAMING_FLAG) != 0';
String get generateAccessorFunction {
return """
function generateAccessor(field, prototype) {
var len = field.length;
- var lastChar = field[len - 1];
- var needsGetter = lastChar == '$GETTER_SUFFIX' || lastChar == '$GETTER_SETTER_SUFFIX';
- var needsSetter = lastChar == '$SETTER_SUFFIX' || lastChar == '$GETTER_SETTER_SUFFIX';
- if (needsGetter || needsSetter) field = field.substring(0, len - 1);
- if (needsGetter) {
- var getterString = "return this." + field + ";";
-"""
- /* The supportsProtoCheck below depends on the getter/setter convention.
- When changing here, update the protoCheck too. */
- """
- prototype["get\$" + field] = new Function(getterString);
+ var lastCharCode = field.charCodeAt(len - 1);
+ var needsAccessor = (lastCharCode & $SUFFIX_MASK) >= $FIRST_SUFFIX_CODE;
+ if (needsAccessor) {
+ var needsGetter = ${needsGetterCode('lastCharCode')};
+ var needsSetter = ${needsSetterCode('lastCharCode')};
+ var renaming = ${isRenaming('lastCharCode')};
+ var accessorName = field = field.substring(0, len - 1);
+ if (renaming) {
+ var divider = field.indexOf(":");
+ accessorName = field.substring(0, divider);
+ field = field.substring(divider + 1);
+ }
+ if (needsGetter) {
+ var getterString = "return this." + field + ";";
+ prototype["get\$" + accessorName] = new Function(getterString);
}
if (needsSetter) {
var setterString = "this." + field + " = v;";
- prototype["set\$" + field] = new Function("v", setterString);
+ prototype["set\$" + accessorName] = new Function("v", setterString);
}
- return field;
- }""";
+ }
+ return field;
+}""";
}
String get defineClassFunction {
@@ -193,7 +215,7 @@ var $supportsProtoName = false;
var tmp = $defineClassName('c', ['f?'], {}).prototype;
if (tmp.__proto__) {
tmp.__proto__ = {};
- if (typeof tmp.get\$f !== "undefined") $supportsProtoName = true;
+ if (typeof tmp.get\$f !== 'undefined') $supportsProtoName = true;
}
''';
}
@@ -265,7 +287,7 @@ function(collectedClasses) {
}
String get finishIsolateConstructorFunction {
- String isolate = namer.ISOLATE;
+ String isolate = namer.isolateName;
// We replace the old Isolate function with a new one that initializes
// all its field with the initial (and often final) value of all globals.
// This has two advantages:
@@ -287,10 +309,10 @@ function(collectedClasses) {
// We also copy over old values like the prototype, and the
// isolateProperties themselves.
return """function(oldIsolate) {
- var isolateProperties = oldIsolate.${namer.ISOLATE_PROPERTIES};
+ var isolateProperties = oldIsolate.${namer.isolatePropertiesName};
var isolatePrototype = oldIsolate.prototype;
var str = "{\\n";
- str += "var properties = $isolate.${namer.ISOLATE_PROPERTIES};\\n";
+ str += "var properties = $isolate.${namer.isolatePropertiesName};\\n";
for (var staticName in isolateProperties) {
if (Object.prototype.hasOwnProperty.call(isolateProperties, staticName)) {
str += "this." + staticName + "= properties." + staticName + ";\\n";
@@ -300,7 +322,7 @@ function(collectedClasses) {
var newIsolate = new Function(str);
newIsolate.prototype = isolatePrototype;
isolatePrototype.constructor = newIsolate;
- newIsolate.${namer.ISOLATE_PROPERTIES} = isolateProperties;
+ newIsolate.${namer.isolatePropertiesName} = isolateProperties;
return newIsolate;
}""";
}
@@ -371,7 +393,7 @@ $lazyInitializerLogic
}
void emitFinishIsolateConstructorInvocation(CodeBuffer buffer) {
- String isolate = namer.ISOLATE;
+ String isolate = namer.isolateName;
buffer.add("$isolate = $finishIsolateConstructorName($isolate);\n");
}
@@ -527,7 +549,7 @@ $lazyInitializerLogic
// on A and a typed selector on B could yield the same stub.
Set<String> generatedStubNames = new Set<String>();
if (compiler.enabledFunctionApply
- && member.name == Namer.CLOSURE_INVOCATION_NAME) {
+ && member.name == namer.closureInvocationSelector) {
// If [Function.apply] is called, we pessimistically compile all
// possible stubs for this closure.
FunctionSignature signature = member.computeSignature(compiler);
@@ -622,7 +644,7 @@ $lazyInitializerLogic
String compiledFieldName(Element member) {
assert(member.isField());
return member.isNative()
- ? member.name.slowToString()
+ ? member.nativeName()
: namer.getName(member);
}
@@ -726,6 +748,7 @@ $lazyInitializerLogic
void visitClassFields(ClassElement classElement,
void addField(Element member,
String name,
+ String accessorName,
bool needsGetter,
bool needsSetter,
bool needsCheckedSetter)) {
@@ -775,6 +798,7 @@ $lazyInitializerLogic
// Getters and setters with suffixes will be generated dynamically.
addField(member,
fieldName,
+ accessorName,
needsGetter,
needsSetter,
needsCheckedSetter);
@@ -791,16 +815,6 @@ $lazyInitializerLogic
includeSuperMembers: isInstantiated && !classElement.isNative());
}
- void generateGetter(Element member, String fieldName, CodeBuffer buffer) {
- String getterName = namer.getterName(member.getLibrary(), member.name);
- buffer.add("$getterName: function() { return this.$fieldName; }");
- }
-
- void generateSetter(Element member, String fieldName, CodeBuffer buffer) {
- String setterName = namer.setterName(member.getLibrary(), member.name);
- buffer.add("$setterName: function(v) { this.$fieldName = v; }");
- }
-
bool canGenerateCheckedSetter(Element member) {
DartType type = member.computeType(compiler);
if (type.element.isTypeVariable()
@@ -814,6 +828,7 @@ $lazyInitializerLogic
void generateCheckedSetter(Element member,
String fieldName,
+ String accessorName,
CodeBuffer buffer) {
assert(canGenerateCheckedSetter(member));
DartType type = member.computeType(compiler);
@@ -824,7 +839,7 @@ $lazyInitializerLogic
if (helperElement.computeSignature(compiler).parameterCount != 1) {
additionalArgument = ", '${namer.operatorIs(type.element)}'";
}
- String setterName = namer.setterName(member.getLibrary(), member.name);
+ String setterName = namer.setterNameFromAccessorName(accessorName);
buffer.add("$setterName: function(v) { "
"this.$fieldName = $helperName(v$additionalArgument); }");
}
@@ -846,13 +861,10 @@ $lazyInitializerLogic
}
visitClassFields(classElement, (Element member,
String name,
+ String accessorName,
bool needsGetter,
bool needsSetter,
bool needsCheckedSetter) {
- if (!getterAndSetterCanBeImplementedByFieldSpec(
- member, name, needsGetter, needsSetter)) {
- return;
- }
if (!isNative || needsCheckedSetter || needsGetter || needsSetter) {
if (isFirstField) {
isFirstField = false;
@@ -863,13 +875,19 @@ $lazyInitializerLogic
} else {
buffer.add(",");
}
- buffer.add('$name');
+ buffer.add('$accessorName');
+ int flag = 0;
+ if (name != accessorName) {
+ buffer.add(':$name');
+ assert(needsGetter || needsSetter);
+ flag = RENAMING_FLAG;
+ }
if (needsGetter && needsSetter) {
- buffer.add(GETTER_SETTER_SUFFIX);
+ buffer.addCharCode(GETTER_SETTER_CODE + flag);
} else if (needsGetter) {
- buffer.add(GETTER_SUFFIX);
+ buffer.addCharCode(GETTER_CODE + flag);
} else if (needsSetter) {
- buffer.add(SETTER_SUFFIX);
+ buffer.addCharCode(SETTER_CODE + flag);
}
}
});
@@ -895,48 +913,18 @@ $lazyInitializerLogic
visitClassFields(classElement, (Element member,
String name,
+ String accessorName,
bool needsGetter,
bool needsSetter,
bool needsCheckedSetter) {
- if (name == null) throw 123;
- if (getterAndSetterCanBeImplementedByFieldSpec(
- member, name, needsGetter, needsSetter)) {
- needsGetter = false;
- needsSetter = false;
- }
- if (needsGetter) {
- emitComma();
- generateGetter(member, name, buffer);
- }
- if (needsSetter) {
- emitComma();
- generateSetter(member, name, buffer);
- }
if (needsCheckedSetter) {
assert(!needsSetter);
emitComma();
- generateCheckedSetter(member, name, buffer);
+ generateCheckedSetter(member, name, accessorName, buffer);
}
});
}
- bool getterAndSetterCanBeImplementedByFieldSpec(Element member,
- String name,
- bool needsGetter,
- bool needsSetter) {
- if (needsGetter) {
- if (namer.getterName(member.getLibrary(), member.name) != 'get\$$name') {
- return false;
- }
- }
- if (needsSetter) {
- if (namer.setterName(member.getLibrary(), member.name) != 'set\$$name') {
- return false;
- }
- }
- return true;
- }
-
/**
* Documentation wanted -- johnniwinther
*
@@ -1168,7 +1156,7 @@ $lazyInitializerLogic
// create a fake element with the correct name.
// Note: the callElement will not have any enclosingElement.
FunctionElement callElement =
- new ClosureInvocationElement(Namer.CLOSURE_INVOCATION_NAME, element);
+ new ClosureInvocationElement(namer.closureInvocationSelector, element);
String staticName = namer.getName(element);
String invocationName = namer.instanceMethodName(callElement);
String fieldAccess = '$isolateProperties.$staticName';
@@ -1265,8 +1253,8 @@ $classesCollector.$mangledName = {'':
// its stubs we simply create a fake element with the correct name.
// Note: the callElement will not have any enclosingElement.
FunctionElement callElement =
- new ClosureInvocationElement(Namer.CLOSURE_INVOCATION_NAME, member);
-
+ new ClosureInvocationElement(namer.closureInvocationSelector, member);
+
String invocationName = namer.instanceMethodName(callElement);
List<String> arguments = new List<String>(parameterCount);
for (int i = 0; i < parameterCount; i++) {
@@ -1342,7 +1330,7 @@ $classesCollector.$mangledName = {'':
String invocationName =
namer.instanceMethodInvocationName(memberLibrary, member.name,
selector);
- SourceString callName = Namer.CLOSURE_INVOCATION_NAME;
+ SourceString callName = namer.closureInvocationSelector;
String closureCallName =
namer.instanceMethodInvocationName(memberLibrary, callName,
selector);
@@ -1459,7 +1447,7 @@ $classesCollector.$mangledName = {'':
}
void emitMakeConstantList(CodeBuffer buffer) {
- buffer.add(namer.ISOLATE);
+ buffer.add(namer.isolateName);
buffer.add(r'''.makeConstantList = function(list) {
list.immutable$list = true;
list.fixed$length = true;
@@ -1547,11 +1535,14 @@ $classesCollector.$mangledName = {'':
}
String internalName = namer.instanceMethodInvocationName(
selector.library, new SourceString(methodName), selector);
+ Element createInvocationMirror =
+ compiler.findHelper(const SourceString('createInvocationMirror'));
CodeBuffer buffer = new CodeBuffer();
buffer.add('function($args) {\n');
buffer.add(' return this.$noSuchMethodName('
- '\$.createInvocationMirror("$methodName", "$internalName",'
- ' $type, [$args], [$argNames]));\n');
+ '${namer.isolateAccess(createInvocationMirror)}('
+ '"$methodName", "$internalName",'
+ '$type, [$args], [$argNames]));\n');
buffer.add(' }');
return buffer;
}
@@ -1697,7 +1688,7 @@ var \$thisScriptUrl;
function \$static_init(){};
function \$initGlobals(context) {
- context.isolateStatics = new ${namer.ISOLATE}();
+ context.isolateStatics = new ${namer.isolateName}();
}
function \$setGlobals(context) {
$currentIsolate = context.isolateStatics;
@@ -1724,10 +1715,10 @@ $mainEnsureGetter
//
// BEGIN invoke [main].
//
-if (typeof document != 'undefined' && document.readyState != 'complete') {
+if (typeof document !== 'undefined' && document.readyState !== 'complete') {
document.addEventListener('readystatechange', function () {
if (document.readyState == 'complete') {
- if (typeof dartMainRunner == 'function') {
+ if (typeof dartMainRunner === 'function') {
dartMainRunner(function() { ${mainCall}; });
} else {
${mainCall};
@@ -1735,7 +1726,7 @@ if (typeof document != 'undefined' && document.readyState != 'complete') {
}
}, false);
} else {
- if (typeof dartMainRunner == 'function') {
+ if (typeof dartMainRunner === 'function') {
dartMainRunner(function() { ${mainCall}; });
} else {
${mainCall};
@@ -1798,7 +1789,7 @@ if (typeof document != 'undefined' && document.readyState != 'complete') {
String assembleProgram() {
measure(() {
mainBuffer.add(HOOKS_API_USAGE);
- mainBuffer.add('function ${namer.ISOLATE}() {}\n');
+ mainBuffer.add('function ${namer.isolateName}() {}\n');
mainBuffer.add('init();\n\n');
// Shorten the code by using "$$" as temporary.
classesCollector = r"$$";
@@ -1834,7 +1825,7 @@ if (typeof document != 'undefined' && document.readyState != 'complete') {
emitFinishIsolateConstructorInvocation(mainBuffer);
mainBuffer.add(
- 'var ${namer.CURRENT_ISOLATE} = new ${namer.ISOLATE}();\n');
+ 'var ${namer.CURRENT_ISOLATE} = new ${namer.isolateName}();\n');
nativeEmitter.assembleCode(mainBuffer);
emitMain(mainBuffer);

Powered by Google App Engine
This is Rietveld 408576698