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

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

Issue 957343002: Make use of __proto__ when available. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Comments 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
« no previous file with comments | « no previous file | pkg/compiler/lib/src/js_emitter/old_emitter/reflection_data_parser.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart
diff --git a/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart
index a575e1ccf67f0a35e3a00bc96319a34bc6c31eff..d97440f5e98ef3855c7ff0295751fa50722725b7 100644
--- a/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart
@@ -331,14 +331,13 @@ class OldEmitter implements Emitter {
var field = generateAccessor(fields[i], accessors, name);
if (#hasIsolateSupport) { fieldNames += "'" + field + "',"; }
- var parameter = "parameter_" + field;
+ var parameter = "p_" + field;
str += parameter;
body += ("this." + field + " = " + parameter + ";\n");
}
str += ") {\n" + body + "}\n";
str += name + ".builtin$cls=\"" + name + "\";\n";
- str += "$desc=$collectedClasses." + name + ";\n";
- str += "if($desc instanceof Array) $desc = \$desc[1];\n";
+ str += "$desc=$collectedClasses." + name + "[1];\n";
str += name + ".prototype = $desc;\n";
if (typeof defineClass.name != "string") {
str += name + ".name=\"" + name + "\";\n";
@@ -420,25 +419,37 @@ class OldEmitter implements Emitter {
/** Needs defineClass to be defined. */
jsAst.Expression buildInheritFrom() {
- jsAst.Expression result = js(r'''
+ jsAst.Expression result = js(r"""
+ // If the browser supports changing the prototype via __proto__, we make
+ // use of that feature. Otherwise, we copy the properties into a new
+ // constructor.
+ (function () {
+ var cls = function () {};
+ cls.prototype = {'p': {}};
+ var object = new cls();
+ return object.__proto__ &&
+ object.__proto__.p === cls.prototype.p;
+ })() ?
+ function(constructor, superConstructor) {
+ var prototype = constructor.prototype;
+ prototype.__proto__ = superConstructor.prototype;
+ // Use a function for `true` here, as functions are stored in the
+ // hidden class and not as properties in the object.
+ prototype.constructor = constructor;
+ prototype[#operatorIsPrefix + constructor.name] = constructor;
+ return convertToFastObject(prototype);
+ } :
function() {
function tmp() {}
- var hasOwnProperty = Object.prototype.hasOwnProperty;
return function (constructor, superConstructor) {
- if (superConstructor == null) {
- // Fix up the the Dart Object class' prototype.
- var prototype = constructor.prototype;
- prototype.constructor = constructor;
- prototype.#isObject = constructor;
- return prototype;
- }
tmp.prototype = superConstructor.prototype;
var object = new tmp();
+ convertToSlowObject(object);
var properties = constructor.prototype;
- for (var member in properties) {
- if (hasOwnProperty.call(properties, member)) {
- object[member] = properties[member];
- }
+ var members = Object.keys(properties);
+ for (var i = 0; i < members.length; i++) {
+ var member = members[i];
+ object[member] = properties[member];
}
// Use a function for `true` here, as functions are stored in the
// hidden class and not as properties in the object.
@@ -448,8 +459,7 @@ class OldEmitter implements Emitter {
return object;
};
}()
- ''', { 'operatorIsPrefix' : js.string(namer.operatorIsPrefix),
- 'isObject' : namer.operatorIs(compiler.objectClass) });
+ """, { 'operatorIsPrefix' : js.string(namer.operatorIsPrefix)});
if (compiler.hasIncrementalSupport) {
result = js(
r'#.inheritFrom = #', [namer.accessIncrementalHelper, result]);
@@ -498,9 +508,11 @@ class OldEmitter implements Emitter {
var mixin = allClasses[mixinClass];
var mixinPrototype = mixin.prototype;
var clsPrototype = allClasses[cls].prototype;
- for (var d in mixinPrototype) {
- if (hasOwnProperty.call(mixinPrototype, d) &&
- !hasOwnProperty.call(clsPrototype, d))
+
+ var properties = Object.keys(mixinPrototype);
+ for (var i = 0; i < properties.length; i++) {
+ var d = properties[i];
+ if (!hasOwnProperty.call(clsPrototype, d))
clsPrototype[d] = mixinPrototype[d];
}
}
@@ -511,7 +523,12 @@ class OldEmitter implements Emitter {
// the Object.prototype object, and they show through here, so we check
// that we have a string.
if (!superclass || typeof superclass != "string") {
- inheritFrom(allClasses[cls], null);
+ // Inlined special case of InheritFrom here for performance reasons.
+ // Fix up the the Dart Object class' prototype.
+ var constructor = allClasses[cls];
+ var prototype = constructor.prototype;
+ prototype.constructor = constructor;
+ prototype.#isObject = constructor;
return;
}
finishClass(superclass);
@@ -530,7 +547,8 @@ class OldEmitter implements Emitter {
}''', {'finishedClassesAccess': finishedClassesAccess,
'needsMixinSupport': needsMixinSupport,
'hasNativeClasses': hasNativeClasses,
- 'nativeInfoHandler': nativeInfoHandler});
+ 'nativeInfoHandler': nativeInfoHandler,
+ 'isObject' : namer.operatorIs(compiler.objectClass) });
}
void emitFinishIsolateConstructorInvocation(CodeOutput output) {
@@ -1014,10 +1032,12 @@ class OldEmitter implements Emitter {
$finishIsolateConstructorName = function (oldIsolate) {
var isolateProperties = oldIsolate.#isolatePropertiesName;
function Isolate() {
- var hasOwnProperty = Object.prototype.hasOwnProperty;
- for (var staticName in isolateProperties)
- if (hasOwnProperty.call(isolateProperties, staticName))
- this[staticName] = isolateProperties[staticName];
+
+ var staticNames = Object.keys(isolateProperties);
+ for (var i = 0; i < staticNames.length; i++) {
+ var staticName = staticNames[i];
+ this[staticName] = isolateProperties[staticName];
+ }
// Reset lazy initializers to null.
// When forcing the object to fast mode (below) v8 will consider
@@ -1025,8 +1045,9 @@ class OldEmitter implements Emitter {
// (after the first call to the getter), we would have a map
// transition.
var lazies = init.lazies;
- for (var lazyInit in lazies) {
- this[lazies[lazyInit]] = null;
+ var lazyInitializers = lazies ? Object.keys(lazies) : [];
+ for (var i = 0; i < lazyInitializers.length; i++) {
+ this[lazies[lazyInitializers[i]]] = null;
}
// Use the newly created object as prototype. In Chrome,
@@ -1037,8 +1058,8 @@ class OldEmitter implements Emitter {
new ForceEfficientMap();
// Now, after being a fast map we can set the lazies again.
- for (var lazyInit in lazies) {
- var lazyInitName = lazies[lazyInit];
+ for (var i = 0; i < lazyInitializers.length; i++) {
+ var lazyInitName = lazies[lazyInitializers[i]];
this[lazyInitName] = isolateProperties[lazyInitName];
}
}
@@ -1106,6 +1127,20 @@ class OldEmitter implements Emitter {
output.add(N);
}
+ void emitConvertToSlowObjectFunction(CodeOutput output) {
+ jsAst.Statement convertToSlowObject = js.statement(r'''
+ function convertToSlowObject(properties) {
+ // Add and remove a property to make the object transition into hashmap
+ // mode.
+ properties.__MAGIC_SLOW_PROPERTY = 1;
+ delete properties.__MAGIC_SLOW_PROPERTY;
+ return properties;
+ }''');
+
+ output.addBuffer(jsAst.prettyPrint(convertToSlowObject, compiler));
+ output.add(N);
+ }
+
void writeLibraryDescriptors(CodeOutput output, LibraryElement library) {
var uri = "";
if (!compiler.enableMinification || backend.mustPreserveUris) {
@@ -1470,6 +1505,8 @@ class OldEmitter implements Emitter {
'${namer.currentIsolate}$_=${_}new ${namer.isolateName}()$N');
emitConvertToFastObjectFunction(mainOutput);
+ emitConvertToSlowObjectFunction(mainOutput);
+
for (String globalObject in Namer.reservedGlobalObjectNames) {
mainOutput.add('$globalObject = convertToFastObject($globalObject)$N');
}
« no previous file with comments | « no previous file | pkg/compiler/lib/src/js_emitter/old_emitter/reflection_data_parser.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698