blob: 04d758c9fd84e615cce57b760a4c39075d00ad31 [file] [log] [blame]
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_HEAP_CPPGC_FREE_LIST_H_
#define V8_HEAP_CPPGC_FREE_LIST_H_
#include <array>
#include "include/cppgc/heap-statistics.h"
#include "src/base/macros.h"
#include "src/base/sanitizer/asan.h"
#include "src/heap/cppgc/globals.h"
#include "src/heap/cppgc/heap-object-header.h"
namespace cppgc {
namespace internal {
class Filler : public HeapObjectHeader {
public:
inline static Filler& CreateAt(void* memory, size_t size);
protected:
explicit Filler(size_t size) : HeapObjectHeader(size, kFreeListGCInfoIndex) {}
};
class V8_EXPORT_PRIVATE FreeList {
public:
struct Block {
void* address;
size_t size;
};
FreeList();
FreeList(const FreeList&) = delete;
FreeList& operator=(const FreeList&) = delete;
FreeList(FreeList&& other) V8_NOEXCEPT;
FreeList& operator=(FreeList&& other) V8_NOEXCEPT;
// Allocates entries which are at least of the provided size.
Block Allocate(size_t);
// Adds block to the freelist. The minimal block size is a words. Regular
// entries have two words and unusable filler entries have a single word.
void Add(Block);
// Same as `Add()` but also returns the bounds of memory that is not required
// for free list management.
std::pair<Address, Address> AddReturningUnusedBounds(Block);
// Append other freelist into this.
void Append(FreeList&&);
void Clear();
size_t Size() const;
bool IsEmpty() const;
void CollectStatistics(HeapStatistics::FreeListStatistics&);
bool ContainsForTesting(Block) const;
private:
class Entry;
bool IsConsistent(size_t) const;
// All |Entry|s in the nth list have size >= 2^n.
std::array<Entry*, kPageSizeLog2> free_list_heads_;
std::array<Entry*, kPageSizeLog2> free_list_tails_;
size_t biggest_free_list_index_ = 0;
};
// static
Filler& Filler::CreateAt(void* memory, size_t size) {
// The memory area only needs to unpoisoned when running with ASAN. Zapped
// values (DEBUG) or uninitialized values (MSAN) are overwritten below.
ASAN_UNPOISON_MEMORY_REGION(memory, sizeof(Filler));
return *new (memory) Filler(size);
}
} // namespace internal
} // namespace cppgc
#endif // V8_HEAP_CPPGC_FREE_LIST_H_