Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame^] | 1 | //===- Memory.h -------------------------------------------------*- C++ -*-===// |
| 2 | // |
| 3 | // The LLVM Linker |
| 4 | // |
| 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | // |
| 10 | // This file defines arena allocators. |
| 11 | // |
| 12 | // Almost all large objects, such as files, sections or symbols, are |
| 13 | // used for the entire lifetime of the linker once they are created. |
| 14 | // This usage characteristic makes arena allocator an attractive choice |
| 15 | // where the entire linker is one arena. With an arena, newly created |
| 16 | // objects belong to the arena and freed all at once when everything is done. |
| 17 | // Arena allocators are efficient and easy to understand. |
| 18 | // Most objects are allocated using the arena allocators defined by this file. |
| 19 | // |
| 20 | //===----------------------------------------------------------------------===// |
| 21 | |
| 22 | #ifndef LLD_COMMON_MEMORY_H |
| 23 | #define LLD_COMMON_MEMORY_H |
| 24 | |
| 25 | #include "llvm/Support/Allocator.h" |
| 26 | #include "llvm/Support/StringSaver.h" |
| 27 | #include <vector> |
| 28 | |
| 29 | namespace lld { |
| 30 | |
| 31 | // Use this arena if your object doesn't have a destructor. |
| 32 | extern llvm::BumpPtrAllocator BAlloc; |
| 33 | extern llvm::StringSaver Saver; |
| 34 | |
| 35 | void freeArena(); |
| 36 | |
| 37 | // These two classes are hack to keep track of all |
| 38 | // SpecificBumpPtrAllocator instances. |
| 39 | struct SpecificAllocBase { |
| 40 | SpecificAllocBase() { Instances.push_back(this); } |
| 41 | virtual ~SpecificAllocBase() = default; |
| 42 | virtual void reset() = 0; |
| 43 | static std::vector<SpecificAllocBase *> Instances; |
| 44 | }; |
| 45 | |
| 46 | template <class T> struct SpecificAlloc : public SpecificAllocBase { |
| 47 | void reset() override { Alloc.DestroyAll(); } |
| 48 | llvm::SpecificBumpPtrAllocator<T> Alloc; |
| 49 | }; |
| 50 | |
| 51 | // Use this arena if your object has a destructor. |
| 52 | // Your destructor will be invoked from freeArena(). |
| 53 | template <typename T, typename... U> T *make(U &&... Args) { |
| 54 | static SpecificAlloc<T> Alloc; |
| 55 | return new (Alloc.Alloc.Allocate()) T(std::forward<U>(Args)...); |
| 56 | } |
| 57 | |
| 58 | } // namespace lld |
| 59 | |
| 60 | #endif |