OLD | NEW |
1 // Copyright (c) 2011, 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/globals.h" // Needed here to get TARGET_ARCH_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
7 | 7 |
8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
9 #include "vm/code_patcher.h" | 9 #include "vm/code_patcher.h" |
10 #include "vm/cpu.h" | 10 #include "vm/cpu.h" |
11 #include "vm/instructions.h" | 11 #include "vm/instructions.h" |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 *b = tmp; | 155 *b = tmp; |
156 a++; | 156 a++; |
157 b++; | 157 b++; |
158 } | 158 } |
159 } | 159 } |
160 | 160 |
161 | 161 |
162 // The patch code buffer contains the jump code sequence which will be inserted | 162 // The patch code buffer contains the jump code sequence which will be inserted |
163 // at entry point. | 163 // at entry point. |
164 void CodePatcher::PatchEntry(const Code& code) { | 164 void CodePatcher::PatchEntry(const Code& code) { |
165 Jump jmp_entry(code.EntryPoint()); | 165 JumpPattern jmp_entry(code.EntryPoint()); |
166 ASSERT(!jmp_entry.IsValid()); | 166 ASSERT(!jmp_entry.IsValid()); |
167 const uword patch_buffer = code.GetPatchCodePc(); | 167 const uword patch_buffer = code.GetPatchCodePc(); |
168 ASSERT(patch_buffer != 0); | 168 ASSERT(patch_buffer != 0); |
169 Jump jmp_patch(patch_buffer); | 169 JumpPattern jmp_patch(patch_buffer); |
170 ASSERT(jmp_patch.IsValid()); | 170 ASSERT(jmp_patch.IsValid()); |
171 const uword jump_target = jmp_patch.TargetAddress(); | 171 const uword jump_target = jmp_patch.TargetAddress(); |
172 SwapCode(jmp_patch.pattern_length_in_bytes(), | 172 SwapCode(jmp_patch.pattern_length_in_bytes(), |
173 reinterpret_cast<char*>(code.EntryPoint()), | 173 reinterpret_cast<char*>(code.EntryPoint()), |
174 reinterpret_cast<char*>(patch_buffer)); | 174 reinterpret_cast<char*>(patch_buffer)); |
175 jmp_entry.SetTargetAddress(jump_target); | 175 jmp_entry.SetTargetAddress(jump_target); |
176 } | 176 } |
177 | 177 |
178 | 178 |
179 // The entry point is a jump code sequence, the patch code buffer contains | 179 // The entry point is a jump code sequence, the patch code buffer contains |
180 // original code, the entry point contains the jump code sequence. | 180 // original code, the entry point contains the jump code sequence. |
181 void CodePatcher::RestoreEntry(const Code& code) { | 181 void CodePatcher::RestoreEntry(const Code& code) { |
182 Jump jmp_entry(code.EntryPoint()); | 182 JumpPattern jmp_entry(code.EntryPoint()); |
183 ASSERT(jmp_entry.IsValid()); | 183 ASSERT(jmp_entry.IsValid()); |
184 const uword jump_target = jmp_entry.TargetAddress(); | 184 const uword jump_target = jmp_entry.TargetAddress(); |
185 const uword patch_buffer = code.GetPatchCodePc(); | 185 const uword patch_buffer = code.GetPatchCodePc(); |
186 ASSERT(patch_buffer != 0); | 186 ASSERT(patch_buffer != 0); |
187 // 'patch_buffer' contains original entry code. | 187 // 'patch_buffer' contains original entry code. |
188 Jump jmp_patch(patch_buffer); | 188 JumpPattern jmp_patch(patch_buffer); |
189 ASSERT(!jmp_patch.IsValid()); | 189 ASSERT(!jmp_patch.IsValid()); |
190 SwapCode(jmp_patch.pattern_length_in_bytes(), | 190 SwapCode(jmp_patch.pattern_length_in_bytes(), |
191 reinterpret_cast<char*>(code.EntryPoint()), | 191 reinterpret_cast<char*>(code.EntryPoint()), |
192 reinterpret_cast<char*>(patch_buffer)); | 192 reinterpret_cast<char*>(patch_buffer)); |
193 ASSERT(jmp_patch.IsValid()); | 193 ASSERT(jmp_patch.IsValid()); |
194 jmp_patch.SetTargetAddress(jump_target); | 194 jmp_patch.SetTargetAddress(jump_target); |
195 } | 195 } |
196 | 196 |
197 | 197 |
198 bool CodePatcher::CodeIsPatchable(const Code& code) { | 198 bool CodePatcher::CodeIsPatchable(const Code& code) { |
199 Jump jmp_entry(code.EntryPoint()); | 199 JumpPattern jmp_entry(code.EntryPoint()); |
200 if (code.Size() < (jmp_entry.pattern_length_in_bytes() * 2)) { | 200 if (code.Size() < (jmp_entry.pattern_length_in_bytes() * 2)) { |
201 return false; | 201 return false; |
202 } | 202 } |
203 uword limit = code.EntryPoint() + jmp_entry.pattern_length_in_bytes(); | 203 uword limit = code.EntryPoint() + jmp_entry.pattern_length_in_bytes(); |
204 for (intptr_t i = 0; i < code.pointer_offsets_length(); i++) { | 204 for (intptr_t i = 0; i < code.pointer_offsets_length(); i++) { |
205 const uword addr = code.GetPointerOffsetAt(i) + code.EntryPoint(); | 205 const uword addr = code.GetPointerOffsetAt(i) + code.EntryPoint(); |
206 if (addr < limit) { | 206 if (addr < limit) { |
207 return false; | 207 return false; |
208 } | 208 } |
209 } | 209 } |
(...skipping 30 matching lines...) Expand all Loading... |
240 } | 240 } |
241 | 241 |
242 | 242 |
243 intptr_t CodePatcher::InstanceCallSizeInBytes() { | 243 intptr_t CodePatcher::InstanceCallSizeInBytes() { |
244 return DartCallPattern::kCallPatternSize; | 244 return DartCallPattern::kCallPatternSize; |
245 } | 245 } |
246 | 246 |
247 } // namespace dart | 247 } // namespace dart |
248 | 248 |
249 #endif // defined TARGET_ARCH_X64 | 249 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |