| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/interpreter/bytecode-register-allocator.h" | 5 #include "src/interpreter/bytecode-register-allocator.h" |
| 6 | 6 |
| 7 #include "src/interpreter/bytecode-array-builder.h" | 7 #include "src/interpreter/bytecode-array-builder.h" |
| 8 | 8 |
| 9 namespace v8 { | 9 namespace v8 { |
| 10 namespace internal { | 10 namespace internal { |
| 11 namespace interpreter { | 11 namespace interpreter { |
| 12 | 12 |
| 13 TemporaryRegisterAllocator::TemporaryRegisterAllocator(Zone* zone, | 13 TemporaryRegisterAllocator::TemporaryRegisterAllocator(Zone* zone, |
| 14 int allocation_base) | 14 int allocation_base) |
| 15 : free_temporaries_(zone), | 15 : free_temporaries_(zone), |
| 16 allocation_base_(allocation_base), | 16 allocation_base_(allocation_base), |
| 17 allocation_count_(0) {} | 17 allocation_count_(0), |
| 18 observer_(nullptr) {} |
| 18 | 19 |
| 19 Register TemporaryRegisterAllocator::first_temporary_register() const { | 20 Register TemporaryRegisterAllocator::first_temporary_register() const { |
| 20 DCHECK(allocation_count() > 0); | 21 DCHECK(allocation_count() > 0); |
| 21 return Register(allocation_base()); | 22 return Register(allocation_base()); |
| 22 } | 23 } |
| 23 | 24 |
| 24 Register TemporaryRegisterAllocator::last_temporary_register() const { | 25 Register TemporaryRegisterAllocator::last_temporary_register() const { |
| 25 DCHECK(allocation_count() > 0); | 26 DCHECK(allocation_count() > 0); |
| 26 return Register(allocation_base() + allocation_count() - 1); | 27 return Register(allocation_base() + allocation_count() - 1); |
| 27 } | 28 } |
| 28 | 29 |
| 30 void TemporaryRegisterAllocator::set_observer( |
| 31 TemporaryRegisterObserver* observer) { |
| 32 DCHECK(observer_ == nullptr); |
| 33 observer_ = observer; |
| 34 } |
| 35 |
| 29 int TemporaryRegisterAllocator::AllocateTemporaryRegister() { | 36 int TemporaryRegisterAllocator::AllocateTemporaryRegister() { |
| 30 allocation_count_ += 1; | 37 allocation_count_ += 1; |
| 31 return allocation_base() + allocation_count() - 1; | 38 return allocation_base() + allocation_count() - 1; |
| 32 } | 39 } |
| 33 | 40 |
| 34 int TemporaryRegisterAllocator::BorrowTemporaryRegister() { | 41 int TemporaryRegisterAllocator::BorrowTemporaryRegister() { |
| 35 if (free_temporaries_.empty()) { | 42 if (free_temporaries_.empty()) { |
| 36 return AllocateTemporaryRegister(); | 43 return AllocateTemporaryRegister(); |
| 37 } else { | 44 } else { |
| 38 auto pos = free_temporaries_.begin(); | 45 auto pos = free_temporaries_.begin(); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 133 | 140 |
| 134 void TemporaryRegisterAllocator::BorrowConsecutiveTemporaryRegister( | 141 void TemporaryRegisterAllocator::BorrowConsecutiveTemporaryRegister( |
| 135 int reg_index) { | 142 int reg_index) { |
| 136 DCHECK(free_temporaries_.find(reg_index) != free_temporaries_.end()); | 143 DCHECK(free_temporaries_.find(reg_index) != free_temporaries_.end()); |
| 137 free_temporaries_.erase(reg_index); | 144 free_temporaries_.erase(reg_index); |
| 138 } | 145 } |
| 139 | 146 |
| 140 void TemporaryRegisterAllocator::ReturnTemporaryRegister(int reg_index) { | 147 void TemporaryRegisterAllocator::ReturnTemporaryRegister(int reg_index) { |
| 141 DCHECK(free_temporaries_.find(reg_index) == free_temporaries_.end()); | 148 DCHECK(free_temporaries_.find(reg_index) == free_temporaries_.end()); |
| 142 free_temporaries_.insert(reg_index); | 149 free_temporaries_.insert(reg_index); |
| 150 if (observer_) { |
| 151 observer_->TemporaryRegisterFreeEvent(Register(reg_index)); |
| 152 } |
| 143 } | 153 } |
| 144 | 154 |
| 145 BytecodeRegisterAllocator::BytecodeRegisterAllocator( | 155 BytecodeRegisterAllocator::BytecodeRegisterAllocator( |
| 146 Zone* zone, TemporaryRegisterAllocator* allocator) | 156 Zone* zone, TemporaryRegisterAllocator* allocator) |
| 147 : base_allocator_(allocator), | 157 : base_allocator_(allocator), |
| 148 allocated_(zone), | 158 allocated_(zone), |
| 149 next_consecutive_register_(-1), | 159 next_consecutive_register_(-1), |
| 150 next_consecutive_count_(-1) {} | 160 next_consecutive_count_(-1) {} |
| 151 | 161 |
| 152 BytecodeRegisterAllocator::~BytecodeRegisterAllocator() { | 162 BytecodeRegisterAllocator::~BytecodeRegisterAllocator() { |
| 153 for (auto i = allocated_.rbegin(); i != allocated_.rend(); i++) { | 163 for (auto i = allocated_.rbegin(); i != allocated_.rend(); i++) { |
| 154 base_allocator()->ReturnTemporaryRegister(*i); | 164 base_allocator()->ReturnTemporaryRegister(*i); |
| 155 } | 165 } |
| 156 allocated_.clear(); | 166 allocated_.clear(); |
| 157 } | 167 } |
| 158 | 168 |
| 159 | |
| 160 Register BytecodeRegisterAllocator::NewRegister() { | 169 Register BytecodeRegisterAllocator::NewRegister() { |
| 161 int allocated = -1; | 170 int allocated = -1; |
| 162 if (next_consecutive_count_ <= 0) { | 171 if (next_consecutive_count_ <= 0) { |
| 163 allocated = base_allocator()->BorrowTemporaryRegister(); | 172 allocated = base_allocator()->BorrowTemporaryRegister(); |
| 164 } else { | 173 } else { |
| 165 allocated = base_allocator()->BorrowTemporaryRegisterNotInRange( | 174 allocated = base_allocator()->BorrowTemporaryRegisterNotInRange( |
| 166 next_consecutive_register_, | 175 next_consecutive_register_, |
| 167 next_consecutive_register_ + next_consecutive_count_ - 1); | 176 next_consecutive_register_ + next_consecutive_count_ - 1); |
| 168 } | 177 } |
| 169 allocated_.push_back(allocated); | 178 allocated_.push_back(allocated); |
| 170 return Register(allocated); | 179 return Register(allocated); |
| 171 } | 180 } |
| 172 | 181 |
| 173 | |
| 174 bool BytecodeRegisterAllocator::RegisterIsAllocatedInThisScope( | 182 bool BytecodeRegisterAllocator::RegisterIsAllocatedInThisScope( |
| 175 Register reg) const { | 183 Register reg) const { |
| 176 for (auto i = allocated_.begin(); i != allocated_.end(); i++) { | 184 for (auto i = allocated_.begin(); i != allocated_.end(); i++) { |
| 177 if (*i == reg.index()) return true; | 185 if (*i == reg.index()) return true; |
| 178 } | 186 } |
| 179 return false; | 187 return false; |
| 180 } | 188 } |
| 181 | 189 |
| 182 | |
| 183 void BytecodeRegisterAllocator::PrepareForConsecutiveAllocations(size_t count) { | 190 void BytecodeRegisterAllocator::PrepareForConsecutiveAllocations(size_t count) { |
| 184 if (static_cast<int>(count) > next_consecutive_count_) { | 191 if (static_cast<int>(count) > next_consecutive_count_) { |
| 185 next_consecutive_register_ = | 192 next_consecutive_register_ = |
| 186 base_allocator()->PrepareForConsecutiveTemporaryRegisters(count); | 193 base_allocator()->PrepareForConsecutiveTemporaryRegisters(count); |
| 187 next_consecutive_count_ = static_cast<int>(count); | 194 next_consecutive_count_ = static_cast<int>(count); |
| 188 } | 195 } |
| 189 } | 196 } |
| 190 | 197 |
| 191 | |
| 192 Register BytecodeRegisterAllocator::NextConsecutiveRegister() { | 198 Register BytecodeRegisterAllocator::NextConsecutiveRegister() { |
| 193 DCHECK_GE(next_consecutive_register_, 0); | 199 DCHECK_GE(next_consecutive_register_, 0); |
| 194 DCHECK_GT(next_consecutive_count_, 0); | 200 DCHECK_GT(next_consecutive_count_, 0); |
| 195 base_allocator()->BorrowConsecutiveTemporaryRegister( | 201 base_allocator()->BorrowConsecutiveTemporaryRegister( |
| 196 next_consecutive_register_); | 202 next_consecutive_register_); |
| 197 allocated_.push_back(next_consecutive_register_); | 203 allocated_.push_back(next_consecutive_register_); |
| 198 next_consecutive_count_--; | 204 next_consecutive_count_--; |
| 199 return Register(next_consecutive_register_++); | 205 return Register(next_consecutive_register_++); |
| 200 } | 206 } |
| 201 | 207 |
| 202 } // namespace interpreter | 208 } // namespace interpreter |
| 203 } // namespace internal | 209 } // namespace internal |
| 204 } // namespace v8 | 210 } // namespace v8 |
| OLD | NEW |