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 |