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

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: Patch for landing 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
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, 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
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
OLDNEW
« src/objects.h ('K') | « src/objects.h ('k') | test/cctest/cctest.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698