| 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 674 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 685 PropertyCell::cast(property_dictionary->ValueAt(entry))); | 685 PropertyCell::cast(property_dictionary->ValueAt(entry))); |
| 686 PropertyCell::SetValueInferType(cell, value); | 686 PropertyCell::SetValueInferType(cell, value); |
| 687 // Please note we have to update the property details. | 687 // Please note we have to update the property details. |
| 688 property_dictionary->DetailsAtPut(entry, details); | 688 property_dictionary->DetailsAtPut(entry, details); |
| 689 } else { | 689 } else { |
| 690 property_dictionary->SetEntry(entry, *name, *value, details); | 690 property_dictionary->SetEntry(entry, *name, *value, details); |
| 691 } | 691 } |
| 692 } | 692 } |
| 693 | 693 |
| 694 | 694 |
| 695 // TODO(mstarzinger): Temporary wrapper until target is handlified. | |
| 696 Handle<NameDictionary> NameDictionaryShrink(Handle<NameDictionary> dict, | |
| 697 Handle<Name> name) { | |
| 698 CALL_HEAP_FUNCTION(dict->GetIsolate(), dict->Shrink(*name), NameDictionary); | |
| 699 } | |
| 700 | |
| 701 | |
| 702 Handle<Object> JSObject::DeleteNormalizedProperty(Handle<JSObject> object, | 695 Handle<Object> JSObject::DeleteNormalizedProperty(Handle<JSObject> object, |
| 703 Handle<Name> name, | 696 Handle<Name> name, |
| 704 DeleteMode mode) { | 697 DeleteMode mode) { |
| 705 ASSERT(!object->HasFastProperties()); | 698 ASSERT(!object->HasFastProperties()); |
| 706 Isolate* isolate = object->GetIsolate(); | 699 Isolate* isolate = object->GetIsolate(); |
| 707 Handle<NameDictionary> dictionary(object->property_dictionary()); | 700 Handle<NameDictionary> dictionary(object->property_dictionary()); |
| 708 int entry = dictionary->FindEntry(*name); | 701 int entry = dictionary->FindEntry(*name); |
| 709 if (entry != NameDictionary::kNotFound) { | 702 if (entry != NameDictionary::kNotFound) { |
| 710 // If we have a global object set the cell to the hole. | 703 // If we have a global object set the cell to the hole. |
| 711 if (object->IsGlobalObject()) { | 704 if (object->IsGlobalObject()) { |
| 712 PropertyDetails details = dictionary->DetailsAt(entry); | 705 PropertyDetails details = dictionary->DetailsAt(entry); |
| 713 if (details.IsDontDelete()) { | 706 if (details.IsDontDelete()) { |
| 714 if (mode != FORCE_DELETION) return isolate->factory()->false_value(); | 707 if (mode != FORCE_DELETION) return isolate->factory()->false_value(); |
| 715 // When forced to delete global properties, we have to make a | 708 // When forced to delete global properties, we have to make a |
| 716 // map change to invalidate any ICs that think they can load | 709 // map change to invalidate any ICs that think they can load |
| 717 // from the DontDelete cell without checking if it contains | 710 // from the DontDelete cell without checking if it contains |
| 718 // the hole value. | 711 // the hole value. |
| 719 Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map())); | 712 Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map())); |
| 720 ASSERT(new_map->is_dictionary_map()); | 713 ASSERT(new_map->is_dictionary_map()); |
| 721 object->set_map(*new_map); | 714 object->set_map(*new_map); |
| 722 } | 715 } |
| 723 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry))); | 716 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry))); |
| 724 Handle<Object> value = isolate->factory()->the_hole_value(); | 717 Handle<Object> value = isolate->factory()->the_hole_value(); |
| 725 PropertyCell::SetValueInferType(cell, value); | 718 PropertyCell::SetValueInferType(cell, value); |
| 726 dictionary->DetailsAtPut(entry, details.AsDeleted()); | 719 dictionary->DetailsAtPut(entry, details.AsDeleted()); |
| 727 } else { | 720 } else { |
| 728 Handle<Object> deleted(dictionary->DeleteProperty(entry, mode), isolate); | 721 Handle<Object> deleted(dictionary->DeleteProperty(entry, mode), isolate); |
| 729 if (*deleted == isolate->heap()->true_value()) { | 722 if (*deleted == isolate->heap()->true_value()) { |
| 730 Handle<NameDictionary> new_properties = | 723 Handle<NameDictionary> new_properties = |
| 731 NameDictionaryShrink(dictionary, name); | 724 NameDictionary::Shrink(dictionary, *name); |
| 732 object->set_properties(*new_properties); | 725 object->set_properties(*new_properties); |
| 733 } | 726 } |
| 734 return deleted; | 727 return deleted; |
| 735 } | 728 } |
| 736 } | 729 } |
| 737 return isolate->factory()->true_value(); | 730 return isolate->factory()->true_value(); |
| 738 } | 731 } |
| 739 | 732 |
| 740 | 733 |
| 741 bool JSObject::IsDirty() { | 734 bool JSObject::IsDirty() { |
| (...skipping 12423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13165 } | 13158 } |
| 13166 } | 13159 } |
| 13167 | 13160 |
| 13168 | 13161 |
| 13169 // Certain compilers request function template instantiation when they | 13162 // Certain compilers request function template instantiation when they |
| 13170 // see the definition of the other template functions in the | 13163 // see the definition of the other template functions in the |
| 13171 // class. This requires us to have the template functions put | 13164 // class. This requires us to have the template functions put |
| 13172 // together, so even though this function belongs in objects-debug.cc, | 13165 // together, so even though this function belongs in objects-debug.cc, |
| 13173 // we keep it here instead to satisfy certain compilers. | 13166 // we keep it here instead to satisfy certain compilers. |
| 13174 #ifdef OBJECT_PRINT | 13167 #ifdef OBJECT_PRINT |
| 13175 template<typename Shape, typename Key> | 13168 template<typename Derived, typename Shape, typename Key> |
| 13176 void Dictionary<Shape, Key>::Print(FILE* out) { | 13169 void Dictionary<Derived, Shape, Key>::Print(FILE* out) { |
| 13177 int capacity = HashTable<Shape, Key>::Capacity(); | 13170 int capacity = DerivedHashTable::Capacity(); |
| 13178 for (int i = 0; i < capacity; i++) { | 13171 for (int i = 0; i < capacity; i++) { |
| 13179 Object* k = HashTable<Shape, Key>::KeyAt(i); | 13172 Object* k = DerivedHashTable::KeyAt(i); |
| 13180 if (HashTable<Shape, Key>::IsKey(k)) { | 13173 if (DerivedHashTable::IsKey(k)) { |
| 13181 PrintF(out, " "); | 13174 PrintF(out, " "); |
| 13182 if (k->IsString()) { | 13175 if (k->IsString()) { |
| 13183 String::cast(k)->StringPrint(out); | 13176 String::cast(k)->StringPrint(out); |
| 13184 } else { | 13177 } else { |
| 13185 k->ShortPrint(out); | 13178 k->ShortPrint(out); |
| 13186 } | 13179 } |
| 13187 PrintF(out, ": "); | 13180 PrintF(out, ": "); |
| 13188 ValueAt(i)->ShortPrint(out); | 13181 ValueAt(i)->ShortPrint(out); |
| 13189 PrintF(out, "\n"); | 13182 PrintF(out, "\n"); |
| 13190 } | 13183 } |
| 13191 } | 13184 } |
| 13192 } | 13185 } |
| 13193 #endif | 13186 #endif |
| 13194 | 13187 |
| 13195 | 13188 |
| 13196 template<typename Shape, typename Key> | 13189 template<typename Derived, typename Shape, typename Key> |
| 13197 void Dictionary<Shape, Key>::CopyValuesTo(FixedArray* elements) { | 13190 void Dictionary<Derived, Shape, Key>::CopyValuesTo(FixedArray* elements) { |
| 13198 int pos = 0; | 13191 int pos = 0; |
| 13199 int capacity = HashTable<Shape, Key>::Capacity(); | 13192 int capacity = DerivedHashTable::Capacity(); |
| 13200 DisallowHeapAllocation no_gc; | 13193 DisallowHeapAllocation no_gc; |
| 13201 WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc); | 13194 WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc); |
| 13202 for (int i = 0; i < capacity; i++) { | 13195 for (int i = 0; i < capacity; i++) { |
| 13203 Object* k = Dictionary<Shape, Key>::KeyAt(i); | 13196 Object* k = Dictionary::KeyAt(i); |
| 13204 if (Dictionary<Shape, Key>::IsKey(k)) { | 13197 if (Dictionary::IsKey(k)) { |
| 13205 elements->set(pos++, ValueAt(i), mode); | 13198 elements->set(pos++, ValueAt(i), mode); |
| 13206 } | 13199 } |
| 13207 } | 13200 } |
| 13208 ASSERT(pos == elements->length()); | 13201 ASSERT(pos == elements->length()); |
| 13209 } | 13202 } |
| 13210 | 13203 |
| 13211 | 13204 |
| 13212 InterceptorInfo* JSObject::GetNamedInterceptor() { | 13205 InterceptorInfo* JSObject::GetNamedInterceptor() { |
| 13213 ASSERT(map()->has_named_interceptor()); | 13206 ASSERT(map()->has_named_interceptor()); |
| 13214 JSFunction* constructor = JSFunction::cast(map()->constructor()); | 13207 JSFunction* constructor = JSFunction::cast(map()->constructor()); |
| (...skipping 686 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13901 } | 13894 } |
| 13902 | 13895 |
| 13903 static uint32_t StringHash(Object* obj) { | 13896 static uint32_t StringHash(Object* obj) { |
| 13904 return String::cast(obj)->Hash(); | 13897 return String::cast(obj)->Hash(); |
| 13905 } | 13898 } |
| 13906 | 13899 |
| 13907 String* string_; | 13900 String* string_; |
| 13908 }; | 13901 }; |
| 13909 | 13902 |
| 13910 | 13903 |
| 13911 template<typename Shape, typename Key> | 13904 template<typename Derived, typename Shape, typename Key> |
| 13912 void HashTable<Shape, Key>::IteratePrefix(ObjectVisitor* v) { | 13905 void HashTable<Derived, Shape, Key>::IteratePrefix(ObjectVisitor* v) { |
| 13913 IteratePointers(v, 0, kElementsStartOffset); | 13906 IteratePointers(v, 0, kElementsStartOffset); |
| 13914 } | 13907 } |
| 13915 | 13908 |
| 13916 | 13909 |
| 13917 template<typename Shape, typename Key> | 13910 template<typename Derived, typename Shape, typename Key> |
| 13918 void HashTable<Shape, Key>::IterateElements(ObjectVisitor* v) { | 13911 void HashTable<Derived, Shape, Key>::IterateElements(ObjectVisitor* v) { |
| 13919 IteratePointers(v, | 13912 IteratePointers(v, |
| 13920 kElementsStartOffset, | 13913 kElementsStartOffset, |
| 13921 kHeaderSize + length() * kPointerSize); | 13914 kHeaderSize + length() * kPointerSize); |
| 13922 } | 13915 } |
| 13923 | 13916 |
| 13924 | 13917 |
| 13925 template<typename Shape, typename Key> | 13918 template<typename Derived, typename Shape, typename Key> |
| 13926 MaybeObject* HashTable<Shape, Key>::Allocate(Heap* heap, | 13919 MaybeObject* HashTable<Derived, Shape, Key>::Allocate( |
| 13927 int at_least_space_for, | 13920 Heap* heap, |
| 13928 MinimumCapacity capacity_option, | 13921 int at_least_space_for, |
| 13929 PretenureFlag pretenure) { | 13922 MinimumCapacity capacity_option, |
| 13923 PretenureFlag pretenure) { |
| 13930 ASSERT(!capacity_option || IsPowerOf2(at_least_space_for)); | 13924 ASSERT(!capacity_option || IsPowerOf2(at_least_space_for)); |
| 13931 int capacity = (capacity_option == USE_CUSTOM_MINIMUM_CAPACITY) | 13925 int capacity = (capacity_option == USE_CUSTOM_MINIMUM_CAPACITY) |
| 13932 ? at_least_space_for | 13926 ? at_least_space_for |
| 13933 : ComputeCapacity(at_least_space_for); | 13927 : ComputeCapacity(at_least_space_for); |
| 13934 if (capacity > HashTable::kMaxCapacity) { | 13928 if (capacity > HashTable::kMaxCapacity) { |
| 13935 v8::internal::Heap::FatalProcessOutOfMemory("invalid table size", true); | 13929 v8::internal::Heap::FatalProcessOutOfMemory("invalid table size", true); |
| 13936 } | 13930 } |
| 13937 | 13931 |
| 13938 Object* obj; | 13932 Object* obj; |
| 13939 { MaybeObject* maybe_obj = | 13933 { MaybeObject* maybe_obj = |
| 13940 heap-> AllocateHashTable(EntryToIndex(capacity), pretenure); | 13934 heap-> AllocateHashTable(EntryToIndex(capacity), pretenure); |
| 13941 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 13935 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 13942 } | 13936 } |
| 13943 HashTable::cast(obj)->SetNumberOfElements(0); | 13937 HashTable::cast(obj)->SetNumberOfElements(0); |
| 13944 HashTable::cast(obj)->SetNumberOfDeletedElements(0); | 13938 HashTable::cast(obj)->SetNumberOfDeletedElements(0); |
| 13945 HashTable::cast(obj)->SetCapacity(capacity); | 13939 HashTable::cast(obj)->SetCapacity(capacity); |
| 13946 return obj; | 13940 return obj; |
| 13947 } | 13941 } |
| 13948 | 13942 |
| 13949 | 13943 |
| 13944 template<typename Derived, typename Shape, typename Key> |
| 13945 Handle<Derived> HashTable<Derived, Shape, Key>::New( |
| 13946 Isolate* isolate, |
| 13947 int at_least_space_for, |
| 13948 MinimumCapacity capacity_option, |
| 13949 PretenureFlag pretenure) { |
| 13950 CALL_HEAP_FUNCTION( |
| 13951 isolate, |
| 13952 Allocate(isolate->heap(), at_least_space_for, capacity_option, pretenure), |
| 13953 Derived); |
| 13954 } |
| 13955 |
| 13956 |
| 13950 // Find entry for key otherwise return kNotFound. | 13957 // Find entry for key otherwise return kNotFound. |
| 13951 int NameDictionary::FindEntry(Name* key) { | 13958 int NameDictionary::FindEntry(Name* key) { |
| 13952 if (!key->IsUniqueName()) { | 13959 if (!key->IsUniqueName()) { |
| 13953 return HashTable<NameDictionaryShape, Name*>::FindEntry(key); | 13960 return DerivedHashTable::FindEntry(key); |
| 13954 } | 13961 } |
| 13955 | 13962 |
| 13956 // Optimized for unique names. Knowledge of the key type allows: | 13963 // Optimized for unique names. Knowledge of the key type allows: |
| 13957 // 1. Move the check if the key is unique out of the loop. | 13964 // 1. Move the check if the key is unique out of the loop. |
| 13958 // 2. Avoid comparing hash codes in unique-to-unique comparison. | 13965 // 2. Avoid comparing hash codes in unique-to-unique comparison. |
| 13959 // 3. Detect a case when a dictionary key is not unique but the key is. | 13966 // 3. Detect a case when a dictionary key is not unique but the key is. |
| 13960 // In case of positive result the dictionary key may be replaced by the | 13967 // In case of positive result the dictionary key may be replaced by the |
| 13961 // internalized string with minimal performance penalty. It gives a chance | 13968 // internalized string with minimal performance penalty. It gives a chance |
| 13962 // to perform further lookups in code stubs (and significant performance | 13969 // to perform further lookups in code stubs (and significant performance |
| 13963 // boost a certain style of code). | 13970 // boost a certain style of code). |
| (...skipping 16 matching lines...) Expand all Loading... |
| 13980 set(index, key); | 13987 set(index, key); |
| 13981 return entry; | 13988 return entry; |
| 13982 } | 13989 } |
| 13983 ASSERT(element->IsTheHole() || !Name::cast(element)->Equals(key)); | 13990 ASSERT(element->IsTheHole() || !Name::cast(element)->Equals(key)); |
| 13984 entry = NextProbe(entry, count++, capacity); | 13991 entry = NextProbe(entry, count++, capacity); |
| 13985 } | 13992 } |
| 13986 return kNotFound; | 13993 return kNotFound; |
| 13987 } | 13994 } |
| 13988 | 13995 |
| 13989 | 13996 |
| 13990 template<typename Shape, typename Key> | 13997 template<typename Derived, typename Shape, typename Key> |
| 13991 MaybeObject* HashTable<Shape, Key>::Rehash(HashTable* new_table, Key key) { | 13998 void HashTable<Derived, Shape, Key>::Rehash(Derived* new_table, Key key) { |
| 13992 ASSERT(NumberOfElements() < new_table->Capacity()); | 13999 ASSERT(NumberOfElements() < new_table->Capacity()); |
| 13993 | 14000 |
| 13994 DisallowHeapAllocation no_gc; | 14001 DisallowHeapAllocation no_gc; |
| 13995 WriteBarrierMode mode = new_table->GetWriteBarrierMode(no_gc); | 14002 WriteBarrierMode mode = new_table->GetWriteBarrierMode(no_gc); |
| 13996 | 14003 |
| 13997 // Copy prefix to new array. | 14004 // Copy prefix to new array. |
| 13998 for (int i = kPrefixStartIndex; | 14005 for (int i = kPrefixStartIndex; |
| 13999 i < kPrefixStartIndex + Shape::kPrefixSize; | 14006 i < kPrefixStartIndex + Shape::kPrefixSize; |
| 14000 i++) { | 14007 i++) { |
| 14001 new_table->set(i, get(i), mode); | 14008 new_table->set(i, get(i), mode); |
| 14002 } | 14009 } |
| 14003 | 14010 |
| 14004 // Rehash the elements. | 14011 // Rehash the elements. |
| 14005 int capacity = Capacity(); | 14012 int capacity = Capacity(); |
| 14006 for (int i = 0; i < capacity; i++) { | 14013 for (int i = 0; i < capacity; i++) { |
| 14007 uint32_t from_index = EntryToIndex(i); | 14014 uint32_t from_index = EntryToIndex(i); |
| 14008 Object* k = get(from_index); | 14015 Object* k = get(from_index); |
| 14009 if (IsKey(k)) { | 14016 if (IsKey(k)) { |
| 14010 uint32_t hash = HashTable<Shape, Key>::HashForObject(key, k); | 14017 uint32_t hash = HashTable::HashForObject(key, k); |
| 14011 uint32_t insertion_index = | 14018 uint32_t insertion_index = |
| 14012 EntryToIndex(new_table->FindInsertionEntry(hash)); | 14019 EntryToIndex(new_table->FindInsertionEntry(hash)); |
| 14013 for (int j = 0; j < Shape::kEntrySize; j++) { | 14020 for (int j = 0; j < Shape::kEntrySize; j++) { |
| 14014 new_table->set(insertion_index + j, get(from_index + j), mode); | 14021 new_table->set(insertion_index + j, get(from_index + j), mode); |
| 14015 } | 14022 } |
| 14016 } | 14023 } |
| 14017 } | 14024 } |
| 14018 new_table->SetNumberOfElements(NumberOfElements()); | 14025 new_table->SetNumberOfElements(NumberOfElements()); |
| 14019 new_table->SetNumberOfDeletedElements(0); | 14026 new_table->SetNumberOfDeletedElements(0); |
| 14020 return new_table; | |
| 14021 } | 14027 } |
| 14022 | 14028 |
| 14023 | 14029 |
| 14024 template<typename Shape, typename Key> | 14030 template<typename Derived, typename Shape, typename Key> |
| 14025 uint32_t HashTable<Shape, Key>::EntryForProbe(Key key, | 14031 uint32_t HashTable<Derived, Shape, Key>::EntryForProbe( |
| 14026 Object* k, | 14032 Key key, |
| 14027 int probe, | 14033 Object* k, |
| 14028 uint32_t expected) { | 14034 int probe, |
| 14029 uint32_t hash = HashTable<Shape, Key>::HashForObject(key, k); | 14035 uint32_t expected) { |
| 14036 uint32_t hash = HashTable::HashForObject(key, k); |
| 14030 uint32_t capacity = Capacity(); | 14037 uint32_t capacity = Capacity(); |
| 14031 uint32_t entry = FirstProbe(hash, capacity); | 14038 uint32_t entry = FirstProbe(hash, capacity); |
| 14032 for (int i = 1; i < probe; i++) { | 14039 for (int i = 1; i < probe; i++) { |
| 14033 if (entry == expected) return expected; | 14040 if (entry == expected) return expected; |
| 14034 entry = NextProbe(entry, i, capacity); | 14041 entry = NextProbe(entry, i, capacity); |
| 14035 } | 14042 } |
| 14036 return entry; | 14043 return entry; |
| 14037 } | 14044 } |
| 14038 | 14045 |
| 14039 | 14046 |
| 14040 template<typename Shape, typename Key> | 14047 template<typename Derived, typename Shape, typename Key> |
| 14041 void HashTable<Shape, Key>::Swap(uint32_t entry1, | 14048 void HashTable<Derived, Shape, Key>::Swap(uint32_t entry1, |
| 14042 uint32_t entry2, | 14049 uint32_t entry2, |
| 14043 WriteBarrierMode mode) { | 14050 WriteBarrierMode mode) { |
| 14044 int index1 = EntryToIndex(entry1); | 14051 int index1 = EntryToIndex(entry1); |
| 14045 int index2 = EntryToIndex(entry2); | 14052 int index2 = EntryToIndex(entry2); |
| 14046 Object* temp[Shape::kEntrySize]; | 14053 Object* temp[Shape::kEntrySize]; |
| 14047 for (int j = 0; j < Shape::kEntrySize; j++) { | 14054 for (int j = 0; j < Shape::kEntrySize; j++) { |
| 14048 temp[j] = get(index1 + j); | 14055 temp[j] = get(index1 + j); |
| 14049 } | 14056 } |
| 14050 for (int j = 0; j < Shape::kEntrySize; j++) { | 14057 for (int j = 0; j < Shape::kEntrySize; j++) { |
| 14051 set(index1 + j, get(index2 + j), mode); | 14058 set(index1 + j, get(index2 + j), mode); |
| 14052 } | 14059 } |
| 14053 for (int j = 0; j < Shape::kEntrySize; j++) { | 14060 for (int j = 0; j < Shape::kEntrySize; j++) { |
| 14054 set(index2 + j, temp[j], mode); | 14061 set(index2 + j, temp[j], mode); |
| 14055 } | 14062 } |
| 14056 } | 14063 } |
| 14057 | 14064 |
| 14058 | 14065 |
| 14059 template<typename Shape, typename Key> | 14066 template<typename Derived, typename Shape, typename Key> |
| 14060 void HashTable<Shape, Key>::Rehash(Key key) { | 14067 void HashTable<Derived, Shape, Key>::Rehash(Key key) { |
| 14061 DisallowHeapAllocation no_gc; | 14068 DisallowHeapAllocation no_gc; |
| 14062 WriteBarrierMode mode = GetWriteBarrierMode(no_gc); | 14069 WriteBarrierMode mode = GetWriteBarrierMode(no_gc); |
| 14063 uint32_t capacity = Capacity(); | 14070 uint32_t capacity = Capacity(); |
| 14064 bool done = false; | 14071 bool done = false; |
| 14065 for (int probe = 1; !done; probe++) { | 14072 for (int probe = 1; !done; probe++) { |
| 14066 // All elements at entries given by one of the first _probe_ probes | 14073 // All elements at entries given by one of the first _probe_ probes |
| 14067 // are placed correctly. Other elements might need to be moved. | 14074 // are placed correctly. Other elements might need to be moved. |
| 14068 done = true; | 14075 done = true; |
| 14069 for (uint32_t current = 0; current < capacity; current++) { | 14076 for (uint32_t current = 0; current < capacity; current++) { |
| 14070 Object* current_key = get(EntryToIndex(current)); | 14077 Object* current_key = get(EntryToIndex(current)); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 14082 // The place for the current element is occupied. Leave the element | 14089 // The place for the current element is occupied. Leave the element |
| 14083 // for the next probe. | 14090 // for the next probe. |
| 14084 done = false; | 14091 done = false; |
| 14085 } | 14092 } |
| 14086 } | 14093 } |
| 14087 } | 14094 } |
| 14088 } | 14095 } |
| 14089 } | 14096 } |
| 14090 | 14097 |
| 14091 | 14098 |
| 14092 template<typename Shape, typename Key> | 14099 template<typename Derived, typename Shape, typename Key> |
| 14093 MaybeObject* HashTable<Shape, Key>::EnsureCapacity(int n, | 14100 MaybeObject* HashTable<Derived, Shape, Key>::EnsureCapacity( |
| 14094 Key key, | 14101 int n, |
| 14095 PretenureFlag pretenure) { | 14102 Key key, |
| 14103 PretenureFlag pretenure) { |
| 14096 int capacity = Capacity(); | 14104 int capacity = Capacity(); |
| 14097 int nof = NumberOfElements() + n; | 14105 int nof = NumberOfElements() + n; |
| 14098 int nod = NumberOfDeletedElements(); | 14106 int nod = NumberOfDeletedElements(); |
| 14099 // Return if: | 14107 // Return if: |
| 14100 // 50% is still free after adding n elements and | 14108 // 50% is still free after adding n elements and |
| 14101 // at most 50% of the free elements are deleted elements. | 14109 // at most 50% of the free elements are deleted elements. |
| 14102 if (nod <= (capacity - nof) >> 1) { | 14110 if (nod <= (capacity - nof) >> 1) { |
| 14103 int needed_free = nof >> 1; | 14111 int needed_free = nof >> 1; |
| 14104 if (nof + needed_free <= capacity) return this; | 14112 if (nof + needed_free <= capacity) return this; |
| 14105 } | 14113 } |
| 14106 | 14114 |
| 14107 const int kMinCapacityForPretenure = 256; | 14115 const int kMinCapacityForPretenure = 256; |
| 14108 bool should_pretenure = pretenure == TENURED || | 14116 bool should_pretenure = pretenure == TENURED || |
| 14109 ((capacity > kMinCapacityForPretenure) && !GetHeap()->InNewSpace(this)); | 14117 ((capacity > kMinCapacityForPretenure) && !GetHeap()->InNewSpace(this)); |
| 14110 Object* obj; | 14118 Object* obj; |
| 14111 { MaybeObject* maybe_obj = | 14119 { MaybeObject* maybe_obj = |
| 14112 Allocate(GetHeap(), | 14120 Allocate(GetHeap(), |
| 14113 nof * 2, | 14121 nof * 2, |
| 14114 USE_DEFAULT_MINIMUM_CAPACITY, | 14122 USE_DEFAULT_MINIMUM_CAPACITY, |
| 14115 should_pretenure ? TENURED : NOT_TENURED); | 14123 should_pretenure ? TENURED : NOT_TENURED); |
| 14116 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 14124 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 14117 } | 14125 } |
| 14118 | 14126 |
| 14119 return Rehash(HashTable::cast(obj), key); | 14127 Rehash(Derived::cast(obj), key); |
| 14128 return Derived::cast(obj); |
| 14120 } | 14129 } |
| 14121 | 14130 |
| 14122 | 14131 |
| 14123 template<typename Shape, typename Key> | 14132 template<typename Derived, typename Shape, typename Key> |
| 14124 MaybeObject* HashTable<Shape, Key>::Shrink(Key key) { | 14133 Handle<Derived> HashTable<Derived, Shape, Key>::Shrink(Handle<Derived> table, |
| 14125 int capacity = Capacity(); | 14134 Key key) { |
| 14126 int nof = NumberOfElements(); | 14135 int capacity = table->Capacity(); |
| 14136 int nof = table->NumberOfElements(); |
| 14127 | 14137 |
| 14128 // Shrink to fit the number of elements if only a quarter of the | 14138 // Shrink to fit the number of elements if only a quarter of the |
| 14129 // capacity is filled with elements. | 14139 // capacity is filled with elements. |
| 14130 if (nof > (capacity >> 2)) return this; | 14140 if (nof > (capacity >> 2)) return table; |
| 14131 // Allocate a new dictionary with room for at least the current | 14141 // Allocate a new dictionary with room for at least the current |
| 14132 // number of elements. The allocation method will make sure that | 14142 // number of elements. The allocation method will make sure that |
| 14133 // there is extra room in the dictionary for additions. Don't go | 14143 // there is extra room in the dictionary for additions. Don't go |
| 14134 // lower than room for 16 elements. | 14144 // lower than room for 16 elements. |
| 14135 int at_least_room_for = nof; | 14145 int at_least_room_for = nof; |
| 14136 if (at_least_room_for < 16) return this; | 14146 if (at_least_room_for < 16) return table; |
| 14137 | 14147 |
| 14148 Isolate* isolate = table->GetIsolate(); |
| 14138 const int kMinCapacityForPretenure = 256; | 14149 const int kMinCapacityForPretenure = 256; |
| 14139 bool pretenure = | 14150 bool pretenure = |
| 14140 (at_least_room_for > kMinCapacityForPretenure) && | 14151 (at_least_room_for > kMinCapacityForPretenure) && |
| 14141 !GetHeap()->InNewSpace(this); | 14152 !isolate->heap()->InNewSpace(*table); |
| 14142 Object* obj; | 14153 Handle<Derived> new_table = New( |
| 14143 { MaybeObject* maybe_obj = | 14154 isolate, |
| 14144 Allocate(GetHeap(), | 14155 at_least_room_for, |
| 14145 at_least_room_for, | 14156 USE_DEFAULT_MINIMUM_CAPACITY, |
| 14146 USE_DEFAULT_MINIMUM_CAPACITY, | 14157 pretenure ? TENURED : NOT_TENURED); |
| 14147 pretenure ? TENURED : NOT_TENURED); | |
| 14148 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | |
| 14149 } | |
| 14150 | 14158 |
| 14151 return Rehash(HashTable::cast(obj), key); | 14159 table->Rehash(*new_table, key); |
| 14160 return new_table; |
| 14152 } | 14161 } |
| 14153 | 14162 |
| 14154 | 14163 |
| 14155 template<typename Shape, typename Key> | 14164 template<typename Derived, typename Shape, typename Key> |
| 14156 uint32_t HashTable<Shape, Key>::FindInsertionEntry(uint32_t hash) { | 14165 uint32_t HashTable<Derived, Shape, Key>::FindInsertionEntry(uint32_t hash) { |
| 14157 uint32_t capacity = Capacity(); | 14166 uint32_t capacity = Capacity(); |
| 14158 uint32_t entry = FirstProbe(hash, capacity); | 14167 uint32_t entry = FirstProbe(hash, capacity); |
| 14159 uint32_t count = 1; | 14168 uint32_t count = 1; |
| 14160 // EnsureCapacity will guarantee the hash table is never full. | 14169 // EnsureCapacity will guarantee the hash table is never full. |
| 14161 while (true) { | 14170 while (true) { |
| 14162 Object* element = KeyAt(entry); | 14171 Object* element = KeyAt(entry); |
| 14163 if (element->IsUndefined() || element->IsTheHole()) break; | 14172 if (element->IsUndefined() || element->IsTheHole()) break; |
| 14164 entry = NextProbe(entry, count++, capacity); | 14173 entry = NextProbe(entry, count++, capacity); |
| 14165 } | 14174 } |
| 14166 return entry; | 14175 return entry; |
| 14167 } | 14176 } |
| 14168 | 14177 |
| 14169 | 14178 |
| 14170 // Force instantiation of template instances class. | 14179 // Force instantiation of template instances class. |
| 14171 // Please note this list is compiler dependent. | 14180 // Please note this list is compiler dependent. |
| 14172 | 14181 |
| 14173 template class HashTable<StringTableShape, HashTableKey*>; | 14182 template class HashTable<StringTable, StringTableShape, HashTableKey*>; |
| 14174 | 14183 |
| 14175 template class HashTable<CompilationCacheShape, HashTableKey*>; | 14184 template class HashTable<CompilationCacheTable, |
| 14185 CompilationCacheShape, |
| 14186 HashTableKey*>; |
| 14176 | 14187 |
| 14177 template class HashTable<MapCacheShape, HashTableKey*>; | 14188 template class HashTable<MapCache, MapCacheShape, HashTableKey*>; |
| 14178 | 14189 |
| 14179 template class HashTable<ObjectHashTableShape, Object*>; | 14190 template class HashTable<ObjectHashTable, ObjectHashTableShape, Object*>; |
| 14180 | 14191 |
| 14181 template class HashTable<WeakHashTableShape<2>, Object*>; | 14192 template class HashTable<WeakHashTable, WeakHashTableShape<2>, Object*>; |
| 14182 | 14193 |
| 14183 template class Dictionary<NameDictionaryShape, Name*>; | 14194 template class Dictionary<NameDictionary, NameDictionaryShape, Name*>; |
| 14184 | 14195 |
| 14185 template class Dictionary<SeededNumberDictionaryShape, uint32_t>; | 14196 template class Dictionary<SeededNumberDictionary, |
| 14197 SeededNumberDictionaryShape, |
| 14198 uint32_t>; |
| 14186 | 14199 |
| 14187 template class Dictionary<UnseededNumberDictionaryShape, uint32_t>; | 14200 template class Dictionary<UnseededNumberDictionary, |
| 14201 UnseededNumberDictionaryShape, |
| 14202 uint32_t>; |
| 14188 | 14203 |
| 14189 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>:: | 14204 template MaybeObject* |
| 14205 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
| 14190 Allocate(Heap* heap, int at_least_space_for, PretenureFlag pretenure); | 14206 Allocate(Heap* heap, int at_least_space_for, PretenureFlag pretenure); |
| 14191 | 14207 |
| 14192 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: | 14208 template MaybeObject* |
| 14209 Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>:: |
| 14193 Allocate(Heap* heap, int at_least_space_for, PretenureFlag pretenure); | 14210 Allocate(Heap* heap, int at_least_space_for, PretenureFlag pretenure); |
| 14194 | 14211 |
| 14195 template MaybeObject* Dictionary<NameDictionaryShape, Name*>:: | 14212 template MaybeObject* Dictionary<NameDictionary, NameDictionaryShape, Name*>:: |
| 14196 Allocate(Heap* heap, int n, PretenureFlag pretenure); | 14213 Allocate(Heap* heap, int n, PretenureFlag pretenure); |
| 14197 | 14214 |
| 14198 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::AtPut( | 14215 template MaybeObject* |
| 14199 uint32_t, Object*); | 14216 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
| 14200 | |
| 14201 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: | |
| 14202 AtPut(uint32_t, Object*); | 14217 AtPut(uint32_t, Object*); |
| 14203 | 14218 |
| 14204 template Object* Dictionary<SeededNumberDictionaryShape, uint32_t>:: | 14219 template MaybeObject* |
| 14220 Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>:: |
| 14221 AtPut(uint32_t, Object*); |
| 14222 |
| 14223 template Object* |
| 14224 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
| 14205 SlowReverseLookup(Object* value); | 14225 SlowReverseLookup(Object* value); |
| 14206 | 14226 |
| 14207 template Object* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: | 14227 template Object* |
| 14228 Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>:: |
| 14208 SlowReverseLookup(Object* value); | 14229 SlowReverseLookup(Object* value); |
| 14209 | 14230 |
| 14210 template Object* Dictionary<NameDictionaryShape, Name*>::SlowReverseLookup( | 14231 template Object* |
| 14232 Dictionary<NameDictionary, NameDictionaryShape, Name*>::SlowReverseLookup( |
| 14211 Object*); | 14233 Object*); |
| 14212 | 14234 |
| 14213 template void Dictionary<SeededNumberDictionaryShape, uint32_t>::CopyKeysTo( | 14235 template void |
| 14214 FixedArray*, | 14236 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
| 14215 PropertyAttributes, | 14237 CopyKeysTo( |
| 14216 Dictionary<SeededNumberDictionaryShape, uint32_t>::SortMode); | 14238 FixedArray*, |
| 14239 PropertyAttributes, |
| 14240 Dictionary<SeededNumberDictionary, |
| 14241 SeededNumberDictionaryShape, |
| 14242 uint32_t>::SortMode); |
| 14217 | 14243 |
| 14218 template Object* Dictionary<NameDictionaryShape, Name*>::DeleteProperty( | 14244 template Object* |
| 14245 Dictionary<NameDictionary, NameDictionaryShape, Name*>::DeleteProperty( |
| 14219 int, JSObject::DeleteMode); | 14246 int, JSObject::DeleteMode); |
| 14220 | 14247 |
| 14221 template Handle<Object> Dictionary<NameDictionaryShape, Name*>::DeleteProperty( | 14248 template Handle<Object> |
| 14222 Handle<Dictionary<NameDictionaryShape, Name*> >, | 14249 Dictionary<NameDictionary, NameDictionaryShape, Name*>::DeleteProperty( |
| 14250 Handle<Dictionary<NameDictionary, NameDictionaryShape, Name*> >, |
| 14223 int, | 14251 int, |
| 14224 JSObject::DeleteMode); | 14252 JSObject::DeleteMode); |
| 14225 | 14253 |
| 14226 template Object* Dictionary<SeededNumberDictionaryShape, uint32_t>:: | 14254 template Object* |
| 14255 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
| 14227 DeleteProperty(int, JSObject::DeleteMode); | 14256 DeleteProperty(int, JSObject::DeleteMode); |
| 14228 | 14257 |
| 14229 template Handle<Object> | 14258 template Handle<Object> |
| 14230 Dictionary<SeededNumberDictionaryShape, uint32_t>::DeleteProperty( | 14259 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
| 14231 Handle<Dictionary<SeededNumberDictionaryShape, uint32_t> >, | 14260 DeleteProperty( |
| 14232 int, | 14261 Handle<Dictionary<SeededNumberDictionary, |
| 14233 JSObject::DeleteMode); | 14262 SeededNumberDictionaryShape, |
| 14263 uint32_t> >, |
| 14264 int, |
| 14265 JSObject::DeleteMode); |
| 14234 | 14266 |
| 14235 template MaybeObject* Dictionary<NameDictionaryShape, Name*>::Shrink(Name* n); | 14267 template Handle<NameDictionary> |
| 14268 HashTable<NameDictionary, NameDictionaryShape, Name*>:: |
| 14269 Shrink(Handle<NameDictionary>, Name* n); |
| 14236 | 14270 |
| 14237 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::Shrink( | 14271 template Handle<SeededNumberDictionary> |
| 14238 uint32_t); | 14272 HashTable<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
| 14239 template Handle<FixedArray> | 14273 Shrink(Handle<SeededNumberDictionary>, uint32_t); |
| 14240 Dictionary<SeededNumberDictionaryShape, uint32_t>::Shrink( | |
| 14241 Handle<Dictionary<SeededNumberDictionaryShape, uint32_t> >, | |
| 14242 uint32_t); | |
| 14243 | 14274 |
| 14244 template void Dictionary<NameDictionaryShape, Name*>::CopyKeysTo( | 14275 template void Dictionary<NameDictionary, NameDictionaryShape, Name*>:: |
| 14245 FixedArray*, | 14276 CopyKeysTo( |
| 14246 int, | 14277 FixedArray*, |
| 14247 PropertyAttributes, | 14278 int, |
| 14248 Dictionary<NameDictionaryShape, Name*>::SortMode); | 14279 PropertyAttributes, |
| 14280 Dictionary<NameDictionary, NameDictionaryShape, Name*>::SortMode); |
| 14249 | 14281 |
| 14250 template int | 14282 template int |
| 14251 Dictionary<NameDictionaryShape, Name*>::NumberOfElementsFilterAttributes( | 14283 Dictionary<NameDictionary, NameDictionaryShape, Name*>:: |
| 14252 PropertyAttributes); | 14284 NumberOfElementsFilterAttributes(PropertyAttributes); |
| 14253 | 14285 |
| 14254 template MaybeObject* Dictionary<NameDictionaryShape, Name*>::Add( | 14286 template MaybeObject* |
| 14287 Dictionary<NameDictionary, NameDictionaryShape, Name*>::Add( |
| 14255 Name*, Object*, PropertyDetails); | 14288 Name*, Object*, PropertyDetails); |
| 14256 | 14289 |
| 14257 template MaybeObject* | 14290 template MaybeObject* |
| 14258 Dictionary<NameDictionaryShape, Name*>::GenerateNewEnumerationIndices(); | 14291 Dictionary<NameDictionary, NameDictionaryShape, Name*>:: |
| 14292 GenerateNewEnumerationIndices(); |
| 14259 | 14293 |
| 14260 template int | 14294 template int |
| 14261 Dictionary<SeededNumberDictionaryShape, uint32_t>:: | 14295 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
| 14262 NumberOfElementsFilterAttributes(PropertyAttributes); | 14296 NumberOfElementsFilterAttributes(PropertyAttributes); |
| 14263 | 14297 |
| 14264 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::Add( | 14298 template MaybeObject* |
| 14299 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::Add( |
| 14265 uint32_t, Object*, PropertyDetails); | 14300 uint32_t, Object*, PropertyDetails); |
| 14266 | 14301 |
| 14267 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>::Add( | 14302 template MaybeObject* |
| 14268 uint32_t, Object*, PropertyDetails); | 14303 Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>:: |
| 14304 Add(uint32_t, Object*, PropertyDetails); |
| 14269 | 14305 |
| 14270 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>:: | 14306 template MaybeObject* |
| 14307 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
| 14271 EnsureCapacity(int, uint32_t); | 14308 EnsureCapacity(int, uint32_t); |
| 14272 | 14309 |
| 14273 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: | 14310 template MaybeObject* |
| 14311 Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>:: |
| 14274 EnsureCapacity(int, uint32_t); | 14312 EnsureCapacity(int, uint32_t); |
| 14275 | 14313 |
| 14276 template MaybeObject* Dictionary<NameDictionaryShape, Name*>:: | 14314 template MaybeObject* |
| 14315 Dictionary<NameDictionary, NameDictionaryShape, Name*>:: |
| 14277 EnsureCapacity(int, Name*); | 14316 EnsureCapacity(int, Name*); |
| 14278 | 14317 |
| 14279 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>:: | 14318 template MaybeObject* |
| 14319 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
| 14280 AddEntry(uint32_t, Object*, PropertyDetails, uint32_t); | 14320 AddEntry(uint32_t, Object*, PropertyDetails, uint32_t); |
| 14281 | 14321 |
| 14282 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: | 14322 template MaybeObject* |
| 14323 Dictionary<UnseededNumberDictionary, UnseededNumberDictionaryShape, uint32_t>:: |
| 14283 AddEntry(uint32_t, Object*, PropertyDetails, uint32_t); | 14324 AddEntry(uint32_t, Object*, PropertyDetails, uint32_t); |
| 14284 | 14325 |
| 14285 template MaybeObject* Dictionary<NameDictionaryShape, Name*>::AddEntry( | 14326 template MaybeObject* |
| 14327 Dictionary<NameDictionary, NameDictionaryShape, Name*>::AddEntry( |
| 14286 Name*, Object*, PropertyDetails, uint32_t); | 14328 Name*, Object*, PropertyDetails, uint32_t); |
| 14287 | 14329 |
| 14288 template | 14330 template |
| 14289 int Dictionary<SeededNumberDictionaryShape, uint32_t>::NumberOfEnumElements(); | 14331 int Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
| 14332 NumberOfEnumElements(); |
| 14290 | 14333 |
| 14291 template | 14334 template |
| 14292 int Dictionary<NameDictionaryShape, Name*>::NumberOfEnumElements(); | 14335 int Dictionary<NameDictionary, NameDictionaryShape, Name*>:: |
| 14336 NumberOfEnumElements(); |
| 14293 | 14337 |
| 14294 template | 14338 template |
| 14295 int HashTable<SeededNumberDictionaryShape, uint32_t>::FindEntry(uint32_t); | 14339 int HashTable<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
| 14340 FindEntry(uint32_t); |
| 14296 | 14341 |
| 14297 | 14342 |
| 14298 Handle<Object> JSObject::PrepareSlowElementsForSort( | 14343 Handle<Object> JSObject::PrepareSlowElementsForSort( |
| 14299 Handle<JSObject> object, uint32_t limit) { | 14344 Handle<JSObject> object, uint32_t limit) { |
| 14300 CALL_HEAP_FUNCTION(object->GetIsolate(), | 14345 CALL_HEAP_FUNCTION(object->GetIsolate(), |
| 14301 object->PrepareSlowElementsForSort(limit), | 14346 object->PrepareSlowElementsForSort(limit), |
| 14302 Object); | 14347 Object); |
| 14303 } | 14348 } |
| 14304 | 14349 |
| 14305 | 14350 |
| (...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14902 } | 14947 } |
| 14903 | 14948 |
| 14904 private: | 14949 private: |
| 14905 uint16_t c1_; | 14950 uint16_t c1_; |
| 14906 uint16_t c2_; | 14951 uint16_t c2_; |
| 14907 uint32_t hash_; | 14952 uint32_t hash_; |
| 14908 }; | 14953 }; |
| 14909 | 14954 |
| 14910 | 14955 |
| 14911 bool StringTable::LookupStringIfExists(String* string, String** result) { | 14956 bool StringTable::LookupStringIfExists(String* string, String** result) { |
| 14957 SLOW_ASSERT(this == HeapObject::cast(this)->GetHeap()->string_table()); |
| 14912 InternalizedStringKey key(string); | 14958 InternalizedStringKey key(string); |
| 14913 int entry = FindEntry(&key); | 14959 int entry = FindEntry(&key); |
| 14914 if (entry == kNotFound) { | 14960 if (entry == kNotFound) { |
| 14915 return false; | 14961 return false; |
| 14916 } else { | 14962 } else { |
| 14917 *result = String::cast(KeyAt(entry)); | 14963 *result = String::cast(KeyAt(entry)); |
| 14918 ASSERT(StringShape(*result).IsInternalized()); | 14964 ASSERT(StringShape(*result).IsInternalized()); |
| 14919 return true; | 14965 return true; |
| 14920 } | 14966 } |
| 14921 } | 14967 } |
| 14922 | 14968 |
| 14923 | 14969 |
| 14924 bool StringTable::LookupTwoCharsStringIfExists(uint16_t c1, | 14970 bool StringTable::LookupTwoCharsStringIfExists(uint16_t c1, |
| 14925 uint16_t c2, | 14971 uint16_t c2, |
| 14926 String** result) { | 14972 String** result) { |
| 14973 SLOW_ASSERT(this == HeapObject::cast(this)->GetHeap()->string_table()); |
| 14927 TwoCharHashTableKey key(c1, c2, GetHeap()->HashSeed()); | 14974 TwoCharHashTableKey key(c1, c2, GetHeap()->HashSeed()); |
| 14928 int entry = FindEntry(&key); | 14975 int entry = FindEntry(&key); |
| 14929 if (entry == kNotFound) { | 14976 if (entry == kNotFound) { |
| 14930 return false; | 14977 return false; |
| 14931 } else { | 14978 } else { |
| 14932 *result = String::cast(KeyAt(entry)); | 14979 *result = String::cast(KeyAt(entry)); |
| 14933 ASSERT(StringShape(*result).IsInternalized()); | 14980 ASSERT(StringShape(*result).IsInternalized()); |
| 14934 return true; | 14981 return true; |
| 14935 } | 14982 } |
| 14936 } | 14983 } |
| 14937 | 14984 |
| 14938 | 14985 |
| 14939 MaybeObject* StringTable::LookupKey(HashTableKey* key, Object** s) { | 14986 MaybeObject* StringTable::LookupKey(HashTableKey* key, Object** s) { |
| 14987 SLOW_ASSERT(this == HeapObject::cast(this)->GetHeap()->string_table()); |
| 14940 int entry = FindEntry(key); | 14988 int entry = FindEntry(key); |
| 14941 | 14989 |
| 14942 // String already in table. | 14990 // String already in table. |
| 14943 if (entry != kNotFound) { | 14991 if (entry != kNotFound) { |
| 14944 *s = KeyAt(entry); | 14992 *s = KeyAt(entry); |
| 14945 return this; | 14993 return this; |
| 14946 } | 14994 } |
| 14947 | 14995 |
| 14948 // Adding new string. Grow table if needed. | 14996 // Adding new string. Grow table if needed. |
| 14949 Object* obj; | 14997 Object* obj; |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15131 | 15179 |
| 15132 MapCache* cache = reinterpret_cast<MapCache*>(obj); | 15180 MapCache* cache = reinterpret_cast<MapCache*>(obj); |
| 15133 int entry = cache->FindInsertionEntry(key.Hash()); | 15181 int entry = cache->FindInsertionEntry(key.Hash()); |
| 15134 cache->set(EntryToIndex(entry), array); | 15182 cache->set(EntryToIndex(entry), array); |
| 15135 cache->set(EntryToIndex(entry) + 1, value); | 15183 cache->set(EntryToIndex(entry) + 1, value); |
| 15136 cache->ElementAdded(); | 15184 cache->ElementAdded(); |
| 15137 return cache; | 15185 return cache; |
| 15138 } | 15186 } |
| 15139 | 15187 |
| 15140 | 15188 |
| 15141 template<typename Shape, typename Key> | 15189 template<typename Derived, typename Shape, typename Key> |
| 15142 MaybeObject* Dictionary<Shape, Key>::Allocate(Heap* heap, | 15190 MaybeObject* Dictionary<Derived, Shape, Key>::Allocate( |
| 15143 int at_least_space_for, | 15191 Heap* heap, |
| 15144 PretenureFlag pretenure) { | 15192 int at_least_space_for, |
| 15193 PretenureFlag pretenure) { |
| 15145 Object* obj; | 15194 Object* obj; |
| 15146 { MaybeObject* maybe_obj = | 15195 { MaybeObject* maybe_obj = |
| 15147 HashTable<Shape, Key>::Allocate( | 15196 DerivedHashTable::Allocate( |
| 15148 heap, | 15197 heap, |
| 15149 at_least_space_for, | 15198 at_least_space_for, |
| 15150 USE_DEFAULT_MINIMUM_CAPACITY, | 15199 USE_DEFAULT_MINIMUM_CAPACITY, |
| 15151 pretenure); | 15200 pretenure); |
| 15152 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 15201 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 15153 } | 15202 } |
| 15154 // Initialize the next enumeration index. | 15203 // Initialize the next enumeration index. |
| 15155 Dictionary<Shape, Key>::cast(obj)-> | 15204 Dictionary::cast(obj)-> |
| 15156 SetNextEnumerationIndex(PropertyDetails::kInitialIndex); | 15205 SetNextEnumerationIndex(PropertyDetails::kInitialIndex); |
| 15157 return obj; | 15206 return obj; |
| 15158 } | 15207 } |
| 15159 | 15208 |
| 15160 | 15209 |
| 15161 void NameDictionary::DoGenerateNewEnumerationIndices( | 15210 void NameDictionary::DoGenerateNewEnumerationIndices( |
| 15162 Handle<NameDictionary> dictionary) { | 15211 Handle<NameDictionary> dictionary) { |
| 15163 CALL_HEAP_FUNCTION_VOID(dictionary->GetIsolate(), | 15212 CALL_HEAP_FUNCTION_VOID(dictionary->GetIsolate(), |
| 15164 dictionary->GenerateNewEnumerationIndices()); | 15213 dictionary->GenerateNewEnumerationIndices()); |
| 15165 } | 15214 } |
| 15166 | 15215 |
| 15167 template<typename Shape, typename Key> | 15216 template<typename Derived, typename Shape, typename Key> |
| 15168 MaybeObject* Dictionary<Shape, Key>::GenerateNewEnumerationIndices() { | 15217 MaybeObject* Dictionary<Derived, Shape, Key>::GenerateNewEnumerationIndices() { |
| 15169 Heap* heap = Dictionary<Shape, Key>::GetHeap(); | 15218 Heap* heap = Dictionary::GetHeap(); |
| 15170 int length = HashTable<Shape, Key>::NumberOfElements(); | 15219 int length = DerivedHashTable::NumberOfElements(); |
| 15171 | 15220 |
| 15172 // Allocate and initialize iteration order array. | 15221 // Allocate and initialize iteration order array. |
| 15173 Object* obj; | 15222 Object* obj; |
| 15174 { MaybeObject* maybe_obj = heap->AllocateFixedArray(length); | 15223 { MaybeObject* maybe_obj = heap->AllocateFixedArray(length); |
| 15175 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 15224 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 15176 } | 15225 } |
| 15177 FixedArray* iteration_order = FixedArray::cast(obj); | 15226 FixedArray* iteration_order = FixedArray::cast(obj); |
| 15178 for (int i = 0; i < length; i++) { | 15227 for (int i = 0; i < length; i++) { |
| 15179 iteration_order->set(i, Smi::FromInt(i)); | 15228 iteration_order->set(i, Smi::FromInt(i)); |
| 15180 } | 15229 } |
| 15181 | 15230 |
| 15182 // Allocate array with enumeration order. | 15231 // Allocate array with enumeration order. |
| 15183 { MaybeObject* maybe_obj = heap->AllocateFixedArray(length); | 15232 { MaybeObject* maybe_obj = heap->AllocateFixedArray(length); |
| 15184 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 15233 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 15185 } | 15234 } |
| 15186 FixedArray* enumeration_order = FixedArray::cast(obj); | 15235 FixedArray* enumeration_order = FixedArray::cast(obj); |
| 15187 | 15236 |
| 15188 // Fill the enumeration order array with property details. | 15237 // Fill the enumeration order array with property details. |
| 15189 int capacity = HashTable<Shape, Key>::Capacity(); | 15238 int capacity = DerivedHashTable::Capacity(); |
| 15190 int pos = 0; | 15239 int pos = 0; |
| 15191 for (int i = 0; i < capacity; i++) { | 15240 for (int i = 0; i < capacity; i++) { |
| 15192 if (Dictionary<Shape, Key>::IsKey(Dictionary<Shape, Key>::KeyAt(i))) { | 15241 if (Dictionary::IsKey(Dictionary::KeyAt(i))) { |
| 15193 int index = DetailsAt(i).dictionary_index(); | 15242 int index = DetailsAt(i).dictionary_index(); |
| 15194 enumeration_order->set(pos++, Smi::FromInt(index)); | 15243 enumeration_order->set(pos++, Smi::FromInt(index)); |
| 15195 } | 15244 } |
| 15196 } | 15245 } |
| 15197 | 15246 |
| 15198 // Sort the arrays wrt. enumeration order. | 15247 // Sort the arrays wrt. enumeration order. |
| 15199 iteration_order->SortPairs(enumeration_order, enumeration_order->length()); | 15248 iteration_order->SortPairs(enumeration_order, enumeration_order->length()); |
| 15200 | 15249 |
| 15201 // Overwrite the enumeration_order with the enumeration indices. | 15250 // Overwrite the enumeration_order with the enumeration indices. |
| 15202 for (int i = 0; i < length; i++) { | 15251 for (int i = 0; i < length; i++) { |
| 15203 int index = Smi::cast(iteration_order->get(i))->value(); | 15252 int index = Smi::cast(iteration_order->get(i))->value(); |
| 15204 int enum_index = PropertyDetails::kInitialIndex + i; | 15253 int enum_index = PropertyDetails::kInitialIndex + i; |
| 15205 enumeration_order->set(index, Smi::FromInt(enum_index)); | 15254 enumeration_order->set(index, Smi::FromInt(enum_index)); |
| 15206 } | 15255 } |
| 15207 | 15256 |
| 15208 // Update the dictionary with new indices. | 15257 // Update the dictionary with new indices. |
| 15209 capacity = HashTable<Shape, Key>::Capacity(); | 15258 capacity = DerivedHashTable::Capacity(); |
| 15210 pos = 0; | 15259 pos = 0; |
| 15211 for (int i = 0; i < capacity; i++) { | 15260 for (int i = 0; i < capacity; i++) { |
| 15212 if (Dictionary<Shape, Key>::IsKey(Dictionary<Shape, Key>::KeyAt(i))) { | 15261 if (Dictionary::IsKey(Dictionary::KeyAt(i))) { |
| 15213 int enum_index = Smi::cast(enumeration_order->get(pos++))->value(); | 15262 int enum_index = Smi::cast(enumeration_order->get(pos++))->value(); |
| 15214 PropertyDetails details = DetailsAt(i); | 15263 PropertyDetails details = DetailsAt(i); |
| 15215 PropertyDetails new_details = PropertyDetails( | 15264 PropertyDetails new_details = PropertyDetails( |
| 15216 details.attributes(), details.type(), enum_index); | 15265 details.attributes(), details.type(), enum_index); |
| 15217 DetailsAtPut(i, new_details); | 15266 DetailsAtPut(i, new_details); |
| 15218 } | 15267 } |
| 15219 } | 15268 } |
| 15220 | 15269 |
| 15221 // Set the next enumeration index. | 15270 // Set the next enumeration index. |
| 15222 SetNextEnumerationIndex(PropertyDetails::kInitialIndex+length); | 15271 SetNextEnumerationIndex(PropertyDetails::kInitialIndex+length); |
| 15223 return this; | 15272 return this; |
| 15224 } | 15273 } |
| 15225 | 15274 |
| 15226 template<typename Shape, typename Key> | 15275 template<typename Derived, typename Shape, typename Key> |
| 15227 MaybeObject* Dictionary<Shape, Key>::EnsureCapacity(int n, Key key) { | 15276 MaybeObject* Dictionary<Derived, Shape, Key>::EnsureCapacity(int n, Key key) { |
| 15228 // Check whether there are enough enumeration indices to add n elements. | 15277 // Check whether there are enough enumeration indices to add n elements. |
| 15229 if (Shape::kIsEnumerable && | 15278 if (Shape::kIsEnumerable && |
| 15230 !PropertyDetails::IsValidIndex(NextEnumerationIndex() + n)) { | 15279 !PropertyDetails::IsValidIndex(NextEnumerationIndex() + n)) { |
| 15231 // If not, we generate new indices for the properties. | 15280 // If not, we generate new indices for the properties. |
| 15232 Object* result; | 15281 Object* result; |
| 15233 { MaybeObject* maybe_result = GenerateNewEnumerationIndices(); | 15282 { MaybeObject* maybe_result = GenerateNewEnumerationIndices(); |
| 15234 if (!maybe_result->ToObject(&result)) return maybe_result; | 15283 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 15235 } | 15284 } |
| 15236 } | 15285 } |
| 15237 return HashTable<Shape, Key>::EnsureCapacity(n, key); | 15286 return DerivedHashTable::EnsureCapacity(n, key); |
| 15238 } | 15287 } |
| 15239 | 15288 |
| 15240 | 15289 |
| 15241 // TODO(ishell): Temporary wrapper until handlified. | 15290 // TODO(ishell): Temporary wrapper until handlified. |
| 15242 template<typename Shape, typename Key> | 15291 template<typename Derived, typename Shape, typename Key> |
| 15243 Handle<Object> Dictionary<Shape, Key>::DeleteProperty( | 15292 Handle<Object> Dictionary<Derived, Shape, Key>::DeleteProperty( |
| 15244 Handle<Dictionary<Shape, Key> > dictionary, | 15293 Handle<Dictionary<Derived, Shape, Key> > dictionary, |
| 15245 int entry, | 15294 int entry, |
| 15246 JSObject::DeleteMode mode) { | 15295 JSObject::DeleteMode mode) { |
| 15247 CALL_HEAP_FUNCTION(dictionary->GetIsolate(), | 15296 CALL_HEAP_FUNCTION(dictionary->GetIsolate(), |
| 15248 dictionary->DeleteProperty(entry, mode), | 15297 dictionary->DeleteProperty(entry, mode), |
| 15249 Object); | 15298 Object); |
| 15250 } | 15299 } |
| 15251 | 15300 |
| 15252 | 15301 |
| 15253 template<typename Shape, typename Key> | 15302 template<typename Derived, typename Shape, typename Key> |
| 15254 Object* Dictionary<Shape, Key>::DeleteProperty(int entry, | 15303 Object* Dictionary<Derived, Shape, Key>::DeleteProperty( |
| 15255 JSReceiver::DeleteMode mode) { | 15304 int entry, |
| 15256 Heap* heap = Dictionary<Shape, Key>::GetHeap(); | 15305 JSReceiver::DeleteMode mode) { |
| 15306 Heap* heap = Dictionary::GetHeap(); |
| 15257 PropertyDetails details = DetailsAt(entry); | 15307 PropertyDetails details = DetailsAt(entry); |
| 15258 // Ignore attributes if forcing a deletion. | 15308 // Ignore attributes if forcing a deletion. |
| 15259 if (details.IsDontDelete() && mode != JSReceiver::FORCE_DELETION) { | 15309 if (details.IsDontDelete() && mode != JSReceiver::FORCE_DELETION) { |
| 15260 return heap->false_value(); | 15310 return heap->false_value(); |
| 15261 } | 15311 } |
| 15262 SetEntry(entry, heap->the_hole_value(), heap->the_hole_value()); | 15312 SetEntry(entry, heap->the_hole_value(), heap->the_hole_value()); |
| 15263 HashTable<Shape, Key>::ElementRemoved(); | 15313 DerivedHashTable::ElementRemoved(); |
| 15264 return heap->true_value(); | 15314 return heap->true_value(); |
| 15265 } | 15315 } |
| 15266 | 15316 |
| 15267 | 15317 |
| 15268 // TODO(ishell): Temporary wrapper until handlified. | 15318 template<typename Derived, typename Shape, typename Key> |
| 15269 template<typename Shape, typename Key> | 15319 MaybeObject* Dictionary<Derived, Shape, Key>::AtPut(Key key, Object* value) { |
| 15270 Handle<FixedArray> Dictionary<Shape, Key>::Shrink( | |
| 15271 Handle<Dictionary<Shape, Key> > dictionary, | |
| 15272 Key key) { | |
| 15273 CALL_HEAP_FUNCTION(dictionary->GetIsolate(), | |
| 15274 dictionary->Shrink(key), | |
| 15275 FixedArray); | |
| 15276 } | |
| 15277 | |
| 15278 | |
| 15279 template<typename Shape, typename Key> | |
| 15280 MaybeObject* Dictionary<Shape, Key>::Shrink(Key key) { | |
| 15281 return HashTable<Shape, Key>::Shrink(key); | |
| 15282 } | |
| 15283 | |
| 15284 | |
| 15285 template<typename Shape, typename Key> | |
| 15286 MaybeObject* Dictionary<Shape, Key>::AtPut(Key key, Object* value) { | |
| 15287 int entry = this->FindEntry(key); | 15320 int entry = this->FindEntry(key); |
| 15288 | 15321 |
| 15289 // If the entry is present set the value; | 15322 // If the entry is present set the value; |
| 15290 if (entry != Dictionary<Shape, Key>::kNotFound) { | 15323 if (entry != Dictionary::kNotFound) { |
| 15291 ValueAtPut(entry, value); | 15324 ValueAtPut(entry, value); |
| 15292 return this; | 15325 return this; |
| 15293 } | 15326 } |
| 15294 | 15327 |
| 15295 // Check whether the dictionary should be extended. | 15328 // Check whether the dictionary should be extended. |
| 15296 Object* obj; | 15329 Object* obj; |
| 15297 { MaybeObject* maybe_obj = EnsureCapacity(1, key); | 15330 { MaybeObject* maybe_obj = EnsureCapacity(1, key); |
| 15298 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 15331 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 15299 } | 15332 } |
| 15300 | 15333 |
| 15301 Object* k; | 15334 Object* k; |
| 15302 { MaybeObject* maybe_k = Shape::AsObject(this->GetHeap(), key); | 15335 { MaybeObject* maybe_k = Shape::AsObject(this->GetHeap(), key); |
| 15303 if (!maybe_k->ToObject(&k)) return maybe_k; | 15336 if (!maybe_k->ToObject(&k)) return maybe_k; |
| 15304 } | 15337 } |
| 15305 PropertyDetails details = PropertyDetails(NONE, NORMAL, 0); | 15338 PropertyDetails details = PropertyDetails(NONE, NORMAL, 0); |
| 15306 | 15339 |
| 15307 return Dictionary<Shape, Key>::cast(obj)->AddEntry(key, value, details, | 15340 return Dictionary::cast(obj)->AddEntry( |
| 15308 Dictionary<Shape, Key>::Hash(key)); | 15341 key, value, details, Dictionary::Hash(key)); |
| 15309 } | 15342 } |
| 15310 | 15343 |
| 15311 | 15344 |
| 15312 template<typename Shape, typename Key> | 15345 template<typename Derived, typename Shape, typename Key> |
| 15313 MaybeObject* Dictionary<Shape, Key>::Add(Key key, | 15346 MaybeObject* Dictionary<Derived, Shape, Key>::Add( |
| 15314 Object* value, | 15347 Key key, |
| 15315 PropertyDetails details) { | 15348 Object* value, |
| 15349 PropertyDetails details) { |
| 15316 // Valdate key is absent. | 15350 // Valdate key is absent. |
| 15317 SLOW_ASSERT((this->FindEntry(key) == Dictionary<Shape, Key>::kNotFound)); | 15351 SLOW_ASSERT((this->FindEntry(key) == Dictionary::kNotFound)); |
| 15318 // Check whether the dictionary should be extended. | 15352 // Check whether the dictionary should be extended. |
| 15319 Object* obj; | 15353 Object* obj; |
| 15320 { MaybeObject* maybe_obj = EnsureCapacity(1, key); | 15354 { MaybeObject* maybe_obj = EnsureCapacity(1, key); |
| 15321 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 15355 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 15322 } | 15356 } |
| 15323 | 15357 |
| 15324 return Dictionary<Shape, Key>::cast(obj)->AddEntry(key, value, details, | 15358 return Dictionary::cast(obj)->AddEntry( |
| 15325 Dictionary<Shape, Key>::Hash(key)); | 15359 key, value, details, Dictionary::Hash(key)); |
| 15326 } | 15360 } |
| 15327 | 15361 |
| 15328 | 15362 |
| 15329 // Add a key, value pair to the dictionary. | 15363 // Add a key, value pair to the dictionary. |
| 15330 template<typename Shape, typename Key> | 15364 template<typename Derived, typename Shape, typename Key> |
| 15331 MaybeObject* Dictionary<Shape, Key>::AddEntry(Key key, | 15365 MaybeObject* Dictionary<Derived, Shape, Key>::AddEntry( |
| 15332 Object* value, | 15366 Key key, |
| 15333 PropertyDetails details, | 15367 Object* value, |
| 15334 uint32_t hash) { | 15368 PropertyDetails details, |
| 15369 uint32_t hash) { |
| 15335 // Compute the key object. | 15370 // Compute the key object. |
| 15336 Object* k; | 15371 Object* k; |
| 15337 { MaybeObject* maybe_k = Shape::AsObject(this->GetHeap(), key); | 15372 { MaybeObject* maybe_k = Shape::AsObject(this->GetHeap(), key); |
| 15338 if (!maybe_k->ToObject(&k)) return maybe_k; | 15373 if (!maybe_k->ToObject(&k)) return maybe_k; |
| 15339 } | 15374 } |
| 15340 | 15375 |
| 15341 uint32_t entry = Dictionary<Shape, Key>::FindInsertionEntry(hash); | 15376 uint32_t entry = Dictionary::FindInsertionEntry(hash); |
| 15342 // Insert element at empty or deleted entry | 15377 // Insert element at empty or deleted entry |
| 15343 if (!details.IsDeleted() && | 15378 if (!details.IsDeleted() && |
| 15344 details.dictionary_index() == 0 && | 15379 details.dictionary_index() == 0 && |
| 15345 Shape::kIsEnumerable) { | 15380 Shape::kIsEnumerable) { |
| 15346 // Assign an enumeration index to the property and update | 15381 // Assign an enumeration index to the property and update |
| 15347 // SetNextEnumerationIndex. | 15382 // SetNextEnumerationIndex. |
| 15348 int index = NextEnumerationIndex(); | 15383 int index = NextEnumerationIndex(); |
| 15349 details = PropertyDetails(details.attributes(), details.type(), index); | 15384 details = PropertyDetails(details.attributes(), details.type(), index); |
| 15350 SetNextEnumerationIndex(index + 1); | 15385 SetNextEnumerationIndex(index + 1); |
| 15351 } | 15386 } |
| 15352 SetEntry(entry, k, value, details); | 15387 SetEntry(entry, k, value, details); |
| 15353 ASSERT((Dictionary<Shape, Key>::KeyAt(entry)->IsNumber() || | 15388 ASSERT((Dictionary::KeyAt(entry)->IsNumber() || |
| 15354 Dictionary<Shape, Key>::KeyAt(entry)->IsName())); | 15389 Dictionary::KeyAt(entry)->IsName())); |
| 15355 HashTable<Shape, Key>::ElementAdded(); | 15390 DerivedHashTable::ElementAdded(); |
| 15356 return this; | 15391 return this; |
| 15357 } | 15392 } |
| 15358 | 15393 |
| 15359 | 15394 |
| 15360 void SeededNumberDictionary::UpdateMaxNumberKey(uint32_t key) { | 15395 void SeededNumberDictionary::UpdateMaxNumberKey(uint32_t key) { |
| 15361 // If the dictionary requires slow elements an element has already | 15396 // If the dictionary requires slow elements an element has already |
| 15362 // been added at a high index. | 15397 // been added at a high index. |
| 15363 if (requires_slow_elements()) return; | 15398 if (requires_slow_elements()) return; |
| 15364 // Check if this index is high enough that we should require slow | 15399 // Check if this index is high enough that we should require slow |
| 15365 // elements. | 15400 // elements. |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15459 MaybeObject* maybe_object_key = | 15494 MaybeObject* maybe_object_key = |
| 15460 UnseededNumberDictionaryShape::AsObject(GetHeap(), key); | 15495 UnseededNumberDictionaryShape::AsObject(GetHeap(), key); |
| 15461 Object* object_key; | 15496 Object* object_key; |
| 15462 if (!maybe_object_key->ToObject(&object_key)) return maybe_object_key; | 15497 if (!maybe_object_key->ToObject(&object_key)) return maybe_object_key; |
| 15463 SetEntry(entry, object_key, value); | 15498 SetEntry(entry, object_key, value); |
| 15464 return this; | 15499 return this; |
| 15465 } | 15500 } |
| 15466 | 15501 |
| 15467 | 15502 |
| 15468 | 15503 |
| 15469 template<typename Shape, typename Key> | 15504 template<typename Derived, typename Shape, typename Key> |
| 15470 int Dictionary<Shape, Key>::NumberOfElementsFilterAttributes( | 15505 int Dictionary<Derived, Shape, Key>::NumberOfElementsFilterAttributes( |
| 15471 PropertyAttributes filter) { | 15506 PropertyAttributes filter) { |
| 15472 int capacity = HashTable<Shape, Key>::Capacity(); | 15507 int capacity = DerivedHashTable::Capacity(); |
| 15473 int result = 0; | 15508 int result = 0; |
| 15474 for (int i = 0; i < capacity; i++) { | 15509 for (int i = 0; i < capacity; i++) { |
| 15475 Object* k = HashTable<Shape, Key>::KeyAt(i); | 15510 Object* k = DerivedHashTable::KeyAt(i); |
| 15476 if (HashTable<Shape, Key>::IsKey(k) && !FilterKey(k, filter)) { | 15511 if (DerivedHashTable::IsKey(k) && !FilterKey(k, filter)) { |
| 15477 PropertyDetails details = DetailsAt(i); | 15512 PropertyDetails details = DetailsAt(i); |
| 15478 if (details.IsDeleted()) continue; | 15513 if (details.IsDeleted()) continue; |
| 15479 PropertyAttributes attr = details.attributes(); | 15514 PropertyAttributes attr = details.attributes(); |
| 15480 if ((attr & filter) == 0) result++; | 15515 if ((attr & filter) == 0) result++; |
| 15481 } | 15516 } |
| 15482 } | 15517 } |
| 15483 return result; | 15518 return result; |
| 15484 } | 15519 } |
| 15485 | 15520 |
| 15486 | 15521 |
| 15487 template<typename Shape, typename Key> | 15522 template<typename Derived, typename Shape, typename Key> |
| 15488 int Dictionary<Shape, Key>::NumberOfEnumElements() { | 15523 int Dictionary<Derived, Shape, Key>::NumberOfEnumElements() { |
| 15489 return NumberOfElementsFilterAttributes( | 15524 return NumberOfElementsFilterAttributes( |
| 15490 static_cast<PropertyAttributes>(DONT_ENUM | SYMBOLIC)); | 15525 static_cast<PropertyAttributes>(DONT_ENUM | SYMBOLIC)); |
| 15491 } | 15526 } |
| 15492 | 15527 |
| 15493 | 15528 |
| 15494 template<typename Shape, typename Key> | 15529 template<typename Derived, typename Shape, typename Key> |
| 15495 void Dictionary<Shape, Key>::CopyKeysTo( | 15530 void Dictionary<Derived, Shape, Key>::CopyKeysTo( |
| 15496 FixedArray* storage, | 15531 FixedArray* storage, |
| 15497 PropertyAttributes filter, | 15532 PropertyAttributes filter, |
| 15498 typename Dictionary<Shape, Key>::SortMode sort_mode) { | 15533 typename Dictionary<Derived, Shape, Key>::SortMode sort_mode) { |
| 15499 ASSERT(storage->length() >= NumberOfElementsFilterAttributes(filter)); | 15534 ASSERT(storage->length() >= NumberOfElementsFilterAttributes(filter)); |
| 15500 int capacity = HashTable<Shape, Key>::Capacity(); | 15535 int capacity = DerivedHashTable::Capacity(); |
| 15501 int index = 0; | 15536 int index = 0; |
| 15502 for (int i = 0; i < capacity; i++) { | 15537 for (int i = 0; i < capacity; i++) { |
| 15503 Object* k = HashTable<Shape, Key>::KeyAt(i); | 15538 Object* k = DerivedHashTable::KeyAt(i); |
| 15504 if (HashTable<Shape, Key>::IsKey(k) && !FilterKey(k, filter)) { | 15539 if (DerivedHashTable::IsKey(k) && !FilterKey(k, filter)) { |
| 15505 PropertyDetails details = DetailsAt(i); | 15540 PropertyDetails details = DetailsAt(i); |
| 15506 if (details.IsDeleted()) continue; | 15541 if (details.IsDeleted()) continue; |
| 15507 PropertyAttributes attr = details.attributes(); | 15542 PropertyAttributes attr = details.attributes(); |
| 15508 if ((attr & filter) == 0) storage->set(index++, k); | 15543 if ((attr & filter) == 0) storage->set(index++, k); |
| 15509 } | 15544 } |
| 15510 } | 15545 } |
| 15511 if (sort_mode == Dictionary<Shape, Key>::SORTED) { | 15546 if (sort_mode == Dictionary::SORTED) { |
| 15512 storage->SortPairs(storage, index); | 15547 storage->SortPairs(storage, index); |
| 15513 } | 15548 } |
| 15514 ASSERT(storage->length() >= index); | 15549 ASSERT(storage->length() >= index); |
| 15515 } | 15550 } |
| 15516 | 15551 |
| 15517 | 15552 |
| 15518 struct EnumIndexComparator { | 15553 struct EnumIndexComparator { |
| 15519 explicit EnumIndexComparator(NameDictionary* dict) : dict(dict) { } | 15554 explicit EnumIndexComparator(NameDictionary* dict) : dict(dict) { } |
| 15520 bool operator() (Smi* a, Smi* b) { | 15555 bool operator() (Smi* a, Smi* b) { |
| 15521 PropertyDetails da(dict->DetailsAt(a->value())); | 15556 PropertyDetails da(dict->DetailsAt(a->value())); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 15543 EnumIndexComparator cmp(this); | 15578 EnumIndexComparator cmp(this); |
| 15544 Smi** start = reinterpret_cast<Smi**>(storage->GetFirstElementAddress()); | 15579 Smi** start = reinterpret_cast<Smi**>(storage->GetFirstElementAddress()); |
| 15545 std::sort(start, start + length, cmp); | 15580 std::sort(start, start + length, cmp); |
| 15546 for (int i = 0; i < length; i++) { | 15581 for (int i = 0; i < length; i++) { |
| 15547 int index = Smi::cast(storage->get(i))->value(); | 15582 int index = Smi::cast(storage->get(i))->value(); |
| 15548 storage->set(i, KeyAt(index)); | 15583 storage->set(i, KeyAt(index)); |
| 15549 } | 15584 } |
| 15550 } | 15585 } |
| 15551 | 15586 |
| 15552 | 15587 |
| 15553 template<typename Shape, typename Key> | 15588 template<typename Derived, typename Shape, typename Key> |
| 15554 void Dictionary<Shape, Key>::CopyKeysTo( | 15589 void Dictionary<Derived, Shape, Key>::CopyKeysTo( |
| 15555 FixedArray* storage, | 15590 FixedArray* storage, |
| 15556 int index, | 15591 int index, |
| 15557 PropertyAttributes filter, | 15592 PropertyAttributes filter, |
| 15558 typename Dictionary<Shape, Key>::SortMode sort_mode) { | 15593 typename Dictionary<Derived, Shape, Key>::SortMode sort_mode) { |
| 15559 ASSERT(storage->length() >= NumberOfElementsFilterAttributes(filter)); | 15594 ASSERT(storage->length() >= NumberOfElementsFilterAttributes(filter)); |
| 15560 int capacity = HashTable<Shape, Key>::Capacity(); | 15595 int capacity = DerivedHashTable::Capacity(); |
| 15561 for (int i = 0; i < capacity; i++) { | 15596 for (int i = 0; i < capacity; i++) { |
| 15562 Object* k = HashTable<Shape, Key>::KeyAt(i); | 15597 Object* k = DerivedHashTable::KeyAt(i); |
| 15563 if (HashTable<Shape, Key>::IsKey(k) && !FilterKey(k, filter)) { | 15598 if (DerivedHashTable::IsKey(k) && !FilterKey(k, filter)) { |
| 15564 PropertyDetails details = DetailsAt(i); | 15599 PropertyDetails details = DetailsAt(i); |
| 15565 if (details.IsDeleted()) continue; | 15600 if (details.IsDeleted()) continue; |
| 15566 PropertyAttributes attr = details.attributes(); | 15601 PropertyAttributes attr = details.attributes(); |
| 15567 if ((attr & filter) == 0) storage->set(index++, k); | 15602 if ((attr & filter) == 0) storage->set(index++, k); |
| 15568 } | 15603 } |
| 15569 } | 15604 } |
| 15570 if (sort_mode == Dictionary<Shape, Key>::SORTED) { | 15605 if (sort_mode == Dictionary::SORTED) { |
| 15571 storage->SortPairs(storage, index); | 15606 storage->SortPairs(storage, index); |
| 15572 } | 15607 } |
| 15573 ASSERT(storage->length() >= index); | 15608 ASSERT(storage->length() >= index); |
| 15574 } | 15609 } |
| 15575 | 15610 |
| 15576 | 15611 |
| 15577 // Backwards lookup (slow). | 15612 // Backwards lookup (slow). |
| 15578 template<typename Shape, typename Key> | 15613 template<typename Derived, typename Shape, typename Key> |
| 15579 Object* Dictionary<Shape, Key>::SlowReverseLookup(Object* value) { | 15614 Object* Dictionary<Derived, Shape, Key>::SlowReverseLookup(Object* value) { |
| 15580 int capacity = HashTable<Shape, Key>::Capacity(); | 15615 int capacity = DerivedHashTable::Capacity(); |
| 15581 for (int i = 0; i < capacity; i++) { | 15616 for (int i = 0; i < capacity; i++) { |
| 15582 Object* k = HashTable<Shape, Key>::KeyAt(i); | 15617 Object* k = DerivedHashTable::KeyAt(i); |
| 15583 if (Dictionary<Shape, Key>::IsKey(k)) { | 15618 if (Dictionary::IsKey(k)) { |
| 15584 Object* e = ValueAt(i); | 15619 Object* e = ValueAt(i); |
| 15585 if (e->IsPropertyCell()) { | 15620 if (e->IsPropertyCell()) { |
| 15586 e = PropertyCell::cast(e)->value(); | 15621 e = PropertyCell::cast(e)->value(); |
| 15587 } | 15622 } |
| 15588 if (e == value) return k; | 15623 if (e == value) return k; |
| 15589 } | 15624 } |
| 15590 } | 15625 } |
| 15591 Heap* heap = Dictionary<Shape, Key>::GetHeap(); | 15626 Heap* heap = Dictionary::GetHeap(); |
| 15592 return heap->undefined_value(); | 15627 return heap->undefined_value(); |
| 15593 } | 15628 } |
| 15594 | 15629 |
| 15595 | 15630 |
| 15596 Handle<ObjectHashTable> ObjectHashTable::EnsureCapacity( | 15631 Handle<ObjectHashTable> ObjectHashTable::EnsureCapacity( |
| 15597 Handle<ObjectHashTable> table, | 15632 Handle<ObjectHashTable> table, |
| 15598 int n, | 15633 int n, |
| 15599 Handle<Object> key, | 15634 Handle<Object> key, |
| 15600 PretenureFlag pretenure) { | 15635 PretenureFlag pretenure) { |
| 15601 Handle<HashTable<ObjectHashTableShape, Object*> > table_base = table; | 15636 Handle<HashTable<ObjectHashTable, |
| 15637 ObjectHashTableShape, |
| 15638 Object*> > table_base = table; |
| 15602 CALL_HEAP_FUNCTION(table_base->GetIsolate(), | 15639 CALL_HEAP_FUNCTION(table_base->GetIsolate(), |
| 15603 table_base->EnsureCapacity(n, *key, pretenure), | 15640 table_base->EnsureCapacity(n, *key, pretenure), |
| 15604 ObjectHashTable); | 15641 ObjectHashTable); |
| 15605 } | 15642 } |
| 15606 | 15643 |
| 15607 | 15644 |
| 15608 Handle<ObjectHashTable> ObjectHashTable::Shrink( | |
| 15609 Handle<ObjectHashTable> table, Handle<Object> key) { | |
| 15610 Handle<HashTable<ObjectHashTableShape, Object*> > table_base = table; | |
| 15611 CALL_HEAP_FUNCTION(table_base->GetIsolate(), | |
| 15612 table_base->Shrink(*key), | |
| 15613 ObjectHashTable); | |
| 15614 } | |
| 15615 | |
| 15616 | |
| 15617 Object* ObjectHashTable::Lookup(Object* key) { | 15645 Object* ObjectHashTable::Lookup(Object* key) { |
| 15618 ASSERT(IsKey(key)); | 15646 ASSERT(IsKey(key)); |
| 15619 | 15647 |
| 15620 // If the object does not have an identity hash, it was never used as a key. | 15648 // If the object does not have an identity hash, it was never used as a key. |
| 15621 Object* hash = key->GetHash(); | 15649 Object* hash = key->GetHash(); |
| 15622 if (hash->IsUndefined()) { | 15650 if (hash->IsUndefined()) { |
| 15623 return GetHeap()->the_hole_value(); | 15651 return GetHeap()->the_hole_value(); |
| 15624 } | 15652 } |
| 15625 int entry = FindEntry(key); | 15653 int entry = FindEntry(key); |
| 15626 if (entry == kNotFound) return GetHeap()->the_hole_value(); | 15654 if (entry == kNotFound) return GetHeap()->the_hole_value(); |
| (...skipping 859 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16486 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16514 #define ERROR_MESSAGES_TEXTS(C, T) T, |
| 16487 static const char* error_messages_[] = { | 16515 static const char* error_messages_[] = { |
| 16488 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16516 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
| 16489 }; | 16517 }; |
| 16490 #undef ERROR_MESSAGES_TEXTS | 16518 #undef ERROR_MESSAGES_TEXTS |
| 16491 return error_messages_[reason]; | 16519 return error_messages_[reason]; |
| 16492 } | 16520 } |
| 16493 | 16521 |
| 16494 | 16522 |
| 16495 } } // namespace v8::internal | 16523 } } // namespace v8::internal |
| OLD | NEW |