 Chromium Code Reviews
 Chromium Code Reviews Issue 202293004:
  Work in progress: ES6 Maps and Sets with deterministic iteration support  (Closed) 
  Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
    
  
    Issue 202293004:
  Work in progress: ES6 Maps and Sets with deterministic iteration support  (Closed) 
  Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge| 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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 | 
| OLD | NEW |