10b57cec5SDimitry Andric //===- Memory.h -------------------------------------------------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file defines arena allocators. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric // Almost all large objects, such as files, sections or symbols, are 120b57cec5SDimitry Andric // used for the entire lifetime of the linker once they are created. 130b57cec5SDimitry Andric // This usage characteristic makes arena allocator an attractive choice 140b57cec5SDimitry Andric // where the entire linker is one arena. With an arena, newly created 150b57cec5SDimitry Andric // objects belong to the arena and freed all at once when everything is done. 160b57cec5SDimitry Andric // Arena allocators are efficient and easy to understand. 170b57cec5SDimitry Andric // Most objects are allocated using the arena allocators defined by this file. 180b57cec5SDimitry Andric // 190b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric #ifndef LLD_COMMON_MEMORY_H 220b57cec5SDimitry Andric #define LLD_COMMON_MEMORY_H 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric #include "llvm/Support/Allocator.h" 250b57cec5SDimitry Andric #include "llvm/Support/StringSaver.h" 260b57cec5SDimitry Andric #include <vector> 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric namespace lld { 290b57cec5SDimitry Andric 300b57cec5SDimitry Andric // Use this arena if your object doesn't have a destructor. 310b57cec5SDimitry Andric extern llvm::BumpPtrAllocator bAlloc; 320b57cec5SDimitry Andric extern llvm::StringSaver saver; 330b57cec5SDimitry Andric 340b57cec5SDimitry Andric void freeArena(); 350b57cec5SDimitry Andric 360b57cec5SDimitry Andric // These two classes are hack to keep track of all 370b57cec5SDimitry Andric // SpecificBumpPtrAllocator instances. 380b57cec5SDimitry Andric struct SpecificAllocBase { 390b57cec5SDimitry Andric SpecificAllocBase() { instances.push_back(this); } 400b57cec5SDimitry Andric virtual ~SpecificAllocBase() = default; 410b57cec5SDimitry Andric virtual void reset() = 0; 420b57cec5SDimitry Andric static std::vector<SpecificAllocBase *> instances; 430b57cec5SDimitry Andric }; 440b57cec5SDimitry Andric 450b57cec5SDimitry Andric template <class T> struct SpecificAlloc : public SpecificAllocBase { 460b57cec5SDimitry Andric void reset() override { alloc.DestroyAll(); } 470b57cec5SDimitry Andric llvm::SpecificBumpPtrAllocator<T> alloc; 480b57cec5SDimitry Andric }; 490b57cec5SDimitry Andric 505ffd83dbSDimitry Andric // Use a static local for these singletons so they are only registered if an 515ffd83dbSDimitry Andric // object of this instance is ever constructed. Otherwise we will create and 525ffd83dbSDimitry Andric // register ELF allocators for COFF and the reverse. 535ffd83dbSDimitry Andric template <typename T> 545ffd83dbSDimitry Andric inline llvm::SpecificBumpPtrAllocator<T> &getSpecificAllocSingleton() { 555ffd83dbSDimitry Andric static SpecificAlloc<T> instance; 565ffd83dbSDimitry Andric return instance.alloc; 575ffd83dbSDimitry Andric } 585ffd83dbSDimitry Andric 590b57cec5SDimitry Andric // Use this arena if your object has a destructor. 600b57cec5SDimitry Andric // Your destructor will be invoked from freeArena(). 610b57cec5SDimitry Andric template <typename T, typename... U> T *make(U &&... args) { 625ffd83dbSDimitry Andric return new (getSpecificAllocSingleton<T>().Allocate()) 635ffd83dbSDimitry Andric T(std::forward<U>(args)...); 640b57cec5SDimitry Andric } 650b57cec5SDimitry Andric 660b57cec5SDimitry Andric } // namespace lld 670b57cec5SDimitry Andric 680b57cec5SDimitry Andric #endif 69