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

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

Issue 2781483005: Improve internal compiler API so that OSR code is never installed on function. (Closed)
Patch Set: cosmetics Created 3 years, 8 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 | « runtime/lib/mirrors.cc ('k') | runtime/vm/compiler.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) 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 639 matching lines...) Expand 10 before | Expand all | Expand 10 after
650 // Compiles target if necessary. 650 // Compiles target if necessary.
651 DEFINE_RUNTIME_ENTRY(PatchStaticCall, 0) { 651 DEFINE_RUNTIME_ENTRY(PatchStaticCall, 0) {
652 DartFrameIterator iterator; 652 DartFrameIterator iterator;
653 StackFrame* caller_frame = iterator.NextFrame(); 653 StackFrame* caller_frame = iterator.NextFrame();
654 ASSERT(caller_frame != NULL); 654 ASSERT(caller_frame != NULL);
655 const Code& caller_code = Code::Handle(zone, caller_frame->LookupDartCode()); 655 const Code& caller_code = Code::Handle(zone, caller_frame->LookupDartCode());
656 ASSERT(!caller_code.IsNull()); 656 ASSERT(!caller_code.IsNull());
657 ASSERT(caller_code.is_optimized()); 657 ASSERT(caller_code.is_optimized());
658 const Function& target_function = Function::Handle( 658 const Function& target_function = Function::Handle(
659 zone, caller_code.GetStaticCallTargetFunctionAt(caller_frame->pc())); 659 zone, caller_code.GetStaticCallTargetFunctionAt(caller_frame->pc()));
660 if (!target_function.HasCode()) { 660 const Code& target_code = Code::Handle(zone, target_function.EnsureHasCode());
661 const Error& error =
662 Error::Handle(zone, Compiler::CompileFunction(thread, target_function));
663 if (!error.IsNull()) {
664 Exceptions::PropagateError(error);
665 }
666 }
667 const Code& target_code = Code::Handle(zone, target_function.CurrentCode());
668 // Before patching verify that we are not repeatedly patching to the same 661 // Before patching verify that we are not repeatedly patching to the same
669 // target. 662 // target.
670 ASSERT(target_code.raw() != 663 ASSERT(target_code.raw() !=
671 CodePatcher::GetStaticCallTargetAt(caller_frame->pc(), caller_code)); 664 CodePatcher::GetStaticCallTargetAt(caller_frame->pc(), caller_code));
672 CodePatcher::PatchStaticCallAt(caller_frame->pc(), caller_code, target_code); 665 CodePatcher::PatchStaticCallAt(caller_frame->pc(), caller_code, target_code);
673 caller_code.SetStaticCallTargetCodeAt(caller_frame->pc(), target_code); 666 caller_code.SetStaticCallTargetCodeAt(caller_frame->pc(), target_code);
674 if (FLAG_trace_patching) { 667 if (FLAG_trace_patching) {
675 THR_Print("PatchStaticCall: patching caller pc %#" Px 668 THR_Print("PatchStaticCall: patching caller pc %#" Px
676 "" 669 ""
677 " to '%s' new entry point %#" Px " (%s)\n", 670 " to '%s' new entry point %#" Px " (%s)\n",
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
933 // Handles a static call in unoptimized code that has one argument type not 926 // Handles a static call in unoptimized code that has one argument type not
934 // seen before. Compile the target if necessary and update the ICData. 927 // seen before. Compile the target if necessary and update the ICData.
935 // Arg0: argument. 928 // Arg0: argument.
936 // Arg1: IC data object. 929 // Arg1: IC data object.
937 DEFINE_RUNTIME_ENTRY(StaticCallMissHandlerOneArg, 2) { 930 DEFINE_RUNTIME_ENTRY(StaticCallMissHandlerOneArg, 2) {
938 const Instance& arg = Instance::CheckedHandle(arguments.ArgAt(0)); 931 const Instance& arg = Instance::CheckedHandle(arguments.ArgAt(0));
939 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1)); 932 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1));
940 // IC data for static call is prepopulated with the statically known target. 933 // IC data for static call is prepopulated with the statically known target.
941 ASSERT(ic_data.NumberOfChecksIs(1)); 934 ASSERT(ic_data.NumberOfChecksIs(1));
942 const Function& target = Function::Handle(ic_data.GetTargetAt(0)); 935 const Function& target = Function::Handle(ic_data.GetTargetAt(0));
943 if (!target.HasCode()) { 936 target.EnsureHasCode();
944 const Error& error =
945 Error::Handle(Compiler::CompileFunction(thread, target));
946 if (!error.IsNull()) {
947 Exceptions::PropagateError(error);
948 }
949 }
950 ASSERT(!target.IsNull() && target.HasCode()); 937 ASSERT(!target.IsNull() && target.HasCode());
951 ic_data.AddReceiverCheck(arg.GetClassId(), target, 1); 938 ic_data.AddReceiverCheck(arg.GetClassId(), target, 1);
952 if (FLAG_trace_ic) { 939 if (FLAG_trace_ic) {
953 DartFrameIterator iterator; 940 DartFrameIterator iterator;
954 StackFrame* caller_frame = iterator.NextFrame(); 941 StackFrame* caller_frame = iterator.NextFrame();
955 ASSERT(caller_frame != NULL); 942 ASSERT(caller_frame != NULL);
956 OS::PrintErr("StaticCallMissHandler at %#" Px " target %s (%" Pd ")\n", 943 OS::PrintErr("StaticCallMissHandler at %#" Px " target %s (%" Pd ")\n",
957 caller_frame->pc(), target.ToCString(), arg.GetClassId()); 944 caller_frame->pc(), target.ToCString(), arg.GetClassId());
958 } 945 }
959 arguments.SetReturn(target); 946 arguments.SetReturn(target);
960 } 947 }
961 948
962 949
963 // Handles a static call in unoptimized code that has two argument types not 950 // Handles a static call in unoptimized code that has two argument types not
964 // seen before. Compile the target if necessary and update the ICData. 951 // seen before. Compile the target if necessary and update the ICData.
965 // Arg0: argument 0. 952 // Arg0: argument 0.
966 // Arg1: argument 1. 953 // Arg1: argument 1.
967 // Arg2: IC data object. 954 // Arg2: IC data object.
968 DEFINE_RUNTIME_ENTRY(StaticCallMissHandlerTwoArgs, 3) { 955 DEFINE_RUNTIME_ENTRY(StaticCallMissHandlerTwoArgs, 3) {
969 const Instance& arg0 = Instance::CheckedHandle(arguments.ArgAt(0)); 956 const Instance& arg0 = Instance::CheckedHandle(arguments.ArgAt(0));
970 const Instance& arg1 = Instance::CheckedHandle(arguments.ArgAt(1)); 957 const Instance& arg1 = Instance::CheckedHandle(arguments.ArgAt(1));
971 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(2)); 958 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(2));
972 // IC data for static call is prepopulated with the statically known target. 959 // IC data for static call is prepopulated with the statically known target.
973 ASSERT(!ic_data.NumberOfChecksIs(0)); 960 ASSERT(!ic_data.NumberOfChecksIs(0));
974 const Function& target = Function::Handle(ic_data.GetTargetAt(0)); 961 const Function& target = Function::Handle(ic_data.GetTargetAt(0));
975 if (!target.HasCode()) { 962 target.EnsureHasCode();
976 const Error& error =
977 Error::Handle(Compiler::CompileFunction(thread, target));
978 if (!error.IsNull()) {
979 Exceptions::PropagateError(error);
980 }
981 }
982 ASSERT(!target.IsNull() && target.HasCode());
983 GrowableArray<intptr_t> cids(2); 963 GrowableArray<intptr_t> cids(2);
984 cids.Add(arg0.GetClassId()); 964 cids.Add(arg0.GetClassId());
985 cids.Add(arg1.GetClassId()); 965 cids.Add(arg1.GetClassId());
986 ic_data.AddCheck(cids, target); 966 ic_data.AddCheck(cids, target);
987 if (FLAG_trace_ic) { 967 if (FLAG_trace_ic) {
988 DartFrameIterator iterator; 968 DartFrameIterator iterator;
989 StackFrame* caller_frame = iterator.NextFrame(); 969 StackFrame* caller_frame = iterator.NextFrame();
990 ASSERT(caller_frame != NULL); 970 ASSERT(caller_frame != NULL);
991 OS::PrintErr("StaticCallMissHandler at %#" Px " target %s (%" Pd ", %" Pd 971 OS::PrintErr("StaticCallMissHandler at %#" Px " target %s (%" Pd ", %" Pd
992 ")\n", 972 ")\n",
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
1314 1294
1315 if (number_of_checks == 0 && !target_function.HasOptionalParameters() && 1295 if (number_of_checks == 0 && !target_function.HasOptionalParameters() &&
1316 !Isolate::Current()->compilation_allowed()) { 1296 !Isolate::Current()->compilation_allowed()) {
1317 // This call site is unlinked: transition to a monomorphic direct call. 1297 // This call site is unlinked: transition to a monomorphic direct call.
1318 // Note we cannot do this if the target has optional parameters because 1298 // Note we cannot do this if the target has optional parameters because
1319 // the monomorphic direct call does not load the arguments descriptor. 1299 // the monomorphic direct call does not load the arguments descriptor.
1320 // We cannot do this if we are still in the middle of precompiling because 1300 // We cannot do this if we are still in the middle of precompiling because
1321 // the monomorphic case hides an live instance selector from the 1301 // the monomorphic case hides an live instance selector from the
1322 // treeshaker. 1302 // treeshaker.
1323 1303
1324 if (!target_function.HasCode()) { 1304 const Code& target_code =
1325 const Error& error = 1305 Code::Handle(zone, target_function.EnsureHasCode());
1326 Error::Handle(Compiler::CompileFunction(thread, target_function));
1327 if (!error.IsNull()) {
1328 Exceptions::PropagateError(error);
1329 }
1330 }
1331 1306
1332 DartFrameIterator iterator; 1307 DartFrameIterator iterator;
1333 StackFrame* miss_function_frame = iterator.NextFrame(); 1308 StackFrame* miss_function_frame = iterator.NextFrame();
1334 ASSERT(miss_function_frame->IsDartFrame()); 1309 ASSERT(miss_function_frame->IsDartFrame());
1335 StackFrame* caller_frame = iterator.NextFrame(); 1310 StackFrame* caller_frame = iterator.NextFrame();
1336 ASSERT(caller_frame->IsDartFrame()); 1311 ASSERT(caller_frame->IsDartFrame());
1337 const Code& caller_code = 1312 const Code& caller_code =
1338 Code::Handle(zone, caller_frame->LookupDartCode()); 1313 Code::Handle(zone, caller_frame->LookupDartCode());
1339 const Code& target_code =
1340 Code::Handle(zone, target_function.CurrentCode());
1341 const Smi& expected_cid = 1314 const Smi& expected_cid =
1342 Smi::Handle(zone, Smi::New(receiver.GetClassId())); 1315 Smi::Handle(zone, Smi::New(receiver.GetClassId()));
1343 1316
1344 CodePatcher::PatchSwitchableCallAt(caller_frame->pc(), caller_code, 1317 CodePatcher::PatchSwitchableCallAt(caller_frame->pc(), caller_code,
1345 expected_cid, target_code); 1318 expected_cid, target_code);
1346 } else { 1319 } else {
1347 ic_data.AddReceiverCheck(receiver.GetClassId(), target_function); 1320 ic_data.AddReceiverCheck(receiver.GetClassId(), target_function);
1348 if (number_of_checks > FLAG_max_polymorphic_checks) { 1321 if (number_of_checks > FLAG_max_polymorphic_checks) {
1349 // Switch to megamorphic call. 1322 // Switch to megamorphic call.
1350 const MegamorphicCache& cache = MegamorphicCache::Handle( 1323 const MegamorphicCache& cache = MegamorphicCache::Handle(
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after
1699 ASSERT(function.unoptimized_code() != Object::null()); 1672 ASSERT(function.unoptimized_code() != Object::null());
1700 intptr_t osr_id = 1673 intptr_t osr_id =
1701 Code::Handle(function.unoptimized_code()).GetDeoptIdForOsr(frame->pc()); 1674 Code::Handle(function.unoptimized_code()).GetDeoptIdForOsr(frame->pc());
1702 ASSERT(osr_id != Compiler::kNoOSRDeoptId); 1675 ASSERT(osr_id != Compiler::kNoOSRDeoptId);
1703 if (FLAG_trace_osr) { 1676 if (FLAG_trace_osr) {
1704 OS::Print("Attempting OSR for %s at id=%" Pd ", count=%" Pd "\n", 1677 OS::Print("Attempting OSR for %s at id=%" Pd ", count=%" Pd "\n",
1705 function.ToFullyQualifiedCString(), osr_id, 1678 function.ToFullyQualifiedCString(), osr_id,
1706 function.usage_counter()); 1679 function.usage_counter());
1707 } 1680 }
1708 1681
1709 const Code& original_code = Code::Handle(function.CurrentCode());
1710 // Since the code is referenced from the frame and the ZoneHandle, 1682 // Since the code is referenced from the frame and the ZoneHandle,
1711 // it cannot have been removed from the function. 1683 // it cannot have been removed from the function.
1712 ASSERT(!original_code.IsNull()); 1684 const Object& result = Object::Handle(
1713 const Error& error = Error::Handle(
1714 Compiler::CompileOptimizedFunction(thread, function, osr_id)); 1685 Compiler::CompileOptimizedFunction(thread, function, osr_id));
1715 if (!error.IsNull()) { 1686 if (result.IsError()) {
1716 Exceptions::PropagateError(error); 1687 Exceptions::PropagateError(Error::Cast(result));
1717 } 1688 }
1718 1689
1719 const Code& optimized_code = Code::Handle(function.CurrentCode()); 1690 if (!result.IsNull()) {
1720 // The current code will not be changed in the case that the compiler 1691 const Code& code = Code::Cast(result);
1721 // bailed out during OSR compilation.
1722 if (optimized_code.raw() != original_code.raw()) {
1723 // The OSR code does not work for calling the function, so restore the
1724 // unoptimized code. Patch the stack frame to return into the OSR
1725 // code.
1726 uword optimized_entry = 1692 uword optimized_entry =
1727 Instructions::UncheckedEntryPoint(optimized_code.instructions()); 1693 Instructions::UncheckedEntryPoint(code.instructions());
1728 function.AttachCode(original_code);
1729 frame->set_pc(optimized_entry); 1694 frame->set_pc(optimized_entry);
1730 frame->set_pc_marker(optimized_code.raw()); 1695 frame->set_pc_marker(code.raw());
1731 } 1696 }
1732 } 1697 }
1733 } 1698 }
1734 1699
1735 1700
1736 DEFINE_RUNTIME_ENTRY(TraceICCall, 2) { 1701 DEFINE_RUNTIME_ENTRY(TraceICCall, 2) {
1737 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(0)); 1702 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(0));
1738 const Function& function = Function::CheckedHandle(arguments.ArgAt(1)); 1703 const Function& function = Function::CheckedHandle(arguments.ArgAt(1));
1739 DartFrameIterator iterator; 1704 DartFrameIterator iterator;
1740 StackFrame* frame = iterator.NextFrame(); 1705 StackFrame* frame = iterator.NextFrame();
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1793 1758
1794 // Reset usage counter for reoptimization before calling optimizer to 1759 // Reset usage counter for reoptimization before calling optimizer to
1795 // prevent recursive triggering of function optimization. 1760 // prevent recursive triggering of function optimization.
1796 function.set_usage_counter(0); 1761 function.set_usage_counter(0);
1797 if (FLAG_trace_compiler || FLAG_trace_optimizing_compiler) { 1762 if (FLAG_trace_compiler || FLAG_trace_optimizing_compiler) {
1798 if (function.HasOptimizedCode()) { 1763 if (function.HasOptimizedCode()) {
1799 THR_Print("ReCompiling function: '%s' \n", 1764 THR_Print("ReCompiling function: '%s' \n",
1800 function.ToFullyQualifiedCString()); 1765 function.ToFullyQualifiedCString());
1801 } 1766 }
1802 } 1767 }
1803 const Error& error = Error::Handle( 1768 const Object& result = Object::Handle(
1804 zone, Compiler::CompileOptimizedFunction(thread, function)); 1769 zone, Compiler::CompileOptimizedFunction(thread, function));
1805 if (!error.IsNull()) { 1770 if (result.IsError()) {
1806 Exceptions::PropagateError(error); 1771 Exceptions::PropagateError(Error::Cast(result));
1807 } 1772 }
1808 const Code& optimized_code = Code::Handle(zone, function.CurrentCode());
1809 ASSERT(!optimized_code.IsNull());
1810 } 1773 }
1811 arguments.SetReturn(function); 1774 arguments.SetReturn(function);
1812 #else 1775 #else
1813 UNREACHABLE(); 1776 UNREACHABLE();
1814 #endif // !DART_PRECOMPILED_RUNTIME 1777 #endif // !DART_PRECOMPILED_RUNTIME
1815 } 1778 }
1816 1779
1817 1780
1818 // The caller must be a static call in a Dart frame, or an entry frame. 1781 // The caller must be a static call in a Dart frame, or an entry frame.
1819 // Patch static call to point to valid code's entry point. 1782 // Patch static call to point to valid code's entry point.
1820 DEFINE_RUNTIME_ENTRY(FixCallersTarget, 0) { 1783 DEFINE_RUNTIME_ENTRY(FixCallersTarget, 0) {
1821 StackFrameIterator iterator(StackFrameIterator::kDontValidateFrames); 1784 StackFrameIterator iterator(StackFrameIterator::kDontValidateFrames);
1822 StackFrame* frame = iterator.NextFrame(); 1785 StackFrame* frame = iterator.NextFrame();
1823 ASSERT(frame != NULL); 1786 ASSERT(frame != NULL);
1824 while (frame->IsStubFrame() || frame->IsExitFrame()) { 1787 while (frame->IsStubFrame() || frame->IsExitFrame()) {
1825 frame = iterator.NextFrame(); 1788 frame = iterator.NextFrame();
1826 ASSERT(frame != NULL); 1789 ASSERT(frame != NULL);
1827 } 1790 }
1828 if (frame->IsEntryFrame()) { 1791 if (frame->IsEntryFrame()) {
1829 // Since function's current code is always unpatched, the entry frame always 1792 // Since function's current code is always unpatched, the entry frame always
1830 // calls to unpatched code. 1793 // calls to unpatched code.
1831 UNREACHABLE(); 1794 UNREACHABLE();
1832 } 1795 }
1833 ASSERT(frame->IsDartFrame()); 1796 ASSERT(frame->IsDartFrame());
1834 const Code& caller_code = Code::Handle(zone, frame->LookupDartCode()); 1797 const Code& caller_code = Code::Handle(zone, frame->LookupDartCode());
1835 ASSERT(caller_code.is_optimized()); 1798 ASSERT(caller_code.is_optimized());
1836 const Function& target_function = Function::Handle( 1799 const Function& target_function = Function::Handle(
1837 zone, caller_code.GetStaticCallTargetFunctionAt(frame->pc())); 1800 zone, caller_code.GetStaticCallTargetFunctionAt(frame->pc()));
1838 if (!target_function.HasCode()) {
1839 const Error& error =
1840 Error::Handle(zone, Compiler::CompileFunction(thread, target_function));
1841 if (!error.IsNull()) {
1842 Exceptions::PropagateError(error);
1843 }
1844 }
1845 ASSERT(target_function.HasCode());
1846 1801
1847 const Code& current_target_code = 1802 const Code& current_target_code =
1848 Code::Handle(zone, target_function.CurrentCode()); 1803 Code::Handle(zone, target_function.EnsureHasCode());
1849 CodePatcher::PatchStaticCallAt(frame->pc(), caller_code, current_target_code); 1804 CodePatcher::PatchStaticCallAt(frame->pc(), caller_code, current_target_code);
1850 caller_code.SetStaticCallTargetCodeAt(frame->pc(), current_target_code); 1805 caller_code.SetStaticCallTargetCodeAt(frame->pc(), current_target_code);
1851 if (FLAG_trace_patching) { 1806 if (FLAG_trace_patching) {
1852 OS::PrintErr("FixCallersTarget: caller %#" Px 1807 OS::PrintErr("FixCallersTarget: caller %#" Px
1853 " " 1808 " "
1854 "target '%s' -> %#" Px "\n", 1809 "target '%s' -> %#" Px "\n",
1855 frame->pc(), target_function.ToFullyQualifiedCString(), 1810 frame->pc(), target_function.ToFullyQualifiedCString(),
1856 current_target_code.UncheckedEntryPoint()); 1811 current_target_code.UncheckedEntryPoint());
1857 } 1812 }
1858 ASSERT(!current_target_code.IsDisabled()); 1813 ASSERT(!current_target_code.IsDisabled());
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after
2261 const intptr_t elm_size = old_data.ElementSizeInBytes(); 2216 const intptr_t elm_size = old_data.ElementSizeInBytes();
2262 const TypedData& new_data = 2217 const TypedData& new_data =
2263 TypedData::Handle(TypedData::New(cid, new_size, Heap::kOld)); 2218 TypedData::Handle(TypedData::New(cid, new_size, Heap::kOld));
2264 TypedData::Copy(new_data, 0, old_data, 0, old_size * elm_size); 2219 TypedData::Copy(new_data, 0, old_data, 0, old_size * elm_size);
2265 typed_data_cell.SetAt(0, new_data); 2220 typed_data_cell.SetAt(0, new_data);
2266 arguments.SetReturn(new_data); 2221 arguments.SetReturn(new_data);
2267 } 2222 }
2268 2223
2269 2224
2270 } // namespace dart 2225 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/lib/mirrors.cc ('k') | runtime/vm/compiler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698