Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(377)

Side by Side Diff: src/objects.cc

Issue 220293002: OrderedHashTable implementation with Set and Map interfaces (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Handlified Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | test/cctest/cctest.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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) {
15900 // capacity must be a factor of two
15901 const int kMinCapacity = 4;
15902 capacity = RoundUpToPowerOf2(Max(kMinCapacity, capacity));
15903 if (capacity > kMaxCapacity) {
15904 v8::internal::Heap::FatalProcessOutOfMemory("invalid table size", true);
15905 }
15906 int num_buckets = capacity / kLoadFactor;
15907 Handle<Derived> table =
15908 Handle<Derived>::cast(
15909 isolate->factory()->NewFixedArray(
15910 kHashTableStartIndex + num_buckets + (capacity * kEntrySize)));
15911 for (int i = 0; i < num_buckets; ++i) {
15912 table->set(kHashTableStartIndex + i, Smi::FromInt(kNotFound));
15913 }
15914 table->SetNumberOfBuckets(num_buckets);
15915 table->SetNumberOfElements(0);
15916 table->SetNumberOfDeletedElements(0);
15917 return table;
15918 }
15919
15920
15921 template<class Derived, int entrysize>
15922 Handle<Derived> OrderedHashTable<Derived, entrysize>::EnsureGrowable(
15923 Handle<Derived> table) {
15924 int nof = table->NumberOfElements();
15925 int nod = table->NumberOfDeletedElements();
15926 int capacity = table->Capacity();
15927 if ((nof + nod) < capacity) return table;
15928 // Don't need to grow if we can simply clear out deleted entries instead.
15929 // Note that we can't compact in place, though, so we always allocate
15930 // a new table.
15931 return Rehash(table, (nod < (capacity >> 1)) ? capacity << 1 : capacity);
15932 }
15933
15934
15935 template<class Derived, int entrysize>
15936 Handle<Derived> OrderedHashTable<Derived, entrysize>::Shrink(
15937 Handle<Derived> table) {
15938 int nof = table->NumberOfElements();
15939 int capacity = table->Capacity();
15940 if (nof > (capacity >> 2)) return table;
15941 return Rehash(table, capacity / 2);
15942 }
15943
15944
15945 template<class Derived, int entrysize>
15946 Handle<Derived> OrderedHashTable<Derived, entrysize>::Rehash(
15947 Handle<Derived> table, int new_capacity) {
15948 Handle<Derived> new_table = Allocate(table->GetIsolate(), new_capacity);
15949 int nof = table->NumberOfElements();
15950 int nod = table->NumberOfDeletedElements();
15951 int new_buckets = new_table->NumberOfBuckets();
15952 int new_entry = 0;
15953 for (int old_entry = 0; old_entry < (nof + nod); ++old_entry) {
15954 Object* key = table->KeyAt(old_entry);
15955 if (key->IsTheHole()) continue;
15956 Object* hash = key->GetHash();
15957 int bucket = Smi::cast(hash)->value() & (new_buckets - 1);
15958 Object* chain_entry = new_table->get(kHashTableStartIndex + bucket);
15959 new_table->set(kHashTableStartIndex + bucket, Smi::FromInt(new_entry));
15960 int new_index = new_table->EntryToIndex(new_entry);
15961 int old_index = table->EntryToIndex(old_entry);
15962 for (int i = 0; i < entrysize; ++i) {
15963 Object* value = table->get(old_index + i);
15964 new_table->set(new_index + i, value);
15965 }
15966 new_table->set(new_index + kChainOffset, chain_entry);
15967 ++new_entry;
15968 }
15969 new_table->SetNumberOfElements(nof);
15970 return new_table;
15971 }
15972
15973
15974 template<class Derived, int entrysize>
15975 int OrderedHashTable<Derived, entrysize>::FindEntry(Object* key) {
15976 ASSERT(!key->IsTheHole());
15977 Object* hash = key->GetHash();
15978 if (hash->IsUndefined()) return kNotFound;
15979 for (int entry = HashToEntry(Smi::cast(hash)->value());
15980 entry != kNotFound;
15981 entry = ChainAt(entry)) {
15982 Object* candidate = KeyAt(entry);
15983 if (candidate->SameValue(key))
15984 return entry;
15985 }
15986 return kNotFound;
15987 }
15988
15989
15990 template<class Derived, int entrysize>
15991 int OrderedHashTable<Derived, entrysize>::AddEntry(int hash) {
15992 int entry = NumberOfElements() + NumberOfDeletedElements();
15993 int bucket = HashToBucket(hash);
15994 int index = EntryToIndex(entry);
15995 Object* chain_entry = get(kHashTableStartIndex + bucket);
15996 set(kHashTableStartIndex + bucket, Smi::FromInt(entry));
15997 set(index + kChainOffset, chain_entry);
15998 SetNumberOfElements(NumberOfElements() + 1);
15999 return index;
16000 }
16001
16002
16003 template<class Derived, int entrysize>
16004 void OrderedHashTable<Derived, entrysize>::RemoveEntry(int entry) {
16005 int index = EntryToIndex(entry);
16006 for (int i = 0; i < entrysize; ++i) {
16007 set_the_hole(index + i);
16008 }
16009 SetNumberOfElements(NumberOfElements() - 1);
16010 SetNumberOfDeletedElements(NumberOfDeletedElements() + 1);
16011 }
16012
16013
16014 template class OrderedHashTable<OrderedHashSet, 1>;
16015 template class OrderedHashTable<OrderedHashMap, 2>;
16016
16017
16018 bool OrderedHashSet::Contains(Object* key) {
16019 return FindEntry(key) != kNotFound;
16020 }
16021
16022
16023 Handle<OrderedHashSet> OrderedHashSet::Add(Handle<OrderedHashSet> table,
16024 Handle<Object> key) {
16025 if (table->FindEntry(*key) != kNotFound) return table;
16026
16027 table = EnsureGrowable(table);
16028
16029 Handle<Object> hash = GetOrCreateHash(key, table->GetIsolate());
16030 int index = table->AddEntry(Smi::cast(*hash)->value());
16031 table->set(index, *key);
16032 return table;
16033 }
16034
16035
16036 Handle<OrderedHashSet> OrderedHashSet::Remove(Handle<OrderedHashSet> table,
16037 Handle<Object> key) {
16038 int entry = table->FindEntry(*key);
16039 if (entry == kNotFound) return table;
16040 table->RemoveEntry(entry);
16041 // TODO(adamk): Don't shrink if we're being iterated over
16042 return Shrink(table);
16043 }
16044
16045
16046 Object* OrderedHashMap::Lookup(Object* key) {
16047 int entry = FindEntry(key);
16048 if (entry == kNotFound) return GetHeap()->the_hole_value();
16049 return ValueAt(entry);
16050 }
16051
16052
16053 Handle<OrderedHashMap> OrderedHashMap::Put(Handle<OrderedHashMap> table,
16054 Handle<Object> key,
16055 Handle<Object> value) {
16056 int entry = table->FindEntry(*key);
16057
16058 if (value->IsTheHole()) {
16059 if (entry == kNotFound) return table;
16060 table->RemoveEntry(entry);
16061 // TODO(adamk): Only shrink if not iterating
16062 return Shrink(table);
16063 }
16064
16065 if (entry != kNotFound) {
16066 table->set(table->EntryToIndex(entry) + kValueOffset, *value);
16067 return table;
16068 }
16069
16070 table = EnsureGrowable(table);
16071
16072 Handle<Object> hash = GetOrCreateHash(key, table->GetIsolate());
16073 int index = table->AddEntry(Smi::cast(*hash)->value());
16074 table->set(index, *key);
16075 table->set(index + kValueOffset, *value);
16076 return table;
16077 }
16078
16079
15897 DeclaredAccessorDescriptorIterator::DeclaredAccessorDescriptorIterator( 16080 DeclaredAccessorDescriptorIterator::DeclaredAccessorDescriptorIterator(
15898 DeclaredAccessorDescriptor* descriptor) 16081 DeclaredAccessorDescriptor* descriptor)
15899 : array_(descriptor->serialized_data()->GetDataStartAddress()), 16082 : array_(descriptor->serialized_data()->GetDataStartAddress()),
15900 length_(descriptor->serialized_data()->length()), 16083 length_(descriptor->serialized_data()->length()),
15901 offset_(0) { 16084 offset_(0) {
15902 } 16085 }
15903 16086
15904 16087
15905 const DeclaredAccessorDescriptorData* 16088 const DeclaredAccessorDescriptorData*
15906 DeclaredAccessorDescriptorIterator::Next() { 16089 DeclaredAccessorDescriptorIterator::Next() {
(...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after
16419 #define ERROR_MESSAGES_TEXTS(C, T) T, 16602 #define ERROR_MESSAGES_TEXTS(C, T) T,
16420 static const char* error_messages_[] = { 16603 static const char* error_messages_[] = {
16421 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 16604 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
16422 }; 16605 };
16423 #undef ERROR_MESSAGES_TEXTS 16606 #undef ERROR_MESSAGES_TEXTS
16424 return error_messages_[reason]; 16607 return error_messages_[reason];
16425 } 16608 }
16426 16609
16427 16610
16428 } } // namespace v8::internal 16611 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | test/cctest/cctest.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698