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 26 namespace lld { 27 // A base class only used by the CommonLinkerContext to keep track of the 28 // SpecificAlloc<> instances. 29 struct SpecificAllocBase { 30 virtual ~SpecificAllocBase() = default; 31 static SpecificAllocBase *getOrCreate(void *tag, size_t size, size_t align, 32 SpecificAllocBase *(&creator)(void *)); 33 }; 34 35 // An arena of specific types T, created on-demand. 36 template <class T> struct SpecificAlloc : public SpecificAllocBase { 37 static SpecificAllocBase *create(void *storage) { 38 return new (storage) SpecificAlloc<T>(); 39 } 40 llvm::SpecificBumpPtrAllocator<T> alloc; 41 static int tag; 42 }; 43 44 // The address of this static member is only used as a key in 45 // CommonLinkerContext::instances. Its value does not matter. 46 template <class T> int SpecificAlloc<T>::tag = 0; 47 48 // Creates the arena on-demand on the first call; or returns it, if it was 49 // already created. 50 template <typename T> 51 inline llvm::SpecificBumpPtrAllocator<T> &getSpecificAllocSingleton() { 52 SpecificAllocBase *instance = SpecificAllocBase::getOrCreate( 53 &SpecificAlloc<T>::tag, sizeof(SpecificAlloc<T>), 54 alignof(SpecificAlloc<T>), SpecificAlloc<T>::create); 55 return ((SpecificAlloc<T> *)instance)->alloc; 56 } 57 58 // Creates new instances of T off a (almost) contiguous arena/object pool. The 59 // instances are destroyed whenever lldMain() goes out of scope. 60 template <typename T, typename... U> T *make(U &&... args) { 61 return new (getSpecificAllocSingleton<T>().Allocate()) 62 T(std::forward<U>(args)...); 63 } 64 65 } // namespace lld 66 67 #endif 68