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

Side by Side Diff: runtime/vm/code_generator.cc

Issue 9460015: Do not count invocations but usage of a function, i.e., increment a function's counter at IC calls … (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 10 months 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
« no previous file with comments | « no previous file | runtime/vm/code_generator_arm.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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/code_generator.h" 5 #include "vm/code_generator.h"
6 6
7 #include "vm/code_index_table.h" 7 #include "vm/code_index_table.h"
8 #include "vm/code_patcher.h" 8 #include "vm/code_patcher.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"
11 #include "vm/dart_entry.h" 11 #include "vm/dart_entry.h"
12 #include "vm/debugger.h" 12 #include "vm/debugger.h"
13 #include "vm/exceptions.h" 13 #include "vm/exceptions.h"
14 #include "vm/object_store.h" 14 #include "vm/object_store.h"
15 #include "vm/resolver.h" 15 #include "vm/resolver.h"
16 #include "vm/runtime_entry.h" 16 #include "vm/runtime_entry.h"
17 #include "vm/stack_frame.h" 17 #include "vm/stack_frame.h"
18 #include "vm/verifier.h" 18 #include "vm/verifier.h"
19 19
20 namespace dart { 20 namespace dart {
21 21
22 DEFINE_FLAG(bool, inline_cache, true, "enable inline caches"); 22 DEFINE_FLAG(bool, inline_cache, true, "enable inline caches");
23 DEFINE_FLAG(bool, trace_deopt, false, "Trace deoptimization"); 23 DEFINE_FLAG(bool, trace_deopt, false, "Trace deoptimization");
24 DEFINE_FLAG(bool, trace_ic, false, "trace IC handling"); 24 DEFINE_FLAG(bool, trace_ic, false, "trace IC handling");
25 DEFINE_FLAG(bool, trace_patching, false, "Trace patching of code."); 25 DEFINE_FLAG(bool, trace_patching, false, "Trace patching of code.");
26 DEFINE_FLAG(bool, trace_runtime_calls, false, "Trace runtime calls."); 26 DEFINE_FLAG(bool, trace_runtime_calls, false, "Trace runtime calls.");
27 DEFINE_FLAG(int, optimization_counter_threshold, 2000,
28 "function's usage-counter value before it is optimized, -1 means never.");
29 DECLARE_FLAG(bool, trace_type_checks);
30 DECLARE_FLAG(bool, report_usage_count);
27 DECLARE_FLAG(int, deoptimization_counter_threshold); 31 DECLARE_FLAG(int, deoptimization_counter_threshold);
28 DECLARE_FLAG(bool, trace_type_checks); 32
33
34 bool CodeGenerator::CanOptimize() {
35 return
36 !FLAG_report_usage_count &&
37 (FLAG_optimization_counter_threshold >= 0) &&
38 !Isolate::Current()->debugger()->IsActive();
39 }
29 40
30 41
31 void CodeGenerator::DescriptorList::AddDescriptor( 42 void CodeGenerator::DescriptorList::AddDescriptor(
32 PcDescriptors::Kind kind, 43 PcDescriptors::Kind kind,
33 intptr_t pc_offset, 44 intptr_t pc_offset,
34 intptr_t node_id, 45 intptr_t node_id,
35 intptr_t token_index, 46 intptr_t token_index,
36 intptr_t try_index) { 47 intptr_t try_index) {
37 struct PcDesc data; 48 struct PcDesc data;
38 data.pc_offset = pc_offset; 49 data.pc_offset = pc_offset;
(...skipping 906 matching lines...) Expand 10 before | Expand all | Expand 10 after
945 // Only unoptimized code has invocation counter threshold checking. 956 // Only unoptimized code has invocation counter threshold checking.
946 // Once the invocation counter threshold is reached any entry into the 957 // Once the invocation counter threshold is reached any entry into the
947 // unoptimized code is redirected to this function. 958 // unoptimized code is redirected to this function.
948 DEFINE_RUNTIME_ENTRY(OptimizeInvokedFunction, 1) { 959 DEFINE_RUNTIME_ENTRY(OptimizeInvokedFunction, 1) {
949 ASSERT(arguments.Count() == 960 ASSERT(arguments.Count() ==
950 kOptimizeInvokedFunctionRuntimeEntry.argument_count()); 961 kOptimizeInvokedFunctionRuntimeEntry.argument_count());
951 const Function& function = Function::CheckedHandle(arguments.At(0)); 962 const Function& function = Function::CheckedHandle(arguments.At(0));
952 if (function.deoptimization_counter() >= 963 if (function.deoptimization_counter() >=
953 FLAG_deoptimization_counter_threshold) { 964 FLAG_deoptimization_counter_threshold) {
954 // TODO(srdjan): Investigate excessive deoptimization. 965 // TODO(srdjan): Investigate excessive deoptimization.
955 function.set_invocation_counter(0); 966 function.set_usage_counter(0);
967 return;
968 }
969 if (Code::Handle(function.code()).is_optimized()) {
970 // The caller has been already optimized.
971 // TODO(srdjan): This is a significant slowdown, the caller is probably in
972 // a loop. Maybe test if the code has been optimized before calling.
973 // If this happens from optimized code, then it means that the optimized
974 // code needs to be reoptimized.
975 function.set_usage_counter(0);
956 return; 976 return;
957 } 977 }
958 if (function.is_optimizable()) { 978 if (function.is_optimizable()) {
959 ASSERT(!Code::Handle(function.code()).is_optimized()); 979 ASSERT(!Code::Handle(function.code()).is_optimized());
960 const Code& unoptimized_code = Code::Handle(function.code()); 980 const Code& unoptimized_code = Code::Handle(function.code());
961 // Compilation patches the entry of unoptimized code. 981 // Compilation patches the entry of unoptimized code.
962 const Error& error = 982 const Error& error =
963 Error::Handle(Compiler::CompileOptimizedFunction(function)); 983 Error::Handle(Compiler::CompileOptimizedFunction(function));
964 if (!error.IsNull()) { 984 if (!error.IsNull()) {
965 Exceptions::PropagateError(error); 985 Exceptions::PropagateError(error);
966 } 986 }
967 const Code& optimized_code = Code::Handle(function.code()); 987 const Code& optimized_code = Code::Handle(function.code());
968 ASSERT(!optimized_code.IsNull()); 988 ASSERT(!optimized_code.IsNull());
969 ASSERT(!unoptimized_code.IsNull()); 989 ASSERT(!unoptimized_code.IsNull());
970 } else { 990 } else {
971 // TODO(5442338): Abort as this should not happen. 991 // TODO(5442338): Abort as this should not happen.
972 function.set_invocation_counter(0); 992 function.set_usage_counter(0);
973 } 993 }
974 } 994 }
975 995
976 996
977 // The caller must be a static call in a Dart frame, or an entry frame. 997 // The caller must be a static call in a Dart frame, or an entry frame.
978 // Patch static call to point to 'new_entry_point'. 998 // Patch static call to point to 'new_entry_point'.
979 DEFINE_RUNTIME_ENTRY(FixCallersTarget, 1) { 999 DEFINE_RUNTIME_ENTRY(FixCallersTarget, 1) {
980 ASSERT(arguments.Count() == kFixCallersTargetRuntimeEntry.argument_count()); 1000 ASSERT(arguments.Count() == kFixCallersTargetRuntimeEntry.argument_count());
981 const Function& function = Function::CheckedHandle(arguments.At(0)); 1001 const Function& function = Function::CheckedHandle(arguments.At(0));
982 ASSERT(!function.IsNull()); 1002 ASSERT(!function.IsNull());
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1054 const Class& cls = Class::Handle(function.owner()); 1074 const Class& cls = Class::Handle(function.owner());
1055 const Script& script = Script::Handle(cls.script()); 1075 const Script& script = Script::Handle(cls.script());
1056 intptr_t line, column; 1076 intptr_t line, column;
1057 script.GetTokenLocation(deopt_token_index, &line, &column); 1077 script.GetTokenLocation(deopt_token_index, &line, &column);
1058 OS::Print(" Line: %d Column: %d ", line, column); 1078 OS::Print(" Line: %d Column: %d ", line, column);
1059 OS::Print(">> %s\n", String::Handle(script.GetLine(line)).ToCString()); 1079 OS::Print(">> %s\n", String::Handle(script.GetLine(line)).ToCString());
1060 } 1080 }
1061 caller_frame->set_pc(continue_at_pc); 1081 caller_frame->set_pc(continue_at_pc);
1062 // Clear invocation counter so that the function gets optimized after 1082 // Clear invocation counter so that the function gets optimized after
1063 // types/classes have been collected. 1083 // types/classes have been collected.
1064 function.set_invocation_counter(0); 1084 function.set_usage_counter(0);
1065 function.set_deoptimization_counter(function.deoptimization_counter() + 1); 1085 function.set_deoptimization_counter(function.deoptimization_counter() + 1);
1066 1086
1067 // We have to skip the following otherwise the compiler will complain 1087 // We have to skip the following otherwise the compiler will complain
1068 // when it attempts to install unoptimized code into a function that 1088 // when it attempts to install unoptimized code into a function that
1069 // was already deoptimized. 1089 // was already deoptimized.
1070 if (Code::Handle(function.code()).is_optimized()) { 1090 if (Code::Handle(function.code()).is_optimized()) {
1071 // Get unoptimized code. Compilation restores (reenables) the entry of 1091 // Get unoptimized code. Compilation restores (reenables) the entry of
1072 // unoptimized code. 1092 // unoptimized code.
1073 const Error& error = Error::Handle(Compiler::CompileFunction(function)); 1093 const Error& error = Error::Handle(Compiler::CompileFunction(function));
1074 if (!error.IsNull()) { 1094 if (!error.IsNull()) {
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1157 } 1177 }
1158 } 1178 }
1159 } 1179 }
1160 // The cache is null terminated, therefore the loop above should never 1180 // The cache is null terminated, therefore the loop above should never
1161 // terminate by itself. 1181 // terminate by itself.
1162 UNREACHABLE(); 1182 UNREACHABLE();
1163 return Code::null(); 1183 return Code::null();
1164 } 1184 }
1165 1185
1166 } // namespace dart 1186 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/code_generator_arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698