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

Unified Diff: pkg/compiler/lib/src/js_emitter/old_emitter/reflection_data_parser.dart

Issue 974803002: Defer addStubs to class instantiation time. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Use JS_NAME and fix deferred loading. Created 5 years, 9 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/old_emitter/reflection_data_parser.dart
diff --git a/pkg/compiler/lib/src/js_emitter/old_emitter/reflection_data_parser.dart b/pkg/compiler/lib/src/js_emitter/old_emitter/reflection_data_parser.dart
index 5981370a47a9b5d75f139a2c9ae161a17a261d22..ceddd0a8e1b26ca2b30fa0e53b807338ee548240 100644
--- a/pkg/compiler/lib/src/js_emitter/old_emitter/reflection_data_parser.dart
+++ b/pkg/compiler/lib/src/js_emitter/old_emitter/reflection_data_parser.dart
@@ -17,9 +17,9 @@ const bool VALIDATE_DATA = false;
// TODO(zarah): Rename this when renaming this file.
String get parseReflectionDataName => 'parseReflectionData';
-jsAst.Expression getReflectionDataParser(OldEmitter oldEmitter,
- JavaScriptBackend backend,
- bool needsNativeSupport) {
+jsAst.Statement getReflectionDataParser(OldEmitter oldEmitter,
+ JavaScriptBackend backend,
+ bool needsNativeSupport) {
Namer namer = backend.namer;
Compiler compiler = backend.compiler;
CodeEmitterTask emitter = backend.emitter;
@@ -53,27 +53,62 @@ jsAst.Expression getReflectionDataParser(OldEmitter oldEmitter,
jsAst.Expression typesAccess =
emitter.generateEmbeddedGlobalAccess(embeddedNames.TYPES);
+
jsAst.Statement processClassData = js.statement('''{
+ function finishAddStubsHelper(prototype) {
+ var prototype = prototype || this;
floitsch 2015/03/11 13:59:33 document this.
herhut 2015/03/13 12:28:52 Done.
+ var object;
+ while (prototype.#deferredAction != #markerFun) {
+ if (prototype.hasOwnProperty(#deferredActionString)) {
+ delete prototype.#deferredAction; // Intended to make it slow, too.
+ var properties = Object.keys(prototype);
+ for (var index = 0; index < properties.length; index++) {
+ var property = properties[index];
+ var firstChar = property.charCodeAt(0);
+ var elem;
+ // We have to filter out some special properties that are used for
+ // metadata in descriptors. Currently, we filter everything that
+ // starts with + or *. This has to stay in sync with the special
+ // properties that are used by processClassData below.
+ if (property !== "${namer.classDescriptorProperty}" &&
+ property !== "$reflectableField" &&
+ firstChar !== 43 && // 43 is aka "+".
+ firstChar !== 42 && // 42 is aka "*"
+ (elem = prototype[property]) != null &&
+ elem.constructor === Array &&
+ property !== "<>") {
+ addStubs(prototype, elem, property, false, null);
+ }
+ }
+ convertToFastObject(prototype);
+ }
+ prototype = prototype.__proto__;
+ }
+ }
+
function processClassData(cls, descriptor, processedClasses) {
- var newDesc = map(); // Use a slow object.
+ descriptor = convertToSlowObject(descriptor); // Use a slow object.
var previousProperty;
var properties = Object.keys(descriptor);
+ var hasDeferredWork = false;
+ var deferWork = supportsDirectProtoAccess && cls != #objectClassName;
floitsch 2015/03/11 13:59:33 shouldDeferWork ? shouldAddStubsEagerly = !... sho
herhut 2015/03/13 12:28:52 Done.
for (var i = 0; i < properties.length; i++) {
var property = properties[i];
- var firstChar = property.substring(0, 1);
+ var firstChar = property.charCodeAt(0);
if (property === "static") {
- processStatics(#embeddedStatics[cls] = descriptor[property],
+ processStatics(#embeddedStatics[cls] = descriptor.static,
processedClasses);
- } else if (firstChar === "+") {
+ delete descriptor.static;
+ } else if (firstChar === 43) { // 43 is aka "+".
floitsch 2015/03/11 13:59:33 is aka -> "is" or "aka".
herhut 2015/03/13 12:28:52 Argh, missed that one. Thanks, done.
mangledNames[previousProperty] = property.substring(1);
var flag = descriptor[property];
if (flag > 0)
descriptor[previousProperty].$reflectableField = flag;
- } else if (firstChar === "*") {
- newDesc[previousProperty].$defaultValuesField = descriptor[property];
- var optionalMethods = newDesc.$methodsWithOptionalArgumentsField;
+ } else if (firstChar === 42) { // 42 is "*"
+ descriptor[previousProperty].$defaultValuesField = descriptor[property];
+ var optionalMethods = descriptor.$methodsWithOptionalArgumentsField;
if (!optionalMethods) {
- newDesc.$methodsWithOptionalArgumentsField = optionalMethods={}
+ descriptor.$methodsWithOptionalArgumentsField = optionalMethods={}
}
optionalMethods[property] = previousProperty;
} else {
@@ -82,12 +117,19 @@ jsAst.Expression getReflectionDataParser(OldEmitter oldEmitter,
elem != null &&
elem.constructor === Array &&
property !== "<>") {
- addStubs(newDesc, elem, property, false, []);
+ if (deferWork) {
+ hasDeferredWork = true;
+ } else {
+ addStubs(descriptor, elem, property, false, null);
+ }
} else {
- newDesc[previousProperty = property] = elem;
+ previousProperty = property;
}
}
}
+
+ if (hasDeferredWork)
+ descriptor.#deferredAction = finishAddStubsHelper;
/* The 'fields' are either a constructor function or a
* string encoding fields, constructor and superclass. Gets the
@@ -95,7 +137,7 @@ jsAst.Expression getReflectionDataParser(OldEmitter oldEmitter,
* 'Super;field1,field2'
* from the CLASS_DESCRIPTOR_PROPERTY property on the descriptor.
*/
- var classData = newDesc["${namer.classDescriptorProperty}"],
+ var classData = descriptor["${namer.classDescriptorProperty}"],
split, supr, fields = classData;
if (#hasRetainedMetadata)
@@ -113,7 +155,7 @@ jsAst.Expression getReflectionDataParser(OldEmitter oldEmitter,
supr = split[0];
var functionSignature = split[1];
if (functionSignature)
- newDesc.${namer.operatorSignature} = function(s) {
+ descriptor.${namer.operatorSignature} = function(s) {
return function() {
return #types[s];
};
@@ -125,13 +167,18 @@ jsAst.Expression getReflectionDataParser(OldEmitter oldEmitter,
processedClasses.combinedConstructorFunction += defineClass(cls, fields);
processedClasses.constructorsList.push(cls);
}
- processedClasses.collected[cls] = [globalObject, newDesc];
+ processedClasses.collected[cls] = [globalObject, descriptor];
classes.push(cls);
}
-}''', {'embeddedStatics': staticsAccess,
+}''', {'deferredAction': namer.deferredAction,
+ 'deferredActionString': js.string(namer.deferredAction),
+ 'embeddedStatics': staticsAccess,
'hasRetainedMetadata': backend.hasRetainedMetadata,
+ 'markerFun': oldEmitter.markerFun,
'types': typesAccess,
- 'notInCspMode': !compiler.useContentSecurityPolicy});
+ 'notInCspMode': !compiler.useContentSecurityPolicy,
+ 'objectClassName':
+ js.string(namer.runtimeTypeName(compiler.objectClass))});
// TODO(zarah): Remove empty else branches in output when if(#hole) is false.
jsAst.Statement processStatics = js.statement('''
@@ -141,16 +188,16 @@ jsAst.Expression getReflectionDataParser(OldEmitter oldEmitter,
var property = properties[i];
if (property === "${namer.classDescriptorProperty}") continue;
var element = descriptor[property];
- var firstChar = property.substring(0, 1);
+ var firstChar = property.charCodeAt(0);
var previousProperty;
- if (firstChar === "+") {
+ if (firstChar === 43) { // 43 is "+".
mangledGlobalNames[previousProperty] = property.substring(1);
var flag = descriptor[property];
if (flag > 0)
descriptor[previousProperty].$reflectableField = flag;
if (element && element.length)
#typeInformation[previousProperty] = element;
- } else if (firstChar === "*") {
+ } else if (firstChar === 42) { // 42 is "*"
globalObject[previousProperty].$defaultValuesField = element;
var optionalMethods = descriptor.$methodsWithOptionalArgumentsField;
if (!optionalMethods) {
@@ -195,7 +242,7 @@ jsAst.Expression getReflectionDataParser(OldEmitter oldEmitter,
}
var funcs = [descriptor[name] = descriptor[alias] = f];
f.\$stubName = name;
- functions.push(name);
+ if (isStatic) functions.push(name);
floitsch 2015/03/11 13:59:33 Is this necessary in this CL?
herhut 2015/03/13 12:28:52 Great catch. That was a left-over from an experime
for (; index < array.length; index += 2) {
f = array[index + 1];
if (typeof f != "function") break;
@@ -203,7 +250,7 @@ jsAst.Expression getReflectionDataParser(OldEmitter oldEmitter,
funcs.push(f);
if (f.\$stubName) {
descriptor[f.\$stubName] = f;
- functions.push(f.\$stubName);
+ if (isStatic) functions.push(f.\$stubName);
}
}
index++;
@@ -230,10 +277,12 @@ jsAst.Expression getReflectionDataParser(OldEmitter oldEmitter,
descriptor[name].\$getter = f;
f.\$getterStub = true;
// Used to create an isolate using spawnFunction.
- if (isStatic) #globalFunctions[name] = f;
+ if (isStatic) {
+ #globalFunctions[name] = f;
+ functions.push(getterStubName);
+ }
descriptor[getterStubName] = f;
funcs.push(f);
- if (getterStubName) functions.push(getterStubName);
f.\$stubName = getterStubName;
f.\$callName = null;
// Update the interceptedNames map (which only exists if `invokeOn` was
@@ -427,7 +476,7 @@ jsAst.Expression getReflectionDataParser(OldEmitter oldEmitter,
'#.addStubs = addStubs;', [namer.accessIncrementalHelper]));
}
- return js('''
+ return js.statement('''
function $parseReflectionDataName(reflectionData) {
"use strict";
if (#needsClassSupport) {

Powered by Google App Engine
This is Rietveld 408576698