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 15876 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15887 } | 15887 } |
15888 | 15888 |
15889 | 15889 |
15890 void WeakHashTable::AddEntry(int entry, Object* key, Object* value) { | 15890 void WeakHashTable::AddEntry(int entry, Object* key, Object* value) { |
15891 set(EntryToIndex(entry), key); | 15891 set(EntryToIndex(entry), key); |
15892 set(EntryToValueIndex(entry), value); | 15892 set(EntryToValueIndex(entry), value); |
15893 ElementAdded(); | 15893 ElementAdded(); |
15894 } | 15894 } |
15895 | 15895 |
15896 | 15896 |
| 15897 template<class Derived, int entrysize> |
| 15898 Handle<Derived> OrderedHashTable<Derived, entrysize>::Allocate( |
| 15899 Isolate* isolate, int capacity, PretenureFlag pretenure) { |
| 15900 // Capacity must be a power of two, since we depend on being able |
| 15901 // to divide and multiple by 2 (kLoadFactor) to derive capacity |
| 15902 // from number of buckets. If we decide to change kLoadFactor |
| 15903 // to something other than 2, capacity should be stored as another |
| 15904 // field of this object. |
| 15905 const int kMinCapacity = 4; |
| 15906 capacity = RoundUpToPowerOf2(Max(kMinCapacity, capacity)); |
| 15907 if (capacity > kMaxCapacity) { |
| 15908 v8::internal::Heap::FatalProcessOutOfMemory("invalid table size", true); |
| 15909 } |
| 15910 int num_buckets = capacity / kLoadFactor; |
| 15911 Handle<Derived> table = |
| 15912 Handle<Derived>::cast( |
| 15913 isolate->factory()->NewFixedArray( |
| 15914 kHashTableStartIndex + num_buckets + (capacity * kEntrySize), |
| 15915 pretenure)); |
| 15916 for (int i = 0; i < num_buckets; ++i) { |
| 15917 table->set(kHashTableStartIndex + i, Smi::FromInt(kNotFound)); |
| 15918 } |
| 15919 table->SetNumberOfBuckets(num_buckets); |
| 15920 table->SetNumberOfElements(0); |
| 15921 table->SetNumberOfDeletedElements(0); |
| 15922 return table; |
| 15923 } |
| 15924 |
| 15925 |
| 15926 template<class Derived, int entrysize> |
| 15927 Handle<Derived> OrderedHashTable<Derived, entrysize>::EnsureGrowable( |
| 15928 Handle<Derived> table) { |
| 15929 int nof = table->NumberOfElements(); |
| 15930 int nod = table->NumberOfDeletedElements(); |
| 15931 int capacity = table->Capacity(); |
| 15932 if ((nof + nod) < capacity) return table; |
| 15933 // Don't need to grow if we can simply clear out deleted entries instead. |
| 15934 // Note that we can't compact in place, though, so we always allocate |
| 15935 // a new table. |
| 15936 return Rehash(table, (nod < (capacity >> 1)) ? capacity << 1 : capacity); |
| 15937 } |
| 15938 |
| 15939 |
| 15940 template<class Derived, int entrysize> |
| 15941 Handle<Derived> OrderedHashTable<Derived, entrysize>::Shrink( |
| 15942 Handle<Derived> table) { |
| 15943 int nof = table->NumberOfElements(); |
| 15944 int capacity = table->Capacity(); |
| 15945 if (nof > (capacity >> 2)) return table; |
| 15946 return Rehash(table, capacity / 2); |
| 15947 } |
| 15948 |
| 15949 |
| 15950 template<class Derived, int entrysize> |
| 15951 Handle<Derived> OrderedHashTable<Derived, entrysize>::Rehash( |
| 15952 Handle<Derived> table, int new_capacity) { |
| 15953 Handle<Derived> new_table = |
| 15954 Allocate(table->GetIsolate(), |
| 15955 new_capacity, |
| 15956 table->GetHeap()->InNewSpace(*table) ? NOT_TENURED : TENURED); |
| 15957 int nof = table->NumberOfElements(); |
| 15958 int nod = table->NumberOfDeletedElements(); |
| 15959 int new_buckets = new_table->NumberOfBuckets(); |
| 15960 int new_entry = 0; |
| 15961 for (int old_entry = 0; old_entry < (nof + nod); ++old_entry) { |
| 15962 Object* key = table->KeyAt(old_entry); |
| 15963 if (key->IsTheHole()) continue; |
| 15964 Object* hash = key->GetHash(); |
| 15965 int bucket = Smi::cast(hash)->value() & (new_buckets - 1); |
| 15966 Object* chain_entry = new_table->get(kHashTableStartIndex + bucket); |
| 15967 new_table->set(kHashTableStartIndex + bucket, Smi::FromInt(new_entry)); |
| 15968 int new_index = new_table->EntryToIndex(new_entry); |
| 15969 int old_index = table->EntryToIndex(old_entry); |
| 15970 for (int i = 0; i < entrysize; ++i) { |
| 15971 Object* value = table->get(old_index + i); |
| 15972 new_table->set(new_index + i, value); |
| 15973 } |
| 15974 new_table->set(new_index + kChainOffset, chain_entry); |
| 15975 ++new_entry; |
| 15976 } |
| 15977 new_table->SetNumberOfElements(nof); |
| 15978 return new_table; |
| 15979 } |
| 15980 |
| 15981 |
| 15982 template<class Derived, int entrysize> |
| 15983 int OrderedHashTable<Derived, entrysize>::FindEntry(Object* key) { |
| 15984 ASSERT(!key->IsTheHole()); |
| 15985 Object* hash = key->GetHash(); |
| 15986 if (hash->IsUndefined()) return kNotFound; |
| 15987 for (int entry = HashToEntry(Smi::cast(hash)->value()); |
| 15988 entry != kNotFound; |
| 15989 entry = ChainAt(entry)) { |
| 15990 Object* candidate = KeyAt(entry); |
| 15991 if (candidate->SameValue(key)) |
| 15992 return entry; |
| 15993 } |
| 15994 return kNotFound; |
| 15995 } |
| 15996 |
| 15997 |
| 15998 template<class Derived, int entrysize> |
| 15999 int OrderedHashTable<Derived, entrysize>::AddEntry(int hash) { |
| 16000 int entry = NumberOfElements() + NumberOfDeletedElements(); |
| 16001 int bucket = HashToBucket(hash); |
| 16002 int index = EntryToIndex(entry); |
| 16003 Object* chain_entry = get(kHashTableStartIndex + bucket); |
| 16004 set(kHashTableStartIndex + bucket, Smi::FromInt(entry)); |
| 16005 set(index + kChainOffset, chain_entry); |
| 16006 SetNumberOfElements(NumberOfElements() + 1); |
| 16007 return index; |
| 16008 } |
| 16009 |
| 16010 |
| 16011 template<class Derived, int entrysize> |
| 16012 void OrderedHashTable<Derived, entrysize>::RemoveEntry(int entry) { |
| 16013 int index = EntryToIndex(entry); |
| 16014 for (int i = 0; i < entrysize; ++i) { |
| 16015 set_the_hole(index + i); |
| 16016 } |
| 16017 SetNumberOfElements(NumberOfElements() - 1); |
| 16018 SetNumberOfDeletedElements(NumberOfDeletedElements() + 1); |
| 16019 } |
| 16020 |
| 16021 |
| 16022 template class OrderedHashTable<OrderedHashSet, 1>; |
| 16023 template class OrderedHashTable<OrderedHashMap, 2>; |
| 16024 |
| 16025 |
| 16026 bool OrderedHashSet::Contains(Object* key) { |
| 16027 return FindEntry(key) != kNotFound; |
| 16028 } |
| 16029 |
| 16030 |
| 16031 Handle<OrderedHashSet> OrderedHashSet::Add(Handle<OrderedHashSet> table, |
| 16032 Handle<Object> key) { |
| 16033 if (table->FindEntry(*key) != kNotFound) return table; |
| 16034 |
| 16035 table = EnsureGrowable(table); |
| 16036 |
| 16037 Handle<Object> hash = GetOrCreateHash(key, table->GetIsolate()); |
| 16038 int index = table->AddEntry(Smi::cast(*hash)->value()); |
| 16039 table->set(index, *key); |
| 16040 return table; |
| 16041 } |
| 16042 |
| 16043 |
| 16044 Handle<OrderedHashSet> OrderedHashSet::Remove(Handle<OrderedHashSet> table, |
| 16045 Handle<Object> key) { |
| 16046 int entry = table->FindEntry(*key); |
| 16047 if (entry == kNotFound) return table; |
| 16048 table->RemoveEntry(entry); |
| 16049 // TODO(adamk): Don't shrink if we're being iterated over |
| 16050 return Shrink(table); |
| 16051 } |
| 16052 |
| 16053 |
| 16054 Object* OrderedHashMap::Lookup(Object* key) { |
| 16055 int entry = FindEntry(key); |
| 16056 if (entry == kNotFound) return GetHeap()->the_hole_value(); |
| 16057 return ValueAt(entry); |
| 16058 } |
| 16059 |
| 16060 |
| 16061 Handle<OrderedHashMap> OrderedHashMap::Put(Handle<OrderedHashMap> table, |
| 16062 Handle<Object> key, |
| 16063 Handle<Object> value) { |
| 16064 int entry = table->FindEntry(*key); |
| 16065 |
| 16066 if (value->IsTheHole()) { |
| 16067 if (entry == kNotFound) return table; |
| 16068 table->RemoveEntry(entry); |
| 16069 // TODO(adamk): Only shrink if not iterating |
| 16070 return Shrink(table); |
| 16071 } |
| 16072 |
| 16073 if (entry != kNotFound) { |
| 16074 table->set(table->EntryToIndex(entry) + kValueOffset, *value); |
| 16075 return table; |
| 16076 } |
| 16077 |
| 16078 table = EnsureGrowable(table); |
| 16079 |
| 16080 Handle<Object> hash = GetOrCreateHash(key, table->GetIsolate()); |
| 16081 int index = table->AddEntry(Smi::cast(*hash)->value()); |
| 16082 table->set(index, *key); |
| 16083 table->set(index + kValueOffset, *value); |
| 16084 return table; |
| 16085 } |
| 16086 |
| 16087 |
15897 DeclaredAccessorDescriptorIterator::DeclaredAccessorDescriptorIterator( | 16088 DeclaredAccessorDescriptorIterator::DeclaredAccessorDescriptorIterator( |
15898 DeclaredAccessorDescriptor* descriptor) | 16089 DeclaredAccessorDescriptor* descriptor) |
15899 : array_(descriptor->serialized_data()->GetDataStartAddress()), | 16090 : array_(descriptor->serialized_data()->GetDataStartAddress()), |
15900 length_(descriptor->serialized_data()->length()), | 16091 length_(descriptor->serialized_data()->length()), |
15901 offset_(0) { | 16092 offset_(0) { |
15902 } | 16093 } |
15903 | 16094 |
15904 | 16095 |
15905 const DeclaredAccessorDescriptorData* | 16096 const DeclaredAccessorDescriptorData* |
15906 DeclaredAccessorDescriptorIterator::Next() { | 16097 DeclaredAccessorDescriptorIterator::Next() { |
(...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16419 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16610 #define ERROR_MESSAGES_TEXTS(C, T) T, |
16420 static const char* error_messages_[] = { | 16611 static const char* error_messages_[] = { |
16421 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16612 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
16422 }; | 16613 }; |
16423 #undef ERROR_MESSAGES_TEXTS | 16614 #undef ERROR_MESSAGES_TEXTS |
16424 return error_messages_[reason]; | 16615 return error_messages_[reason]; |
16425 } | 16616 } |
16426 | 16617 |
16427 | 16618 |
16428 } } // namespace v8::internal | 16619 } } // namespace v8::internal |
OLD | NEW |