| 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 752 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 763 | 763 |
| 764 | 764 |
| 765 DEFINE_RUNTIME_ENTRY(ReThrow, 2) { | 765 DEFINE_RUNTIME_ENTRY(ReThrow, 2) { |
| 766 ASSERT(arguments.ArgCount() == kReThrowRuntimeEntry.argument_count()); | 766 ASSERT(arguments.ArgCount() == kReThrowRuntimeEntry.argument_count()); |
| 767 const Instance& exception = Instance::CheckedHandle(arguments.ArgAt(0)); | 767 const Instance& exception = Instance::CheckedHandle(arguments.ArgAt(0)); |
| 768 const Instance& stacktrace = Instance::CheckedHandle(arguments.ArgAt(1)); | 768 const Instance& stacktrace = Instance::CheckedHandle(arguments.ArgAt(1)); |
| 769 Exceptions::ReThrow(exception, stacktrace); | 769 Exceptions::ReThrow(exception, stacktrace); |
| 770 } | 770 } |
| 771 | 771 |
| 772 | 772 |
| 773 // Patches static call with the target's entry point. Compiles target if |
| 774 // necessary. |
| 773 DEFINE_RUNTIME_ENTRY(PatchStaticCall, 0) { | 775 DEFINE_RUNTIME_ENTRY(PatchStaticCall, 0) { |
| 774 // This function is called after successful resolving and compilation of | |
| 775 // the target method. | |
| 776 ASSERT(arguments.ArgCount() == kPatchStaticCallRuntimeEntry.argument_count()); | 776 ASSERT(arguments.ArgCount() == kPatchStaticCallRuntimeEntry.argument_count()); |
| 777 DartFrameIterator iterator; | 777 DartFrameIterator iterator; |
| 778 StackFrame* caller_frame = iterator.NextFrame(); | 778 StackFrame* caller_frame = iterator.NextFrame(); |
| 779 ASSERT(caller_frame != NULL); | 779 ASSERT(caller_frame != NULL); |
| 780 uword target = 0; | 780 const Code& caller_code = Code::Handle(caller_frame->LookupDartCode()); |
| 781 Function& target_function = Function::Handle(); | 781 ASSERT(!caller_code.IsNull()); |
| 782 CodePatcher::GetStaticCallAt(caller_frame->pc(), &target_function, &target); | 782 const Function& target_function = Function::Handle( |
| 783 ASSERT(target_function.HasCode()); | 783 caller_code.GetStaticCallTargetFunctionAt(caller_frame->pc())); |
| 784 if (!target_function.HasCode()) { |
| 785 const Error& error = |
| 786 Error::Handle(Compiler::CompileFunction(target_function)); |
| 787 if (!error.IsNull()) { |
| 788 Exceptions::PropagateError(error); |
| 789 } |
| 790 } |
| 784 const Code& target_code = Code::Handle(target_function.CurrentCode()); | 791 const Code& target_code = Code::Handle(target_function.CurrentCode()); |
| 785 uword new_target = target_code.EntryPoint(); | 792 // Before patching verify that we are not repeatedly patching to the same |
| 786 // Verify that we are not patching repeatedly. | 793 // target. |
| 787 ASSERT(target != new_target); | 794 ASSERT(target_code.EntryPoint() != |
| 788 CodePatcher::PatchStaticCallAt(caller_frame->pc(), new_target); | 795 CodePatcher::GetStaticCallTargetAt(caller_frame->pc())); |
| 789 const Code& code = Code::Handle(caller_frame->LookupDartCode()); | 796 CodePatcher::PatchStaticCallAt(caller_frame->pc(), target_code.EntryPoint()); |
| 790 code.SetStaticCallTargetCodeAt(caller_frame->pc(), target_code); | 797 caller_code.SetStaticCallTargetCodeAt(caller_frame->pc(), target_code); |
| 791 if (FLAG_trace_patching) { | 798 if (FLAG_trace_patching) { |
| 792 OS::Print("PatchStaticCall: patching from %#"Px" to '%s' %#"Px"\n", | 799 OS::Print("PatchStaticCall: patching from %#"Px" to '%s' %#"Px"\n", |
| 793 caller_frame->pc(), | 800 caller_frame->pc(), |
| 794 target_function.ToFullyQualifiedCString(), | 801 target_function.ToFullyQualifiedCString(), |
| 795 new_target); | 802 target_code.EntryPoint()); |
| 796 } | 803 } |
| 797 } | 804 } |
| 798 | 805 |
| 799 | 806 |
| 800 // Resolves and compiles the target function of an instance call, updates | 807 // Resolves and compiles the target function of an instance call, updates |
| 801 // function cache of the receiver's class and returns the compiled code or null. | 808 // function cache of the receiver's class and returns the compiled code or null. |
| 802 // Only the number of named arguments is checked, but not the actual names. | 809 // Only the number of named arguments is checked, but not the actual names. |
| 803 RawCode* ResolveCompileInstanceCallTarget(Isolate* isolate, | 810 RawCode* ResolveCompileInstanceCallTarget(Isolate* isolate, |
| 804 const Instance& receiver) { | 811 const Instance& receiver) { |
| 805 int num_arguments = -1; | 812 int num_arguments = -1; |
| (...skipping 709 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1515 if (FLAG_trace_failed_optimization_attempts) { | 1522 if (FLAG_trace_failed_optimization_attempts) { |
| 1516 PrintCaller("Not Optimizable"); | 1523 PrintCaller("Not Optimizable"); |
| 1517 } | 1524 } |
| 1518 // TODO(5442338): Abort as this should not happen. | 1525 // TODO(5442338): Abort as this should not happen. |
| 1519 function.set_usage_counter(kLowInvocationCount); | 1526 function.set_usage_counter(kLowInvocationCount); |
| 1520 } | 1527 } |
| 1521 } | 1528 } |
| 1522 | 1529 |
| 1523 | 1530 |
| 1524 // The caller must be a static call in a Dart frame, or an entry frame. | 1531 // The caller must be a static call in a Dart frame, or an entry frame. |
| 1525 // Patch static call to point to 'new_entry_point'. | 1532 // Patch static call to point to valid code's entry point. |
| 1526 DEFINE_RUNTIME_ENTRY(FixCallersTarget, 1) { | 1533 DEFINE_RUNTIME_ENTRY(FixCallersTarget, 1) { |
| 1527 ASSERT(arguments.ArgCount() == | 1534 ASSERT(arguments.ArgCount() == |
| 1528 kFixCallersTargetRuntimeEntry.argument_count()); | 1535 kFixCallersTargetRuntimeEntry.argument_count()); |
| 1529 const Function& function = Function::CheckedHandle(arguments.ArgAt(0)); | 1536 const Function& function = Function::CheckedHandle(arguments.ArgAt(0)); |
| 1530 ASSERT(!function.IsNull()); | 1537 ASSERT(!function.IsNull()); |
| 1531 ASSERT(function.HasCode()); | 1538 ASSERT(function.HasCode()); |
| 1532 | 1539 |
| 1533 StackFrameIterator iterator(StackFrameIterator::kDontValidateFrames); | 1540 StackFrameIterator iterator(StackFrameIterator::kDontValidateFrames); |
| 1534 StackFrame* frame = iterator.NextFrame(); | 1541 StackFrame* frame = iterator.NextFrame(); |
| 1535 while (frame != NULL && (frame->IsStubFrame() || frame->IsExitFrame())) { | 1542 while (frame != NULL && (frame->IsStubFrame() || frame->IsExitFrame())) { |
| 1536 frame = iterator.NextFrame(); | 1543 frame = iterator.NextFrame(); |
| 1537 } | 1544 } |
| 1538 ASSERT(frame != NULL); | 1545 ASSERT(frame != NULL); |
| 1539 if (!frame->IsEntryFrame()) { | 1546 if (!frame->IsEntryFrame()) { |
| 1540 ASSERT(frame->IsDartFrame()); | 1547 ASSERT(frame->IsDartFrame()); |
| 1541 uword target = 0; | 1548 uword target = CodePatcher::GetStaticCallTargetAt(frame->pc()); |
| 1542 Function& target_function = Function::Handle(); | |
| 1543 CodePatcher::GetStaticCallAt(frame->pc(), &target_function, &target); | |
| 1544 ASSERT(target_function.HasCode()); | |
| 1545 ASSERT(target_function.raw() == function.raw()); | |
| 1546 const Code& target_code = Code::Handle(function.CurrentCode()); | 1549 const Code& target_code = Code::Handle(function.CurrentCode()); |
| 1547 const uword new_entry_point = target_code.EntryPoint(); | 1550 const uword new_entry_point = target_code.EntryPoint(); |
| 1548 ASSERT(target != new_entry_point); // Why patch otherwise. | 1551 ASSERT(target != new_entry_point); // Why patch otherwise. |
| 1549 CodePatcher::PatchStaticCallAt(frame->pc(), new_entry_point); | 1552 CodePatcher::PatchStaticCallAt(frame->pc(), new_entry_point); |
| 1550 const Code& code = Code::Handle(frame->LookupDartCode()); | 1553 const Code& code = Code::Handle(frame->LookupDartCode()); |
| 1551 code.SetStaticCallTargetCodeAt(frame->pc(), target_code); | 1554 code.SetStaticCallTargetCodeAt(frame->pc(), target_code); |
| 1552 if (FLAG_trace_patching) { | 1555 if (FLAG_trace_patching) { |
| 1553 OS::Print("FixCallersTarget: patching from %#"Px" to '%s' %#"Px"\n", | 1556 OS::Print("FixCallersTarget: patching from %#"Px" to '%s' %#"Px"\n", |
| 1554 frame->pc(), | 1557 frame->pc(), |
| 1555 target_function.ToFullyQualifiedCString(), | 1558 Function::Handle(target_code.function()).ToFullyQualifiedCString(), |
| 1556 new_entry_point); | 1559 new_entry_point); |
| 1557 } | 1560 } |
| 1558 } | 1561 } |
| 1559 } | 1562 } |
| 1560 | 1563 |
| 1561 | 1564 |
| 1562 const char* DeoptReasonToText(intptr_t deopt_id) { | 1565 const char* DeoptReasonToText(intptr_t deopt_id) { |
| 1563 switch (deopt_id) { | 1566 switch (deopt_id) { |
| 1564 #define DEOPT_REASON_ID_TO_TEXT(name) case kDeopt##name: return #name; | 1567 #define DEOPT_REASON_ID_TO_TEXT(name) case kDeopt##name: return #name; |
| 1565 DEOPT_REASONS(DEOPT_REASON_ID_TO_TEXT) | 1568 DEOPT_REASONS(DEOPT_REASON_ID_TO_TEXT) |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1898 intptr_t line, column; | 1901 intptr_t line, column; |
| 1899 script.GetTokenLocation(token_pos, &line, &column); | 1902 script.GetTokenLocation(token_pos, &line, &column); |
| 1900 String& line_string = String::Handle(script.GetLine(line)); | 1903 String& line_string = String::Handle(script.GetLine(line)); |
| 1901 OS::Print(" Function: %s\n", top_function.ToFullyQualifiedCString()); | 1904 OS::Print(" Function: %s\n", top_function.ToFullyQualifiedCString()); |
| 1902 OS::Print(" Line %"Pd": '%s'\n", line, line_string.ToCString()); | 1905 OS::Print(" Line %"Pd": '%s'\n", line, line_string.ToCString()); |
| 1903 } | 1906 } |
| 1904 } | 1907 } |
| 1905 | 1908 |
| 1906 | 1909 |
| 1907 } // namespace dart | 1910 } // namespace dart |
| OLD | NEW |