| 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 static bool UpdateResolvedStaticCall(const Code& code, | |
| 774 intptr_t offset, | |
| 775 const Code& target_code) { | |
| 776 // PC offsets are mapped to the corresponding code object in the | |
| 777 // resolved_static_calls array. The array grows as static calls are being | |
| 778 // resolved. | |
| 779 const int kOffset = 0; | |
| 780 const int kCode = 1; | |
| 781 const int kEntrySize = 2; | |
| 782 | |
| 783 GrowableObjectArray& resolved_static_calls = | |
| 784 GrowableObjectArray::Handle(code.resolved_static_calls()); | |
| 785 intptr_t index = -1; | |
| 786 if (resolved_static_calls.IsNull()) { | |
| 787 resolved_static_calls = GrowableObjectArray::New(2, Heap::kOld); | |
| 788 code.set_resolved_static_calls(resolved_static_calls); | |
| 789 } else { | |
| 790 // Search for the offset in the resolved static calls. | |
| 791 const intptr_t len = resolved_static_calls.Length(); | |
| 792 Object& off = Object::Handle(); | |
| 793 for (intptr_t i = 0; i < len; i += kEntrySize) { | |
| 794 off = resolved_static_calls.At(i + kOffset); | |
| 795 if (Smi::Cast(off).Value() == offset) { | |
| 796 index = i; | |
| 797 break; | |
| 798 } | |
| 799 } | |
| 800 } | |
| 801 if (index == -1) { | |
| 802 // The static call with this offset is not yet present: Add it. | |
| 803 resolved_static_calls.Add(Smi::Handle(Smi::New(offset))); | |
| 804 resolved_static_calls.Add(target_code); | |
| 805 } else { | |
| 806 // Overwrite the currently recorded target. | |
| 807 resolved_static_calls.SetAt(index + kCode, target_code); | |
| 808 } | |
| 809 return index != -1; | |
| 810 } | |
| 811 | |
| 812 | |
| 813 DEFINE_RUNTIME_ENTRY(PatchStaticCall, 0) { | 773 DEFINE_RUNTIME_ENTRY(PatchStaticCall, 0) { |
| 814 // This function is called after successful resolving and compilation of | 774 // This function is called after successful resolving and compilation of |
| 815 // the target method. | 775 // the target method. |
| 816 ASSERT(arguments.ArgCount() == kPatchStaticCallRuntimeEntry.argument_count()); | 776 ASSERT(arguments.ArgCount() == kPatchStaticCallRuntimeEntry.argument_count()); |
| 817 DartFrameIterator iterator; | 777 DartFrameIterator iterator; |
| 818 StackFrame* caller_frame = iterator.NextFrame(); | 778 StackFrame* caller_frame = iterator.NextFrame(); |
| 819 ASSERT(caller_frame != NULL); | 779 ASSERT(caller_frame != NULL); |
| 820 uword target = 0; | 780 uword target = 0; |
| 821 Function& target_function = Function::Handle(); | 781 Function& target_function = Function::Handle(); |
| 822 CodePatcher::GetStaticCallAt(caller_frame->pc(), &target_function, &target); | 782 CodePatcher::GetStaticCallAt(caller_frame->pc(), &target_function, &target); |
| 823 ASSERT(target_function.HasCode()); | 783 ASSERT(target_function.HasCode()); |
| 824 const Code& target_code = Code::Handle(target_function.CurrentCode()); | 784 const Code& target_code = Code::Handle(target_function.CurrentCode()); |
| 825 uword new_target = target_code.EntryPoint(); | 785 uword new_target = target_code.EntryPoint(); |
| 826 // Verify that we are not patching repeatedly. | 786 // Verify that we are not patching repeatedly. |
| 827 ASSERT(target != new_target); | 787 ASSERT(target != new_target); |
| 828 CodePatcher::PatchStaticCallAt(caller_frame->pc(), new_target); | 788 CodePatcher::PatchStaticCallAt(caller_frame->pc(), new_target); |
| 829 const Code& code = Code::Handle(caller_frame->LookupDartCode()); | 789 const Code& code = Code::Handle(caller_frame->LookupDartCode()); |
| 830 bool found = UpdateResolvedStaticCall(code, | 790 code.SetStaticCallTargetCodeAt(caller_frame->pc(), target_code); |
| 831 caller_frame->pc() - code.EntryPoint(), | |
| 832 target_code); | |
| 833 ASSERT(!found); | |
| 834 if (FLAG_trace_patching) { | 791 if (FLAG_trace_patching) { |
| 835 OS::Print("PatchStaticCall: patching from %#"Px" to '%s' %#"Px"\n", | 792 OS::Print("PatchStaticCall: patching from %#"Px" to '%s' %#"Px"\n", |
| 836 caller_frame->pc(), | 793 caller_frame->pc(), |
| 837 target_function.ToFullyQualifiedCString(), | 794 target_function.ToFullyQualifiedCString(), |
| 838 new_target); | 795 new_target); |
| 839 } | 796 } |
| 840 } | 797 } |
| 841 | 798 |
| 842 | 799 |
| 843 // Resolves and compiles the target function of an instance call, updates | 800 // Resolves and compiles the target function of an instance call, updates |
| (...skipping 740 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1584 uword target = 0; | 1541 uword target = 0; |
| 1585 Function& target_function = Function::Handle(); | 1542 Function& target_function = Function::Handle(); |
| 1586 CodePatcher::GetStaticCallAt(frame->pc(), &target_function, &target); | 1543 CodePatcher::GetStaticCallAt(frame->pc(), &target_function, &target); |
| 1587 ASSERT(target_function.HasCode()); | 1544 ASSERT(target_function.HasCode()); |
| 1588 ASSERT(target_function.raw() == function.raw()); | 1545 ASSERT(target_function.raw() == function.raw()); |
| 1589 const Code& target_code = Code::Handle(function.CurrentCode()); | 1546 const Code& target_code = Code::Handle(function.CurrentCode()); |
| 1590 const uword new_entry_point = target_code.EntryPoint(); | 1547 const uword new_entry_point = target_code.EntryPoint(); |
| 1591 ASSERT(target != new_entry_point); // Why patch otherwise. | 1548 ASSERT(target != new_entry_point); // Why patch otherwise. |
| 1592 CodePatcher::PatchStaticCallAt(frame->pc(), new_entry_point); | 1549 CodePatcher::PatchStaticCallAt(frame->pc(), new_entry_point); |
| 1593 const Code& code = Code::Handle(frame->LookupDartCode()); | 1550 const Code& code = Code::Handle(frame->LookupDartCode()); |
| 1594 bool found = UpdateResolvedStaticCall(code, | 1551 code.SetStaticCallTargetCodeAt(frame->pc(), target_code); |
| 1595 frame->pc() - code.EntryPoint(), | |
| 1596 target_code); | |
| 1597 ASSERT(found); | |
| 1598 if (FLAG_trace_patching) { | 1552 if (FLAG_trace_patching) { |
| 1599 OS::Print("FixCallersTarget: patching from %#"Px" to '%s' %#"Px"\n", | 1553 OS::Print("FixCallersTarget: patching from %#"Px" to '%s' %#"Px"\n", |
| 1600 frame->pc(), | 1554 frame->pc(), |
| 1601 target_function.ToFullyQualifiedCString(), | 1555 target_function.ToFullyQualifiedCString(), |
| 1602 new_entry_point); | 1556 new_entry_point); |
| 1603 } | 1557 } |
| 1604 } | 1558 } |
| 1605 } | 1559 } |
| 1606 | 1560 |
| 1607 | 1561 |
| (...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1944 intptr_t line, column; | 1898 intptr_t line, column; |
| 1945 script.GetTokenLocation(token_pos, &line, &column); | 1899 script.GetTokenLocation(token_pos, &line, &column); |
| 1946 String& line_string = String::Handle(script.GetLine(line)); | 1900 String& line_string = String::Handle(script.GetLine(line)); |
| 1947 OS::Print(" Function: %s\n", top_function.ToFullyQualifiedCString()); | 1901 OS::Print(" Function: %s\n", top_function.ToFullyQualifiedCString()); |
| 1948 OS::Print(" Line %"Pd": '%s'\n", line, line_string.ToCString()); | 1902 OS::Print(" Line %"Pd": '%s'\n", line, line_string.ToCString()); |
| 1949 } | 1903 } |
| 1950 } | 1904 } |
| 1951 | 1905 |
| 1952 | 1906 |
| 1953 } // namespace dart | 1907 } // namespace dart |
| OLD | NEW |