23 static_assert(offsetof(
Record, original_string_) == 0);
24 constexpr int kRecordPointerSize =
sizeof(
Record) /
sizeof(
Address);
29void* StringForwardingTable::Block::operator
new(
size_t size,
int capacity) {
33 static_assert(std::is_trivial_v<Record>);
34 static_assert(std::is_standard_layout_v<Record>);
45 const size_t elements_size = capacity *
sizeof(
Record);
48 const size_t new_size = size + elements_size -
sizeof(
Record);
53void StringForwardingTable::Block::operator
delete(
void*
block) {
59 return std::unique_ptr<Block>(
new (capacity)
Block(capacity));
93 for (
int index = 0; index < up_to_index; ++
index) {
98 if (Heap::InFromPage(
object)) {
100 const bool was_forwarded = UpdateForwardedSlot(
object, slot);
101 if (!was_forwarded) {
112 record(index)->ForwardStringObjectOrHash(cage_base);
122 for (
int index = 0; index < up_to_index; ++
index) {
131 UpdateForwardedSlot(forward, forward_slot);
145std::unique_ptr<StringForwardingTable::BlockVector>
150 std::unique_ptr<BlockVector> new_data =
151 std::make_unique<BlockVector>(capacity);
153 for (
size_t i = 0;
i < data->
size();
i++) {
154 new_data->begin_[
i] = data->LoadBlock(
i);
156 new_data->size_ = data->size();
167 for (uint32_t block_index = 0; block_index < blocks->
size(); block_index++) {
174 .emplace_back(std::make_unique<BlockVector>(
178 blocks_.store(blocks, std::memory_order_relaxed);
182 uint32_t block_index) {
187 blocks =
blocks_.load(std::memory_order_relaxed);
189 if (block_index >= blocks->
size()) {
192 if (block_index >= blocks->
capacity()) {
193 std::unique_ptr<BlockVector> new_blocks =
197 blocks_.store(blocks, std::memory_order_release);
200 std::unique_ptr<Block> new_block =
Block::New(capacity);
201 blocks->
AddBlock(std::move(new_block));
214 uint32_t index_in_block;
215 const uint32_t block_index =
BlockForIndex(index, &index_in_block);
226 uint32_t index_in_block;
227 const uint32_t block_index =
BlockForIndex(index, &index_in_block);
237 constexpr bool is_one_byte =
238 std::is_base_of_v<v8::String::ExternalOneByteStringResource, T>;
243 uint32_t index_in_block;
244 const uint32_t block_index =
BlockForIndex(index, &index_in_block);
248 block->
record(index_in_block)
249 ->
SetExternal(
string, resource, is_one_byte, raw_hash);
264 constexpr bool is_one_byte =
265 std::is_base_of_v<v8::String::ExternalOneByteStringResource, T>;
268 uint32_t index_in_block;
269 const uint32_t block_index =
BlockForIndex(index, &index_in_block);
272 return block->record(index_in_block)
273 ->TryUpdateExternalResource(resource, is_one_byte);
284 PtrComprCageBase cage_base,
int index)
const {
286 uint32_t index_in_block;
287 const uint32_t block_index =
BlockForIndex(index, &index_in_block);
288 Block* block =
blocks_.load(std::memory_order_acquire)
290 return block->record(index_in_block)->forward_string(cage_base);
296 return isolate->string_forwarding_table()
297 ->GetForwardString(isolate, index)
304 uint32_t index_in_block;
305 const uint32_t block_index =
BlockForIndex(index, &index_in_block);
313 return isolate->string_forwarding_table()->GetRawHash(isolate, index);
319 uint32_t index_in_block;
320 const uint32_t block_index =
BlockForIndex(index, &index_in_block);
327 std::unordered_set<Address> disposed_resources;
331 if (resource !=
kNullAddress && disposed_resources.count(resource) == 0) {
332 record->DisposeExternalResource();
333 disposed_resources.insert(resource);
345 for (uint32_t block_index = 0; block_index < blocks->
size(); ++block_index) {
362 const unsigned int last_block_index =
363 static_cast<unsigned int>(blocks->
size() - 1);
364 for (
unsigned int block_index = 0; block_index < last_block_index;
379 const unsigned int last_block_index =
380 static_cast<unsigned int>(blocks->
size() - 1);
381 for (
unsigned int block_index = 0; block_index < last_block_index;
RegisterAllocator * allocator_
Tagged< Object > Acquire_Load() const
void Release_Store(Tagged< Object > value) const
static V8_INLINE bool InYoungGeneration(Tagged< Object > object)
static V8_INLINE bool InWritableSharedSpace(Tagged< HeapObject > object)
static V8_INLINE bool InAnySharedSpace(Tagged< HeapObject > object)
HeapState gc_state() const
IsolateSafepoint * safepoint()
bool IsForwardingAddress() const
Tagged< HeapObject > ToForwardingAddress(Tagged< HeapObject > map_word_host)
static std::unique_ptr< BlockVector > Grow(BlockVector *data, size_t capacity, const base::Mutex &mutex)
void AddBlock(std::unique_ptr< Block > block)
V8_NO_UNIQUE_ADDRESS Allocator allocator_
Block * LoadBlock(size_t index, AcquireLoadTag)
std::allocator< Block * > Allocator
BlockVector(size_t capacity)
void UpdateAfterFullEvacuation(PtrComprCageBase cage_base)
static std::unique_ptr< Block > New(int capacity)
void UpdateAfterYoungEvacuation(PtrComprCageBase cage_base)
Record * record(int index)
void SetInternalized(Tagged< String > string, Tagged< String > forward_to)
uint32_t raw_hash(PtrComprCageBase cage_base) const
void SetExternal(Tagged< String > string, v8::String::ExternalStringResourceBase *, bool is_one_byte, uint32_t raw_hash)
v8::String::ExternalStringResourceBase * external_resource(bool *is_one_byte) const
void set_forward_string(Tagged< Object > object)
std::atomic< BlockVector * > blocks_
static uint32_t IndexInBlock(int index, uint32_t block)
bool TryUpdateExternalResource(int index, T *resource)
static constexpr Tagged< Smi > unused_element()
int AddExternalResourceAndHash(Tagged< String > string, T *resource, uint32_t raw_hash)
StringForwardingTable(Isolate *isolate)
static Address GetForwardStringAddress(Isolate *isolate, int index)
void UpdateAfterYoungEvacuation()
static constexpr int kInitialBlockVectorCapacity
void UpdateForwardString(int index, Tagged< String > forward_to)
V8_EXPORT_PRIVATE uint32_t GetRawHash(PtrComprCageBase cage_base, int index) const
std::atomic< int > next_free_index_
v8::String::ExternalStringResourceBase * GetExternalResource(int index, bool *is_one_byte) const
static uint32_t GetRawHashStatic(Isolate *isolate, int index)
static uint32_t CapacityForBlock(uint32_t block)
static constexpr int kInitialBlockSize
static uint32_t BlockForIndex(int index, uint32_t *index_in_block_out)
V8_INLINE void IterateElements(Func &&callback)
void UpdateAfterFullEvacuation()
static constexpr Tagged< Smi > deleted_element()
BlockVector * EnsureCapacity(uint32_t block)
Tagged< String > GetForwardString(PtrComprCageBase cage_base, int index) const
std::vector< std::unique_ptr< BlockVector > > block_vector_storage_
void InitializeBlockVector()
int AddForwardString(Tagged< String > string, Tagged< String > forward_to)
V8_INLINE constexpr StorageType ptr() const
#define EXPORT_TEMPLATE_DEFINE(export)
Handle< FixedArray > elements_
constexpr int kTaggedSize
Tagged(T object) -> Tagged< T >
void * AlignedAllocWithRetry(size_t size, size_t alignment)
constexpr int kSystemPointerSize
V8_INLINE constexpr bool IsHeapObject(TaggedImpl< kRefType, StorageType > obj)
V8_EXPORT_PRIVATE FlagValues v8_flags
SlotTraits::TOffHeapObjectSlot OffHeapObjectSlot
void AlignedFree(void *ptr)
static constexpr Address kNullAddress
void MemsetPointer(FullObjectSlot start, Tagged< Object > value, size_t counter)
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
static constexpr RelaxedLoadTag kRelaxedLoad
static constexpr AcquireLoadTag kAcquireLoad
#define DCHECK_LE(v1, v2)
#define CHECK_LT(lhs, rhs)
#define DCHECK_IMPLIES(v1, v2)
#define DCHECK_NE(v1, v2)
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)
#define V8_EXPORT_PRIVATE
#define V8_UNLIKELY(condition)