OLD | NEW |
---|---|
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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/globals.h" | 5 #include "vm/globals.h" |
6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
7 | 7 |
8 #include "vm/debugger.h" | 8 #include "vm/debugger.h" |
9 | 9 |
10 #include "vm/assembler.h" | 10 #include "vm/assembler.h" |
11 #include "vm/code_patcher.h" | |
11 #include "vm/cpu.h" | 12 #include "vm/cpu.h" |
13 #include "vm/instructions.h" | |
12 #include "vm/stub_code.h" | 14 #include "vm/stub_code.h" |
13 | 15 |
14 namespace dart { | 16 namespace dart { |
15 | 17 |
16 RawInstance* ActivationFrame::GetInstanceCallReceiver( | 18 RawInstance* ActivationFrame::GetInstanceCallReceiver( |
17 intptr_t num_actual_args) { | 19 intptr_t num_actual_args) { |
18 ASSERT(num_actual_args > 0); // At minimum we have a receiver on the stack. | 20 ASSERT(num_actual_args > 0); // At minimum we have a receiver on the stack. |
19 // Stack pointer points to last argument that was pushed on the stack. | 21 // Stack pointer points to last argument that was pushed on the stack. |
20 uword receiver_addr = sp() + ((num_actual_args - 1) * kWordSize); | 22 uword receiver_addr = sp() + ((num_actual_args - 1) * kWordSize); |
21 return reinterpret_cast<RawInstance*>( | 23 return reinterpret_cast<RawInstance*>( |
22 *reinterpret_cast<uword*>(receiver_addr)); | 24 *reinterpret_cast<uword*>(receiver_addr)); |
23 } | 25 } |
24 | 26 |
25 | 27 |
26 RawObject* ActivationFrame::GetClosureObject(intptr_t num_actual_args) { | 28 RawObject* ActivationFrame::GetClosureObject(intptr_t num_actual_args) { |
27 // At a minimum we have the closure object on the stack. | 29 // At a minimum we have the closure object on the stack. |
28 ASSERT(num_actual_args > 0); | 30 ASSERT(num_actual_args > 0); |
29 // Stack pointer points to last argument that was pushed on the stack. | 31 // Stack pointer points to last argument that was pushed on the stack. |
30 uword closure_addr = sp() + ((num_actual_args - 1) * kWordSize); | 32 uword closure_addr = sp() + ((num_actual_args - 1) * kWordSize); |
31 return reinterpret_cast<RawObject*>( | 33 return reinterpret_cast<RawObject*>( |
32 *reinterpret_cast<uword*>(closure_addr)); | 34 *reinterpret_cast<uword*>(closure_addr)); |
33 } | 35 } |
34 | 36 |
37 | |
38 uword CodeBreakpoint::OrigStubAddress() const { | |
39 const Code& code = | |
40 Code::Handle(Function::Handle(function_).unoptimized_code()); | |
41 const Array& object_pool = Array::Handle(code.ObjectPool()); | |
42 uword offset = saved_value_ + kHeapObjectTag; | |
43 ASSERT((offset % kWordSize) == 0); | |
44 intptr_t index = (offset - Array::data_offset()) / kWordSize; | |
45 return reinterpret_cast<uword>(object_pool.At(index)); | |
Ivan Posva
2014/01/14 22:12:39
There are some assertions that you can make about
hausner
2014/01/14 22:49:41
Done.
| |
46 } | |
47 | |
48 | |
49 void CodeBreakpoint::PatchCode() { | |
50 ASSERT(!is_enabled_); | |
51 switch (breakpoint_kind_) { | |
52 case PcDescriptors::kIcCall: { | |
53 saved_value_ = CodePatcher::GetPoolOffsetAt(pc_); | |
54 const uint32_t stub_offset = | |
55 InstructionPattern::OffsetFromPPIndex( | |
56 Assembler::kBreakpointDynamicCPIndex); | |
57 CodePatcher::SetPoolOffsetAt(pc_, stub_offset); | |
58 //printf("XXX dynamic: patched offs %ld with %d at 0x%lx\n", saved_value_, stub_ offset, pc_); | |
59 break; | |
60 } | |
61 case PcDescriptors::kUnoptStaticCall: { | |
62 saved_value_ = CodePatcher::GetPoolOffsetAt(pc_); | |
63 const uint32_t stub_offset = | |
64 InstructionPattern::OffsetFromPPIndex( | |
65 Assembler::kBreakpointStaticCPIndex); | |
66 CodePatcher::SetPoolOffsetAt(pc_, stub_offset); | |
67 //printf("XXX static: patched offs %ld with %d at 0x%lx\n", saved_value_, stub_o ffset, pc_); | |
68 break; | |
69 } | |
70 case PcDescriptors::kRuntimeCall: | |
71 case PcDescriptors::kClosureCall: | |
72 case PcDescriptors::kReturn: { | |
73 saved_value_ = CodePatcher::GetPoolOffsetAt(pc_); | |
74 const uint32_t stub_offset = | |
75 InstructionPattern::OffsetFromPPIndex( | |
76 Assembler::kBreakpointRuntimeCPIndex); | |
77 CodePatcher::SetPoolOffsetAt(pc_, stub_offset); | |
78 //printf("XXX runtime: patched offs %ld with %d at 0x%lx\n", saved_value_, stub_ offset, pc_); | |
79 break; | |
80 } | |
81 default: | |
82 UNREACHABLE(); | |
83 } | |
84 is_enabled_ = true; | |
85 } | |
86 | |
87 | |
88 void CodeBreakpoint::RestoreCode() { | |
89 ASSERT(is_enabled_); | |
90 switch (breakpoint_kind_) { | |
91 case PcDescriptors::kIcCall: | |
92 case PcDescriptors::kUnoptStaticCall: | |
93 case PcDescriptors::kClosureCall: | |
94 case PcDescriptors::kRuntimeCall: | |
95 case PcDescriptors::kReturn: { | |
96 CodePatcher::SetPoolOffsetAt(pc_, saved_value_); | |
97 break; | |
98 } | |
99 default: | |
100 UNREACHABLE(); | |
101 } | |
102 is_enabled_ = false; | |
103 } | |
104 | |
105 | |
35 } // namespace dart | 106 } // namespace dart |
36 | 107 |
37 #endif // defined TARGET_ARCH_X64 | 108 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |