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

Side by Side Diff: src/interpreter/bytecode-register-optimizer.cc

Issue 1997653002: [interpreter] Bytecode register optimizer. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Grammar. Created 4 years, 6 months 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
OLDNEW
(Empty)
1 // Copyright 2015 the V8 project authors. All rights reserved.
rmcilroy 2016/05/26 10:24:53 2016
oth 2016/05/26 21:26:51 Done.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "src/interpreter/bytecode-register-optimizer.h"
6
7 namespace v8 {
8 namespace internal {
9 namespace interpreter {
10
11 // A class for tracking the state of a register. In particular, it
12 // tracks whether one register is valuewise equivalent to another, and
13 // also whether a register is materialized in the bytecode stream.
14 class BytecodeRegisterOptimizer::RegisterInfo final : public ZoneObject {
15 public:
16 RegisterInfo(Register reg, int equivalence_id, bool materialized)
17 : register_(reg),
18 equivalence_id_(equivalence_id),
19 materialized_(materialized),
20 next_(this),
21 prev_(this) {}
22
23 void AddToEquivalenceSetOf(RegisterInfo* info);
24 void RemoveFromEquivalenceSet();
25 bool IsOnlyEquivalent() const;
26 bool IsOnlyMaterializedEquivalent() const;
27 bool IsEquivalent(RegisterInfo* info) const;
28
29 RegisterInfo* GetMaterializedEquivalent();
30 RegisterInfo* GetMaterializedEquivalentOtherThan(Register reg);
31 RegisterInfo* GetMaterializationCandidate();
rmcilroy 2016/05/26 10:24:52 I think these functions deserve a comment, particu
oth 2016/05/26 21:26:51 Done.
32
33 Register register_value() const { return register_; }
34 bool materialized() const { return materialized_; }
35 void set_materialized(bool materialized) { materialized_ = materialized; }
36 void set_equivalence_id(int equivalence_id) {
37 equivalence_id_ = equivalence_id;
38 }
39 int equivalence_id() const { return equivalence_id_; }
40 RegisterInfo* next() const { return next_; }
41
42 private:
43 Register register_;
44 int equivalence_id_;
rmcilroy 2016/05/26 10:24:53 This should probably be an unsigned long, and mayb
oth 2016/05/26 21:26:50 Done.
45 bool materialized_;
46
47 // Equivalence set pointers.
48 RegisterInfo* next_;
49 RegisterInfo* prev_;
50
51 DISALLOW_COPY_AND_ASSIGN(RegisterInfo);
52 };
53
54 void BytecodeRegisterOptimizer::RegisterInfo::AddToEquivalenceSetOf(
55 RegisterInfo* info) {
56 DCHECK(!IsEquivalent(info) && IsOnlyEquivalent());
57 this->next_ = info->next_;
58 this->prev_ = info;
59 this->prev_->next_ = this;
60 this->next_->prev_ = this;
61 set_equivalence_id(info->equivalence_id());
62 }
63
64 void BytecodeRegisterOptimizer::RegisterInfo::RemoveFromEquivalenceSet() {
65 this->next_->prev_ = this->prev_;
66 this->prev_->next_ = this->next_;
67 this->next_ = this->prev_ = this;
68 }
69
70 bool BytecodeRegisterOptimizer::RegisterInfo::IsOnlyEquivalent() const {
rmcilroy 2016/05/26 10:24:53 This name is a bit confusing to me, how about IsUn
oth 2016/05/26 21:26:51 Agreed. For readability, perhaps IsOnlyMemberOfEqu
rmcilroy 2016/05/27 09:18:58 SGTM, thanks.
71 return this->next_ == this;
72 }
73
74 bool BytecodeRegisterOptimizer::RegisterInfo::IsOnlyMaterializedEquivalent()
75 const {
76 DCHECK(materialized());
77
78 const RegisterInfo* visitor = this->next_;
79 while (visitor != this) {
80 if (visitor->materialized()) {
81 return false;
82 }
83 visitor = visitor->next_;
84 }
85 return true;
86 }
87
88 bool BytecodeRegisterOptimizer::RegisterInfo::IsEquivalent(
89 RegisterInfo* info) const {
90 return equivalence_id() == info->equivalence_id();
91 }
92
93 BytecodeRegisterOptimizer::RegisterInfo*
94 BytecodeRegisterOptimizer::RegisterInfo::GetMaterializedEquivalent() {
95 RegisterInfo* visitor = this;
96 do {
97 if (visitor->materialized()) {
98 return visitor;
99 }
100 visitor = visitor->next_;
101 } while (visitor != this);
102
103 return nullptr;
104 }
105
106 BytecodeRegisterOptimizer::RegisterInfo*
107 BytecodeRegisterOptimizer::RegisterInfo::GetMaterializationCandidate() {
rmcilroy 2016/05/26 10:24:53 It is difficult to figure out what this function d
oth 2016/05/26 21:26:50 GetEquivalentToMaterialize()?
rmcilroy 2016/05/27 09:18:58 SGTM, thanks.
108 DCHECK(this->materialized());
109 RegisterInfo* visitor = this->next_;
110 Register best_reg;
rmcilroy 2016/05/26 10:24:53 unused
oth 2016/05/26 21:26:51 Done.
111 RegisterInfo* best_info = nullptr;
112 while (visitor != this) {
113 if (visitor->materialized()) {
114 return nullptr;
115 }
116 if (best_info == nullptr ||
117 visitor->register_value() < best_info->register_value()) {
118 best_info = visitor;
119 }
120 visitor = visitor->next_;
121 }
122 return best_info;
123 }
124
125 BytecodeRegisterOptimizer::BytecodeRegisterOptimizer(
126 Zone* zone, TemporaryRegisterAllocator* register_allocator,
127 int parameter_count, int fixed_register_count,
128 BytecodePipelineStage* next_stage)
129 : accumulator_(Register::bytecode_array()),
rmcilroy 2016/05/26 10:24:52 We don't use bytecode_array in bytecode, but I won
oth 2016/05/26 21:26:51 Done. It was implemented in this way to keep the
130 temporary_base_(register_allocator->allocation_base()),
131 register_map_(zone),
132 equivalence_id_(0),
133 next_stage_(next_stage),
134 flushed_(false),
135 zone_(zone) {
136 register_allocator->set_observer(this);
137
138 // Calculate offset so register index values can be mapped into
139 // a vector of register metadata.
140 if (parameter_count != 0) {
141 map_index_offset_ =
142 -Register::FromParameterIndex(0, parameter_count).index();
143 } else {
144 map_index_offset_ = -accumulator_.index();
rmcilroy 2016/05/26 10:24:53 Does this side ever get hit? We should always have
oth 2016/05/26 21:26:50 Yes, it gets hit in tests that craft bytecode. Th
rmcilroy 2016/05/27 09:18:58 SG, thanks
145 }
146
147 // Initialize register map for parameters, locals, and the
148 // accumulator.
149 register_map_.resize(map_index_offset_ +
150 static_cast<size_t>(fixed_register_count));
rmcilroy 2016/05/26 10:24:53 Isn't fixed_register_count the same (or less than)
oth 2016/05/26 21:26:50 Done.
151 for (size_t i = 0; i < register_map_.size(); ++i) {
152 register_map_[i] = new (zone)
153 RegisterInfo(RegisterFromMapIndex(i), equivalence_id_++, true);
154 DCHECK_EQ(register_map_[i]->register_value().index(),
155 RegisterFromMapIndex(i).index());
156 }
157 accumulator_info_ = GetRegisterInfo(accumulator_);
158 DCHECK(accumulator_info_->register_value() == accumulator_);
159 }
160
161 void BytecodeRegisterOptimizer::FlushState() {
162 if (flushed_) {
163 return;
164 }
165
166 // Materialize all live registers.
167 size_t count = register_map_.size();
168 for (size_t i = 0; i < count; ++i) {
169 RegisterInfo* reg_info = register_map_[i];
170 if (!reg_info->materialized() && !reg_info->IsOnlyEquivalent()) {
171 DCHECK(RegisterIsTemporary(reg_info->register_value()) ||
172 reg_info->register_value() == accumulator_);
173 Materialize(reg_info);
174 }
175 }
176
177 // Break all existing equivalences.
178 for (size_t i = 0; i < count; ++i) {
179 RegisterInfo* reg_info = register_map_[i];
180 if (!reg_info->IsOnlyEquivalent()) {
181 reg_info->RemoveFromEquivalenceSet();
182 reg_info->set_equivalence_id(equivalence_id_++);
rmcilroy 2016/05/26 10:24:53 nit - move the setting of equivalence_id into Remo
oth 2016/05/26 21:26:50 Done.
183 }
184 }
185 flushed_ = true;
186 }
187
188 // override
189 void BytecodeRegisterOptimizer::FlushBasicBlock() {
190 FlushState();
191 next_stage_->FlushBasicBlock();
192 }
193
194 // override
195 size_t BytecodeRegisterOptimizer::FlushForOffset() {
196 FlushState();
197 return next_stage_->FlushForOffset();
198 }
199
200 void BytecodeRegisterOptimizer::EmitNopTakingSourcePosition(
201 BytecodeNode* node) {
202 BytecodeNode nop(Bytecode::kNop);
203 nop.source_info().Update(node->source_info());
204 WriteToNextStage(&nop);
205 node->source_info().set_invalid();
206 }
207
208 // override
209 void BytecodeRegisterOptimizer::Write(BytecodeNode* node) {
210 flushed_ = false;
211
212 //
213 // The logic for register to register transfer here emits Nops with the
214 // current source position.
rmcilroy 2016/05/26 10:24:53 I'm not sure what this adds anything beyond the tw
oth 2016/05/26 21:26:50 Done.
215 //
216 // Transfers with observable registers as the destination will be
217 // immediately materialized so the source position information will
218 // be ordered correctly.
219 //
220 // Transfers without observable destination registers will initially
221 // be emitted as Nop's with the source position. They may, or may
222 // not, be materialized by the optimizer. However, the source
223 // position is not lost and being attachd to a Nop is fine as the
rmcilroy 2016/05/26 10:24:53 attached
oth 2016/05/26 21:26:51 Done.
224 // destination register is not observable in the debugger.
225 //
226 switch (node->bytecode()) {
227 case Bytecode::kLdar: {
228 EmitNopTakingSourcePosition(node);
rmcilroy 2016/05/26 10:24:53 nit - move into DoLdar / DoStar / DoMov. Optional
oth 2016/05/26 21:26:50 Done. Tried the experiment with the source positio
229 DoLdar(node);
230 return;
231 }
232 case Bytecode::kStar: {
233 EmitNopTakingSourcePosition(node);
234 DoStar(node);
235 return;
236 }
237 case Bytecode::kMov: {
238 EmitNopTakingSourcePosition(node);
239 DoMov(node);
240 return;
241 }
242 default:
243 break;
244 }
245
246 if (Bytecodes::IsJump(node->bytecode()) ||
247 node->bytecode() == Bytecode::kDebugger) {
248 // The debugger can manipulate locals and parameters, flush
249 // everything before handing over to it. Similarly, all state must
250 // be flushed before emitting a jump due to how bytecode offsets
251 // for jumps are evaluated.
252 FlushState();
253 WriteToNextStage(node);
254 return;
rmcilroy 2016/05/26 10:24:53 nit - just do the FlushState here and fall-through
oth 2016/05/26 21:26:51 Done.
255 }
256
257 PrepareOperands(node);
258 WriteToNextStage(node);
259 }
260
261 void BytecodeRegisterOptimizer::WriteToNextStage(BytecodeNode* node) {
262 next_stage_->Write(node);
263 }
264
265 void BytecodeRegisterOptimizer::OutputRegisterTransfer(
266 RegisterInfo* input_info, RegisterInfo* output_info) {
267 Register input = input_info->register_value();
268 Register output = output_info->register_value();
269 DCHECK_NE(input.index(), output.index());
270
271 if (input == accumulator_) {
272 uint32_t operand = static_cast<uint32_t>(output.ToOperand());
273 OperandScale scale = Bytecodes::OperandSizesToScale(output.SizeOfOperand());
274 BytecodeNode node(Bytecode::kStar, operand, scale);
275 WriteToNextStage(&node);
276 } else if (output == accumulator_) {
277 uint32_t operand = static_cast<uint32_t>(input.ToOperand());
278 OperandScale scale = Bytecodes::OperandSizesToScale(input.SizeOfOperand());
279 BytecodeNode node(Bytecode::kLdar, operand, scale);
280 WriteToNextStage(&node);
281 } else {
282 uint32_t operand0 = static_cast<uint32_t>(input.ToOperand());
283 uint32_t operand1 = static_cast<uint32_t>(output.ToOperand());
284 OperandScale scale = Bytecodes::OperandSizesToScale(input.SizeOfOperand(),
285 output.SizeOfOperand());
286 BytecodeNode node(Bytecode::kMov, operand0, operand1, scale);
287 WriteToNextStage(&node);
288 }
289 }
290
291 void BytecodeRegisterOptimizer::CreateMaterializedEquivalentIfRequired(
292 RegisterInfo* info) {
293 if (info->materialized()) {
294 RegisterInfo* unmaterialized = info->GetMaterializationCandidate();
295 if (unmaterialized) {
296 OutputRegisterTransfer(info, unmaterialized);
297 unmaterialized->set_materialized(true);
298 }
299 }
300 }
301
302 BytecodeRegisterOptimizer::RegisterInfo*
303 BytecodeRegisterOptimizer::GetMaterializedEquivalent(RegisterInfo* info) {
304 return info->materialized() ? info : info->GetMaterializedEquivalent();
305 }
306
307 BytecodeRegisterOptimizer::RegisterInfo*
308 BytecodeRegisterOptimizer::GetMaterializedEquivalentNotAccumulator(
309 RegisterInfo* info) {
310 if (info->materialized()) {
311 return info;
312 }
313
314 RegisterInfo* result = info->GetMaterializedEquivalent();
rmcilroy 2016/05/26 10:24:53 Maybe just add an option to GetMaterializedEquival
oth 2016/05/26 21:26:51 Done.
315 if (result->register_value() == accumulator_) {
316 result = result->next()->GetMaterializedEquivalent();
317 if (result->register_value() == accumulator_) {
318 Materialize(info);
319 result = info;
320 }
321 }
322 return result;
323 }
324
325 void BytecodeRegisterOptimizer::Materialize(RegisterInfo* info) {
326 if (!info->materialized()) {
327 RegisterInfo* materialized = info->GetMaterializedEquivalent();
328 OutputRegisterTransfer(materialized, info);
329 info->set_materialized(true);
330 }
331 }
332
333 void BytecodeRegisterOptimizer::RegisterTransfer(RegisterInfo* input_info,
334 RegisterInfo* output_info) {
335 // Ensure value associated with output is materialized into a
336 // different register if necessary.
337 CreateMaterializedEquivalentIfRequired(output_info);
338 bool output_is_observable =
339 RegisterIsObservable(output_info->register_value());
340
341 // If the output and input are not equivalent or the output is
342 // visible to the user/debugger, update equivalence set and
343 // potentially emit store if the transfer is observable.
344 if (!output_info->IsEquivalent(input_info) || output_is_observable) {
345 // Remove from current set and invalidate equivalence id.
346 output_info->RemoveFromEquivalenceSet();
347 output_info->set_equivalence_id(equivalence_id_++);
348
349 // Add to the equivalence set of |input_info|.
350 RegisterInfo* materialized_info = input_info->GetMaterializedEquivalent();
351 output_info->AddToEquivalenceSetOf(materialized_info);
352 output_info->set_materialized(output_is_observable);
353 if (output_is_observable) {
354 OutputRegisterTransfer(materialized_info, output_info);
rmcilroy 2016/05/26 10:24:53 output_info should be set_materialized(true) shoul
oth 2016/05/26 21:26:51 Re-worked hopefully easier to reason about now ?
rmcilroy 2016/05/27 09:18:58 Looks good, thanks
355 }
356 }
357 }
358
359 void BytecodeRegisterOptimizer::DoLdar(const BytecodeNode* const node) {
360 Register input = GetRegisterInputOperand(
361 0, node->bytecode(), node->operands(), node->operand_count());
362 RegisterInfo* input_info = GetRegisterInfo(input);
363 RegisterTransfer(input_info, accumulator_info_);
364 }
365
366 void BytecodeRegisterOptimizer::DoMov(const BytecodeNode* const node) {
367 Register input = GetRegisterInputOperand(
368 0, node->bytecode(), node->operands(), node->operand_count());
369 RegisterInfo* input_info = GetRegisterInfo(input);
370 Register output = GetRegisterOutputOperand(
371 1, node->bytecode(), node->operands(), node->operand_count());
372 RegisterInfo* output_info = GetOrCreateRegisterInfo(output);
373 RegisterTransfer(input_info, output_info);
374 }
375
376 void BytecodeRegisterOptimizer::DoStar(const BytecodeNode* const node) {
377 Register output = GetRegisterOutputOperand(
378 0, node->bytecode(), node->operands(), node->operand_count());
379 RegisterInfo* output_info = GetOrCreateRegisterInfo(output);
380 RegisterTransfer(accumulator_info_, output_info);
381 }
382
383 void BytecodeRegisterOptimizer::PrepareRegisterOutputOperand(
384 RegisterInfo* reg_info) {
385 CreateMaterializedEquivalentIfRequired(reg_info);
386
387 // Put register in it's own equivalence set.
388 reg_info->RemoveFromEquivalenceSet();
389 reg_info->set_materialized(true);
390 reg_info->set_equivalence_id(equivalence_id_++);
391 }
392
393 void BytecodeRegisterOptimizer::PrepareRegisterRangeOutputOperand(
394 Register start, int count) {
395 for (int i = 0; i < count; ++i) {
396 Register reg(start.index() + i);
397 RegisterInfo* reg_info = GetOrCreateRegisterInfo(reg);
398 PrepareRegisterOutputOperand(reg_info);
399 }
400 }
401
402 Register BytecodeRegisterOptimizer::PrepareRegisterInputOperand(Register reg) {
403 RegisterInfo* reg_info = GetOrCreateRegisterInfo(reg);
rmcilroy 2016/05/26 10:24:53 Reginfo should be create here shouldn't it? Just G
oth 2016/05/26 21:26:51 Comment added. The create case is for the first ti
404 if (reg_info->materialized()) {
405 return reg;
406 } else {
407 RegisterInfo* equivalent_info =
408 GetMaterializedEquivalentNotAccumulator(reg_info);
409 return equivalent_info->register_value();
410 }
411 }
412
413 void BytecodeRegisterOptimizer::PrepareRegisterRangeInputOperand(Register start,
414 int count) {
415 for (int i = 0; i < count; ++i) {
416 Register current(start.index() + i);
417 RegisterInfo* input_info = GetRegisterInfo(current);
418 Materialize(input_info);
419 }
420 }
421
422 void BytecodeRegisterOptimizer::PrepareRegisterOperands(
423 BytecodeNode* const node) {
424 //
425 // For each input operand, get a materialized equivalent if it is
426 // just a single register, otherwise materialize register range.
427 // Update operand_scale if necessary.
428 //
429 // For each output register about to be clobbered, materialize an
430 // equivalent if it exists. Put each register in it's own equivalence set.
431 //
432 int register_operand_bitmap =
433 Bytecodes::GetRegisterOperandBitmap(node->bytecode());
434 const OperandType* operand_types =
435 Bytecodes::GetOperandTypes(node->bytecode());
436 uint32_t* operands = node->operands();
437 for (int i = 0; register_operand_bitmap != 0;
438 ++i, register_operand_bitmap >>= 1) {
439 if ((register_operand_bitmap & 1) == 0) {
440 continue;
441 }
442 OperandType operand_type = operand_types[i];
443 int count = 0;
444 if (operand_types[i + 1] == OperandType::kRegCount) {
rmcilroy 2016/05/26 10:24:53 This is repeated in a bunch of places (e.g., bytec
oth 2016/05/26 21:26:51 This is a little bit raw. If it's a helper, it'll
445 count = static_cast<int>(operands[i + 1]);
446 if (count == 0) {
447 continue;
448 }
449 } else {
450 count = Bytecodes::GetNumberOfRegistersRepresentedBy(operand_type);
451 }
452
453 Register reg = Register::FromOperand(static_cast<int32_t>(operands[i]));
454 if (Bytecodes::IsRegisterInputOperandType(operand_type)) {
455 if (count == 1) {
456 Register equivalent = PrepareRegisterInputOperand(reg);
rmcilroy 2016/05/26 10:24:53 PrepareRegisterInputOperand does something differe
oth 2016/05/26 21:26:50 Done.
457 operands[i] = static_cast<uint32_t>(equivalent.ToOperand());
458 // Update operand scale as equivalent may be different.
459 OperandScale operand_scale =
460 Bytecodes::OperandSizesToScale(equivalent.SizeOfOperand());
461 if (operand_scale > node->operand_scale()) {
462 node->set_operand_scale(operand_scale);
463 }
464 } else if (count > 1) {
465 PrepareRegisterRangeInputOperand(reg, count);
466 }
467 } else if (Bytecodes::IsRegisterOutputOperandType(operand_type)) {
468 PrepareRegisterRangeOutputOperand(reg, count);
469 }
470 }
471 }
472
473 void BytecodeRegisterOptimizer::PrepareAccumulator(BytecodeNode* const node) {
474 // Materialize the accumulator if it is read by the bytecode. The
475 // accumulator is special and no other register can be materialized
476 // in it's place.
477 if (Bytecodes::ReadsAccumulator(node->bytecode()) &&
478 !accumulator_info_->materialized()) {
479 Materialize(accumulator_info_);
480 }
481
482 // Materialize an equivalent to the accumulator if it will be
483 // clobbered when the bytecode is dispatched.
484 if (Bytecodes::WritesAccumulator(node->bytecode())) {
485 PrepareRegisterOutputOperand(accumulator_info_);
486 }
487 }
488
489 void BytecodeRegisterOptimizer::PrepareOperands(BytecodeNode* const node) {
490 PrepareAccumulator(node);
491 PrepareRegisterOperands(node);
492 }
493
494 // static
495 Register BytecodeRegisterOptimizer::GetRegisterInputOperand(
496 int index, Bytecode bytecode, const uint32_t* operands, int operand_count) {
497 DCHECK_LT(index, operand_count);
498 DCHECK(Bytecodes::IsRegisterInputOperandType(
499 Bytecodes::GetOperandType(bytecode, index)));
500 return OperandToRegister(operands[index]);
501 }
502
503 // static
504 Register BytecodeRegisterOptimizer::GetRegisterOutputOperand(
505 int index, Bytecode bytecode, const uint32_t* operands, int operand_count) {
506 DCHECK_LT(index, operand_count);
507 DCHECK(Bytecodes::IsRegisterOutputOperandType(
508 Bytecodes::GetOperandType(bytecode, index)));
509 return OperandToRegister(operands[index]);
510 }
511
512 BytecodeRegisterOptimizer::RegisterInfo*
513 BytecodeRegisterOptimizer::GetRegisterInfo(Register reg) {
514 size_t index = GetMapIndex(reg);
515 return (index < register_map_.size()) ? register_map_[index] : nullptr;
rmcilroy 2016/05/26 10:24:53 it looks like we always depend on this returning n
oth 2016/05/26 21:26:50 This can be called from TemporaryRegisterFreeEvent
rmcilroy 2016/05/27 09:18:58 OK sounds good, thanks.
516 }
517
518 BytecodeRegisterOptimizer::RegisterInfo*
519 BytecodeRegisterOptimizer::GetOrCreateRegisterInfo(Register reg) {
520 size_t index = GetMapIndex(reg);
521 return index < register_map_.size() ? register_map_[index]
522 : NewRegisterInfo(reg);
523 }
524
525 BytecodeRegisterOptimizer::RegisterInfo*
526 BytecodeRegisterOptimizer::NewRegisterInfo(Register reg) {
527 size_t index = GetMapIndex(reg);
528 DCHECK_GE(index, register_map_.size());
529 GrowRegisterMap(reg);
530 return register_map_[index];
531 }
532
533 void BytecodeRegisterOptimizer::GrowRegisterMap(Register reg) {
534 DCHECK(RegisterIsTemporary(reg));
535 size_t index = GetMapIndex(reg);
536 DCHECK_GE(index, register_map_.size());
537 size_t new_size = index + 1;
538 size_t old_size = register_map_.size();
539 register_map_.resize(new_size);
540 for (size_t i = old_size; i < new_size; ++i) {
541 register_map_[i] = new (zone())
542 RegisterInfo(RegisterFromMapIndex(i), equivalence_id_++, false);
543 }
544 }
545
546 void BytecodeRegisterOptimizer::TemporaryRegisterFreeEvent(Register reg) {
547 RegisterInfo* info = GetRegisterInfo(reg);
548 if (info != nullptr) {
549 // If register is materialized and part of equivalence set, make
550 // sure another member of the set holds the value before the
551 // temporary register is removed.
552 CreateMaterializedEquivalentIfRequired(info);
553 info->RemoveFromEquivalenceSet();
554 info->set_materialized(false);
555 info->set_equivalence_id(-1);
556 }
557 }
558
559 } // namespace interpreter
560 } // namespace internal
561 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698