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

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

Issue 12261005: Simplify the FunctionSet implementation and remove a slightly broken optimization from SelectorMap. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Add comment. Created 7 years, 10 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
« no previous file with comments | « sdk/lib/_internal/compiler/implementation/universe/partial_type_tree.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 universe; 5 part of universe;
6 6
7 // TODO(kasperl): It seems possible to rewrite this class to be more
8 // like the FunctionSet abstraction which is a lot simpler.
7 class SelectorMap<T> extends PartialTypeTree { 9 class SelectorMap<T> extends PartialTypeTree {
8 10
9 SelectorMap(Compiler compiler) : super(compiler); 11 SelectorMap(Compiler compiler) : super(compiler);
10 12
11 SelectorMapNode<T> newSpecializedNode(ClassElement type) 13 SelectorMapNode<T> newNode(ClassElement type) => new SelectorMapNode<T>(type);
12 => new SelectorMapNode<T>(type);
13 14
14 T operator [](Selector selector) { 15 T operator [](Selector selector) {
15 SelectorMapNode<T> node = findNode(selectorType(selector), false); 16 SelectorMapNode<T> node = findNode(selectorType(selector), false);
16 if (node == null) return null; 17 if (node == null) return null;
17 Link<SelectorValue<T>> selectors = node.selectorsByName[selector.name]; 18 Link<SelectorValue<T>> selectors = node.selectorsByName[selector.name];
18 if (selectors == null) return null; 19 if (selectors == null) return null;
19 for (Link link = selectors; !link.isEmpty; link = link.tail) { 20 for (Link link = selectors; !link.isEmpty; link = link.tail) {
20 SelectorValue<T> existing = link.head; 21 SelectorValue<T> existing = link.head;
21 if (existing.selector.equalsUntyped(selector)) return existing.value; 22 if (existing.selector.equalsUntyped(selector)) return existing.value;
22 } 23 }
23 return null; 24 return null;
24 } 25 }
25 26
27 // TODO(kasperl): Do we need to support removing selectors by
28 // passing null as the value?
26 void operator []=(Selector selector, T value) { 29 void operator []=(Selector selector, T value) {
27 SelectorMapNode<T> node = findNode(selectorType(selector), true); 30 ClassElement type = selectorType(selector);
28 Link<SelectorValue<T>> selectors = node.selectorsByName[selector.name]; 31 SelectorMapNode<T> node = findNode(type, true);
29 if (selectors == null) { 32 SourceString name = selector.name;
30 // No existing selectors with the given name. Create a new 33 Link<SelectorValue<T>> selectors = node.selectorsByName.putIfAbsent(
31 // linked list. 34 name, () => const Link());
32 SelectorValue<T> head = new SelectorValue<T>(selector, value); 35 // Run through the linked list of selectors with the same name. If
33 node.selectorsByName[selector.name] = 36 // we find one that matches, we update the value in the mapping.
34 new Link<SelectorValue<T>>().prepend(head); 37 for (Link link = selectors; !link.isEmpty; link = link.tail) {
35 } else { 38 SelectorValue<T> existing = link.head;
36 // Run through the linked list of selectors with the same name. If 39 // It is safe to ignore the type here, because all selector
37 // we find one that matches, we update the value in the mapping. 40 // mappings that are stored in a single node have the same type.
38 for (Link link = selectors; !link.isEmpty; link = link.tail) { 41 if (existing.selector.equalsUntyped(selector)) {
39 SelectorValue<T> existing = link.head; 42 existing.value = value;
40 // It is safe to ignore the type here, because all selector 43 return;
41 // mappings that are stored in a single node have the same type.
42 if (existing.selector.equalsUntyped(selector)) {
43 existing.value = value;
44 return;
45 }
46 } 44 }
47 // We could not find an existing mapping for the selector, so
48 // we add a new one to the existing linked list.
49 SelectorValue<T> head = new SelectorValue<T>(selector, value);
50 node.selectorsByName[selector.name] = selectors.prepend(head);
51 } 45 }
46 // We could not find an existing mapping for the selector, so
47 // we add a new one to the existing linked list.
48 SelectorValue<T> head = new SelectorValue<T>(selector, value);
49 node.selectorsByName[name] = selectors.prepend(head);
52 } 50 }
53 51
54 // TODO(kasperl): Share code with the [] operator? 52 // TODO(kasperl): Share code with the [] operator?
55 bool containsKey(Selector selector) { 53 bool containsKey(Selector selector) {
56 SelectorMapNode<T> node = findNode(selectorType(selector), false); 54 SelectorMapNode<T> node = findNode(selectorType(selector), false);
57 if (node == null) return false; 55 if (node == null) return false;
58 Link<SelectorValue<T>> selectors = node.selectorsByName[selector.name]; 56 Link<SelectorValue<T>> selectors = node.selectorsByName[selector.name];
59 if (selectors == null) return false; 57 if (selectors == null) return false;
60 for (Link link = selectors; !link.isEmpty; link = link.tail) { 58 for (Link link = selectors; !link.isEmpty; link = link.tail) {
61 SelectorValue<T> existing = link.head; 59 SelectorValue<T> existing = link.head;
62 if (existing.selector.equalsUntyped(selector)) return true; 60 if (existing.selector.equalsUntyped(selector)) return true;
63 } 61 }
64 return false; 62 return false;
65 } 63 }
66 64
67 /** 65 /**
68 * Visits all mappings for selectors that may be used to invoke the 66 * Visits all mappings for selectors that may be used to invoke the
69 * given [member] element. If the [visit] function ever returns false, 67 * given [member] element. If the [visit] function ever returns false,
70 * we abort the traversal early. 68 * we abort the traversal early.
71 */ 69 */
72 void visitMatching(Element member, bool visit(Selector selector, T value)) { 70 void visitMatching(Element member, bool visit(Selector selector, T value)) {
73 assert(member.isMember()); 71 assert(member.isMember());
74 if (root == null) return; 72 if (root == null) return;
75 // TODO(kasperl): For now, we use a different implementation for 73 // TODO(kasperl): Use visitHierachyMatching when possible. It is
76 // visiting if the tree contains interface subtypes. 74 // currently broken in subtle ways when it comes to finding typed
77 if (containsInterfaceSubtypes) { 75 // selectors where we only know the interface of the receiver.
78 visitAllMatching(member, visit); 76 visitAllMatching(member, visit);
79 } else {
80 visitHierarchyMatching(member, visit);
81 }
82 } 77 }
83 78
84 void visitAllMatching(Element member, bool visit(selector, value)) { 79 void visitAllMatching(Element member, bool visit(selector, value)) {
85 root.visitRecursively((SelectorMapNode<T> node) { 80 root.visitRecursively((SelectorMapNode<T> node) {
86 Link<SelectorValue<T>> selectors = node.selectorsByName[member.name]; 81 Link<SelectorValue<T>> selectors = node.selectorsByName[member.name];
87 if (selectors == null) return true; 82 if (selectors == null) return true;
88 for (Link link = selectors; !link.isEmpty; link = link.tail) { 83 for (Link link = selectors; !link.isEmpty; link = link.tail) {
89 SelectorValue<T> existing = link.head; 84 SelectorValue<T> existing = link.head;
90 Selector selector = existing.selector; 85 Selector selector = existing.selector;
91 // Since we're running through the entire tree we have to use 86 // Since we're running through the entire tree we have to use
(...skipping 17 matching lines...) Expand all
109 if (!visit(selector, existing.value)) return false; 104 if (!visit(selector, existing.value)) return false;
110 } 105 }
111 } 106 }
112 return true; 107 return true;
113 }); 108 });
114 } 109 }
115 110
116 } 111 }
117 112
118 class SelectorMapNode<T> extends PartialTypeTreeNode { 113 class SelectorMapNode<T> extends PartialTypeTreeNode {
119 114 final Map<SourceString, Link<SelectorValue<T>>> selectorsByName =
120 final Map<SourceString, Link<SelectorValue<T>>> selectorsByName; 115 new Map<SourceString, Link<SelectorValue<T>>>();
121 116 SelectorMapNode(ClassElement type) : super(type);
122 SelectorMapNode(ClassElement type) : super(type),
123 selectorsByName = new Map<SourceString, Link<SelectorValue<T>>>();
124
125 } 117 }
126 118
127 class SelectorValue<T> { 119 class SelectorValue<T> {
128 final Selector selector; 120 final Selector selector;
129 T value; 121 T value;
130 SelectorValue(this.selector, this.value); 122 SelectorValue(this.selector, this.value);
131 toString() => "$selector -> $value"; 123 toString() => "$selector -> $value";
132 } 124 }
OLDNEW
« no previous file with comments | « sdk/lib/_internal/compiler/implementation/universe/partial_type_tree.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698