Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/clang/lib/AST/ByteCode/DynamicAllocator.h
213799 views
1
//==--------- DynamicAllocator.h - Dynamic allocations ------------*- 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
#ifndef LLVM_CLANG_AST_INTERP_DYNAMIC_ALLOCATOR_H
10
#define LLVM_CLANG_AST_INTERP_DYNAMIC_ALLOCATOR_H
11
12
#include "Descriptor.h"
13
#include "InterpBlock.h"
14
#include "llvm/ADT/SmallVector.h"
15
#include "llvm/ADT/iterator_range.h"
16
#include "llvm/Support/Allocator.h"
17
18
namespace clang {
19
class Expr;
20
namespace interp {
21
class Block;
22
class InterpState;
23
24
/// Manages dynamic memory allocations done during bytecode interpretation.
25
///
26
/// We manage allocations as a map from their new-expression to a list
27
/// of allocations. This is called an AllocationSite. For each site, we
28
/// record whether it was allocated using new or new[], the
29
/// IsArrayAllocation flag.
30
///
31
/// For all array allocations, we need to allocate new Descriptor instances,
32
/// so the DynamicAllocator has a llvm::BumpPtrAllocator similar to Program.
33
class DynamicAllocator final {
34
public:
35
enum class Form : uint8_t {
36
NonArray,
37
Array,
38
Operator,
39
};
40
41
private:
42
struct Allocation {
43
std::unique_ptr<std::byte[]> Memory;
44
Allocation(std::unique_ptr<std::byte[]> Memory)
45
: Memory(std::move(Memory)) {}
46
};
47
48
struct AllocationSite {
49
llvm::SmallVector<Allocation> Allocations;
50
Form AllocForm;
51
52
AllocationSite(std::unique_ptr<std::byte[]> Memory, Form AllocForm)
53
: AllocForm(AllocForm) {
54
Allocations.push_back({std::move(Memory)});
55
}
56
57
size_t size() const { return Allocations.size(); }
58
};
59
60
public:
61
DynamicAllocator() = default;
62
DynamicAllocator(DynamicAllocator &) = delete;
63
DynamicAllocator(DynamicAllocator &&) = delete;
64
~DynamicAllocator();
65
66
void cleanup();
67
68
unsigned getNumAllocations() const { return AllocationSites.size(); }
69
70
/// Allocate ONE element of the given descriptor.
71
Block *allocate(const Descriptor *D, unsigned EvalID, Form AllocForm);
72
/// Allocate \p NumElements primitive elements of the given type.
73
Block *allocate(const Expr *Source, PrimType T, size_t NumElements,
74
unsigned EvalID, Form AllocForm);
75
/// Allocate \p NumElements elements of the given descriptor.
76
Block *allocate(const Descriptor *D, size_t NumElements, unsigned EvalID,
77
Form AllocForm);
78
79
/// Deallocate the given source+block combination.
80
/// Returns \c true if anything has been deallocatd, \c false otherwise.
81
bool deallocate(const Expr *Source, const Block *BlockToDelete,
82
InterpState &S);
83
84
/// Checks whether the allocation done at the given source is an array
85
/// allocation.
86
std::optional<Form> getAllocationForm(const Expr *Source) const {
87
if (auto It = AllocationSites.find(Source); It != AllocationSites.end())
88
return It->second.AllocForm;
89
return std::nullopt;
90
}
91
92
/// Allocation site iterator.
93
using const_virtual_iter =
94
llvm::DenseMap<const Expr *, AllocationSite>::const_iterator;
95
llvm::iterator_range<const_virtual_iter> allocation_sites() const {
96
return llvm::make_range(AllocationSites.begin(), AllocationSites.end());
97
}
98
99
private:
100
llvm::DenseMap<const Expr *, AllocationSite> AllocationSites;
101
102
using PoolAllocTy = llvm::BumpPtrAllocator;
103
PoolAllocTy DescAllocator;
104
105
/// Allocates a new descriptor.
106
template <typename... Ts> Descriptor *allocateDescriptor(Ts &&...Args) {
107
return new (DescAllocator) Descriptor(std::forward<Ts>(Args)...);
108
}
109
};
110
111
} // namespace interp
112
} // namespace clang
113
#endif
114
115