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 |