| 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/objects.h" | 5 #include "src/objects.h" |
| 6 | 6 |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 #include <iomanip> | 8 #include <iomanip> |
| 9 #include <sstream> | 9 #include <sstream> |
| 10 | 10 |
| (...skipping 1502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1513 Context* native_context = isolate->context()->native_context(); | 1513 Context* native_context = isolate->context()->native_context(); |
| 1514 JSFunction* constructor_function = | 1514 JSFunction* constructor_function = |
| 1515 JSFunction::cast(native_context->get(constructor_function_index)); | 1515 JSFunction::cast(native_context->get(constructor_function_index)); |
| 1516 return constructor_function->initial_map(); | 1516 return constructor_function->initial_map(); |
| 1517 } | 1517 } |
| 1518 return isolate->heap()->null_value()->map(); | 1518 return isolate->heap()->null_value()->map(); |
| 1519 } | 1519 } |
| 1520 | 1520 |
| 1521 | 1521 |
| 1522 Object* Object::GetHash() { | 1522 Object* Object::GetHash() { |
| 1523 DisallowHeapAllocation no_gc; |
| 1523 Object* hash = GetSimpleHash(); | 1524 Object* hash = GetSimpleHash(); |
| 1524 if (hash->IsSmi()) return hash; | 1525 if (hash->IsSmi()) return hash; |
| 1525 | 1526 |
| 1526 DisallowHeapAllocation no_gc; | |
| 1527 DCHECK(IsJSReceiver()); | 1527 DCHECK(IsJSReceiver()); |
| 1528 JSReceiver* receiver = JSReceiver::cast(this); | 1528 JSReceiver* receiver = JSReceiver::cast(this); |
| 1529 Isolate* isolate = receiver->GetIsolate(); | 1529 Isolate* isolate = receiver->GetIsolate(); |
| 1530 return *JSReceiver::GetIdentityHash(isolate, handle(receiver, isolate)); | 1530 return *JSReceiver::GetIdentityHash(isolate, handle(receiver, isolate)); |
| 1531 } | 1531 } |
| 1532 | 1532 |
| 1533 | 1533 |
| 1534 Object* Object::GetSimpleHash() { | 1534 Object* Object::GetSimpleHash() { |
| 1535 // The object is either a Smi, a HeapNumber, a name, an odd-ball, | 1535 // The object is either a Smi, a HeapNumber, a name, an odd-ball, |
| 1536 // a SIMD value type, a real JS object, or a Harmony proxy. | 1536 // a SIMD value type, a real JS object, or a Harmony proxy. |
| (...skipping 4145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5682 } else { | 5682 } else { |
| 5683 iteration_order = NameDictionary::BuildIterationIndicesArray(dictionary); | 5683 iteration_order = NameDictionary::BuildIterationIndicesArray(dictionary); |
| 5684 } | 5684 } |
| 5685 | 5685 |
| 5686 int instance_descriptor_length = iteration_order->length(); | 5686 int instance_descriptor_length = iteration_order->length(); |
| 5687 int number_of_fields = 0; | 5687 int number_of_fields = 0; |
| 5688 | 5688 |
| 5689 // Compute the length of the instance descriptor. | 5689 // Compute the length of the instance descriptor. |
| 5690 for (int i = 0; i < instance_descriptor_length; i++) { | 5690 for (int i = 0; i < instance_descriptor_length; i++) { |
| 5691 int index = Smi::cast(iteration_order->get(i))->value(); | 5691 int index = Smi::cast(iteration_order->get(i))->value(); |
| 5692 DCHECK(dictionary->IsKey(dictionary->KeyAt(index))); | 5692 DCHECK(dictionary->IsKey(isolate, dictionary->KeyAt(index))); |
| 5693 | 5693 |
| 5694 Object* value = dictionary->ValueAt(index); | 5694 Object* value = dictionary->ValueAt(index); |
| 5695 PropertyType type = dictionary->DetailsAt(index).type(); | 5695 PropertyType type = dictionary->DetailsAt(index).type(); |
| 5696 if (type == DATA && !value->IsJSFunction()) { | 5696 if (type == DATA && !value->IsJSFunction()) { |
| 5697 number_of_fields += 1; | 5697 number_of_fields += 1; |
| 5698 } | 5698 } |
| 5699 } | 5699 } |
| 5700 | 5700 |
| 5701 Handle<Map> old_map(object->map(), isolate); | 5701 Handle<Map> old_map(object->map(), isolate); |
| 5702 | 5702 |
| (...skipping 1914 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7617 return iter.GetCurrent<JSObject>()->map()->is_extensible(); | 7617 return iter.GetCurrent<JSObject>()->map()->is_extensible(); |
| 7618 } | 7618 } |
| 7619 return object->map()->is_extensible(); | 7619 return object->map()->is_extensible(); |
| 7620 } | 7620 } |
| 7621 | 7621 |
| 7622 | 7622 |
| 7623 template <typename Dictionary> | 7623 template <typename Dictionary> |
| 7624 static void ApplyAttributesToDictionary(Dictionary* dictionary, | 7624 static void ApplyAttributesToDictionary(Dictionary* dictionary, |
| 7625 const PropertyAttributes attributes) { | 7625 const PropertyAttributes attributes) { |
| 7626 int capacity = dictionary->Capacity(); | 7626 int capacity = dictionary->Capacity(); |
| 7627 Isolate* isolate = dictionary->GetIsolate(); |
| 7627 for (int i = 0; i < capacity; i++) { | 7628 for (int i = 0; i < capacity; i++) { |
| 7628 Object* k = dictionary->KeyAt(i); | 7629 Object* k = dictionary->KeyAt(i); |
| 7629 if (dictionary->IsKey(k) && | 7630 if (dictionary->IsKey(isolate, k) && |
| 7630 !(k->IsSymbol() && Symbol::cast(k)->is_private())) { | 7631 !(k->IsSymbol() && Symbol::cast(k)->is_private())) { |
| 7631 PropertyDetails details = dictionary->DetailsAt(i); | 7632 PropertyDetails details = dictionary->DetailsAt(i); |
| 7632 int attrs = attributes; | 7633 int attrs = attributes; |
| 7633 // READ_ONLY is an invalid attribute for JS setters/getters. | 7634 // READ_ONLY is an invalid attribute for JS setters/getters. |
| 7634 if ((attributes & READ_ONLY) && details.type() == ACCESSOR_CONSTANT) { | 7635 if ((attributes & READ_ONLY) && details.type() == ACCESSOR_CONSTANT) { |
| 7635 Object* v = dictionary->ValueAt(i); | 7636 Object* v = dictionary->ValueAt(i); |
| 7636 if (v->IsPropertyCell()) v = PropertyCell::cast(v)->value(); | 7637 if (v->IsPropertyCell()) v = PropertyCell::cast(v)->value(); |
| 7637 if (v->IsAccessorPair()) attrs &= ~READ_ONLY; | 7638 if (v->IsAccessorPair()) attrs &= ~READ_ONLY; |
| 7638 } | 7639 } |
| 7639 details = details.CopyAddAttributes( | 7640 details = details.CopyAddAttributes( |
| (...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7946 } | 7947 } |
| 7947 } | 7948 } |
| 7948 break; | 7949 break; |
| 7949 } | 7950 } |
| 7950 case DICTIONARY_ELEMENTS: { | 7951 case DICTIONARY_ELEMENTS: { |
| 7951 Handle<SeededNumberDictionary> element_dictionary( | 7952 Handle<SeededNumberDictionary> element_dictionary( |
| 7952 copy->element_dictionary()); | 7953 copy->element_dictionary()); |
| 7953 int capacity = element_dictionary->Capacity(); | 7954 int capacity = element_dictionary->Capacity(); |
| 7954 for (int i = 0; i < capacity; i++) { | 7955 for (int i = 0; i < capacity; i++) { |
| 7955 Object* k = element_dictionary->KeyAt(i); | 7956 Object* k = element_dictionary->KeyAt(i); |
| 7956 if (element_dictionary->IsKey(k)) { | 7957 if (element_dictionary->IsKey(isolate, k)) { |
| 7957 Handle<Object> value(element_dictionary->ValueAt(i), isolate); | 7958 Handle<Object> value(element_dictionary->ValueAt(i), isolate); |
| 7958 if (value->IsJSObject()) { | 7959 if (value->IsJSObject()) { |
| 7959 Handle<JSObject> result; | 7960 Handle<JSObject> result; |
| 7960 ASSIGN_RETURN_ON_EXCEPTION( | 7961 ASSIGN_RETURN_ON_EXCEPTION( |
| 7961 isolate, result, | 7962 isolate, result, |
| 7962 VisitElementOrProperty(copy, Handle<JSObject>::cast(value)), | 7963 VisitElementOrProperty(copy, Handle<JSObject>::cast(value)), |
| 7963 JSObject); | 7964 JSObject); |
| 7964 if (copying) { | 7965 if (copying) { |
| 7965 element_dictionary->ValueAtPut(i, *result); | 7966 element_dictionary->ValueAtPut(i, *result); |
| 7966 } | 7967 } |
| (...skipping 7364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15331 | 15332 |
| 15332 | 15333 |
| 15333 // Certain compilers request function template instantiation when they | 15334 // Certain compilers request function template instantiation when they |
| 15334 // see the definition of the other template functions in the | 15335 // see the definition of the other template functions in the |
| 15335 // class. This requires us to have the template functions put | 15336 // class. This requires us to have the template functions put |
| 15336 // together, so even though this function belongs in objects-debug.cc, | 15337 // together, so even though this function belongs in objects-debug.cc, |
| 15337 // we keep it here instead to satisfy certain compilers. | 15338 // we keep it here instead to satisfy certain compilers. |
| 15338 #ifdef OBJECT_PRINT | 15339 #ifdef OBJECT_PRINT |
| 15339 template <typename Derived, typename Shape, typename Key> | 15340 template <typename Derived, typename Shape, typename Key> |
| 15340 void Dictionary<Derived, Shape, Key>::Print(std::ostream& os) { // NOLINT | 15341 void Dictionary<Derived, Shape, Key>::Print(std::ostream& os) { // NOLINT |
| 15342 Isolate* isolate = this->GetIsolate(); |
| 15341 int capacity = this->Capacity(); | 15343 int capacity = this->Capacity(); |
| 15342 for (int i = 0; i < capacity; i++) { | 15344 for (int i = 0; i < capacity; i++) { |
| 15343 Object* k = this->KeyAt(i); | 15345 Object* k = this->KeyAt(i); |
| 15344 if (this->IsKey(k)) { | 15346 if (this->IsKey(isolate, k)) { |
| 15345 os << "\n "; | 15347 os << "\n "; |
| 15346 if (k->IsString()) { | 15348 if (k->IsString()) { |
| 15347 String::cast(k)->StringPrint(os); | 15349 String::cast(k)->StringPrint(os); |
| 15348 } else { | 15350 } else { |
| 15349 os << Brief(k); | 15351 os << Brief(k); |
| 15350 } | 15352 } |
| 15351 os << ": " << Brief(this->ValueAt(i)) << " " << this->DetailsAt(i); | 15353 os << ": " << Brief(this->ValueAt(i)) << " " << this->DetailsAt(i); |
| 15352 } | 15354 } |
| 15353 } | 15355 } |
| 15354 } | 15356 } |
| 15355 template <typename Derived, typename Shape, typename Key> | 15357 template <typename Derived, typename Shape, typename Key> |
| 15356 void Dictionary<Derived, Shape, Key>::Print() { | 15358 void Dictionary<Derived, Shape, Key>::Print() { |
| 15357 OFStream os(stdout); | 15359 OFStream os(stdout); |
| 15358 Print(os); | 15360 Print(os); |
| 15359 } | 15361 } |
| 15360 #endif | 15362 #endif |
| 15361 | 15363 |
| 15362 | 15364 |
| 15363 template<typename Derived, typename Shape, typename Key> | 15365 template<typename Derived, typename Shape, typename Key> |
| 15364 void Dictionary<Derived, Shape, Key>::CopyValuesTo(FixedArray* elements) { | 15366 void Dictionary<Derived, Shape, Key>::CopyValuesTo(FixedArray* elements) { |
| 15367 Isolate* isolate = this->GetIsolate(); |
| 15365 int pos = 0; | 15368 int pos = 0; |
| 15366 int capacity = this->Capacity(); | 15369 int capacity = this->Capacity(); |
| 15367 DisallowHeapAllocation no_gc; | 15370 DisallowHeapAllocation no_gc; |
| 15368 WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc); | 15371 WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc); |
| 15369 for (int i = 0; i < capacity; i++) { | 15372 for (int i = 0; i < capacity; i++) { |
| 15370 Object* k = this->KeyAt(i); | 15373 Object* k = this->KeyAt(i); |
| 15371 if (this->IsKey(k)) { | 15374 if (this->IsKey(isolate, k)) { |
| 15372 elements->set(pos++, this->ValueAt(i), mode); | 15375 elements->set(pos++, this->ValueAt(i), mode); |
| 15373 } | 15376 } |
| 15374 } | 15377 } |
| 15375 DCHECK(pos == elements->length()); | 15378 DCHECK(pos == elements->length()); |
| 15376 } | 15379 } |
| 15377 | 15380 |
| 15378 | 15381 |
| 15379 MaybeHandle<Object> JSObject::GetPropertyWithInterceptor(LookupIterator* it, | 15382 MaybeHandle<Object> JSObject::GetPropertyWithInterceptor(LookupIterator* it, |
| 15380 bool* done) { | 15383 bool* done) { |
| 15381 *done = false; | 15384 *done = false; |
| (...skipping 784 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16166 for (int j = 0; j < Shape::kEntrySize; j++) { | 16169 for (int j = 0; j < Shape::kEntrySize; j++) { |
| 16167 set(index2 + j, temp[j], mode); | 16170 set(index2 + j, temp[j], mode); |
| 16168 } | 16171 } |
| 16169 } | 16172 } |
| 16170 | 16173 |
| 16171 | 16174 |
| 16172 template<typename Derived, typename Shape, typename Key> | 16175 template<typename Derived, typename Shape, typename Key> |
| 16173 void HashTable<Derived, Shape, Key>::Rehash(Key key) { | 16176 void HashTable<Derived, Shape, Key>::Rehash(Key key) { |
| 16174 DisallowHeapAllocation no_gc; | 16177 DisallowHeapAllocation no_gc; |
| 16175 WriteBarrierMode mode = GetWriteBarrierMode(no_gc); | 16178 WriteBarrierMode mode = GetWriteBarrierMode(no_gc); |
| 16179 Isolate* isolate = GetIsolate(); |
| 16176 uint32_t capacity = Capacity(); | 16180 uint32_t capacity = Capacity(); |
| 16177 bool done = false; | 16181 bool done = false; |
| 16178 for (int probe = 1; !done; probe++) { | 16182 for (int probe = 1; !done; probe++) { |
| 16179 // All elements at entries given by one of the first _probe_ probes | 16183 // All elements at entries given by one of the first _probe_ probes |
| 16180 // are placed correctly. Other elements might need to be moved. | 16184 // are placed correctly. Other elements might need to be moved. |
| 16181 done = true; | 16185 done = true; |
| 16182 for (uint32_t current = 0; current < capacity; current++) { | 16186 for (uint32_t current = 0; current < capacity; current++) { |
| 16183 Object* current_key = get(EntryToIndex(current)); | 16187 Object* current_key = get(EntryToIndex(current)); |
| 16184 if (IsKey(current_key)) { | 16188 if (IsKey(isolate, current_key)) { |
| 16185 uint32_t target = EntryForProbe(key, current_key, probe, current); | 16189 uint32_t target = EntryForProbe(key, current_key, probe, current); |
| 16186 if (current == target) continue; | 16190 if (current == target) continue; |
| 16187 Object* target_key = get(EntryToIndex(target)); | 16191 Object* target_key = get(EntryToIndex(target)); |
| 16188 if (!IsKey(target_key) || | 16192 if (!IsKey(target_key) || |
| 16189 EntryForProbe(key, target_key, probe, target) != target) { | 16193 EntryForProbe(key, target_key, probe, target) != target) { |
| 16190 // Put the current element into the correct position. | 16194 // Put the current element into the correct position. |
| 16191 Swap(current, target, mode); | 16195 Swap(current, target, mode); |
| 16192 // The other element will be processed on the next iteration. | 16196 // The other element will be processed on the next iteration. |
| 16193 current--; | 16197 current--; |
| 16194 } else { | 16198 } else { |
| 16195 // The place for the current element is occupied. Leave the element | 16199 // The place for the current element is occupied. Leave the element |
| 16196 // for the next probe. | 16200 // for the next probe. |
| 16197 done = false; | 16201 done = false; |
| 16198 } | 16202 } |
| 16199 } | 16203 } |
| 16200 } | 16204 } |
| 16201 } | 16205 } |
| 16202 // Wipe deleted entries. | 16206 // Wipe deleted entries. |
| 16203 Heap* heap = GetHeap(); | 16207 Object* the_hole = isolate->heap()->the_hole_value(); |
| 16204 Object* the_hole = heap->the_hole_value(); | 16208 Object* undefined = isolate->heap()->undefined_value(); |
| 16205 Object* undefined = heap->undefined_value(); | |
| 16206 for (uint32_t current = 0; current < capacity; current++) { | 16209 for (uint32_t current = 0; current < capacity; current++) { |
| 16207 if (get(EntryToIndex(current)) == the_hole) { | 16210 if (get(EntryToIndex(current)) == the_hole) { |
| 16208 set(EntryToIndex(current), undefined); | 16211 set(EntryToIndex(current), undefined); |
| 16209 } | 16212 } |
| 16210 } | 16213 } |
| 16211 SetNumberOfDeletedElements(0); | 16214 SetNumberOfDeletedElements(0); |
| 16212 } | 16215 } |
| 16213 | 16216 |
| 16214 | 16217 |
| 16215 template<typename Derived, typename Shape, typename Key> | 16218 template<typename Derived, typename Shape, typename Key> |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16286 return new_table; | 16289 return new_table; |
| 16287 } | 16290 } |
| 16288 | 16291 |
| 16289 | 16292 |
| 16290 template<typename Derived, typename Shape, typename Key> | 16293 template<typename Derived, typename Shape, typename Key> |
| 16291 uint32_t HashTable<Derived, Shape, Key>::FindInsertionEntry(uint32_t hash) { | 16294 uint32_t HashTable<Derived, Shape, Key>::FindInsertionEntry(uint32_t hash) { |
| 16292 uint32_t capacity = Capacity(); | 16295 uint32_t capacity = Capacity(); |
| 16293 uint32_t entry = FirstProbe(hash, capacity); | 16296 uint32_t entry = FirstProbe(hash, capacity); |
| 16294 uint32_t count = 1; | 16297 uint32_t count = 1; |
| 16295 // EnsureCapacity will guarantee the hash table is never full. | 16298 // EnsureCapacity will guarantee the hash table is never full. |
| 16296 Heap* heap = GetHeap(); | 16299 Isolate* isolate = GetIsolate(); |
| 16297 Object* the_hole = heap->the_hole_value(); | |
| 16298 Object* undefined = heap->undefined_value(); | |
| 16299 while (true) { | 16300 while (true) { |
| 16300 Object* element = KeyAt(entry); | 16301 Object* element = KeyAt(entry); |
| 16301 if (element == the_hole || element == undefined) break; | 16302 if (!IsKey(isolate, element)) break; |
| 16302 entry = NextProbe(entry, count++, capacity); | 16303 entry = NextProbe(entry, count++, capacity); |
| 16303 } | 16304 } |
| 16304 return entry; | 16305 return entry; |
| 16305 } | 16306 } |
| 16306 | 16307 |
| 16307 | 16308 |
| 16308 // Force instantiation of template instances class. | 16309 // Force instantiation of template instances class. |
| 16309 // Please note this list is compiler dependent. | 16310 // Please note this list is compiler dependent. |
| 16310 | 16311 |
| 16311 template class HashTable<StringTable, StringTableShape, HashTableKey*>; | 16312 template class HashTable<StringTable, StringTableShape, HashTableKey*>; |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16483 | 16484 |
| 16484 uint32_t pos = 0; | 16485 uint32_t pos = 0; |
| 16485 uint32_t undefs = 0; | 16486 uint32_t undefs = 0; |
| 16486 int capacity = dict->Capacity(); | 16487 int capacity = dict->Capacity(); |
| 16487 Handle<Smi> bailout(Smi::FromInt(-1), isolate); | 16488 Handle<Smi> bailout(Smi::FromInt(-1), isolate); |
| 16488 // Entry to the new dictionary does not cause it to grow, as we have | 16489 // Entry to the new dictionary does not cause it to grow, as we have |
| 16489 // allocated one that is large enough for all entries. | 16490 // allocated one that is large enough for all entries. |
| 16490 DisallowHeapAllocation no_gc; | 16491 DisallowHeapAllocation no_gc; |
| 16491 for (int i = 0; i < capacity; i++) { | 16492 for (int i = 0; i < capacity; i++) { |
| 16492 Object* k = dict->KeyAt(i); | 16493 Object* k = dict->KeyAt(i); |
| 16493 if (!dict->IsKey(k)) continue; | 16494 if (!dict->IsKey(isolate, k)) continue; |
| 16494 | 16495 |
| 16495 DCHECK(k->IsNumber()); | 16496 DCHECK(k->IsNumber()); |
| 16496 DCHECK(!k->IsSmi() || Smi::cast(k)->value() >= 0); | 16497 DCHECK(!k->IsSmi() || Smi::cast(k)->value() >= 0); |
| 16497 DCHECK(!k->IsHeapNumber() || HeapNumber::cast(k)->value() >= 0); | 16498 DCHECK(!k->IsHeapNumber() || HeapNumber::cast(k)->value() >= 0); |
| 16498 DCHECK(!k->IsHeapNumber() || HeapNumber::cast(k)->value() <= kMaxUInt32); | 16499 DCHECK(!k->IsHeapNumber() || HeapNumber::cast(k)->value() <= kMaxUInt32); |
| 16499 | 16500 |
| 16500 HandleScope scope(isolate); | 16501 HandleScope scope(isolate); |
| 16501 Handle<Object> value(dict->ValueAt(i), isolate); | 16502 Handle<Object> value(dict->ValueAt(i), isolate); |
| 16502 PropertyDetails details = dict->DetailsAt(i); | 16503 PropertyDetails details = dict->DetailsAt(i); |
| 16503 if (details.type() == ACCESSOR_CONSTANT || details.IsReadOnly()) { | 16504 if (details.type() == ACCESSOR_CONSTANT || details.IsReadOnly()) { |
| (...skipping 618 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17122 | 17123 |
| 17123 // Initialize the next enumeration index. | 17124 // Initialize the next enumeration index. |
| 17124 dict->SetNextEnumerationIndex(PropertyDetails::kInitialIndex); | 17125 dict->SetNextEnumerationIndex(PropertyDetails::kInitialIndex); |
| 17125 return dict; | 17126 return dict; |
| 17126 } | 17127 } |
| 17127 | 17128 |
| 17128 | 17129 |
| 17129 template <typename Derived, typename Shape, typename Key> | 17130 template <typename Derived, typename Shape, typename Key> |
| 17130 Handle<FixedArray> Dictionary<Derived, Shape, Key>::BuildIterationIndicesArray( | 17131 Handle<FixedArray> Dictionary<Derived, Shape, Key>::BuildIterationIndicesArray( |
| 17131 Handle<Derived> dictionary) { | 17132 Handle<Derived> dictionary) { |
| 17132 Factory* factory = dictionary->GetIsolate()->factory(); | 17133 Isolate* isolate = dictionary->GetIsolate(); |
| 17134 Factory* factory = isolate->factory(); |
| 17133 int length = dictionary->NumberOfElements(); | 17135 int length = dictionary->NumberOfElements(); |
| 17134 | 17136 |
| 17135 Handle<FixedArray> iteration_order = factory->NewFixedArray(length); | 17137 Handle<FixedArray> iteration_order = factory->NewFixedArray(length); |
| 17136 Handle<FixedArray> enumeration_order = factory->NewFixedArray(length); | 17138 Handle<FixedArray> enumeration_order = factory->NewFixedArray(length); |
| 17137 | 17139 |
| 17138 // Fill both the iteration order array and the enumeration order array | 17140 // Fill both the iteration order array and the enumeration order array |
| 17139 // with property details. | 17141 // with property details. |
| 17140 int capacity = dictionary->Capacity(); | 17142 int capacity = dictionary->Capacity(); |
| 17141 int pos = 0; | 17143 int pos = 0; |
| 17142 for (int i = 0; i < capacity; i++) { | 17144 for (int i = 0; i < capacity; i++) { |
| 17143 if (dictionary->IsKey(dictionary->KeyAt(i))) { | 17145 if (dictionary->IsKey(isolate, dictionary->KeyAt(i))) { |
| 17144 int index = dictionary->DetailsAt(i).dictionary_index(); | 17146 int index = dictionary->DetailsAt(i).dictionary_index(); |
| 17145 iteration_order->set(pos, Smi::FromInt(i)); | 17147 iteration_order->set(pos, Smi::FromInt(i)); |
| 17146 enumeration_order->set(pos, Smi::FromInt(index)); | 17148 enumeration_order->set(pos, Smi::FromInt(index)); |
| 17147 pos++; | 17149 pos++; |
| 17148 } | 17150 } |
| 17149 } | 17151 } |
| 17150 DCHECK(pos == length); | 17152 DCHECK(pos == length); |
| 17151 | 17153 |
| 17152 // Sort the arrays wrt. enumeration order. | 17154 // Sort the arrays wrt. enumeration order. |
| 17153 iteration_order->SortPairs(*enumeration_order, enumeration_order->length()); | 17155 iteration_order->SortPairs(*enumeration_order, enumeration_order->length()); |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17280 dictionary->SetNextEnumerationIndex(index + 1); | 17282 dictionary->SetNextEnumerationIndex(index + 1); |
| 17281 } | 17283 } |
| 17282 dictionary->SetEntry(entry, k, value, details); | 17284 dictionary->SetEntry(entry, k, value, details); |
| 17283 DCHECK((dictionary->KeyAt(entry)->IsNumber() || | 17285 DCHECK((dictionary->KeyAt(entry)->IsNumber() || |
| 17284 dictionary->KeyAt(entry)->IsName())); | 17286 dictionary->KeyAt(entry)->IsName())); |
| 17285 dictionary->ElementAdded(); | 17287 dictionary->ElementAdded(); |
| 17286 } | 17288 } |
| 17287 | 17289 |
| 17288 bool SeededNumberDictionary::HasComplexElements() { | 17290 bool SeededNumberDictionary::HasComplexElements() { |
| 17289 if (!requires_slow_elements()) return false; | 17291 if (!requires_slow_elements()) return false; |
| 17292 Isolate* isolate = this->GetIsolate(); |
| 17290 int capacity = this->Capacity(); | 17293 int capacity = this->Capacity(); |
| 17291 for (int i = 0; i < capacity; i++) { | 17294 for (int i = 0; i < capacity; i++) { |
| 17292 Object* k = this->KeyAt(i); | 17295 Object* k = this->KeyAt(i); |
| 17293 if (this->IsKey(k)) { | 17296 if (!this->IsKey(isolate, k)) continue; |
| 17294 DCHECK(!IsDeleted(i)); | 17297 DCHECK(!IsDeleted(i)); |
| 17295 PropertyDetails details = this->DetailsAt(i); | 17298 PropertyDetails details = this->DetailsAt(i); |
| 17296 if (details.type() == ACCESSOR_CONSTANT) return true; | 17299 if (details.type() == ACCESSOR_CONSTANT) return true; |
| 17297 PropertyAttributes attr = details.attributes(); | 17300 PropertyAttributes attr = details.attributes(); |
| 17298 if (attr & ALL_ATTRIBUTES_MASK) return true; | 17301 if (attr & ALL_ATTRIBUTES_MASK) return true; |
| 17299 } | |
| 17300 } | 17302 } |
| 17301 return false; | 17303 return false; |
| 17302 } | 17304 } |
| 17303 | 17305 |
| 17304 void SeededNumberDictionary::UpdateMaxNumberKey(uint32_t key, | 17306 void SeededNumberDictionary::UpdateMaxNumberKey(uint32_t key, |
| 17305 bool used_as_prototype) { | 17307 bool used_as_prototype) { |
| 17306 DisallowHeapAllocation no_allocation; | 17308 DisallowHeapAllocation no_allocation; |
| 17307 // If the dictionary requires slow elements an element has already | 17309 // If the dictionary requires slow elements an element has already |
| 17308 // been added at a high index. | 17310 // been added at a high index. |
| 17309 if (requires_slow_elements()) return; | 17311 if (requires_slow_elements()) return; |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17385 Handle<Object> object_key = | 17387 Handle<Object> object_key = |
| 17386 UnseededNumberDictionaryShape::AsHandle(dictionary->GetIsolate(), key); | 17388 UnseededNumberDictionaryShape::AsHandle(dictionary->GetIsolate(), key); |
| 17387 dictionary->SetEntry(entry, object_key, value); | 17389 dictionary->SetEntry(entry, object_key, value); |
| 17388 return dictionary; | 17390 return dictionary; |
| 17389 } | 17391 } |
| 17390 | 17392 |
| 17391 | 17393 |
| 17392 template <typename Derived, typename Shape, typename Key> | 17394 template <typename Derived, typename Shape, typename Key> |
| 17393 int Dictionary<Derived, Shape, Key>::NumberOfElementsFilterAttributes( | 17395 int Dictionary<Derived, Shape, Key>::NumberOfElementsFilterAttributes( |
| 17394 PropertyFilter filter) { | 17396 PropertyFilter filter) { |
| 17397 Isolate* isolate = this->GetIsolate(); |
| 17395 int capacity = this->Capacity(); | 17398 int capacity = this->Capacity(); |
| 17396 int result = 0; | 17399 int result = 0; |
| 17397 for (int i = 0; i < capacity; i++) { | 17400 for (int i = 0; i < capacity; i++) { |
| 17398 Object* k = this->KeyAt(i); | 17401 Object* k = this->KeyAt(i); |
| 17399 if (this->IsKey(k) && !k->FilterKey(filter)) { | 17402 if (this->IsKey(isolate, k) && !k->FilterKey(filter)) { |
| 17400 if (this->IsDeleted(i)) continue; | 17403 if (this->IsDeleted(i)) continue; |
| 17401 PropertyDetails details = this->DetailsAt(i); | 17404 PropertyDetails details = this->DetailsAt(i); |
| 17402 PropertyAttributes attr = details.attributes(); | 17405 PropertyAttributes attr = details.attributes(); |
| 17403 if ((attr & filter) == 0) result++; | 17406 if ((attr & filter) == 0) result++; |
| 17404 } | 17407 } |
| 17405 } | 17408 } |
| 17406 return result; | 17409 return result; |
| 17407 } | 17410 } |
| 17408 | 17411 |
| 17409 | 17412 |
| 17410 template <typename Dictionary> | 17413 template <typename Dictionary> |
| 17411 struct EnumIndexComparator { | 17414 struct EnumIndexComparator { |
| 17412 explicit EnumIndexComparator(Dictionary* dict) : dict(dict) {} | 17415 explicit EnumIndexComparator(Dictionary* dict) : dict(dict) {} |
| 17413 bool operator() (Smi* a, Smi* b) { | 17416 bool operator() (Smi* a, Smi* b) { |
| 17414 PropertyDetails da(dict->DetailsAt(a->value())); | 17417 PropertyDetails da(dict->DetailsAt(a->value())); |
| 17415 PropertyDetails db(dict->DetailsAt(b->value())); | 17418 PropertyDetails db(dict->DetailsAt(b->value())); |
| 17416 return da.dictionary_index() < db.dictionary_index(); | 17419 return da.dictionary_index() < db.dictionary_index(); |
| 17417 } | 17420 } |
| 17418 Dictionary* dict; | 17421 Dictionary* dict; |
| 17419 }; | 17422 }; |
| 17420 | 17423 |
| 17421 | 17424 |
| 17422 template <typename Derived, typename Shape, typename Key> | 17425 template <typename Derived, typename Shape, typename Key> |
| 17423 void Dictionary<Derived, Shape, Key>::CopyEnumKeysTo(FixedArray* storage) { | 17426 void Dictionary<Derived, Shape, Key>::CopyEnumKeysTo(FixedArray* storage) { |
| 17427 Isolate* isolate = this->GetIsolate(); |
| 17424 int length = storage->length(); | 17428 int length = storage->length(); |
| 17425 int capacity = this->Capacity(); | 17429 int capacity = this->Capacity(); |
| 17426 int properties = 0; | 17430 int properties = 0; |
| 17427 for (int i = 0; i < capacity; i++) { | 17431 for (int i = 0; i < capacity; i++) { |
| 17428 Object* k = this->KeyAt(i); | 17432 Object* k = this->KeyAt(i); |
| 17429 if (this->IsKey(k) && !k->IsSymbol()) { | 17433 if (this->IsKey(isolate, k) && !k->IsSymbol()) { |
| 17430 PropertyDetails details = this->DetailsAt(i); | 17434 PropertyDetails details = this->DetailsAt(i); |
| 17431 if (details.IsDontEnum() || this->IsDeleted(i)) continue; | 17435 if (details.IsDontEnum() || this->IsDeleted(i)) continue; |
| 17432 storage->set(properties, Smi::FromInt(i)); | 17436 storage->set(properties, Smi::FromInt(i)); |
| 17433 properties++; | 17437 properties++; |
| 17434 if (properties == length) break; | 17438 if (properties == length) break; |
| 17435 } | 17439 } |
| 17436 } | 17440 } |
| 17437 CHECK_EQ(length, properties); | 17441 CHECK_EQ(length, properties); |
| 17438 EnumIndexComparator<Derived> cmp(static_cast<Derived*>(this)); | 17442 EnumIndexComparator<Derived> cmp(static_cast<Derived*>(this)); |
| 17439 Smi** start = reinterpret_cast<Smi**>(storage->GetFirstElementAddress()); | 17443 Smi** start = reinterpret_cast<Smi**>(storage->GetFirstElementAddress()); |
| 17440 std::sort(start, start + length, cmp); | 17444 std::sort(start, start + length, cmp); |
| 17441 for (int i = 0; i < length; i++) { | 17445 for (int i = 0; i < length; i++) { |
| 17442 int index = Smi::cast(storage->get(i))->value(); | 17446 int index = Smi::cast(storage->get(i))->value(); |
| 17443 storage->set(i, this->KeyAt(index)); | 17447 storage->set(i, this->KeyAt(index)); |
| 17444 } | 17448 } |
| 17445 } | 17449 } |
| 17446 | 17450 |
| 17447 template <typename Derived, typename Shape, typename Key> | 17451 template <typename Derived, typename Shape, typename Key> |
| 17448 void Dictionary<Derived, Shape, Key>::CollectKeysTo( | 17452 void Dictionary<Derived, Shape, Key>::CollectKeysTo( |
| 17449 Handle<Dictionary<Derived, Shape, Key> > dictionary, KeyAccumulator* keys, | 17453 Handle<Dictionary<Derived, Shape, Key> > dictionary, KeyAccumulator* keys, |
| 17450 PropertyFilter filter) { | 17454 PropertyFilter filter) { |
| 17455 Isolate* isolate = keys->isolate(); |
| 17451 int capacity = dictionary->Capacity(); | 17456 int capacity = dictionary->Capacity(); |
| 17452 Handle<FixedArray> array = | 17457 Handle<FixedArray> array = |
| 17453 keys->isolate()->factory()->NewFixedArray(dictionary->NumberOfElements()); | 17458 isolate->factory()->NewFixedArray(dictionary->NumberOfElements()); |
| 17454 int array_size = 0; | 17459 int array_size = 0; |
| 17455 | 17460 |
| 17456 { | 17461 { |
| 17457 DisallowHeapAllocation no_gc; | 17462 DisallowHeapAllocation no_gc; |
| 17458 Dictionary<Derived, Shape, Key>* raw_dict = *dictionary; | 17463 Dictionary<Derived, Shape, Key>* raw_dict = *dictionary; |
| 17459 for (int i = 0; i < capacity; i++) { | 17464 for (int i = 0; i < capacity; i++) { |
| 17460 Object* k = raw_dict->KeyAt(i); | 17465 Object* k = raw_dict->KeyAt(i); |
| 17461 if (!raw_dict->IsKey(k) || k->FilterKey(filter)) continue; | 17466 if (!raw_dict->IsKey(isolate, k) || k->FilterKey(filter)) continue; |
| 17462 if (raw_dict->IsDeleted(i)) continue; | 17467 if (raw_dict->IsDeleted(i)) continue; |
| 17463 PropertyDetails details = raw_dict->DetailsAt(i); | 17468 PropertyDetails details = raw_dict->DetailsAt(i); |
| 17464 if ((details.attributes() & filter) != 0) continue; | 17469 if ((details.attributes() & filter) != 0) continue; |
| 17465 if (filter & ONLY_ALL_CAN_READ) { | 17470 if (filter & ONLY_ALL_CAN_READ) { |
| 17466 if (details.kind() != kAccessor) continue; | 17471 if (details.kind() != kAccessor) continue; |
| 17467 Object* accessors = raw_dict->ValueAt(i); | 17472 Object* accessors = raw_dict->ValueAt(i); |
| 17468 if (accessors->IsPropertyCell()) { | 17473 if (accessors->IsPropertyCell()) { |
| 17469 accessors = PropertyCell::cast(accessors)->value(); | 17474 accessors = PropertyCell::cast(accessors)->value(); |
| 17470 } | 17475 } |
| 17471 if (!accessors->IsAccessorInfo()) continue; | 17476 if (!accessors->IsAccessorInfo()) continue; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 17496 if (!key->IsSymbol()) continue; | 17501 if (!key->IsSymbol()) continue; |
| 17497 keys->AddKey(key, DO_NOT_CONVERT); | 17502 keys->AddKey(key, DO_NOT_CONVERT); |
| 17498 } | 17503 } |
| 17499 } | 17504 } |
| 17500 } | 17505 } |
| 17501 | 17506 |
| 17502 | 17507 |
| 17503 // Backwards lookup (slow). | 17508 // Backwards lookup (slow). |
| 17504 template<typename Derived, typename Shape, typename Key> | 17509 template<typename Derived, typename Shape, typename Key> |
| 17505 Object* Dictionary<Derived, Shape, Key>::SlowReverseLookup(Object* value) { | 17510 Object* Dictionary<Derived, Shape, Key>::SlowReverseLookup(Object* value) { |
| 17511 Isolate* isolate = this->GetIsolate(); |
| 17506 int capacity = this->Capacity(); | 17512 int capacity = this->Capacity(); |
| 17507 for (int i = 0; i < capacity; i++) { | 17513 for (int i = 0; i < capacity; i++) { |
| 17508 Object* k = this->KeyAt(i); | 17514 Object* k = this->KeyAt(i); |
| 17509 if (this->IsKey(k)) { | 17515 if (!this->IsKey(isolate, k)) continue; |
| 17510 Object* e = this->ValueAt(i); | 17516 Object* e = this->ValueAt(i); |
| 17511 // TODO(dcarney): this should be templatized. | 17517 // TODO(dcarney): this should be templatized. |
| 17512 if (e->IsPropertyCell()) { | 17518 if (e->IsPropertyCell()) { |
| 17513 e = PropertyCell::cast(e)->value(); | 17519 e = PropertyCell::cast(e)->value(); |
| 17514 } | |
| 17515 if (e == value) return k; | |
| 17516 } | 17520 } |
| 17521 if (e == value) return k; |
| 17517 } | 17522 } |
| 17518 Heap* heap = Dictionary::GetHeap(); | 17523 return isolate->heap()->undefined_value(); |
| 17519 return heap->undefined_value(); | |
| 17520 } | 17524 } |
| 17521 | 17525 |
| 17522 | 17526 |
| 17523 Object* ObjectHashTable::Lookup(Isolate* isolate, Handle<Object> key, | 17527 Object* ObjectHashTable::Lookup(Isolate* isolate, Handle<Object> key, |
| 17524 int32_t hash) { | 17528 int32_t hash) { |
| 17525 DisallowHeapAllocation no_gc; | 17529 DisallowHeapAllocation no_gc; |
| 17526 DCHECK(IsKey(*key)); | 17530 DCHECK(IsKey(isolate, *key)); |
| 17527 | 17531 |
| 17528 int entry = FindEntry(isolate, key, hash); | 17532 int entry = FindEntry(isolate, key, hash); |
| 17529 if (entry == kNotFound) return isolate->heap()->the_hole_value(); | 17533 if (entry == kNotFound) return isolate->heap()->the_hole_value(); |
| 17530 return get(EntryToIndex(entry) + 1); | 17534 return get(EntryToIndex(entry) + 1); |
| 17531 } | 17535 } |
| 17532 | 17536 |
| 17533 | 17537 |
| 17534 Object* ObjectHashTable::Lookup(Handle<Object> key) { | 17538 Object* ObjectHashTable::Lookup(Handle<Object> key) { |
| 17535 DisallowHeapAllocation no_gc; | 17539 DisallowHeapAllocation no_gc; |
| 17536 DCHECK(IsKey(*key)); | |
| 17537 | 17540 |
| 17538 Isolate* isolate = GetIsolate(); | 17541 Isolate* isolate = GetIsolate(); |
| 17542 DCHECK(IsKey(isolate, *key)); |
| 17539 | 17543 |
| 17540 // If the object does not have an identity hash, it was never used as a key. | 17544 // If the object does not have an identity hash, it was never used as a key. |
| 17541 Object* hash = key->GetHash(); | 17545 Object* hash = key->GetHash(); |
| 17542 if (hash->IsUndefined(isolate)) { | 17546 if (hash->IsUndefined(isolate)) { |
| 17543 return isolate->heap()->the_hole_value(); | 17547 return isolate->heap()->the_hole_value(); |
| 17544 } | 17548 } |
| 17545 return Lookup(isolate, key, Smi::cast(hash)->value()); | 17549 return Lookup(isolate, key, Smi::cast(hash)->value()); |
| 17546 } | 17550 } |
| 17547 | 17551 |
| 17548 | 17552 |
| 17549 Object* ObjectHashTable::Lookup(Handle<Object> key, int32_t hash) { | 17553 Object* ObjectHashTable::Lookup(Handle<Object> key, int32_t hash) { |
| 17550 return Lookup(GetIsolate(), key, hash); | 17554 return Lookup(GetIsolate(), key, hash); |
| 17551 } | 17555 } |
| 17552 | 17556 |
| 17553 | 17557 |
| 17554 Handle<ObjectHashTable> ObjectHashTable::Put(Handle<ObjectHashTable> table, | 17558 Handle<ObjectHashTable> ObjectHashTable::Put(Handle<ObjectHashTable> table, |
| 17555 Handle<Object> key, | 17559 Handle<Object> key, |
| 17556 Handle<Object> value) { | 17560 Handle<Object> value) { |
| 17557 Isolate* isolate = table->GetIsolate(); | 17561 Isolate* isolate = table->GetIsolate(); |
| 17558 | 17562 DCHECK(table->IsKey(isolate, *key)); |
| 17559 DCHECK(table->IsKey(*key)); | |
| 17560 DCHECK(!value->IsTheHole(isolate)); | 17563 DCHECK(!value->IsTheHole(isolate)); |
| 17561 | 17564 |
| 17562 // Make sure the key object has an identity hash code. | 17565 // Make sure the key object has an identity hash code. |
| 17563 int32_t hash = Object::GetOrCreateHash(isolate, key)->value(); | 17566 int32_t hash = Object::GetOrCreateHash(isolate, key)->value(); |
| 17564 | 17567 |
| 17565 return Put(table, key, value, hash); | 17568 return Put(table, key, value, hash); |
| 17566 } | 17569 } |
| 17567 | 17570 |
| 17568 | 17571 |
| 17569 Handle<ObjectHashTable> ObjectHashTable::Put(Handle<ObjectHashTable> table, | 17572 Handle<ObjectHashTable> ObjectHashTable::Put(Handle<ObjectHashTable> table, |
| 17570 Handle<Object> key, | 17573 Handle<Object> key, |
| 17571 Handle<Object> value, | 17574 Handle<Object> value, |
| 17572 int32_t hash) { | 17575 int32_t hash) { |
| 17573 Isolate* isolate = table->GetIsolate(); | 17576 Isolate* isolate = table->GetIsolate(); |
| 17574 | 17577 DCHECK(table->IsKey(isolate, *key)); |
| 17575 DCHECK(table->IsKey(*key)); | |
| 17576 DCHECK(!value->IsTheHole(isolate)); | 17578 DCHECK(!value->IsTheHole(isolate)); |
| 17577 | 17579 |
| 17578 int entry = table->FindEntry(isolate, key, hash); | 17580 int entry = table->FindEntry(isolate, key, hash); |
| 17579 | 17581 |
| 17580 // Key is already in table, just overwrite value. | 17582 // Key is already in table, just overwrite value. |
| 17581 if (entry != kNotFound) { | 17583 if (entry != kNotFound) { |
| 17582 table->set(EntryToIndex(entry) + 1, *value); | 17584 table->set(EntryToIndex(entry) + 1, *value); |
| 17583 return table; | 17585 return table; |
| 17584 } | 17586 } |
| 17585 | 17587 |
| 17586 // Rehash if more than 33% of the entries are deleted entries. | 17588 // Rehash if more than 33% of the entries are deleted entries. |
| 17587 // TODO(jochen): Consider to shrink the fixed array in place. | 17589 // TODO(jochen): Consider to shrink the fixed array in place. |
| 17588 if ((table->NumberOfDeletedElements() << 1) > table->NumberOfElements()) { | 17590 if ((table->NumberOfDeletedElements() << 1) > table->NumberOfElements()) { |
| 17589 table->Rehash(isolate->factory()->undefined_value()); | 17591 table->Rehash(isolate->factory()->undefined_value()); |
| 17590 } | 17592 } |
| 17591 | 17593 |
| 17592 // Check whether the hash table should be extended. | 17594 // Check whether the hash table should be extended. |
| 17593 table = EnsureCapacity(table, 1, key); | 17595 table = EnsureCapacity(table, 1, key); |
| 17594 table->AddEntry(table->FindInsertionEntry(hash), *key, *value); | 17596 table->AddEntry(table->FindInsertionEntry(hash), *key, *value); |
| 17595 return table; | 17597 return table; |
| 17596 } | 17598 } |
| 17597 | 17599 |
| 17598 | 17600 |
| 17599 Handle<ObjectHashTable> ObjectHashTable::Remove(Handle<ObjectHashTable> table, | 17601 Handle<ObjectHashTable> ObjectHashTable::Remove(Handle<ObjectHashTable> table, |
| 17600 Handle<Object> key, | 17602 Handle<Object> key, |
| 17601 bool* was_present) { | 17603 bool* was_present) { |
| 17602 DCHECK(table->IsKey(*key)); | 17604 DCHECK(table->IsKey(table->GetIsolate(), *key)); |
| 17603 | 17605 |
| 17604 Object* hash = key->GetHash(); | 17606 Object* hash = key->GetHash(); |
| 17605 if (hash->IsUndefined(table->GetIsolate())) { | 17607 if (hash->IsUndefined(table->GetIsolate())) { |
| 17606 *was_present = false; | 17608 *was_present = false; |
| 17607 return table; | 17609 return table; |
| 17608 } | 17610 } |
| 17609 | 17611 |
| 17610 return Remove(table, key, was_present, Smi::cast(hash)->value()); | 17612 return Remove(table, key, was_present, Smi::cast(hash)->value()); |
| 17611 } | 17613 } |
| 17612 | 17614 |
| 17613 | 17615 |
| 17614 Handle<ObjectHashTable> ObjectHashTable::Remove(Handle<ObjectHashTable> table, | 17616 Handle<ObjectHashTable> ObjectHashTable::Remove(Handle<ObjectHashTable> table, |
| 17615 Handle<Object> key, | 17617 Handle<Object> key, |
| 17616 bool* was_present, | 17618 bool* was_present, |
| 17617 int32_t hash) { | 17619 int32_t hash) { |
| 17618 DCHECK(table->IsKey(*key)); | 17620 Isolate* isolate = table->GetIsolate(); |
| 17621 DCHECK(table->IsKey(isolate, *key)); |
| 17619 | 17622 |
| 17620 int entry = table->FindEntry(table->GetIsolate(), key, hash); | 17623 int entry = table->FindEntry(isolate, key, hash); |
| 17621 if (entry == kNotFound) { | 17624 if (entry == kNotFound) { |
| 17622 *was_present = false; | 17625 *was_present = false; |
| 17623 return table; | 17626 return table; |
| 17624 } | 17627 } |
| 17625 | 17628 |
| 17626 *was_present = true; | 17629 *was_present = true; |
| 17627 table->RemoveEntry(entry); | 17630 table->RemoveEntry(entry); |
| 17628 return Shrink(table, key); | 17631 return Shrink(table, key); |
| 17629 } | 17632 } |
| 17630 | 17633 |
| 17631 | 17634 |
| 17632 void ObjectHashTable::AddEntry(int entry, Object* key, Object* value) { | 17635 void ObjectHashTable::AddEntry(int entry, Object* key, Object* value) { |
| 17633 set(EntryToIndex(entry), key); | 17636 set(EntryToIndex(entry), key); |
| 17634 set(EntryToIndex(entry) + 1, value); | 17637 set(EntryToIndex(entry) + 1, value); |
| 17635 ElementAdded(); | 17638 ElementAdded(); |
| 17636 } | 17639 } |
| 17637 | 17640 |
| 17638 | 17641 |
| 17639 void ObjectHashTable::RemoveEntry(int entry) { | 17642 void ObjectHashTable::RemoveEntry(int entry) { |
| 17640 set_the_hole(EntryToIndex(entry)); | 17643 set_the_hole(EntryToIndex(entry)); |
| 17641 set_the_hole(EntryToIndex(entry) + 1); | 17644 set_the_hole(EntryToIndex(entry) + 1); |
| 17642 ElementRemoved(); | 17645 ElementRemoved(); |
| 17643 } | 17646 } |
| 17644 | 17647 |
| 17645 | 17648 |
| 17646 Object* WeakHashTable::Lookup(Handle<HeapObject> key) { | 17649 Object* WeakHashTable::Lookup(Handle<HeapObject> key) { |
| 17647 DisallowHeapAllocation no_gc; | 17650 DisallowHeapAllocation no_gc; |
| 17648 DCHECK(IsKey(*key)); | 17651 Isolate* isolate = GetIsolate(); |
| 17652 DCHECK(IsKey(isolate, *key)); |
| 17649 int entry = FindEntry(key); | 17653 int entry = FindEntry(key); |
| 17650 if (entry == kNotFound) return GetHeap()->the_hole_value(); | 17654 if (entry == kNotFound) return isolate->heap()->the_hole_value(); |
| 17651 return get(EntryToValueIndex(entry)); | 17655 return get(EntryToValueIndex(entry)); |
| 17652 } | 17656 } |
| 17653 | 17657 |
| 17654 | 17658 |
| 17655 Handle<WeakHashTable> WeakHashTable::Put(Handle<WeakHashTable> table, | 17659 Handle<WeakHashTable> WeakHashTable::Put(Handle<WeakHashTable> table, |
| 17656 Handle<HeapObject> key, | 17660 Handle<HeapObject> key, |
| 17657 Handle<HeapObject> value) { | 17661 Handle<HeapObject> value) { |
| 17658 DCHECK(table->IsKey(*key)); | 17662 Isolate* isolate = key->GetIsolate(); |
| 17663 DCHECK(table->IsKey(isolate, *key)); |
| 17659 int entry = table->FindEntry(key); | 17664 int entry = table->FindEntry(key); |
| 17660 // Key is already in table, just overwrite value. | 17665 // Key is already in table, just overwrite value. |
| 17661 if (entry != kNotFound) { | 17666 if (entry != kNotFound) { |
| 17662 table->set(EntryToValueIndex(entry), *value); | 17667 table->set(EntryToValueIndex(entry), *value); |
| 17663 return table; | 17668 return table; |
| 17664 } | 17669 } |
| 17665 | 17670 |
| 17666 Handle<WeakCell> key_cell = key->GetIsolate()->factory()->NewWeakCell(key); | 17671 Handle<WeakCell> key_cell = isolate->factory()->NewWeakCell(key); |
| 17667 | 17672 |
| 17668 // Check whether the hash table should be extended. | 17673 // Check whether the hash table should be extended. |
| 17669 table = EnsureCapacity(table, 1, key, TENURED); | 17674 table = EnsureCapacity(table, 1, key, TENURED); |
| 17670 | 17675 |
| 17671 table->AddEntry(table->FindInsertionEntry(table->Hash(key)), key_cell, value); | 17676 table->AddEntry(table->FindInsertionEntry(table->Hash(key)), key_cell, value); |
| 17672 return table; | 17677 return table; |
| 17673 } | 17678 } |
| 17674 | 17679 |
| 17675 | 17680 |
| 17676 void WeakHashTable::AddEntry(int entry, Handle<WeakCell> key_cell, | 17681 void WeakHashTable::AddEntry(int entry, Handle<WeakCell> key_cell, |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17750 | 17755 |
| 17751 table->SetNextTable(*new_table); | 17756 table->SetNextTable(*new_table); |
| 17752 table->SetNumberOfDeletedElements(kClearedTableSentinel); | 17757 table->SetNumberOfDeletedElements(kClearedTableSentinel); |
| 17753 | 17758 |
| 17754 return new_table; | 17759 return new_table; |
| 17755 } | 17760 } |
| 17756 | 17761 |
| 17757 template <class Derived, class Iterator, int entrysize> | 17762 template <class Derived, class Iterator, int entrysize> |
| 17758 bool OrderedHashTable<Derived, Iterator, entrysize>::HasKey( | 17763 bool OrderedHashTable<Derived, Iterator, entrysize>::HasKey( |
| 17759 Handle<Derived> table, Handle<Object> key) { | 17764 Handle<Derived> table, Handle<Object> key) { |
| 17760 int entry = table->KeyToFirstEntry(*key); | 17765 DisallowHeapAllocation no_gc; |
| 17766 Isolate* isolate = table->GetIsolate(); |
| 17767 Object* raw_key = *key; |
| 17768 int entry = table->KeyToFirstEntry(isolate, raw_key); |
| 17761 // Walk the chain in the bucket to find the key. | 17769 // Walk the chain in the bucket to find the key. |
| 17762 while (entry != kNotFound) { | 17770 while (entry != kNotFound) { |
| 17763 Object* candidate_key = table->KeyAt(entry); | 17771 Object* candidate_key = table->KeyAt(entry); |
| 17764 if (candidate_key->SameValueZero(*key)) return true; | 17772 if (candidate_key->SameValueZero(raw_key)) return true; |
| 17765 entry = table->NextChainEntry(entry); | 17773 entry = table->NextChainEntry(entry); |
| 17766 } | 17774 } |
| 17767 return false; | 17775 return false; |
| 17768 } | 17776 } |
| 17769 | 17777 |
| 17770 | 17778 |
| 17771 Handle<OrderedHashSet> OrderedHashSet::Add(Handle<OrderedHashSet> table, | 17779 Handle<OrderedHashSet> OrderedHashSet::Add(Handle<OrderedHashSet> table, |
| 17772 Handle<Object> key) { | 17780 Handle<Object> key) { |
| 17773 int hash = Object::GetOrCreateHash(table->GetIsolate(), key)->value(); | 17781 int hash = Object::GetOrCreateHash(table->GetIsolate(), key)->value(); |
| 17774 int entry = table->HashToEntry(hash); | 17782 int entry = table->HashToEntry(hash); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17814 result->set(i, key); | 17822 result->set(i, key); |
| 17815 } | 17823 } |
| 17816 result->Shrink(length); | 17824 result->Shrink(length); |
| 17817 return result; | 17825 return result; |
| 17818 } | 17826 } |
| 17819 | 17827 |
| 17820 template<class Derived, class Iterator, int entrysize> | 17828 template<class Derived, class Iterator, int entrysize> |
| 17821 Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Rehash( | 17829 Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Rehash( |
| 17822 Handle<Derived> table, int new_capacity) { | 17830 Handle<Derived> table, int new_capacity) { |
| 17823 Isolate* isolate = table->GetIsolate(); | 17831 Isolate* isolate = table->GetIsolate(); |
| 17824 Heap* heap = isolate->heap(); | |
| 17825 DCHECK(!table->IsObsolete()); | 17832 DCHECK(!table->IsObsolete()); |
| 17826 | 17833 |
| 17827 Handle<Derived> new_table = Allocate( | 17834 Handle<Derived> new_table = |
| 17828 isolate, new_capacity, heap->InNewSpace(*table) ? NOT_TENURED : TENURED); | 17835 Allocate(isolate, new_capacity, |
| 17836 isolate->heap()->InNewSpace(*table) ? NOT_TENURED : TENURED); |
| 17829 int nof = table->NumberOfElements(); | 17837 int nof = table->NumberOfElements(); |
| 17830 int nod = table->NumberOfDeletedElements(); | 17838 int nod = table->NumberOfDeletedElements(); |
| 17831 int new_buckets = new_table->NumberOfBuckets(); | 17839 int new_buckets = new_table->NumberOfBuckets(); |
| 17832 int new_entry = 0; | 17840 int new_entry = 0; |
| 17833 int removed_holes_index = 0; | 17841 int removed_holes_index = 0; |
| 17834 | 17842 |
| 17835 DisallowHeapAllocation no_gc; | 17843 DisallowHeapAllocation no_gc; |
| 17836 Object* the_hole = heap->the_hole_value(); | |
| 17837 for (int old_entry = 0; old_entry < (nof + nod); ++old_entry) { | 17844 for (int old_entry = 0; old_entry < (nof + nod); ++old_entry) { |
| 17838 Object* key = table->KeyAt(old_entry); | 17845 Object* key = table->KeyAt(old_entry); |
| 17839 if (key == the_hole) { | 17846 if (key->IsTheHole(isolate)) { |
| 17840 table->SetRemovedIndexAt(removed_holes_index++, old_entry); | 17847 table->SetRemovedIndexAt(removed_holes_index++, old_entry); |
| 17841 continue; | 17848 continue; |
| 17842 } | 17849 } |
| 17843 | 17850 |
| 17844 Object* hash = key->GetHash(); | 17851 Object* hash = key->GetHash(); |
| 17845 int bucket = Smi::cast(hash)->value() & (new_buckets - 1); | 17852 int bucket = Smi::cast(hash)->value() & (new_buckets - 1); |
| 17846 Object* chain_entry = new_table->get(kHashTableStartIndex + bucket); | 17853 Object* chain_entry = new_table->get(kHashTableStartIndex + bucket); |
| 17847 new_table->set(kHashTableStartIndex + bucket, Smi::FromInt(new_entry)); | 17854 new_table->set(kHashTableStartIndex + bucket, Smi::FromInt(new_entry)); |
| 17848 int new_index = new_table->EntryToIndex(new_entry); | 17855 int new_index = new_table->EntryToIndex(new_entry); |
| 17849 int old_index = table->EntryToIndex(old_entry); | 17856 int old_index = table->EntryToIndex(old_entry); |
| (...skipping 924 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 18774 if (cell->value() != *new_value) { | 18781 if (cell->value() != *new_value) { |
| 18775 cell->set_value(*new_value); | 18782 cell->set_value(*new_value); |
| 18776 Isolate* isolate = cell->GetIsolate(); | 18783 Isolate* isolate = cell->GetIsolate(); |
| 18777 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 18784 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
| 18778 isolate, DependentCode::kPropertyCellChangedGroup); | 18785 isolate, DependentCode::kPropertyCellChangedGroup); |
| 18779 } | 18786 } |
| 18780 } | 18787 } |
| 18781 | 18788 |
| 18782 } // namespace internal | 18789 } // namespace internal |
| 18783 } // namespace v8 | 18790 } // namespace v8 |
| OLD | NEW |