| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 71 ASSERT(&obj == &loc.constant()); | 71 ASSERT(&obj == &loc.constant()); |
| 72 return loc; | 72 return loc; |
| 73 } | 73 } |
| 74 | 74 |
| 75 const Object& constant() const { | 75 const Object& constant() const { |
| 76 ASSERT(IsConstant()); | 76 ASSERT(IsConstant()); |
| 77 return *reinterpret_cast<const Object*>(value_ & ~kConstantMask); | 77 return *reinterpret_cast<const Object*>(value_ & ~kConstantMask); |
| 78 } | 78 } |
| 79 | 79 |
| 80 // Unallocated locations. | 80 // Unallocated locations. |
| 81 // TODO(vegorov): writable register policy? |
| 81 enum Policy { | 82 enum Policy { |
| 83 kAny, |
| 84 kPrefersRegister, |
| 82 kRequiresRegister, | 85 kRequiresRegister, |
| 83 kSameAsFirstInput, | 86 kSameAsFirstInput, |
| 84 }; | 87 }; |
| 85 | 88 |
| 86 bool IsUnallocated() const { | 89 bool IsUnallocated() const { |
| 87 return kind() == kUnallocated; | 90 return kind() == kUnallocated; |
| 88 } | 91 } |
| 89 | 92 |
| 93 bool IsRegisterBeneficial() { |
| 94 return !Equals(Any()); |
| 95 } |
| 96 |
| 90 static Location UnallocatedLocation(Policy policy) { | 97 static Location UnallocatedLocation(Policy policy) { |
| 91 return Location(kUnallocated, PolicyField::encode(policy)); | 98 return Location(kUnallocated, PolicyField::encode(policy)); |
| 92 } | 99 } |
| 93 | 100 |
| 94 // Any free register is suitable to replace this unallocated location. | 101 // Any free register is suitable to replace this unallocated location. |
| 102 static Location Any() { |
| 103 return UnallocatedLocation(kAny); |
| 104 } |
| 105 |
| 106 static Location PrefersRegister() { |
| 107 return UnallocatedLocation(kPrefersRegister); |
| 108 } |
| 109 |
| 95 static Location RequiresRegister() { | 110 static Location RequiresRegister() { |
| 96 return UnallocatedLocation(kRequiresRegister); | 111 return UnallocatedLocation(kRequiresRegister); |
| 97 } | 112 } |
| 98 | 113 |
| 99 // The location of the first input to the instruction will be | 114 // The location of the first input to the instruction will be |
| 100 // used to replace this unallocated location. | 115 // used to replace this unallocated location. |
| 101 static Location SameAsFirstInput() { | 116 static Location SameAsFirstInput() { |
| 102 return UnallocatedLocation(kSameAsFirstInput); | 117 return UnallocatedLocation(kSameAsFirstInput); |
| 103 } | 118 } |
| 104 | 119 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 136 } | 151 } |
| 137 | 152 |
| 138 intptr_t spill_index() const { | 153 intptr_t spill_index() const { |
| 139 ASSERT(IsSpillSlot()); | 154 ASSERT(IsSpillSlot()); |
| 140 return static_cast<intptr_t>(payload()); | 155 return static_cast<intptr_t>(payload()); |
| 141 } | 156 } |
| 142 | 157 |
| 143 const char* Name() const; | 158 const char* Name() const; |
| 144 void PrintTo(BufferFormatter* f) const; | 159 void PrintTo(BufferFormatter* f) const; |
| 145 | 160 |
| 146 // Compare two non-constant locations. | 161 // Compare two locations. |
| 147 bool Equals(Location other) const { | 162 bool Equals(Location other) const { |
| 148 ASSERT(!IsConstant() && !other.IsConstant()); | |
| 149 return value_ == other.value_; | 163 return value_ == other.value_; |
| 150 } | 164 } |
| 151 | 165 |
| 152 private: | 166 private: |
| 153 explicit Location(uword value) : value_(value) { } | 167 explicit Location(uword value) : value_(value) { } |
| 154 | 168 |
| 155 Location(Kind kind, uword payload) | 169 Location(Kind kind, uword payload) |
| 156 : value_(KindField::encode(kind) | PayloadField::encode(payload)) { } | 170 : value_(KindField::encode(kind) | PayloadField::encode(payload)) { } |
| 157 | 171 |
| 158 uword payload() const { | 172 uword payload() const { |
| 159 return PayloadField::decode(value_); | 173 return PayloadField::decode(value_); |
| 160 } | 174 } |
| 161 | 175 |
| 162 // If current location is constant might return something that | 176 // If current location is constant might return something that |
| 163 // is not equal to any Kind. | 177 // is not equal to any Kind. |
| 164 Kind kind() const { | 178 Kind kind() const { |
| 165 return KindField::decode(value_); | 179 return KindField::decode(value_); |
| 166 } | 180 } |
| 167 | 181 |
| 168 typedef BitField<Kind, 0, 3> KindField; | 182 typedef BitField<Kind, 0, 3> KindField; |
| 169 typedef BitField<uword, 3, kWordSize * kBitsPerByte - 2> PayloadField; | 183 typedef BitField<uword, 3, kWordSize * kBitsPerByte - 2> PayloadField; |
| 170 | 184 |
| 171 // Layout for kUnallocated locations payload. | 185 // Layout for kUnallocated locations payload. |
| 172 typedef BitField<Policy, 0, 1> PolicyField; | 186 typedef BitField<Policy, 0, 2> PolicyField; |
| 173 | 187 |
| 174 // Location either contains kind and payload fields or a tagged handle for | 188 // Location either contains kind and payload fields or a tagged handle for |
| 175 // a constant locations. Values of enumeration Kind are selected in such a | 189 // a constant locations. Values of enumeration Kind are selected in such a |
| 176 // way that none of them can be interpreted as a kConstant tag. | 190 // way that none of them can be interpreted as a kConstant tag. |
| 177 uword value_; | 191 uword value_; |
| 178 }; | 192 }; |
| 179 | 193 |
| 180 | 194 |
| 181 // Specification of locations for inputs and output. | 195 // Specification of locations for inputs and output. |
| 182 class LocationSummary : public ZoneAllocated { | 196 class LocationSummary : public ZoneAllocated { |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 GrowableArray<Location> temp_locations_; | 266 GrowableArray<Location> temp_locations_; |
| 253 Location output_location_; | 267 Location output_location_; |
| 254 | 268 |
| 255 const bool is_call_; | 269 const bool is_call_; |
| 256 }; | 270 }; |
| 257 | 271 |
| 258 | 272 |
| 259 } // namespace dart | 273 } // namespace dart |
| 260 | 274 |
| 261 #endif // VM_LOCATIONS_H_ | 275 #endif // VM_LOCATIONS_H_ |
| OLD | NEW |