OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 #include "vm/precompiler.h" | 5 #include "vm/precompiler.h" |
6 | 6 |
7 #include "vm/code_patcher.h" | 7 #include "vm/code_patcher.h" |
8 #include "vm/compiler.h" | 8 #include "vm/compiler.h" |
9 #include "vm/isolate.h" | 9 #include "vm/isolate.h" |
10 #include "vm/log.h" | 10 #include "vm/log.h" |
(...skipping 695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
706 } | 706 } |
707 } | 707 } |
708 } | 708 } |
709 | 709 |
710 | 710 |
711 void Precompiler::DropUncompiledFunctions() { | 711 void Precompiler::DropUncompiledFunctions() { |
712 Library& lib = Library::Handle(Z); | 712 Library& lib = Library::Handle(Z); |
713 Class& cls = Class::Handle(Z); | 713 Class& cls = Class::Handle(Z); |
714 Array& functions = Array::Handle(Z); | 714 Array& functions = Array::Handle(Z); |
715 Function& function = Function::Handle(Z); | 715 Function& function = Function::Handle(Z); |
| 716 Function& function2 = Function::Handle(Z); |
716 GrowableObjectArray& retained_functions = GrowableObjectArray::Handle(Z); | 717 GrowableObjectArray& retained_functions = GrowableObjectArray::Handle(Z); |
717 GrowableObjectArray& closures = GrowableObjectArray::Handle(Z); | 718 GrowableObjectArray& closures = GrowableObjectArray::Handle(Z); |
718 | 719 |
719 for (intptr_t i = 0; i < libraries_.Length(); i++) { | 720 for (intptr_t i = 0; i < libraries_.Length(); i++) { |
720 lib ^= libraries_.At(i); | 721 lib ^= libraries_.At(i); |
721 ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate); | 722 ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate); |
722 while (it.HasNext()) { | 723 while (it.HasNext()) { |
723 cls = it.GetNextClass(); | 724 cls = it.GetNextClass(); |
724 if (cls.IsDynamicClass()) { | 725 if (cls.IsDynamicClass()) { |
725 continue; // class 'dynamic' is in the read-only VM isolate. | 726 continue; // class 'dynamic' is in the read-only VM isolate. |
726 } | 727 } |
727 | 728 |
728 functions = cls.functions(); | 729 functions = cls.functions(); |
729 retained_functions = GrowableObjectArray::New(); | 730 retained_functions = GrowableObjectArray::New(); |
730 for (intptr_t j = 0; j < functions.Length(); j++) { | 731 for (intptr_t j = 0; j < functions.Length(); j++) { |
731 function ^= functions.At(j); | 732 function ^= functions.At(j); |
732 if (function.HasCode()) { | 733 bool retain = function.HasCode(); |
| 734 if (!retain && function.HasImplicitClosureFunction()) { |
| 735 // It can happen that all uses of an implicit closure inline their |
| 736 // target function, leaving the target function uncompiled. Keep |
| 737 // the target function anyway so we can enumerate it to bind its |
| 738 // static calls, etc. |
| 739 function2 = function.ImplicitClosureFunction(); |
| 740 retain = function2.HasCode(); |
| 741 } |
| 742 if (retain) { |
733 retained_functions.Add(function); | 743 retained_functions.Add(function); |
734 function.DropUncompiledImplicitClosureFunction(); | 744 function.DropUncompiledImplicitClosureFunction(); |
735 } else { | 745 } else { |
736 dropped_function_count_++; | 746 dropped_function_count_++; |
737 if (FLAG_trace_precompiler) { | 747 if (FLAG_trace_precompiler) { |
738 THR_Print("Precompilation dropping %s\n", | 748 THR_Print("Precompilation dropping %s\n", |
739 function.ToLibNamePrefixedQualifiedCString()); | 749 function.ToLibNamePrefixedQualifiedCString()); |
740 } | 750 } |
741 } | 751 } |
742 } | 752 } |
(...skipping 30 matching lines...) Expand all Loading... |
773 public: | 783 public: |
774 explicit BindStaticCallsVisitor(Zone* zone) : | 784 explicit BindStaticCallsVisitor(Zone* zone) : |
775 code_(Code::Handle(zone)), | 785 code_(Code::Handle(zone)), |
776 table_(Array::Handle(zone)), | 786 table_(Array::Handle(zone)), |
777 pc_offset_(Smi::Handle(zone)), | 787 pc_offset_(Smi::Handle(zone)), |
778 target_(Function::Handle(zone)), | 788 target_(Function::Handle(zone)), |
779 target_code_(Code::Handle(zone)) { | 789 target_code_(Code::Handle(zone)) { |
780 } | 790 } |
781 | 791 |
782 void VisitFunction(const Function& function) { | 792 void VisitFunction(const Function& function) { |
783 ASSERT(function.HasCode()); | 793 if (!function.HasCode()) { |
| 794 ASSERT(function.HasImplicitClosureFunction()); |
| 795 return; |
| 796 } |
784 code_ = function.CurrentCode(); | 797 code_ = function.CurrentCode(); |
785 table_ = code_.static_calls_target_table(); | 798 table_ = code_.static_calls_target_table(); |
786 | 799 |
787 for (intptr_t i = 0; | 800 for (intptr_t i = 0; |
788 i < table_.Length(); | 801 i < table_.Length(); |
789 i += Code::kSCallTableEntryLength) { | 802 i += Code::kSCallTableEntryLength) { |
790 pc_offset_ ^= table_.At(i + Code::kSCallTableOffsetEntry); | 803 pc_offset_ ^= table_.At(i + Code::kSCallTableOffsetEntry); |
791 target_ ^= table_.At(i + Code::kSCallTableFunctionEntry); | 804 target_ ^= table_.At(i + Code::kSCallTableFunctionEntry); |
792 if (target_.IsNull()) { | 805 if (target_.IsNull()) { |
793 target_code_ ^= table_.At(i + Code::kSCallTableCodeEntry); | 806 target_code_ ^= table_.At(i + Code::kSCallTableCodeEntry); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
830 public: | 843 public: |
831 explicit DedupStackmapsVisitor(Zone* zone) : | 844 explicit DedupStackmapsVisitor(Zone* zone) : |
832 zone_(zone), | 845 zone_(zone), |
833 canonical_stackmaps_(), | 846 canonical_stackmaps_(), |
834 code_(Code::Handle(zone)), | 847 code_(Code::Handle(zone)), |
835 stackmaps_(Array::Handle(zone)), | 848 stackmaps_(Array::Handle(zone)), |
836 stackmap_(Stackmap::Handle(zone)) { | 849 stackmap_(Stackmap::Handle(zone)) { |
837 } | 850 } |
838 | 851 |
839 void VisitFunction(const Function& function) { | 852 void VisitFunction(const Function& function) { |
| 853 if (!function.HasCode()) { |
| 854 ASSERT(function.HasImplicitClosureFunction()); |
| 855 return; |
| 856 } |
840 code_ = function.CurrentCode(); | 857 code_ = function.CurrentCode(); |
841 stackmaps_ = code_.stackmaps(); | 858 stackmaps_ = code_.stackmaps(); |
842 if (stackmaps_.IsNull()) return; | 859 if (stackmaps_.IsNull()) return; |
843 for (intptr_t i = 0; i < stackmaps_.Length(); i++) { | 860 for (intptr_t i = 0; i < stackmaps_.Length(); i++) { |
844 stackmap_ ^= stackmaps_.At(i); | 861 stackmap_ ^= stackmaps_.At(i); |
845 stackmap_ = DedupStackmap(stackmap_); | 862 stackmap_ = DedupStackmap(stackmap_); |
846 stackmaps_.SetAt(i, stackmap_); | 863 stackmaps_.SetAt(i, stackmap_); |
847 } | 864 } |
848 } | 865 } |
849 | 866 |
(...skipping 19 matching lines...) Expand all Loading... |
869 | 886 |
870 DedupStackmapsVisitor visitor(Z); | 887 DedupStackmapsVisitor visitor(Z); |
871 VisitFunctions(&visitor); | 888 VisitFunctions(&visitor); |
872 } | 889 } |
873 | 890 |
874 | 891 |
875 void Precompiler::VisitFunctions(FunctionVisitor* visitor) { | 892 void Precompiler::VisitFunctions(FunctionVisitor* visitor) { |
876 Library& lib = Library::Handle(Z); | 893 Library& lib = Library::Handle(Z); |
877 Class& cls = Class::Handle(Z); | 894 Class& cls = Class::Handle(Z); |
878 Array& functions = Array::Handle(Z); | 895 Array& functions = Array::Handle(Z); |
| 896 Object& object = Object::Handle(Z); |
879 Function& function = Function::Handle(Z); | 897 Function& function = Function::Handle(Z); |
880 GrowableObjectArray& closures = GrowableObjectArray::Handle(Z); | 898 GrowableObjectArray& closures = GrowableObjectArray::Handle(Z); |
881 | 899 |
882 for (intptr_t i = 0; i < libraries_.Length(); i++) { | 900 for (intptr_t i = 0; i < libraries_.Length(); i++) { |
883 lib ^= libraries_.At(i); | 901 lib ^= libraries_.At(i); |
884 ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate); | 902 ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate); |
885 while (it.HasNext()) { | 903 while (it.HasNext()) { |
886 cls = it.GetNextClass(); | 904 cls = it.GetNextClass(); |
887 if (cls.IsDynamicClass()) { | 905 if (cls.IsDynamicClass()) { |
888 continue; // class 'dynamic' is in the read-only VM isolate. | 906 continue; // class 'dynamic' is in the read-only VM isolate. |
889 } | 907 } |
890 | 908 |
891 functions = cls.functions(); | 909 functions = cls.functions(); |
892 for (intptr_t j = 0; j < functions.Length(); j++) { | 910 for (intptr_t j = 0; j < functions.Length(); j++) { |
893 function ^= functions.At(j); | 911 function ^= functions.At(j); |
894 visitor->VisitFunction(function); | 912 visitor->VisitFunction(function); |
895 if (function.HasImplicitClosureFunction()) { | 913 if (function.HasImplicitClosureFunction()) { |
896 function = function.ImplicitClosureFunction(); | 914 function = function.ImplicitClosureFunction(); |
897 visitor->VisitFunction(function); | 915 visitor->VisitFunction(function); |
898 } | 916 } |
899 } | 917 } |
| 918 |
| 919 functions = cls.invocation_dispatcher_cache(); |
| 920 for (intptr_t j = 0; j < functions.Length(); j++) { |
| 921 object = functions.At(j); |
| 922 if (object.IsFunction()) { |
| 923 function ^= functions.At(j); |
| 924 visitor->VisitFunction(function); |
| 925 } |
| 926 } |
900 } | 927 } |
901 } | 928 } |
902 closures = isolate()->object_store()->closure_functions(); | 929 closures = isolate()->object_store()->closure_functions(); |
903 for (intptr_t j = 0; j < closures.Length(); j++) { | 930 for (intptr_t j = 0; j < closures.Length(); j++) { |
904 function ^= closures.At(j); | 931 function ^= closures.At(j); |
905 visitor->VisitFunction(function); | 932 visitor->VisitFunction(function); |
906 } | 933 } |
907 } | 934 } |
908 | 935 |
909 | 936 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
957 cls = it.GetNextClass(); | 984 cls = it.GetNextClass(); |
958 if (cls.IsDynamicClass()) { | 985 if (cls.IsDynamicClass()) { |
959 continue; // class 'dynamic' is in the read-only VM isolate. | 986 continue; // class 'dynamic' is in the read-only VM isolate. |
960 } | 987 } |
961 cls.set_is_allocated(false); | 988 cls.set_is_allocated(false); |
962 } | 989 } |
963 } | 990 } |
964 } | 991 } |
965 | 992 |
966 } // namespace dart | 993 } // namespace dart |
OLD | NEW |