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 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
60