Chromium Code Reviews| 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 bool UpdateResolvedStaticCall(const Code& code, | |
| 752 intptr_t offset, | |
| 753 const Code& target_code) { | |
| 754 GrowableObjectArray& resolved_static_calls = | |
| 755 GrowableObjectArray::Handle(code.resolved_static_calls()); | |
| 756 intptr_t index = -1; | |
| 757 if (resolved_static_calls.IsNull()) { | |
| 758 resolved_static_calls = GrowableObjectArray::New(2, Heap::kOld); | |
| 759 code.set_resolved_static_calls(resolved_static_calls); | |
| 760 } else { | |
| 761 // Search for the offset in the resolved static calls. | |
| 762 intptr_t len = resolved_static_calls.Length(); | |
|
srdjan
2012/10/25 20:00:48
const intptr_t len
Ivan Posva
2012/10/25 23:45:41
Done.
| |
| 763 Object& off = Object::Handle(); | |
| 764 for (intptr_t i = 0; i < len; i += 2) { | |
|
srdjan
2012/10/25 20:00:48
Maybe it would be good to have the length, entries
Ivan Posva
2012/10/25 23:45:41
Done.
| |
| 765 off = resolved_static_calls.At(i); | |
| 766 if (Smi::Cast(off).Value() == offset) { | |
| 767 index = i; | |
| 768 break; | |
| 769 } | |
| 770 } | |
| 771 } | |
| 772 if (index == -1) { | |
| 773 // The static call with this offset is not yet present: Add it. | |
| 774 resolved_static_calls.Add(Smi::Handle(Smi::New(offset))); | |
| 775 resolved_static_calls.Add(target_code); | |
| 776 } else { | |
| 777 // Overwrite the currently recorded target. | |
| 778 resolved_static_calls.SetAt(index + 1, target_code); | |
|
srdjan
2012/10/25 20:00:48
ditto
Ivan Posva
2012/10/25 23:45:41
Done.
| |
| 779 } | |
| 780 return index != -1; | |
| 781 } | |
| 782 | |
| 783 | |
| 751 DEFINE_RUNTIME_ENTRY(PatchStaticCall, 0) { | 784 DEFINE_RUNTIME_ENTRY(PatchStaticCall, 0) { |
| 752 // This function is called after successful resolving and compilation of | 785 // This function is called after successful resolving and compilation of |
| 753 // the target method. | 786 // the target method. |
| 754 ASSERT(arguments.Count() == kPatchStaticCallRuntimeEntry.argument_count()); | 787 ASSERT(arguments.Count() == kPatchStaticCallRuntimeEntry.argument_count()); |
| 755 DartFrameIterator iterator; | 788 DartFrameIterator iterator; |
| 756 StackFrame* caller_frame = iterator.NextFrame(); | 789 StackFrame* caller_frame = iterator.NextFrame(); |
| 757 ASSERT(caller_frame != NULL); | 790 ASSERT(caller_frame != NULL); |
| 758 uword target = 0; | 791 uword target = 0; |
| 759 Function& target_function = Function::Handle(); | 792 Function& target_function = Function::Handle(); |
| 760 CodePatcher::GetStaticCallAt(caller_frame->pc(), &target_function, &target); | 793 CodePatcher::GetStaticCallAt(caller_frame->pc(), &target_function, &target); |
| 761 ASSERT(target_function.HasCode()); | 794 ASSERT(target_function.HasCode()); |
| 762 uword new_target = Code::Handle(target_function.CurrentCode()).EntryPoint(); | 795 Code& target_code = Code::Handle(target_function.CurrentCode()); |
|
srdjan
2012/10/25 20:00:48
const Code
Ivan Posva
2012/10/25 23:45:41
Done.
| |
| 796 uword new_target = target_code.EntryPoint(); | |
| 763 // Verify that we are not patching repeatedly. | 797 // Verify that we are not patching repeatedly. |
| 764 ASSERT(target != new_target); | 798 ASSERT(target != new_target); |
| 765 CodePatcher::PatchStaticCallAt(caller_frame->pc(), new_target); | 799 CodePatcher::PatchStaticCallAt(caller_frame->pc(), new_target); |
| 800 Code& code = Code::Handle(caller_frame->LookupDartCode()); | |
|
srdjan
2012/10/25 20:00:48
ditto
Ivan Posva
2012/10/25 23:45:41
Done.
| |
| 801 UpdateResolvedStaticCall(code, | |
| 802 caller_frame->pc() - code.EntryPoint(), | |
| 803 target_code); | |
|
siva
2012/10/25 22:29:52
bool found = Update....;
ASSERT(!found);
Ivan Posva
2012/10/25 23:45:41
Done.
| |
| 766 if (FLAG_trace_patching) { | 804 if (FLAG_trace_patching) { |
| 767 OS::Print("PatchStaticCall: patching from %#"Px" to '%s' %#"Px"\n", | 805 OS::Print("PatchStaticCall: patching from %#"Px" to '%s' %#"Px"\n", |
| 768 caller_frame->pc(), | 806 caller_frame->pc(), |
| 769 target_function.ToFullyQualifiedCString(), | 807 target_function.ToFullyQualifiedCString(), |
| 770 new_target); | 808 new_target); |
| 771 } | 809 } |
| 772 } | 810 } |
| 773 | 811 |
| 774 | 812 |
| 775 // Resolves and compiles the target function of an instance call, updates | 813 // 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())) { | 1464 while (frame != NULL && (frame->IsStubFrame() || frame->IsExitFrame())) { |
| 1427 frame = iterator.NextFrame(); | 1465 frame = iterator.NextFrame(); |
| 1428 } | 1466 } |
| 1429 ASSERT(frame != NULL); | 1467 ASSERT(frame != NULL); |
| 1430 if (!frame->IsEntryFrame()) { | 1468 if (!frame->IsEntryFrame()) { |
| 1431 ASSERT(frame->IsDartFrame()); | 1469 ASSERT(frame->IsDartFrame()); |
| 1432 uword target = 0; | 1470 uword target = 0; |
| 1433 Function& target_function = Function::Handle(); | 1471 Function& target_function = Function::Handle(); |
| 1434 CodePatcher::GetStaticCallAt(frame->pc(), &target_function, &target); | 1472 CodePatcher::GetStaticCallAt(frame->pc(), &target_function, &target); |
| 1435 ASSERT(target_function.HasCode()); | 1473 ASSERT(target_function.HasCode()); |
| 1436 const uword new_entry_point = | 1474 ASSERT(target_function.raw() == function.raw()); |
| 1437 Code::Handle(function.CurrentCode()).EntryPoint(); | 1475 const Code& target_code = Code::Handle(function.CurrentCode()); |
| 1476 const uword new_entry_point = target_code.EntryPoint(); | |
| 1438 ASSERT(target != new_entry_point); // Why patch otherwise. | 1477 ASSERT(target != new_entry_point); // Why patch otherwise. |
| 1439 CodePatcher::PatchStaticCallAt(frame->pc(), new_entry_point); | 1478 CodePatcher::PatchStaticCallAt(frame->pc(), new_entry_point); |
| 1479 const Code& code = Code::Handle(frame->LookupDartCode()); | |
| 1480 bool found = UpdateResolvedStaticCall(code, | |
| 1481 frame->pc() - code.EntryPoint(), | |
| 1482 target_code); | |
| 1483 ASSERT(found); | |
| 1440 if (FLAG_trace_patching) { | 1484 if (FLAG_trace_patching) { |
| 1441 OS::Print("FixCallersTarget: patching from %#"Px" to '%s' %#"Px"\n", | 1485 OS::Print("FixCallersTarget: patching from %#"Px" to '%s' %#"Px"\n", |
| 1442 frame->pc(), | 1486 frame->pc(), |
| 1443 target_function.ToFullyQualifiedCString(), | 1487 target_function.ToFullyQualifiedCString(), |
| 1444 new_entry_point); | 1488 new_entry_point); |
| 1445 } | 1489 } |
| 1446 } | 1490 } |
| 1447 } | 1491 } |
| 1448 | 1492 |
| 1449 | 1493 |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1752 intptr_t line, column; | 1796 intptr_t line, column; |
| 1753 script.GetTokenLocation(token_pos, &line, &column); | 1797 script.GetTokenLocation(token_pos, &line, &column); |
| 1754 String& line_string = String::Handle(script.GetLine(line)); | 1798 String& line_string = String::Handle(script.GetLine(line)); |
| 1755 OS::Print(" Function: %s\n", top_function.ToFullyQualifiedCString()); | 1799 OS::Print(" Function: %s\n", top_function.ToFullyQualifiedCString()); |
| 1756 OS::Print(" Line %"Pd": '%s'\n", line, line_string.ToCString()); | 1800 OS::Print(" Line %"Pd": '%s'\n", line, line_string.ToCString()); |
| 1757 } | 1801 } |
| 1758 } | 1802 } |
| 1759 | 1803 |
| 1760 | 1804 |
| 1761 } // namespace dart | 1805 } // namespace dart |
| OLD | NEW |