/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ #ifndef EXTENT_H #define EXTENT_H #include "mozjemalloc_types.h" #include "BaseAlloc.h" #include "RedBlackTree.h" #include "mozilla/UniquePtr.h" // *************************************************************************** // Extent data structures. struct arena_t; enum ChunkType; // Tree of extents. struct extent_node_t { union { // Linkage for the size/address-ordered tree for chunk recycling. RedBlackTreeNode mLinkBySize; // Arena id for huge allocations. It's meant to match mArena->mId, // which only holds true when the arena hasn't been disposed of. arena_id_t mArenaId; }; // Linkage for the address-ordered tree. RedBlackTreeNode mLinkByAddr; // Pointer to the extent that this tree node is responsible for. void* mAddr; // Total region size. size_t mSize; union { // What type of chunk is there; used for chunk recycling. ChunkType mChunkType; // A pointer to the associated arena, for huge allocations. arena_t* mArena; }; }; struct ExtentTreeSzTrait { static RedBlackTreeNode& GetTreeNode(extent_node_t* aThis) { return aThis->mLinkBySize; } static inline Order Compare(extent_node_t* aNode, extent_node_t* aOther) { Order ret = CompareInt(aNode->mSize, aOther->mSize); return (ret != Order::eEqual) ? ret : CompareAddr(aNode->mAddr, aOther->mAddr); } }; struct ExtentTreeTrait { static RedBlackTreeNode& GetTreeNode(extent_node_t* aThis) { return aThis->mLinkByAddr; } static inline Order Compare(extent_node_t* aNode, extent_node_t* aOther) { return CompareAddr(aNode->mAddr, aOther->mAddr); } }; struct ExtentTreeBoundsTrait : public ExtentTreeTrait { static inline Order Compare(extent_node_t* aKey, extent_node_t* aNode) { uintptr_t key_addr = reinterpret_cast(aKey->mAddr); uintptr_t node_addr = reinterpret_cast(aNode->mAddr); size_t node_size = aNode->mSize; // Is aKey within aNode? if (node_addr <= key_addr && key_addr < node_addr + node_size) { return Order::eEqual; } return CompareAddr(aKey->mAddr, aNode->mAddr); } }; using ExtentAlloc = TypedBaseAlloc; template <> extent_node_t* ExtentAlloc::sFirstFree; using UniqueBaseNode = mozilla::UniquePtr>; #endif /* ! EXTENT_H */