| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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/runtime_entry.h" | 5 #include "vm/runtime_entry.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 715 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 726 DEFINE_RUNTIME_ENTRY(ReThrow, 2) { | 726 DEFINE_RUNTIME_ENTRY(ReThrow, 2) { |
| 727 const Instance& exception = Instance::CheckedHandle(zone, arguments.ArgAt(0)); | 727 const Instance& exception = Instance::CheckedHandle(zone, arguments.ArgAt(0)); |
| 728 const Instance& stacktrace = | 728 const Instance& stacktrace = |
| 729 Instance::CheckedHandle(zone, arguments.ArgAt(1)); | 729 Instance::CheckedHandle(zone, arguments.ArgAt(1)); |
| 730 Exceptions::ReThrow(thread, exception, stacktrace); | 730 Exceptions::ReThrow(thread, exception, stacktrace); |
| 731 } | 731 } |
| 732 | 732 |
| 733 // Patches static call in optimized code with the target's entry point. | 733 // Patches static call in optimized code with the target's entry point. |
| 734 // Compiles target if necessary. | 734 // Compiles target if necessary. |
| 735 DEFINE_RUNTIME_ENTRY(PatchStaticCall, 0) { | 735 DEFINE_RUNTIME_ENTRY(PatchStaticCall, 0) { |
| 736 #if !defined(DART_PRECOMPILED_RUNTIME) |
| 736 DartFrameIterator iterator(thread, | 737 DartFrameIterator iterator(thread, |
| 737 StackFrameIterator::kNoCrossThreadIteration); | 738 StackFrameIterator::kNoCrossThreadIteration); |
| 738 StackFrame* caller_frame = iterator.NextFrame(); | 739 StackFrame* caller_frame = iterator.NextFrame(); |
| 739 ASSERT(caller_frame != NULL); | 740 ASSERT(caller_frame != NULL); |
| 740 const Code& caller_code = Code::Handle(zone, caller_frame->LookupDartCode()); | 741 const Code& caller_code = Code::Handle(zone, caller_frame->LookupDartCode()); |
| 741 ASSERT(!caller_code.IsNull()); | 742 ASSERT(!caller_code.IsNull()); |
| 742 ASSERT(caller_code.is_optimized()); | 743 ASSERT(caller_code.is_optimized()); |
| 743 const Function& target_function = Function::Handle( | 744 const Function& target_function = Function::Handle( |
| 744 zone, caller_code.GetStaticCallTargetFunctionAt(caller_frame->pc())); | 745 zone, caller_code.GetStaticCallTargetFunctionAt(caller_frame->pc())); |
| 745 const Code& target_code = Code::Handle(zone, target_function.EnsureHasCode()); | 746 const Code& target_code = Code::Handle(zone, target_function.EnsureHasCode()); |
| 746 // Before patching verify that we are not repeatedly patching to the same | 747 // Before patching verify that we are not repeatedly patching to the same |
| 747 // target. | 748 // target. |
| 748 ASSERT(target_code.raw() != | 749 ASSERT(target_code.raw() != |
| 749 CodePatcher::GetStaticCallTargetAt(caller_frame->pc(), caller_code)); | 750 CodePatcher::GetStaticCallTargetAt(caller_frame->pc(), caller_code)); |
| 750 CodePatcher::PatchStaticCallAt(caller_frame->pc(), caller_code, target_code); | 751 CodePatcher::PatchStaticCallAt(caller_frame->pc(), caller_code, target_code); |
| 751 caller_code.SetStaticCallTargetCodeAt(caller_frame->pc(), target_code); | 752 caller_code.SetStaticCallTargetCodeAt(caller_frame->pc(), target_code); |
| 752 if (FLAG_trace_patching) { | 753 if (FLAG_trace_patching) { |
| 753 THR_Print("PatchStaticCall: patching caller pc %#" Px | 754 THR_Print("PatchStaticCall: patching caller pc %#" Px |
| 754 "" | 755 "" |
| 755 " to '%s' new entry point %#" Px " (%s)\n", | 756 " to '%s' new entry point %#" Px " (%s)\n", |
| 756 caller_frame->pc(), target_function.ToFullyQualifiedCString(), | 757 caller_frame->pc(), target_function.ToFullyQualifiedCString(), |
| 757 target_code.UncheckedEntryPoint(), | 758 target_code.UncheckedEntryPoint(), |
| 758 target_code.is_optimized() ? "optimized" : "unoptimized"); | 759 target_code.is_optimized() ? "optimized" : "unoptimized"); |
| 759 } | 760 } |
| 760 arguments.SetReturn(target_code); | 761 arguments.SetReturn(target_code); |
| 762 #else |
| 763 UNREACHABLE(); |
| 764 #endif |
| 761 } | 765 } |
| 762 | 766 |
| 763 // Result of an invoke may be an unhandled exception, in which case we | 767 // Result of an invoke may be an unhandled exception, in which case we |
| 764 // rethrow it. | 768 // rethrow it. |
| 765 static void CheckResultError(const Object& result) { | 769 static void CheckResultError(const Object& result) { |
| 766 if (result.IsError()) { | 770 if (result.IsError()) { |
| 767 Exceptions::PropagateError(Error::Cast(result)); | 771 Exceptions::PropagateError(Error::Cast(result)); |
| 768 } | 772 } |
| 769 } | 773 } |
| 770 | 774 |
| 771 #if defined(PRODUCT) | 775 #if defined(PRODUCT) || defined(DART_PRECOMPILED_RUNTIME) |
| 772 DEFINE_RUNTIME_ENTRY(BreakpointRuntimeHandler, 0) { | 776 DEFINE_RUNTIME_ENTRY(BreakpointRuntimeHandler, 0) { |
| 773 UNREACHABLE(); | 777 UNREACHABLE(); |
| 774 return; | 778 return; |
| 775 } | 779 } |
| 776 #elif !defined(TARGET_ARCH_DBC) | 780 #elif !defined(TARGET_ARCH_DBC) |
| 777 // Gets called from debug stub when code reaches a breakpoint | 781 // Gets called from debug stub when code reaches a breakpoint |
| 778 // set on a runtime stub call. | 782 // set on a runtime stub call. |
| 779 DEFINE_RUNTIME_ENTRY(BreakpointRuntimeHandler, 0) { | 783 DEFINE_RUNTIME_ENTRY(BreakpointRuntimeHandler, 0) { |
| 780 DartFrameIterator iterator(thread, | 784 DartFrameIterator iterator(thread, |
| 781 StackFrameIterator::kNoCrossThreadIteration); | 785 StackFrameIterator::kNoCrossThreadIteration); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 796 DEFINE_RUNTIME_ENTRY(BreakpointRuntimeHandler, 0) { | 800 DEFINE_RUNTIME_ENTRY(BreakpointRuntimeHandler, 0) { |
| 797 const Error& error = Error::Handle(isolate->debugger()->PauseBreakpoint()); | 801 const Error& error = Error::Handle(isolate->debugger()->PauseBreakpoint()); |
| 798 if (!error.IsNull()) { | 802 if (!error.IsNull()) { |
| 799 Exceptions::PropagateError(error); | 803 Exceptions::PropagateError(error); |
| 800 UNREACHABLE(); | 804 UNREACHABLE(); |
| 801 } | 805 } |
| 802 } | 806 } |
| 803 #endif // !defined(TARGET_ARCH_DBC) | 807 #endif // !defined(TARGET_ARCH_DBC) |
| 804 | 808 |
| 805 DEFINE_RUNTIME_ENTRY(SingleStepHandler, 0) { | 809 DEFINE_RUNTIME_ENTRY(SingleStepHandler, 0) { |
| 806 #if defined(PRODUCT) | 810 #if defined(PRODUCT) || defined(DART_PRECOMPILED_RUNTIME) |
| 807 UNREACHABLE(); | 811 UNREACHABLE(); |
| 808 return; | |
| 809 #else | 812 #else |
| 810 const Error& error = | 813 const Error& error = |
| 811 Error::Handle(zone, isolate->debugger()->PauseStepping()); | 814 Error::Handle(zone, isolate->debugger()->PauseStepping()); |
| 812 if (!error.IsNull()) { | 815 if (!error.IsNull()) { |
| 813 Exceptions::PropagateError(error); | 816 Exceptions::PropagateError(error); |
| 814 UNREACHABLE(); | 817 UNREACHABLE(); |
| 815 } | 818 } |
| 816 #endif | 819 #endif |
| 817 } | 820 } |
| 818 | 821 |
| (...skipping 1040 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1859 } | 1862 } |
| 1860 arguments.SetReturn(function); | 1863 arguments.SetReturn(function); |
| 1861 #else | 1864 #else |
| 1862 UNREACHABLE(); | 1865 UNREACHABLE(); |
| 1863 #endif // !DART_PRECOMPILED_RUNTIME | 1866 #endif // !DART_PRECOMPILED_RUNTIME |
| 1864 } | 1867 } |
| 1865 | 1868 |
| 1866 // The caller must be a static call in a Dart frame, or an entry frame. | 1869 // The caller must be a static call in a Dart frame, or an entry frame. |
| 1867 // Patch static call to point to valid code's entry point. | 1870 // Patch static call to point to valid code's entry point. |
| 1868 DEFINE_RUNTIME_ENTRY(FixCallersTarget, 0) { | 1871 DEFINE_RUNTIME_ENTRY(FixCallersTarget, 0) { |
| 1872 #if !defined(DART_PRECOMPILED_RUNTIME) |
| 1869 StackFrameIterator iterator(StackFrameIterator::kDontValidateFrames, thread, | 1873 StackFrameIterator iterator(StackFrameIterator::kDontValidateFrames, thread, |
| 1870 StackFrameIterator::kNoCrossThreadIteration); | 1874 StackFrameIterator::kNoCrossThreadIteration); |
| 1871 StackFrame* frame = iterator.NextFrame(); | 1875 StackFrame* frame = iterator.NextFrame(); |
| 1872 ASSERT(frame != NULL); | 1876 ASSERT(frame != NULL); |
| 1873 while (frame->IsStubFrame() || frame->IsExitFrame()) { | 1877 while (frame->IsStubFrame() || frame->IsExitFrame()) { |
| 1874 frame = iterator.NextFrame(); | 1878 frame = iterator.NextFrame(); |
| 1875 ASSERT(frame != NULL); | 1879 ASSERT(frame != NULL); |
| 1876 } | 1880 } |
| 1877 if (frame->IsEntryFrame()) { | 1881 if (frame->IsEntryFrame()) { |
| 1878 // Since function's current code is always unpatched, the entry frame always | 1882 // Since function's current code is always unpatched, the entry frame always |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1891 caller_code.SetStaticCallTargetCodeAt(frame->pc(), current_target_code); | 1895 caller_code.SetStaticCallTargetCodeAt(frame->pc(), current_target_code); |
| 1892 if (FLAG_trace_patching) { | 1896 if (FLAG_trace_patching) { |
| 1893 OS::PrintErr("FixCallersTarget: caller %#" Px | 1897 OS::PrintErr("FixCallersTarget: caller %#" Px |
| 1894 " " | 1898 " " |
| 1895 "target '%s' -> %#" Px "\n", | 1899 "target '%s' -> %#" Px "\n", |
| 1896 frame->pc(), target_function.ToFullyQualifiedCString(), | 1900 frame->pc(), target_function.ToFullyQualifiedCString(), |
| 1897 current_target_code.UncheckedEntryPoint()); | 1901 current_target_code.UncheckedEntryPoint()); |
| 1898 } | 1902 } |
| 1899 ASSERT(!current_target_code.IsDisabled()); | 1903 ASSERT(!current_target_code.IsDisabled()); |
| 1900 arguments.SetReturn(current_target_code); | 1904 arguments.SetReturn(current_target_code); |
| 1905 #else |
| 1906 UNREACHABLE(); |
| 1907 #endif |
| 1901 } | 1908 } |
| 1902 | 1909 |
| 1903 // The caller tried to allocate an instance via an invalidated allocation | 1910 // The caller tried to allocate an instance via an invalidated allocation |
| 1904 // stub. | 1911 // stub. |
| 1905 DEFINE_RUNTIME_ENTRY(FixAllocationStubTarget, 0) { | 1912 DEFINE_RUNTIME_ENTRY(FixAllocationStubTarget, 0) { |
| 1906 #if !defined(DART_PRECOMPILED_RUNTIME) | 1913 #if !defined(DART_PRECOMPILED_RUNTIME) |
| 1907 StackFrameIterator iterator(StackFrameIterator::kDontValidateFrames, thread, | 1914 StackFrameIterator iterator(StackFrameIterator::kDontValidateFrames, thread, |
| 1908 StackFrameIterator::kNoCrossThreadIteration); | 1915 StackFrameIterator::kNoCrossThreadIteration); |
| 1909 StackFrame* frame = iterator.NextFrame(); | 1916 StackFrame* frame = iterator.NextFrame(); |
| 1910 ASSERT(frame != NULL); | 1917 ASSERT(frame != NULL); |
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2266 } | 2273 } |
| 2267 } | 2274 } |
| 2268 return remainder; | 2275 return remainder; |
| 2269 } | 2276 } |
| 2270 | 2277 |
| 2271 // Update global type feedback recorded for a field recording the assignment | 2278 // Update global type feedback recorded for a field recording the assignment |
| 2272 // of the given value. | 2279 // of the given value. |
| 2273 // Arg0: Field object; | 2280 // Arg0: Field object; |
| 2274 // Arg1: Value that is being stored. | 2281 // Arg1: Value that is being stored. |
| 2275 DEFINE_RUNTIME_ENTRY(UpdateFieldCid, 2) { | 2282 DEFINE_RUNTIME_ENTRY(UpdateFieldCid, 2) { |
| 2283 #if !defined(DART_PRECOMPILED_RUNTIME) |
| 2276 const Field& field = Field::CheckedHandle(arguments.ArgAt(0)); | 2284 const Field& field = Field::CheckedHandle(arguments.ArgAt(0)); |
| 2277 const Object& value = Object::Handle(arguments.ArgAt(1)); | 2285 const Object& value = Object::Handle(arguments.ArgAt(1)); |
| 2278 field.RecordStore(value); | 2286 field.RecordStore(value); |
| 2287 #else |
| 2288 UNREACHABLE(); |
| 2289 #endif |
| 2279 } | 2290 } |
| 2280 | 2291 |
| 2281 DEFINE_RUNTIME_ENTRY(InitStaticField, 1) { | 2292 DEFINE_RUNTIME_ENTRY(InitStaticField, 1) { |
| 2282 const Field& field = Field::CheckedHandle(arguments.ArgAt(0)); | 2293 const Field& field = Field::CheckedHandle(arguments.ArgAt(0)); |
| 2283 field.EvaluateInitializer(); | 2294 field.EvaluateInitializer(); |
| 2284 } | 2295 } |
| 2285 | 2296 |
| 2286 // Use expected function signatures to help MSVC compiler resolve overloading. | 2297 // Use expected function signatures to help MSVC compiler resolve overloading. |
| 2287 typedef double (*UnaryMathCFunction)(double x); | 2298 typedef double (*UnaryMathCFunction)(double x); |
| 2288 typedef double (*BinaryMathCFunction)(double x, double y); | 2299 typedef double (*BinaryMathCFunction)(double x, double y); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2361 true /* is_float */, | 2372 true /* is_float */, |
| 2362 reinterpret_cast<RuntimeFunction>(static_cast<UnaryMathCFunction>(&tan))); | 2373 reinterpret_cast<RuntimeFunction>(static_cast<UnaryMathCFunction>(&tan))); |
| 2363 | 2374 |
| 2364 DEFINE_RAW_LEAF_RUNTIME_ENTRY( | 2375 DEFINE_RAW_LEAF_RUNTIME_ENTRY( |
| 2365 LibcAtan, | 2376 LibcAtan, |
| 2366 1, | 2377 1, |
| 2367 true /* is_float */, | 2378 true /* is_float */, |
| 2368 reinterpret_cast<RuntimeFunction>(static_cast<UnaryMathCFunction>(&atan))); | 2379 reinterpret_cast<RuntimeFunction>(static_cast<UnaryMathCFunction>(&atan))); |
| 2369 | 2380 |
| 2370 } // namespace dart | 2381 } // namespace dart |
| OLD | NEW |