| 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 730 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 741 | 741 |
| 742 | 742 |
| 743 DEFINE_RUNTIME_ENTRY(ReThrow, 2) { | 743 DEFINE_RUNTIME_ENTRY(ReThrow, 2) { |
| 744 ASSERT(arguments.Count() == kReThrowRuntimeEntry.argument_count()); | 744 ASSERT(arguments.Count() == kReThrowRuntimeEntry.argument_count()); |
| 745 const Instance& exception = Instance::CheckedHandle(arguments.At(0)); | 745 const Instance& exception = Instance::CheckedHandle(arguments.At(0)); |
| 746 const Instance& stacktrace = Instance::CheckedHandle(arguments.At(1)); | 746 const Instance& stacktrace = Instance::CheckedHandle(arguments.At(1)); |
| 747 Exceptions::ReThrow(exception, stacktrace); | 747 Exceptions::ReThrow(exception, stacktrace); |
| 748 } | 748 } |
| 749 | 749 |
| 750 | 750 |
| 751 static bool UpdateResolvedStaticCall(const Code& code, |
| 752 intptr_t offset, |
| 753 const Code& target_code) { |
| 754 // PC offsets are mapped to the corresponding code object in the |
| 755 // resolved_static_calls array. The array grows as static calls are being |
| 756 // resolved. |
| 757 const int kOffset = 0; |
| 758 const int kCode = 1; |
| 759 const int kEntrySize = 2; |
| 760 |
| 761 GrowableObjectArray& resolved_static_calls = |
| 762 GrowableObjectArray::Handle(code.resolved_static_calls()); |
| 763 intptr_t index = -1; |
| 764 if (resolved_static_calls.IsNull()) { |
| 765 resolved_static_calls = GrowableObjectArray::New(2, Heap::kOld); |
| 766 code.set_resolved_static_calls(resolved_static_calls); |
| 767 } else { |
| 768 // Search for the offset in the resolved static calls. |
| 769 const intptr_t len = resolved_static_calls.Length(); |
| 770 Object& off = Object::Handle(); |
| 771 for (intptr_t i = 0; i < len; i += kEntrySize) { |
| 772 off = resolved_static_calls.At(i + kOffset); |
| 773 if (Smi::Cast(off).Value() == offset) { |
| 774 index = i; |
| 775 break; |
| 776 } |
| 777 } |
| 778 } |
| 779 if (index == -1) { |
| 780 // The static call with this offset is not yet present: Add it. |
| 781 resolved_static_calls.Add(Smi::Handle(Smi::New(offset))); |
| 782 resolved_static_calls.Add(target_code); |
| 783 } else { |
| 784 // Overwrite the currently recorded target. |
| 785 resolved_static_calls.SetAt(index + kCode, target_code); |
| 786 } |
| 787 return index != -1; |
| 788 } |
| 789 |
| 790 |
| 751 DEFINE_RUNTIME_ENTRY(PatchStaticCall, 0) { | 791 DEFINE_RUNTIME_ENTRY(PatchStaticCall, 0) { |
| 752 // This function is called after successful resolving and compilation of | 792 // This function is called after successful resolving and compilation of |
| 753 // the target method. | 793 // the target method. |
| 754 ASSERT(arguments.Count() == kPatchStaticCallRuntimeEntry.argument_count()); | 794 ASSERT(arguments.Count() == kPatchStaticCallRuntimeEntry.argument_count()); |
| 755 DartFrameIterator iterator; | 795 DartFrameIterator iterator; |
| 756 StackFrame* caller_frame = iterator.NextFrame(); | 796 StackFrame* caller_frame = iterator.NextFrame(); |
| 757 ASSERT(caller_frame != NULL); | 797 ASSERT(caller_frame != NULL); |
| 758 uword target = 0; | 798 uword target = 0; |
| 759 Function& target_function = Function::Handle(); | 799 Function& target_function = Function::Handle(); |
| 760 CodePatcher::GetStaticCallAt(caller_frame->pc(), &target_function, &target); | 800 CodePatcher::GetStaticCallAt(caller_frame->pc(), &target_function, &target); |
| 761 ASSERT(target_function.HasCode()); | 801 ASSERT(target_function.HasCode()); |
| 762 uword new_target = Code::Handle(target_function.CurrentCode()).EntryPoint(); | 802 const Code& target_code = Code::Handle(target_function.CurrentCode()); |
| 803 uword new_target = target_code.EntryPoint(); |
| 763 // Verify that we are not patching repeatedly. | 804 // Verify that we are not patching repeatedly. |
| 764 ASSERT(target != new_target); | 805 ASSERT(target != new_target); |
| 765 CodePatcher::PatchStaticCallAt(caller_frame->pc(), new_target); | 806 CodePatcher::PatchStaticCallAt(caller_frame->pc(), new_target); |
| 807 const Code& code = Code::Handle(caller_frame->LookupDartCode()); |
| 808 bool found = UpdateResolvedStaticCall(code, |
| 809 caller_frame->pc() - code.EntryPoint(), |
| 810 target_code); |
| 811 ASSERT(!found); |
| 766 if (FLAG_trace_patching) { | 812 if (FLAG_trace_patching) { |
| 767 OS::Print("PatchStaticCall: patching from %#"Px" to '%s' %#"Px"\n", | 813 OS::Print("PatchStaticCall: patching from %#"Px" to '%s' %#"Px"\n", |
| 768 caller_frame->pc(), | 814 caller_frame->pc(), |
| 769 target_function.ToFullyQualifiedCString(), | 815 target_function.ToFullyQualifiedCString(), |
| 770 new_target); | 816 new_target); |
| 771 } | 817 } |
| 772 } | 818 } |
| 773 | 819 |
| 774 | 820 |
| 775 // Resolves and compiles the target function of an instance call, updates | 821 // Resolves and compiles the target function of an instance call, updates |
| (...skipping 650 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1426 while (frame != NULL && (frame->IsStubFrame() || frame->IsExitFrame())) { | 1472 while (frame != NULL && (frame->IsStubFrame() || frame->IsExitFrame())) { |
| 1427 frame = iterator.NextFrame(); | 1473 frame = iterator.NextFrame(); |
| 1428 } | 1474 } |
| 1429 ASSERT(frame != NULL); | 1475 ASSERT(frame != NULL); |
| 1430 if (!frame->IsEntryFrame()) { | 1476 if (!frame->IsEntryFrame()) { |
| 1431 ASSERT(frame->IsDartFrame()); | 1477 ASSERT(frame->IsDartFrame()); |
| 1432 uword target = 0; | 1478 uword target = 0; |
| 1433 Function& target_function = Function::Handle(); | 1479 Function& target_function = Function::Handle(); |
| 1434 CodePatcher::GetStaticCallAt(frame->pc(), &target_function, &target); | 1480 CodePatcher::GetStaticCallAt(frame->pc(), &target_function, &target); |
| 1435 ASSERT(target_function.HasCode()); | 1481 ASSERT(target_function.HasCode()); |
| 1436 const uword new_entry_point = | 1482 ASSERT(target_function.raw() == function.raw()); |
| 1437 Code::Handle(function.CurrentCode()).EntryPoint(); | 1483 const Code& target_code = Code::Handle(function.CurrentCode()); |
| 1484 const uword new_entry_point = target_code.EntryPoint(); |
| 1438 ASSERT(target != new_entry_point); // Why patch otherwise. | 1485 ASSERT(target != new_entry_point); // Why patch otherwise. |
| 1439 CodePatcher::PatchStaticCallAt(frame->pc(), new_entry_point); | 1486 CodePatcher::PatchStaticCallAt(frame->pc(), new_entry_point); |
| 1487 const Code& code = Code::Handle(frame->LookupDartCode()); |
| 1488 bool found = UpdateResolvedStaticCall(code, |
| 1489 frame->pc() - code.EntryPoint(), |
| 1490 target_code); |
| 1491 ASSERT(found); |
| 1440 if (FLAG_trace_patching) { | 1492 if (FLAG_trace_patching) { |
| 1441 OS::Print("FixCallersTarget: patching from %#"Px" to '%s' %#"Px"\n", | 1493 OS::Print("FixCallersTarget: patching from %#"Px" to '%s' %#"Px"\n", |
| 1442 frame->pc(), | 1494 frame->pc(), |
| 1443 target_function.ToFullyQualifiedCString(), | 1495 target_function.ToFullyQualifiedCString(), |
| 1444 new_entry_point); | 1496 new_entry_point); |
| 1445 } | 1497 } |
| 1446 } | 1498 } |
| 1447 } | 1499 } |
| 1448 | 1500 |
| 1449 | 1501 |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1752 intptr_t line, column; | 1804 intptr_t line, column; |
| 1753 script.GetTokenLocation(token_pos, &line, &column); | 1805 script.GetTokenLocation(token_pos, &line, &column); |
| 1754 String& line_string = String::Handle(script.GetLine(line)); | 1806 String& line_string = String::Handle(script.GetLine(line)); |
| 1755 OS::Print(" Function: %s\n", top_function.ToFullyQualifiedCString()); | 1807 OS::Print(" Function: %s\n", top_function.ToFullyQualifiedCString()); |
| 1756 OS::Print(" Line %"Pd": '%s'\n", line, line_string.ToCString()); | 1808 OS::Print(" Line %"Pd": '%s'\n", line, line_string.ToCString()); |
| 1757 } | 1809 } |
| 1758 } | 1810 } |
| 1759 | 1811 |
| 1760 | 1812 |
| 1761 } // namespace dart | 1813 } // namespace dart |
| OLD | NEW |