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 |