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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/enqueue.dart

Issue 15888010: Re-apply "Implement operator== and hashCode for bound closures." (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 6 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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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; 5 part of dart2js;
6 6
7 class EnqueueTask extends CompilerTask { 7 class EnqueueTask extends CompilerTask {
8 final ResolutionEnqueuer resolution; 8 final ResolutionEnqueuer resolution;
9 final CodegenEnqueuer codegen; 9 final CodegenEnqueuer codegen;
10 10
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 compiler.backend.nativeResolutionEnqueuer(resolution); 80 compiler.backend.nativeResolutionEnqueuer(resolution);
81 } 81 }
82 } 82 }
83 83
84 abstract class Enqueuer { 84 abstract class Enqueuer {
85 final String name; 85 final String name;
86 final Compiler compiler; // TODO(ahe): Remove this dependency. 86 final Compiler compiler; // TODO(ahe): Remove this dependency.
87 final Function itemCompilationContextCreator; 87 final Function itemCompilationContextCreator;
88 final Map<String, Link<Element>> instanceMembersByName 88 final Map<String, Link<Element>> instanceMembersByName
89 = new Map<String, Link<Element>>(); 89 = new Map<String, Link<Element>>();
90 final Map<String, Link<Element>> instanceFunctionsByName
91 = new Map<String, Link<Element>>();
90 final Set<ClassElement> seenClasses = new Set<ClassElement>(); 92 final Set<ClassElement> seenClasses = new Set<ClassElement>();
91 final Universe universe = new Universe(); 93 final Universe universe = new Universe();
92 94
93 bool queueIsClosed = false; 95 bool queueIsClosed = false;
94 EnqueueTask task; 96 EnqueueTask task;
95 native.NativeEnqueuer nativeEnqueuer; // Set by EnqueueTask 97 native.NativeEnqueuer nativeEnqueuer; // Set by EnqueueTask
96 98
97 Enqueuer(this.name, this.compiler, 99 Enqueuer(this.name, this.compiler,
98 ItemCompilationContext itemCompilationContextCreator()) 100 ItemCompilationContext itemCompilationContextCreator())
99 : this.itemCompilationContextCreator = itemCompilationContextCreator; 101 : this.itemCompilationContextCreator = itemCompilationContextCreator;
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 // enclosing class, since the metadata has not been parsed yet. 204 // enclosing class, since the metadata has not been parsed yet.
203 if (!member.enclosingElement.isNative()) return; 205 if (!member.enclosingElement.isNative()) return;
204 } 206 }
205 207
206 String memberName = member.name.slowToString(); 208 String memberName = member.name.slowToString();
207 209
208 if (member.kind == ElementKind.FUNCTION) { 210 if (member.kind == ElementKind.FUNCTION) {
209 if (member.name == Compiler.NO_SUCH_METHOD) { 211 if (member.name == Compiler.NO_SUCH_METHOD) {
210 enableNoSuchMethod(member); 212 enableNoSuchMethod(member);
211 } 213 }
212 if (universe.hasInvocation(member, compiler)) {
213 return addToWorkList(member);
214 }
215 // If there is a property access with the same name as a method we 214 // If there is a property access with the same name as a method we
216 // need to emit the method. 215 // need to emit the method.
217 if (universe.hasInvokedGetter(member, compiler)) { 216 if (universe.hasInvokedGetter(member, compiler)) {
218 // We will emit a closure, so make sure the closure class is 217 // We will emit a closure, so make sure the bound closure class is
219 // generated. 218 // generated.
220 compiler.closureClass.ensureResolved(compiler); 219 registerInstantiatedClass(compiler.boundClosureClass,
221 registerInstantiatedClass(compiler.closureClass,
222 // Precise dependency is not important here. 220 // Precise dependency is not important here.
223 compiler.globalDependencies); 221 compiler.globalDependencies);
224 return addToWorkList(member); 222 return addToWorkList(member);
225 } 223 }
224 // Store the member in [instanceFunctionsByName] to catch
225 // getters on the function.
226 Link<Element> members = instanceFunctionsByName.putIfAbsent(
227 memberName, () => const Link<Element>());
228 instanceFunctionsByName[memberName] = members.prepend(member);
229 if (universe.hasInvocation(member, compiler)) {
230 return addToWorkList(member);
231 }
226 } else if (member.kind == ElementKind.GETTER) { 232 } else if (member.kind == ElementKind.GETTER) {
227 if (universe.hasInvokedGetter(member, compiler)) { 233 if (universe.hasInvokedGetter(member, compiler)) {
228 return addToWorkList(member); 234 return addToWorkList(member);
229 } 235 }
230 // We don't know what selectors the returned closure accepts. If 236 // We don't know what selectors the returned closure accepts. If
231 // the set contains any selector we have to assume that it matches. 237 // the set contains any selector we have to assume that it matches.
232 if (universe.hasInvocation(member, compiler)) { 238 if (universe.hasInvocation(member, compiler)) {
233 return addToWorkList(member); 239 return addToWorkList(member);
234 } 240 }
235 } else if (member.kind == ElementKind.SETTER) { 241 } else if (member.kind == ElementKind.SETTER) {
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 registerInvokedGetter(element.name, selector); 385 registerInvokedGetter(element.name, selector);
380 } 386 }
381 } 387 }
382 } 388 }
383 } 389 }
384 390
385 /// Called when [:new Symbol(...):] is seen. 391 /// Called when [:new Symbol(...):] is seen.
386 void registerNewSymbol(TreeElements elements) { 392 void registerNewSymbol(TreeElements elements) {
387 } 393 }
388 394
389 processInstanceMembers(SourceString n, bool f(Element e)) { 395 processLink(Map<String, Link<Element>> map,
396 SourceString n,
397 bool f(Element e)) {
390 String memberName = n.slowToString(); 398 String memberName = n.slowToString();
391 Link<Element> members = instanceMembersByName[memberName]; 399 Link<Element> members = map[memberName];
392 if (members != null) { 400 if (members != null) {
393 LinkBuilder<Element> remaining = new LinkBuilder<Element>(); 401 LinkBuilder<Element> remaining = new LinkBuilder<Element>();
394 for (; !members.isEmpty; members = members.tail) { 402 for (; !members.isEmpty; members = members.tail) {
395 if (!f(members.head)) remaining.addLast(members.head); 403 if (!f(members.head)) remaining.addLast(members.head);
396 } 404 }
397 instanceMembersByName[memberName] = remaining.toLink(); 405 map[memberName] = remaining.toLink();
398 } 406 }
399 } 407 }
400 408
409 processInstanceMembers(SourceString n, bool f(Element e)) {
410 processLink(instanceMembersByName, n, f);
411 }
412
413 processInstanceFunctions(SourceString n, bool f(Element e)) {
414 processLink(instanceFunctionsByName, n, f);
415 }
416
401 void handleUnseenSelector(SourceString methodName, Selector selector) { 417 void handleUnseenSelector(SourceString methodName, Selector selector) {
402 processInstanceMembers(methodName, (Element member) { 418 processInstanceMembers(methodName, (Element member) {
403 if (selector.appliesUnnamed(member, compiler)) { 419 if (selector.appliesUnnamed(member, compiler)) {
404 if (member.isField() && member.enclosingElement.isNative()) { 420 if (member.isField() && member.enclosingElement.isNative()) {
405 if (selector.isGetter() || selector.isCall()) { 421 if (selector.isGetter() || selector.isCall()) {
406 nativeEnqueuer.registerFieldLoad(member); 422 nativeEnqueuer.registerFieldLoad(member);
407 // We have to also handle storing to the field because we only get 423 // We have to also handle storing to the field because we only get
408 // one look at each member and there might be a store we have not 424 // one look at each member and there might be a store we have not
409 // seen yet. 425 // seen yet.
410 // TODO(sra): Process fields for storing separately. 426 // TODO(sra): Process fields for storing separately.
411 nativeEnqueuer.registerFieldStore(member); 427 nativeEnqueuer.registerFieldStore(member);
412 } else { 428 } else {
413 nativeEnqueuer.registerFieldStore(member); 429 nativeEnqueuer.registerFieldStore(member);
414 // We have to also handle loading from the field because we only get 430 // We have to also handle loading from the field because we only get
415 // one look at each member and there might be a load we have not 431 // one look at each member and there might be a load we have not
416 // seen yet. 432 // seen yet.
417 // TODO(sra): Process fields for storing separately. 433 // TODO(sra): Process fields for storing separately.
418 nativeEnqueuer.registerFieldLoad(member); 434 nativeEnqueuer.registerFieldLoad(member);
419 } 435 }
420 } else { 436 } else {
421 addToWorkList(member); 437 addToWorkList(member);
422 } 438 }
423 return true; 439 return true;
424 } 440 }
425 return false; 441 return false;
426 }); 442 });
443 if (selector.isGetter()) {
444 processInstanceFunctions(methodName, (Element member) {
445 if (selector.appliesUnnamed(member, compiler)) {
446 // We will emit a closure, so make sure the bound closure class is
447 // generated.
448 registerInstantiatedClass(compiler.boundClosureClass,
449 // Precise dependency is not important here.
450 compiler.globalDependencies);
451 return true;
452 }
453 return false;
454 });
455 }
427 } 456 }
428 457
429 /** 458 /**
430 * Documentation wanted -- johnniwinther 459 * Documentation wanted -- johnniwinther
431 * 460 *
432 * Invariant: [element] must be a declaration element. 461 * Invariant: [element] must be a declaration element.
433 */ 462 */
434 void registerStaticUse(Element element) { 463 void registerStaticUse(Element element) {
435 if (element == null) return; 464 if (element == null) return;
436 assert(invariant(element, element.isDeclaration)); 465 assert(invariant(element, element.isDeclaration));
437 addToWorkList(element); 466 addToWorkList(element);
438 } 467 }
439 468
440 void registerGetOfStaticFunction(FunctionElement element) { 469 void registerGetOfStaticFunction(FunctionElement element) {
441 registerStaticUse(element); 470 registerStaticUse(element);
471 registerInstantiatedClass(compiler.closureClass,
472 compiler.globalDependencies);
442 universe.staticFunctionsNeedingGetter.add(element); 473 universe.staticFunctionsNeedingGetter.add(element);
443 } 474 }
444 475
445 void registerDynamicInvocation(SourceString methodName, Selector selector) { 476 void registerDynamicInvocation(SourceString methodName, Selector selector) {
446 assert(selector != null); 477 assert(selector != null);
447 registerInvocation(methodName, selector); 478 registerInvocation(methodName, selector);
448 } 479 }
449 480
450 void registerDynamicInvocationOf(Element element, Selector selector) { 481 void registerDynamicInvocationOf(Element element, Selector selector) {
451 assert(selector.isCall() 482 assert(selector.isCall()
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
721 while(!queue.isEmpty) { 752 while(!queue.isEmpty) {
722 // TODO(johnniwinther): Find an optimal process order for codegen. 753 // TODO(johnniwinther): Find an optimal process order for codegen.
723 f(queue.removeLast()); 754 f(queue.removeLast());
724 } 755 }
725 } 756 }
726 757
727 void _logSpecificSummary(log(message)) { 758 void _logSpecificSummary(log(message)) {
728 log('Compiled ${generatedCode.length} methods.'); 759 log('Compiled ${generatedCode.length} methods.');
729 } 760 }
730 } 761 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698