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_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
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 26 matching lines...) Expand all Loading... |
37 static const int kPatternSize = | 37 static const int kPatternSize = |
38 2 * kMovInstructionSize + kCallInstructionSize; | 38 2 * kMovInstructionSize + kCallInstructionSize; |
39 | 39 |
40 private: | 40 private: |
41 bool IsValid() { | 41 bool IsValid() { |
42 uint8_t* code_bytes = reinterpret_cast<uint8_t*>(start_); | 42 uint8_t* code_bytes = reinterpret_cast<uint8_t*>(start_); |
43 return (code_bytes[0] == 0xB9) && | 43 return (code_bytes[0] == 0xB9) && |
44 (code_bytes[2 * kMovInstructionSize] == 0xFF); | 44 (code_bytes[2 * kMovInstructionSize] == 0xFF); |
45 } | 45 } |
46 | 46 |
47 uword return_address() const { | 47 uword return_address() const { return start_ + kPatternSize; } |
48 return start_ + kPatternSize; | |
49 } | |
50 | 48 |
51 uword call_address() const { | 49 uword call_address() const { return start_ + 2 * kMovInstructionSize; } |
52 return start_ + 2 * kMovInstructionSize; | |
53 } | |
54 | 50 |
55 protected: | 51 protected: |
56 uword start_; | 52 uword start_; |
57 | 53 |
58 private: | 54 private: |
59 DISALLOW_IMPLICIT_CONSTRUCTORS(UnoptimizedCall); | 55 DISALLOW_IMPLICIT_CONSTRUCTORS(UnoptimizedCall); |
60 }; | 56 }; |
61 | 57 |
62 | 58 |
63 class NativeCall : public UnoptimizedCall { | 59 class NativeCall : public UnoptimizedCall { |
64 public: | 60 public: |
65 explicit NativeCall(uword return_address) : UnoptimizedCall(return_address) { | 61 explicit NativeCall(uword return_address) : UnoptimizedCall(return_address) {} |
66 } | |
67 | 62 |
68 NativeFunction native_function() const { | 63 NativeFunction native_function() const { |
69 return *reinterpret_cast<NativeFunction*>(start_ + 1); | 64 return *reinterpret_cast<NativeFunction*>(start_ + 1); |
70 } | 65 } |
71 | 66 |
72 void set_native_function(NativeFunction func) const { | 67 void set_native_function(NativeFunction func) const { |
73 WritableInstructionsScope writable(start_ + 1, sizeof(func)); | 68 WritableInstructionsScope writable(start_ + 1, sizeof(func)); |
74 *reinterpret_cast<NativeFunction*>(start_ + 1) = func; | 69 *reinterpret_cast<NativeFunction*>(start_ + 1) = func; |
75 } | 70 } |
76 | 71 |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
138 uword imm = reinterpret_cast<uword>(target.raw()); | 133 uword imm = reinterpret_cast<uword>(target.raw()); |
139 *target_addr = imm; | 134 *target_addr = imm; |
140 CPU::FlushICache(start_ + 1, sizeof(imm)); | 135 CPU::FlushICache(start_ + 1, sizeof(imm)); |
141 } | 136 } |
142 | 137 |
143 static const int kMovInstructionSize = 5; | 138 static const int kMovInstructionSize = 5; |
144 static const int kCallInstructionSize = 3; | 139 static const int kCallInstructionSize = 3; |
145 | 140 |
146 private: | 141 private: |
147 uword return_address() const { | 142 uword return_address() const { |
148 return start_ + kMovInstructionSize + kCallInstructionSize; | 143 return start_ + kMovInstructionSize + kCallInstructionSize; |
149 } | 144 } |
150 | 145 |
151 uword call_address() const { | 146 uword call_address() const { return start_ + kMovInstructionSize; } |
152 return start_ + kMovInstructionSize; | |
153 } | |
154 | 147 |
155 uword start_; | 148 uword start_; |
156 | 149 |
157 DISALLOW_IMPLICIT_CONSTRUCTORS(StaticCall); | 150 DISALLOW_IMPLICIT_CONSTRUCTORS(StaticCall); |
158 }; | 151 }; |
159 | 152 |
160 | 153 |
161 RawCode* CodePatcher::GetStaticCallTargetAt(uword return_address, | 154 RawCode* CodePatcher::GetStaticCallTargetAt(uword return_address, |
162 const Code& code) { | 155 const Code& code) { |
163 ASSERT(code.ContainsInstructionAt(return_address)); | 156 ASSERT(code.ContainsInstructionAt(return_address)); |
(...skipping 11 matching lines...) Expand all Loading... |
175 StaticCall call(return_address); | 168 StaticCall call(return_address); |
176 call.set_target(new_target); | 169 call.set_target(new_target); |
177 } | 170 } |
178 | 171 |
179 | 172 |
180 void CodePatcher::InsertDeoptimizationCallAt(uword start) { | 173 void CodePatcher::InsertDeoptimizationCallAt(uword start) { |
181 UNREACHABLE(); | 174 UNREACHABLE(); |
182 } | 175 } |
183 | 176 |
184 | 177 |
185 RawCode* CodePatcher::GetInstanceCallAt( | 178 RawCode* CodePatcher::GetInstanceCallAt(uword return_address, |
186 uword return_address, const Code& code, ICData* ic_data) { | 179 const Code& code, |
| 180 ICData* ic_data) { |
187 ASSERT(code.ContainsInstructionAt(return_address)); | 181 ASSERT(code.ContainsInstructionAt(return_address)); |
188 InstanceCall call(return_address); | 182 InstanceCall call(return_address); |
189 if (ic_data != NULL) { | 183 if (ic_data != NULL) { |
190 *ic_data ^= call.ic_data(); | 184 *ic_data ^= call.ic_data(); |
191 } | 185 } |
192 return Code::null(); | 186 return Code::null(); |
193 } | 187 } |
194 | 188 |
195 | 189 |
196 RawFunction* CodePatcher::GetUnoptimizedStaticCallAt( | 190 RawFunction* CodePatcher::GetUnoptimizedStaticCallAt(uword return_address, |
197 uword return_address, const Code& code, ICData* ic_data_result) { | 191 const Code& code, |
| 192 ICData* ic_data_result) { |
198 ASSERT(code.ContainsInstructionAt(return_address)); | 193 ASSERT(code.ContainsInstructionAt(return_address)); |
199 UnoptimizedStaticCall static_call(return_address); | 194 UnoptimizedStaticCall static_call(return_address); |
200 ICData& ic_data = ICData::Handle(); | 195 ICData& ic_data = ICData::Handle(); |
201 ic_data ^= static_call.ic_data(); | 196 ic_data ^= static_call.ic_data(); |
202 if (ic_data_result != NULL) { | 197 if (ic_data_result != NULL) { |
203 *ic_data_result = ic_data.raw(); | 198 *ic_data_result = ic_data.raw(); |
204 } | 199 } |
205 return ic_data.GetTargetAt(0); | 200 return ic_data.GetTargetAt(0); |
206 } | 201 } |
207 | 202 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
240 | 235 |
241 | 236 |
242 RawCode* CodePatcher::GetNativeCallAt(uword return_address, | 237 RawCode* CodePatcher::GetNativeCallAt(uword return_address, |
243 const Code& code, | 238 const Code& code, |
244 NativeFunction* target) { | 239 NativeFunction* target) { |
245 UNREACHABLE(); | 240 UNREACHABLE(); |
246 return NULL; | 241 return NULL; |
247 } | 242 } |
248 | 243 |
249 | 244 |
250 | |
251 intptr_t CodePatcher::InstanceCallSizeInBytes() { | 245 intptr_t CodePatcher::InstanceCallSizeInBytes() { |
252 return InstanceCall::kPatternSize; | 246 return InstanceCall::kPatternSize; |
253 } | 247 } |
254 | 248 |
255 } // namespace dart | 249 } // namespace dart |
256 | 250 |
257 #endif // defined TARGET_ARCH_IA32 | 251 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |