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

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

Issue 10704210: Fix problem of excessive attempts to optimize, fix excessive deoptimizations for load/store indexed… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 5 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 | « runtime/vm/code_generator.h ('k') | runtime/vm/exceptions.cc » ('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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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/assembler_macros.h" 7 #include "vm/assembler_macros.h"
8 #include "vm/ast.h" 8 #include "vm/ast.h"
9 #include "vm/code_patcher.h" 9 #include "vm/code_patcher.h"
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
11 #include "vm/dart_api_impl.h" 11 #include "vm/dart_api_impl.h"
12 #include "vm/dart_entry.h" 12 #include "vm/dart_entry.h"
13 #include "vm/debugger.h" 13 #include "vm/debugger.h"
14 #include "vm/exceptions.h" 14 #include "vm/exceptions.h"
15 #include "vm/object_store.h" 15 #include "vm/object_store.h"
16 #include "vm/message.h" 16 #include "vm/message.h"
17 #include "vm/message_handler.h" 17 #include "vm/message_handler.h"
18 #include "vm/resolver.h" 18 #include "vm/resolver.h"
19 #include "vm/runtime_entry.h" 19 #include "vm/runtime_entry.h"
20 #include "vm/stack_frame.h" 20 #include "vm/stack_frame.h"
21 #include "vm/verifier.h" 21 #include "vm/verifier.h"
22 22
23 namespace dart { 23 namespace dart {
24 24
25 DEFINE_FLAG(bool, inline_cache, true, "enable inline caches"); 25 DEFINE_FLAG(bool, inline_cache, true, "Enable inline caches");
26 DEFINE_FLAG(bool, trace_deopt, false, "Trace deoptimization"); 26 DEFINE_FLAG(bool, trace_deopt, false, "Trace deoptimization");
27 DEFINE_FLAG(bool, trace_ic, false, "trace IC handling"); 27 DEFINE_FLAG(bool, trace_ic, false, "Trace IC handling");
28 DEFINE_FLAG(bool, trace_patching, false, "Trace patching of code."); 28 DEFINE_FLAG(bool, trace_patching, false, "Trace patching of code.");
29 DEFINE_FLAG(bool, trace_runtime_calls, false, "Trace runtime calls."); 29 DEFINE_FLAG(bool, trace_runtime_calls, false, "Trace runtime calls");
30 DEFINE_FLAG(int, optimization_counter_threshold, 2000, 30 DEFINE_FLAG(int, optimization_counter_threshold, 2000,
31 "function's usage-counter value before it is optimized, -1 means never."); 31 "Function's usage-counter value before it is optimized, -1 means never");
32 DECLARE_FLAG(bool, enable_type_checks); 32 DECLARE_FLAG(bool, enable_type_checks);
33 DECLARE_FLAG(bool, trace_type_checks); 33 DECLARE_FLAG(bool, trace_type_checks);
34 DECLARE_FLAG(bool, report_usage_count); 34 DECLARE_FLAG(bool, report_usage_count);
35 DECLARE_FLAG(int, deoptimization_counter_threshold); 35 DECLARE_FLAG(int, deoptimization_counter_threshold);
36 DEFINE_FLAG(charp, optimization_filter, NULL, "Optimize only named function"); 36 DEFINE_FLAG(charp, optimization_filter, NULL, "Optimize only named function");
37 DEFINE_FLAG(bool, trace_failed_optimization_attempts, false,
38 "Traces all failed optimization attempts");
37 39
38 40
39 DEFINE_RUNTIME_ENTRY(TraceFunctionEntry, 1) { 41 DEFINE_RUNTIME_ENTRY(TraceFunctionEntry, 1) {
40 ASSERT(arguments.Count() == kTraceFunctionEntryRuntimeEntry.argument_count()); 42 ASSERT(arguments.Count() == kTraceFunctionEntryRuntimeEntry.argument_count());
41 const Function& function = Function::CheckedHandle(arguments.At(0)); 43 const Function& function = Function::CheckedHandle(arguments.At(0));
42 const String& function_name = String::Handle(function.name()); 44 const String& function_name = String::Handle(function.name());
43 const String& class_name = 45 const String& class_name =
44 String::Handle(Class::Handle(function.owner()).Name()); 46 String::Handle(Class::Handle(function.owner()).Name());
45 OS::Print("> Entering '%s.%s'\n", 47 OS::Print("> Entering '%s.%s'\n",
46 class_name.ToCString(), function_name.ToCString()); 48 class_name.ToCString(), function_name.ToCString());
(...skipping 1219 matching lines...) Expand 10 before | Expand all | Expand 10 after
1266 return; 1268 return;
1267 } else { 1269 } else {
1268 // TODO(turnidge): Unwind the stack. 1270 // TODO(turnidge): Unwind the stack.
1269 UNIMPLEMENTED(); 1271 UNIMPLEMENTED();
1270 } 1272 }
1271 } 1273 }
1272 } 1274 }
1273 } 1275 }
1274 1276
1275 1277
1278 static void PrintCaller(const char* msg) {
1279 DartFrameIterator iterator;
1280 StackFrame* top_frame = iterator.NextFrame();
1281 ASSERT(top_frame != NULL);
1282 const Function& top_function = Function::Handle(
1283 top_frame->LookupDartFunction());
1284 OS::Print("Failed: '%s' %s @ 0x%x\n",
1285 msg, top_function.ToFullyQualifiedCString(), top_frame->pc());
1286 StackFrame* caller_frame = iterator.NextFrame();
1287 if (caller_frame != NULL) {
1288 const Function& caller_function = Function::Handle(
1289 caller_frame->LookupDartFunction());
1290 const Code& code = Code::Handle(caller_frame->LookupDartCode());
1291 OS::Print(" -> caller: %s (%s)\n",
1292 caller_function.ToFullyQualifiedCString(),
1293 code.is_optimized() ? "optimized" : "unoptimized");
1294 }
1295 }
1296
1297
1298
1276 // Only unoptimized code has invocation counter threshold checking. 1299 // Only unoptimized code has invocation counter threshold checking.
1277 // Once the invocation counter threshold is reached any entry into the 1300 // Once the invocation counter threshold is reached any entry into the
1278 // unoptimized code is redirected to this function. 1301 // unoptimized code is redirected to this function.
1279 DEFINE_RUNTIME_ENTRY(OptimizeInvokedFunction, 1) { 1302 DEFINE_RUNTIME_ENTRY(OptimizeInvokedFunction, 1) {
1280 const intptr_t kLowInvocationCount = -100000000; 1303 const intptr_t kLowInvocationCount = -100000000;
1281 ASSERT(arguments.Count() == 1304 ASSERT(arguments.Count() ==
1282 kOptimizeInvokedFunctionRuntimeEntry.argument_count()); 1305 kOptimizeInvokedFunctionRuntimeEntry.argument_count());
1283 const Function& function = Function::CheckedHandle(arguments.At(0)); 1306 const Function& function = Function::CheckedHandle(arguments.At(0));
1284 if (isolate->debugger()->IsActive()) { 1307 if (isolate->debugger()->IsActive()) {
1285 // We cannot set breakpoints in optimized code, so do not optimize 1308 // We cannot set breakpoints in optimized code, so do not optimize
1286 // the function. 1309 // the function.
1287 function.set_usage_counter(0); 1310 function.set_usage_counter(0);
1288 return; 1311 return;
1289 } 1312 }
1290 if (function.deoptimization_counter() >= 1313 if (function.deoptimization_counter() >=
1291 FLAG_deoptimization_counter_threshold) { 1314 FLAG_deoptimization_counter_threshold) {
1315 if (FLAG_trace_failed_optimization_attempts) {
1316 PrintCaller("Too Many Deoptimizations");
1317 }
1292 // TODO(srdjan): Investigate excessive deoptimization. 1318 // TODO(srdjan): Investigate excessive deoptimization.
1293 function.set_usage_counter(kLowInvocationCount); 1319 function.set_usage_counter(kLowInvocationCount);
1294 return; 1320 return;
1295 } 1321 }
1296 if (function.HasOptimizedCode()) { 1322 if (function.HasOptimizedCode()) {
1297 // The caller has been already optimized. 1323 // The caller has been already optimized, the caller is probably in
1298 // TODO(srdjan): This is a significant slowdown, the caller is probably in 1324 // a loop or in a recursive call chain.
1299 // a loop. Maybe test if the code has been optimized before calling. 1325 // Leave the usage_counter at the limit so that the count test knows that
1300 // If this happens from optimized code, then it means that the optimized 1326 // method is optimized.
1301 // code needs to be reoptimized. 1327 if (FLAG_trace_failed_optimization_attempts) {
1302 function.set_usage_counter(kLowInvocationCount); 1328 PrintCaller("Has Optimized Code");
1329 }
1330 // TODO(srdjan): Enable reoptimizing optimized code, but most recognize
1331 // that reoptimization was not already applied.
1303 return; 1332 return;
1304 } 1333 }
1305 if ((FLAG_optimization_filter != NULL) && 1334 if ((FLAG_optimization_filter != NULL) &&
1306 (strncmp(function.ToFullyQualifiedCString(), 1335 (strncmp(function.ToFullyQualifiedCString(),
1307 FLAG_optimization_filter, 1336 FLAG_optimization_filter,
1308 strlen(FLAG_optimization_filter)) != 0)) { 1337 strlen(FLAG_optimization_filter)) != 0)) {
1309 function.set_usage_counter(kLowInvocationCount); 1338 function.set_usage_counter(kLowInvocationCount);
1310 return; 1339 return;
1311 } 1340 }
1312 if (function.is_optimizable()) { 1341 if (function.is_optimizable()) {
1342 // Compilation patches the entry of unoptimized code.
1313 ASSERT(!function.HasOptimizedCode()); 1343 ASSERT(!function.HasOptimizedCode());
1314 const Code& unoptimized_code = Code::Handle(function.unoptimized_code());
1315 // Compilation patches the entry of unoptimized code.
1316 const Error& error = 1344 const Error& error =
1317 Error::Handle(Compiler::CompileOptimizedFunction(function)); 1345 Error::Handle(Compiler::CompileOptimizedFunction(function));
1318 if (!error.IsNull()) { 1346 if (!error.IsNull()) {
1319 Exceptions::PropagateError(error); 1347 Exceptions::PropagateError(error);
1320 } 1348 }
1321 const Code& optimized_code = Code::Handle(function.CurrentCode()); 1349 const Code& optimized_code = Code::Handle(function.CurrentCode());
1322 ASSERT(!optimized_code.IsNull()); 1350 ASSERT(!optimized_code.IsNull());
1323 ASSERT(!unoptimized_code.IsNull()); 1351 function.set_usage_counter(0);
1324 } else { 1352 } else {
1353 if (FLAG_trace_failed_optimization_attempts) {
1354 PrintCaller("Not Optimizable");
1355 }
1325 // TODO(5442338): Abort as this should not happen. 1356 // TODO(5442338): Abort as this should not happen.
1326 function.set_usage_counter(kLowInvocationCount); 1357 function.set_usage_counter(kLowInvocationCount);
1327 } 1358 }
1328 } 1359 }
1329 1360
1330 1361
1331 // The caller must be a static call in a Dart frame, or an entry frame. 1362 // The caller must be a static call in a Dart frame, or an entry frame.
1332 // Patch static call to point to 'new_entry_point'. 1363 // Patch static call to point to 'new_entry_point'.
1333 DEFINE_RUNTIME_ENTRY(FixCallersTarget, 1) { 1364 DEFINE_RUNTIME_ENTRY(FixCallersTarget, 1) {
1334 ASSERT(arguments.Count() == kFixCallersTargetRuntimeEntry.argument_count()); 1365 ASSERT(arguments.Count() == kFixCallersTargetRuntimeEntry.argument_count());
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
1538 } 1569 }
1539 } 1570 }
1540 } 1571 }
1541 // The cache is null terminated, therefore the loop above should never 1572 // The cache is null terminated, therefore the loop above should never
1542 // terminate by itself. 1573 // terminate by itself.
1543 UNREACHABLE(); 1574 UNREACHABLE();
1544 return Code::null(); 1575 return Code::null();
1545 } 1576 }
1546 1577
1547 } // namespace dart 1578 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/code_generator.h ('k') | runtime/vm/exceptions.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698