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 |