Chromium Code Reviews| 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 | 54 |
| 51 | 55 |
| 52 DEFINE_RUNTIME_ENTRY(TraceFunctionEntry, 1) { | 56 DEFINE_RUNTIME_ENTRY(TraceFunctionEntry, 1) { |
| 53 ASSERT(arguments.Count() == kTraceFunctionEntryRuntimeEntry.argument_count()); | 57 ASSERT(arguments.Count() == kTraceFunctionEntryRuntimeEntry.argument_count()); |
| 54 const Function& function = Function::CheckedHandle(arguments.At(0)); | 58 const Function& function = Function::CheckedHandle(arguments.At(0)); |
| 55 const String& function_name = String::Handle(function.name()); | 59 const String& function_name = String::Handle(function.name()); |
| 56 const String& class_name = | 60 const String& class_name = |
| 57 String::Handle(Class::Handle(function.Owner()).Name()); | 61 String::Handle(Class::Handle(function.Owner()).Name()); |
| 58 OS::Print("> Entering '%s.%s'\n", | 62 OS::Print("> Entering '%s.%s'\n", |
| 59 class_name.ToCString(), function_name.ToCString()); | 63 class_name.ToCString(), function_name.ToCString()); |
| (...skipping 1408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1468 const Function& caller_function = Function::Handle( | 1472 const Function& caller_function = Function::Handle( |
| 1469 caller_frame->LookupDartFunction()); | 1473 caller_frame->LookupDartFunction()); |
| 1470 const Code& code = Code::Handle(caller_frame->LookupDartCode()); | 1474 const Code& code = Code::Handle(caller_frame->LookupDartCode()); |
| 1471 OS::Print(" -> caller: %s (%s)\n", | 1475 OS::Print(" -> caller: %s (%s)\n", |
| 1472 caller_function.ToFullyQualifiedCString(), | 1476 caller_function.ToFullyQualifiedCString(), |
| 1473 code.is_optimized() ? "optimized" : "unoptimized"); | 1477 code.is_optimized() ? "optimized" : "unoptimized"); |
| 1474 } | 1478 } |
| 1475 } | 1479 } |
| 1476 | 1480 |
| 1477 | 1481 |
| 1482 DEFINE_RUNTIME_ENTRY(TraceICCall, 2) { | |
| 1483 ASSERT(arguments.Count() == | |
| 1484 kTraceICCallRuntimeEntry.argument_count()); | |
| 1485 const ICData& ic_data = ICData::CheckedHandle(arguments.At(0)); | |
| 1486 const Function& function = Function::CheckedHandle(arguments.At(1)); | |
| 1487 DartFrameIterator iterator; | |
| 1488 StackFrame* frame = iterator.NextFrame(); | |
| 1489 ASSERT(frame != NULL); | |
| 1490 OS::Print("IC call @%#"Px": ICData:%#"Px" cnt:%"Pd" nchecks: %"Pd" %s %s\n", | |
| 1491 frame->pc(), | |
| 1492 reinterpret_cast<uword>(ic_data.raw()), | |
|
Kevin Millikin (Google)
2012/11/13 17:56:53
You don't have to cast the pointer to uword and us
srdjan
2012/11/13 18:21:39
Done.
| |
| 1493 function.usage_counter(), | |
| 1494 ic_data.NumberOfChecks(), | |
| 1495 ic_data.is_closure_call() ? "closure" : "", | |
| 1496 function.ToFullyQualifiedCString()); | |
| 1497 } | |
| 1478 | 1498 |
| 1479 // Only unoptimized code has invocation counter threshold checking. | 1499 |
| 1480 // Once the invocation counter threshold is reached any entry into the | 1500 // This is called from function that needs to be optimized. |
| 1481 // unoptimized code is redirected to this function. | 1501 // The requesting function can be already optimized (reoptimization). |
| 1482 DEFINE_RUNTIME_ENTRY(OptimizeInvokedFunction, 1) { | 1502 DEFINE_RUNTIME_ENTRY(OptimizeInvokedFunction, 1) { |
| 1483 const intptr_t kLowInvocationCount = -100000000; | |
| 1484 ASSERT(arguments.Count() == | 1503 ASSERT(arguments.Count() == |
| 1485 kOptimizeInvokedFunctionRuntimeEntry.argument_count()); | 1504 kOptimizeInvokedFunctionRuntimeEntry.argument_count()); |
| 1505 const intptr_t kLowInvocationCount = -100000000; | |
| 1486 const Function& function = Function::CheckedHandle(arguments.At(0)); | 1506 const Function& function = Function::CheckedHandle(arguments.At(0)); |
| 1487 if (isolate->debugger()->IsActive()) { | 1507 if (isolate->debugger()->IsActive()) { |
| 1488 // We cannot set breakpoints in optimized code, so do not optimize | 1508 // We cannot set breakpoints in optimized code, so do not optimize |
| 1489 // the function. | 1509 // the function. |
| 1490 function.set_usage_counter(0); | 1510 function.set_usage_counter(0); |
| 1491 return; | 1511 return; |
| 1492 } | 1512 } |
| 1493 if (function.deoptimization_counter() >= | 1513 if (function.deoptimization_counter() >= |
| 1494 FLAG_deoptimization_counter_threshold) { | 1514 FLAG_deoptimization_counter_threshold) { |
| 1495 if (FLAG_trace_failed_optimization_attempts) { | 1515 if (FLAG_trace_failed_optimization_attempts) { |
| 1496 PrintCaller("Too Many Deoptimizations"); | 1516 PrintCaller("Too Many Deoptimizations"); |
| 1497 } | 1517 } |
| 1498 // TODO(srdjan): Investigate excessive deoptimization. | 1518 // TODO(srdjan): Investigate excessive deoptimization. |
| 1499 function.set_usage_counter(kLowInvocationCount); | 1519 function.set_usage_counter(kLowInvocationCount); |
| 1500 return; | 1520 return; |
| 1501 } | 1521 } |
| 1502 if (function.HasOptimizedCode()) { | |
| 1503 // The caller has been already optimized, the caller is probably in | |
| 1504 // a loop or in a recursive call chain. | |
| 1505 // Leave the usage_counter at the limit so that the count test knows that | |
| 1506 // method is optimized. | |
| 1507 if (FLAG_trace_failed_optimization_attempts) { | |
| 1508 PrintCaller("Has Optimized Code"); | |
| 1509 } | |
| 1510 // TODO(srdjan): Enable reoptimizing optimized code, but most recognize | |
| 1511 // that reoptimization was not already applied. | |
| 1512 return; | |
| 1513 } | |
| 1514 if ((FLAG_optimization_filter != NULL) && | 1522 if ((FLAG_optimization_filter != NULL) && |
| 1515 (strstr(function.ToFullyQualifiedCString(), | 1523 (strstr(function.ToFullyQualifiedCString(), |
| 1516 FLAG_optimization_filter) == NULL)) { | 1524 FLAG_optimization_filter) == NULL)) { |
| 1517 function.set_usage_counter(kLowInvocationCount); | 1525 function.set_usage_counter(kLowInvocationCount); |
| 1518 return; | 1526 return; |
| 1519 } | 1527 } |
| 1520 if (function.is_optimizable()) { | 1528 if (function.is_optimizable()) { |
| 1521 // Compilation patches the entry of unoptimized code. | |
| 1522 ASSERT(!function.HasOptimizedCode()); | |
| 1523 const Error& error = | 1529 const Error& error = |
| 1524 Error::Handle(Compiler::CompileOptimizedFunction(function)); | 1530 Error::Handle(Compiler::CompileOptimizedFunction(function)); |
| 1525 if (!error.IsNull()) { | 1531 if (!error.IsNull()) { |
| 1526 Exceptions::PropagateError(error); | 1532 Exceptions::PropagateError(error); |
| 1527 } | 1533 } |
| 1528 const Code& optimized_code = Code::Handle(function.CurrentCode()); | 1534 const Code& optimized_code = Code::Handle(function.CurrentCode()); |
| 1529 ASSERT(!optimized_code.IsNull()); | 1535 ASSERT(!optimized_code.IsNull()); |
| 1530 function.set_usage_counter(0); | 1536 // Set usage counter for reoptimization. |
| 1537 function.set_usage_counter( | |
| 1538 function.usage_counter() - FLAG_reoptimization_counter_threshold); | |
| 1531 } else { | 1539 } else { |
| 1532 if (FLAG_trace_failed_optimization_attempts) { | 1540 if (FLAG_trace_failed_optimization_attempts) { |
| 1533 PrintCaller("Not Optimizable"); | 1541 PrintCaller("Not Optimizable"); |
| 1534 } | 1542 } |
| 1535 // TODO(5442338): Abort as this should not happen. | 1543 // TODO(5442338): Abort as this should not happen. |
| 1536 function.set_usage_counter(kLowInvocationCount); | 1544 function.set_usage_counter(kLowInvocationCount); |
| 1537 } | 1545 } |
| 1538 } | 1546 } |
| 1539 | 1547 |
| 1540 | 1548 |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1885 intptr_t line, column; | 1893 intptr_t line, column; |
| 1886 script.GetTokenLocation(token_pos, &line, &column); | 1894 script.GetTokenLocation(token_pos, &line, &column); |
| 1887 String& line_string = String::Handle(script.GetLine(line)); | 1895 String& line_string = String::Handle(script.GetLine(line)); |
| 1888 OS::Print(" Function: %s\n", top_function.ToFullyQualifiedCString()); | 1896 OS::Print(" Function: %s\n", top_function.ToFullyQualifiedCString()); |
| 1889 OS::Print(" Line %"Pd": '%s'\n", line, line_string.ToCString()); | 1897 OS::Print(" Line %"Pd": '%s'\n", line, line_string.ToCString()); |
| 1890 } | 1898 } |
| 1891 } | 1899 } |
| 1892 | 1900 |
| 1893 | 1901 |
| 1894 } // namespace dart | 1902 } // namespace dart |
| OLD | NEW |