Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(141)

Side by Side Diff: runtime/vm/instructions_arm.cc

Issue 2974233002: VM: Re-format to use at most one newline between functions (Closed)
Patch Set: Rebase and merge Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/instructions_arm.h ('k') | runtime/vm/instructions_arm64.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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_ARM. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM.
6 #if defined(TARGET_ARCH_ARM) 6 #if defined(TARGET_ARCH_ARM)
7 7
8 #include "vm/instructions.h" 8 #include "vm/instructions.h"
9 #include "vm/instructions_arm.h" 9 #include "vm/instructions_arm.h"
10 10
(...skipping 13 matching lines...) Expand all
24 ASSERT(code.ContainsInstructionAt(pc)); 24 ASSERT(code.ContainsInstructionAt(pc));
25 // Last instruction: blx lr. 25 // Last instruction: blx lr.
26 ASSERT(*(reinterpret_cast<uword*>(end_) - 1) == 0xe12fff3e); 26 ASSERT(*(reinterpret_cast<uword*>(end_) - 1) == 0xe12fff3e);
27 27
28 Register reg; 28 Register reg;
29 ic_data_load_end_ = InstructionPattern::DecodeLoadWordFromPool( 29 ic_data_load_end_ = InstructionPattern::DecodeLoadWordFromPool(
30 end_ - 2 * Instr::kInstrSize, &reg, &target_code_pool_index_); 30 end_ - 2 * Instr::kInstrSize, &reg, &target_code_pool_index_);
31 ASSERT(reg == CODE_REG); 31 ASSERT(reg == CODE_REG);
32 } 32 }
33 33
34
35 NativeCallPattern::NativeCallPattern(uword pc, const Code& code) 34 NativeCallPattern::NativeCallPattern(uword pc, const Code& code)
36 : object_pool_(ObjectPool::Handle(code.GetObjectPool())), 35 : object_pool_(ObjectPool::Handle(code.GetObjectPool())),
37 end_(pc), 36 end_(pc),
38 native_function_pool_index_(-1), 37 native_function_pool_index_(-1),
39 target_code_pool_index_(-1) { 38 target_code_pool_index_(-1) {
40 ASSERT(code.ContainsInstructionAt(pc)); 39 ASSERT(code.ContainsInstructionAt(pc));
41 // Last instruction: blx lr. 40 // Last instruction: blx lr.
42 ASSERT(*(reinterpret_cast<uword*>(end_) - 1) == 0xe12fff3e); 41 ASSERT(*(reinterpret_cast<uword*>(end_) - 1) == 0xe12fff3e);
43 42
44 Register reg; 43 Register reg;
45 uword native_function_load_end = InstructionPattern::DecodeLoadWordFromPool( 44 uword native_function_load_end = InstructionPattern::DecodeLoadWordFromPool(
46 end_ - 2 * Instr::kInstrSize, &reg, &target_code_pool_index_); 45 end_ - 2 * Instr::kInstrSize, &reg, &target_code_pool_index_);
47 ASSERT(reg == CODE_REG); 46 ASSERT(reg == CODE_REG);
48 InstructionPattern::DecodeLoadWordFromPool(native_function_load_end, &reg, 47 InstructionPattern::DecodeLoadWordFromPool(native_function_load_end, &reg,
49 &native_function_pool_index_); 48 &native_function_pool_index_);
50 ASSERT(reg == R9); 49 ASSERT(reg == R9);
51 } 50 }
52 51
53
54 RawCode* NativeCallPattern::target() const { 52 RawCode* NativeCallPattern::target() const {
55 return reinterpret_cast<RawCode*>( 53 return reinterpret_cast<RawCode*>(
56 object_pool_.ObjectAt(target_code_pool_index_)); 54 object_pool_.ObjectAt(target_code_pool_index_));
57 } 55 }
58 56
59
60 void NativeCallPattern::set_target(const Code& new_target) const { 57 void NativeCallPattern::set_target(const Code& new_target) const {
61 object_pool_.SetObjectAt(target_code_pool_index_, new_target); 58 object_pool_.SetObjectAt(target_code_pool_index_, new_target);
62 // No need to flush the instruction cache, since the code is not modified. 59 // No need to flush the instruction cache, since the code is not modified.
63 } 60 }
64 61
65
66 NativeFunction NativeCallPattern::native_function() const { 62 NativeFunction NativeCallPattern::native_function() const {
67 return reinterpret_cast<NativeFunction>( 63 return reinterpret_cast<NativeFunction>(
68 object_pool_.RawValueAt(native_function_pool_index_)); 64 object_pool_.RawValueAt(native_function_pool_index_));
69 } 65 }
70 66
71
72 void NativeCallPattern::set_native_function(NativeFunction func) const { 67 void NativeCallPattern::set_native_function(NativeFunction func) const {
73 object_pool_.SetRawValueAt(native_function_pool_index_, 68 object_pool_.SetRawValueAt(native_function_pool_index_,
74 reinterpret_cast<uword>(func)); 69 reinterpret_cast<uword>(func));
75 } 70 }
76 71
77
78 // Decodes a load sequence ending at 'end' (the last instruction of the load 72 // Decodes a load sequence ending at 'end' (the last instruction of the load
79 // sequence is the instruction before the one at end). Returns a pointer to 73 // sequence is the instruction before the one at end). Returns a pointer to
80 // the first instruction in the sequence. Returns the register being loaded 74 // the first instruction in the sequence. Returns the register being loaded
81 // and the loaded object in the output parameters 'reg' and 'obj' 75 // and the loaded object in the output parameters 'reg' and 'obj'
82 // respectively. 76 // respectively.
83 uword InstructionPattern::DecodeLoadObject(uword end, 77 uword InstructionPattern::DecodeLoadObject(uword end,
84 const ObjectPool& object_pool, 78 const ObjectPool& object_pool,
85 Register* reg, 79 Register* reg,
86 Object* obj) { 80 Object* obj) {
87 uword start = 0; 81 uword start = 0;
88 Instr* instr = Instr::At(end - Instr::kInstrSize); 82 Instr* instr = Instr::At(end - Instr::kInstrSize);
89 if ((instr->InstructionBits() & 0xfff00000) == 0xe5900000) { 83 if ((instr->InstructionBits() & 0xfff00000) == 0xe5900000) {
90 // ldr reg, [reg, #+offset] 84 // ldr reg, [reg, #+offset]
91 intptr_t index = 0; 85 intptr_t index = 0;
92 start = DecodeLoadWordFromPool(end, reg, &index); 86 start = DecodeLoadWordFromPool(end, reg, &index);
93 *obj = object_pool.ObjectAt(index); 87 *obj = object_pool.ObjectAt(index);
94 } else { 88 } else {
95 intptr_t value = 0; 89 intptr_t value = 0;
96 start = DecodeLoadWordImmediate(end, reg, &value); 90 start = DecodeLoadWordImmediate(end, reg, &value);
97 *obj = reinterpret_cast<RawObject*>(value); 91 *obj = reinterpret_cast<RawObject*>(value);
98 } 92 }
99 return start; 93 return start;
100 } 94 }
101 95
102
103 // Decodes a load sequence ending at 'end' (the last instruction of the load 96 // Decodes a load sequence ending at 'end' (the last instruction of the load
104 // sequence is the instruction before the one at end). Returns a pointer to 97 // sequence is the instruction before the one at end). Returns a pointer to
105 // the first instruction in the sequence. Returns the register being loaded 98 // the first instruction in the sequence. Returns the register being loaded
106 // and the loaded immediate value in the output parameters 'reg' and 'value' 99 // and the loaded immediate value in the output parameters 'reg' and 'value'
107 // respectively. 100 // respectively.
108 uword InstructionPattern::DecodeLoadWordImmediate(uword end, 101 uword InstructionPattern::DecodeLoadWordImmediate(uword end,
109 Register* reg, 102 Register* reg,
110 intptr_t* value) { 103 intptr_t* value) {
111 uword start = end - Instr::kInstrSize; 104 uword start = end - Instr::kInstrSize;
112 int32_t instr = Instr::At(start)->InstructionBits(); 105 int32_t instr = Instr::At(start)->InstructionBits();
(...skipping 30 matching lines...) Expand all
143 } 136 }
144 ASSERT((instr & 0xfff00000) == 0xe3000000); // movw reg, #imm_lo 137 ASSERT((instr & 0xfff00000) == 0xe3000000); // movw reg, #imm_lo
145 imm |= (instr & 0xf0000) >> 4; 138 imm |= (instr & 0xf0000) >> 4;
146 imm |= instr & 0xfff; 139 imm |= instr & 0xfff;
147 *reg = static_cast<Register>((instr & 0xf000) >> 12); 140 *reg = static_cast<Register>((instr & 0xf000) >> 12);
148 *value = imm; 141 *value = imm;
149 } 142 }
150 return start; 143 return start;
151 } 144 }
152 145
153
154 static bool IsLoadWithOffset(int32_t instr, 146 static bool IsLoadWithOffset(int32_t instr,
155 Register base, 147 Register base,
156 intptr_t* offset, 148 intptr_t* offset,
157 Register* dst) { 149 Register* dst) {
158 if ((instr & 0xffff0000) == (0xe5900000 | (base << 16))) { 150 if ((instr & 0xffff0000) == (0xe5900000 | (base << 16))) {
159 // ldr reg, [base, #+offset] 151 // ldr reg, [base, #+offset]
160 *offset = instr & 0xfff; 152 *offset = instr & 0xfff;
161 *dst = static_cast<Register>((instr & 0xf000) >> 12); 153 *dst = static_cast<Register>((instr & 0xf000) >> 12);
162 return true; 154 return true;
163 } 155 }
164 return false; 156 return false;
165 } 157 }
166 158
167
168 // Decodes a load sequence ending at 'end' (the last instruction of the load 159 // Decodes a load sequence ending at 'end' (the last instruction of the load
169 // sequence is the instruction before the one at end). Returns a pointer to 160 // sequence is the instruction before the one at end). Returns a pointer to
170 // the first instruction in the sequence. Returns the register being loaded 161 // the first instruction in the sequence. Returns the register being loaded
171 // and the index in the pool being read from in the output parameters 'reg' 162 // and the index in the pool being read from in the output parameters 'reg'
172 // and 'index' respectively. 163 // and 'index' respectively.
173 uword InstructionPattern::DecodeLoadWordFromPool(uword end, 164 uword InstructionPattern::DecodeLoadWordFromPool(uword end,
174 Register* reg, 165 Register* reg,
175 intptr_t* index) { 166 intptr_t* index) {
176 uword start = end - Instr::kInstrSize; 167 uword start = end - Instr::kInstrSize;
177 int32_t instr = Instr::At(start)->InstructionBits(); 168 int32_t instr = Instr::At(start)->InstructionBits();
(...skipping 14 matching lines...) Expand all
192 } else { 183 } else {
193 ASSERT((instr & 0xffff0000) == (0xe0800000 | (PP << 16))); 184 ASSERT((instr & 0xffff0000) == (0xe0800000 | (PP << 16)));
194 // add reg, pp, reg 185 // add reg, pp, reg
195 end = DecodeLoadWordImmediate(end, reg, &offset); 186 end = DecodeLoadWordImmediate(end, reg, &offset);
196 } 187 }
197 } 188 }
198 *index = ObjectPool::IndexFromOffset(offset); 189 *index = ObjectPool::IndexFromOffset(offset);
199 return start; 190 return start;
200 } 191 }
201 192
202
203 bool DecodeLoadObjectFromPoolOrThread(uword pc, const Code& code, Object* obj) { 193 bool DecodeLoadObjectFromPoolOrThread(uword pc, const Code& code, Object* obj) {
204 ASSERT(code.ContainsInstructionAt(pc)); 194 ASSERT(code.ContainsInstructionAt(pc));
205 195
206 int32_t instr = Instr::At(pc)->InstructionBits(); 196 int32_t instr = Instr::At(pc)->InstructionBits();
207 intptr_t offset; 197 intptr_t offset;
208 Register dst; 198 Register dst;
209 if (IsLoadWithOffset(instr, PP, &offset, &dst)) { 199 if (IsLoadWithOffset(instr, PP, &offset, &dst)) {
210 intptr_t index = ObjectPool::IndexFromOffset(offset); 200 intptr_t index = ObjectPool::IndexFromOffset(offset);
211 const ObjectPool& pool = ObjectPool::Handle(code.object_pool()); 201 const ObjectPool& pool = ObjectPool::Handle(code.object_pool());
212 if (pool.InfoAt(index) == ObjectPool::kTaggedObject) { 202 if (pool.InfoAt(index) == ObjectPool::kTaggedObject) {
213 *obj = pool.ObjectAt(index); 203 *obj = pool.ObjectAt(index);
214 return true; 204 return true;
215 } 205 }
216 } else if (IsLoadWithOffset(instr, THR, &offset, &dst)) { 206 } else if (IsLoadWithOffset(instr, THR, &offset, &dst)) {
217 return Thread::ObjectAtOffset(offset, obj); 207 return Thread::ObjectAtOffset(offset, obj);
218 } 208 }
219 // TODO(rmacnak): Sequence for loads beyond 12 bits. 209 // TODO(rmacnak): Sequence for loads beyond 12 bits.
220 210
221 return false; 211 return false;
222 } 212 }
223 213
224
225 RawICData* CallPattern::IcData() { 214 RawICData* CallPattern::IcData() {
226 if (ic_data_.IsNull()) { 215 if (ic_data_.IsNull()) {
227 Register reg; 216 Register reg;
228 InstructionPattern::DecodeLoadObject(ic_data_load_end_, object_pool_, &reg, 217 InstructionPattern::DecodeLoadObject(ic_data_load_end_, object_pool_, &reg,
229 &ic_data_); 218 &ic_data_);
230 ASSERT(reg == R9); 219 ASSERT(reg == R9);
231 } 220 }
232 return ic_data_.raw(); 221 return ic_data_.raw();
233 } 222 }
234 223
235
236 RawCode* CallPattern::TargetCode() const { 224 RawCode* CallPattern::TargetCode() const {
237 return reinterpret_cast<RawCode*>( 225 return reinterpret_cast<RawCode*>(
238 object_pool_.ObjectAt(target_code_pool_index_)); 226 object_pool_.ObjectAt(target_code_pool_index_));
239 } 227 }
240 228
241
242 void CallPattern::SetTargetCode(const Code& target_code) const { 229 void CallPattern::SetTargetCode(const Code& target_code) const {
243 object_pool_.SetObjectAt(target_code_pool_index_, target_code); 230 object_pool_.SetObjectAt(target_code_pool_index_, target_code);
244 } 231 }
245 232
246
247 SwitchableCallPattern::SwitchableCallPattern(uword pc, const Code& code) 233 SwitchableCallPattern::SwitchableCallPattern(uword pc, const Code& code)
248 : object_pool_(ObjectPool::Handle(code.GetObjectPool())), 234 : object_pool_(ObjectPool::Handle(code.GetObjectPool())),
249 data_pool_index_(-1), 235 data_pool_index_(-1),
250 target_pool_index_(-1) { 236 target_pool_index_(-1) {
251 ASSERT(code.ContainsInstructionAt(pc)); 237 ASSERT(code.ContainsInstructionAt(pc));
252 // Last instruction: blx lr. 238 // Last instruction: blx lr.
253 ASSERT(*(reinterpret_cast<uword*>(pc) - 1) == 0xe12fff3e); 239 ASSERT(*(reinterpret_cast<uword*>(pc) - 1) == 0xe12fff3e);
254 240
255 Register reg; 241 Register reg;
256 uword data_load_end = InstructionPattern::DecodeLoadWordFromPool( 242 uword data_load_end = InstructionPattern::DecodeLoadWordFromPool(
257 pc - Instr::kInstrSize, &reg, &data_pool_index_); 243 pc - Instr::kInstrSize, &reg, &data_pool_index_);
258 ASSERT(reg == R9); 244 ASSERT(reg == R9);
259 InstructionPattern::DecodeLoadWordFromPool(data_load_end - Instr::kInstrSize, 245 InstructionPattern::DecodeLoadWordFromPool(data_load_end - Instr::kInstrSize,
260 &reg, &target_pool_index_); 246 &reg, &target_pool_index_);
261 ASSERT(reg == CODE_REG); 247 ASSERT(reg == CODE_REG);
262 } 248 }
263 249
264
265 RawObject* SwitchableCallPattern::data() const { 250 RawObject* SwitchableCallPattern::data() const {
266 return object_pool_.ObjectAt(data_pool_index_); 251 return object_pool_.ObjectAt(data_pool_index_);
267 } 252 }
268 253
269
270 RawCode* SwitchableCallPattern::target() const { 254 RawCode* SwitchableCallPattern::target() const {
271 return reinterpret_cast<RawCode*>(object_pool_.ObjectAt(target_pool_index_)); 255 return reinterpret_cast<RawCode*>(object_pool_.ObjectAt(target_pool_index_));
272 } 256 }
273 257
274
275 void SwitchableCallPattern::SetData(const Object& data) const { 258 void SwitchableCallPattern::SetData(const Object& data) const {
276 ASSERT(!Object::Handle(object_pool_.ObjectAt(data_pool_index_)).IsCode()); 259 ASSERT(!Object::Handle(object_pool_.ObjectAt(data_pool_index_)).IsCode());
277 object_pool_.SetObjectAt(data_pool_index_, data); 260 object_pool_.SetObjectAt(data_pool_index_, data);
278 } 261 }
279 262
280
281 void SwitchableCallPattern::SetTarget(const Code& target) const { 263 void SwitchableCallPattern::SetTarget(const Code& target) const {
282 ASSERT(Object::Handle(object_pool_.ObjectAt(target_pool_index_)).IsCode()); 264 ASSERT(Object::Handle(object_pool_.ObjectAt(target_pool_index_)).IsCode());
283 object_pool_.SetObjectAt(target_pool_index_, target); 265 object_pool_.SetObjectAt(target_pool_index_, target);
284 } 266 }
285 267
286
287 ReturnPattern::ReturnPattern(uword pc) : pc_(pc) {} 268 ReturnPattern::ReturnPattern(uword pc) : pc_(pc) {}
288 269
289
290 bool ReturnPattern::IsValid() const { 270 bool ReturnPattern::IsValid() const {
291 Instr* bx_lr = Instr::At(pc_); 271 Instr* bx_lr = Instr::At(pc_);
292 const int32_t B4 = 1 << 4; 272 const int32_t B4 = 1 << 4;
293 const int32_t B21 = 1 << 21; 273 const int32_t B21 = 1 << 21;
294 const int32_t B24 = 1 << 24; 274 const int32_t B24 = 1 << 24;
295 int32_t instruction = (static_cast<int32_t>(AL) << kConditionShift) | B24 | 275 int32_t instruction = (static_cast<int32_t>(AL) << kConditionShift) | B24 |
296 B21 | (0xfff << 8) | B4 | 276 B21 | (0xfff << 8) | B4 |
297 (static_cast<int32_t>(LR) << kRmShift); 277 (static_cast<int32_t>(LR) << kRmShift);
298 const ARMVersion version = TargetCPUFeatures::arm_version(); 278 const ARMVersion version = TargetCPUFeatures::arm_version();
299 if ((version == ARMv5TE) || (version == ARMv6)) { 279 if ((version == ARMv5TE) || (version == ARMv6)) {
300 return bx_lr->InstructionBits() == instruction; 280 return bx_lr->InstructionBits() == instruction;
301 } else { 281 } else {
302 ASSERT(version == ARMv7); 282 ASSERT(version == ARMv7);
303 return bx_lr->InstructionBits() == instruction; 283 return bx_lr->InstructionBits() == instruction;
304 } 284 }
305 return false; 285 return false;
306 } 286 }
307 287
308 } // namespace dart 288 } // namespace dart
309 289
310 #endif // defined TARGET_ARCH_ARM 290 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/instructions_arm.h ('k') | runtime/vm/instructions_arm64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698