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