| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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_MIPS. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS. |
| 6 #if defined(TARGET_ARCH_MIPS) | 6 #if defined(TARGET_ARCH_MIPS) |
| 7 | 7 |
| 8 #include "vm/constants_mips.h" | 8 #include "vm/constants_mips.h" |
| 9 #include "vm/cpu.h" | 9 #include "vm/cpu.h" |
| 10 #include "vm/instructions.h" | 10 #include "vm/instructions.h" |
| 11 #include "vm/object.h" | 11 #include "vm/object.h" |
| 12 | 12 |
| 13 namespace dart { | 13 namespace dart { |
| 14 | 14 |
| 15 CallPattern::CallPattern(uword pc, const Code& code) | 15 CallPattern::CallPattern(uword pc, const Code& code) |
| 16 : object_pool_(Array::Handle(code.ObjectPool())), | 16 : object_pool_(ObjectPool::Handle(code.GetObjectPool())), |
| 17 end_(pc), | 17 end_(pc), |
| 18 args_desc_load_end_(0), | 18 args_desc_load_end_(0), |
| 19 ic_data_load_end_(0), | 19 ic_data_load_end_(0), |
| 20 target_address_pool_index_(-1), | 20 target_address_pool_index_(-1), |
| 21 args_desc_(Array::Handle()), | 21 args_desc_(Array::Handle()), |
| 22 ic_data_(ICData::Handle()) { | 22 ic_data_(ICData::Handle()) { |
| 23 ASSERT(code.ContainsInstructionAt(pc)); | 23 ASSERT(code.ContainsInstructionAt(pc)); |
| 24 // Last instruction: jalr RA, T9(=R25). | 24 // Last instruction: jalr RA, T9(=R25). |
| 25 ASSERT(*(reinterpret_cast<uword*>(end_) - 2) == 0x0320f809); | 25 ASSERT(*(reinterpret_cast<uword*>(end_) - 2) == 0x0320f809); |
| 26 Register reg; | 26 Register reg; |
| 27 // The end of the pattern is the instruction after the delay slot of the jalr. | 27 // The end of the pattern is the instruction after the delay slot of the jalr. |
| 28 ic_data_load_end_ = | 28 ic_data_load_end_ = |
| 29 InstructionPattern::DecodeLoadWordFromPool(end_ - (2 * Instr::kInstrSize), | 29 InstructionPattern::DecodeLoadWordFromPool(end_ - (2 * Instr::kInstrSize), |
| 30 ®, | 30 ®, |
| 31 &target_address_pool_index_); | 31 &target_address_pool_index_); |
| 32 ASSERT(reg == T9); | 32 ASSERT(reg == T9); |
| 33 } | 33 } |
| 34 | 34 |
| 35 | 35 |
| 36 // Decodes a load sequence ending at 'end' (the last instruction of the load | 36 // Decodes a load sequence ending at 'end' (the last instruction of the load |
| 37 // sequence is the instruction before the one at end). Returns a pointer to | 37 // sequence is the instruction before the one at end). Returns a pointer to |
| 38 // the first instruction in the sequence. Returns the register being loaded | 38 // the first instruction in the sequence. Returns the register being loaded |
| 39 // and the loaded object in the output parameters 'reg' and 'obj' | 39 // and the loaded object in the output parameters 'reg' and 'obj' |
| 40 // respectively. | 40 // respectively. |
| 41 uword InstructionPattern::DecodeLoadObject(uword end, | 41 uword InstructionPattern::DecodeLoadObject(uword end, |
| 42 const Array& object_pool, | 42 const ObjectPool& object_pool, |
| 43 Register* reg, | 43 Register* reg, |
| 44 Object* obj) { | 44 Object* obj) { |
| 45 uword start = 0; | 45 uword start = 0; |
| 46 Instr* instr = Instr::At(end - Instr::kInstrSize); | 46 Instr* instr = Instr::At(end - Instr::kInstrSize); |
| 47 if (instr->OpcodeField() == LW) { | 47 if (instr->OpcodeField() == LW) { |
| 48 intptr_t index = 0; | 48 intptr_t index = 0; |
| 49 start = DecodeLoadWordFromPool(end, reg, &index); | 49 start = DecodeLoadWordFromPool(end, reg, &index); |
| 50 *obj = object_pool.At(index); | 50 *obj = object_pool.ObjectAt(index); |
| 51 } else { | 51 } else { |
| 52 intptr_t value = 0; | 52 intptr_t value = 0; |
| 53 start = DecodeLoadWordImmediate(end, reg, &value); | 53 start = DecodeLoadWordImmediate(end, reg, &value); |
| 54 *obj = reinterpret_cast<RawObject*>(value); | 54 *obj = reinterpret_cast<RawObject*>(value); |
| 55 } | 55 } |
| 56 return start; | 56 return start; |
| 57 } | 57 } |
| 58 | 58 |
| 59 | 59 |
| 60 // Decodes a load sequence ending at 'end' (the last instruction of the load | 60 // Decodes a load sequence ending at 'end' (the last instruction of the load |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 object_pool_, | 147 object_pool_, |
| 148 ®, | 148 ®, |
| 149 &args_desc_); | 149 &args_desc_); |
| 150 ASSERT(reg == S4); | 150 ASSERT(reg == S4); |
| 151 } | 151 } |
| 152 return args_desc_.raw(); | 152 return args_desc_.raw(); |
| 153 } | 153 } |
| 154 | 154 |
| 155 | 155 |
| 156 uword CallPattern::TargetAddress() const { | 156 uword CallPattern::TargetAddress() const { |
| 157 ASSERT(target_address_pool_index_ >= 0); | 157 return object_pool_.RawValueAt(target_address_pool_index_); |
| 158 const Object& target_address = | |
| 159 Object::Handle(object_pool_.At(target_address_pool_index_)); | |
| 160 ASSERT(target_address.IsSmi()); | |
| 161 // The address is stored in the object array as a RawSmi. | |
| 162 return reinterpret_cast<uword>(target_address.raw()); | |
| 163 } | 158 } |
| 164 | 159 |
| 165 | 160 |
| 166 void CallPattern::SetTargetAddress(uword target_address) const { | 161 void CallPattern::SetTargetAddress(uword target_address) const { |
| 167 ASSERT(Utils::IsAligned(target_address, 4)); | 162 object_pool_.SetRawValueAt(target_address_pool_index_, target_address); |
| 168 // The address is stored in the object array as a RawSmi. | |
| 169 const Smi& smi = Smi::Handle(reinterpret_cast<RawSmi*>(target_address)); | |
| 170 object_pool_.SetAt(target_address_pool_index_, smi); | |
| 171 // No need to flush the instruction cache, since the code is not modified. | 163 // No need to flush the instruction cache, since the code is not modified. |
| 172 } | 164 } |
| 173 | 165 |
| 174 | 166 |
| 175 void CallPattern::InsertAt(uword pc, uword target_address) { | 167 void CallPattern::InsertAt(uword pc, uword target_address) { |
| 176 Instr* lui = Instr::At(pc + (0 * Instr::kInstrSize)); | 168 Instr* lui = Instr::At(pc + (0 * Instr::kInstrSize)); |
| 177 Instr* ori = Instr::At(pc + (1 * Instr::kInstrSize)); | 169 Instr* ori = Instr::At(pc + (1 * Instr::kInstrSize)); |
| 178 Instr* jr = Instr::At(pc + (2 * Instr::kInstrSize)); | 170 Instr* jr = Instr::At(pc + (2 * Instr::kInstrSize)); |
| 179 Instr* nop = Instr::At(pc + (3 * Instr::kInstrSize)); | 171 Instr* nop = Instr::At(pc + (3 * Instr::kInstrSize)); |
| 180 uint16_t target_lo = target_address & 0xffff; | 172 uint16_t target_lo = target_address & 0xffff; |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 236 bool ReturnPattern::IsValid() const { | 228 bool ReturnPattern::IsValid() const { |
| 237 Instr* jr = Instr::At(pc_); | 229 Instr* jr = Instr::At(pc_); |
| 238 return (jr->OpcodeField() == SPECIAL) && | 230 return (jr->OpcodeField() == SPECIAL) && |
| 239 (jr->FunctionField() == JR) && | 231 (jr->FunctionField() == JR) && |
| 240 (jr->RsField() == RA); | 232 (jr->RsField() == RA); |
| 241 } | 233 } |
| 242 | 234 |
| 243 } // namespace dart | 235 } // namespace dart |
| 244 | 236 |
| 245 #endif // defined TARGET_ARCH_MIPS | 237 #endif // defined TARGET_ARCH_MIPS |
| OLD | NEW |