| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 691 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 702 PropertyCell::cast(property_dictionary->ValueAt(entry))); | 702 PropertyCell::cast(property_dictionary->ValueAt(entry))); |
| 703 PropertyCell::SetValueInferType(cell, value); | 703 PropertyCell::SetValueInferType(cell, value); |
| 704 // Please note we have to update the property details. | 704 // Please note we have to update the property details. |
| 705 property_dictionary->DetailsAtPut(entry, details); | 705 property_dictionary->DetailsAtPut(entry, details); |
| 706 } else { | 706 } else { |
| 707 property_dictionary->SetEntry(entry, *name, *value, details); | 707 property_dictionary->SetEntry(entry, *name, *value, details); |
| 708 } | 708 } |
| 709 } | 709 } |
| 710 | 710 |
| 711 | 711 |
| 712 // TODO(mstarzinger): Temporary wrapper until target is handlified. | |
| 713 Handle<NameDictionary> NameDictionaryShrink(Handle<NameDictionary> dict, | |
| 714 Handle<Name> name) { | |
| 715 CALL_HEAP_FUNCTION(dict->GetIsolate(), dict->Shrink(*name), NameDictionary); | |
| 716 } | |
| 717 | |
| 718 | |
| 719 Handle<Object> JSObject::DeleteNormalizedProperty(Handle<JSObject> object, | 712 Handle<Object> JSObject::DeleteNormalizedProperty(Handle<JSObject> object, |
| 720 Handle<Name> name, | 713 Handle<Name> name, |
| 721 DeleteMode mode) { | 714 DeleteMode mode) { |
| 722 ASSERT(!object->HasFastProperties()); | 715 ASSERT(!object->HasFastProperties()); |
| 723 Isolate* isolate = object->GetIsolate(); | 716 Isolate* isolate = object->GetIsolate(); |
| 724 Handle<NameDictionary> dictionary(object->property_dictionary()); | 717 Handle<NameDictionary> dictionary(object->property_dictionary()); |
| 725 int entry = dictionary->FindEntry(*name); | 718 int entry = dictionary->FindEntry(*name); |
| 726 if (entry != NameDictionary::kNotFound) { | 719 if (entry != NameDictionary::kNotFound) { |
| 727 // If we have a global object set the cell to the hole. | 720 // If we have a global object set the cell to the hole. |
| 728 if (object->IsGlobalObject()) { | 721 if (object->IsGlobalObject()) { |
| 729 PropertyDetails details = dictionary->DetailsAt(entry); | 722 PropertyDetails details = dictionary->DetailsAt(entry); |
| 730 if (details.IsDontDelete()) { | 723 if (details.IsDontDelete()) { |
| 731 if (mode != FORCE_DELETION) return isolate->factory()->false_value(); | 724 if (mode != FORCE_DELETION) return isolate->factory()->false_value(); |
| 732 // When forced to delete global properties, we have to make a | 725 // When forced to delete global properties, we have to make a |
| 733 // map change to invalidate any ICs that think they can load | 726 // map change to invalidate any ICs that think they can load |
| 734 // from the DontDelete cell without checking if it contains | 727 // from the DontDelete cell without checking if it contains |
| 735 // the hole value. | 728 // the hole value. |
| 736 Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map())); | 729 Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map())); |
| 737 ASSERT(new_map->is_dictionary_map()); | 730 ASSERT(new_map->is_dictionary_map()); |
| 738 object->set_map(*new_map); | 731 object->set_map(*new_map); |
| 739 } | 732 } |
| 740 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry))); | 733 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry))); |
| 741 Handle<Object> value = isolate->factory()->the_hole_value(); | 734 Handle<Object> value = isolate->factory()->the_hole_value(); |
| 742 PropertyCell::SetValueInferType(cell, value); | 735 PropertyCell::SetValueInferType(cell, value); |
| 743 dictionary->DetailsAtPut(entry, details.AsDeleted()); | 736 dictionary->DetailsAtPut(entry, details.AsDeleted()); |
| 744 } else { | 737 } else { |
| 745 Handle<Object> deleted(dictionary->DeleteProperty(entry, mode), isolate); | 738 Handle<Object> deleted(dictionary->DeleteProperty(entry, mode), isolate); |
| 746 if (*deleted == isolate->heap()->true_value()) { | 739 if (*deleted == isolate->heap()->true_value()) { |
| 747 Handle<NameDictionary> new_properties = | 740 Handle<NameDictionary> new_properties = |
| 748 NameDictionaryShrink(dictionary, name); | 741 NameDictionary::Shrink(dictionary, *name); |
| 749 object->set_properties(*new_properties); | 742 object->set_properties(*new_properties); |
| 750 } | 743 } |
| 751 return deleted; | 744 return deleted; |
| 752 } | 745 } |
| 753 } | 746 } |
| 754 return isolate->factory()->true_value(); | 747 return isolate->factory()->true_value(); |
| 755 } | 748 } |
| 756 | 749 |
| 757 | 750 |
| 758 bool JSObject::IsDirty() { | 751 bool JSObject::IsDirty() { |
| (...skipping 12282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13041 } | 13034 } |
| 13042 } | 13035 } |
| 13043 | 13036 |
| 13044 | 13037 |
| 13045 // Certain compilers request function template instantiation when they | 13038 // Certain compilers request function template instantiation when they |
| 13046 // see the definition of the other template functions in the | 13039 // see the definition of the other template functions in the |
| 13047 // class. This requires us to have the template functions put | 13040 // class. This requires us to have the template functions put |
| 13048 // together, so even though this function belongs in objects-debug.cc, | 13041 // together, so even though this function belongs in objects-debug.cc, |
| 13049 // we keep it here instead to satisfy certain compilers. | 13042 // we keep it here instead to satisfy certain compilers. |
| 13050 #ifdef OBJECT_PRINT | 13043 #ifdef OBJECT_PRINT |
| 13051 template<typename Shape, typename Key> | 13044 template<typename Derived, typename Shape, typename Key> |
| 13052 void Dictionary<Shape, Key>::Print(FILE* out) { | 13045 void Dictionary<Derived, Shape, Key>::Print(FILE* out) { |
| 13053 int capacity = HashTable<Shape, Key>::Capacity(); | 13046 int capacity = HashTable_::Capacity(); |
| 13054 for (int i = 0; i < capacity; i++) { | 13047 for (int i = 0; i < capacity; i++) { |
| 13055 Object* k = HashTable<Shape, Key>::KeyAt(i); | 13048 Object* k = HashTable_::KeyAt(i); |
| 13056 if (HashTable<Shape, Key>::IsKey(k)) { | 13049 if (HashTable_::IsKey(k)) { |
| 13057 PrintF(out, " "); | 13050 PrintF(out, " "); |
| 13058 if (k->IsString()) { | 13051 if (k->IsString()) { |
| 13059 String::cast(k)->StringPrint(out); | 13052 String::cast(k)->StringPrint(out); |
| 13060 } else { | 13053 } else { |
| 13061 k->ShortPrint(out); | 13054 k->ShortPrint(out); |
| 13062 } | 13055 } |
| 13063 PrintF(out, ": "); | 13056 PrintF(out, ": "); |
| 13064 ValueAt(i)->ShortPrint(out); | 13057 ValueAt(i)->ShortPrint(out); |
| 13065 PrintF(out, "\n"); | 13058 PrintF(out, "\n"); |
| 13066 } | 13059 } |
| 13067 } | 13060 } |
| 13068 } | 13061 } |
| 13069 #endif | 13062 #endif |
| 13070 | 13063 |
| 13071 | 13064 |
| 13072 template<typename Shape, typename Key> | 13065 template<typename Derived, typename Shape, typename Key> |
| 13073 void Dictionary<Shape, Key>::CopyValuesTo(FixedArray* elements) { | 13066 void Dictionary<Derived, Shape, Key>::CopyValuesTo(FixedArray* elements) { |
| 13074 int pos = 0; | 13067 int pos = 0; |
| 13075 int capacity = HashTable<Shape, Key>::Capacity(); | 13068 int capacity = HashTable_::Capacity(); |
| 13076 DisallowHeapAllocation no_gc; | 13069 DisallowHeapAllocation no_gc; |
| 13077 WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc); | 13070 WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc); |
| 13078 for (int i = 0; i < capacity; i++) { | 13071 for (int i = 0; i < capacity; i++) { |
| 13079 Object* k = Dictionary<Shape, Key>::KeyAt(i); | 13072 Object* k = Dictionary::KeyAt(i); |
| 13080 if (Dictionary<Shape, Key>::IsKey(k)) { | 13073 if (Dictionary::IsKey(k)) { |
| 13081 elements->set(pos++, ValueAt(i), mode); | 13074 elements->set(pos++, ValueAt(i), mode); |
| 13082 } | 13075 } |
| 13083 } | 13076 } |
| 13084 ASSERT(pos == elements->length()); | 13077 ASSERT(pos == elements->length()); |
| 13085 } | 13078 } |
| 13086 | 13079 |
| 13087 | 13080 |
| 13088 InterceptorInfo* JSObject::GetNamedInterceptor() { | 13081 InterceptorInfo* JSObject::GetNamedInterceptor() { |
| 13089 ASSERT(map()->has_named_interceptor()); | 13082 ASSERT(map()->has_named_interceptor()); |
| 13090 JSFunction* constructor = JSFunction::cast(map()->constructor()); | 13083 JSFunction* constructor = JSFunction::cast(map()->constructor()); |
| (...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13774 } | 13767 } |
| 13775 | 13768 |
| 13776 static uint32_t StringHash(Object* obj) { | 13769 static uint32_t StringHash(Object* obj) { |
| 13777 return String::cast(obj)->Hash(); | 13770 return String::cast(obj)->Hash(); |
| 13778 } | 13771 } |
| 13779 | 13772 |
| 13780 String* string_; | 13773 String* string_; |
| 13781 }; | 13774 }; |
| 13782 | 13775 |
| 13783 | 13776 |
| 13784 template<typename Shape, typename Key> | 13777 template<typename Derived, typename Shape, typename Key> |
| 13785 void HashTable<Shape, Key>::IteratePrefix(ObjectVisitor* v) { | 13778 void HashTable<Derived, Shape, Key>::IteratePrefix(ObjectVisitor* v) { |
| 13786 IteratePointers(v, 0, kElementsStartOffset); | 13779 IteratePointers(v, 0, kElementsStartOffset); |
| 13787 } | 13780 } |
| 13788 | 13781 |
| 13789 | 13782 |
| 13790 template<typename Shape, typename Key> | 13783 template<typename Derived, typename Shape, typename Key> |
| 13791 void HashTable<Shape, Key>::IterateElements(ObjectVisitor* v) { | 13784 void HashTable<Derived, Shape, Key>::IterateElements(ObjectVisitor* v) { |
| 13792 IteratePointers(v, | 13785 IteratePointers(v, |
| 13793 kElementsStartOffset, | 13786 kElementsStartOffset, |
| 13794 kHeaderSize + length() * kPointerSize); | 13787 kHeaderSize + length() * kPointerSize); |
| 13795 } | 13788 } |
| 13796 | 13789 |
| 13797 | 13790 |
| 13798 template<typename Shape, typename Key> | 13791 template<typename Derived, typename Shape, typename Key> |
| 13799 MaybeObject* HashTable<Shape, Key>::Allocate(Heap* heap, | 13792 MaybeObject* HashTable<Derived, Shape, Key>::Allocate( |
| 13800 int at_least_space_for, | 13793 Heap* heap, |
| 13801 MinimumCapacity capacity_option, | 13794 int at_least_space_for, |
| 13802 PretenureFlag pretenure) { | 13795 MinimumCapacity capacity_option, |
| 13796 PretenureFlag pretenure) { |
| 13803 ASSERT(!capacity_option || IsPowerOf2(at_least_space_for)); | 13797 ASSERT(!capacity_option || IsPowerOf2(at_least_space_for)); |
| 13804 int capacity = (capacity_option == USE_CUSTOM_MINIMUM_CAPACITY) | 13798 int capacity = (capacity_option == USE_CUSTOM_MINIMUM_CAPACITY) |
| 13805 ? at_least_space_for | 13799 ? at_least_space_for |
| 13806 : ComputeCapacity(at_least_space_for); | 13800 : ComputeCapacity(at_least_space_for); |
| 13807 if (capacity > HashTable::kMaxCapacity) { | 13801 if (capacity > HashTable::kMaxCapacity) { |
| 13808 v8::internal::Heap::FatalProcessOutOfMemory("invalid table size", true); | 13802 v8::internal::Heap::FatalProcessOutOfMemory("invalid table size", true); |
| 13809 } | 13803 } |
| 13810 | 13804 |
| 13811 Object* obj; | 13805 Object* obj; |
| 13812 { MaybeObject* maybe_obj = | 13806 { MaybeObject* maybe_obj = |
| 13813 heap-> AllocateHashTable(EntryToIndex(capacity), pretenure); | 13807 heap-> AllocateHashTable(EntryToIndex(capacity), pretenure); |
| 13814 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 13808 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 13815 } | 13809 } |
| 13816 HashTable::cast(obj)->SetNumberOfElements(0); | 13810 HashTable::cast(obj)->SetNumberOfElements(0); |
| 13817 HashTable::cast(obj)->SetNumberOfDeletedElements(0); | 13811 HashTable::cast(obj)->SetNumberOfDeletedElements(0); |
| 13818 HashTable::cast(obj)->SetCapacity(capacity); | 13812 HashTable::cast(obj)->SetCapacity(capacity); |
| 13819 return obj; | 13813 return obj; |
| 13820 } | 13814 } |
| 13821 | 13815 |
| 13822 | 13816 |
| 13817 template<typename Derived, typename Shape, typename Key> |
| 13818 Handle<Derived> HashTable<Derived, Shape, Key>::New( |
| 13819 Isolate* isolate, |
| 13820 int at_least_space_for, |
| 13821 MinimumCapacity capacity_option, |
| 13822 PretenureFlag pretenure) { |
| 13823 CALL_HEAP_FUNCTION( |
| 13824 isolate, |
| 13825 Allocate(isolate->heap(), at_least_space_for, capacity_option, pretenure), |
| 13826 Derived); |
| 13827 } |
| 13828 |
| 13829 |
| 13823 // Find entry for key otherwise return kNotFound. | 13830 // Find entry for key otherwise return kNotFound. |
| 13824 int NameDictionary::FindEntry(Name* key) { | 13831 int NameDictionary::FindEntry(Name* key) { |
| 13825 if (!key->IsUniqueName()) { | 13832 if (!key->IsUniqueName()) { |
| 13826 return HashTable<NameDictionaryShape, Name*>::FindEntry(key); | 13833 return HashTable_::FindEntry(key); |
| 13827 } | 13834 } |
| 13828 | 13835 |
| 13829 // Optimized for unique names. Knowledge of the key type allows: | 13836 // Optimized for unique names. Knowledge of the key type allows: |
| 13830 // 1. Move the check if the key is unique out of the loop. | 13837 // 1. Move the check if the key is unique out of the loop. |
| 13831 // 2. Avoid comparing hash codes in unique-to-unique comparison. | 13838 // 2. Avoid comparing hash codes in unique-to-unique comparison. |
| 13832 // 3. Detect a case when a dictionary key is not unique but the key is. | 13839 // 3. Detect a case when a dictionary key is not unique but the key is. |
| 13833 // In case of positive result the dictionary key may be replaced by the | 13840 // In case of positive result the dictionary key may be replaced by the |
| 13834 // internalized string with minimal performance penalty. It gives a chance | 13841 // internalized string with minimal performance penalty. It gives a chance |
| 13835 // to perform further lookups in code stubs (and significant performance | 13842 // to perform further lookups in code stubs (and significant performance |
| 13836 // boost a certain style of code). | 13843 // boost a certain style of code). |
| (...skipping 16 matching lines...) Expand all Loading... |
| 13853 set(index, key); | 13860 set(index, key); |
| 13854 return entry; | 13861 return entry; |
| 13855 } | 13862 } |
| 13856 ASSERT(element->IsTheHole() || !Name::cast(element)->Equals(key)); | 13863 ASSERT(element->IsTheHole() || !Name::cast(element)->Equals(key)); |
| 13857 entry = NextProbe(entry, count++, capacity); | 13864 entry = NextProbe(entry, count++, capacity); |
| 13858 } | 13865 } |
| 13859 return kNotFound; | 13866 return kNotFound; |
| 13860 } | 13867 } |
| 13861 | 13868 |
| 13862 | 13869 |
| 13863 template<typename Shape, typename Key> | 13870 template<typename Derived, typename Shape, typename Key> |
| 13864 MaybeObject* HashTable<Shape, Key>::Rehash(HashTable* new_table, Key key) { | 13871 void HashTable<Derived, Shape, Key>::Rehash(Derived* new_table, Key key) { |
| 13865 ASSERT(NumberOfElements() < new_table->Capacity()); | 13872 ASSERT(NumberOfElements() < new_table->Capacity()); |
| 13866 | 13873 |
| 13867 DisallowHeapAllocation no_gc; | 13874 DisallowHeapAllocation no_gc; |
| 13868 WriteBarrierMode mode = new_table->GetWriteBarrierMode(no_gc); | 13875 WriteBarrierMode mode = new_table->GetWriteBarrierMode(no_gc); |
| 13869 | 13876 |
| 13870 // Copy prefix to new array. | 13877 // Copy prefix to new array. |
| 13871 for (int i = kPrefixStartIndex; | 13878 for (int i = kPrefixStartIndex; |
| 13872 i < kPrefixStartIndex + Shape::kPrefixSize; | 13879 i < kPrefixStartIndex + Shape::kPrefixSize; |
| 13873 i++) { | 13880 i++) { |
| 13874 new_table->set(i, get(i), mode); | 13881 new_table->set(i, get(i), mode); |
| 13875 } | 13882 } |
| 13876 | 13883 |
| 13877 // Rehash the elements. | 13884 // Rehash the elements. |
| 13878 int capacity = Capacity(); | 13885 int capacity = Capacity(); |
| 13879 for (int i = 0; i < capacity; i++) { | 13886 for (int i = 0; i < capacity; i++) { |
| 13880 uint32_t from_index = EntryToIndex(i); | 13887 uint32_t from_index = EntryToIndex(i); |
| 13881 Object* k = get(from_index); | 13888 Object* k = get(from_index); |
| 13882 if (IsKey(k)) { | 13889 if (IsKey(k)) { |
| 13883 uint32_t hash = HashTable<Shape, Key>::HashForObject(key, k); | 13890 uint32_t hash = HashTable::HashForObject(key, k); |
| 13884 uint32_t insertion_index = | 13891 uint32_t insertion_index = |
| 13885 EntryToIndex(new_table->FindInsertionEntry(hash)); | 13892 EntryToIndex(new_table->FindInsertionEntry(hash)); |
| 13886 for (int j = 0; j < Shape::kEntrySize; j++) { | 13893 for (int j = 0; j < Shape::kEntrySize; j++) { |
| 13887 new_table->set(insertion_index + j, get(from_index + j), mode); | 13894 new_table->set(insertion_index + j, get(from_index + j), mode); |
| 13888 } | 13895 } |
| 13889 } | 13896 } |
| 13890 } | 13897 } |
| 13891 new_table->SetNumberOfElements(NumberOfElements()); | 13898 new_table->SetNumberOfElements(NumberOfElements()); |
| 13892 new_table->SetNumberOfDeletedElements(0); | 13899 new_table->SetNumberOfDeletedElements(0); |
| 13893 return new_table; | |
| 13894 } | 13900 } |
| 13895 | 13901 |
| 13896 | 13902 |
| 13897 template<typename Shape, typename Key> | 13903 template<typename Derived, typename Shape, typename Key> |
| 13898 uint32_t HashTable<Shape, Key>::EntryForProbe(Key key, | 13904 uint32_t HashTable<Derived, Shape, Key>::EntryForProbe( |
| 13899 Object* k, | 13905 Key key, |
| 13900 int probe, | 13906 Object* k, |
| 13901 uint32_t expected) { | 13907 int probe, |
| 13902 uint32_t hash = HashTable<Shape, Key>::HashForObject(key, k); | 13908 uint32_t expected) { |
| 13909 uint32_t hash = HashTable::HashForObject(key, k); |
| 13903 uint32_t capacity = Capacity(); | 13910 uint32_t capacity = Capacity(); |
| 13904 uint32_t entry = FirstProbe(hash, capacity); | 13911 uint32_t entry = FirstProbe(hash, capacity); |
| 13905 for (int i = 1; i < probe; i++) { | 13912 for (int i = 1; i < probe; i++) { |
| 13906 if (entry == expected) return expected; | 13913 if (entry == expected) return expected; |
| 13907 entry = NextProbe(entry, i, capacity); | 13914 entry = NextProbe(entry, i, capacity); |
| 13908 } | 13915 } |
| 13909 return entry; | 13916 return entry; |
| 13910 } | 13917 } |
| 13911 | 13918 |
| 13912 | 13919 |
| 13913 template<typename Shape, typename Key> | 13920 template<typename Derived, typename Shape, typename Key> |
| 13914 void HashTable<Shape, Key>::Swap(uint32_t entry1, | 13921 void HashTable<Derived, Shape, Key>::Swap(uint32_t entry1, |
| 13915 uint32_t entry2, | 13922 uint32_t entry2, |
| 13916 WriteBarrierMode mode) { | 13923 WriteBarrierMode mode) { |
| 13917 int index1 = EntryToIndex(entry1); | 13924 int index1 = EntryToIndex(entry1); |
| 13918 int index2 = EntryToIndex(entry2); | 13925 int index2 = EntryToIndex(entry2); |
| 13919 Object* temp[Shape::kEntrySize]; | 13926 Object* temp[Shape::kEntrySize]; |
| 13920 for (int j = 0; j < Shape::kEntrySize; j++) { | 13927 for (int j = 0; j < Shape::kEntrySize; j++) { |
| 13921 temp[j] = get(index1 + j); | 13928 temp[j] = get(index1 + j); |
| 13922 } | 13929 } |
| 13923 for (int j = 0; j < Shape::kEntrySize; j++) { | 13930 for (int j = 0; j < Shape::kEntrySize; j++) { |
| 13924 set(index1 + j, get(index2 + j), mode); | 13931 set(index1 + j, get(index2 + j), mode); |
| 13925 } | 13932 } |
| 13926 for (int j = 0; j < Shape::kEntrySize; j++) { | 13933 for (int j = 0; j < Shape::kEntrySize; j++) { |
| 13927 set(index2 + j, temp[j], mode); | 13934 set(index2 + j, temp[j], mode); |
| 13928 } | 13935 } |
| 13929 } | 13936 } |
| 13930 | 13937 |
| 13931 | 13938 |
| 13932 template<typename Shape, typename Key> | 13939 template<typename Derived, typename Shape, typename Key> |
| 13933 void HashTable<Shape, Key>::Rehash(Key key) { | 13940 void HashTable<Derived, Shape, Key>::Rehash(Key key) { |
| 13934 DisallowHeapAllocation no_gc; | 13941 DisallowHeapAllocation no_gc; |
| 13935 WriteBarrierMode mode = GetWriteBarrierMode(no_gc); | 13942 WriteBarrierMode mode = GetWriteBarrierMode(no_gc); |
| 13936 uint32_t capacity = Capacity(); | 13943 uint32_t capacity = Capacity(); |
| 13937 bool done = false; | 13944 bool done = false; |
| 13938 for (int probe = 1; !done; probe++) { | 13945 for (int probe = 1; !done; probe++) { |
| 13939 // All elements at entries given by one of the first _probe_ probes | 13946 // All elements at entries given by one of the first _probe_ probes |
| 13940 // are placed correctly. Other elements might need to be moved. | 13947 // are placed correctly. Other elements might need to be moved. |
| 13941 done = true; | 13948 done = true; |
| 13942 for (uint32_t current = 0; current < capacity; current++) { | 13949 for (uint32_t current = 0; current < capacity; current++) { |
| 13943 Object* current_key = get(EntryToIndex(current)); | 13950 Object* current_key = get(EntryToIndex(current)); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 13955 // The place for the current element is occupied. Leave the element | 13962 // The place for the current element is occupied. Leave the element |
| 13956 // for the next probe. | 13963 // for the next probe. |
| 13957 done = false; | 13964 done = false; |
| 13958 } | 13965 } |
| 13959 } | 13966 } |
| 13960 } | 13967 } |
| 13961 } | 13968 } |
| 13962 } | 13969 } |
| 13963 | 13970 |
| 13964 | 13971 |
| 13965 template<typename Shape, typename Key> | 13972 template<typename Derived, typename Shape, typename Key> |
| 13966 MaybeObject* HashTable<Shape, Key>::EnsureCapacity(int n, | 13973 MaybeObject* HashTable<Derived, Shape, Key>::EnsureCapacity( |
| 13967 Key key, | 13974 int n, |
| 13968 PretenureFlag pretenure) { | 13975 Key key, |
| 13976 PretenureFlag pretenure) { |
| 13969 int capacity = Capacity(); | 13977 int capacity = Capacity(); |
| 13970 int nof = NumberOfElements() + n; | 13978 int nof = NumberOfElements() + n; |
| 13971 int nod = NumberOfDeletedElements(); | 13979 int nod = NumberOfDeletedElements(); |
| 13972 // Return if: | 13980 // Return if: |
| 13973 // 50% is still free after adding n elements and | 13981 // 50% is still free after adding n elements and |
| 13974 // at most 50% of the free elements are deleted elements. | 13982 // at most 50% of the free elements are deleted elements. |
| 13975 if (nod <= (capacity - nof) >> 1) { | 13983 if (nod <= (capacity - nof) >> 1) { |
| 13976 int needed_free = nof >> 1; | 13984 int needed_free = nof >> 1; |
| 13977 if (nof + needed_free <= capacity) return this; | 13985 if (nof + needed_free <= capacity) return this; |
| 13978 } | 13986 } |
| 13979 | 13987 |
| 13980 const int kMinCapacityForPretenure = 256; | 13988 const int kMinCapacityForPretenure = 256; |
| 13981 bool should_pretenure = pretenure == TENURED || | 13989 bool should_pretenure = pretenure == TENURED || |
| 13982 ((capacity > kMinCapacityForPretenure) && !GetHeap()->InNewSpace(this)); | 13990 ((capacity > kMinCapacityForPretenure) && !GetHeap()->InNewSpace(this)); |
| 13983 Object* obj; | 13991 Object* obj; |
| 13984 { MaybeObject* maybe_obj = | 13992 { MaybeObject* maybe_obj = |
| 13985 Allocate(GetHeap(), | 13993 Allocate(GetHeap(), |
| 13986 nof * 2, | 13994 nof * 2, |
| 13987 USE_DEFAULT_MINIMUM_CAPACITY, | 13995 USE_DEFAULT_MINIMUM_CAPACITY, |
| 13988 should_pretenure ? TENURED : NOT_TENURED); | 13996 should_pretenure ? TENURED : NOT_TENURED); |
| 13989 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 13997 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 13990 } | 13998 } |
| 13991 | 13999 |
| 13992 return Rehash(HashTable::cast(obj), key); | 14000 Rehash(Derived::cast(obj), key); |
| 14001 return Derived::cast(obj); |
| 13993 } | 14002 } |
| 13994 | 14003 |
| 13995 | 14004 |
| 13996 template<typename Shape, typename Key> | 14005 template<typename Derived, typename Shape, typename Key> |
| 13997 MaybeObject* HashTable<Shape, Key>::Shrink(Key key) { | 14006 Handle<Derived> HashTable<Derived, Shape, Key>::Shrink(Handle<Derived> table, |
| 13998 int capacity = Capacity(); | 14007 Key key) { |
| 13999 int nof = NumberOfElements(); | 14008 int capacity = table->Capacity(); |
| 14009 int nof = table->NumberOfElements(); |
| 14000 | 14010 |
| 14001 // Shrink to fit the number of elements if only a quarter of the | 14011 // Shrink to fit the number of elements if only a quarter of the |
| 14002 // capacity is filled with elements. | 14012 // capacity is filled with elements. |
| 14003 if (nof > (capacity >> 2)) return this; | 14013 if (nof > (capacity >> 2)) return table; |
| 14004 // Allocate a new dictionary with room for at least the current | 14014 // Allocate a new dictionary with room for at least the current |
| 14005 // number of elements. The allocation method will make sure that | 14015 // number of elements. The allocation method will make sure that |
| 14006 // there is extra room in the dictionary for additions. Don't go | 14016 // there is extra room in the dictionary for additions. Don't go |
| 14007 // lower than room for 16 elements. | 14017 // lower than room for 16 elements. |
| 14008 int at_least_room_for = nof; | 14018 int at_least_room_for = nof; |
| 14009 if (at_least_room_for < 16) return this; | 14019 if (at_least_room_for < 16) return table; |
| 14010 | 14020 |
| 14021 Isolate* isolate = table->GetIsolate(); |
| 14011 const int kMinCapacityForPretenure = 256; | 14022 const int kMinCapacityForPretenure = 256; |
| 14012 bool pretenure = | 14023 bool pretenure = |
| 14013 (at_least_room_for > kMinCapacityForPretenure) && | 14024 (at_least_room_for > kMinCapacityForPretenure) && |
| 14014 !GetHeap()->InNewSpace(this); | 14025 !isolate->heap()->InNewSpace(*table); |
| 14015 Object* obj; | 14026 Handle<Derived> new_table = New( |
| 14016 { MaybeObject* maybe_obj = | 14027 isolate, |
| 14017 Allocate(GetHeap(), | 14028 at_least_room_for, |
| 14018 at_least_room_for, | 14029 USE_DEFAULT_MINIMUM_CAPACITY, |
| 14019 USE_DEFAULT_MINIMUM_CAPACITY, | 14030 pretenure ? TENURED : NOT_TENURED); |
| 14020 pretenure ? TENURED : NOT_TENURED); | |
| 14021 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | |
| 14022 } | |
| 14023 | 14031 |
| 14024 return Rehash(HashTable::cast(obj), key); | 14032 table->Rehash(*new_table, key); |
| 14033 return new_table; |
| 14025 } | 14034 } |
| 14026 | 14035 |
| 14027 | 14036 |
| 14028 template<typename Shape, typename Key> | 14037 template<typename Derived, typename Shape, typename Key> |
| 14029 uint32_t HashTable<Shape, Key>::FindInsertionEntry(uint32_t hash) { | 14038 uint32_t HashTable<Derived, Shape, Key>::FindInsertionEntry(uint32_t hash) { |
| 14030 uint32_t capacity = Capacity(); | 14039 uint32_t capacity = Capacity(); |
| 14031 uint32_t entry = FirstProbe(hash, capacity); | 14040 uint32_t entry = FirstProbe(hash, capacity); |
| 14032 uint32_t count = 1; | 14041 uint32_t count = 1; |
| 14033 // EnsureCapacity will guarantee the hash table is never full. | 14042 // EnsureCapacity will guarantee the hash table is never full. |
| 14034 while (true) { | 14043 while (true) { |
| 14035 Object* element = KeyAt(entry); | 14044 Object* element = KeyAt(entry); |
| 14036 if (element->IsUndefined() || element->IsTheHole()) break; | 14045 if (element->IsUndefined() || element->IsTheHole()) break; |
| 14037 entry = NextProbe(entry, count++, capacity); | 14046 entry = NextProbe(entry, count++, capacity); |
| 14038 } | 14047 } |
| 14039 return entry; | 14048 return entry; |
| 14040 } | 14049 } |
| 14041 | 14050 |
| 14042 | 14051 |
| 14043 // Force instantiation of template instances class. | 14052 // Force instantiation of template instances class. |
| 14044 // Please note this list is compiler dependent. | 14053 // Please note this list is compiler dependent. |
| 14045 | 14054 |
| 14046 template class HashTable<StringTableShape, HashTableKey*>; | 14055 template class HashTable<StringTable, StringTableShape, HashTableKey*>; |
| 14047 | 14056 |
| 14048 template class HashTable<CompilationCacheShape, HashTableKey*>; | 14057 template class HashTable<CompilationCacheTable, |
| 14058 CompilationCacheShape, |
| 14059 HashTableKey*>; |
| 14049 | 14060 |
| 14050 template class HashTable<MapCacheShape, HashTableKey*>; | 14061 template class HashTable<MapCache, MapCacheShape, HashTableKey*>; |
| 14051 | 14062 |
| 14052 template class HashTable<ObjectHashTableShape, Object*>; | 14063 template class HashTable<ObjectHashTable, ObjectHashTableShape, Object*>; |
| 14053 | 14064 |
| 14054 template class HashTable<WeakHashTableShape<2>, Object*>; | 14065 template class HashTable<WeakHashTable, WeakHashTableShape<2>, Object*>; |
| 14055 | 14066 |
| 14056 template class Dictionary<NameDictionaryShape, Name*>; | 14067 template class Dictionary<NameDictionary, NameDictionaryShape, Name*>; |
| 14057 | 14068 |
| 14058 template class Dictionary<SeededNumberDictionaryShape, uint32_t>; | 14069 template class Dictionary<SeededNumberDictionary, |
| 14070 SeededNumberDictionaryShape, |
| 14071 uint32_t>; |
| 14059 | 14072 |
| 14060 template class Dictionary<UnseededNumberDictionaryShape, uint32_t>; | 14073 template class Dictionary<UnseededNumberDictionary, |
| 14074 UnseededNumberDictionaryShape, |
| 14075 uint32_t>; |
| 14061 | 14076 |
| 14062 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>:: | 14077 template MaybeObject* |
| 14078 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
| 14063 Allocate(Heap* heap, int at_least_space_for, PretenureFlag pretenure); | 14079 Allocate(Heap* heap, int at_least_space_for, PretenureFlag pretenure); |
| 14064 | 14080 |
| 14065 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: | 14081 template MaybeObject* |
| 14082 Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>:: |
| 14066 Allocate(Heap* heap, int at_least_space_for, PretenureFlag pretenure); | 14083 Allocate(Heap* heap, int at_least_space_for, PretenureFlag pretenure); |
| 14067 | 14084 |
| 14068 template MaybeObject* Dictionary<NameDictionaryShape, Name*>:: | 14085 template MaybeObject* Dictionary<NameDictionary, NameDictionaryShape, Name*>:: |
| 14069 Allocate(Heap* heap, int n, PretenureFlag pretenure); | 14086 Allocate(Heap* heap, int n, PretenureFlag pretenure); |
| 14070 | 14087 |
| 14071 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::AtPut( | 14088 template MaybeObject* |
| 14072 uint32_t, Object*); | 14089 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
| 14073 | |
| 14074 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: | |
| 14075 AtPut(uint32_t, Object*); | 14090 AtPut(uint32_t, Object*); |
| 14076 | 14091 |
| 14077 template Object* Dictionary<SeededNumberDictionaryShape, uint32_t>:: | 14092 template MaybeObject* |
| 14093 Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>:: |
| 14094 AtPut(uint32_t, Object*); |
| 14095 |
| 14096 template Object* |
| 14097 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
| 14078 SlowReverseLookup(Object* value); | 14098 SlowReverseLookup(Object* value); |
| 14079 | 14099 |
| 14080 template Object* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: | 14100 template Object* |
| 14101 Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>:: |
| 14081 SlowReverseLookup(Object* value); | 14102 SlowReverseLookup(Object* value); |
| 14082 | 14103 |
| 14083 template Object* Dictionary<NameDictionaryShape, Name*>::SlowReverseLookup( | 14104 template Object* |
| 14105 Dictionary<NameDictionary, NameDictionaryShape, Name*>::SlowReverseLookup( |
| 14084 Object*); | 14106 Object*); |
| 14085 | 14107 |
| 14086 template void Dictionary<SeededNumberDictionaryShape, uint32_t>::CopyKeysTo( | 14108 template void |
| 14087 FixedArray*, | 14109 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
| 14088 PropertyAttributes, | 14110 CopyKeysTo( |
| 14089 Dictionary<SeededNumberDictionaryShape, uint32_t>::SortMode); | 14111 FixedArray*, |
| 14112 PropertyAttributes, |
| 14113 Dictionary<SeededNumberDictionary, |
| 14114 SeededNumberDictionaryShape, |
| 14115 uint32_t>::SortMode); |
| 14090 | 14116 |
| 14091 template Object* Dictionary<NameDictionaryShape, Name*>::DeleteProperty( | 14117 template Object* |
| 14118 Dictionary<NameDictionary, NameDictionaryShape, Name*>::DeleteProperty( |
| 14092 int, JSObject::DeleteMode); | 14119 int, JSObject::DeleteMode); |
| 14093 | 14120 |
| 14094 template Handle<Object> Dictionary<NameDictionaryShape, Name*>::DeleteProperty( | 14121 template Handle<Object> |
| 14095 Handle<Dictionary<NameDictionaryShape, Name*> >, | 14122 Dictionary<NameDictionary, NameDictionaryShape, Name*>::DeleteProperty( |
| 14123 Handle<Dictionary<NameDictionary, NameDictionaryShape, Name*> >, |
| 14096 int, | 14124 int, |
| 14097 JSObject::DeleteMode); | 14125 JSObject::DeleteMode); |
| 14098 | 14126 |
| 14099 template Object* Dictionary<SeededNumberDictionaryShape, uint32_t>:: | 14127 template Object* |
| 14128 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
| 14100 DeleteProperty(int, JSObject::DeleteMode); | 14129 DeleteProperty(int, JSObject::DeleteMode); |
| 14101 | 14130 |
| 14102 template Handle<Object> | 14131 template Handle<Object> |
| 14103 Dictionary<SeededNumberDictionaryShape, uint32_t>::DeleteProperty( | 14132 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
| 14104 Handle<Dictionary<SeededNumberDictionaryShape, uint32_t> >, | 14133 DeleteProperty( |
| 14105 int, | 14134 Handle<Dictionary<SeededNumberDictionary, |
| 14106 JSObject::DeleteMode); | 14135 SeededNumberDictionaryShape, |
| 14136 uint32_t> >, |
| 14137 int, |
| 14138 JSObject::DeleteMode); |
| 14107 | 14139 |
| 14108 template MaybeObject* Dictionary<NameDictionaryShape, Name*>::Shrink(Name* n); | 14140 template void Dictionary<NameDictionary, NameDictionaryShape, Name*>:: |
| 14109 | 14141 CopyKeysTo( |
| 14110 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::Shrink( | 14142 FixedArray*, |
| 14111 uint32_t); | 14143 int, |
| 14112 template Handle<FixedArray> | 14144 PropertyAttributes, |
| 14113 Dictionary<SeededNumberDictionaryShape, uint32_t>::Shrink( | 14145 Dictionary<NameDictionary, NameDictionaryShape, Name*>::SortMode); |
| 14114 Handle<Dictionary<SeededNumberDictionaryShape, uint32_t> >, | |
| 14115 uint32_t); | |
| 14116 | |
| 14117 template void Dictionary<NameDictionaryShape, Name*>::CopyKeysTo( | |
| 14118 FixedArray*, | |
| 14119 int, | |
| 14120 PropertyAttributes, | |
| 14121 Dictionary<NameDictionaryShape, Name*>::SortMode); | |
| 14122 | 14146 |
| 14123 template int | 14147 template int |
| 14124 Dictionary<NameDictionaryShape, Name*>::NumberOfElementsFilterAttributes( | 14148 Dictionary<NameDictionary, NameDictionaryShape, Name*>:: |
| 14125 PropertyAttributes); | 14149 NumberOfElementsFilterAttributes(PropertyAttributes); |
| 14126 | 14150 |
| 14127 template MaybeObject* Dictionary<NameDictionaryShape, Name*>::Add( | 14151 template MaybeObject* |
| 14152 Dictionary<NameDictionary, NameDictionaryShape, Name*>::Add( |
| 14128 Name*, Object*, PropertyDetails); | 14153 Name*, Object*, PropertyDetails); |
| 14129 | 14154 |
| 14130 template MaybeObject* | 14155 template MaybeObject* |
| 14131 Dictionary<NameDictionaryShape, Name*>::GenerateNewEnumerationIndices(); | 14156 Dictionary<NameDictionary, NameDictionaryShape, Name*>:: |
| 14157 GenerateNewEnumerationIndices(); |
| 14132 | 14158 |
| 14133 template int | 14159 template int |
| 14134 Dictionary<SeededNumberDictionaryShape, uint32_t>:: | 14160 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
| 14135 NumberOfElementsFilterAttributes(PropertyAttributes); | 14161 NumberOfElementsFilterAttributes(PropertyAttributes); |
| 14136 | 14162 |
| 14137 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::Add( | 14163 template MaybeObject* |
| 14164 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::Add( |
| 14138 uint32_t, Object*, PropertyDetails); | 14165 uint32_t, Object*, PropertyDetails); |
| 14139 | 14166 |
| 14140 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>::Add( | 14167 template MaybeObject* |
| 14141 uint32_t, Object*, PropertyDetails); | 14168 Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>:: |
| 14169 Add(uint32_t, Object*, PropertyDetails); |
| 14142 | 14170 |
| 14143 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>:: | 14171 template MaybeObject* |
| 14172 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
| 14144 EnsureCapacity(int, uint32_t); | 14173 EnsureCapacity(int, uint32_t); |
| 14145 | 14174 |
| 14146 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: | 14175 template MaybeObject* |
| 14176 Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>:: |
| 14147 EnsureCapacity(int, uint32_t); | 14177 EnsureCapacity(int, uint32_t); |
| 14148 | 14178 |
| 14149 template MaybeObject* Dictionary<NameDictionaryShape, Name*>:: | 14179 template MaybeObject* |
| 14180 Dictionary<NameDictionary, NameDictionaryShape, Name*>:: |
| 14150 EnsureCapacity(int, Name*); | 14181 EnsureCapacity(int, Name*); |
| 14151 | 14182 |
| 14152 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>:: | 14183 template MaybeObject* |
| 14184 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
| 14153 AddEntry(uint32_t, Object*, PropertyDetails, uint32_t); | 14185 AddEntry(uint32_t, Object*, PropertyDetails, uint32_t); |
| 14154 | 14186 |
| 14155 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: | 14187 template MaybeObject* |
| 14188 Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>:: |
| 14156 AddEntry(uint32_t, Object*, PropertyDetails, uint32_t); | 14189 AddEntry(uint32_t, Object*, PropertyDetails, uint32_t); |
| 14157 | 14190 |
| 14158 template MaybeObject* Dictionary<NameDictionaryShape, Name*>::AddEntry( | 14191 template MaybeObject* |
| 14192 Dictionary<NameDictionary, NameDictionaryShape, Name*>::AddEntry( |
| 14159 Name*, Object*, PropertyDetails, uint32_t); | 14193 Name*, Object*, PropertyDetails, uint32_t); |
| 14160 | 14194 |
| 14161 template | 14195 template |
| 14162 int Dictionary<SeededNumberDictionaryShape, uint32_t>::NumberOfEnumElements(); | 14196 int Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
| 14197 NumberOfEnumElements(); |
| 14163 | 14198 |
| 14164 template | 14199 template |
| 14165 int Dictionary<NameDictionaryShape, Name*>::NumberOfEnumElements(); | 14200 int Dictionary<NameDictionary, NameDictionaryShape, Name*>:: |
| 14201 NumberOfEnumElements(); |
| 14166 | 14202 |
| 14167 template | 14203 template |
| 14168 int HashTable<SeededNumberDictionaryShape, uint32_t>::FindEntry(uint32_t); | 14204 int HashTable<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
| 14205 FindEntry(uint32_t); |
| 14169 | 14206 |
| 14170 | 14207 |
| 14171 Handle<Object> JSObject::PrepareSlowElementsForSort( | 14208 Handle<Object> JSObject::PrepareSlowElementsForSort( |
| 14172 Handle<JSObject> object, uint32_t limit) { | 14209 Handle<JSObject> object, uint32_t limit) { |
| 14173 CALL_HEAP_FUNCTION(object->GetIsolate(), | 14210 CALL_HEAP_FUNCTION(object->GetIsolate(), |
| 14174 object->PrepareSlowElementsForSort(limit), | 14211 object->PrepareSlowElementsForSort(limit), |
| 14175 Object); | 14212 Object); |
| 14176 } | 14213 } |
| 14177 | 14214 |
| 14178 | 14215 |
| (...skipping 825 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15004 | 15041 |
| 15005 MapCache* cache = reinterpret_cast<MapCache*>(obj); | 15042 MapCache* cache = reinterpret_cast<MapCache*>(obj); |
| 15006 int entry = cache->FindInsertionEntry(key.Hash()); | 15043 int entry = cache->FindInsertionEntry(key.Hash()); |
| 15007 cache->set(EntryToIndex(entry), array); | 15044 cache->set(EntryToIndex(entry), array); |
| 15008 cache->set(EntryToIndex(entry) + 1, value); | 15045 cache->set(EntryToIndex(entry) + 1, value); |
| 15009 cache->ElementAdded(); | 15046 cache->ElementAdded(); |
| 15010 return cache; | 15047 return cache; |
| 15011 } | 15048 } |
| 15012 | 15049 |
| 15013 | 15050 |
| 15014 template<typename Shape, typename Key> | 15051 template<typename Derived, typename Shape, typename Key> |
| 15015 MaybeObject* Dictionary<Shape, Key>::Allocate(Heap* heap, | 15052 MaybeObject* Dictionary<Derived, Shape, Key>::Allocate( |
| 15016 int at_least_space_for, | 15053 Heap* heap, |
| 15017 PretenureFlag pretenure) { | 15054 int at_least_space_for, |
| 15055 PretenureFlag pretenure) { |
| 15018 Object* obj; | 15056 Object* obj; |
| 15019 { MaybeObject* maybe_obj = | 15057 { MaybeObject* maybe_obj = |
| 15020 HashTable<Shape, Key>::Allocate( | 15058 HashTable_::Allocate( |
| 15021 heap, | 15059 heap, |
| 15022 at_least_space_for, | 15060 at_least_space_for, |
| 15023 USE_DEFAULT_MINIMUM_CAPACITY, | 15061 USE_DEFAULT_MINIMUM_CAPACITY, |
| 15024 pretenure); | 15062 pretenure); |
| 15025 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 15063 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 15026 } | 15064 } |
| 15027 // Initialize the next enumeration index. | 15065 // Initialize the next enumeration index. |
| 15028 Dictionary<Shape, Key>::cast(obj)-> | 15066 Dictionary::cast(obj)-> |
| 15029 SetNextEnumerationIndex(PropertyDetails::kInitialIndex); | 15067 SetNextEnumerationIndex(PropertyDetails::kInitialIndex); |
| 15030 return obj; | 15068 return obj; |
| 15031 } | 15069 } |
| 15032 | 15070 |
| 15033 | 15071 |
| 15034 void NameDictionary::DoGenerateNewEnumerationIndices( | 15072 void NameDictionary::DoGenerateNewEnumerationIndices( |
| 15035 Handle<NameDictionary> dictionary) { | 15073 Handle<NameDictionary> dictionary) { |
| 15036 CALL_HEAP_FUNCTION_VOID(dictionary->GetIsolate(), | 15074 CALL_HEAP_FUNCTION_VOID(dictionary->GetIsolate(), |
| 15037 dictionary->GenerateNewEnumerationIndices()); | 15075 dictionary->GenerateNewEnumerationIndices()); |
| 15038 } | 15076 } |
| 15039 | 15077 |
| 15040 template<typename Shape, typename Key> | 15078 template<typename Derived, typename Shape, typename Key> |
| 15041 MaybeObject* Dictionary<Shape, Key>::GenerateNewEnumerationIndices() { | 15079 MaybeObject* Dictionary<Derived, Shape, Key>::GenerateNewEnumerationIndices() { |
| 15042 Heap* heap = Dictionary<Shape, Key>::GetHeap(); | 15080 Heap* heap = Dictionary::GetHeap(); |
| 15043 int length = HashTable<Shape, Key>::NumberOfElements(); | 15081 int length = HashTable_::NumberOfElements(); |
| 15044 | 15082 |
| 15045 // Allocate and initialize iteration order array. | 15083 // Allocate and initialize iteration order array. |
| 15046 Object* obj; | 15084 Object* obj; |
| 15047 { MaybeObject* maybe_obj = heap->AllocateFixedArray(length); | 15085 { MaybeObject* maybe_obj = heap->AllocateFixedArray(length); |
| 15048 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 15086 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 15049 } | 15087 } |
| 15050 FixedArray* iteration_order = FixedArray::cast(obj); | 15088 FixedArray* iteration_order = FixedArray::cast(obj); |
| 15051 for (int i = 0; i < length; i++) { | 15089 for (int i = 0; i < length; i++) { |
| 15052 iteration_order->set(i, Smi::FromInt(i)); | 15090 iteration_order->set(i, Smi::FromInt(i)); |
| 15053 } | 15091 } |
| 15054 | 15092 |
| 15055 // Allocate array with enumeration order. | 15093 // Allocate array with enumeration order. |
| 15056 { MaybeObject* maybe_obj = heap->AllocateFixedArray(length); | 15094 { MaybeObject* maybe_obj = heap->AllocateFixedArray(length); |
| 15057 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 15095 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 15058 } | 15096 } |
| 15059 FixedArray* enumeration_order = FixedArray::cast(obj); | 15097 FixedArray* enumeration_order = FixedArray::cast(obj); |
| 15060 | 15098 |
| 15061 // Fill the enumeration order array with property details. | 15099 // Fill the enumeration order array with property details. |
| 15062 int capacity = HashTable<Shape, Key>::Capacity(); | 15100 int capacity = HashTable_::Capacity(); |
| 15063 int pos = 0; | 15101 int pos = 0; |
| 15064 for (int i = 0; i < capacity; i++) { | 15102 for (int i = 0; i < capacity; i++) { |
| 15065 if (Dictionary<Shape, Key>::IsKey(Dictionary<Shape, Key>::KeyAt(i))) { | 15103 if (Dictionary::IsKey(Dictionary::KeyAt(i))) { |
| 15066 int index = DetailsAt(i).dictionary_index(); | 15104 int index = DetailsAt(i).dictionary_index(); |
| 15067 enumeration_order->set(pos++, Smi::FromInt(index)); | 15105 enumeration_order->set(pos++, Smi::FromInt(index)); |
| 15068 } | 15106 } |
| 15069 } | 15107 } |
| 15070 | 15108 |
| 15071 // Sort the arrays wrt. enumeration order. | 15109 // Sort the arrays wrt. enumeration order. |
| 15072 iteration_order->SortPairs(enumeration_order, enumeration_order->length()); | 15110 iteration_order->SortPairs(enumeration_order, enumeration_order->length()); |
| 15073 | 15111 |
| 15074 // Overwrite the enumeration_order with the enumeration indices. | 15112 // Overwrite the enumeration_order with the enumeration indices. |
| 15075 for (int i = 0; i < length; i++) { | 15113 for (int i = 0; i < length; i++) { |
| 15076 int index = Smi::cast(iteration_order->get(i))->value(); | 15114 int index = Smi::cast(iteration_order->get(i))->value(); |
| 15077 int enum_index = PropertyDetails::kInitialIndex + i; | 15115 int enum_index = PropertyDetails::kInitialIndex + i; |
| 15078 enumeration_order->set(index, Smi::FromInt(enum_index)); | 15116 enumeration_order->set(index, Smi::FromInt(enum_index)); |
| 15079 } | 15117 } |
| 15080 | 15118 |
| 15081 // Update the dictionary with new indices. | 15119 // Update the dictionary with new indices. |
| 15082 capacity = HashTable<Shape, Key>::Capacity(); | 15120 capacity = HashTable_::Capacity(); |
| 15083 pos = 0; | 15121 pos = 0; |
| 15084 for (int i = 0; i < capacity; i++) { | 15122 for (int i = 0; i < capacity; i++) { |
| 15085 if (Dictionary<Shape, Key>::IsKey(Dictionary<Shape, Key>::KeyAt(i))) { | 15123 if (Dictionary::IsKey(Dictionary::KeyAt(i))) { |
| 15086 int enum_index = Smi::cast(enumeration_order->get(pos++))->value(); | 15124 int enum_index = Smi::cast(enumeration_order->get(pos++))->value(); |
| 15087 PropertyDetails details = DetailsAt(i); | 15125 PropertyDetails details = DetailsAt(i); |
| 15088 PropertyDetails new_details = PropertyDetails( | 15126 PropertyDetails new_details = PropertyDetails( |
| 15089 details.attributes(), details.type(), enum_index); | 15127 details.attributes(), details.type(), enum_index); |
| 15090 DetailsAtPut(i, new_details); | 15128 DetailsAtPut(i, new_details); |
| 15091 } | 15129 } |
| 15092 } | 15130 } |
| 15093 | 15131 |
| 15094 // Set the next enumeration index. | 15132 // Set the next enumeration index. |
| 15095 SetNextEnumerationIndex(PropertyDetails::kInitialIndex+length); | 15133 SetNextEnumerationIndex(PropertyDetails::kInitialIndex+length); |
| 15096 return this; | 15134 return this; |
| 15097 } | 15135 } |
| 15098 | 15136 |
| 15099 template<typename Shape, typename Key> | 15137 template<typename Derived, typename Shape, typename Key> |
| 15100 MaybeObject* Dictionary<Shape, Key>::EnsureCapacity(int n, Key key) { | 15138 MaybeObject* Dictionary<Derived, Shape, Key>::EnsureCapacity(int n, Key key) { |
| 15101 // Check whether there are enough enumeration indices to add n elements. | 15139 // Check whether there are enough enumeration indices to add n elements. |
| 15102 if (Shape::kIsEnumerable && | 15140 if (Shape::kIsEnumerable && |
| 15103 !PropertyDetails::IsValidIndex(NextEnumerationIndex() + n)) { | 15141 !PropertyDetails::IsValidIndex(NextEnumerationIndex() + n)) { |
| 15104 // If not, we generate new indices for the properties. | 15142 // If not, we generate new indices for the properties. |
| 15105 Object* result; | 15143 Object* result; |
| 15106 { MaybeObject* maybe_result = GenerateNewEnumerationIndices(); | 15144 { MaybeObject* maybe_result = GenerateNewEnumerationIndices(); |
| 15107 if (!maybe_result->ToObject(&result)) return maybe_result; | 15145 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 15108 } | 15146 } |
| 15109 } | 15147 } |
| 15110 return HashTable<Shape, Key>::EnsureCapacity(n, key); | 15148 return HashTable_::EnsureCapacity(n, key); |
| 15111 } | 15149 } |
| 15112 | 15150 |
| 15113 | 15151 |
| 15114 // TODO(ishell): Temporary wrapper until handlified. | 15152 // TODO(ishell): Temporary wrapper until handlified. |
| 15115 template<typename Shape, typename Key> | 15153 template<typename Derived, typename Shape, typename Key> |
| 15116 Handle<Object> Dictionary<Shape, Key>::DeleteProperty( | 15154 Handle<Object> Dictionary<Derived, Shape, Key>::DeleteProperty( |
| 15117 Handle<Dictionary<Shape, Key> > dictionary, | 15155 Handle<Dictionary<Derived, Shape, Key> > dictionary, |
| 15118 int entry, | 15156 int entry, |
| 15119 JSObject::DeleteMode mode) { | 15157 JSObject::DeleteMode mode) { |
| 15120 CALL_HEAP_FUNCTION(dictionary->GetIsolate(), | 15158 CALL_HEAP_FUNCTION(dictionary->GetIsolate(), |
| 15121 dictionary->DeleteProperty(entry, mode), | 15159 dictionary->DeleteProperty(entry, mode), |
| 15122 Object); | 15160 Object); |
| 15123 } | 15161 } |
| 15124 | 15162 |
| 15125 | 15163 |
| 15126 template<typename Shape, typename Key> | 15164 template<typename Derived, typename Shape, typename Key> |
| 15127 Object* Dictionary<Shape, Key>::DeleteProperty(int entry, | 15165 Object* Dictionary<Derived, Shape, Key>::DeleteProperty( |
| 15128 JSReceiver::DeleteMode mode) { | 15166 int entry, |
| 15129 Heap* heap = Dictionary<Shape, Key>::GetHeap(); | 15167 JSReceiver::DeleteMode mode) { |
| 15168 Heap* heap = Dictionary::GetHeap(); |
| 15130 PropertyDetails details = DetailsAt(entry); | 15169 PropertyDetails details = DetailsAt(entry); |
| 15131 // Ignore attributes if forcing a deletion. | 15170 // Ignore attributes if forcing a deletion. |
| 15132 if (details.IsDontDelete() && mode != JSReceiver::FORCE_DELETION) { | 15171 if (details.IsDontDelete() && mode != JSReceiver::FORCE_DELETION) { |
| 15133 return heap->false_value(); | 15172 return heap->false_value(); |
| 15134 } | 15173 } |
| 15135 SetEntry(entry, heap->the_hole_value(), heap->the_hole_value()); | 15174 SetEntry(entry, heap->the_hole_value(), heap->the_hole_value()); |
| 15136 HashTable<Shape, Key>::ElementRemoved(); | 15175 HashTable_::ElementRemoved(); |
| 15137 return heap->true_value(); | 15176 return heap->true_value(); |
| 15138 } | 15177 } |
| 15139 | 15178 |
| 15140 | 15179 |
| 15141 // TODO(ishell): Temporary wrapper until handlified. | 15180 template<typename Derived, typename Shape, typename Key> |
| 15142 template<typename Shape, typename Key> | 15181 MaybeObject* Dictionary<Derived, Shape, Key>::AtPut(Key key, Object* value) { |
| 15143 Handle<FixedArray> Dictionary<Shape, Key>::Shrink( | |
| 15144 Handle<Dictionary<Shape, Key> > dictionary, | |
| 15145 Key key) { | |
| 15146 CALL_HEAP_FUNCTION(dictionary->GetIsolate(), | |
| 15147 dictionary->Shrink(key), | |
| 15148 FixedArray); | |
| 15149 } | |
| 15150 | |
| 15151 | |
| 15152 template<typename Shape, typename Key> | |
| 15153 MaybeObject* Dictionary<Shape, Key>::Shrink(Key key) { | |
| 15154 return HashTable<Shape, Key>::Shrink(key); | |
| 15155 } | |
| 15156 | |
| 15157 | |
| 15158 template<typename Shape, typename Key> | |
| 15159 MaybeObject* Dictionary<Shape, Key>::AtPut(Key key, Object* value) { | |
| 15160 int entry = this->FindEntry(key); | 15182 int entry = this->FindEntry(key); |
| 15161 | 15183 |
| 15162 // If the entry is present set the value; | 15184 // If the entry is present set the value; |
| 15163 if (entry != Dictionary<Shape, Key>::kNotFound) { | 15185 if (entry != Dictionary::kNotFound) { |
| 15164 ValueAtPut(entry, value); | 15186 ValueAtPut(entry, value); |
| 15165 return this; | 15187 return this; |
| 15166 } | 15188 } |
| 15167 | 15189 |
| 15168 // Check whether the dictionary should be extended. | 15190 // Check whether the dictionary should be extended. |
| 15169 Object* obj; | 15191 Object* obj; |
| 15170 { MaybeObject* maybe_obj = EnsureCapacity(1, key); | 15192 { MaybeObject* maybe_obj = EnsureCapacity(1, key); |
| 15171 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 15193 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 15172 } | 15194 } |
| 15173 | 15195 |
| 15174 Object* k; | 15196 Object* k; |
| 15175 { MaybeObject* maybe_k = Shape::AsObject(this->GetHeap(), key); | 15197 { MaybeObject* maybe_k = Shape::AsObject(this->GetHeap(), key); |
| 15176 if (!maybe_k->ToObject(&k)) return maybe_k; | 15198 if (!maybe_k->ToObject(&k)) return maybe_k; |
| 15177 } | 15199 } |
| 15178 PropertyDetails details = PropertyDetails(NONE, NORMAL, 0); | 15200 PropertyDetails details = PropertyDetails(NONE, NORMAL, 0); |
| 15179 | 15201 |
| 15180 return Dictionary<Shape, Key>::cast(obj)->AddEntry(key, value, details, | 15202 return Dictionary::cast(obj)->AddEntry( |
| 15181 Dictionary<Shape, Key>::Hash(key)); | 15203 key, value, details, Dictionary::Hash(key)); |
| 15182 } | 15204 } |
| 15183 | 15205 |
| 15184 | 15206 |
| 15185 template<typename Shape, typename Key> | 15207 template<typename Derived, typename Shape, typename Key> |
| 15186 MaybeObject* Dictionary<Shape, Key>::Add(Key key, | 15208 MaybeObject* Dictionary<Derived, Shape, Key>::Add( |
| 15187 Object* value, | 15209 Key key, |
| 15188 PropertyDetails details) { | 15210 Object* value, |
| 15211 PropertyDetails details) { |
| 15189 // Valdate key is absent. | 15212 // Valdate key is absent. |
| 15190 SLOW_ASSERT((this->FindEntry(key) == Dictionary<Shape, Key>::kNotFound)); | 15213 SLOW_ASSERT((this->FindEntry(key) == Dictionary::kNotFound)); |
| 15191 // Check whether the dictionary should be extended. | 15214 // Check whether the dictionary should be extended. |
| 15192 Object* obj; | 15215 Object* obj; |
| 15193 { MaybeObject* maybe_obj = EnsureCapacity(1, key); | 15216 { MaybeObject* maybe_obj = EnsureCapacity(1, key); |
| 15194 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 15217 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 15195 } | 15218 } |
| 15196 | 15219 |
| 15197 return Dictionary<Shape, Key>::cast(obj)->AddEntry(key, value, details, | 15220 return Dictionary::cast(obj)->AddEntry( |
| 15198 Dictionary<Shape, Key>::Hash(key)); | 15221 key, value, details, Dictionary::Hash(key)); |
| 15199 } | 15222 } |
| 15200 | 15223 |
| 15201 | 15224 |
| 15202 // Add a key, value pair to the dictionary. | 15225 // Add a key, value pair to the dictionary. |
| 15203 template<typename Shape, typename Key> | 15226 template<typename Derived, typename Shape, typename Key> |
| 15204 MaybeObject* Dictionary<Shape, Key>::AddEntry(Key key, | 15227 MaybeObject* Dictionary<Derived, Shape, Key>::AddEntry( |
| 15205 Object* value, | 15228 Key key, |
| 15206 PropertyDetails details, | 15229 Object* value, |
| 15207 uint32_t hash) { | 15230 PropertyDetails details, |
| 15231 uint32_t hash) { |
| 15208 // Compute the key object. | 15232 // Compute the key object. |
| 15209 Object* k; | 15233 Object* k; |
| 15210 { MaybeObject* maybe_k = Shape::AsObject(this->GetHeap(), key); | 15234 { MaybeObject* maybe_k = Shape::AsObject(this->GetHeap(), key); |
| 15211 if (!maybe_k->ToObject(&k)) return maybe_k; | 15235 if (!maybe_k->ToObject(&k)) return maybe_k; |
| 15212 } | 15236 } |
| 15213 | 15237 |
| 15214 uint32_t entry = Dictionary<Shape, Key>::FindInsertionEntry(hash); | 15238 uint32_t entry = Dictionary::FindInsertionEntry(hash); |
| 15215 // Insert element at empty or deleted entry | 15239 // Insert element at empty or deleted entry |
| 15216 if (!details.IsDeleted() && | 15240 if (!details.IsDeleted() && |
| 15217 details.dictionary_index() == 0 && | 15241 details.dictionary_index() == 0 && |
| 15218 Shape::kIsEnumerable) { | 15242 Shape::kIsEnumerable) { |
| 15219 // Assign an enumeration index to the property and update | 15243 // Assign an enumeration index to the property and update |
| 15220 // SetNextEnumerationIndex. | 15244 // SetNextEnumerationIndex. |
| 15221 int index = NextEnumerationIndex(); | 15245 int index = NextEnumerationIndex(); |
| 15222 details = PropertyDetails(details.attributes(), details.type(), index); | 15246 details = PropertyDetails(details.attributes(), details.type(), index); |
| 15223 SetNextEnumerationIndex(index + 1); | 15247 SetNextEnumerationIndex(index + 1); |
| 15224 } | 15248 } |
| 15225 SetEntry(entry, k, value, details); | 15249 SetEntry(entry, k, value, details); |
| 15226 ASSERT((Dictionary<Shape, Key>::KeyAt(entry)->IsNumber() || | 15250 ASSERT((Dictionary::KeyAt(entry)->IsNumber() || |
| 15227 Dictionary<Shape, Key>::KeyAt(entry)->IsName())); | 15251 Dictionary::KeyAt(entry)->IsName())); |
| 15228 HashTable<Shape, Key>::ElementAdded(); | 15252 HashTable_::ElementAdded(); |
| 15229 return this; | 15253 return this; |
| 15230 } | 15254 } |
| 15231 | 15255 |
| 15232 | 15256 |
| 15233 void SeededNumberDictionary::UpdateMaxNumberKey(uint32_t key) { | 15257 void SeededNumberDictionary::UpdateMaxNumberKey(uint32_t key) { |
| 15234 // If the dictionary requires slow elements an element has already | 15258 // If the dictionary requires slow elements an element has already |
| 15235 // been added at a high index. | 15259 // been added at a high index. |
| 15236 if (requires_slow_elements()) return; | 15260 if (requires_slow_elements()) return; |
| 15237 // Check if this index is high enough that we should require slow | 15261 // Check if this index is high enough that we should require slow |
| 15238 // elements. | 15262 // elements. |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15332 MaybeObject* maybe_object_key = | 15356 MaybeObject* maybe_object_key = |
| 15333 UnseededNumberDictionaryShape::AsObject(GetHeap(), key); | 15357 UnseededNumberDictionaryShape::AsObject(GetHeap(), key); |
| 15334 Object* object_key; | 15358 Object* object_key; |
| 15335 if (!maybe_object_key->ToObject(&object_key)) return maybe_object_key; | 15359 if (!maybe_object_key->ToObject(&object_key)) return maybe_object_key; |
| 15336 SetEntry(entry, object_key, value); | 15360 SetEntry(entry, object_key, value); |
| 15337 return this; | 15361 return this; |
| 15338 } | 15362 } |
| 15339 | 15363 |
| 15340 | 15364 |
| 15341 | 15365 |
| 15342 template<typename Shape, typename Key> | 15366 template<typename Derived, typename Shape, typename Key> |
| 15343 int Dictionary<Shape, Key>::NumberOfElementsFilterAttributes( | 15367 int Dictionary<Derived, Shape, Key>::NumberOfElementsFilterAttributes( |
| 15344 PropertyAttributes filter) { | 15368 PropertyAttributes filter) { |
| 15345 int capacity = HashTable<Shape, Key>::Capacity(); | 15369 int capacity = HashTable_::Capacity(); |
| 15346 int result = 0; | 15370 int result = 0; |
| 15347 for (int i = 0; i < capacity; i++) { | 15371 for (int i = 0; i < capacity; i++) { |
| 15348 Object* k = HashTable<Shape, Key>::KeyAt(i); | 15372 Object* k = HashTable_::KeyAt(i); |
| 15349 if (HashTable<Shape, Key>::IsKey(k) && !FilterKey(k, filter)) { | 15373 if (HashTable_::IsKey(k) && !FilterKey(k, filter)) { |
| 15350 PropertyDetails details = DetailsAt(i); | 15374 PropertyDetails details = DetailsAt(i); |
| 15351 if (details.IsDeleted()) continue; | 15375 if (details.IsDeleted()) continue; |
| 15352 PropertyAttributes attr = details.attributes(); | 15376 PropertyAttributes attr = details.attributes(); |
| 15353 if ((attr & filter) == 0) result++; | 15377 if ((attr & filter) == 0) result++; |
| 15354 } | 15378 } |
| 15355 } | 15379 } |
| 15356 return result; | 15380 return result; |
| 15357 } | 15381 } |
| 15358 | 15382 |
| 15359 | 15383 |
| 15360 template<typename Shape, typename Key> | 15384 template<typename Derived, typename Shape, typename Key> |
| 15361 int Dictionary<Shape, Key>::NumberOfEnumElements() { | 15385 int Dictionary<Derived, Shape, Key>::NumberOfEnumElements() { |
| 15362 return NumberOfElementsFilterAttributes( | 15386 return NumberOfElementsFilterAttributes( |
| 15363 static_cast<PropertyAttributes>(DONT_ENUM | SYMBOLIC)); | 15387 static_cast<PropertyAttributes>(DONT_ENUM | SYMBOLIC)); |
| 15364 } | 15388 } |
| 15365 | 15389 |
| 15366 | 15390 |
| 15367 template<typename Shape, typename Key> | 15391 template<typename Derived, typename Shape, typename Key> |
| 15368 void Dictionary<Shape, Key>::CopyKeysTo( | 15392 void Dictionary<Derived, Shape, Key>::CopyKeysTo( |
| 15369 FixedArray* storage, | 15393 FixedArray* storage, |
| 15370 PropertyAttributes filter, | 15394 PropertyAttributes filter, |
| 15371 typename Dictionary<Shape, Key>::SortMode sort_mode) { | 15395 typename Dictionary<Derived, Shape, Key>::SortMode sort_mode) { |
| 15372 ASSERT(storage->length() >= NumberOfElementsFilterAttributes(filter)); | 15396 ASSERT(storage->length() >= NumberOfElementsFilterAttributes(filter)); |
| 15373 int capacity = HashTable<Shape, Key>::Capacity(); | 15397 int capacity = HashTable_::Capacity(); |
| 15374 int index = 0; | 15398 int index = 0; |
| 15375 for (int i = 0; i < capacity; i++) { | 15399 for (int i = 0; i < capacity; i++) { |
| 15376 Object* k = HashTable<Shape, Key>::KeyAt(i); | 15400 Object* k = HashTable_::KeyAt(i); |
| 15377 if (HashTable<Shape, Key>::IsKey(k) && !FilterKey(k, filter)) { | 15401 if (HashTable_::IsKey(k) && !FilterKey(k, filter)) { |
| 15378 PropertyDetails details = DetailsAt(i); | 15402 PropertyDetails details = DetailsAt(i); |
| 15379 if (details.IsDeleted()) continue; | 15403 if (details.IsDeleted()) continue; |
| 15380 PropertyAttributes attr = details.attributes(); | 15404 PropertyAttributes attr = details.attributes(); |
| 15381 if ((attr & filter) == 0) storage->set(index++, k); | 15405 if ((attr & filter) == 0) storage->set(index++, k); |
| 15382 } | 15406 } |
| 15383 } | 15407 } |
| 15384 if (sort_mode == Dictionary<Shape, Key>::SORTED) { | 15408 if (sort_mode == Dictionary::SORTED) { |
| 15385 storage->SortPairs(storage, index); | 15409 storage->SortPairs(storage, index); |
| 15386 } | 15410 } |
| 15387 ASSERT(storage->length() >= index); | 15411 ASSERT(storage->length() >= index); |
| 15388 } | 15412 } |
| 15389 | 15413 |
| 15390 | 15414 |
| 15391 struct EnumIndexComparator { | 15415 struct EnumIndexComparator { |
| 15392 explicit EnumIndexComparator(NameDictionary* dict) : dict(dict) { } | 15416 explicit EnumIndexComparator(NameDictionary* dict) : dict(dict) { } |
| 15393 bool operator() (Smi* a, Smi* b) { | 15417 bool operator() (Smi* a, Smi* b) { |
| 15394 PropertyDetails da(dict->DetailsAt(a->value())); | 15418 PropertyDetails da(dict->DetailsAt(a->value())); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 15416 EnumIndexComparator cmp(this); | 15440 EnumIndexComparator cmp(this); |
| 15417 Smi** start = reinterpret_cast<Smi**>(storage->GetFirstElementAddress()); | 15441 Smi** start = reinterpret_cast<Smi**>(storage->GetFirstElementAddress()); |
| 15418 std::sort(start, start + length, cmp); | 15442 std::sort(start, start + length, cmp); |
| 15419 for (int i = 0; i < length; i++) { | 15443 for (int i = 0; i < length; i++) { |
| 15420 int index = Smi::cast(storage->get(i))->value(); | 15444 int index = Smi::cast(storage->get(i))->value(); |
| 15421 storage->set(i, KeyAt(index)); | 15445 storage->set(i, KeyAt(index)); |
| 15422 } | 15446 } |
| 15423 } | 15447 } |
| 15424 | 15448 |
| 15425 | 15449 |
| 15426 template<typename Shape, typename Key> | 15450 template<typename Derived, typename Shape, typename Key> |
| 15427 void Dictionary<Shape, Key>::CopyKeysTo( | 15451 void Dictionary<Derived, Shape, Key>::CopyKeysTo( |
| 15428 FixedArray* storage, | 15452 FixedArray* storage, |
| 15429 int index, | 15453 int index, |
| 15430 PropertyAttributes filter, | 15454 PropertyAttributes filter, |
| 15431 typename Dictionary<Shape, Key>::SortMode sort_mode) { | 15455 typename Dictionary<Derived, Shape, Key>::SortMode sort_mode) { |
| 15432 ASSERT(storage->length() >= NumberOfElementsFilterAttributes(filter)); | 15456 ASSERT(storage->length() >= NumberOfElementsFilterAttributes(filter)); |
| 15433 int capacity = HashTable<Shape, Key>::Capacity(); | 15457 int capacity = HashTable_::Capacity(); |
| 15434 for (int i = 0; i < capacity; i++) { | 15458 for (int i = 0; i < capacity; i++) { |
| 15435 Object* k = HashTable<Shape, Key>::KeyAt(i); | 15459 Object* k = HashTable_::KeyAt(i); |
| 15436 if (HashTable<Shape, Key>::IsKey(k) && !FilterKey(k, filter)) { | 15460 if (HashTable_::IsKey(k) && !FilterKey(k, filter)) { |
| 15437 PropertyDetails details = DetailsAt(i); | 15461 PropertyDetails details = DetailsAt(i); |
| 15438 if (details.IsDeleted()) continue; | 15462 if (details.IsDeleted()) continue; |
| 15439 PropertyAttributes attr = details.attributes(); | 15463 PropertyAttributes attr = details.attributes(); |
| 15440 if ((attr & filter) == 0) storage->set(index++, k); | 15464 if ((attr & filter) == 0) storage->set(index++, k); |
| 15441 } | 15465 } |
| 15442 } | 15466 } |
| 15443 if (sort_mode == Dictionary<Shape, Key>::SORTED) { | 15467 if (sort_mode == Dictionary::SORTED) { |
| 15444 storage->SortPairs(storage, index); | 15468 storage->SortPairs(storage, index); |
| 15445 } | 15469 } |
| 15446 ASSERT(storage->length() >= index); | 15470 ASSERT(storage->length() >= index); |
| 15447 } | 15471 } |
| 15448 | 15472 |
| 15449 | 15473 |
| 15450 // Backwards lookup (slow). | 15474 // Backwards lookup (slow). |
| 15451 template<typename Shape, typename Key> | 15475 template<typename Derived, typename Shape, typename Key> |
| 15452 Object* Dictionary<Shape, Key>::SlowReverseLookup(Object* value) { | 15476 Object* Dictionary<Derived, Shape, Key>::SlowReverseLookup(Object* value) { |
| 15453 int capacity = HashTable<Shape, Key>::Capacity(); | 15477 int capacity = HashTable_::Capacity(); |
| 15454 for (int i = 0; i < capacity; i++) { | 15478 for (int i = 0; i < capacity; i++) { |
| 15455 Object* k = HashTable<Shape, Key>::KeyAt(i); | 15479 Object* k = HashTable_::KeyAt(i); |
| 15456 if (Dictionary<Shape, Key>::IsKey(k)) { | 15480 if (Dictionary::IsKey(k)) { |
| 15457 Object* e = ValueAt(i); | 15481 Object* e = ValueAt(i); |
| 15458 if (e->IsPropertyCell()) { | 15482 if (e->IsPropertyCell()) { |
| 15459 e = PropertyCell::cast(e)->value(); | 15483 e = PropertyCell::cast(e)->value(); |
| 15460 } | 15484 } |
| 15461 if (e == value) return k; | 15485 if (e == value) return k; |
| 15462 } | 15486 } |
| 15463 } | 15487 } |
| 15464 Heap* heap = Dictionary<Shape, Key>::GetHeap(); | 15488 Heap* heap = Dictionary::GetHeap(); |
| 15465 return heap->undefined_value(); | 15489 return heap->undefined_value(); |
| 15466 } | 15490 } |
| 15467 | 15491 |
| 15468 | 15492 |
| 15469 MaybeObject* NameDictionary::TransformPropertiesToFastFor( | 15493 MaybeObject* NameDictionary::TransformPropertiesToFastFor( |
| 15470 JSObject* obj, int unused_property_fields) { | 15494 JSObject* obj, int unused_property_fields) { |
| 15471 // Make sure we preserve dictionary representation if there are too many | 15495 // Make sure we preserve dictionary representation if there are too many |
| 15472 // descriptors. | 15496 // descriptors. |
| 15473 int number_of_elements = NumberOfElements(); | 15497 int number_of_elements = NumberOfElements(); |
| 15474 if (number_of_elements > kMaxNumberOfDescriptors) return obj; | 15498 if (number_of_elements > kMaxNumberOfDescriptors) return obj; |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15609 | 15633 |
| 15610 return obj; | 15634 return obj; |
| 15611 } | 15635 } |
| 15612 | 15636 |
| 15613 | 15637 |
| 15614 Handle<ObjectHashTable> ObjectHashTable::EnsureCapacity( | 15638 Handle<ObjectHashTable> ObjectHashTable::EnsureCapacity( |
| 15615 Handle<ObjectHashTable> table, | 15639 Handle<ObjectHashTable> table, |
| 15616 int n, | 15640 int n, |
| 15617 Handle<Object> key, | 15641 Handle<Object> key, |
| 15618 PretenureFlag pretenure) { | 15642 PretenureFlag pretenure) { |
| 15619 Handle<HashTable<ObjectHashTableShape, Object*> > table_base = table; | 15643 Handle<HashTable<ObjectHashTable, |
| 15644 ObjectHashTableShape, |
| 15645 Object*> > table_base = table; |
| 15620 CALL_HEAP_FUNCTION(table_base->GetIsolate(), | 15646 CALL_HEAP_FUNCTION(table_base->GetIsolate(), |
| 15621 table_base->EnsureCapacity(n, *key, pretenure), | 15647 table_base->EnsureCapacity(n, *key, pretenure), |
| 15622 ObjectHashTable); | 15648 ObjectHashTable); |
| 15623 } | 15649 } |
| 15624 | 15650 |
| 15625 | 15651 |
| 15626 Handle<ObjectHashTable> ObjectHashTable::Shrink( | |
| 15627 Handle<ObjectHashTable> table, Handle<Object> key) { | |
| 15628 Handle<HashTable<ObjectHashTableShape, Object*> > table_base = table; | |
| 15629 CALL_HEAP_FUNCTION(table_base->GetIsolate(), | |
| 15630 table_base->Shrink(*key), | |
| 15631 ObjectHashTable); | |
| 15632 } | |
| 15633 | |
| 15634 | |
| 15635 Object* ObjectHashTable::Lookup(Object* key) { | 15652 Object* ObjectHashTable::Lookup(Object* key) { |
| 15636 ASSERT(IsKey(key)); | 15653 ASSERT(IsKey(key)); |
| 15637 | 15654 |
| 15638 // If the object does not have an identity hash, it was never used as a key. | 15655 // If the object does not have an identity hash, it was never used as a key. |
| 15639 Object* hash = key->GetHash(); | 15656 Object* hash = key->GetHash(); |
| 15640 if (hash->IsUndefined()) { | 15657 if (hash->IsUndefined()) { |
| 15641 return GetHeap()->the_hole_value(); | 15658 return GetHeap()->the_hole_value(); |
| 15642 } | 15659 } |
| 15643 int entry = FindEntry(key); | 15660 int entry = FindEntry(key); |
| 15644 if (entry == kNotFound) return GetHeap()->the_hole_value(); | 15661 if (entry == kNotFound) return GetHeap()->the_hole_value(); |
| (...skipping 859 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16504 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16521 #define ERROR_MESSAGES_TEXTS(C, T) T, |
| 16505 static const char* error_messages_[] = { | 16522 static const char* error_messages_[] = { |
| 16506 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16523 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
| 16507 }; | 16524 }; |
| 16508 #undef ERROR_MESSAGES_TEXTS | 16525 #undef ERROR_MESSAGES_TEXTS |
| 16509 return error_messages_[reason]; | 16526 return error_messages_[reason]; |
| 16510 } | 16527 } |
| 16511 | 16528 |
| 16512 | 16529 |
| 16513 } } // namespace v8::internal | 16530 } } // namespace v8::internal |
| OLD | NEW |