40 if (
static_cast<size_t>(node->Size()) < minimum_size) {
45 *node_size = node->Size();
54 cur_node = cur_node->next()) {
57 if (size >= minimum_size) {
60 if (cur_node ==
top()) {
63 if (!prev_non_evac_node.
is_null()) {
66 prev_non_evac_node->Size());
68 prev_non_evac_node->
address(), prev_non_evac_node->Size());
69 prev_non_evac_node->SetNext(free_space, cur_node->next());
71 prev_non_evac_node->SetNext(
73 prev_non_evac_node->
address(), prev_non_evac_node->Size()),
81 prev_non_evac_node = cur_node;
91 free_space->SetNext(writable_free_space,
top());
93 size_t size_in_bytes = writable_free_space.
Size();
107 while (!n.is_null()) {
127 : number_of_categories_(number_of_categories),
128 last_category_(number_of_categories - 1),
129 min_block_size_(min_block_size) {}
132 return std::make_unique<FreeListManyCachedOrigin>();
136 return std::make_unique<FreeListManyCachedFastPathForNewSpace>();
143 if (category ==
nullptr)
return FreeSpace();
145 if (!node.is_null()) {
160 while (it.HasNext()) {
163 if (!node.is_null()) {
166 if (current->is_empty()) {
177 size_t size_in_bytes = free_space.
Size();
179 page->DecreaseAllocatedBytes(size_in_bytes);
183 page->add_wasted_memory(size_in_bytes);
184 return size_in_bytes;
190 page->free_list_category(type)->Free(free_space, mode,
this);
192 page->AvailableInFreeListFromAllocatedBytes());
213 for (
int cat = minimum_category + 1; !page && cat <=
last_category_; cat++) {
234 if (node.is_null()) {
239 if (!node.is_null()) {
271 CheckCacheIntegrity();
281 int type = category->
type_;
287 CheckCacheIntegrity();
294 size_t size_in_bytes = free_space.
Size();
296 page->DecreaseAllocatedBytes(size_in_bytes);
300 page->add_wasted_memory(size_in_bytes);
301 return size_in_bytes;
307 page->free_list_category(type)->Free(free_space, mode,
this);
314 CheckCacheIntegrity();
319 page->AvailableInFreeListFromAllocatedBytes());
334 if (!node.is_null())
break;
337 if (node.is_null()) {
344 if (!node.is_null() &&
categories_[type] ==
nullptr) {
349 CheckCacheIntegrity();
352 if (!node.is_null()) {
376 if (!node.is_null())
break;
381 if (node.is_null()) {
388 if (!node.is_null())
break;
396 if (node.is_null()) {
403 if (node.is_null()) {
408 if (!node.is_null())
break;
412 if (!node.is_null()) {
418 CheckCacheIntegrity();
462 category->
Reset(
this);
476 category->
Reset(
this);
478 page->add_wasted_memory(sum);
491 if (category->
is_empty())
return false;
495 if (top !=
nullptr) {
496 top->set_prev(category);
515 if (top == category) {
518 if (category->
prev() !=
nullptr) {
521 if (category->
next() !=
nullptr) {
530 PrintF(
"FreeList[%p, top=%p, %d] ",
static_cast<void*
>(
this),
532 while (it.HasNext()) {
534 PrintF(
"%p -> ",
static_cast<void*
>(current));
549 ->
root(RootIndex::kFreeSpaceMap)
567bool FreeList::IsVeryLong() {
571 while (it.HasNext()) {
572 len += it.Next()->FreeListLength();
582size_t FreeList::SumFreeLists() {
void Relink(FreeList *owner)
uint32_t available() const
Tagged< FreeSpace > top()
bool is_linked(FreeList *owner) const
FreeListCategory * next()
void RepairFreeList(Heap *heap)
static constexpr int kVeryLongFreeList
void Reset(FreeList *owner)
FreeListCategory * prev()
FreeListCategoryType type_
void Free(const WritableFreeSpace &writable_free_space, FreeMode mode, FreeList *owner)
Tagged< FreeSpace > SearchForNodeInList(size_t minimum_size, size_t *node_size)
void UpdateCountersAfterAllocation(size_t allocation_size)
void set_prev(FreeListCategory *prev)
V8_EXPORT_PRIVATE Tagged< FreeSpace > PickNodeFromList(size_t minimum_size, size_t *node_size)
void set_top(Tagged< FreeSpace > top)
void set_next(FreeListCategory *next)
void Unlink(FreeList *owner)
static const size_t kTinyObjectMaxSize
FreeListCategoryType SelectFastAllocationFreeListCategoryType(size_t size_in_bytes)
V8_WARN_UNUSED_RESULT Tagged< FreeSpace > Allocate(size_t size_in_bytes, size_t *node_size, AllocationOrigin origin) override
SmallBlocksMode small_blocks_mode_
static const FreeListCategoryType kFastPathFallBackTiny
static const FreeListCategoryType kFastPathFirstCategory
V8_WARN_UNUSED_RESULT Tagged< FreeSpace > Allocate(size_t size_in_bytes, size_t *node_size, AllocationOrigin origin) override
void ResetForNonBlackAllocatedPages() override
bool AddCategory(FreeListCategory *category) override
size_t Free(const WritableFreeSpace &free_space, FreeMode mode) override
V8_WARN_UNUSED_RESULT Tagged< FreeSpace > Allocate(size_t size_in_bytes, size_t *node_size, AllocationOrigin origin) override
void UpdateCacheAfterAddition(FreeListCategoryType cat)
void RemoveCategory(FreeListCategory *category) override
void UpdateCacheAfterRemoval(FreeListCategoryType cat)
int next_nonempty_category[kNumberOfCategories+1]
FreeListCategoryType SelectFreeListCategoryType(size_t size_in_bytes) override
static constexpr unsigned int categories_min[kNumberOfCategories]
V8_WARN_UNUSED_RESULT Tagged< FreeSpace > Allocate(size_t size_in_bytes, size_t *node_size, AllocationOrigin origin) override
static constexpr size_t kMaxBlockSize
PageMetadata * GetPageForSize(size_t size_in_bytes) override
virtual FreeListCategoryType SelectFreeListCategoryType(size_t size_in_bytes)=0
virtual void ResetForNonBlackAllocatedPages()
static V8_EXPORT_PRIVATE std::unique_ptr< FreeList > CreateFreeList()
FreeList(int number_of_categories, size_t min_block_size)
const int number_of_categories_
Tagged< FreeSpace > SearchForNodeInList(FreeListCategoryType type, size_t minimum_size, size_t *node_size)
V8_EXPORT_PRIVATE void EvictFreeListItems(PageMetadata *page)
virtual bool AddCategory(FreeListCategory *category)
FreeListCategory ** categories_
void IncreaseAvailableBytes(size_t bytes)
std::atomic< size_t > wasted_bytes_
PageMetadata * GetPageForCategoryType(FreeListCategoryType type)
void ForAllFreeListCategories(FreeListCategoryType type, Callback callback)
static V8_EXPORT_PRIVATE std::unique_ptr< FreeList > CreateFreeListForNewSpace()
virtual size_t Free(const WritableFreeSpace &free_space, FreeMode mode)
void DecreaseAvailableBytes(size_t bytes)
const FreeListCategoryType last_category_
friend class FreeListCategory
virtual V8_WARN_UNUSED_RESULT Tagged< FreeSpace > Allocate(size_t size_in_bytes, size_t *node_size, AllocationOrigin origin)=0
virtual V8_EXPORT_PRIVATE void RemoveCategory(FreeListCategory *category)
void RepairLists(Heap *heap)
void PrintCategories(FreeListCategoryType type)
Tagged< FreeSpace > TryFindNodeIn(FreeListCategoryType type, size_t minimum_size, size_t *node_size)
bool contains_map_value(Address raw_value) const
void store_map(Tagged< Map > map) const
static Tagged< HeapObject > FromAddress(Address address)
Isolate * isolate() const
Tagged< Object > root(RootIndex index) const
static V8_INLINE MemoryChunk * FromHeapObject(Tagged< HeapObject > object)
static V8_INLINE PageMetadata * FromHeapObject(Tagged< HeapObject > o)
static V8_INLINE PageMetadata * FromAddress(Address addr)
V8_INLINE constexpr StorageType ptr() const
V8_INLINE constexpr bool is_null() const
static V8_INLINE WritableFreeSpace ForNonExecutableMemory(base::Address addr, size_t size)
base::Address Address() const
V8_INLINE WritableFreeSpace FreeRange(Address addr, size_t size)
static constexpr FreeListCategoryType kFirstCategory
void PrintF(const char *format,...)
int32_t FreeListCategoryType
V8_EXPORT_PRIVATE FlagValues v8_flags
static constexpr Address kNullAddress
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
static constexpr RelaxedLoadTag kRelaxedLoad
#define DCHECK_NE(v1, v2)
#define DCHECK_GE(v1, v2)
#define DCHECK(condition)
#define DCHECK_LT(v1, v2)
#define DCHECK_EQ(v1, v2)