Chromium Code Reviews| Index: lib/compiler/implementation/enqueue.dart |
| diff --git a/lib/compiler/implementation/enqueue.dart b/lib/compiler/implementation/enqueue.dart |
| index a0a453af6be5b08e14bf3beae2e3f81602e759f5..a064a6bdfa27dbc6a415e7d89ae9228946b55889 100644 |
| --- a/lib/compiler/implementation/enqueue.dart |
| +++ b/lib/compiler/implementation/enqueue.dart |
| @@ -17,6 +17,34 @@ class EnqueueTask extends CompilerTask { |
| } |
| } |
| +class RecompilationQueue { |
| + final Queue<WorkItem> queue; |
| + final Set<Element> queueElements; |
| + |
| + RecompilationQueue() |
| + : queue = new Queue<WorkItem>(), |
| + queueElements = new Set<Element>(); |
| + |
| + void add(Element element, TreeElements elements) { |
| + if (queueElements.contains(element)) return; |
| + // TODO(sgjesse): Make this handle constructor bodies as well. |
|
ngeoffray
2012/06/14 12:42:24
Why don't we handle them right now?
Søren Gjesse
2012/06/15 09:25:02
I can't remember the exact problem. I will get bac
|
| + if (element.kind !== ElementKind.GENERATIVE_CONSTRUCTOR_BODY) { |
| + queueElements.add(element); |
| + queue.add(new WorkItem(element, elements)); |
| + } |
| + } |
| + |
| + int get length() => queue.length; |
| + |
| + bool isEmpty() => queue.isEmpty(); |
| + |
| + WorkItem next() { |
| + WorkItem item = queue.removeLast(); |
| + queueElements.remove(item.element); |
| + return item; |
| + } |
| +} |
| + |
| class Enqueuer { |
| final Compiler compiler; // TODO(ahe): Remove this dependency. |
| final Map<String, Link<Element>> instanceMembersByName; |
| @@ -24,6 +52,8 @@ class Enqueuer { |
| final Universe universe; |
| final Queue<WorkItem> queue; |
| final Map<Element, TreeElements> resolvedElements; |
| + final RecompilationQueue recompilationCandidates; |
| + |
| bool queueIsClosed = false; |
| EnqueueTask task; |
| @@ -32,7 +62,8 @@ class Enqueuer { |
| seenClasses = new Set<ClassElement>(), |
| universe = new Universe(), |
| queue = new Queue<WorkItem>(), |
| - resolvedElements = new Map<Element, TreeElements>(); |
| + resolvedElements = new Map<Element, TreeElements>(), |
| + recompilationCandidates = new RecompilationQueue(); |
| bool get isFirstQueue() => compiler.enqueuer.resolution === this; |
| @@ -43,6 +74,7 @@ class Enqueuer { |
| void addToWorkList(Element element, [TreeElements elements]) { |
| if (element.isForeign()) return; |
| + if (compiler.pass == 2) return; |
| if (queueIsClosed) { |
| if (isFirstQueue && getCachedElements(element) !== null) return; |
| compiler.internalErrorOnElement(element, "Work list is closed."); |
| @@ -56,6 +88,24 @@ class Enqueuer { |
| queue.add(new WorkItem(element, elements)); |
| } |
| + bool canBeRecompiled(Element element) { |
| + // Only member functions can be recompiled. An exception to this is members |
|
ngeoffray
2012/06/14 12:42:24
Why not static methods?
Søren Gjesse
2012/06/15 09:25:02
Doesn't isMember cover static functions as well? A
ngeoffray
2012/06/15 20:06:14
you are right that isMember covers static function
|
| + // of closures. They are processed as part of the enclosing function and not |
| + // present as a separate element (the call to the closure will be a member |
| + // function). |
| + var closure = const SourceString("Closure"); |
| + return element.isMember() && element.getEnclosingClass().name != closure; |
|
ahe
2012/06/14 13:23:54
This should be:
element.getEnclosingClass() !== c
Søren Gjesse
2012/06/15 09:25:02
Done.
|
| + } |
| + |
| + void registerRecompilationCandidate(Element element, |
| + [TreeElements elements]) { |
| + if (!canBeRecompiled(element)) return; |
| + if (queueIsClosed) { |
| + compiler.internalErrorOnElement(element, "Work list is closed."); |
| + } |
| + recompilationCandidates.add(element, elements); |
| + } |
| + |
| void registerInstantiatedClass(ClassElement cls) { |
| if (cls.isInterface()) { |
| compiler.internalErrorOnElement( |