| 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 |