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

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

Issue 1557533002: Eliminate excessive increment of deoptimization counters (e.g., with deep recursion of deoptimized … (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: r Created 4 years, 11 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
« no previous file with comments | « no previous file | runtime/vm/compiler.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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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.h" 7 #include "vm/assembler.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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 "Traces all failed optimization attempts"); 50 "Traces all failed optimization attempts");
51 DEFINE_FLAG(bool, trace_ic, false, "Trace IC handling"); 51 DEFINE_FLAG(bool, trace_ic, false, "Trace IC handling");
52 DEFINE_FLAG(bool, trace_ic_miss_in_optimized, false, 52 DEFINE_FLAG(bool, trace_ic_miss_in_optimized, false,
53 "Trace IC miss in optimized code"); 53 "Trace IC miss in optimized code");
54 DEFINE_FLAG(bool, trace_optimized_ic_calls, false, 54 DEFINE_FLAG(bool, trace_optimized_ic_calls, false,
55 "Trace IC calls in optimized code."); 55 "Trace IC calls in optimized code.");
56 DEFINE_FLAG(bool, trace_patching, false, "Trace patching of code."); 56 DEFINE_FLAG(bool, trace_patching, false, "Trace patching of code.");
57 DEFINE_FLAG(bool, trace_runtime_calls, false, "Trace runtime calls"); 57 DEFINE_FLAG(bool, trace_runtime_calls, false, "Trace runtime calls");
58 DEFINE_FLAG(bool, trace_type_checks, false, "Trace runtime type checks."); 58 DEFINE_FLAG(bool, trace_type_checks, false, "Trace runtime type checks.");
59 59
60 DECLARE_FLAG(int, deoptimization_counter_threshold); 60 DECLARE_FLAG(int, max_deoptimization_counter_threshold);
61 DECLARE_FLAG(bool, enable_inlining_annotations); 61 DECLARE_FLAG(bool, enable_inlining_annotations);
62 DECLARE_FLAG(bool, trace_compiler); 62 DECLARE_FLAG(bool, trace_compiler);
63 DECLARE_FLAG(bool, trace_optimizing_compiler); 63 DECLARE_FLAG(bool, trace_optimizing_compiler);
64 DECLARE_FLAG(bool, warn_on_javascript_compatibility); 64 DECLARE_FLAG(bool, warn_on_javascript_compatibility);
65 DECLARE_FLAG(int, max_polymorphic_checks); 65 DECLARE_FLAG(int, max_polymorphic_checks);
66 66
67 DEFINE_FLAG(bool, use_osr, true, "Use on-stack replacement."); 67 DEFINE_FLAG(bool, use_osr, true, "Use on-stack replacement.");
68 DEFINE_FLAG(bool, trace_osr, false, "Trace attempts at on-stack replacement."); 68 DEFINE_FLAG(bool, trace_osr, false, "Trace attempts at on-stack replacement.");
69 69
70 DEFINE_FLAG(int, stacktrace_every, 0, 70 DEFINE_FLAG(int, stacktrace_every, 0,
(...skipping 599 matching lines...) Expand 10 before | Expand all | Expand 10 after
670 const Code& target_code = Code::Handle(target_function.CurrentCode()); 670 const Code& target_code = Code::Handle(target_function.CurrentCode());
671 // Before patching verify that we are not repeatedly patching to the same 671 // Before patching verify that we are not repeatedly patching to the same
672 // target. 672 // target.
673 ASSERT(target_code.raw() != 673 ASSERT(target_code.raw() !=
674 CodePatcher::GetStaticCallTargetAt(caller_frame->pc(), caller_code)); 674 CodePatcher::GetStaticCallTargetAt(caller_frame->pc(), caller_code));
675 CodePatcher::PatchStaticCallAt(caller_frame->pc(), 675 CodePatcher::PatchStaticCallAt(caller_frame->pc(),
676 caller_code, 676 caller_code,
677 target_code); 677 target_code);
678 caller_code.SetStaticCallTargetCodeAt(caller_frame->pc(), target_code); 678 caller_code.SetStaticCallTargetCodeAt(caller_frame->pc(), target_code);
679 if (FLAG_trace_patching) { 679 if (FLAG_trace_patching) {
680 OS::PrintErr("PatchStaticCall: patching caller pc %#" Px "" 680 THR_Print("PatchStaticCall: patching caller pc %#" Px ""
681 " to '%s' new entry point %#" Px " (%s)\n", 681 " to '%s' new entry point %#" Px " (%s)\n",
682 caller_frame->pc(), 682 caller_frame->pc(),
683 target_function.ToFullyQualifiedCString(), 683 target_function.ToFullyQualifiedCString(),
684 target_code.EntryPoint(), 684 target_code.EntryPoint(),
685 target_code.is_optimized() ? "optimized" : "unoptimized"); 685 target_code.is_optimized() ? "optimized" : "unoptimized");
686 } 686 }
687 arguments.SetReturn(target_code); 687 arguments.SetReturn(target_code);
688 } 688 }
689 689
690 690
(...skipping 557 matching lines...) Expand 10 before | Expand all | Expand 10 after
1248 const intptr_t kLowInvocationCount = -100000000; 1248 const intptr_t kLowInvocationCount = -100000000;
1249 Isolate* isolate = thread->isolate(); 1249 Isolate* isolate = thread->isolate();
1250 if (isolate->debugger()->IsStepping() || 1250 if (isolate->debugger()->IsStepping() ||
1251 isolate->debugger()->HasBreakpoint(function, thread->zone())) { 1251 isolate->debugger()->HasBreakpoint(function, thread->zone())) {
1252 // We cannot set breakpoints and single step in optimized code, 1252 // We cannot set breakpoints and single step in optimized code,
1253 // so do not optimize the function. 1253 // so do not optimize the function.
1254 function.set_usage_counter(0); 1254 function.set_usage_counter(0);
1255 return false; 1255 return false;
1256 } 1256 }
1257 if (function.deoptimization_counter() >= 1257 if (function.deoptimization_counter() >=
1258 FLAG_deoptimization_counter_threshold) { 1258 FLAG_max_deoptimization_counter_threshold) {
1259 if (FLAG_trace_failed_optimization_attempts || 1259 if (FLAG_trace_failed_optimization_attempts ||
1260 FLAG_stop_on_excessive_deoptimization) { 1260 FLAG_stop_on_excessive_deoptimization) {
1261 OS::PrintErr("Too Many Deoptimizations: %s\n", 1261 OS::PrintErr("Too Many Deoptimizations: %s\n",
1262 function.ToFullyQualifiedCString()); 1262 function.ToFullyQualifiedCString());
1263 if (FLAG_stop_on_excessive_deoptimization) { 1263 if (FLAG_stop_on_excessive_deoptimization) {
1264 FATAL("Stop on excessive deoptimization"); 1264 FATAL("Stop on excessive deoptimization");
1265 } 1265 }
1266 } 1266 }
1267 // TODO(srdjan): Investigate excessive deoptimization. 1267 // TODO(srdjan): Investigate excessive deoptimization.
1268 function.set_usage_counter(kLowInvocationCount); 1268 function.set_usage_counter(kLowInvocationCount);
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after
1700 cpu_registers_copy[i] = 1700 cpu_registers_copy[i] =
1701 *reinterpret_cast<intptr_t*>(saved_registers_address); 1701 *reinterpret_cast<intptr_t*>(saved_registers_address);
1702 saved_registers_address += kWordSize; 1702 saved_registers_address += kWordSize;
1703 } 1703 }
1704 *cpu_registers = cpu_registers_copy; 1704 *cpu_registers = cpu_registers_copy;
1705 } 1705 }
1706 1706
1707 1707
1708 // Copies saved registers and caller's frame into temporary buffers. 1708 // Copies saved registers and caller's frame into temporary buffers.
1709 // Returns the stack size of unoptimized frame. 1709 // Returns the stack size of unoptimized frame.
1710 // The calling code must be optimized, but its function may not have
1711 // have optimized code if the code is OSR code, or if the code was invalidated
1712 // through class loading/finalization or field guard.
1710 DEFINE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, 1713 DEFINE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame,
1711 2, 1714 2,
1712 uword saved_registers_address, 1715 uword saved_registers_address,
1713 uword is_lazy_deopt) { 1716 uword is_lazy_deopt) {
1714 Thread* thread = Thread::Current(); 1717 Thread* thread = Thread::Current();
1715 Isolate* isolate = thread->isolate(); 1718 Isolate* isolate = thread->isolate();
1716 StackZone zone(thread); 1719 StackZone zone(thread);
1717 HANDLESCOPE(thread); 1720 HANDLESCOPE(thread);
1718 1721
1719 // All registers have been saved below last-fp as if they were locals. 1722 // All registers have been saved below last-fp as if they were locals.
1720 const uword last_fp = saved_registers_address 1723 const uword last_fp = saved_registers_address
1721 + (kNumberOfCpuRegisters * kWordSize) 1724 + (kNumberOfCpuRegisters * kWordSize)
1722 + (kNumberOfFpuRegisters * kFpuRegisterSize) 1725 + (kNumberOfFpuRegisters * kFpuRegisterSize)
1723 - ((kFirstLocalSlotFromFp + 1) * kWordSize); 1726 - ((kFirstLocalSlotFromFp + 1) * kWordSize);
1724 1727
1725 // Get optimized code and frame that need to be deoptimized. 1728 // Get optimized code and frame that need to be deoptimized.
1726 DartFrameIterator iterator(last_fp); 1729 DartFrameIterator iterator(last_fp);
1727 StackFrame* caller_frame = iterator.NextFrame(); 1730 StackFrame* caller_frame = iterator.NextFrame();
1728 ASSERT(caller_frame != NULL); 1731 ASSERT(caller_frame != NULL);
1729 const Code& optimized_code = Code::Handle(caller_frame->LookupDartCode()); 1732 const Code& optimized_code = Code::Handle(caller_frame->LookupDartCode());
1730 ASSERT(optimized_code.is_optimized()); 1733 ASSERT(optimized_code.is_optimized());
1734 const Function& top_function =
1735 Function::Handle(thread->zone(), optimized_code.function());
1736 const bool deoptimizing_code = top_function.HasOptimizedCode();
1737 if (FLAG_trace_deoptimization) {
1738 const Function& function = Function::Handle(optimized_code.function());
1739 THR_Print("== Deoptimizing code for '%s', %s, %s\n",
1740 function.ToFullyQualifiedCString(),
1741 deoptimizing_code ? "code & frame" : "frame",
1742 is_lazy_deopt ? "lazy-deopt" : "");
1743 }
1731 1744
1732 // Copy the saved registers from the stack. 1745 // Copy the saved registers from the stack.
1733 fpu_register_t* fpu_registers; 1746 fpu_register_t* fpu_registers;
1734 intptr_t* cpu_registers; 1747 intptr_t* cpu_registers;
1735 CopySavedRegisters(saved_registers_address, &fpu_registers, &cpu_registers); 1748 CopySavedRegisters(saved_registers_address, &fpu_registers, &cpu_registers);
1736 1749
1737 // Create the DeoptContext. 1750 // Create the DeoptContext.
1738 DeoptContext* deopt_context = 1751 DeoptContext* deopt_context =
1739 new DeoptContext(caller_frame, 1752 new DeoptContext(caller_frame,
1740 optimized_code, 1753 optimized_code,
1741 DeoptContext::kDestIsOriginalFrame, 1754 DeoptContext::kDestIsOriginalFrame,
1742 fpu_registers, 1755 fpu_registers,
1743 cpu_registers, 1756 cpu_registers,
1744 is_lazy_deopt != 0); 1757 is_lazy_deopt != 0,
1758 deoptimizing_code);
1745 isolate->set_deopt_context(deopt_context); 1759 isolate->set_deopt_context(deopt_context);
1746 1760
1747 // Stack size (FP - SP) in bytes. 1761 // Stack size (FP - SP) in bytes.
1748 return deopt_context->DestStackAdjustment() * kWordSize; 1762 return deopt_context->DestStackAdjustment() * kWordSize;
1749 } 1763 }
1750 END_LEAF_RUNTIME_ENTRY 1764 END_LEAF_RUNTIME_ENTRY
1751 1765
1752 1766
1753 // The stack has been adjusted to fit all values for unoptimized frame. 1767 // The stack has been adjusted to fit all values for unoptimized frame.
1754 // Fill the unoptimized frame. 1768 // Fill the unoptimized frame.
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
1875 const intptr_t elm_size = old_data.ElementSizeInBytes(); 1889 const intptr_t elm_size = old_data.ElementSizeInBytes();
1876 const TypedData& new_data = 1890 const TypedData& new_data =
1877 TypedData::Handle(TypedData::New(cid, new_size, Heap::kOld)); 1891 TypedData::Handle(TypedData::New(cid, new_size, Heap::kOld));
1878 TypedData::Copy(new_data, 0, old_data, 0, old_size * elm_size); 1892 TypedData::Copy(new_data, 0, old_data, 0, old_size * elm_size);
1879 typed_data_cell.SetAt(0, new_data); 1893 typed_data_cell.SetAt(0, new_data);
1880 arguments.SetReturn(new_data); 1894 arguments.SetReturn(new_data);
1881 } 1895 }
1882 1896
1883 1897
1884 } // namespace dart 1898 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/compiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698