OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/value-numbering-reducer.h" | 5 #include "src/compiler/value-numbering-reducer.h" |
6 | 6 |
7 #include <cstring> | 7 #include <cstring> |
8 | 8 |
9 #include "src/base/functional.h" | 9 #include "src/base/functional.h" |
10 #include "src/compiler/node-properties.h" | 10 #include "src/compiler/node-properties.h" |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
62 // Allocate the initial entries and insert the first entry. | 62 // Allocate the initial entries and insert the first entry. |
63 capacity_ = kInitialCapacity; | 63 capacity_ = kInitialCapacity; |
64 entries_ = temp_zone()->NewArray<Node*>(kInitialCapacity); | 64 entries_ = temp_zone()->NewArray<Node*>(kInitialCapacity); |
65 memset(entries_, 0, sizeof(*entries_) * kInitialCapacity); | 65 memset(entries_, 0, sizeof(*entries_) * kInitialCapacity); |
66 entries_[hash & (kInitialCapacity - 1)] = node; | 66 entries_[hash & (kInitialCapacity - 1)] = node; |
67 size_ = 1; | 67 size_ = 1; |
68 return NoChange(); | 68 return NoChange(); |
69 } | 69 } |
70 | 70 |
71 DCHECK(size_ < capacity_); | 71 DCHECK(size_ < capacity_); |
72 DCHECK(size_ * kCapacityToSizeRatio < capacity_); | 72 DCHECK(size_ + size_ / 4 < capacity_); |
73 | 73 |
74 const size_t mask = capacity_ - 1; | 74 const size_t mask = capacity_ - 1; |
75 size_t dead = capacity_; | 75 size_t dead = capacity_; |
76 | 76 |
77 for (size_t i = hash & mask;; i = (i + 1) & mask) { | 77 for (size_t i = hash & mask;; i = (i + 1) & mask) { |
78 Node* entry = entries_[i]; | 78 Node* entry = entries_[i]; |
79 if (!entry) { | 79 if (!entry) { |
80 if (dead != capacity_) { | 80 if (dead != capacity_) { |
81 // Reuse dead entry that we discovered on the way. | 81 // Reuse dead entry that we discovered on the way. |
82 entries_[dead] = node; | 82 entries_[dead] = node; |
83 } else { | 83 } else { |
84 // Have to insert a new entry. | 84 // Have to insert a new entry. |
85 entries_[i] = node; | 85 entries_[i] = node; |
86 size_++; | 86 size_++; |
87 | 87 |
88 // Resize to keep load factor below 1/kCapacityToSizeRatio. | 88 // Resize to keep load factor below 80% |
89 if (size_ * kCapacityToSizeRatio >= capacity_) Grow(); | 89 if (size_ + size_ / 4 >= capacity_) Grow(); |
90 } | 90 } |
91 DCHECK(size_ * kCapacityToSizeRatio < capacity_); | 91 DCHECK(size_ + size_ / 4 < capacity_); |
92 return NoChange(); | 92 return NoChange(); |
93 } | 93 } |
94 | 94 |
95 if (entry == node) { | 95 if (entry == node) { |
96 // We need to check for a certain class of collisions here. Imagine the | 96 // We need to check for a certain class of collisions here. Imagine the |
97 // following scenario: | 97 // following scenario: |
98 // | 98 // |
99 // 1. We insert node1 with op1 and certain inputs at index i. | 99 // 1. We insert node1 with op1 and certain inputs at index i. |
100 // 2. We insert node2 with op2 and certain inputs at index i+1. | 100 // 2. We insert node2 with op2 and certain inputs at index i+1. |
101 // 3. Some other reducer changes node1 to op2 and the inputs from node2. | 101 // 3. Some other reducer changes node1 to op2 and the inputs from node2. |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 } | 145 } |
146 } | 146 } |
147 } | 147 } |
148 return Replace(entry); | 148 return Replace(entry); |
149 } | 149 } |
150 } | 150 } |
151 } | 151 } |
152 | 152 |
153 | 153 |
154 void ValueNumberingReducer::Grow() { | 154 void ValueNumberingReducer::Grow() { |
155 // Allocate a new block of entries kCapacityToSizeRatio times the previous | 155 // Allocate a new block of entries double the previous capacity. |
156 // capacity. | |
157 Node** const old_entries = entries_; | 156 Node** const old_entries = entries_; |
158 size_t const old_capacity = capacity_; | 157 size_t const old_capacity = capacity_; |
159 capacity_ *= kCapacityToSizeRatio; | 158 capacity_ *= 2; |
160 entries_ = temp_zone()->NewArray<Node*>(capacity_); | 159 entries_ = temp_zone()->NewArray<Node*>(capacity_); |
161 memset(entries_, 0, sizeof(*entries_) * capacity_); | 160 memset(entries_, 0, sizeof(*entries_) * capacity_); |
162 size_ = 0; | 161 size_ = 0; |
163 size_t const mask = capacity_ - 1; | 162 size_t const mask = capacity_ - 1; |
164 | 163 |
165 // Insert the old entries into the new block (skipping dead nodes). | 164 // Insert the old entries into the new block (skipping dead nodes). |
166 for (size_t i = 0; i < old_capacity; ++i) { | 165 for (size_t i = 0; i < old_capacity; ++i) { |
167 Node* const old_entry = old_entries[i]; | 166 Node* const old_entry = old_entries[i]; |
168 if (!old_entry || old_entry->IsDead()) continue; | 167 if (!old_entry || old_entry->IsDead()) continue; |
169 for (size_t j = HashCode(old_entry) & mask;; j = (j + 1) & mask) { | 168 for (size_t j = HashCode(old_entry) & mask;; j = (j + 1) & mask) { |
170 Node* const entry = entries_[j]; | 169 Node* const entry = entries_[j]; |
171 if (entry == old_entry) { | 170 if (entry == old_entry) { |
172 // Skip duplicate of the old entry. | 171 // Skip duplicate of the old entry. |
173 break; | 172 break; |
174 } | 173 } |
175 if (!entry) { | 174 if (!entry) { |
176 entries_[j] = old_entry; | 175 entries_[j] = old_entry; |
177 size_++; | 176 size_++; |
178 break; | 177 break; |
179 } | 178 } |
180 } | 179 } |
181 } | 180 } |
182 } | 181 } |
183 | 182 |
184 } // namespace compiler | 183 } // namespace compiler |
185 } // namespace internal | 184 } // namespace internal |
186 } // namespace v8 | 185 } // namespace v8 |
OLD | NEW |