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 #ifndef VM_LOCATIONS_H_ | 5 #ifndef VM_LOCATIONS_H_ |
6 #define VM_LOCATIONS_H_ | 6 #define 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 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
358 bool Equals(Location other) const { | 358 bool Equals(Location other) const { |
359 return value_ == other.value_; | 359 return value_ == other.value_; |
360 } | 360 } |
361 | 361 |
362 // If current location is constant might return something that | 362 // If current location is constant might return something that |
363 // is not equal to any Kind. | 363 // is not equal to any Kind. |
364 Kind kind() const { | 364 Kind kind() const { |
365 return KindField::decode(value_); | 365 return KindField::decode(value_); |
366 } | 366 } |
367 | 367 |
| 368 Location Copy() const; |
| 369 |
368 private: | 370 private: |
369 explicit Location(uword value) : value_(value) { } | 371 explicit Location(uword value) : value_(value) { } |
370 | 372 |
371 Location(Kind kind, uword payload) | 373 Location(Kind kind, uword payload) |
372 : value_(KindField::encode(kind) | PayloadField::encode(payload)) { } | 374 : value_(KindField::encode(kind) | PayloadField::encode(payload)) { } |
373 | 375 |
374 uword payload() const { | 376 uword payload() const { |
375 return PayloadField::decode(value_); | 377 return PayloadField::decode(value_); |
376 } | 378 } |
377 | 379 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
421 } | 423 } |
422 | 424 |
423 private: | 425 private: |
424 static const intptr_t kPairLength = 2; | 426 static const intptr_t kPairLength = 2; |
425 Location locations_[kPairLength]; | 427 Location locations_[kPairLength]; |
426 }; | 428 }; |
427 | 429 |
428 | 430 |
429 class RegisterSet : public ValueObject { | 431 class RegisterSet : public ValueObject { |
430 public: | 432 public: |
431 RegisterSet() : cpu_registers_(0), fpu_registers_(0) { | 433 RegisterSet() : cpu_registers_(0), untagged_cpu_registers_(0), |
| 434 fpu_registers_(0) { |
432 ASSERT(kNumberOfCpuRegisters <= (kWordSize * kBitsPerByte)); | 435 ASSERT(kNumberOfCpuRegisters <= (kWordSize * kBitsPerByte)); |
433 ASSERT(kNumberOfFpuRegisters <= (kWordSize * kBitsPerByte)); | 436 ASSERT(kNumberOfFpuRegisters <= (kWordSize * kBitsPerByte)); |
434 } | 437 } |
435 | 438 |
436 | 439 |
437 void Add(Location loc) { | 440 void Add(Location loc, Representation rep = kTagged) { |
438 if (loc.IsRegister()) { | 441 if (loc.IsRegister()) { |
439 cpu_registers_ |= (1 << loc.reg()); | 442 cpu_registers_ |= (1 << loc.reg()); |
| 443 if (rep != kTagged) { |
| 444 // CPU register contains an untagged value. |
| 445 MarkUntagged(loc); |
| 446 } |
440 } else if (loc.IsFpuRegister()) { | 447 } else if (loc.IsFpuRegister()) { |
441 fpu_registers_ |= (1 << loc.fpu_reg()); | 448 fpu_registers_ |= (1 << loc.fpu_reg()); |
442 } | 449 } |
443 } | 450 } |
444 | 451 |
445 void Remove(Location loc) { | 452 void Remove(Location loc) { |
446 if (loc.IsRegister()) { | 453 if (loc.IsRegister()) { |
447 cpu_registers_ &= ~(1 << loc.reg()); | 454 cpu_registers_ &= ~(1 << loc.reg()); |
448 } else if (loc.IsFpuRegister()) { | 455 } else if (loc.IsFpuRegister()) { |
449 fpu_registers_ &= ~(1 << loc.fpu_reg()); | 456 fpu_registers_ &= ~(1 << loc.fpu_reg()); |
450 } | 457 } |
451 } | 458 } |
452 | 459 |
| 460 void MarkUntagged(Location loc) { |
| 461 ASSERT(loc.IsRegister()); |
| 462 untagged_cpu_registers_ |= (1 << loc.reg()); |
| 463 } |
| 464 |
| 465 bool IsTagged(Register reg) const { |
| 466 return (untagged_cpu_registers_ & (1 << reg)) == 0; |
| 467 } |
| 468 |
453 bool ContainsRegister(Register reg) const { | 469 bool ContainsRegister(Register reg) const { |
454 return (cpu_registers_ & (1 << reg)) != 0; | 470 return (cpu_registers_ & (1 << reg)) != 0; |
455 } | 471 } |
456 | 472 |
457 bool ContainsFpuRegister(FpuRegister fpu_reg) const { | 473 bool ContainsFpuRegister(FpuRegister fpu_reg) const { |
458 return (fpu_registers_ & (1 << fpu_reg)) != 0; | 474 return (fpu_registers_ & (1 << fpu_reg)) != 0; |
459 } | 475 } |
460 | 476 |
461 intptr_t CpuRegisterCount() const { return RegisterCount(cpu_registers_); } | 477 intptr_t CpuRegisterCount() const { return RegisterCount(cpu_registers_); } |
462 intptr_t FpuRegisterCount() const { return RegisterCount(fpu_registers_); } | 478 intptr_t FpuRegisterCount() const { return RegisterCount(fpu_registers_); } |
463 | 479 |
464 static intptr_t RegisterCount(intptr_t registers); | 480 static intptr_t RegisterCount(intptr_t registers); |
465 | 481 |
466 intptr_t cpu_registers() const { return cpu_registers_; } | 482 intptr_t cpu_registers() const { return cpu_registers_; } |
467 intptr_t fpu_registers() const { return fpu_registers_; } | 483 intptr_t fpu_registers() const { return fpu_registers_; } |
468 | 484 |
469 private: | 485 private: |
470 intptr_t cpu_registers_; | 486 intptr_t cpu_registers_; |
| 487 intptr_t untagged_cpu_registers_; |
471 intptr_t fpu_registers_; | 488 intptr_t fpu_registers_; |
472 | 489 |
473 DISALLOW_COPY_AND_ASSIGN(RegisterSet); | 490 DISALLOW_COPY_AND_ASSIGN(RegisterSet); |
474 }; | 491 }; |
475 | 492 |
476 | 493 |
477 // Specification of locations for inputs and output. | 494 // Specification of locations for inputs and output. |
478 class LocationSummary : public ZoneAllocated { | 495 class LocationSummary : public ZoneAllocated { |
479 public: | 496 public: |
480 enum ContainsCall { | 497 enum ContainsCall { |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
554 BitmapBuilder* stack_bitmap() const { return stack_bitmap_; } | 571 BitmapBuilder* stack_bitmap() const { return stack_bitmap_; } |
555 | 572 |
556 bool always_calls() const { | 573 bool always_calls() const { |
557 return contains_call_ == kCall; | 574 return contains_call_ == kCall; |
558 } | 575 } |
559 | 576 |
560 bool can_call() { | 577 bool can_call() { |
561 return contains_call_ != kNoCall; | 578 return contains_call_ != kNoCall; |
562 } | 579 } |
563 | 580 |
| 581 bool HasCallOnSlowPath() { |
| 582 return can_call() && !always_calls(); |
| 583 } |
| 584 |
564 void PrintTo(BufferFormatter* f) const; | 585 void PrintTo(BufferFormatter* f) const; |
565 | 586 |
566 static LocationSummary* Make(intptr_t input_count, | 587 static LocationSummary* Make(intptr_t input_count, |
567 Location out, | 588 Location out, |
568 ContainsCall contains_call); | 589 ContainsCall contains_call); |
569 | 590 |
570 RegisterSet* live_registers() { | 591 RegisterSet* live_registers() { |
571 return &live_registers_; | 592 return &live_registers_; |
572 } | 593 } |
573 | 594 |
574 private: | 595 private: |
575 ZoneGrowableArray<Location> input_locations_; | 596 ZoneGrowableArray<Location> input_locations_; |
576 ZoneGrowableArray<Location> temp_locations_; | 597 ZoneGrowableArray<Location> temp_locations_; |
577 ZoneGrowableArray<Location> output_locations_; | 598 ZoneGrowableArray<Location> output_locations_; |
578 | 599 |
579 BitmapBuilder* stack_bitmap_; | 600 BitmapBuilder* stack_bitmap_; |
580 | 601 |
581 const ContainsCall contains_call_; | 602 const ContainsCall contains_call_; |
582 RegisterSet live_registers_; | 603 RegisterSet live_registers_; |
583 }; | 604 }; |
584 | 605 |
585 | 606 |
586 } // namespace dart | 607 } // namespace dart |
587 | 608 |
588 #endif // VM_LOCATIONS_H_ | 609 #endif // VM_LOCATIONS_H_ |
OLD | NEW |