Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 1 | //===- Memory.h -------------------------------------------------*- C++ -*-===// |
| 2 | // |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame] | 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 |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 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 this arena if your object has a destructor. |
| 51 | // Your destructor will be invoked from freeArena(). |
| 52 | template <typename T, typename... U> T *make(U &&... Args) { |
| 53 | static SpecificAlloc<T> Alloc; |
| 54 | return new (Alloc.Alloc.Allocate()) T(std::forward<U>(Args)...); |
| 55 | } |
| 56 | |
| 57 | } // namespace lld |
| 58 | |
| 59 | #endif |