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 783 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
794 ASSERT(target_code.EntryPoint() != | 794 ASSERT(target_code.EntryPoint() != |
795 CodePatcher::GetStaticCallTargetAt(caller_frame->pc())); | 795 CodePatcher::GetStaticCallTargetAt(caller_frame->pc())); |
796 CodePatcher::PatchStaticCallAt(caller_frame->pc(), target_code.EntryPoint()); | 796 CodePatcher::PatchStaticCallAt(caller_frame->pc(), target_code.EntryPoint()); |
797 caller_code.SetStaticCallTargetCodeAt(caller_frame->pc(), target_code); | 797 caller_code.SetStaticCallTargetCodeAt(caller_frame->pc(), target_code); |
798 if (FLAG_trace_patching) { | 798 if (FLAG_trace_patching) { |
799 OS::Print("PatchStaticCall: patching from %#"Px" to '%s' %#"Px"\n", | 799 OS::Print("PatchStaticCall: patching from %#"Px" to '%s' %#"Px"\n", |
800 caller_frame->pc(), | 800 caller_frame->pc(), |
801 target_function.ToFullyQualifiedCString(), | 801 target_function.ToFullyQualifiedCString(), |
802 target_code.EntryPoint()); | 802 target_code.EntryPoint()); |
803 } | 803 } |
| 804 arguments.SetReturn(target_code); |
804 } | 805 } |
805 | 806 |
806 | 807 |
807 // Resolves and compiles the target function of an instance call, updates | 808 // Resolves and compiles the target function of an instance call, updates |
808 // function cache of the receiver's class and returns the compiled code or null. | 809 // function cache of the receiver's class and returns the compiled code or null. |
809 // Only the number of named arguments is checked, but not the actual names. | 810 // Only the number of named arguments is checked, but not the actual names. |
810 RawCode* ResolveCompileInstanceCallTarget(Isolate* isolate, | 811 RawCode* ResolveCompileInstanceCallTarget(Isolate* isolate, |
811 const Instance& receiver) { | 812 const Instance& receiver) { |
812 int num_arguments = -1; | 813 int num_arguments = -1; |
813 int num_named_arguments = -1; | 814 int num_named_arguments = -1; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
861 ASSERT(arguments.ArgCount() == | 862 ASSERT(arguments.ArgCount() == |
862 kResolveCompileInstanceFunctionRuntimeEntry.argument_count()); | 863 kResolveCompileInstanceFunctionRuntimeEntry.argument_count()); |
863 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); | 864 const Instance& receiver = Instance::CheckedHandle(arguments.ArgAt(0)); |
864 const Code& code = Code::Handle( | 865 const Code& code = Code::Handle( |
865 ResolveCompileInstanceCallTarget(isolate, receiver)); | 866 ResolveCompileInstanceCallTarget(isolate, receiver)); |
866 arguments.SetReturn(code); | 867 arguments.SetReturn(code); |
867 } | 868 } |
868 | 869 |
869 | 870 |
870 // Gets called from debug stub when code reaches a breakpoint. | 871 // Gets called from debug stub when code reaches a breakpoint. |
871 // Arg0: function object of the static function that was about to be called. | 872 DEFINE_RUNTIME_ENTRY(BreakpointStaticHandler, 0) { |
872 DEFINE_RUNTIME_ENTRY(BreakpointStaticHandler, 1) { | |
873 ASSERT(arguments.ArgCount() == | 873 ASSERT(arguments.ArgCount() == |
874 kBreakpointStaticHandlerRuntimeEntry.argument_count()); | 874 kBreakpointStaticHandlerRuntimeEntry.argument_count()); |
875 ASSERT(isolate->debugger() != NULL); | 875 ASSERT(isolate->debugger() != NULL); |
876 isolate->debugger()->SignalBpReached(); | 876 isolate->debugger()->SignalBpReached(); |
877 // Make sure the static function that is about to be called is | 877 // Make sure the static function that is about to be called is |
878 // compiled. The stub will jump to the entry point without any | 878 // compiled. The stub will jump to the entry point without any |
879 // further tests. | 879 // further tests. |
880 const Function& function = Function::CheckedHandle(arguments.ArgAt(0)); | 880 DartFrameIterator iterator; |
| 881 StackFrame* caller_frame = iterator.NextFrame(); |
| 882 ASSERT(caller_frame != NULL); |
| 883 const Code& code = Code::Handle(caller_frame->LookupDartCode()); |
| 884 const Function& function = |
| 885 Function::Handle(code.GetStaticCallTargetFunctionAt(caller_frame->pc())); |
| 886 |
881 if (!function.HasCode()) { | 887 if (!function.HasCode()) { |
882 const Error& error = Error::Handle(Compiler::CompileFunction(function)); | 888 const Error& error = Error::Handle(Compiler::CompileFunction(function)); |
883 if (!error.IsNull()) { | 889 if (!error.IsNull()) { |
884 Exceptions::PropagateError(error); | 890 Exceptions::PropagateError(error); |
885 } | 891 } |
886 } | 892 } |
| 893 arguments.SetReturn(Code::ZoneHandle(function.CurrentCode())); |
887 } | 894 } |
888 | 895 |
889 | 896 |
890 // Gets called from debug stub when code reaches a breakpoint at a return | 897 // Gets called from debug stub when code reaches a breakpoint at a return |
891 // in Dart code. | 898 // in Dart code. |
892 DEFINE_RUNTIME_ENTRY(BreakpointReturnHandler, 0) { | 899 DEFINE_RUNTIME_ENTRY(BreakpointReturnHandler, 0) { |
893 ASSERT(arguments.ArgCount() == | 900 ASSERT(arguments.ArgCount() == |
894 kBreakpointReturnHandlerRuntimeEntry.argument_count()); | 901 kBreakpointReturnHandlerRuntimeEntry.argument_count()); |
895 ASSERT(isolate->debugger() != NULL); | 902 ASSERT(isolate->debugger() != NULL); |
896 isolate->debugger()->SignalBpReached(); | 903 isolate->debugger()->SignalBpReached(); |
(...skipping 626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1523 PrintCaller("Not Optimizable"); | 1530 PrintCaller("Not Optimizable"); |
1524 } | 1531 } |
1525 // TODO(5442338): Abort as this should not happen. | 1532 // TODO(5442338): Abort as this should not happen. |
1526 function.set_usage_counter(kLowInvocationCount); | 1533 function.set_usage_counter(kLowInvocationCount); |
1527 } | 1534 } |
1528 } | 1535 } |
1529 | 1536 |
1530 | 1537 |
1531 // The caller must be a static call in a Dart frame, or an entry frame. | 1538 // The caller must be a static call in a Dart frame, or an entry frame. |
1532 // Patch static call to point to valid code's entry point. | 1539 // Patch static call to point to valid code's entry point. |
1533 DEFINE_RUNTIME_ENTRY(FixCallersTarget, 1) { | 1540 DEFINE_RUNTIME_ENTRY(FixCallersTarget, 0) { |
1534 ASSERT(arguments.ArgCount() == | 1541 ASSERT(arguments.ArgCount() == |
1535 kFixCallersTargetRuntimeEntry.argument_count()); | 1542 kFixCallersTargetRuntimeEntry.argument_count()); |
1536 const Function& function = Function::CheckedHandle(arguments.ArgAt(0)); | |
1537 ASSERT(!function.IsNull()); | |
1538 ASSERT(function.HasCode()); | |
1539 | 1543 |
1540 StackFrameIterator iterator(StackFrameIterator::kDontValidateFrames); | 1544 StackFrameIterator iterator(StackFrameIterator::kDontValidateFrames); |
1541 StackFrame* frame = iterator.NextFrame(); | 1545 StackFrame* frame = iterator.NextFrame(); |
1542 while (frame != NULL && (frame->IsStubFrame() || frame->IsExitFrame())) { | 1546 while (frame != NULL && (frame->IsStubFrame() || frame->IsExitFrame())) { |
1543 frame = iterator.NextFrame(); | 1547 frame = iterator.NextFrame(); |
1544 } | 1548 } |
1545 ASSERT(frame != NULL); | 1549 ASSERT(frame != NULL); |
1546 if (!frame->IsEntryFrame()) { | 1550 if (frame->IsEntryFrame()) { |
1547 ASSERT(frame->IsDartFrame()); | 1551 // Since function's current code is always unpatched, the entry frame always |
1548 uword target = CodePatcher::GetStaticCallTargetAt(frame->pc()); | 1552 // calls to unpatched code. |
1549 const Code& target_code = Code::Handle(function.CurrentCode()); | 1553 UNREACHABLE(); |
1550 const uword new_entry_point = target_code.EntryPoint(); | |
1551 ASSERT(target != new_entry_point); // Why patch otherwise. | |
1552 CodePatcher::PatchStaticCallAt(frame->pc(), new_entry_point); | |
1553 const Code& code = Code::Handle(frame->LookupDartCode()); | |
1554 code.SetStaticCallTargetCodeAt(frame->pc(), target_code); | |
1555 if (FLAG_trace_patching) { | |
1556 OS::Print("FixCallersTarget: patching from %#"Px" to '%s' %#"Px"\n", | |
1557 frame->pc(), | |
1558 Function::Handle(target_code.function()).ToFullyQualifiedCString(), | |
1559 new_entry_point); | |
1560 } | |
1561 } | 1554 } |
| 1555 ASSERT(frame->IsDartFrame()); |
| 1556 const Code& caller_code = Code::Handle(frame->LookupDartCode()); |
| 1557 const Function& target_function = Function::Handle( |
| 1558 caller_code.GetStaticCallTargetFunctionAt(frame->pc())); |
| 1559 const Code& target_code = Code::Handle(target_function.CurrentCode()); |
| 1560 CodePatcher::PatchStaticCallAt(frame->pc(), target_code.EntryPoint()); |
| 1561 caller_code.SetStaticCallTargetCodeAt(frame->pc(), target_code); |
| 1562 if (FLAG_trace_patching) { |
| 1563 OS::Print("FixCallersTarget: patching from %#"Px" to '%s' %#"Px"\n", |
| 1564 frame->pc(), |
| 1565 Function::Handle(target_code.function()).ToFullyQualifiedCString(), |
| 1566 target_code.EntryPoint()); |
| 1567 } |
| 1568 arguments.SetReturn(target_code); |
1562 } | 1569 } |
1563 | 1570 |
1564 | 1571 |
1565 const char* DeoptReasonToText(intptr_t deopt_id) { | 1572 const char* DeoptReasonToText(intptr_t deopt_id) { |
1566 switch (deopt_id) { | 1573 switch (deopt_id) { |
1567 #define DEOPT_REASON_ID_TO_TEXT(name) case kDeopt##name: return #name; | 1574 #define DEOPT_REASON_ID_TO_TEXT(name) case kDeopt##name: return #name; |
1568 DEOPT_REASONS(DEOPT_REASON_ID_TO_TEXT) | 1575 DEOPT_REASONS(DEOPT_REASON_ID_TO_TEXT) |
1569 #undef DEOPT_REASON_ID_TO_TEXT | 1576 #undef DEOPT_REASON_ID_TO_TEXT |
1570 default: | 1577 default: |
1571 UNREACHABLE(); | 1578 UNREACHABLE(); |
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1901 intptr_t line, column; | 1908 intptr_t line, column; |
1902 script.GetTokenLocation(token_pos, &line, &column); | 1909 script.GetTokenLocation(token_pos, &line, &column); |
1903 String& line_string = String::Handle(script.GetLine(line)); | 1910 String& line_string = String::Handle(script.GetLine(line)); |
1904 OS::Print(" Function: %s\n", top_function.ToFullyQualifiedCString()); | 1911 OS::Print(" Function: %s\n", top_function.ToFullyQualifiedCString()); |
1905 OS::Print(" Line %"Pd": '%s'\n", line, line_string.ToCString()); | 1912 OS::Print(" Line %"Pd": '%s'\n", line, line_string.ToCString()); |
1906 } | 1913 } |
1907 } | 1914 } |
1908 | 1915 |
1909 | 1916 |
1910 } // namespace dart | 1917 } // namespace dart |
OLD | NEW |