1 //===- Memory.h -------------------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file defines arena allocators. 10 // 11 // Almost all large objects, such as files, sections or symbols, are 12 // used for the entire lifetime of the linker once they are created. 13 // This usage characteristic makes arena allocator an attractive choice 14 // where the entire linker is one arena. With an arena, newly created 15 // objects belong to the arena and freed all at once when everything is done. 16 // Arena allocators are efficient and easy to understand. 17 // Most objects are allocated using the arena allocators defined by this file. 18 // 19 //===----------------------------------------------------------------------===// 20 21 #ifndef LLD_COMMON_MEMORY_H 22 #define LLD_COMMON_MEMORY_H 23 24 #include "llvm/Support/Allocator.h" 25 #include "llvm/Support/StringSaver.h" 26 #include <vector> 27 28 namespace lld { 29 30 // Use this arena if your object doesn't have a destructor. 31 extern llvm::BumpPtrAllocator bAlloc; 32 extern llvm::StringSaver saver; 33 34 void freeArena(); 35 36 // These two classes are hack to keep track of all 37 // SpecificBumpPtrAllocator instances. 38 struct SpecificAllocBase { SpecificAllocBaseSpecificAllocBase39 SpecificAllocBase() { instances.push_back(this); } 40 virtual ~SpecificAllocBase() = default; 41 virtual void reset() = 0; 42 static std::vector<SpecificAllocBase *> instances; 43 }; 44 45 template <class T> struct SpecificAlloc : public SpecificAllocBase { resetSpecificAlloc46 void reset() override { alloc.DestroyAll(); } 47 llvm::SpecificBumpPtrAllocator<T> alloc; 48 }; 49 50 // Use a static local for these singletons so they are only registered if an 51 // object of this instance is ever constructed. Otherwise we will create and 52 // register ELF allocators for COFF and the reverse. 53 template <typename T> getSpecificAllocSingleton()54inline llvm::SpecificBumpPtrAllocator<T> &getSpecificAllocSingleton() { 55 static SpecificAlloc<T> instance; 56 return instance.alloc; 57 } 58 59 // Use this arena if your object has a destructor. 60 // Your destructor will be invoked from freeArena(). make(U &&...args)61template <typename T, typename... U> T *make(U &&... args) { 62 return new (getSpecificAllocSingleton<T>().Allocate()) 63 T(std::forward<U>(args)...); 64 } 65 66 } // namespace lld 67 68 #endif 69