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

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: 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
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 640 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 if (!target_function.HasCode()) {
661 const Error& error = 661 const Object& result = Object::Handle(
662 Error::Handle(zone, Compiler::CompileFunction(thread, target_function)); 662 zone, Compiler::CompileFunction(thread, target_function));
663 if (!error.IsNull()) { 663 if (result.IsError()) {
664 Exceptions::PropagateError(error); 664 Exceptions::PropagateError(Error::Cast(result));
665 } 665 }
666 } 666 }
667 const Code& target_code = Code::Handle(zone, target_function.CurrentCode()); 667 const Code& target_code = Code::Handle(zone, target_function.CurrentCode());
668 // Before patching verify that we are not repeatedly patching to the same 668 // Before patching verify that we are not repeatedly patching to the same
669 // target. 669 // target.
670 ASSERT(target_code.raw() != 670 ASSERT(target_code.raw() !=
671 CodePatcher::GetStaticCallTargetAt(caller_frame->pc(), caller_code)); 671 CodePatcher::GetStaticCallTargetAt(caller_frame->pc(), caller_code));
672 CodePatcher::PatchStaticCallAt(caller_frame->pc(), caller_code, target_code); 672 CodePatcher::PatchStaticCallAt(caller_frame->pc(), caller_code, target_code);
673 caller_code.SetStaticCallTargetCodeAt(caller_frame->pc(), target_code); 673 caller_code.SetStaticCallTargetCodeAt(caller_frame->pc(), target_code);
674 if (FLAG_trace_patching) { 674 if (FLAG_trace_patching) {
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
934 // seen before. Compile the target if necessary and update the ICData. 934 // seen before. Compile the target if necessary and update the ICData.
935 // Arg0: argument. 935 // Arg0: argument.
936 // Arg1: IC data object. 936 // Arg1: IC data object.
937 DEFINE_RUNTIME_ENTRY(StaticCallMissHandlerOneArg, 2) { 937 DEFINE_RUNTIME_ENTRY(StaticCallMissHandlerOneArg, 2) {
938 const Instance& arg = Instance::CheckedHandle(arguments.ArgAt(0)); 938 const Instance& arg = Instance::CheckedHandle(arguments.ArgAt(0));
939 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1)); 939 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(1));
940 // IC data for static call is prepopulated with the statically known target. 940 // IC data for static call is prepopulated with the statically known target.
941 ASSERT(ic_data.NumberOfChecksIs(1)); 941 ASSERT(ic_data.NumberOfChecksIs(1));
942 const Function& target = Function::Handle(ic_data.GetTargetAt(0)); 942 const Function& target = Function::Handle(ic_data.GetTargetAt(0));
943 if (!target.HasCode()) { 943 if (!target.HasCode()) {
944 const Error& error = 944 const Object& result =
945 Error::Handle(Compiler::CompileFunction(thread, target)); 945 Object::Handle(Compiler::CompileFunction(thread, target));
946 if (!error.IsNull()) { 946 if (result.IsError()) {
947 Exceptions::PropagateError(error); 947 Exceptions::PropagateError(Error::Cast(result));
948 } 948 }
949 } 949 }
950 ASSERT(!target.IsNull() && target.HasCode()); 950 ASSERT(!target.IsNull() && target.HasCode());
951 ic_data.AddReceiverCheck(arg.GetClassId(), target, 1); 951 ic_data.AddReceiverCheck(arg.GetClassId(), target, 1);
952 if (FLAG_trace_ic) { 952 if (FLAG_trace_ic) {
953 DartFrameIterator iterator; 953 DartFrameIterator iterator;
954 StackFrame* caller_frame = iterator.NextFrame(); 954 StackFrame* caller_frame = iterator.NextFrame();
955 ASSERT(caller_frame != NULL); 955 ASSERT(caller_frame != NULL);
956 OS::PrintErr("StaticCallMissHandler at %#" Px " target %s (%" Pd ")\n", 956 OS::PrintErr("StaticCallMissHandler at %#" Px " target %s (%" Pd ")\n",
957 caller_frame->pc(), target.ToCString(), arg.GetClassId()); 957 caller_frame->pc(), target.ToCString(), arg.GetClassId());
958 } 958 }
959 arguments.SetReturn(target); 959 arguments.SetReturn(target);
960 } 960 }
961 961
962 962
963 // Handles a static call in unoptimized code that has two argument types not 963 // 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. 964 // seen before. Compile the target if necessary and update the ICData.
965 // Arg0: argument 0. 965 // Arg0: argument 0.
966 // Arg1: argument 1. 966 // Arg1: argument 1.
967 // Arg2: IC data object. 967 // Arg2: IC data object.
968 DEFINE_RUNTIME_ENTRY(StaticCallMissHandlerTwoArgs, 3) { 968 DEFINE_RUNTIME_ENTRY(StaticCallMissHandlerTwoArgs, 3) {
969 const Instance& arg0 = Instance::CheckedHandle(arguments.ArgAt(0)); 969 const Instance& arg0 = Instance::CheckedHandle(arguments.ArgAt(0));
970 const Instance& arg1 = Instance::CheckedHandle(arguments.ArgAt(1)); 970 const Instance& arg1 = Instance::CheckedHandle(arguments.ArgAt(1));
971 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(2)); 971 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(2));
972 // IC data for static call is prepopulated with the statically known target. 972 // IC data for static call is prepopulated with the statically known target.
973 ASSERT(!ic_data.NumberOfChecksIs(0)); 973 ASSERT(!ic_data.NumberOfChecksIs(0));
974 const Function& target = Function::Handle(ic_data.GetTargetAt(0)); 974 const Function& target = Function::Handle(ic_data.GetTargetAt(0));
975 if (!target.HasCode()) { 975 if (!target.HasCode()) {
976 const Error& error = 976 const Object& result =
977 Error::Handle(Compiler::CompileFunction(thread, target)); 977 Object::Handle(Compiler::CompileFunction(thread, target));
978 if (!error.IsNull()) { 978 if (result.IsError()) {
979 Exceptions::PropagateError(error); 979 Exceptions::PropagateError(Error::Cast(result));
980 } 980 }
981 } 981 }
982 ASSERT(!target.IsNull() && target.HasCode()); 982 ASSERT(!target.IsNull() && target.HasCode());
983 GrowableArray<intptr_t> cids(2); 983 GrowableArray<intptr_t> cids(2);
984 cids.Add(arg0.GetClassId()); 984 cids.Add(arg0.GetClassId());
985 cids.Add(arg1.GetClassId()); 985 cids.Add(arg1.GetClassId());
986 ic_data.AddCheck(cids, target); 986 ic_data.AddCheck(cids, target);
987 if (FLAG_trace_ic) { 987 if (FLAG_trace_ic) {
988 DartFrameIterator iterator; 988 DartFrameIterator iterator;
989 StackFrame* caller_frame = iterator.NextFrame(); 989 StackFrame* caller_frame = iterator.NextFrame();
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
1315 if (number_of_checks == 0 && !target_function.HasOptionalParameters() && 1315 if (number_of_checks == 0 && !target_function.HasOptionalParameters() &&
1316 !Isolate::Current()->compilation_allowed()) { 1316 !Isolate::Current()->compilation_allowed()) {
1317 // This call site is unlinked: transition to a monomorphic direct call. 1317 // This call site is unlinked: transition to a monomorphic direct call.
1318 // Note we cannot do this if the target has optional parameters because 1318 // Note we cannot do this if the target has optional parameters because
1319 // the monomorphic direct call does not load the arguments descriptor. 1319 // 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 1320 // 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 1321 // the monomorphic case hides an live instance selector from the
1322 // treeshaker. 1322 // treeshaker.
1323 1323
1324 if (!target_function.HasCode()) { 1324 if (!target_function.HasCode()) {
1325 const Error& error = 1325 const Object& result =
1326 Error::Handle(Compiler::CompileFunction(thread, target_function)); 1326 Object::Handle(Compiler::CompileFunction(thread, target_function));
1327 if (!error.IsNull()) { 1327 if (result.IsError()) {
1328 Exceptions::PropagateError(error); 1328 Exceptions::PropagateError(Error::Cast(result));
1329 } 1329 }
1330 } 1330 }
1331 1331
1332 DartFrameIterator iterator; 1332 DartFrameIterator iterator;
1333 StackFrame* miss_function_frame = iterator.NextFrame(); 1333 StackFrame* miss_function_frame = iterator.NextFrame();
1334 ASSERT(miss_function_frame->IsDartFrame()); 1334 ASSERT(miss_function_frame->IsDartFrame());
1335 StackFrame* caller_frame = iterator.NextFrame(); 1335 StackFrame* caller_frame = iterator.NextFrame();
1336 ASSERT(caller_frame->IsDartFrame()); 1336 ASSERT(caller_frame->IsDartFrame());
1337 const Code& caller_code = 1337 const Code& caller_code =
1338 Code::Handle(zone, caller_frame->LookupDartCode()); 1338 Code::Handle(zone, caller_frame->LookupDartCode());
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after
1699 ASSERT(function.unoptimized_code() != Object::null()); 1699 ASSERT(function.unoptimized_code() != Object::null());
1700 intptr_t osr_id = 1700 intptr_t osr_id =
1701 Code::Handle(function.unoptimized_code()).GetDeoptIdForOsr(frame->pc()); 1701 Code::Handle(function.unoptimized_code()).GetDeoptIdForOsr(frame->pc());
1702 ASSERT(osr_id != Compiler::kNoOSRDeoptId); 1702 ASSERT(osr_id != Compiler::kNoOSRDeoptId);
1703 if (FLAG_trace_osr) { 1703 if (FLAG_trace_osr) {
1704 OS::Print("Attempting OSR for %s at id=%" Pd ", count=%" Pd "\n", 1704 OS::Print("Attempting OSR for %s at id=%" Pd ", count=%" Pd "\n",
1705 function.ToFullyQualifiedCString(), osr_id, 1705 function.ToFullyQualifiedCString(), osr_id,
1706 function.usage_counter()); 1706 function.usage_counter());
1707 } 1707 }
1708 1708
1709 const Code& original_code = Code::Handle(function.CurrentCode());
1710 // Since the code is referenced from the frame and the ZoneHandle, 1709 // Since the code is referenced from the frame and the ZoneHandle,
1711 // it cannot have been removed from the function. 1710 // it cannot have been removed from the function.
1712 ASSERT(!original_code.IsNull()); 1711 const Object& result = Object::Handle(
1713 const Error& error = Error::Handle(
1714 Compiler::CompileOptimizedFunction(thread, function, osr_id)); 1712 Compiler::CompileOptimizedFunction(thread, function, osr_id));
1715 if (!error.IsNull()) { 1713 if (result.IsError()) {
1716 Exceptions::PropagateError(error); 1714 Exceptions::PropagateError(Error::Cast(result));
1717 } 1715 }
1718 1716
1719 const Code& optimized_code = Code::Handle(function.CurrentCode()); 1717 if (!result.IsNull()) {
1720 // The current code will not be changed in the case that the compiler 1718 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 = 1719 uword optimized_entry =
1727 Instructions::UncheckedEntryPoint(optimized_code.instructions()); 1720 Instructions::UncheckedEntryPoint(code.instructions());
1728 function.AttachCode(original_code);
1729 frame->set_pc(optimized_entry); 1721 frame->set_pc(optimized_entry);
1730 frame->set_pc_marker(optimized_code.raw()); 1722 frame->set_pc_marker(code.raw());
1731 } 1723 }
1732 } 1724 }
1733 } 1725 }
1734 1726
1735 1727
1736 DEFINE_RUNTIME_ENTRY(TraceICCall, 2) { 1728 DEFINE_RUNTIME_ENTRY(TraceICCall, 2) {
1737 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(0)); 1729 const ICData& ic_data = ICData::CheckedHandle(arguments.ArgAt(0));
1738 const Function& function = Function::CheckedHandle(arguments.ArgAt(1)); 1730 const Function& function = Function::CheckedHandle(arguments.ArgAt(1));
1739 DartFrameIterator iterator; 1731 DartFrameIterator iterator;
1740 StackFrame* frame = iterator.NextFrame(); 1732 StackFrame* frame = iterator.NextFrame();
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1793 1785
1794 // Reset usage counter for reoptimization before calling optimizer to 1786 // Reset usage counter for reoptimization before calling optimizer to
1795 // prevent recursive triggering of function optimization. 1787 // prevent recursive triggering of function optimization.
1796 function.set_usage_counter(0); 1788 function.set_usage_counter(0);
1797 if (FLAG_trace_compiler || FLAG_trace_optimizing_compiler) { 1789 if (FLAG_trace_compiler || FLAG_trace_optimizing_compiler) {
1798 if (function.HasOptimizedCode()) { 1790 if (function.HasOptimizedCode()) {
1799 THR_Print("ReCompiling function: '%s' \n", 1791 THR_Print("ReCompiling function: '%s' \n",
1800 function.ToFullyQualifiedCString()); 1792 function.ToFullyQualifiedCString());
1801 } 1793 }
1802 } 1794 }
1803 const Error& error = Error::Handle( 1795 const Object& result = Object::Handle(
1804 zone, Compiler::CompileOptimizedFunction(thread, function)); 1796 zone, Compiler::CompileOptimizedFunction(thread, function));
1805 if (!error.IsNull()) { 1797 if (result.IsError()) {
1806 Exceptions::PropagateError(error); 1798 Exceptions::PropagateError(Error::Cast(result));
1807 } 1799 }
1808 const Code& optimized_code = Code::Handle(zone, function.CurrentCode());
1809 ASSERT(!optimized_code.IsNull());
1810 } 1800 }
1811 arguments.SetReturn(function); 1801 arguments.SetReturn(function);
1812 #else 1802 #else
1813 UNREACHABLE(); 1803 UNREACHABLE();
1814 #endif // !DART_PRECOMPILED_RUNTIME 1804 #endif // !DART_PRECOMPILED_RUNTIME
1815 } 1805 }
1816 1806
1817 1807
1818 // The caller must be a static call in a Dart frame, or an entry frame. 1808 // 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. 1809 // Patch static call to point to valid code's entry point.
1820 DEFINE_RUNTIME_ENTRY(FixCallersTarget, 0) { 1810 DEFINE_RUNTIME_ENTRY(FixCallersTarget, 0) {
1821 StackFrameIterator iterator(StackFrameIterator::kDontValidateFrames); 1811 StackFrameIterator iterator(StackFrameIterator::kDontValidateFrames);
1822 StackFrame* frame = iterator.NextFrame(); 1812 StackFrame* frame = iterator.NextFrame();
1823 ASSERT(frame != NULL); 1813 ASSERT(frame != NULL);
1824 while (frame->IsStubFrame() || frame->IsExitFrame()) { 1814 while (frame->IsStubFrame() || frame->IsExitFrame()) {
1825 frame = iterator.NextFrame(); 1815 frame = iterator.NextFrame();
1826 ASSERT(frame != NULL); 1816 ASSERT(frame != NULL);
1827 } 1817 }
1828 if (frame->IsEntryFrame()) { 1818 if (frame->IsEntryFrame()) {
1829 // Since function's current code is always unpatched, the entry frame always 1819 // Since function's current code is always unpatched, the entry frame always
1830 // calls to unpatched code. 1820 // calls to unpatched code.
1831 UNREACHABLE(); 1821 UNREACHABLE();
1832 } 1822 }
1833 ASSERT(frame->IsDartFrame()); 1823 ASSERT(frame->IsDartFrame());
1834 const Code& caller_code = Code::Handle(zone, frame->LookupDartCode()); 1824 const Code& caller_code = Code::Handle(zone, frame->LookupDartCode());
1835 ASSERT(caller_code.is_optimized()); 1825 ASSERT(caller_code.is_optimized());
1836 const Function& target_function = Function::Handle( 1826 const Function& target_function = Function::Handle(
1837 zone, caller_code.GetStaticCallTargetFunctionAt(frame->pc())); 1827 zone, caller_code.GetStaticCallTargetFunctionAt(frame->pc()));
1838 if (!target_function.HasCode()) { 1828 if (!target_function.HasCode()) {
1839 const Error& error = 1829 const Object& result =
1840 Error::Handle(zone, Compiler::CompileFunction(thread, target_function)); 1830 Object::Handle(Compiler::CompileFunction(thread, target_function));
1841 if (!error.IsNull()) { 1831 if (result.IsError()) {
1842 Exceptions::PropagateError(error); 1832 Exceptions::PropagateError(Error::Cast(result));
1843 } 1833 }
1844 } 1834 }
1845 ASSERT(target_function.HasCode()); 1835 ASSERT(target_function.HasCode());
1846 1836
1847 const Code& current_target_code = 1837 const Code& current_target_code =
1848 Code::Handle(zone, target_function.CurrentCode()); 1838 Code::Handle(zone, target_function.CurrentCode());
1849 CodePatcher::PatchStaticCallAt(frame->pc(), caller_code, current_target_code); 1839 CodePatcher::PatchStaticCallAt(frame->pc(), caller_code, current_target_code);
1850 caller_code.SetStaticCallTargetCodeAt(frame->pc(), current_target_code); 1840 caller_code.SetStaticCallTargetCodeAt(frame->pc(), current_target_code);
1851 if (FLAG_trace_patching) { 1841 if (FLAG_trace_patching) {
1852 OS::PrintErr("FixCallersTarget: caller %#" Px 1842 OS::PrintErr("FixCallersTarget: caller %#" Px
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after
2261 const intptr_t elm_size = old_data.ElementSizeInBytes(); 2251 const intptr_t elm_size = old_data.ElementSizeInBytes();
2262 const TypedData& new_data = 2252 const TypedData& new_data =
2263 TypedData::Handle(TypedData::New(cid, new_size, Heap::kOld)); 2253 TypedData::Handle(TypedData::New(cid, new_size, Heap::kOld));
2264 TypedData::Copy(new_data, 0, old_data, 0, old_size * elm_size); 2254 TypedData::Copy(new_data, 0, old_data, 0, old_size * elm_size);
2265 typed_data_cell.SetAt(0, new_data); 2255 typed_data_cell.SetAt(0, new_data);
2266 arguments.SetReturn(new_data); 2256 arguments.SetReturn(new_data);
2267 } 2257 }
2268 2258
2269 2259
2270 } // namespace dart 2260 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698