OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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/isolate_reload.h" | 5 #include "vm/isolate_reload.h" |
6 | 6 |
7 #include "vm/become.h" | 7 #include "vm/become.h" |
8 #include "vm/code_generator.h" | 8 #include "vm/code_generator.h" |
9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
10 #include "vm/dart_api_impl.h" | 10 #include "vm/dart_api_impl.h" |
(...skipping 863 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
874 reinterpret_cast<RawObject**>(&saved_class_table_[0]), saved_num_cids_); | 874 reinterpret_cast<RawObject**>(&saved_class_table_[0]), saved_num_cids_); |
875 } | 875 } |
876 } | 876 } |
877 | 877 |
878 | 878 |
879 ObjectStore* IsolateReloadContext::object_store() { | 879 ObjectStore* IsolateReloadContext::object_store() { |
880 return isolate_->object_store(); | 880 return isolate_->object_store(); |
881 } | 881 } |
882 | 882 |
883 | 883 |
884 static void ResetICs(const Function& function, const Code& code) { | |
885 // TODO(johnmccutchan): Relying on the function's ICData Map can miss ICDatas. | |
886 // Use the code's object pool instead. | |
887 if (function.ic_data_array() == Array::null()) { | |
888 // TODO(johnmccutchan): Even in this case, we need to scan the code's object | |
889 // pool instead. | |
890 return; // Already reset in an earlier round. | |
891 } | |
892 | |
893 Thread* thread = Thread::Current(); | |
894 Zone* zone = thread->zone(); | |
895 | |
896 ZoneGrowableArray<const ICData*>* ic_data_array = | |
897 new(zone) ZoneGrowableArray<const ICData*>(); | |
898 function.RestoreICDataMap(ic_data_array, false /* clone ic-data */); | |
899 const intptr_t ic_data_array_length = ic_data_array->length(); | |
900 if (ic_data_array_length == 0) { | |
901 return; | |
902 } | |
903 const PcDescriptors& descriptors = | |
904 PcDescriptors::Handle(code.pc_descriptors()); | |
905 PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kIcCall | | |
906 RawPcDescriptors::kUnoptStaticCall); | |
907 while (iter.MoveNext()) { | |
908 const intptr_t index = iter.DeoptId(); | |
909 if (index >= ic_data_array_length) { | |
910 // TODO(johnmccutchan): Investigate how this can happen. | |
911 continue; | |
912 } | |
913 const ICData* ic_data = (*ic_data_array)[index]; | |
914 if (ic_data == NULL) { | |
915 // TODO(johnmccutchan): Investigate how this can happen. | |
916 continue; | |
917 } | |
918 bool is_static_call = iter.Kind() == RawPcDescriptors::kUnoptStaticCall; | |
919 ic_data->Reset(is_static_call); | |
920 } | |
921 } | |
922 | |
923 | |
924 void IsolateReloadContext::ResetUnoptimizedICsOnStack() { | 884 void IsolateReloadContext::ResetUnoptimizedICsOnStack() { |
925 Code& code = Code::Handle(); | 885 Code& code = Code::Handle(); |
926 Function& function = Function::Handle(); | 886 Function& function = Function::Handle(); |
927 DartFrameIterator iterator; | 887 DartFrameIterator iterator; |
928 StackFrame* frame = iterator.NextFrame(); | 888 StackFrame* frame = iterator.NextFrame(); |
929 while (frame != NULL) { | 889 while (frame != NULL) { |
930 code = frame->LookupDartCode(); | 890 code = frame->LookupDartCode(); |
931 if (code.is_optimized()) { | 891 if (code.is_optimized()) { |
932 // If this code is optimized, we need to reset the ICs in the | 892 // If this code is optimized, we need to reset the ICs in the |
933 // corresponding unoptimized code, which will be executed when the stack | 893 // corresponding unoptimized code, which will be executed when the stack |
934 // unwinds to the the optimized code. | 894 // unwinds to the the optimized code. |
935 function = code.function(); | 895 function = code.function(); |
936 code = function.unoptimized_code(); | 896 code = function.unoptimized_code(); |
937 ASSERT(!code.IsNull()); | 897 ASSERT(!code.IsNull()); |
938 ResetICs(function, code); | 898 code.ResetICDatas(); |
939 } else { | 899 } else { |
940 function = code.function(); | 900 code.ResetICDatas(); |
941 ResetICs(function, code); | |
942 } | 901 } |
943 frame = iterator.NextFrame(); | 902 frame = iterator.NextFrame(); |
944 } | 903 } |
945 } | 904 } |
946 | 905 |
947 | 906 |
948 void IsolateReloadContext::ResetMegamorphicCaches() { | 907 void IsolateReloadContext::ResetMegamorphicCaches() { |
949 object_store()->set_megamorphic_cache_table(GrowableObjectArray::Handle()); | 908 object_store()->set_megamorphic_cache_table(GrowableObjectArray::Handle()); |
950 // Since any current optimized code will not make any more calls, it may be | 909 // Since any current optimized code will not make any more calls, it may be |
951 // better to clear the table instead of clearing each of the caches, allow | 910 // better to clear the table instead of clearing each of the caches, allow |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
984 const bool clear_code = IsFromDirtyLibrary(func); | 943 const bool clear_code = IsFromDirtyLibrary(func); |
985 const bool stub_code = code_.IsStubCode(); | 944 const bool stub_code = code_.IsStubCode(); |
986 | 945 |
987 // Zero edge counters. | 946 // Zero edge counters. |
988 func.ZeroEdgeCounters(); | 947 func.ZeroEdgeCounters(); |
989 | 948 |
990 if (!stub_code) { | 949 if (!stub_code) { |
991 if (clear_code) { | 950 if (clear_code) { |
992 ClearAllCode(func); | 951 ClearAllCode(func); |
993 } else { | 952 } else { |
994 PreserveUnoptimizedCode(func); | 953 PreserveUnoptimizedCode(); |
995 } | 954 } |
996 } | 955 } |
997 | 956 |
998 // Clear counters. | 957 // Clear counters. |
999 func.set_usage_counter(0); | 958 func.set_usage_counter(0); |
1000 func.set_deoptimization_counter(0); | 959 func.set_deoptimization_counter(0); |
1001 func.set_optimized_instruction_count(0); | 960 func.set_optimized_instruction_count(0); |
1002 func.set_optimized_call_site_count(0); | 961 func.set_optimized_call_site_count(0); |
1003 } | 962 } |
1004 } | 963 } |
1005 | 964 |
1006 private: | 965 private: |
1007 void ClearAllCode(const Function& func) { | 966 void ClearAllCode(const Function& func) { |
1008 // Null out the ICData array and code. | 967 // Null out the ICData array and code. |
1009 func.ClearICDataArray(); | 968 func.ClearICDataArray(); |
1010 func.ClearCode(); | 969 func.ClearCode(); |
1011 func.set_was_compiled(false); | 970 func.set_was_compiled(false); |
1012 } | 971 } |
1013 | 972 |
1014 void PreserveUnoptimizedCode(const Function& func) { | 973 void PreserveUnoptimizedCode() { |
1015 ASSERT(!code_.IsNull()); | 974 ASSERT(!code_.IsNull()); |
1016 // We are preserving the unoptimized code, fill all ICData arrays with | 975 // We are preserving the unoptimized code, fill all ICData arrays with |
1017 // the sentinel values so that we have no stale type feedback. | 976 // the sentinel values so that we have no stale type feedback. |
1018 func.FillICDataWithSentinels(code_); | 977 code_.ResetICDatas(); |
1019 } | 978 } |
1020 | 979 |
1021 bool IsFromDirtyLibrary(const Function& func) { | 980 bool IsFromDirtyLibrary(const Function& func) { |
1022 owning_class_ = func.Owner(); | 981 owning_class_ = func.Owner(); |
1023 owning_lib_ = owning_class_.library(); | 982 owning_lib_ = owning_class_.library(); |
1024 return reload_context_->IsDirty(owning_lib_); | 983 return reload_context_->IsDirty(owning_lib_); |
1025 } | 984 } |
1026 | 985 |
1027 Object& handle_; | 986 Object& handle_; |
1028 Class& owning_class_; | 987 Class& owning_class_; |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1197 ASSERT(!super_cls.IsNull()); | 1156 ASSERT(!super_cls.IsNull()); |
1198 super_cls.AddDirectSubclass(cls); | 1157 super_cls.AddDirectSubclass(cls); |
1199 } | 1158 } |
1200 } | 1159 } |
1201 } | 1160 } |
1202 } | 1161 } |
1203 | 1162 |
1204 #endif // !PRODUCT | 1163 #endif // !PRODUCT |
1205 | 1164 |
1206 } // namespace dart | 1165 } // namespace dart |
OLD | NEW |