|
|
|||
File indexing completed on 2026-05-10 08:42:41
0001 //===- Memory.h -------------------------------------------------*- C++ -*-===// 0002 // 0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 0004 // See https://llvm.org/LICENSE.txt for license information. 0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 0006 // 0007 //===----------------------------------------------------------------------===// 0008 // 0009 // This file defines arena allocators. 0010 // 0011 // Almost all large objects, such as files, sections or symbols, are 0012 // used for the entire lifetime of the linker once they are created. 0013 // This usage characteristic makes arena allocator an attractive choice 0014 // where the entire linker is one arena. With an arena, newly created 0015 // objects belong to the arena and freed all at once when everything is done. 0016 // Arena allocators are efficient and easy to understand. 0017 // Most objects are allocated using the arena allocators defined by this file. 0018 // 0019 //===----------------------------------------------------------------------===// 0020 0021 #ifndef LLD_COMMON_MEMORY_H 0022 #define LLD_COMMON_MEMORY_H 0023 0024 #include "llvm/Support/Allocator.h" 0025 0026 namespace lld { 0027 // A base class only used by the CommonLinkerContext to keep track of the 0028 // SpecificAlloc<> instances. 0029 struct SpecificAllocBase { 0030 virtual ~SpecificAllocBase() = default; 0031 static SpecificAllocBase *getOrCreate(void *tag, size_t size, size_t align, 0032 SpecificAllocBase *(&creator)(void *)); 0033 }; 0034 0035 // An arena of specific types T, created on-demand. 0036 template <class T> struct SpecificAlloc : public SpecificAllocBase { 0037 static SpecificAllocBase *create(void *storage) { 0038 return new (storage) SpecificAlloc<T>(); 0039 } 0040 llvm::SpecificBumpPtrAllocator<T> alloc; 0041 static int tag; 0042 }; 0043 0044 // The address of this static member is only used as a key in 0045 // CommonLinkerContext::instances. Its value does not matter. 0046 template <class T> int SpecificAlloc<T>::tag = 0; 0047 0048 // Creates the arena on-demand on the first call; or returns it, if it was 0049 // already created. 0050 template <typename T> 0051 inline llvm::SpecificBumpPtrAllocator<T> &getSpecificAllocSingleton() { 0052 SpecificAllocBase *instance = SpecificAllocBase::getOrCreate( 0053 &SpecificAlloc<T>::tag, sizeof(SpecificAlloc<T>), 0054 alignof(SpecificAlloc<T>), SpecificAlloc<T>::create); 0055 return ((SpecificAlloc<T> *)instance)->alloc; 0056 } 0057 0058 // Creates new instances of T off a (almost) contiguous arena/object pool. The 0059 // instances are destroyed whenever lldMain() goes out of scope. 0060 template <typename T, typename... U> T *make(U &&... args) { 0061 return new (getSpecificAllocSingleton<T>().Allocate()) 0062 T(std::forward<U>(args)...); 0063 } 0064 0065 template <typename T> 0066 inline llvm::SpecificBumpPtrAllocator<T> & 0067 getSpecificAllocSingletonThreadLocal() { 0068 thread_local SpecificAlloc<T> instance; 0069 return instance.alloc; 0070 } 0071 0072 // Create a new instance of T off a thread-local SpecificAlloc, used by code 0073 // like parallel input section initialization. The use cases assume that the 0074 // return value outlives the containing parallelForEach (if exists), which is 0075 // currently guaranteed: when parallelForEach returns, the threads allocating 0076 // the TLS are not destroyed. 0077 // 0078 // Note: Some ports (e.g. ELF) have lots of global states which are currently 0079 // infeasible to remove, and context() just adds overhead with no benefit. The 0080 // allocation performance is of higher importance, so we simply use thread_local 0081 // allocators instead of doing context indirection and pthread_getspecific. 0082 template <typename T, typename... U> T *makeThreadLocal(U &&...args) { 0083 return new (getSpecificAllocSingletonThreadLocal<T>().Allocate()) 0084 T(std::forward<U>(args)...); 0085 } 0086 0087 template <typename T> T *makeThreadLocalN(size_t n) { 0088 return new (getSpecificAllocSingletonThreadLocal<T>().Allocate(n)) T[n]; 0089 } 0090 0091 } // namespace lld 0092 0093 #endif
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|