OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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/key-accumulator.h" | 5 #include "src/key-accumulator.h" |
6 | 6 |
7 #include "src/elements.h" | 7 #include "src/elements.h" |
8 #include "src/factory.h" | 8 #include "src/factory.h" |
9 #include "src/isolate-inl.h" | 9 #include "src/isolate-inl.h" |
10 #include "src/objects-inl.h" | 10 #include "src/objects-inl.h" |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 } | 131 } |
132 } | 132 } |
133 return AddStringKey(key, convert); | 133 return AddStringKey(key, convert); |
134 } | 134 } |
135 | 135 |
136 | 136 |
137 bool KeyAccumulator::AddKey(uint32_t key) { return AddIntegerKey(key); } | 137 bool KeyAccumulator::AddKey(uint32_t key) { return AddIntegerKey(key); } |
138 | 138 |
139 | 139 |
140 bool KeyAccumulator::AddIntegerKey(uint32_t key) { | 140 bool KeyAccumulator::AddIntegerKey(uint32_t key) { |
141 if (IsKeyHidden(key)) return false; | |
142 // Make sure we do not add keys to a proxy-level (see AddKeysFromProxy). | 141 // Make sure we do not add keys to a proxy-level (see AddKeysFromProxy). |
143 // We mark proxy-levels with a negative length | 142 // We mark proxy-levels with a negative length |
144 DCHECK_LE(0, level_string_length_); | 143 DCHECK_LE(0, level_string_length_); |
145 // Binary search over all but the last level. The last level might not be | 144 // Binary search over all but the last level. The last one might not be |
146 // sorted yet. | 145 // sorted yet. |
147 for (size_t i = 1; i < elements_.size(); i++) { | 146 for (size_t i = 1; i < elements_.size(); i++) { |
148 if (AccumulatorHasKey(elements_[i - 1], key)) return false; | 147 if (AccumulatorHasKey(elements_[i - 1], key)) return false; |
149 } | 148 } |
150 elements_.back()->push_back(key); | 149 elements_.back()->push_back(key); |
151 length_++; | 150 length_++; |
152 return true; | 151 return true; |
153 } | 152 } |
154 | 153 |
155 | 154 |
156 bool KeyAccumulator::AddStringKey(Handle<Object> key, | 155 bool KeyAccumulator::AddStringKey(Handle<Object> key, |
157 AddKeyConversion convert) { | 156 AddKeyConversion convert) { |
158 if (IsKeyHidden(key)) return false; | |
159 if (string_properties_.is_null()) { | 157 if (string_properties_.is_null()) { |
160 string_properties_ = OrderedHashSet::Allocate(isolate_, 16); | 158 string_properties_ = OrderedHashSet::Allocate(isolate_, 16); |
161 } | 159 } |
| 160 // TODO(cbruni): remove this conversion once we throw the correct TypeError |
| 161 // for non-string/symbol elements returned by proxies |
162 if (convert == PROXY_MAGIC && key->IsNumber()) { | 162 if (convert == PROXY_MAGIC && key->IsNumber()) { |
163 key = isolate_->factory()->NumberToString(key); | 163 key = isolate_->factory()->NumberToString(key); |
164 } | 164 } |
165 int prev_size = string_properties_->NumberOfElements(); | 165 int prev_size = string_properties_->NumberOfElements(); |
166 string_properties_ = OrderedHashSet::Add(string_properties_, key); | 166 string_properties_ = OrderedHashSet::Add(string_properties_, key); |
167 if (prev_size < string_properties_->NumberOfElements()) { | 167 if (prev_size < string_properties_->NumberOfElements()) { |
168 length_++; | 168 length_++; |
169 level_string_length_++; | 169 level_string_length_++; |
170 return true; | 170 return true; |
171 } else { | 171 } else { |
172 return false; | 172 return false; |
173 } | 173 } |
174 } | 174 } |
175 | 175 |
176 | 176 |
177 bool KeyAccumulator::AddSymbolKey(Handle<Object> key) { | 177 bool KeyAccumulator::AddSymbolKey(Handle<Object> key) { |
178 if (IsKeyHidden(key)) return false; | |
179 if (symbol_properties_.is_null()) { | 178 if (symbol_properties_.is_null()) { |
180 symbol_properties_ = OrderedHashSet::Allocate(isolate_, 16); | 179 symbol_properties_ = OrderedHashSet::Allocate(isolate_, 16); |
181 } | 180 } |
182 int prev_size = symbol_properties_->NumberOfElements(); | 181 int prev_size = symbol_properties_->NumberOfElements(); |
183 symbol_properties_ = OrderedHashSet::Add(symbol_properties_, key); | 182 symbol_properties_ = OrderedHashSet::Add(symbol_properties_, key); |
184 if (prev_size < symbol_properties_->NumberOfElements()) { | 183 if (prev_size < symbol_properties_->NumberOfElements()) { |
185 length_++; | 184 length_++; |
186 level_symbol_length_++; | 185 level_symbol_length_++; |
187 return true; | 186 return true; |
188 } else { | 187 } else { |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
293 } | 292 } |
294 | 293 |
295 | 294 |
296 void KeyAccumulator::SortCurrentElementsList() { | 295 void KeyAccumulator::SortCurrentElementsList() { |
297 if (elements_.empty()) return; | 296 if (elements_.empty()) return; |
298 auto element_keys = elements_.back(); | 297 auto element_keys = elements_.back(); |
299 std::sort(element_keys->begin(), element_keys->end()); | 298 std::sort(element_keys->begin(), element_keys->end()); |
300 } | 299 } |
301 | 300 |
302 | 301 |
303 void KeyAccumulator::Prepare() { NextPrototype(); } | |
304 | |
305 | |
306 void KeyAccumulator::NextPrototype() { | 302 void KeyAccumulator::NextPrototype() { |
307 // Store the protoLength on the first call of this method. | 303 // Store the protoLength on the first call of this method. |
308 if (!elements_.empty()) { | 304 if (!elements_.empty()) { |
309 level_lengths_.push_back(level_string_length_); | 305 level_lengths_.push_back(level_string_length_); |
310 level_lengths_.push_back(level_symbol_length_); | 306 level_lengths_.push_back(level_symbol_length_); |
311 } | 307 } |
312 elements_.push_back(new std::vector<uint32_t>()); | 308 elements_.push_back(new std::vector<uint32_t>()); |
313 level_string_length_ = 0; | 309 level_string_length_ = 0; |
314 level_symbol_length_ = 0; | 310 level_symbol_length_ = 0; |
315 } | 311 } |
316 | 312 |
317 | 313 |
318 void KeyAccumulator::HideKey(uint32_t key) { hidden_element_keys_.insert(key); } | |
319 | |
320 | |
321 void KeyAccumulator::HideKey(Object* key) { | |
322 HideKey(Handle<Object>(key, isolate_)); | |
323 } | |
324 | |
325 | |
326 void KeyAccumulator::HideKey(Handle<Object> key) { | |
327 if (hidden_keys_.is_null()) { | |
328 hidden_keys_ = OrderedHashSet::Allocate(isolate_, 8); | |
329 } | |
330 hidden_keys_ = OrderedHashSet::Add(hidden_keys_, key); | |
331 } | |
332 | |
333 | |
334 bool KeyAccumulator::IsKeyHidden(uint32_t key) { | |
335 return hidden_element_keys_.count(key); | |
336 } | |
337 | |
338 | |
339 bool KeyAccumulator::IsKeyHidden(Handle<Object> key) { | |
340 if (hidden_keys_.is_null()) return false; | |
341 return OrderedHashSet::HasKey(hidden_keys_, key); | |
342 } | |
343 | |
344 | |
345 } // namespace internal | 314 } // namespace internal |
346 } // namespace v8 | 315 } // namespace v8 |
OLD | NEW |