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/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" |
(...skipping 23 matching lines...) Expand all Loading... |
34 static bool IsValid(uword return_address) { | 34 static bool IsValid(uword return_address) { |
35 uint8_t* code_bytes = | 35 uint8_t* code_bytes = |
36 reinterpret_cast<uint8_t*>(return_address - kCallPatternSize); | 36 reinterpret_cast<uint8_t*>(return_address - kCallPatternSize); |
37 return (code_bytes[0] == 0x49) && (code_bytes[1] == 0x8B) && | 37 return (code_bytes[0] == 0x49) && (code_bytes[1] == 0x8B) && |
38 (code_bytes[2] == 0x9F) && | 38 (code_bytes[2] == 0x9F) && |
39 (code_bytes[7] == 0x41) && (code_bytes[8] == 0xFF) && | 39 (code_bytes[7] == 0x41) && (code_bytes[8] == 0xFF) && |
40 (code_bytes[9] == 0x97); | 40 (code_bytes[9] == 0x97); |
41 } | 41 } |
42 | 42 |
43 RawObject* ic_data() const { | 43 RawObject* ic_data() const { |
44 intptr_t index = InstructionPattern::IndexFromPPLoad(start_ + 3); | 44 intptr_t index = IndexFromPPLoad(start_ + 3); |
45 return object_pool_.ObjectAt(index); | 45 return object_pool_.ObjectAt(index); |
46 } | 46 } |
47 | 47 |
48 uword target() const { | 48 uword target() const { |
49 intptr_t index = InstructionPattern::IndexFromPPLoad(start_ + 10); | 49 intptr_t index = IndexFromPPLoad(start_ + 10); |
50 return object_pool_.RawValueAt(index); | 50 return object_pool_.RawValueAt(index); |
51 } | 51 } |
52 | 52 |
53 void set_target(uword target) const { | 53 void set_target(uword target) const { |
54 intptr_t index = InstructionPattern::IndexFromPPLoad(start_ + 10); | 54 intptr_t index = IndexFromPPLoad(start_ + 10); |
55 object_pool_.SetRawValueAt(index, target); | 55 object_pool_.SetRawValueAt(index, target); |
56 // No need to flush the instruction cache, since the code is not modified. | 56 // No need to flush the instruction cache, since the code is not modified. |
57 } | 57 } |
58 | 58 |
59 private: | 59 private: |
60 uword start_; | 60 uword start_; |
61 const ObjectPool& object_pool_; | 61 const ObjectPool& object_pool_; |
62 DISALLOW_IMPLICIT_CONSTRUCTORS(UnoptimizedCall); | 62 DISALLOW_IMPLICIT_CONSTRUCTORS(UnoptimizedCall); |
63 }; | 63 }; |
64 | 64 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 static const int kCallPatternSize = 7; | 110 static const int kCallPatternSize = 7; |
111 | 111 |
112 static bool IsValid(uword return_address) { | 112 static bool IsValid(uword return_address) { |
113 uint8_t* code_bytes = | 113 uint8_t* code_bytes = |
114 reinterpret_cast<uint8_t*>(return_address - kCallPatternSize); | 114 reinterpret_cast<uint8_t*>(return_address - kCallPatternSize); |
115 return (code_bytes[0] == 0x41) && (code_bytes[1] == 0xFF) && | 115 return (code_bytes[0] == 0x41) && (code_bytes[1] == 0xFF) && |
116 (code_bytes[2] == 0x97); | 116 (code_bytes[2] == 0x97); |
117 } | 117 } |
118 | 118 |
119 intptr_t pp_index() const { | 119 intptr_t pp_index() const { |
120 return InstructionPattern::IndexFromPPLoad(start_ + 3); | 120 return IndexFromPPLoad(start_ + 3); |
121 } | 121 } |
122 | 122 |
123 uword Target() const { | 123 uword Target() const { |
124 return object_pool_.RawValueAt(pp_index()); | 124 return object_pool_.RawValueAt(pp_index()); |
125 } | 125 } |
126 | 126 |
127 void SetTarget(uword target) const { | 127 void SetTarget(uword target) const { |
128 object_pool_.SetRawValueAt(pp_index(), target); | 128 object_pool_.SetRawValueAt(pp_index(), target); |
129 // No need to flush the instruction cache, since the code is not modified. | 129 // No need to flush the instruction cache, since the code is not modified. |
130 } | 130 } |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
183 } | 183 } |
184 | 184 |
185 | 185 |
186 intptr_t CodePatcher::InstanceCallSizeInBytes() { | 186 intptr_t CodePatcher::InstanceCallSizeInBytes() { |
187 return InstanceCall::kCallPatternSize; | 187 return InstanceCall::kCallPatternSize; |
188 } | 188 } |
189 | 189 |
190 | 190 |
191 void CodePatcher::InsertCallAt(uword start, uword target) { | 191 void CodePatcher::InsertCallAt(uword start, uword target) { |
192 // The inserted call should not overlap the lazy deopt jump code. | 192 // The inserted call should not overlap the lazy deopt jump code. |
193 ASSERT(start + ShortCallPattern::InstructionLength() <= target); | 193 ASSERT(start + ShortCallPattern::pattern_length_in_bytes() <= target); |
194 *reinterpret_cast<uint8_t*>(start) = 0xE8; | 194 *reinterpret_cast<uint8_t*>(start) = 0xE8; |
195 ShortCallPattern call(start); | 195 ShortCallPattern call(start); |
196 call.SetTargetAddress(target); | 196 call.SetTargetAddress(target); |
197 CPU::FlushICache(start, ShortCallPattern::InstructionLength()); | 197 CPU::FlushICache(start, ShortCallPattern::pattern_length_in_bytes()); |
198 } | 198 } |
199 | 199 |
200 | 200 |
201 RawFunction* CodePatcher::GetUnoptimizedStaticCallAt( | 201 RawFunction* CodePatcher::GetUnoptimizedStaticCallAt( |
202 uword return_address, const Code& code, ICData* ic_data_result) { | 202 uword return_address, const Code& code, ICData* ic_data_result) { |
203 ASSERT(code.ContainsInstructionAt(return_address)); | 203 ASSERT(code.ContainsInstructionAt(return_address)); |
204 UnoptimizedStaticCall static_call(return_address, code); | 204 UnoptimizedStaticCall static_call(return_address, code); |
205 ICData& ic_data = ICData::Handle(); | 205 ICData& ic_data = ICData::Handle(); |
206 ic_data ^= static_call.ic_data(); | 206 ic_data ^= static_call.ic_data(); |
207 if (ic_data_result != NULL) { | 207 if (ic_data_result != NULL) { |
(...skipping 12 matching lines...) Expand all Loading... |
220 object_pool_(ObjectPool::Handle(code.GetObjectPool())) { | 220 object_pool_(ObjectPool::Handle(code.GetObjectPool())) { |
221 ASSERT(IsValid(end_)); | 221 ASSERT(IsValid(end_)); |
222 } | 222 } |
223 | 223 |
224 static bool IsValid(uword end) { | 224 static bool IsValid(uword end) { |
225 uint8_t* bytes = reinterpret_cast<uint8_t*>(end - 7); | 225 uint8_t* bytes = reinterpret_cast<uint8_t*>(end - 7); |
226 return (bytes[0] == 0x49) && (bytes[1] == 0x8b) && (bytes[2] == 0x87); | 226 return (bytes[0] == 0x49) && (bytes[1] == 0x8b) && (bytes[2] == 0x87); |
227 } | 227 } |
228 | 228 |
229 RawObject* edge_counter() const { | 229 RawObject* edge_counter() const { |
230 return object_pool_.ObjectAt(InstructionPattern::IndexFromPPLoad(end_ - 4)); | 230 return object_pool_.ObjectAt(IndexFromPPLoad(end_ - 4)); |
231 } | 231 } |
232 | 232 |
233 private: | 233 private: |
234 uword end_; | 234 uword end_; |
235 const ObjectPool& object_pool_; | 235 const ObjectPool& object_pool_; |
236 }; | 236 }; |
237 | 237 |
238 | 238 |
239 RawObject* CodePatcher::GetEdgeCounterAt(uword pc, const Code& code) { | 239 RawObject* CodePatcher::GetEdgeCounterAt(uword pc, const Code& code) { |
240 ASSERT(code.ContainsInstructionAt(pc)); | 240 ASSERT(code.ContainsInstructionAt(pc)); |
241 EdgeCounter counter(pc, code); | 241 EdgeCounter counter(pc, code); |
242 return counter.edge_counter(); | 242 return counter.edge_counter(); |
243 } | 243 } |
244 | 244 |
245 } // namespace dart | 245 } // namespace dart |
246 | 246 |
247 #endif // defined TARGET_ARCH_X64 | 247 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |