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

Side by Side Diff: dart/pkg/dart2js_incremental/lib/library_updater.dart

Issue 739513002: Incremental compilation of removed class. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 1 month 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_incremental.library_updater; 5 library dart2js_incremental.library_updater;
6 6
7 import 'dart:async' show 7 import 'dart:async' show
8 Future; 8 Future;
9 9
10 import 'dart:convert' show 10 import 'dart:convert' show
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 LibraryElementX library) { 248 LibraryElementX library) {
249 invalidateScopesAffectedBy(element, library); 249 invalidateScopesAffectedBy(element, library);
250 250
251 updates.add(new AddedClassUpdate(compiler, element, library)); 251 updates.add(new AddedClassUpdate(compiler, element, library));
252 } 252 }
253 253
254 bool canReuseRemovedElement(PartialElement element) { 254 bool canReuseRemovedElement(PartialElement element) {
255 if (element is PartialFunctionElement) { 255 if (element is PartialFunctionElement) {
256 removeFunction(element); 256 removeFunction(element);
257 return true; 257 return true;
258 } else if (element is PartialClassElement) {
259 removeClass(element);
260 return true;
258 } 261 }
259 return cannotReuse(element, "Removed element that isn't a function."); 262 return cannotReuse(element, "Removed element that isn't a function.");
260 } 263 }
261 264
262 void removeFunction(PartialFunctionElement element) { 265 void removeFunction(PartialFunctionElement element) {
263 logVerbose("Removed method $element."); 266 logVerbose("Removed method $element.");
264 267
265 invalidateScopesAffectedBy(element, element.enclosingElement); 268 invalidateScopesAffectedBy(element, element.enclosingElement);
266 269
267 _removedElements.add(element); 270 _removedElements.add(element);
268 271
269 updates.add(new RemovedFunctionUpdate(compiler, element)); 272 updates.add(new RemovedFunctionUpdate(compiler, element));
270 } 273 }
271 274
275 void removeClass(PartialClassElement element) {
276 logVerbose("Removed class $element.");
277
278 invalidateScopesAffectedBy(element, element.enclosingElement);
279
280 _removedElements.add(element);
281 element.forEachLocalMember((ElementX member) {
282 _removedElements.add(member);
283 });
284
285 updates.add(new RemovedClassUpdate(compiler, element));
286 }
287
272 void invalidateScopesAffectedBy( 288 void invalidateScopesAffectedBy(
273 ElementX element, 289 ElementX element,
274 ScopeContainerElement container) { 290 ScopeContainerElement container) {
275 for (ScopeContainerElement scope in scopesAffectedBy(element, container)) { 291 for (ScopeContainerElement scope in scopesAffectedBy(element, container)) {
276 scanSites(scope, (Element member, DeclarationSite site) { 292 scanSites(scope, (Element member, DeclarationSite site) {
277 // TODO(ahe): Cache qualifiedNamesIn to avoid quadratic behavior. 293 // TODO(ahe): Cache qualifiedNamesIn to avoid quadratic behavior.
278 Map<String, List<String>> names = qualifiedNamesIn(site); 294 Map<String, List<String>> names = qualifiedNamesIn(site);
279 if (canNamesResolveStaticallyTo(names, element, container)) { 295 if (canNamesResolveStaticallyTo(names, element, container)) {
280 _elementsToInvalidate.add(member); 296 _elementsToInvalidate.add(member);
281 } 297 }
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after
609 PartialFunctionElement get before; 625 PartialFunctionElement get before;
610 626
611 /// Reset various caches and remove this element from the compiler's internal 627 /// Reset various caches and remove this element from the compiler's internal
612 /// state. 628 /// state.
613 void reuseElement() { 629 void reuseElement() {
614 compiler.forgetElement(before); 630 compiler.forgetElement(before);
615 before.reuseElement(); 631 before.reuseElement();
616 } 632 }
617 } 633 }
618 634
619 class RemovedFunctionUpdate extends Update with JsFeatures, ReuseFunction { 635 class RemovalUpdate extends Update {
620 final PartialFunctionElement element; 636 ElementX get element;
621 637
622 /// Name of property to remove using JavaScript "delete". Null for 638 RemovalUpdate(Compiler compiler)
623 /// non-instance methods.
624 String name;
625
626 /// Name of super-alias property to remove using JavaScript "delete". Null
627 /// for methods that aren't "super aliased", and non-instance methods.
628 String superName;
629
630 /// For instance methods, access to class object. Otherwise, access to the
631 /// method itself.
632 jsAst.Node elementAccess;
633
634 bool wasStateCaptured = false;
635
636 RemovedFunctionUpdate(Compiler compiler, this.element)
637 : super(compiler); 639 : super(compiler);
638 640
639 PartialFunctionElement get before => element;
640
641 PartialElement get after => null;
642
643 bool get isRemoval => true; 641 bool get isRemoval => true;
644 642
645 void captureState() { 643 void writeUpdateJsOn(List<jsAst.Statement> updates);
646 if (wasStateCaptured) throw "captureState was called twice.";
647
648 if (element.isInstanceMember) {
649 elementAccess = namer.elementAccess(element.enclosingClass);
650 name = namer.getNameOfMember(element);
651 if (backend.isAliasedSuperMember(element)) {
652 superName = namer.getNameOfAliasedSuperMember(element);
653 }
654 } else {
655 elementAccess = namer.elementAccess(element);
656 }
657
658 wasStateCaptured = true;
659 }
660
661 PartialFunctionElement apply() {
662 if (!wasStateCaptured) throw "captureState must be called before apply.";
663 removeFromEnclosing();
664 reuseElement();
665 return null;
666 }
667 644
668 void removeFromEnclosing() { 645 void removeFromEnclosing() {
669 // TODO(ahe): Need to recompute duplicated elements logic again. Simplest 646 // TODO(ahe): Need to recompute duplicated elements logic again. Simplest
670 // solution is probably to remove all elements from enclosing scope and add 647 // solution is probably to remove all elements from enclosing scope and add
671 // them back. 648 // them back.
672 PartialClassElement cls = element.enclosingClass; 649 PartialClassElement cls = element.enclosingClass;
673 if (cls == null) { 650 if (cls == null) {
674 removeFromLibrary(element.library); 651 removeFromLibrary(element.library);
675 } else { 652 } else {
676 removeFromEnclosingClass(cls); 653 removeFromEnclosingClass(cls);
(...skipping 17 matching lines...) Expand all
694 LinkBuilder copy = new LinkBuilder(); 671 LinkBuilder copy = new LinkBuilder();
695 672
696 for (; !link.isEmpty; link = link.tail) { 673 for (; !link.isEmpty; link = link.tail) {
697 if (link.head != e) { 674 if (link.head != e) {
698 copy.addLast(e); 675 copy.addLast(e);
699 } 676 }
700 } 677 }
701 678
702 return copy.toLink(link); 679 return copy.toLink(link);
703 } 680 }
681 }
682
683 class RemovedFunctionUpdate extends RemovalUpdate
684 with JsFeatures, ReuseFunction {
685 final PartialFunctionElement element;
686
687 /// Name of property to remove using JavaScript "delete". Null for
688 /// non-instance methods.
689 String name;
690
691 /// Name of super-alias property to remove using JavaScript "delete". Null
692 /// for methods that aren't "super aliased", and non-instance methods.
693 String superName;
694
695 /// For instance methods, access to class object. Otherwise, access to the
696 /// method itself.
697 jsAst.Node elementAccess;
698
699 bool wasStateCaptured = false;
700
701 RemovedFunctionUpdate(Compiler compiler, this.element)
702 : super(compiler);
703
704 PartialFunctionElement get before => element;
705
706 PartialFunctionElement get after => null;
707
708 void captureState() {
709 if (wasStateCaptured) throw "captureState was called twice.";
710 wasStateCaptured = true;
711
712 if (element.isInstanceMember) {
713 elementAccess = namer.elementAccess(element.enclosingClass);
714 name = namer.getNameOfMember(element);
715 if (backend.isAliasedSuperMember(element)) {
716 superName = namer.getNameOfAliasedSuperMember(element);
717 }
718 } else {
719 elementAccess = namer.elementAccess(element);
720 }
721 }
722
723 PartialFunctionElement apply() {
724 if (!wasStateCaptured) throw "captureState must be called before apply.";
725 removeFromEnclosing();
726 reuseElement();
727 return null;
728 }
704 729
705 void writeUpdateJsOn(List<jsAst.Statement> updates) { 730 void writeUpdateJsOn(List<jsAst.Statement> updates) {
706 if (elementAccess == null) { 731 if (elementAccess == null) {
707 compiler.internalError( 732 compiler.internalError(
708 element, 'No elementAccess for ${element.runtimeType}'); 733 element, 'No elementAccess for ${element.runtimeType}');
709 } 734 }
710 if (element.isInstanceMember) { 735 if (element.isInstanceMember) {
711 if (name == null) { 736 if (name == null) {
712 compiler.internalError(element, 'No name for ${element.runtimeType}'); 737 compiler.internalError(element, 'No name for ${element.runtimeType}');
713 } 738 }
714 updates.add( 739 updates.add(
715 js.statement('delete #.prototype.#', [elementAccess, name])); 740 js.statement('delete #.prototype.#', [elementAccess, name]));
716 741
717 if (superName != null) { 742 if (superName != null) {
718 updates.add( 743 updates.add(
719 js.statement('delete #.prototype.#', [elementAccess, superName])); 744 js.statement('delete #.prototype.#', [elementAccess, superName]));
720 } 745 }
721 } else { 746 } else {
722 updates.add(js.statement('delete #', [elementAccess])); 747 updates.add(js.statement('delete #', [elementAccess]));
723 } 748 }
724 } 749 }
725 } 750 }
726 751
752 class RemovedClassUpdate extends RemovalUpdate with JsFeatures {
753 final PartialClassElement element;
754
755 bool wasStateCaptured = false;
756
757 final List<jsAst.Node> accessToStatics = <jsAst.Node>[];
758
759 RemovedClassUpdate(Compiler compiler, this.element)
760 : super(compiler);
761
762 PartialClassElement get before => element;
763
764 PartialClassElement get after => null;
765
766 bool get isRemoval => true;
Johnni Winther 2014/11/19 12:43:53 Not needed. Is already declared in RemovalUpdate.
ahe 2014/11/21 10:47:45 Done.
767
768 void captureState() {
769 if (wasStateCaptured) throw "captureState was called twice.";
770 wasStateCaptured = true;
771
772 accessToStatics.add(namer.elementAccess(element));
773
774 element.forEachLocalMember((ElementX member) {
775 if (!member.isInstanceMember) {
776 accessToStatics.add(namer.elementAccess(member));
777 }
778 });
779 }
780
781 PartialClassElement apply() {
782 if (!wasStateCaptured) {
783 throw new StateError("captureState must be called before apply.");
784 }
785
786 removeFromEnclosing();
787
788 element.forEachLocalMember((ElementX member) {
789 compiler.forgetElement(before);
790 member.reuseElement();
791 });
792
793 compiler.forgetElement(element);
794 element.reuseElement();
795
796 return null;
797 }
798
799 void writeUpdateJsOn(List<jsAst.Statement> updates) {
800 if (accessToStatics.isEmpty) {
801 throw
802 new StateError("captureState must be called before writeUpdateJsOn.");
803 }
804
805 for (jsAst.Node access in accessToStatics) {
806 updates.add(js.statement('delete #', [access]));
807 }
808 }
809 }
810
727 class AddedFunctionUpdate extends Update with JsFeatures { 811 class AddedFunctionUpdate extends Update with JsFeatures {
728 final PartialFunctionElement element; 812 final PartialFunctionElement element;
729 813
730 final ScopeContainerElement container; 814 final ScopeContainerElement container;
731 815
732 AddedFunctionUpdate(Compiler compiler, this.element, this.container) 816 AddedFunctionUpdate(Compiler compiler, this.element, this.container)
733 : super(compiler) { 817 : super(compiler) {
734 if (container == null) { 818 if (container == null) {
735 throw "container is null"; 819 throw "container is null";
736 } 820 }
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
866 950
867 ClassEmitter get classEmitter => backend.emitter.oldEmitter.classEmitter; 951 ClassEmitter get classEmitter => backend.emitter.oldEmitter.classEmitter;
868 952
869 List<String> computeFields(ClassElement cls) { 953 List<String> computeFields(ClassElement cls) {
870 // TODO(ahe): Rewrite for new emitter. 954 // TODO(ahe): Rewrite for new emitter.
871 ClassBuilder builder = new ClassBuilder(cls, namer); 955 ClassBuilder builder = new ClassBuilder(cls, namer);
872 classEmitter.emitFields(cls, builder, ""); 956 classEmitter.emitFields(cls, builder, "");
873 return builder.fields; 957 return builder.fields;
874 } 958 }
875 } 959 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698