| 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; |
| 141 // Make sure we do not add keys to a proxy-level (see AddKeysFromProxy). | 142 // Make sure we do not add keys to a proxy-level (see AddKeysFromProxy). |
| 142 // We mark proxy-levels with a negative length | 143 // We mark proxy-levels with a negative length |
| 143 DCHECK_LE(0, level_string_length_); | 144 DCHECK_LE(0, level_string_length_); |
| 144 // Binary search over all but the last level. The last one might not be | 145 // Binary search over all but the last level. The last level might not be |
| 145 // sorted yet. | 146 // sorted yet. |
| 146 for (size_t i = 1; i < elements_.size(); i++) { | 147 for (size_t i = 1; i < elements_.size(); i++) { |
| 147 if (AccumulatorHasKey(elements_[i - 1], key)) return false; | 148 if (AccumulatorHasKey(elements_[i - 1], key)) return false; |
| 148 } | 149 } |
| 149 elements_.back()->push_back(key); | 150 elements_.back()->push_back(key); |
| 150 length_++; | 151 length_++; |
| 151 return true; | 152 return true; |
| 152 } | 153 } |
| 153 | 154 |
| 154 | 155 |
| 155 bool KeyAccumulator::AddStringKey(Handle<Object> key, | 156 bool KeyAccumulator::AddStringKey(Handle<Object> key, |
| 156 AddKeyConversion convert) { | 157 AddKeyConversion convert) { |
| 158 if (IsKeyHidden(key)) return false; |
| 157 if (string_properties_.is_null()) { | 159 if (string_properties_.is_null()) { |
| 158 string_properties_ = OrderedHashSet::Allocate(isolate_, 16); | 160 string_properties_ = OrderedHashSet::Allocate(isolate_, 16); |
| 159 } | 161 } |
| 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; |
| 178 if (symbol_properties_.is_null()) { | 179 if (symbol_properties_.is_null()) { |
| 179 symbol_properties_ = OrderedHashSet::Allocate(isolate_, 16); | 180 symbol_properties_ = OrderedHashSet::Allocate(isolate_, 16); |
| 180 } | 181 } |
| 181 int prev_size = symbol_properties_->NumberOfElements(); | 182 int prev_size = symbol_properties_->NumberOfElements(); |
| 182 symbol_properties_ = OrderedHashSet::Add(symbol_properties_, key); | 183 symbol_properties_ = OrderedHashSet::Add(symbol_properties_, key); |
| 183 if (prev_size < symbol_properties_->NumberOfElements()) { | 184 if (prev_size < symbol_properties_->NumberOfElements()) { |
| 184 length_++; | 185 length_++; |
| 185 level_symbol_length_++; | 186 level_symbol_length_++; |
| 186 return true; | 187 return true; |
| 187 } else { | 188 } else { |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 292 } | 293 } |
| 293 | 294 |
| 294 | 295 |
| 295 void KeyAccumulator::SortCurrentElementsList() { | 296 void KeyAccumulator::SortCurrentElementsList() { |
| 296 if (elements_.empty()) return; | 297 if (elements_.empty()) return; |
| 297 auto element_keys = elements_.back(); | 298 auto element_keys = elements_.back(); |
| 298 std::sort(element_keys->begin(), element_keys->end()); | 299 std::sort(element_keys->begin(), element_keys->end()); |
| 299 } | 300 } |
| 300 | 301 |
| 301 | 302 |
| 303 void KeyAccumulator::Prepare() { NextPrototype(); } |
| 304 |
| 305 |
| 302 void KeyAccumulator::NextPrototype() { | 306 void KeyAccumulator::NextPrototype() { |
| 303 // Store the protoLength on the first call of this method. | 307 // Store the protoLength on the first call of this method. |
| 304 if (!elements_.empty()) { | 308 if (!elements_.empty()) { |
| 305 level_lengths_.push_back(level_string_length_); | 309 level_lengths_.push_back(level_string_length_); |
| 306 level_lengths_.push_back(level_symbol_length_); | 310 level_lengths_.push_back(level_symbol_length_); |
| 307 } | 311 } |
| 308 elements_.push_back(new std::vector<uint32_t>()); | 312 elements_.push_back(new std::vector<uint32_t>()); |
| 309 level_string_length_ = 0; | 313 level_string_length_ = 0; |
| 310 level_symbol_length_ = 0; | 314 level_symbol_length_ = 0; |
| 311 } | 315 } |
| 312 | 316 |
| 313 | 317 |
| 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 |
| 314 } // namespace internal | 345 } // namespace internal |
| 315 } // namespace v8 | 346 } // namespace v8 |
| OLD | NEW |