| 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 |