| OLD | NEW |
| 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" |
| (...skipping 29 matching lines...) Expand all Loading... |
| 40 DEFINE_FLAG(bool, trace_runtime_calls, false, "Trace runtime calls"); | 40 DEFINE_FLAG(bool, trace_runtime_calls, false, "Trace runtime calls"); |
| 41 DEFINE_FLAG(int, optimization_counter_threshold, 2000, | 41 DEFINE_FLAG(int, optimization_counter_threshold, 2000, |
| 42 "Function's usage-counter value before it is optimized, -1 means never"); | 42 "Function's usage-counter value before it is optimized, -1 means never"); |
| 43 DECLARE_FLAG(bool, enable_type_checks); | 43 DECLARE_FLAG(bool, enable_type_checks); |
| 44 DECLARE_FLAG(bool, trace_type_checks); | 44 DECLARE_FLAG(bool, trace_type_checks); |
| 45 DECLARE_FLAG(bool, report_usage_count); | 45 DECLARE_FLAG(bool, report_usage_count); |
| 46 DECLARE_FLAG(int, deoptimization_counter_threshold); | 46 DECLARE_FLAG(int, deoptimization_counter_threshold); |
| 47 DEFINE_FLAG(charp, optimization_filter, NULL, "Optimize only named function"); | 47 DEFINE_FLAG(charp, optimization_filter, NULL, "Optimize only named function"); |
| 48 DEFINE_FLAG(bool, trace_failed_optimization_attempts, false, | 48 DEFINE_FLAG(bool, trace_failed_optimization_attempts, false, |
| 49 "Traces all failed optimization attempts"); | 49 "Traces all failed optimization attempts"); |
| 50 DEFINE_FLAG(bool, trace_optimized_ic_calls, false, |
| 51 "Trace IC calls in optimized code."); |
| 52 DEFINE_FLAG(int, reoptimization_counter_threshold, 2000, |
| 53 "Counter threshold before a function gets reoptimized."); |
| 50 DEFINE_FLAG(int, max_subtype_cache_entries, 100, | 54 DEFINE_FLAG(int, max_subtype_cache_entries, 100, |
| 51 "Maximum number of subtype cache entries (number of checks cached)."); | 55 "Maximum number of subtype cache entries (number of checks cached)."); |
| 52 | 56 |
| 53 | 57 |
| 54 DEFINE_RUNTIME_ENTRY(TraceFunctionEntry, 1) { | 58 DEFINE_RUNTIME_ENTRY(TraceFunctionEntry, 1) { |
| 55 ASSERT(arguments.Count() == kTraceFunctionEntryRuntimeEntry.argument_count()); | 59 ASSERT(arguments.Count() == kTraceFunctionEntryRuntimeEntry.argument_count()); |
| 56 const Function& function = Function::CheckedHandle(arguments.At(0)); | 60 const Function& function = Function::CheckedHandle(arguments.At(0)); |
| 57 const String& function_name = String::Handle(function.name()); | 61 const String& function_name = String::Handle(function.name()); |
| 58 const String& class_name = | 62 const String& class_name = |
| 59 String::Handle(Class::Handle(function.Owner()).Name()); | 63 String::Handle(Class::Handle(function.Owner()).Name()); |
| (...skipping 1422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1482 const Function& caller_function = Function::Handle( | 1486 const Function& caller_function = Function::Handle( |
| 1483 caller_frame->LookupDartFunction()); | 1487 caller_frame->LookupDartFunction()); |
| 1484 const Code& code = Code::Handle(caller_frame->LookupDartCode()); | 1488 const Code& code = Code::Handle(caller_frame->LookupDartCode()); |
| 1485 OS::Print(" -> caller: %s (%s)\n", | 1489 OS::Print(" -> caller: %s (%s)\n", |
| 1486 caller_function.ToFullyQualifiedCString(), | 1490 caller_function.ToFullyQualifiedCString(), |
| 1487 code.is_optimized() ? "optimized" : "unoptimized"); | 1491 code.is_optimized() ? "optimized" : "unoptimized"); |
| 1488 } | 1492 } |
| 1489 } | 1493 } |
| 1490 | 1494 |
| 1491 | 1495 |
| 1496 DEFINE_RUNTIME_ENTRY(TraceICCall, 2) { |
| 1497 ASSERT(arguments.Count() == |
| 1498 kTraceICCallRuntimeEntry.argument_count()); |
| 1499 const ICData& ic_data = ICData::CheckedHandle(arguments.At(0)); |
| 1500 const Function& function = Function::CheckedHandle(arguments.At(1)); |
| 1501 DartFrameIterator iterator; |
| 1502 StackFrame* frame = iterator.NextFrame(); |
| 1503 ASSERT(frame != NULL); |
| 1504 OS::Print("IC call @%#"Px": ICData: %p cnt:%"Pd" nchecks: %"Pd" %s %s\n", |
| 1505 frame->pc(), |
| 1506 ic_data.raw(), |
| 1507 function.usage_counter(), |
| 1508 ic_data.NumberOfChecks(), |
| 1509 ic_data.is_closure_call() ? "closure" : "", |
| 1510 function.ToFullyQualifiedCString()); |
| 1511 } |
| 1492 | 1512 |
| 1493 // Only unoptimized code has invocation counter threshold checking. | 1513 |
| 1494 // Once the invocation counter threshold is reached any entry into the | 1514 // This is called from function that needs to be optimized. |
| 1495 // unoptimized code is redirected to this function. | 1515 // The requesting function can be already optimized (reoptimization). |
| 1496 DEFINE_RUNTIME_ENTRY(OptimizeInvokedFunction, 1) { | 1516 DEFINE_RUNTIME_ENTRY(OptimizeInvokedFunction, 1) { |
| 1497 const intptr_t kLowInvocationCount = -100000000; | |
| 1498 ASSERT(arguments.Count() == | 1517 ASSERT(arguments.Count() == |
| 1499 kOptimizeInvokedFunctionRuntimeEntry.argument_count()); | 1518 kOptimizeInvokedFunctionRuntimeEntry.argument_count()); |
| 1519 const intptr_t kLowInvocationCount = -100000000; |
| 1500 const Function& function = Function::CheckedHandle(arguments.At(0)); | 1520 const Function& function = Function::CheckedHandle(arguments.At(0)); |
| 1501 if (isolate->debugger()->IsActive()) { | 1521 if (isolate->debugger()->IsActive()) { |
| 1502 // We cannot set breakpoints in optimized code, so do not optimize | 1522 // We cannot set breakpoints in optimized code, so do not optimize |
| 1503 // the function. | 1523 // the function. |
| 1504 function.set_usage_counter(0); | 1524 function.set_usage_counter(0); |
| 1505 return; | 1525 return; |
| 1506 } | 1526 } |
| 1507 if (function.deoptimization_counter() >= | 1527 if (function.deoptimization_counter() >= |
| 1508 FLAG_deoptimization_counter_threshold) { | 1528 FLAG_deoptimization_counter_threshold) { |
| 1509 if (FLAG_trace_failed_optimization_attempts) { | 1529 if (FLAG_trace_failed_optimization_attempts) { |
| 1510 PrintCaller("Too Many Deoptimizations"); | 1530 PrintCaller("Too Many Deoptimizations"); |
| 1511 } | 1531 } |
| 1512 // TODO(srdjan): Investigate excessive deoptimization. | 1532 // TODO(srdjan): Investigate excessive deoptimization. |
| 1513 function.set_usage_counter(kLowInvocationCount); | 1533 function.set_usage_counter(kLowInvocationCount); |
| 1514 return; | 1534 return; |
| 1515 } | 1535 } |
| 1516 if (function.HasOptimizedCode()) { | |
| 1517 // The caller has been already optimized, the caller is probably in | |
| 1518 // a loop or in a recursive call chain. | |
| 1519 // Leave the usage_counter at the limit so that the count test knows that | |
| 1520 // method is optimized. | |
| 1521 if (FLAG_trace_failed_optimization_attempts) { | |
| 1522 PrintCaller("Has Optimized Code"); | |
| 1523 } | |
| 1524 // TODO(srdjan): Enable reoptimizing optimized code, but most recognize | |
| 1525 // that reoptimization was not already applied. | |
| 1526 return; | |
| 1527 } | |
| 1528 if ((FLAG_optimization_filter != NULL) && | 1536 if ((FLAG_optimization_filter != NULL) && |
| 1529 (strstr(function.ToFullyQualifiedCString(), | 1537 (strstr(function.ToFullyQualifiedCString(), |
| 1530 FLAG_optimization_filter) == NULL)) { | 1538 FLAG_optimization_filter) == NULL)) { |
| 1531 function.set_usage_counter(kLowInvocationCount); | 1539 function.set_usage_counter(kLowInvocationCount); |
| 1532 return; | 1540 return; |
| 1533 } | 1541 } |
| 1534 if (function.is_optimizable()) { | 1542 if (function.is_optimizable()) { |
| 1535 // Compilation patches the entry of unoptimized code. | |
| 1536 ASSERT(!function.HasOptimizedCode()); | |
| 1537 const Error& error = | 1543 const Error& error = |
| 1538 Error::Handle(Compiler::CompileOptimizedFunction(function)); | 1544 Error::Handle(Compiler::CompileOptimizedFunction(function)); |
| 1539 if (!error.IsNull()) { | 1545 if (!error.IsNull()) { |
| 1540 Exceptions::PropagateError(error); | 1546 Exceptions::PropagateError(error); |
| 1541 } | 1547 } |
| 1542 const Code& optimized_code = Code::Handle(function.CurrentCode()); | 1548 const Code& optimized_code = Code::Handle(function.CurrentCode()); |
| 1543 ASSERT(!optimized_code.IsNull()); | 1549 ASSERT(!optimized_code.IsNull()); |
| 1544 function.set_usage_counter(0); | 1550 // Set usage counter for reoptimization. |
| 1551 function.set_usage_counter( |
| 1552 function.usage_counter() - FLAG_reoptimization_counter_threshold); |
| 1545 } else { | 1553 } else { |
| 1546 if (FLAG_trace_failed_optimization_attempts) { | 1554 if (FLAG_trace_failed_optimization_attempts) { |
| 1547 PrintCaller("Not Optimizable"); | 1555 PrintCaller("Not Optimizable"); |
| 1548 } | 1556 } |
| 1549 // TODO(5442338): Abort as this should not happen. | 1557 // TODO(5442338): Abort as this should not happen. |
| 1550 function.set_usage_counter(kLowInvocationCount); | 1558 function.set_usage_counter(kLowInvocationCount); |
| 1551 } | 1559 } |
| 1552 } | 1560 } |
| 1553 | 1561 |
| 1554 | 1562 |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1899 intptr_t line, column; | 1907 intptr_t line, column; |
| 1900 script.GetTokenLocation(token_pos, &line, &column); | 1908 script.GetTokenLocation(token_pos, &line, &column); |
| 1901 String& line_string = String::Handle(script.GetLine(line)); | 1909 String& line_string = String::Handle(script.GetLine(line)); |
| 1902 OS::Print(" Function: %s\n", top_function.ToFullyQualifiedCString()); | 1910 OS::Print(" Function: %s\n", top_function.ToFullyQualifiedCString()); |
| 1903 OS::Print(" Line %"Pd": '%s'\n", line, line_string.ToCString()); | 1911 OS::Print(" Line %"Pd": '%s'\n", line, line_string.ToCString()); |
| 1904 } | 1912 } |
| 1905 } | 1913 } |
| 1906 | 1914 |
| 1907 | 1915 |
| 1908 } // namespace dart | 1916 } // namespace dart |
| OLD | NEW |