1 // Copyright 2017 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_OBJECTS_STRING_TABLE_H_ 6 #define V8_OBJECTS_STRING_TABLE_H_ 7 8 #include "src/common/assert-scope.h" 9 #include "src/objects/string.h" 10 #include "src/roots/roots.h" 11 12 // Has to be the last include (doesn't have include guards): 13 #include "src/objects/object-macros.h" 14 15 namespace v8 { 16 namespace internal { 17 18 // A generic key for lookups into the string table, which allows heteromorphic 19 // lookup and on-demand creation of new strings. 20 class StringTableKey { 21 public: 22 virtual ~StringTableKey() = default; 23 inline StringTableKey(uint32_t hash_field, int length); 24 25 // The individual keys will have their own AsHandle, we shouldn't call the 26 // base version. 27 Handle<String> AsHandle(Isolate* isolate) = delete; 28 hash_field()29 uint32_t hash_field() const { 30 DCHECK_NE(0, hash_field_); 31 return hash_field_; 32 } 33 34 virtual bool IsMatch(String string) = 0; 35 inline uint32_t hash() const; length()36 int length() const { return length_; } 37 38 protected: 39 inline void set_hash_field(uint32_t hash_field); 40 41 private: 42 uint32_t hash_field_ = 0; 43 int length_; 44 }; 45 46 class SeqOneByteString; 47 48 // StringTable, for internalizing strings. The Lookup methods are designed to be 49 // thread-safe, in combination with GC safepoints. 50 // 51 // The string table layout is defined by its Data implementation class, see 52 // StringTable::Data for details. 53 class V8_EXPORT_PRIVATE StringTable { 54 public: empty_element()55 static constexpr Smi empty_element() { return Smi::FromInt(0); } deleted_element()56 static constexpr Smi deleted_element() { return Smi::FromInt(1); } 57 58 explicit StringTable(Isolate* isolate); 59 ~StringTable(); 60 61 int Capacity() const; 62 int NumberOfElements() const; 63 64 // Find string in the string table. If it is not there yet, it is 65 // added. The return value is the string found. 66 Handle<String> LookupString(Isolate* isolate, Handle<String> key); 67 68 // Find string in the string table, using the given key. If the string is not 69 // there yet, it is created (by the key) and added. The return value is the 70 // string found. 71 template <typename StringTableKey, typename LocalIsolate> 72 Handle<String> LookupKey(LocalIsolate* isolate, StringTableKey* key); 73 74 // {raw_string} must be a tagged String pointer. 75 // Returns a tagged pointer: either a Smi if the string is an array index, an 76 // internalized string, or a Smi sentinel. 77 static Address TryStringToIndexOrLookupExisting(Isolate* isolate, 78 Address raw_string); 79 80 void Print(IsolateRoot isolate) const; 81 size_t GetCurrentMemoryUsage() const; 82 83 // The following methods must be called either while holding the write lock, 84 // or while in a Heap safepoint. 85 void IterateElements(RootVisitor* visitor); 86 void DropOldData(); 87 void NotifyElementsRemoved(int count); 88 89 private: 90 class Data; 91 92 Data* EnsureCapacity(IsolateRoot isolate, int additional_elements); 93 94 std::atomic<Data*> data_; 95 // Write mutex is mutable so that readers of concurrently mutated values (e.g. 96 // NumberOfElements) are allowed to lock it while staying const. 97 mutable base::Mutex write_mutex_; 98 #ifdef DEBUG 99 Isolate* isolate_; 100 #endif 101 }; 102 103 } // namespace internal 104 } // namespace v8 105 106 #include "src/objects/object-macros-undef.h" 107 108 #endif // V8_OBJECTS_STRING_TABLE_H_ 109