| 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 |