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/compiler/escape-analysis.h" | 5 #include "src/compiler/escape-analysis.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "src/base/flags.h" | 9 #include "src/base/flags.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
194 bool AllFieldsClear() { | 194 bool AllFieldsClear() { |
195 for (size_t i = 0; i < fields_.size(); ++i) { | 195 for (size_t i = 0; i < fields_.size(); ++i) { |
196 if (fields_[i] != nullptr) { | 196 if (fields_[i] != nullptr) { |
197 return false; | 197 return false; |
198 } | 198 } |
199 } | 199 } |
200 return true; | 200 return true; |
201 } | 201 } |
202 bool UpdateFrom(const VirtualObject& other); | 202 bool UpdateFrom(const VirtualObject& other); |
203 bool MergeFrom(MergeCache* cache, Node* at, Graph* graph, | 203 bool MergeFrom(MergeCache* cache, Node* at, Graph* graph, |
204 CommonOperatorBuilder* common); | 204 CommonOperatorBuilder* common, bool initialMerge); |
205 void SetObjectState(Node* node) { object_state_ = node; } | 205 void SetObjectState(Node* node) { object_state_ = node; } |
206 Node* GetObjectState() const { return object_state_; } | 206 Node* GetObjectState() const { return object_state_; } |
207 bool IsCopyRequired() const { return status_ & kCopyRequired; } | 207 bool IsCopyRequired() const { return status_ & kCopyRequired; } |
208 void SetCopyRequired() { status_ |= kCopyRequired; } | 208 void SetCopyRequired() { status_ |= kCopyRequired; } |
209 bool NeedCopyForModification() { | 209 bool NeedCopyForModification() { |
210 if (!IsCopyRequired() || !IsInitialized()) { | 210 if (!IsCopyRequired() || !IsInitialized()) { |
211 return false; | 211 return false; |
212 } | 212 } |
213 return true; | 213 return true; |
214 } | 214 } |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
472 if (old != cache->fields()[n]) { | 472 if (old != cache->fields()[n]) { |
473 changed = true; | 473 changed = true; |
474 NodeProperties::ReplaceValueInput(rep, cache->fields()[n], n); | 474 NodeProperties::ReplaceValueInput(rep, cache->fields()[n], n); |
475 } | 475 } |
476 } | 476 } |
477 } | 477 } |
478 return changed; | 478 return changed; |
479 } | 479 } |
480 | 480 |
481 bool VirtualObject::MergeFrom(MergeCache* cache, Node* at, Graph* graph, | 481 bool VirtualObject::MergeFrom(MergeCache* cache, Node* at, Graph* graph, |
482 CommonOperatorBuilder* common) { | 482 CommonOperatorBuilder* common, |
| 483 bool initialMerge) { |
483 DCHECK(at->opcode() == IrOpcode::kEffectPhi || | 484 DCHECK(at->opcode() == IrOpcode::kEffectPhi || |
484 at->opcode() == IrOpcode::kPhi); | 485 at->opcode() == IrOpcode::kPhi); |
485 bool changed = false; | 486 bool changed = false; |
486 for (size_t i = 0; i < field_count(); ++i) { | 487 for (size_t i = 0; i < field_count(); ++i) { |
| 488 if (!initialMerge && GetField(i) == nullptr) continue; |
487 Node* field = cache->GetFields(i); | 489 Node* field = cache->GetFields(i); |
488 if (field && !IsCreatedPhi(i)) { | 490 if (field && !IsCreatedPhi(i)) { |
489 changed = changed || GetField(i) != field; | 491 changed = changed || GetField(i) != field; |
490 SetField(i, field); | 492 SetField(i, field); |
491 TRACE(" Field %zu agree on rep #%d\n", i, field->id()); | 493 TRACE(" Field %zu agree on rep #%d\n", i, field->id()); |
492 } else { | 494 } else { |
493 size_t arity = at->opcode() == IrOpcode::kEffectPhi | 495 size_t arity = at->opcode() == IrOpcode::kEffectPhi |
494 ? at->op()->EffectInputCount() | 496 ? at->op()->EffectInputCount() |
495 : at->op()->ValueInputCount(); | 497 : at->op()->ValueInputCount(); |
496 if (cache->fields().size() == arity) { | 498 if (cache->fields().size() == arity) { |
(...skipping 22 matching lines...) Expand all Loading... |
519 for (VirtualState* state : cache->states()) { | 521 for (VirtualState* state : cache->states()) { |
520 if (VirtualObject* obj = state->VirtualObjectFromAlias(alias)) { | 522 if (VirtualObject* obj = state->VirtualObjectFromAlias(alias)) { |
521 cache->objects().push_back(obj); | 523 cache->objects().push_back(obj); |
522 if (mergeObject == obj) { | 524 if (mergeObject == obj) { |
523 copy_merge_object = true; | 525 copy_merge_object = true; |
524 } | 526 } |
525 fields = std::min(obj->field_count(), fields); | 527 fields = std::min(obj->field_count(), fields); |
526 } | 528 } |
527 } | 529 } |
528 if (cache->objects().size() == cache->states().size()) { | 530 if (cache->objects().size() == cache->states().size()) { |
| 531 bool initialMerge = false; |
529 if (!mergeObject) { | 532 if (!mergeObject) { |
| 533 initialMerge = true; |
530 VirtualObject* obj = new (zone) | 534 VirtualObject* obj = new (zone) |
531 VirtualObject(cache->objects().front()->id(), this, zone, fields, | 535 VirtualObject(cache->objects().front()->id(), this, zone, fields, |
532 cache->objects().front()->IsInitialized()); | 536 cache->objects().front()->IsInitialized()); |
533 SetVirtualObject(alias, obj); | 537 SetVirtualObject(alias, obj); |
534 mergeObject = obj; | 538 mergeObject = obj; |
535 changed = true; | 539 changed = true; |
536 } else if (copy_merge_object) { | 540 } else if (copy_merge_object) { |
537 VirtualObject* obj = new (zone) VirtualObject(this, *mergeObject); | 541 VirtualObject* obj = new (zone) VirtualObject(this, *mergeObject); |
538 SetVirtualObject(alias, obj); | 542 SetVirtualObject(alias, obj); |
539 mergeObject = obj; | 543 mergeObject = obj; |
540 changed = true; | 544 changed = true; |
541 } else { | 545 } else { |
542 changed = mergeObject->ResizeFields(fields) || changed; | 546 changed = mergeObject->ResizeFields(fields) || changed; |
543 } | 547 } |
544 #ifdef DEBUG | 548 #ifdef DEBUG |
545 if (FLAG_trace_turbo_escape) { | 549 if (FLAG_trace_turbo_escape) { |
546 PrintF(" Alias @%d, merging into %p virtual objects", alias, | 550 PrintF(" Alias @%d, merging into %p virtual objects", alias, |
547 static_cast<void*>(mergeObject)); | 551 static_cast<void*>(mergeObject)); |
548 for (size_t i = 0; i < cache->objects().size(); i++) { | 552 for (size_t i = 0; i < cache->objects().size(); i++) { |
549 PrintF(" %p", static_cast<void*>(cache->objects()[i])); | 553 PrintF(" %p", static_cast<void*>(cache->objects()[i])); |
550 } | 554 } |
551 PrintF("\n"); | 555 PrintF("\n"); |
552 } | 556 } |
553 #endif // DEBUG | 557 #endif // DEBUG |
554 changed = mergeObject->MergeFrom(cache, at, graph, common) || changed; | 558 changed = |
| 559 mergeObject->MergeFrom(cache, at, graph, common, initialMerge) || |
| 560 changed; |
555 } else { | 561 } else { |
556 if (mergeObject) { | 562 if (mergeObject) { |
557 TRACE(" Alias %d, virtual object removed\n", alias); | 563 TRACE(" Alias %d, virtual object removed\n", alias); |
558 changed = true; | 564 changed = true; |
559 } | 565 } |
560 SetVirtualObject(alias, nullptr); | 566 SetVirtualObject(alias, nullptr); |
561 } | 567 } |
562 } | 568 } |
563 return changed; | 569 return changed; |
564 } | 570 } |
(...skipping 1141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1706 } | 1712 } |
1707 } | 1713 } |
1708 return false; | 1714 return false; |
1709 } | 1715 } |
1710 | 1716 |
1711 Graph* EscapeAnalysis::graph() const { return status_analysis_->graph(); } | 1717 Graph* EscapeAnalysis::graph() const { return status_analysis_->graph(); } |
1712 | 1718 |
1713 } // namespace compiler | 1719 } // namespace compiler |
1714 } // namespace internal | 1720 } // namespace internal |
1715 } // namespace v8 | 1721 } // namespace v8 |
OLD | NEW |