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 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 phi_[offset] = created_phi; | 87 phi_[offset] = created_phi; |
88 } | 88 } |
89 bool IsTracked() const { return status_ & kTracked; } | 89 bool IsTracked() const { return status_ & kTracked; } |
90 bool IsInitialized() const { return status_ & kInitialized; } | 90 bool IsInitialized() const { return status_ & kInitialized; } |
91 bool SetInitialized() { return status_ |= kInitialized; } | 91 bool SetInitialized() { return status_ |= kInitialized; } |
92 VirtualState* owner() const { return owner_; } | 92 VirtualState* owner() const { return owner_; } |
93 | 93 |
94 Node** fields_array() { return &fields_.front(); } | 94 Node** fields_array() { return &fields_.front(); } |
95 size_t field_count() { return fields_.size(); } | 95 size_t field_count() { return fields_.size(); } |
96 bool ResizeFields(size_t field_count) { | 96 bool ResizeFields(size_t field_count) { |
97 if (field_count != fields_.size()) { | 97 if (field_count > fields_.size()) { |
98 fields_.resize(field_count); | 98 fields_.resize(field_count); |
99 phi_.resize(field_count); | 99 phi_.resize(field_count); |
100 return true; | 100 return true; |
101 } | 101 } |
102 return false; | 102 return false; |
103 } | 103 } |
104 void ClearAllFields() { | 104 void ClearAllFields() { |
105 for (size_t i = 0; i < fields_.size(); ++i) { | 105 for (size_t i = 0; i < fields_.size(); ++i) { |
106 fields_[i] = nullptr; | 106 fields_[i] = nullptr; |
107 phi_[i] = false; | 107 phi_[i] = false; |
(...skipping 643 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
751 } | 751 } |
752 } | 752 } |
753 } | 753 } |
754 | 754 |
755 EscapeAnalysis::EscapeAnalysis(Graph* graph, CommonOperatorBuilder* common, | 755 EscapeAnalysis::EscapeAnalysis(Graph* graph, CommonOperatorBuilder* common, |
756 Zone* zone) | 756 Zone* zone) |
757 : status_analysis_(this, graph, zone), | 757 : status_analysis_(this, graph, zone), |
758 common_(common), | 758 common_(common), |
759 virtual_states_(zone), | 759 virtual_states_(zone), |
760 replacements_(zone), | 760 replacements_(zone), |
761 cache_(new (zone) MergeCache(zone)) {} | 761 cache_(nullptr) {} |
762 | 762 |
763 EscapeAnalysis::~EscapeAnalysis() {} | 763 EscapeAnalysis::~EscapeAnalysis() {} |
764 | 764 |
765 void EscapeAnalysis::Run() { | 765 void EscapeAnalysis::Run() { |
766 replacements_.resize(graph()->NodeCount()); | 766 replacements_.resize(graph()->NodeCount()); |
767 status_analysis_.AssignAliases(); | 767 status_analysis_.AssignAliases(); |
768 if (status_analysis_.AliasCount() == 0) return; | 768 if (status_analysis_.AliasCount() > 0) { |
769 status_analysis_.ResizeStatusVector(); | 769 cache_ = new (zone()) MergeCache(zone()); |
770 RunObjectAnalysis(); | 770 replacements_.resize(graph()->NodeCount()); |
771 status_analysis_.RunStatusAnalysis(); | 771 status_analysis_.ResizeStatusVector(); |
| 772 RunObjectAnalysis(); |
| 773 status_analysis_.RunStatusAnalysis(); |
| 774 } |
772 } | 775 } |
773 | 776 |
774 void EscapeStatusAnalysis::AssignAliases() { | 777 void EscapeStatusAnalysis::AssignAliases() { |
775 stack_.reserve(graph()->NodeCount() * 0.2); | 778 size_t max_size = 1024; |
| 779 size_t min_size = 32; |
| 780 size_t stack_size = std::min( |
| 781 std::max( |
| 782 std::min(graph()->NodeCount() / 5, graph()->NodeCount() / 20 + 128), |
| 783 min_size), |
| 784 max_size); |
| 785 stack_.reserve(stack_size); |
776 ResizeStatusVector(); | 786 ResizeStatusVector(); |
777 stack_.push_back(graph()->end()); | 787 stack_.push_back(graph()->end()); |
778 CHECK_LT(graph()->NodeCount(), kUntrackable); | 788 CHECK_LT(graph()->NodeCount(), kUntrackable); |
779 aliases_.resize(graph()->NodeCount(), kNotReachable); | 789 aliases_.resize(graph()->NodeCount(), kNotReachable); |
780 aliases_[graph()->end()->id()] = kUntrackable; | 790 aliases_[graph()->end()->id()] = kUntrackable; |
781 status_stack_.reserve(8); | 791 status_stack_.reserve(8); |
782 TRACE("Discovering trackable nodes"); | 792 TRACE("Discovering trackable nodes"); |
783 while (!stack_.empty()) { | 793 while (!stack_.empty()) { |
784 Node* node = stack_.back(); | 794 Node* node = stack_.back(); |
785 stack_.pop_back(); | 795 stack_.pop_back(); |
(...skipping 15 matching lines...) Expand all Loading... |
801 stack_.push_back(allocate); | 811 stack_.push_back(allocate); |
802 } | 812 } |
803 aliases_[allocate->id()] = NextAlias(); | 813 aliases_[allocate->id()] = NextAlias(); |
804 TRACE(" @%d:%s#%u", aliases_[allocate->id()], | 814 TRACE(" @%d:%s#%u", aliases_[allocate->id()], |
805 allocate->op()->mnemonic(), allocate->id()); | 815 allocate->op()->mnemonic(), allocate->id()); |
806 EnqueueForStatusAnalysis(allocate); | 816 EnqueueForStatusAnalysis(allocate); |
807 } | 817 } |
808 aliases_[node->id()] = aliases_[allocate->id()]; | 818 aliases_[node->id()] = aliases_[allocate->id()]; |
809 TRACE(" @%d:%s#%u", aliases_[node->id()], node->op()->mnemonic(), | 819 TRACE(" @%d:%s#%u", aliases_[node->id()], node->op()->mnemonic(), |
810 node->id()); | 820 node->id()); |
811 | |
812 } else { | |
813 aliases_[node->id()] = NextAlias(); | |
814 TRACE(" @%d:%s#%u", aliases_[node->id()], node->op()->mnemonic(), | |
815 node->id()); | |
816 } | 821 } |
817 break; | 822 break; |
818 } | 823 } |
819 default: | 824 default: |
820 DCHECK_EQ(aliases_[node->id()], kUntrackable); | 825 DCHECK_EQ(aliases_[node->id()], kUntrackable); |
821 break; | 826 break; |
822 } | 827 } |
823 for (Edge edge : node->input_edges()) { | 828 for (Edge edge : node->input_edges()) { |
824 Node* input = edge.to(); | 829 Node* input = edge.to(); |
825 if (aliases_[input->id()] == kNotReachable) { | 830 if (aliases_[input->id()] == kNotReachable) { |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
985 continue; | 990 continue; |
986 switch (node->opcode()) { | 991 switch (node->opcode()) { |
987 case IrOpcode::kStoreField: | 992 case IrOpcode::kStoreField: |
988 case IrOpcode::kLoadField: | 993 case IrOpcode::kLoadField: |
989 case IrOpcode::kStoreElement: | 994 case IrOpcode::kStoreElement: |
990 case IrOpcode::kLoadElement: | 995 case IrOpcode::kLoadElement: |
991 case IrOpcode::kFrameState: | 996 case IrOpcode::kFrameState: |
992 case IrOpcode::kStateValues: | 997 case IrOpcode::kStateValues: |
993 case IrOpcode::kReferenceEqual: | 998 case IrOpcode::kReferenceEqual: |
994 case IrOpcode::kFinishRegion: | 999 case IrOpcode::kFinishRegion: |
995 case IrOpcode::kPhi: | 1000 case IrOpcode::kObjectIsSmi: |
996 break; | 1001 break; |
997 default: | 1002 default: |
998 VirtualState* state = virtual_states_[node->id()]; | 1003 VirtualState* state = virtual_states_[node->id()]; |
999 if (VirtualObject* obj = ResolveVirtualObject(state, input)) { | 1004 if (VirtualObject* obj = ResolveVirtualObject(state, input)) { |
1000 if (!obj->AllFieldsClear()) { | 1005 if (!obj->AllFieldsClear()) { |
1001 obj = CopyForModificationAt(obj, state, node); | 1006 obj = CopyForModificationAt(obj, state, node); |
1002 obj->ClearAllFields(); | 1007 obj->ClearAllFields(); |
1003 TRACE("Cleared all fields of @%d:#%d\n", GetAlias(obj->id()), | 1008 TRACE("Cleared all fields of @%d:#%d\n", GetAlias(obj->id()), |
1004 obj->id()); | 1009 obj->id()); |
1005 } | 1010 } |
(...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1524 return true; | 1529 return true; |
1525 } | 1530 } |
1526 } | 1531 } |
1527 } | 1532 } |
1528 return false; | 1533 return false; |
1529 } | 1534 } |
1530 | 1535 |
1531 } // namespace compiler | 1536 } // namespace compiler |
1532 } // namespace internal | 1537 } // namespace internal |
1533 } // namespace v8 | 1538 } // namespace v8 |
OLD | NEW |