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

Side by Side Diff: src/objects.cc

Issue 202293004: Work in progress: ES6 Maps and Sets with deterministic iteration support (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Avoid unnecessary growth Created 6 years, 9 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/factory.cc ('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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 #include "isolate-inl.h" 45 #include "isolate-inl.h"
46 #include "log.h" 46 #include "log.h"
47 #include "objects-inl.h" 47 #include "objects-inl.h"
48 #include "objects-visiting-inl.h" 48 #include "objects-visiting-inl.h"
49 #include "macro-assembler.h" 49 #include "macro-assembler.h"
50 #include "mark-compact.h" 50 #include "mark-compact.h"
51 #include "safepoint-table.h" 51 #include "safepoint-table.h"
52 #include "string-stream.h" 52 #include "string-stream.h"
53 #include "utils.h" 53 #include "utils.h"
54 54
55 #include "close-table.h"
56
55 #ifdef ENABLE_DISASSEMBLER 57 #ifdef ENABLE_DISASSEMBLER
56 #include "disasm.h" 58 #include "disasm.h"
57 #include "disassembler.h" 59 #include "disassembler.h"
58 #endif 60 #endif
59 61
60 namespace v8 { 62 namespace v8 {
61 namespace internal { 63 namespace internal {
62 64
63 65
64 MUST_USE_RESULT static MaybeObject* CreateJSValue(JSFunction* constructor, 66 MUST_USE_RESULT static MaybeObject* CreateJSValue(JSFunction* constructor,
(...skipping 15822 matching lines...) Expand 10 before | Expand all | Expand 10 after
15887 } 15889 }
15888 15890
15889 15891
15890 void WeakHashTable::AddEntry(int entry, Object* key, Object* value) { 15892 void WeakHashTable::AddEntry(int entry, Object* key, Object* value) {
15891 set(EntryToIndex(entry), key); 15893 set(EntryToIndex(entry), key);
15892 set(EntryToValueIndex(entry), value); 15894 set(EntryToValueIndex(entry), value);
15893 ElementAdded(); 15895 ElementAdded();
15894 } 15896 }
15895 15897
15896 15898
15899 template<int entrysize>
15900 MaybeObject* CloseTable<entrysize>::Allocate(Heap* heap, int capacity) {
15901 // capacity must be a factor of two
15902 const int kMinCapacity = 4;
15903 capacity = Max(kMinCapacity, capacity);
arv (Not doing code reviews) 2014/03/29 02:26:07 Can be an assert instead? I don't think this needs
adamk 2014/03/31 15:36:39 Something like that, yeah. I'm sort of waiting til
15904 int num_buckets = capacity / kLoadFactor;
15905 ASSERT(num_buckets * kLoadFactor == capacity);
15906 CloseTable* table;
15907 { MaybeObject* maybe_obj =
15908 heap->AllocateFixedArray(
15909 kHashTableStartIndex + num_buckets
15910 + (capacity * kEntrySize));
15911 if (!maybe_obj->To(&table)) return maybe_obj;
15912 }
15913 for (int i = 0; i < num_buckets; ++i) {
15914 table->set(kHashTableStartIndex + i, heap->the_hole_value());
15915 }
15916 table->SetNumberOfBuckets(num_buckets);
15917 table->SetNumberOfElements(0);
15918 table->SetNumberOfDeletedElements(0);
15919 return table;
15920 }
15921
15922
15923 template<int entrysize>
15924 MaybeObject* CloseTable<entrysize>::EnsureCapacity(int num_to_add) {
15925 int nof = NumberOfElements();
15926 int nod = NumberOfDeletedElements();
15927 int capacity = Capacity();
15928 if ((nof + nod + num_to_add) <= capacity) return this;
15929 // Don't need to grow if we can simply clear out deleted entries instead.
arv (Not doing code reviews) 2014/03/29 02:26:07 This comment does not look accurate. We still call
adamk 2014/03/31 15:36:39 The comment is confusing, I admit. It's trying to
15930 int new_capacity = (nod < (capacity >> 1)) ? capacity << 1 : capacity;
15931 CloseTable* new_table;
15932 { MaybeObject* maybe_obj = Allocate(GetHeap(), new_capacity);
15933 if (!maybe_obj->To(&new_table)) return maybe_obj;
15934 }
15935 return Rehash(new_table);
15936 }
15937
15938
15939 template<int entrysize>
15940 MaybeObject* CloseTable<entrysize>::Shrink() {
15941 int nof = NumberOfElements();
15942 int capacity = Capacity();
15943 if (nof > (capacity >> 2)) return this;
15944 int new_capacity = capacity / 2;
15945 CloseTable* new_table;
15946 { MaybeObject* maybe_obj = Allocate(GetHeap(), new_capacity);
15947 if (!maybe_obj->To(&new_table)) return maybe_obj;
15948 }
15949 return Rehash(new_table);
15950 }
15951
15952
15953 template<int entrysize>
15954 MaybeObject* CloseTable<entrysize>::Rehash(CloseTable* new_table) {
15955 int nof = NumberOfElements();
15956 int nod = NumberOfDeletedElements();
15957 int new_buckets = new_table->NumberOfBuckets();
15958 int new_entry = 0;
15959 for (int old_entry = 0; old_entry < (nof + nod); ++old_entry) {
15960 Object* key = KeyAt(old_entry);
15961 if (key->IsTheHole()) continue;
15962 Object* hash = key->GetHash();
15963 int bucket = Smi::cast(hash)->value() & (new_buckets - 1);
15964 Object* chain_entry = new_table->get(kHashTableStartIndex + bucket);
15965 new_table->set(kHashTableStartIndex + bucket, Smi::FromInt(new_entry));
15966 for (int i = 0; i < kEntrySize; ++i) {
15967 Object* value = get(EntryToIndex(old_entry) + i);
15968 new_table->set(new_table->EntryToIndex(new_entry) + i, value);
15969 }
15970 new_table->set(new_table->EntryToIndex(new_entry) + kChainOffset, chain_entr y);
15971 ++new_entry;
15972 }
15973 new_table->SetNumberOfElements(nof);
15974 return new_table;
15975 }
15976
15977
15978 template<int entrysize>
15979 int CloseTable<entrysize>::FindEntry(Object* key) {
15980 ASSERT(!key->IsTheHole());
15981 Object* hash = key->GetHash();
15982 if (hash->IsUndefined()) return kNotFound;
15983 int bucket = Smi::cast(hash)->value() & (NumberOfBuckets() - 1);
15984 Object* bucket_entry = get(kHashTableStartIndex + bucket);
15985 if (!bucket_entry->IsSmi()) return kNotFound;
15986 int entry = Smi::cast(bucket_entry)->value();
15987 while (true) {
15988 Object* candidate = KeyAt(entry);
15989 if (candidate->SameValue(key))
15990 return entry;
15991 Object* chain = ChainAt(entry);
15992 if (!chain->IsSmi())
15993 break;
15994 entry = Smi::cast(chain)->value();
15995 }
15996 return kNotFound;
15997 }
15998
15999
16000 template class CloseTable<1>;
16001 template class CloseTable<2>;
16002
16003
16004 bool CloseTableSet::Contains(Object* key) {
16005 return FindEntry(key) != kNotFound;
16006 }
16007
16008
16009 Handle<CloseTableSet> CloseTableSet::EnsureCapacity(
16010 Handle<CloseTableSet> table,
16011 int num_to_add) {
16012 Handle<CloseTable<1> > table_base = table;
16013 CALL_HEAP_FUNCTION(table_base->GetIsolate(),
16014 table_base->EnsureCapacity(num_to_add),
16015 CloseTableSet);
16016 }
16017
16018
16019 Handle<CloseTableSet> CloseTableSet::Shrink(Handle<CloseTableSet> table) {
16020 Handle<CloseTable<1> > table_base = table;
16021 CALL_HEAP_FUNCTION(table_base->GetIsolate(),
16022 table_base->Shrink(),
16023 CloseTableSet);
16024 }
16025
16026
16027 Handle<CloseTableSet> CloseTableSet::Add(Handle<CloseTableSet> table,
16028 Handle<Object> key) {
16029 if (table->FindEntry(*key) != kNotFound) return table;
16030
16031 table = EnsureCapacity(table, 1);
16032
16033 Handle<Object> hash = GetOrCreateHash(key, table->GetIsolate());
16034 int bucket = Smi::cast(*hash)->value() & (table->NumberOfBuckets() - 1);
16035 int nof = table->NumberOfElements();
16036 int entry = nof + table->NumberOfDeletedElements();
16037 int index = table->EntryToIndex(entry);
16038 Object* chain_entry = table->get(kHashTableStartIndex + bucket);
16039 table->set(kHashTableStartIndex + bucket, Smi::FromInt(entry));
16040 table->set(index, *key);
16041 table->set(index + kChainOffset, chain_entry);
16042 table->ElementAdded();
16043 return table;
16044 }
16045
16046
16047 Handle<CloseTableSet> CloseTableSet::Remove(Handle<CloseTableSet> table,
16048 Handle<Object> key) {
16049 int entry = table->FindEntry(*key);
16050 if (entry == kNotFound) return table;
16051
16052 table->set_the_hole(table->EntryToIndex(entry));
16053 table->ElementRemoved();
16054
16055 // TODO(adamk): Don't shrink if we're being iterated over
16056 table = Shrink(table);
16057
16058 return table;
16059 }
16060
16061
16062 Object* CloseTableMap::Lookup(Object* key) {
16063 int entry = FindEntry(key);
16064 if (entry == kNotFound) return GetHeap()->the_hole_value();
16065 return ValueAt(entry);
16066 }
16067
16068
16069 Handle<CloseTableMap> CloseTableMap::EnsureCapacity(
16070 Handle<CloseTableMap> table,
16071 int num_to_add) {
16072 Handle<CloseTable<2> > table_base = table;
16073 CALL_HEAP_FUNCTION(table_base->GetIsolate(),
16074 table_base->EnsureCapacity(num_to_add),
16075 CloseTableMap);
16076 }
16077
16078
16079 Handle<CloseTableMap> CloseTableMap::Shrink(Handle<CloseTableMap> table) {
16080 Handle<CloseTable<2> > table_base = table;
16081 CALL_HEAP_FUNCTION(table_base->GetIsolate(),
16082 table_base->Shrink(),
16083 CloseTableMap);
16084 }
16085
16086
16087 Handle<CloseTableMap> CloseTableMap::Put(Handle<CloseTableMap> table,
16088 Handle<Object> key,
16089 Handle<Object> value) {
16090 int entry = table->FindEntry(*key);
16091
16092 if (value->IsTheHole()) {
16093 if (entry == kNotFound) return table;
16094 int index = table->EntryToIndex(entry);
16095 table->set_the_hole(index);
16096 table->set_the_hole(index + kValueOffset);
16097 table->ElementRemoved();
16098
16099 // TODO(adamk): Only shrink if not iterating
16100 table = Shrink(table);
16101 return table;
16102 }
16103
16104 if (entry != kNotFound) {
16105 table->set(table->EntryToIndex(entry) + kValueOffset, *value);
16106 return table;
16107 }
16108
16109 table = EnsureCapacity(table, 1);
16110
16111 Handle<Object> hash = GetOrCreateHash(key, table->GetIsolate());
16112 int bucket = Smi::cast(*hash)->value() & (table->NumberOfBuckets() - 1);
16113 int nof = table->NumberOfElements();
16114 entry = nof + table->NumberOfDeletedElements();
16115 int index = table->EntryToIndex(entry);
16116 Object* chain_entry = table->get(kHashTableStartIndex + bucket);
16117 table->set(kHashTableStartIndex + bucket, Smi::FromInt(entry));
16118 table->set(index, *key);
16119 table->set(index + kValueOffset, *value);
16120 table->set(index + kChainOffset, chain_entry);
16121 table->ElementAdded();
16122 return table;
16123 }
16124
16125
15897 DeclaredAccessorDescriptorIterator::DeclaredAccessorDescriptorIterator( 16126 DeclaredAccessorDescriptorIterator::DeclaredAccessorDescriptorIterator(
15898 DeclaredAccessorDescriptor* descriptor) 16127 DeclaredAccessorDescriptor* descriptor)
15899 : array_(descriptor->serialized_data()->GetDataStartAddress()), 16128 : array_(descriptor->serialized_data()->GetDataStartAddress()),
15900 length_(descriptor->serialized_data()->length()), 16129 length_(descriptor->serialized_data()->length()),
15901 offset_(0) { 16130 offset_(0) {
15902 } 16131 }
15903 16132
15904 16133
15905 const DeclaredAccessorDescriptorData* 16134 const DeclaredAccessorDescriptorData*
15906 DeclaredAccessorDescriptorIterator::Next() { 16135 DeclaredAccessorDescriptorIterator::Next() {
(...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after
16419 #define ERROR_MESSAGES_TEXTS(C, T) T, 16648 #define ERROR_MESSAGES_TEXTS(C, T) T,
16420 static const char* error_messages_[] = { 16649 static const char* error_messages_[] = {
16421 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 16650 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
16422 }; 16651 };
16423 #undef ERROR_MESSAGES_TEXTS 16652 #undef ERROR_MESSAGES_TEXTS
16424 return error_messages_[reason]; 16653 return error_messages_[reason];
16425 } 16654 }
16426 16655
16427 16656
16428 } } // namespace v8::internal 16657 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/factory.cc ('k') | test/cctest/cctest.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698