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
28namespace lld {
29
30// Use this arena if your object doesn't have a destructor.
31extern llvm::BumpPtrAllocator bAlloc;
32extern llvm::StringSaver saver;
33
34void freeArena();
35
36// These two classes are hack to keep track of all
37// SpecificBumpPtrAllocator instances.
38struct SpecificAllocBase {
39 SpecificAllocBase() { instances.push_back(this); }
40 virtual ~SpecificAllocBase() = default;
41 virtual void reset() = 0;
42 static std::vector<SpecificAllocBase *> instances;
43};
44
45template <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.
53template <typename T>
54inline 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().
61template <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