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

Side by Side Diff: runtime/vm/locations.h

Issue 2481873005: clang-format runtime/vm (Closed)
Patch Set: Merge Created 4 years, 1 month 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/libdart_dependency_helper.cc ('k') | runtime/vm/locations.cc » ('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 #ifndef RUNTIME_VM_LOCATIONS_H_ 5 #ifndef RUNTIME_VM_LOCATIONS_H_
6 #define RUNTIME_VM_LOCATIONS_H_ 6 #define RUNTIME_VM_LOCATIONS_H_
7 7
8 #include "vm/allocation.h" 8 #include "vm/allocation.h"
9 #include "vm/assembler.h" 9 #include "vm/assembler.h"
10 #include "vm/bitfield.h" 10 #include "vm/bitfield.h"
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 kPairLocationTag = 2, 80 kPairLocationTag = 2,
81 81
82 // Unallocated location represents a location that is not fixed and can be 82 // Unallocated location represents a location that is not fixed and can be
83 // allocated by a register allocator. Each unallocated location has 83 // allocated by a register allocator. Each unallocated location has
84 // a policy that specifies what kind of location is suitable. Payload 84 // a policy that specifies what kind of location is suitable. Payload
85 // contains register allocation policy. 85 // contains register allocation policy.
86 kUnallocated = 3, 86 kUnallocated = 3,
87 87
88 // Spill slots allocated by the register allocator. Payload contains 88 // Spill slots allocated by the register allocator. Payload contains
89 // a spill index. 89 // a spill index.
90 kStackSlot = 4, // Word size slot. 90 kStackSlot = 4, // Word size slot.
91 kDoubleStackSlot = 7, // 64bit stack slot. 91 kDoubleStackSlot = 7, // 64bit stack slot.
92 kQuadStackSlot = 11, // 128bit stack slot. 92 kQuadStackSlot = 11, // 128bit stack slot.
93 93
94 // Register location represents a fixed register. Payload contains 94 // Register location represents a fixed register. Payload contains
95 // register code. 95 // register code.
96 kRegister = 8, 96 kRegister = 8,
97 97
98 // FpuRegister location represents a fixed fpu register. Payload contains 98 // FpuRegister location represents a fixed fpu register. Payload contains
99 // its code. 99 // its code.
100 kFpuRegister = 12, 100 kFpuRegister = 12,
101 }; 101 };
102 102
(...skipping 22 matching lines...) Expand all
125 COMPILE_ASSERT((kFpuRegister & kLocationTagMask) != kPairLocationTag); 125 COMPILE_ASSERT((kFpuRegister & kLocationTagMask) != kPairLocationTag);
126 126
127 // Verify tags and tagmask. 127 // Verify tags and tagmask.
128 COMPILE_ASSERT((kConstantTag & kLocationTagMask) == kConstantTag); 128 COMPILE_ASSERT((kConstantTag & kLocationTagMask) == kConstantTag);
129 129
130 COMPILE_ASSERT((kPairLocationTag & kLocationTagMask) == kPairLocationTag); 130 COMPILE_ASSERT((kPairLocationTag & kLocationTagMask) == kPairLocationTag);
131 131
132 ASSERT(IsInvalid()); 132 ASSERT(IsInvalid());
133 } 133 }
134 134
135 Location(const Location& other) : ValueObject(), value_(other.value_) { } 135 Location(const Location& other) : ValueObject(), value_(other.value_) {}
136 136
137 Location& operator=(const Location& other) { 137 Location& operator=(const Location& other) {
138 value_ = other.value_; 138 value_ = other.value_;
139 return *this; 139 return *this;
140 } 140 }
141 141
142 bool IsInvalid() const { 142 bool IsInvalid() const { return value_ == kInvalidLocation; }
143 return value_ == kInvalidLocation;
144 }
145 143
146 // Constants. 144 // Constants.
147 bool IsConstant() const { 145 bool IsConstant() const {
148 return (value_ & kLocationTagMask) == kConstantTag; 146 return (value_ & kLocationTagMask) == kConstantTag;
149 } 147 }
150 148
151 static Location Constant(const ConstantInstr* obj) { 149 static Location Constant(const ConstantInstr* obj) {
152 Location loc(reinterpret_cast<uword>(obj) | kConstantTag); 150 Location loc(reinterpret_cast<uword>(obj) | kConstantTag);
153 ASSERT(obj == loc.constant_instruction()); 151 ASSERT(obj == loc.constant_instruction());
154 return loc; 152 return loc;
(...skipping 17 matching lines...) Expand all
172 // Unallocated locations. 170 // Unallocated locations.
173 enum Policy { 171 enum Policy {
174 kAny, 172 kAny,
175 kPrefersRegister, 173 kPrefersRegister,
176 kRequiresRegister, 174 kRequiresRegister,
177 kRequiresFpuRegister, 175 kRequiresFpuRegister,
178 kWritableRegister, 176 kWritableRegister,
179 kSameAsFirstInput, 177 kSameAsFirstInput,
180 }; 178 };
181 179
182 bool IsUnallocated() const { 180 bool IsUnallocated() const { return kind() == kUnallocated; }
183 return kind() == kUnallocated;
184 }
185 181
186 bool IsRegisterBeneficial() { 182 bool IsRegisterBeneficial() { return !Equals(Any()); }
187 return !Equals(Any());
188 }
189 183
190 static Location UnallocatedLocation(Policy policy) { 184 static Location UnallocatedLocation(Policy policy) {
191 return Location(kUnallocated, PolicyField::encode(policy)); 185 return Location(kUnallocated, PolicyField::encode(policy));
192 } 186 }
193 187
194 // Any free register is suitable to replace this unallocated location. 188 // Any free register is suitable to replace this unallocated location.
195 static Location Any() { 189 static Location Any() { return UnallocatedLocation(kAny); }
196 return UnallocatedLocation(kAny);
197 }
198 190
199 static Location PrefersRegister() { 191 static Location PrefersRegister() {
200 return UnallocatedLocation(kPrefersRegister); 192 return UnallocatedLocation(kPrefersRegister);
201 } 193 }
202 194
203 static Location RequiresRegister() { 195 static Location RequiresRegister() {
204 return UnallocatedLocation(kRequiresRegister); 196 return UnallocatedLocation(kRequiresRegister);
205 } 197 }
206 198
207 static Location RequiresFpuRegister() { 199 static Location RequiresFpuRegister() {
208 return UnallocatedLocation(kRequiresFpuRegister); 200 return UnallocatedLocation(kRequiresFpuRegister);
209 } 201 }
210 202
211 static Location WritableRegister() { 203 static Location WritableRegister() {
212 return UnallocatedLocation(kWritableRegister); 204 return UnallocatedLocation(kWritableRegister);
213 } 205 }
214 206
215 // The location of the first input to the instruction will be 207 // The location of the first input to the instruction will be
216 // used to replace this unallocated location. 208 // used to replace this unallocated location.
217 static Location SameAsFirstInput() { 209 static Location SameAsFirstInput() {
218 return UnallocatedLocation(kSameAsFirstInput); 210 return UnallocatedLocation(kSameAsFirstInput);
219 } 211 }
220 212
221 // Empty location. Used if there the location should be ignored. 213 // Empty location. Used if there the location should be ignored.
222 static Location NoLocation() { 214 static Location NoLocation() { return Location(); }
223 return Location();
224 }
225 215
226 Policy policy() const { 216 Policy policy() const {
227 ASSERT(IsUnallocated()); 217 ASSERT(IsUnallocated());
228 return PolicyField::decode(payload()); 218 return PolicyField::decode(payload());
229 } 219 }
230 220
231 // Register locations. 221 // Register locations.
232 static Location RegisterLocation(Register reg) { 222 static Location RegisterLocation(Register reg) {
233 return Location(kRegister, reg); 223 return Location(kRegister, reg);
234 } 224 }
235 225
236 bool IsRegister() const { 226 bool IsRegister() const { return kind() == kRegister; }
237 return kind() == kRegister;
238 }
239 227
240 Register reg() const { 228 Register reg() const {
241 ASSERT(IsRegister()); 229 ASSERT(IsRegister());
242 return static_cast<Register>(payload()); 230 return static_cast<Register>(payload());
243 } 231 }
244 232
245 // FpuRegister locations. 233 // FpuRegister locations.
246 static Location FpuRegisterLocation(FpuRegister reg) { 234 static Location FpuRegisterLocation(FpuRegister reg) {
247 return Location(kFpuRegister, reg); 235 return Location(kFpuRegister, reg);
248 } 236 }
249 237
250 bool IsFpuRegister() const { 238 bool IsFpuRegister() const { return kind() == kFpuRegister; }
251 return kind() == kFpuRegister;
252 }
253 239
254 FpuRegister fpu_reg() const { 240 FpuRegister fpu_reg() const {
255 ASSERT(IsFpuRegister()); 241 ASSERT(IsFpuRegister());
256 return static_cast<FpuRegister>(payload()); 242 return static_cast<FpuRegister>(payload());
257 } 243 }
258 244
259 static bool IsMachineRegisterKind(Kind kind) { 245 static bool IsMachineRegisterKind(Kind kind) {
260 return (kind == kRegister) || (kind == kFpuRegister); 246 return (kind == kRegister) || (kind == kFpuRegister);
261 } 247 }
262 248
263 static Location MachineRegisterLocation(Kind kind, 249 static Location MachineRegisterLocation(Kind kind, intptr_t reg) {
264 intptr_t reg) {
265 if (kind == kRegister) { 250 if (kind == kRegister) {
266 return RegisterLocation(static_cast<Register>(reg)); 251 return RegisterLocation(static_cast<Register>(reg));
267 } else { 252 } else {
268 ASSERT(kind == kFpuRegister); 253 ASSERT(kind == kFpuRegister);
269 return FpuRegisterLocation(static_cast<FpuRegister>(reg)); 254 return FpuRegisterLocation(static_cast<FpuRegister>(reg));
270 } 255 }
271 } 256 }
272 257
273 bool IsMachineRegister() const { 258 bool IsMachineRegister() const { return IsMachineRegisterKind(kind()); }
274 return IsMachineRegisterKind(kind());
275 }
276 259
277 intptr_t register_code() const { 260 intptr_t register_code() const {
278 ASSERT(IsMachineRegister()); 261 ASSERT(IsMachineRegister());
279 return static_cast<intptr_t>(payload()); 262 return static_cast<intptr_t>(payload());
280 } 263 }
281 264
282 static uword EncodeStackIndex(intptr_t stack_index) { 265 static uword EncodeStackIndex(intptr_t stack_index) {
283 ASSERT((-kStackIndexBias <= stack_index) && 266 ASSERT((-kStackIndexBias <= stack_index) &&
284 (stack_index < kStackIndexBias)); 267 (stack_index < kStackIndexBias));
285 return static_cast<uword>(kStackIndexBias + stack_index); 268 return static_cast<uword>(kStackIndexBias + stack_index);
286 } 269 }
287 270
288 // Spill slots. 271 // Spill slots.
289 static Location StackSlot(intptr_t stack_index, 272 static Location StackSlot(intptr_t stack_index, Register base = FPREG) {
290 Register base = FPREG) { 273 uword payload = StackSlotBaseField::encode(base) |
291 uword payload = StackSlotBaseField::encode(base) 274 StackIndexField::encode(EncodeStackIndex(stack_index));
292 | StackIndexField::encode(EncodeStackIndex(stack_index));
293 Location loc(kStackSlot, payload); 275 Location loc(kStackSlot, payload);
294 // Ensure that sign is preserved. 276 // Ensure that sign is preserved.
295 ASSERT(loc.stack_index() == stack_index); 277 ASSERT(loc.stack_index() == stack_index);
296 return loc; 278 return loc;
297 } 279 }
298 280
299 bool IsStackSlot() const { 281 bool IsStackSlot() const { return kind() == kStackSlot; }
300 return kind() == kStackSlot;
301 }
302 282
303 static Location DoubleStackSlot(intptr_t stack_index) { 283 static Location DoubleStackSlot(intptr_t stack_index) {
304 uword payload = StackSlotBaseField::encode(FPREG) 284 uword payload = StackSlotBaseField::encode(FPREG) |
305 | StackIndexField::encode(EncodeStackIndex(stack_index)); 285 StackIndexField::encode(EncodeStackIndex(stack_index));
306 Location loc(kDoubleStackSlot, payload); 286 Location loc(kDoubleStackSlot, payload);
307 // Ensure that sign is preserved. 287 // Ensure that sign is preserved.
308 ASSERT(loc.stack_index() == stack_index); 288 ASSERT(loc.stack_index() == stack_index);
309 return loc; 289 return loc;
310 } 290 }
311 291
312 bool IsDoubleStackSlot() const { 292 bool IsDoubleStackSlot() const { return kind() == kDoubleStackSlot; }
313 return kind() == kDoubleStackSlot;
314 }
315 293
316 static Location QuadStackSlot(intptr_t stack_index) { 294 static Location QuadStackSlot(intptr_t stack_index) {
317 uword payload = StackSlotBaseField::encode(FPREG) 295 uword payload = StackSlotBaseField::encode(FPREG) |
318 | StackIndexField::encode(EncodeStackIndex(stack_index)); 296 StackIndexField::encode(EncodeStackIndex(stack_index));
319 Location loc(kQuadStackSlot, payload); 297 Location loc(kQuadStackSlot, payload);
320 // Ensure that sign is preserved. 298 // Ensure that sign is preserved.
321 ASSERT(loc.stack_index() == stack_index); 299 ASSERT(loc.stack_index() == stack_index);
322 return loc; 300 return loc;
323 } 301 }
324 302
325 bool IsQuadStackSlot() const { 303 bool IsQuadStackSlot() const { return kind() == kQuadStackSlot; }
326 return kind() == kQuadStackSlot;
327 }
328 304
329 Register base_reg() const { 305 Register base_reg() const {
330 ASSERT(HasStackIndex()); 306 ASSERT(HasStackIndex());
331 return StackSlotBaseField::decode(payload()); 307 return StackSlotBaseField::decode(payload());
332 } 308 }
333 309
334 intptr_t stack_index() const { 310 intptr_t stack_index() const {
335 ASSERT(HasStackIndex()); 311 ASSERT(HasStackIndex());
336 // Decode stack index manually to preserve sign. 312 // Decode stack index manually to preserve sign.
337 return StackIndexField::decode(payload()) - kStackIndexBias; 313 return StackIndexField::decode(payload()) - kStackIndexBias;
338 } 314 }
339 315
340 bool HasStackIndex() const { 316 bool HasStackIndex() const {
341 return IsStackSlot() || IsDoubleStackSlot() || IsQuadStackSlot(); 317 return IsStackSlot() || IsDoubleStackSlot() || IsQuadStackSlot();
342 } 318 }
343 319
344 // DBC does not have an notion of 'address' in its instruction set. 320 // DBC does not have an notion of 'address' in its instruction set.
345 #if !defined(TARGET_ARCH_DBC) 321 #if !defined(TARGET_ARCH_DBC)
346 // Return a memory operand for stack slot locations. 322 // Return a memory operand for stack slot locations.
347 Address ToStackSlotAddress() const; 323 Address ToStackSlotAddress() const;
348 #endif 324 #endif
349 325
350 // Returns the offset from the frame pointer for stack slot locations. 326 // Returns the offset from the frame pointer for stack slot locations.
351 intptr_t ToStackSlotOffset() const; 327 intptr_t ToStackSlotOffset() const;
352 328
353 // Constants. 329 // Constants.
354 static Location RegisterOrConstant(Value* value); 330 static Location RegisterOrConstant(Value* value);
355 static Location RegisterOrSmiConstant(Value* value); 331 static Location RegisterOrSmiConstant(Value* value);
356 static Location WritableRegisterOrSmiConstant(Value* value); 332 static Location WritableRegisterOrSmiConstant(Value* value);
357 static Location FixedRegisterOrConstant(Value* value, Register reg); 333 static Location FixedRegisterOrConstant(Value* value, Register reg);
358 static Location FixedRegisterOrSmiConstant(Value* value, Register reg); 334 static Location FixedRegisterOrSmiConstant(Value* value, Register reg);
359 static Location AnyOrConstant(Value* value); 335 static Location AnyOrConstant(Value* value);
360 336
361 const char* Name() const; 337 const char* Name() const;
362 void PrintTo(BufferFormatter* f) const; 338 void PrintTo(BufferFormatter* f) const;
363 void Print() const; 339 void Print() const;
364 const char* ToCString() const; 340 const char* ToCString() const;
365 341
366 // Compare two locations. 342 // Compare two locations.
367 bool Equals(Location other) const { 343 bool Equals(Location other) const { return value_ == other.value_; }
368 return value_ == other.value_;
369 }
370 344
371 // If current location is constant might return something that 345 // If current location is constant might return something that
372 // is not equal to any Kind. 346 // is not equal to any Kind.
373 Kind kind() const { 347 Kind kind() const { return KindField::decode(value_); }
374 return KindField::decode(value_);
375 }
376 348
377 Location Copy() const; 349 Location Copy() const;
378 350
379 Location RemapForSlowPath(Definition* def, 351 Location RemapForSlowPath(Definition* def,
380 intptr_t* cpu_reg_slots, 352 intptr_t* cpu_reg_slots,
381 intptr_t* fpu_reg_slots) const; 353 intptr_t* fpu_reg_slots) const;
382 354
383 private: 355 private:
384 explicit Location(uword value) : value_(value) { } 356 explicit Location(uword value) : value_(value) {}
385 357
386 Location(Kind kind, uword payload) 358 Location(Kind kind, uword payload)
387 : value_(KindField::encode(kind) | PayloadField::encode(payload)) { } 359 : value_(KindField::encode(kind) | PayloadField::encode(payload)) {}
388 360
389 uword payload() const { 361 uword payload() const { return PayloadField::decode(value_); }
390 return PayloadField::decode(value_);
391 }
392 362
393 class KindField : public BitField<uword, Kind, 0, kBitsForKind> {}; 363 class KindField : public BitField<uword, Kind, 0, kBitsForKind> {};
394 class PayloadField : 364 class PayloadField
395 public BitField<uword, uword, kBitsForKind, kBitsForPayload> {}; 365 : public BitField<uword, uword, kBitsForKind, kBitsForPayload> {};
396 366
397 // Layout for kUnallocated locations payload. 367 // Layout for kUnallocated locations payload.
398 typedef BitField<uword, Policy, 0, 3> PolicyField; 368 typedef BitField<uword, Policy, 0, 3> PolicyField;
399 369
400 // Layout for stack slots. 370 // Layout for stack slots.
401 #if defined(ARCH_IS_64_BIT) 371 #if defined(ARCH_IS_64_BIT)
402 static const intptr_t kBitsForBaseReg = 6; 372 static const intptr_t kBitsForBaseReg = 6;
403 #else 373 #else
404 static const intptr_t kBitsForBaseReg = 5; 374 static const intptr_t kBitsForBaseReg = 5;
405 #endif 375 #endif
406 static const intptr_t kBitsForStackIndex = kBitsForPayload - kBitsForBaseReg; 376 static const intptr_t kBitsForStackIndex = kBitsForPayload - kBitsForBaseReg;
407 class StackSlotBaseField : 377 class StackSlotBaseField
408 public BitField<uword, Register, 0, kBitsForBaseReg> {}; 378 : public BitField<uword, Register, 0, kBitsForBaseReg> {};
409 class StackIndexField : 379 class StackIndexField
410 public BitField<uword, intptr_t, kBitsForBaseReg, kBitsForStackIndex> {}; 380 : public BitField<uword, intptr_t, kBitsForBaseReg, kBitsForStackIndex> {
381 };
411 COMPILE_ASSERT(1 << kBitsForBaseReg >= kNumberOfCpuRegisters); 382 COMPILE_ASSERT(1 << kBitsForBaseReg >= kNumberOfCpuRegisters);
412 383
413 static const intptr_t kStackIndexBias = 384 static const intptr_t kStackIndexBias = static_cast<intptr_t>(1)
414 static_cast<intptr_t>(1) << (kBitsForStackIndex - 1); 385 << (kBitsForStackIndex - 1);
415 386
416 // Location either contains kind and payload fields or a tagged handle for 387 // Location either contains kind and payload fields or a tagged handle for
417 // a constant locations. Values of enumeration Kind are selected in such a 388 // a constant locations. Values of enumeration Kind are selected in such a
418 // way that none of them can be interpreted as a kConstant tag. 389 // way that none of them can be interpreted as a kConstant tag.
419 uword value_; 390 uword value_;
420 }; 391 };
421 392
422 393
423 class PairLocation : public ZoneAllocated { 394 class PairLocation : public ZoneAllocated {
424 public: 395 public:
(...skipping 22 matching lines...) Expand all
447 ASSERT(i < kPairLength); 418 ASSERT(i < kPairLength);
448 return &locations_[i]; 419 return &locations_[i];
449 } 420 }
450 421
451 private: 422 private:
452 static const intptr_t kPairLength = 2; 423 static const intptr_t kPairLength = 2;
453 Location locations_[kPairLength]; 424 Location locations_[kPairLength];
454 }; 425 };
455 426
456 427
457 template<typename T> 428 template <typename T>
458 class SmallSet { 429 class SmallSet {
459 public: 430 public:
460 SmallSet() : data_(0) { } 431 SmallSet() : data_(0) {}
461 432
462 explicit SmallSet(intptr_t data) : data_(data) { } 433 explicit SmallSet(intptr_t data) : data_(data) {}
463 434
464 bool Contains(T value) const { return (data_ & ToMask(value)) != 0; } 435 bool Contains(T value) const { return (data_ & ToMask(value)) != 0; }
465 436
466 void Add(T value) { data_ |= ToMask(value); } 437 void Add(T value) { data_ |= ToMask(value); }
467 438
468 void Remove(T value) { data_ &= ~ToMask(value); } 439 void Remove(T value) { data_ &= ~ToMask(value); }
469 440
470 bool IsEmpty() const { return data_ == 0; } 441 bool IsEmpty() const { return data_ == 0; }
471 442
472 intptr_t data() const { return data_; } 443 intptr_t data() const { return data_; }
473 444
474 private: 445 private:
475 static intptr_t ToMask(T value) { 446 static intptr_t ToMask(T value) {
476 ASSERT(static_cast<intptr_t>(value) < (kWordSize * kBitsPerByte)); 447 ASSERT(static_cast<intptr_t>(value) < (kWordSize * kBitsPerByte));
477 return 1 << static_cast<intptr_t>(value); 448 return 1 << static_cast<intptr_t>(value);
478 } 449 }
479 450
480 intptr_t data_; 451 intptr_t data_;
481 }; 452 };
482 453
483 454
484 class RegisterSet : public ValueObject { 455 class RegisterSet : public ValueObject {
485 public: 456 public:
486 RegisterSet() 457 RegisterSet()
487 : cpu_registers_(), 458 : cpu_registers_(), untagged_cpu_registers_(), fpu_registers_() {
488 untagged_cpu_registers_(),
489 fpu_registers_() {
490 ASSERT(kNumberOfCpuRegisters <= (kWordSize * kBitsPerByte)); 459 ASSERT(kNumberOfCpuRegisters <= (kWordSize * kBitsPerByte));
491 ASSERT(kNumberOfFpuRegisters <= (kWordSize * kBitsPerByte)); 460 ASSERT(kNumberOfFpuRegisters <= (kWordSize * kBitsPerByte));
492 } 461 }
493 462
494 463
495 void Add(Location loc, Representation rep = kTagged) { 464 void Add(Location loc, Representation rep = kTagged) {
496 if (loc.IsRegister()) { 465 if (loc.IsRegister()) {
497 cpu_registers_.Add(loc.reg()); 466 cpu_registers_.Add(loc.reg());
498 if (rep != kTagged) { 467 if (rep != kTagged) {
499 // CPU register contains an untagged value. 468 // CPU register contains an untagged value.
(...skipping 21 matching lines...) Expand all
521 UNREACHABLE(); 490 UNREACHABLE();
522 return false; 491 return false;
523 } 492 }
524 } 493 }
525 494
526 void DebugPrint() { 495 void DebugPrint() {
527 for (intptr_t i = 0; i < kNumberOfCpuRegisters; i++) { 496 for (intptr_t i = 0; i < kNumberOfCpuRegisters; i++) {
528 Register r = static_cast<Register>(i); 497 Register r = static_cast<Register>(i);
529 if (ContainsRegister(r)) { 498 if (ContainsRegister(r)) {
530 THR_Print("%s %s\n", Assembler::RegisterName(r), 499 THR_Print("%s %s\n", Assembler::RegisterName(r),
531 IsTagged(r) ? "tagged" : "untagged"); 500 IsTagged(r) ? "tagged" : "untagged");
532 } 501 }
533 } 502 }
534 503
535 for (intptr_t i = 0; i < kNumberOfFpuRegisters; i++) { 504 for (intptr_t i = 0; i < kNumberOfFpuRegisters; i++) {
536 FpuRegister r = static_cast<FpuRegister>(i); 505 FpuRegister r = static_cast<FpuRegister>(i);
537 if (ContainsFpuRegister(r)) { 506 if (ContainsFpuRegister(r)) {
538 THR_Print("%s\n", Assembler::FpuRegisterName(r)); 507 THR_Print("%s\n", Assembler::FpuRegisterName(r));
539 } 508 }
540 } 509 }
541 } 510 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
577 SmallSet<Register> untagged_cpu_registers_; 546 SmallSet<Register> untagged_cpu_registers_;
578 SmallSet<FpuRegister> fpu_registers_; 547 SmallSet<FpuRegister> fpu_registers_;
579 548
580 DISALLOW_COPY_AND_ASSIGN(RegisterSet); 549 DISALLOW_COPY_AND_ASSIGN(RegisterSet);
581 }; 550 };
582 551
583 552
584 // Specification of locations for inputs and output. 553 // Specification of locations for inputs and output.
585 class LocationSummary : public ZoneAllocated { 554 class LocationSummary : public ZoneAllocated {
586 public: 555 public:
587 enum ContainsCall { 556 enum ContainsCall { kNoCall, kCall, kCallOnSlowPath };
588 kNoCall,
589 kCall,
590 kCallOnSlowPath
591 };
592 557
593 LocationSummary(Zone* zone, 558 LocationSummary(Zone* zone,
594 intptr_t input_count, 559 intptr_t input_count,
595 intptr_t temp_count, 560 intptr_t temp_count,
596 LocationSummary::ContainsCall contains_call); 561 LocationSummary::ContainsCall contains_call);
597 562
598 intptr_t input_count() const { 563 intptr_t input_count() const { return num_inputs_; }
599 return num_inputs_;
600 }
601 564
602 Location in(intptr_t index) const { 565 Location in(intptr_t index) const {
603 ASSERT(index >= 0); 566 ASSERT(index >= 0);
604 ASSERT(index < num_inputs_); 567 ASSERT(index < num_inputs_);
605 return input_locations_[index]; 568 return input_locations_[index];
606 } 569 }
607 570
608 Location* in_slot(intptr_t index) { 571 Location* in_slot(intptr_t index) {
609 ASSERT(index >= 0); 572 ASSERT(index >= 0);
610 ASSERT(index < num_inputs_); 573 ASSERT(index < num_inputs_);
611 return &input_locations_[index]; 574 return &input_locations_[index];
612 } 575 }
613 576
614 void set_in(intptr_t index, Location loc) { 577 void set_in(intptr_t index, Location loc) {
615 ASSERT(index >= 0); 578 ASSERT(index >= 0);
616 ASSERT(index < num_inputs_); 579 ASSERT(index < num_inputs_);
617 ASSERT(!always_calls() || loc.IsMachineRegister()); 580 ASSERT(!always_calls() || loc.IsMachineRegister());
618 input_locations_[index] = loc; 581 input_locations_[index] = loc;
619 } 582 }
620 583
621 intptr_t temp_count() const { 584 intptr_t temp_count() const { return num_temps_; }
622 return num_temps_;
623 }
624 585
625 Location temp(intptr_t index) const { 586 Location temp(intptr_t index) const {
626 ASSERT(index >= 0); 587 ASSERT(index >= 0);
627 ASSERT(index < num_temps_); 588 ASSERT(index < num_temps_);
628 return temp_locations_[index]; 589 return temp_locations_[index];
629 } 590 }
630 591
631 Location* temp_slot(intptr_t index) { 592 Location* temp_slot(intptr_t index) {
632 ASSERT(index >= 0); 593 ASSERT(index >= 0);
633 ASSERT(index < num_temps_); 594 ASSERT(index < num_temps_);
634 return &temp_locations_[index]; 595 return &temp_locations_[index];
635 } 596 }
636 597
637 void set_temp(intptr_t index, Location loc) { 598 void set_temp(intptr_t index, Location loc) {
638 ASSERT(index >= 0); 599 ASSERT(index >= 0);
639 ASSERT(index < num_temps_); 600 ASSERT(index < num_temps_);
640 ASSERT(!always_calls() || loc.IsMachineRegister()); 601 ASSERT(!always_calls() || loc.IsMachineRegister());
641 temp_locations_[index] = loc; 602 temp_locations_[index] = loc;
642 } 603 }
643 604
644 intptr_t output_count() const { 605 intptr_t output_count() const { return 1; }
645 return 1;
646 }
647 606
648 Location out(intptr_t index) const { 607 Location out(intptr_t index) const {
649 ASSERT(index == 0); 608 ASSERT(index == 0);
650 return output_location_; 609 return output_location_;
651 } 610 }
652 611
653 Location* out_slot(intptr_t index) { 612 Location* out_slot(intptr_t index) {
654 ASSERT(index == 0); 613 ASSERT(index == 0);
655 return &output_location_; 614 return &output_location_;
656 } 615 }
657 616
658 void set_out(intptr_t index, Location loc) { 617 void set_out(intptr_t index, Location loc) {
659 ASSERT(index == 0); 618 ASSERT(index == 0);
660 // DBC calls are different from call on other architectures so this 619 // DBC calls are different from call on other architectures so this
661 // assert doesn't make sense. 620 // assert doesn't make sense.
662 #if !defined(TARGET_ARCH_DBC) 621 #if !defined(TARGET_ARCH_DBC)
663 ASSERT(!always_calls() || 622 ASSERT(!always_calls() || (loc.IsMachineRegister() || loc.IsInvalid() ||
664 (loc.IsMachineRegister() || loc.IsInvalid() || 623 loc.IsPairLocation()));
665 loc.IsPairLocation()));
666 #endif 624 #endif
667 output_location_ = loc; 625 output_location_ = loc;
668 } 626 }
669 627
670 BitmapBuilder* stack_bitmap() { 628 BitmapBuilder* stack_bitmap() {
671 if (stack_bitmap_ == NULL) { 629 if (stack_bitmap_ == NULL) {
672 stack_bitmap_ = new BitmapBuilder(); 630 stack_bitmap_ = new BitmapBuilder();
673 } 631 }
674 return stack_bitmap_; 632 return stack_bitmap_;
675 } 633 }
676 void SetStackBit(intptr_t index) { 634 void SetStackBit(intptr_t index) { stack_bitmap()->Set(index, true); }
677 stack_bitmap()->Set(index, true);
678 }
679 635
680 bool always_calls() const { 636 bool always_calls() const { return contains_call_ == kCall; }
681 return contains_call_ == kCall;
682 }
683 637
684 bool can_call() { 638 bool can_call() { return contains_call_ != kNoCall; }
685 return contains_call_ != kNoCall;
686 }
687 639
688 bool HasCallOnSlowPath() { 640 bool HasCallOnSlowPath() { return can_call() && !always_calls(); }
689 return can_call() && !always_calls();
690 }
691 641
692 void PrintTo(BufferFormatter* f) const; 642 void PrintTo(BufferFormatter* f) const;
693 643
694 static LocationSummary* Make(Zone* zone, 644 static LocationSummary* Make(Zone* zone,
695 intptr_t input_count, 645 intptr_t input_count,
696 Location out, 646 Location out,
697 ContainsCall contains_call); 647 ContainsCall contains_call);
698 648
699 RegisterSet* live_registers() { 649 RegisterSet* live_registers() { return &live_registers_; }
700 return &live_registers_;
701 }
702 650
703 #if defined(DEBUG) 651 #if defined(DEBUG)
704 // Debug only verification that ensures that writable registers are correctly 652 // Debug only verification that ensures that writable registers are correctly
705 // preserved on the slow path. 653 // preserved on the slow path.
706 void DiscoverWritableInputs(); 654 void DiscoverWritableInputs();
707 void CheckWritableInputs(); 655 void CheckWritableInputs();
708 #endif 656 #endif
709 657
710 private: 658 private:
711 const intptr_t num_inputs_; 659 const intptr_t num_inputs_;
712 Location* input_locations_; 660 Location* input_locations_;
713 const intptr_t num_temps_; 661 const intptr_t num_temps_;
714 Location* temp_locations_; 662 Location* temp_locations_;
715 Location output_location_; 663 Location output_location_;
716 664
717 BitmapBuilder* stack_bitmap_; 665 BitmapBuilder* stack_bitmap_;
718 666
719 const ContainsCall contains_call_; 667 const ContainsCall contains_call_;
720 RegisterSet live_registers_; 668 RegisterSet live_registers_;
721 669
722 #if defined(DEBUG) 670 #if defined(DEBUG)
723 intptr_t writable_inputs_; 671 intptr_t writable_inputs_;
724 #endif 672 #endif
725 }; 673 };
726 674
727 675
728 } // namespace dart 676 } // namespace dart
729 677
730 #endif // RUNTIME_VM_LOCATIONS_H_ 678 #endif // RUNTIME_VM_LOCATIONS_H_
OLDNEW
« no previous file with comments | « runtime/vm/libdart_dependency_helper.cc ('k') | runtime/vm/locations.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698