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

Side by Side 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: Ensure fast prototypes and avoid polymorphic access in constructor 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of dart2js.js_emitter; 5 part of dart2js.js_emitter;
6 6
7 // TODO(ahe): Share these with js_helper.dart. 7 // TODO(ahe): Share these with js_helper.dart.
8 const FUNCTION_INDEX = 0; 8 const FUNCTION_INDEX = 0;
9 const NAME_INDEX = 1; 9 const NAME_INDEX = 1;
10 const CALL_NAME_INDEX = 2; 10 const CALL_NAME_INDEX = 2;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 emitter.generateEmbeddedGlobalAccess(embeddedNames.INTERCEPTED_NAMES); 46 emitter.generateEmbeddedGlobalAccess(embeddedNames.INTERCEPTED_NAMES);
47 jsAst.Expression mangledGlobalNamesAccess = 47 jsAst.Expression mangledGlobalNamesAccess =
48 emitter.generateEmbeddedGlobalAccess(embeddedNames.MANGLED_GLOBAL_NAMES); 48 emitter.generateEmbeddedGlobalAccess(embeddedNames.MANGLED_GLOBAL_NAMES);
49 jsAst.Expression mangledNamesAccess = 49 jsAst.Expression mangledNamesAccess =
50 emitter.generateEmbeddedGlobalAccess(embeddedNames.MANGLED_NAMES); 50 emitter.generateEmbeddedGlobalAccess(embeddedNames.MANGLED_NAMES);
51 jsAst.Expression librariesAccess = 51 jsAst.Expression librariesAccess =
52 emitter.generateEmbeddedGlobalAccess(embeddedNames.LIBRARIES); 52 emitter.generateEmbeddedGlobalAccess(embeddedNames.LIBRARIES);
53 jsAst.Expression metadataAccess = 53 jsAst.Expression metadataAccess =
54 emitter.generateEmbeddedGlobalAccess(embeddedNames.METADATA); 54 emitter.generateEmbeddedGlobalAccess(embeddedNames.METADATA);
55 55
56
56 jsAst.Statement processClassData = js.statement('''{ 57 jsAst.Statement processClassData = js.statement('''{
58 function markerFun() {}
59 function finishAddStubsHelper(prototype) {
60 var prototype = prototype || this;
61 var object;
62 while (prototype.#deferredAction != markerFun) {
63 if (prototype.hasOwnProperty(#deferredActionString)) {
64 delete prototype.#deferredAction; // Intended to make it slow, too.
65 var properties = Object.keys(prototype);
66 for (var index = 0; index < properties.length; index++) {
67 var property = properties[index];
68 var firstChar = property.charCodeAt(0);
69 var elem;
70 if (property !== "${namer.classDescriptorProperty}" &&
71 property !== "$reflectableField" &&
72 firstChar !== 43 && // 43 is aka "+".
floitsch 2015/03/06 14:54:09 Please add comment what this is for. The "+" and "
herhut 2015/03/09 14:28:35 Done.
73 firstChar !== 42 && // 42 is aka "*"
74 (elem = prototype[property]) != null &&
75 elem.constructor === Array &&
76 property !== "<>") {
77 addStubs(prototype, elem, property, false, null);
78 }
79 }
80 convertToFastObject(prototype);
81 }
82 prototype = prototype.__proto__;
83 }
84 }
85
57 function processClassData(cls, descriptor, processedClasses) { 86 function processClassData(cls, descriptor, processedClasses) {
58 descriptor = convertToSlowObject(descriptor); // Use a slow object. 87 descriptor = convertToSlowObject(descriptor); // Use a slow object.
59 var previousProperty; 88 var previousProperty;
60 var properties = Object.keys(descriptor); 89 var properties = Object.keys(descriptor);
90 var hasDeferredWork = false;
91 var deferWork = supportsDirectProtoAccess && cls != #objectClassName;
61 for (var i = 0; i < properties.length; i++) { 92 for (var i = 0; i < properties.length; i++) {
62 var property = properties[i]; 93 var property = properties[i];
63 var firstChar = property.charCodeAt(0); 94 var firstChar = property.charCodeAt(0);
64 if (property === "static") { 95 if (property === "static") {
65 processStatics(#embeddedStatics[cls] = descriptor.static, 96 processStatics(#embeddedStatics[cls] = descriptor.static,
66 processedClasses); 97 processedClasses);
98 delete descriptor.static;
floitsch 2015/03/06 14:54:09 we don't need it for reflection?
herhut 2015/03/09 14:28:35 No, statics are collected separately in an array t
67 } else if (firstChar === 43) { // 43 is aka "+". 99 } else if (firstChar === 43) { // 43 is aka "+".
68 mangledNames[previousProperty] = property.substring(1); 100 mangledNames[previousProperty] = property.substring(1);
69 var flag = descriptor[property]; 101 var flag = descriptor[property];
70 if (flag > 0) 102 if (flag > 0)
71 descriptor[previousProperty].$reflectableField = flag; 103 descriptor[previousProperty].$reflectableField = flag;
72 } else if (firstChar === 42) { // 42 is aka "*" 104 } else if (firstChar === 42) { // 42 is aka "*"
73 descriptor[previousProperty].$defaultValuesField = descriptor[property]; 105 descriptor[previousProperty].$defaultValuesField = descriptor[property];
74 var optionalMethods = descriptor.$methodsWithOptionalArgumentsField; 106 var optionalMethods = descriptor.$methodsWithOptionalArgumentsField;
75 if (!optionalMethods) { 107 if (!optionalMethods) {
76 descriptor.$methodsWithOptionalArgumentsField = optionalMethods={} 108 descriptor.$methodsWithOptionalArgumentsField = optionalMethods={}
77 } 109 }
78 optionalMethods[property] = previousProperty; 110 optionalMethods[property] = previousProperty;
79 } else { 111 } else {
80 var elem = descriptor[property]; 112 var elem = descriptor[property];
81 if (property !== "${namer.classDescriptorProperty}" && 113 if (property !== "${namer.classDescriptorProperty}" &&
82 elem != null && 114 elem != null &&
83 elem.constructor === Array && 115 elem.constructor === Array &&
84 property !== "<>") { 116 property !== "<>") {
85 addStubs(descriptor, elem, property, false, []); 117 if (deferWork) {
118 hasDeferredWork = true;
119 } else {
120 addStubs(descriptor, elem, property, false, null);
121 }
86 } else { 122 } else {
87 previousProperty = property; 123 previousProperty = property;
88 } 124 }
89 } 125 }
90 } 126 }
127
128 if (hasDeferredWork)
129 descriptor.#deferredAction = finishAddStubsHelper;
91 130
92 /* The 'fields' are either a constructor function or a 131 /* The 'fields' are either a constructor function or a
93 * string encoding fields, constructor and superclass. Gets the 132 * string encoding fields, constructor and superclass. Gets the
94 * superclass and fields in the format 133 * superclass and fields in the format
95 * 'Super;field1,field2' 134 * 'Super;field1,field2'
96 * from the CLASS_DESCRIPTOR_PROPERTY property on the descriptor. 135 * from the CLASS_DESCRIPTOR_PROPERTY property on the descriptor.
97 */ 136 */
98 var classData = descriptor["${namer.classDescriptorProperty}"], 137 var classData = descriptor["${namer.classDescriptorProperty}"],
99 split, supr, fields = classData; 138 split, supr, fields = classData;
100 139
(...skipping 20 matching lines...) Expand all
121 } 160 }
122 161
123 if (supr) processedClasses.pending[cls] = supr; 162 if (supr) processedClasses.pending[cls] = supr;
124 if (#notInCspMode) { 163 if (#notInCspMode) {
125 processedClasses.combinedConstructorFunction += defineClass(cls, fields); 164 processedClasses.combinedConstructorFunction += defineClass(cls, fields);
126 processedClasses.constructorsList.push(cls); 165 processedClasses.constructorsList.push(cls);
127 } 166 }
128 processedClasses.collected[cls] = [globalObject, descriptor]; 167 processedClasses.collected[cls] = [globalObject, descriptor];
129 classes.push(cls); 168 classes.push(cls);
130 } 169 }
131 }''', {'embeddedStatics': staticsAccess, 170 }''', {'deferredAction': namer.deferredAction,
171 'deferredActionString': js.string(namer.deferredAction),
172 'embeddedStatics': staticsAccess,
132 'hasRetainedMetadata': backend.hasRetainedMetadata, 173 'hasRetainedMetadata': backend.hasRetainedMetadata,
133 'metadata': metadataAccess, 174 'metadata': metadataAccess,
134 'notInCspMode': !compiler.useContentSecurityPolicy}); 175 'notInCspMode': !compiler.useContentSecurityPolicy,
176 'objectClassName':
177 js.string(namer.getNameOfClass(compiler.objectClass))});
135 178
136 // TODO(zarah): Remove empty else branches in output when if(#hole) is false. 179 // TODO(zarah): Remove empty else branches in output when if(#hole) is false.
137 jsAst.Statement processStatics = js.statement(''' 180 jsAst.Statement processStatics = js.statement('''
138 function processStatics(descriptor, processedClasses) { 181 function processStatics(descriptor, processedClasses) {
139 var properties = Object.keys(descriptor); 182 var properties = Object.keys(descriptor);
140 for (var i = 0; i < properties.length; i++) { 183 for (var i = 0; i < properties.length; i++) {
141 var property = properties[i]; 184 var property = properties[i];
142 if (property === "${namer.classDescriptorProperty}") continue; 185 if (property === "${namer.classDescriptorProperty}") continue;
143 var element = descriptor[property]; 186 var element = descriptor[property];
144 var firstChar = property.charCodeAt(0); 187 var firstChar = property.charCodeAt(0);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
188 function addStubs(descriptor, array, name, isStatic, functions) { 231 function addStubs(descriptor, array, name, isStatic, functions) {
189 var index = $FUNCTION_INDEX, alias = array[index], f; 232 var index = $FUNCTION_INDEX, alias = array[index], f;
190 if (typeof alias == "string") { 233 if (typeof alias == "string") {
191 f = array[++index]; 234 f = array[++index];
192 } else { 235 } else {
193 f = alias; 236 f = alias;
194 alias = name; 237 alias = name;
195 } 238 }
196 var funcs = [descriptor[name] = descriptor[alias] = f]; 239 var funcs = [descriptor[name] = descriptor[alias] = f];
197 f.\$stubName = name; 240 f.\$stubName = name;
198 functions.push(name); 241 if (isStatic) functions.push(name);
199 for (; index < array.length; index += 2) { 242 for (; index < array.length; index += 2) {
200 f = array[index + 1]; 243 f = array[index + 1];
201 if (typeof f != "function") break; 244 if (typeof f != "function") break;
202 f.\$stubName = ${readString("array", "index + 2")}; 245 f.\$stubName = ${readString("array", "index + 2")};
203 funcs.push(f); 246 funcs.push(f);
204 if (f.\$stubName) { 247 if (f.\$stubName) {
205 descriptor[f.\$stubName] = f; 248 descriptor[f.\$stubName] = f;
206 functions.push(f.\$stubName); 249 if (isStatic) functions.push(f.\$stubName);
207 } 250 }
208 } 251 }
209 index++; 252 index++;
210 for (var i = 0; i < funcs.length; index++, i++) { 253 for (var i = 0; i < funcs.length; index++, i++) {
211 funcs[i].\$callName = ${readString("array", "index")}; 254 funcs[i].\$callName = ${readString("array", "index")};
212 } 255 }
213 var getterStubName = ${readString("array", "index")}; 256 var getterStubName = ${readString("array", "index")};
214 array = array.slice(++index); 257 array = array.slice(++index);
215 var requiredParameterInfo = ${readInt("array", "0")}; 258 var requiredParameterInfo = ${readInt("array", "0")};
216 var requiredParameterCount = requiredParameterInfo >> 1; 259 var requiredParameterCount = requiredParameterInfo >> 1;
217 var isAccessor = (requiredParameterInfo & 1) === 1; 260 var isAccessor = (requiredParameterInfo & 1) === 1;
218 var isSetter = requiredParameterInfo === 3; 261 var isSetter = requiredParameterInfo === 3;
219 var isGetter = requiredParameterInfo === 1; 262 var isGetter = requiredParameterInfo === 1;
220 var optionalParameterInfo = ${readInt("array", "1")}; 263 var optionalParameterInfo = ${readInt("array", "1")};
221 var optionalParameterCount = optionalParameterInfo >> 1; 264 var optionalParameterCount = optionalParameterInfo >> 1;
222 var optionalParametersAreNamed = (optionalParameterInfo & 1) === 1; 265 var optionalParametersAreNamed = (optionalParameterInfo & 1) === 1;
223 var isIntercepted = 266 var isIntercepted =
224 requiredParameterCount + optionalParameterCount != funcs[0].length; 267 requiredParameterCount + optionalParameterCount != funcs[0].length;
225 var functionTypeIndex = ${readFunctionType("array", "2")}; 268 var functionTypeIndex = ${readFunctionType("array", "2")};
226 var unmangledNameIndex = $unmangledNameIndex; 269 var unmangledNameIndex = $unmangledNameIndex;
227 270
228 if (getterStubName) { 271 if (getterStubName) {
229 f = tearOff(funcs, array, isStatic, name, isIntercepted); 272 f = tearOff(funcs, array, isStatic, name, isIntercepted);
230 descriptor[name].\$getter = f; 273 descriptor[name].\$getter = f;
231 f.\$getterStub = true; 274 f.\$getterStub = true;
232 // Used to create an isolate using spawnFunction. 275 // Used to create an isolate using spawnFunction.
233 if (isStatic) #globalFunctions[name] = f; 276 if (isStatic) {
277 #globalFunctions[name] = f;
278 functions.push(getterStubName);
279 }
234 descriptor[getterStubName] = f; 280 descriptor[getterStubName] = f;
235 funcs.push(f); 281 funcs.push(f);
236 if (getterStubName) functions.push(getterStubName);
237 f.\$stubName = getterStubName; 282 f.\$stubName = getterStubName;
238 f.\$callName = null; 283 f.\$callName = null;
239 // Update the interceptedNames map (which only exists if `invokeOn` was 284 // Update the interceptedNames map (which only exists if `invokeOn` was
240 // enabled). 285 // enabled).
241 if (#enabledInvokeOn) 286 if (#enabledInvokeOn)
242 if (isIntercepted) #interceptedNames[getterStubName] = 1; 287 if (isIntercepted) #interceptedNames[getterStubName] = 1;
243 } 288 }
244 289
245 if (#usesMangledNames) { 290 if (#usesMangledNames) {
246 var isReflectable = array.length > unmangledNameIndex; 291 var isReflectable = array.length > unmangledNameIndex;
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
482 (function() { 527 (function() {
483 var result = $array[$index]; 528 var result = $array[$index];
484 if ($check) { 529 if ($check) {
485 throw new Error( 530 throw new Error(
486 name + ": expected value of type \'$type\' at index " + ($index) + 531 name + ": expected value of type \'$type\' at index " + ($index) +
487 " but got " + (typeof result)); 532 " but got " + (typeof result));
488 } 533 }
489 return result; 534 return result;
490 })()'''; 535 })()''';
491 } 536 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698