blob: f516a327cfb2b6bc23c91c5ba851903758c8481f [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===- Memory.h -------------------------------------------------*- C++ -*-===//
2//
Andrew Walbran16937d02019-10-22 13:54:20 +01003// 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 Scull5e1ddfa2018-08-14 10:06:54 +01006//
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.
Andrew Walbran3d2c1972020-04-07 12:24:26 +010031extern llvm::BumpPtrAllocator bAlloc;
32extern llvm::StringSaver saver;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010033
34void freeArena();
35
36// These two classes are hack to keep track of all
37// SpecificBumpPtrAllocator instances.
38struct SpecificAllocBase {
Andrew Walbran3d2c1972020-04-07 12:24:26 +010039 SpecificAllocBase() { instances.push_back(this); }
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010040 virtual ~SpecificAllocBase() = default;
41 virtual void reset() = 0;
Andrew Walbran3d2c1972020-04-07 12:24:26 +010042 static std::vector<SpecificAllocBase *> instances;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010043};
44
45template <class T> struct SpecificAlloc : public SpecificAllocBase {
Andrew Walbran3d2c1972020-04-07 12:24:26 +010046 void reset() override { alloc.DestroyAll(); }
47 llvm::SpecificBumpPtrAllocator<T> alloc;
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010048};
49
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020050// 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
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010059// Use this arena if your object has a destructor.
60// Your destructor will be invoked from freeArena().
Andrew Walbran3d2c1972020-04-07 12:24:26 +010061template <typename T, typename... U> T *make(U &&... args) {
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020062 return new (getSpecificAllocSingleton<T>().Allocate())
63 T(std::forward<U>(args)...);
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010064}
65
66} // namespace lld
67
68#endif