| 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 |