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

Side by Side Diff: pkg/compiler/lib/src/js_emitter/program_builder.dart

Issue 865223002: dart2js: store call stubs in the model. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 11 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) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 library dart2js.js_emitter.program_builder; 5 library dart2js.js_emitter.program_builder;
6 6
7 import 'js_emitter.dart' show computeMixinClass; 7 import 'js_emitter.dart' show computeMixinClass;
8 import 'model.dart'; 8 import 'model.dart';
9 9
10 import '../common.dart'; 10 import '../common.dart';
11 import '../js/js.dart' as js; 11 import '../js/js.dart' as js;
12 12
13 import '../js_backend/js_backend.dart' show 13 import '../js_backend/js_backend.dart' show
14 Namer, 14 Namer,
15 JavaScriptBackend, 15 JavaScriptBackend,
16 JavaScriptConstantCompiler; 16 JavaScriptConstantCompiler;
17 17
18 import 'js_emitter.dart' as emitterTask show 18 import 'js_emitter.dart' show
19 ClassStubGenerator,
19 CodeEmitterTask, 20 CodeEmitterTask,
20 Emitter,
21 InterceptorStubGenerator, 21 InterceptorStubGenerator,
22 TypeTestGenerator, 22 TypeTestGenerator,
23 TypeTestProperties; 23 TypeTestProperties;
24 24
25 import '../universe/universe.dart' show Universe; 25 import '../universe/universe.dart' show Universe;
26 import '../deferred_load.dart' show DeferredLoadTask, OutputUnit; 26 import '../deferred_load.dart' show DeferredLoadTask, OutputUnit;
27 27
28 part 'registry.dart'; 28 part 'registry.dart';
29 29
30 class ProgramBuilder { 30 class ProgramBuilder {
31 final Compiler _compiler; 31 final Compiler _compiler;
32 final Namer namer; 32 final Namer namer;
33 final emitterTask.CodeEmitterTask _task; 33 final CodeEmitterTask _task;
34 34
35 final Registry _registry; 35 final Registry _registry;
36 36
37 /// True if the program should store function types in the metadata. 37 /// True if the program should store function types in the metadata.
38 bool _storeFunctionTypesInMetadata = false; 38 bool _storeFunctionTypesInMetadata = false;
39 39
40 ProgramBuilder(Compiler compiler, 40 ProgramBuilder(Compiler compiler,
41 this.namer, 41 this.namer,
42 this._task) 42 this._task)
43 : this._compiler = compiler, 43 : this._compiler = compiler,
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 List<Field> staticFieldsForReflection = _buildFields(library, visitStatics); 259 List<Field> staticFieldsForReflection = _buildFields(library, visitStatics);
260 260
261 return new Library(library, uri, statics, classes, 261 return new Library(library, uri, statics, classes,
262 staticFieldsForReflection); 262 staticFieldsForReflection);
263 } 263 }
264 264
265 Class _buildClass(ClassElement element) { 265 Class _buildClass(ClassElement element) {
266 bool onlyForRti = _task.typeTestRegistry.rtiNeededClasses.contains(element); 266 bool onlyForRti = _task.typeTestRegistry.rtiNeededClasses.contains(element);
267 267
268 List<Method> methods = []; 268 List<Method> methods = [];
269 List<StubMethod> callStubs = <StubMethod>[];
269 270
270 void visitMember(ClassElement enclosing, Element member) { 271 void visitMember(ClassElement enclosing, Element member) {
271 assert(invariant(element, member.isDeclaration)); 272 assert(invariant(element, member.isDeclaration));
272 assert(invariant(element, element == enclosing)); 273 assert(invariant(element, element == enclosing));
273 274
274 if (Elements.isNonAbstractInstanceMember(member)) { 275 if (Elements.isNonAbstractInstanceMember(member)) {
275 js.Expression code = backend.generatedCode[member]; 276 js.Expression code = backend.generatedCode[member];
276 // TODO(kasperl): Figure out under which conditions code is null. 277 // TODO(kasperl): Figure out under which conditions code is null.
277 if (code != null) methods.add(_buildMethod(member, code)); 278 if (code != null) methods.add(_buildMethod(member, code));
278 } 279 }
280 if (member.isGetter || member.isField) {
281 Set<Selector> selectors =
282 _compiler.codegenWorld.invokedNames[member.name];
283 if (selectors != null && !selectors.isEmpty) {
284 ClassStubGenerator generator =
285 new ClassStubGenerator(_compiler, namer, backend);
286 Map<String, js.Expression> callStubsForMember =
287 generator.generateCallStubsForGetter(member, selectors);
288 callStubsForMember.forEach((String name, js.Expression code) {
289 callStubs.add(_buildStubMethod(name, code, element: member));
290 });
291 }
292 }
279 } 293 }
280 294
281 ClassElement implementation = element.implementation; 295 ClassElement implementation = element.implementation;
282 296
283 // MixinApplications run through the members of their mixin. Here, we are 297 // MixinApplications run through the members of their mixin. Here, we are
284 // only interested in direct members. 298 // only interested in direct members.
285 if (!element.isMixinApplication) { 299 if (!onlyForRti && !element.isMixinApplication) {
286 implementation.forEachMember(visitMember, includeBackendMembers: true); 300 implementation.forEachMember(visitMember, includeBackendMembers: true);
287 } 301 }
288 302
289 List<Field> instanceFields = 303 List<Field> instanceFields =
290 onlyForRti ? const <Field>[] : _buildFields(element, false); 304 onlyForRti ? const <Field>[] : _buildFields(element, false);
291 List<Field> staticFieldsForReflection = 305 List<Field> staticFieldsForReflection =
292 onlyForRti ? const <Field>[] : _buildFields(element, true); 306 onlyForRti ? const <Field>[] : _buildFields(element, true);
293 307
294 emitterTask.TypeTestGenerator generator = 308 TypeTestGenerator generator =
295 new emitterTask.TypeTestGenerator(_compiler, _task, namer); 309 new TypeTestGenerator(_compiler, _task, namer);
296 emitterTask.TypeTestProperties typeTests = 310 TypeTestProperties typeTests =
297 generator.generateIsTests( 311 generator.generateIsTests(
298 element, 312 element,
299 storeFunctionTypeInMetadata: _storeFunctionTypesInMetadata); 313 storeFunctionTypeInMetadata: _storeFunctionTypesInMetadata);
300 314
301 List<StubMethod> isChecks = <StubMethod>[]; 315 List<StubMethod> isChecks = <StubMethod>[];
302 typeTests.properties.forEach((String name, js.Node code) { 316 typeTests.properties.forEach((String name, js.Node code) {
303 isChecks.add(_buildStubMethod(name, code)); 317 isChecks.add(_buildStubMethod(name, code));
304 }); 318 });
305 319
306 String name = namer.getNameOfClass(element); 320 String name = namer.getNameOfClass(element);
307 String holderName = namer.globalObjectFor(element); 321 String holderName = namer.globalObjectFor(element);
308 Holder holder = _registry.registerHolder(holderName); 322 Holder holder = _registry.registerHolder(holderName);
309 bool isInstantiated = 323 bool isInstantiated =
310 _compiler.codegenWorld.directlyInstantiatedClasses.contains(element); 324 _compiler.codegenWorld.directlyInstantiatedClasses.contains(element);
311 325
312 Class result; 326 Class result;
313 if (element.isMixinApplication && !onlyForRti) { 327 if (element.isMixinApplication && !onlyForRti) {
314 assert(!element.isNative); 328 assert(!element.isNative);
315 assert(methods.isEmpty); 329 assert(methods.isEmpty);
316 330
317 result = new MixinApplication(element, 331 result = new MixinApplication(element,
318 name, holder, 332 name, holder,
319 instanceFields, 333 instanceFields,
320 staticFieldsForReflection, 334 staticFieldsForReflection,
335 callStubs,
321 isChecks, 336 isChecks,
322 typeTests.functionTypeIndex, 337 typeTests.functionTypeIndex,
323 isDirectlyInstantiated: isInstantiated, 338 isDirectlyInstantiated: isInstantiated,
324 onlyForRti: onlyForRti); 339 onlyForRti: onlyForRti);
325 } else { 340 } else {
326 result = new Class(element, 341 result = new Class(element,
327 name, holder, methods, instanceFields, 342 name, holder, methods, instanceFields,
328 staticFieldsForReflection, 343 staticFieldsForReflection,
344 callStubs,
329 isChecks, 345 isChecks,
330 typeTests.functionTypeIndex, 346 typeTests.functionTypeIndex,
331 isDirectlyInstantiated: isInstantiated, 347 isDirectlyInstantiated: isInstantiated,
332 onlyForRti: onlyForRti, 348 onlyForRti: onlyForRti,
333 isNative: element.isNative); 349 isNative: element.isNative);
334 } 350 }
335 _classes[element] = result; 351 _classes[element] = result;
336 return result; 352 return result;
337 } 353 }
338 354
339 Method _buildMethod(FunctionElement element, js.Expression code) { 355 Method _buildMethod(FunctionElement element, js.Expression code) {
340 String name = namer.getNameOfInstanceMember(element); 356 String name = namer.getNameOfInstanceMember(element);
341 // TODO(floitsch): compute `needsTearOff`. 357 // TODO(floitsch): compute `needsTearOff`.
342 return new Method(element, name, code, needsTearOff: false); 358 return new Method(element, name, code, needsTearOff: false);
343 } 359 }
344 360
345 Method _buildStubMethod(String name, js.Expression code) { 361 /// Builds a stub method.
362 ///
363 /// Stub methods may have an element that can be used for code-size
364 /// attribution.
365 Method _buildStubMethod(String name, js.Expression code,
366 {Element element}) {
346 // TODO(floitsch): compute `needsTearOff`. 367 // TODO(floitsch): compute `needsTearOff`.
347 return new StubMethod(name, code, needsTearOff: false); 368 return new StubMethod(name, code, needsTearOff: false, element: element);
348 } 369 }
349 370
350 // The getInterceptor methods directly access the prototype of classes. 371 // The getInterceptor methods directly access the prototype of classes.
351 // We must evaluate these classes eagerly so that the prototype is 372 // We must evaluate these classes eagerly so that the prototype is
352 // accessible. 373 // accessible.
353 void _markEagerInterceptorClasses() { 374 void _markEagerInterceptorClasses() {
354 Map<String, Set<ClassElement>> specializedGetInterceptors = 375 Map<String, Set<ClassElement>> specializedGetInterceptors =
355 backend.specializedGetInterceptors; 376 backend.specializedGetInterceptors;
356 for (Set<ClassElement> classes in specializedGetInterceptors.values) { 377 for (Set<ClassElement> classes in specializedGetInterceptors.values) {
357 for (ClassElement element in classes) { 378 for (ClassElement element in classes) {
358 Class cls = _classes[element]; 379 Class cls = _classes[element];
359 if (cls != null) cls.isEager = true; 380 if (cls != null) cls.isEager = true;
360 } 381 }
361 } 382 }
362 } 383 }
363 384
364 Iterable<StaticMethod> _generateGetInterceptorMethods() { 385 Iterable<StaticMethod> _generateGetInterceptorMethods() {
365 emitterTask.InterceptorStubGenerator stubGenerator = 386 InterceptorStubGenerator stubGenerator =
366 new emitterTask.InterceptorStubGenerator(_compiler, namer, backend); 387 new InterceptorStubGenerator(_compiler, namer, backend);
367 388
368 String holderName = namer.globalObjectFor(backend.interceptorsLibrary); 389 String holderName = namer.globalObjectFor(backend.interceptorsLibrary);
369 Holder holder = _registry.registerHolder(holderName); 390 Holder holder = _registry.registerHolder(holderName);
370 391
371 Map<String, Set<ClassElement>> specializedGetInterceptors = 392 Map<String, Set<ClassElement>> specializedGetInterceptors =
372 backend.specializedGetInterceptors; 393 backend.specializedGetInterceptors;
373 List<String> names = specializedGetInterceptors.keys.toList()..sort(); 394 List<String> names = specializedGetInterceptors.keys.toList()..sort();
374 return names.map((String name) { 395 return names.map((String name) {
375 Set<ClassElement> classes = specializedGetInterceptors[name]; 396 Set<ClassElement> classes = specializedGetInterceptors[name];
376 js.Expression code = stubGenerator.generateGetInterceptorMethod(classes); 397 js.Expression code = stubGenerator.generateGetInterceptorMethod(classes);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
419 440
420 fields.add(new Field(field, name, accessorName, 441 fields.add(new Field(field, name, accessorName,
421 getterFlags, setterFlags, 442 getterFlags, setterFlags,
422 needsCheckedSetter)); 443 needsCheckedSetter));
423 }); 444 });
424 445
425 return fields; 446 return fields;
426 } 447 }
427 448
428 Iterable<StaticMethod> _generateOneShotInterceptors() { 449 Iterable<StaticMethod> _generateOneShotInterceptors() {
429 emitterTask.InterceptorStubGenerator stubGenerator = 450 InterceptorStubGenerator stubGenerator =
430 new emitterTask.InterceptorStubGenerator(_compiler, namer, backend); 451 new InterceptorStubGenerator(_compiler, namer, backend);
431 452
432 String holderName = namer.globalObjectFor(backend.interceptorsLibrary); 453 String holderName = namer.globalObjectFor(backend.interceptorsLibrary);
433 Holder holder = _registry.registerHolder(holderName); 454 Holder holder = _registry.registerHolder(holderName);
434 455
435 List<String> names = backend.oneShotInterceptors.keys.toList()..sort(); 456 List<String> names = backend.oneShotInterceptors.keys.toList()..sort();
436 return names.map((String name) { 457 return names.map((String name) {
437 js.Expression code = stubGenerator.generateOneShotInterceptor(name); 458 js.Expression code = stubGenerator.generateOneShotInterceptor(name);
438 return new StaticStubMethod(name, holder, code, needsTearOff: false); 459 return new StaticStubMethod(name, holder, code, needsTearOff: false);
439 }); 460 });
440 } 461 }
(...skipping 18 matching lines...) Expand all
459 _registry.registerConstant(outputUnit, constantValue); 480 _registry.registerConstant(outputUnit, constantValue);
460 assert(!_constants.containsKey(constantValue)); 481 assert(!_constants.containsKey(constantValue));
461 String name = namer.constantName(constantValue); 482 String name = namer.constantName(constantValue);
462 String constantObject = namer.globalObjectForConstant(constantValue); 483 String constantObject = namer.globalObjectForConstant(constantValue);
463 Holder holder = _registry.registerHolder(constantObject); 484 Holder holder = _registry.registerHolder(constantObject);
464 Constant constant = new Constant(name, holder, constantValue); 485 Constant constant = new Constant(name, holder, constantValue);
465 _constants[constantValue] = constant; 486 _constants[constantValue] = constant;
466 } 487 }
467 } 488 }
468 } 489 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698