| 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 |