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 { |
39 | 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 { |
46 | 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> |
54 | inline 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(). |
61 | template <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 | |