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 {
SpecificAllocBaseSpecificAllocBase39   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 {
resetSpecificAlloc46   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>
getSpecificAllocSingleton()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().
make(U &&...args)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