clang  20.0.0git
DynamicAllocator.h
Go to the documentation of this file.
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  struct Allocation {
35  std::unique_ptr<std::byte[]> Memory;
36  Allocation(std::unique_ptr<std::byte[]> Memory)
37  : Memory(std::move(Memory)) {}
38  };
39 
40  struct AllocationSite {
42  bool IsArrayAllocation = false;
43 
44  AllocationSite(std::unique_ptr<std::byte[]> Memory, bool Array)
45  : IsArrayAllocation(Array) {
46  Allocations.push_back({std::move(Memory)});
47  }
48 
49  size_t size() const { return Allocations.size(); }
50  };
51 
52 public:
53  DynamicAllocator() = default;
55 
56  void cleanup();
57 
58  unsigned getNumAllocations() const { return AllocationSites.size(); }
59 
60  /// Allocate ONE element of the given descriptor.
61  Block *allocate(const Descriptor *D, unsigned EvalID);
62  /// Allocate \p NumElements primitive elements of the given type.
63  Block *allocate(const Expr *Source, PrimType T, size_t NumElements,
64  unsigned EvalID);
65  /// Allocate \p NumElements elements of the given descriptor.
66  Block *allocate(const Descriptor *D, size_t NumElements, unsigned EvalID);
67 
68  /// Deallocate the given source+block combination.
69  /// Returns \c true if anything has been deallocatd, \c false otherwise.
70  bool deallocate(const Expr *Source, const Block *BlockToDelete,
71  InterpState &S);
72 
73  /// Checks whether the allocation done at the given source is an array
74  /// allocation.
75  bool isArrayAllocation(const Expr *Source) const {
76  if (auto It = AllocationSites.find(Source); It != AllocationSites.end())
77  return It->second.IsArrayAllocation;
78  return false;
79  }
80 
81  /// Allocation site iterator.
83  llvm::DenseMap<const Expr *, AllocationSite>::const_iterator;
84  llvm::iterator_range<const_virtual_iter> allocation_sites() const {
85  return llvm::make_range(AllocationSites.begin(), AllocationSites.end());
86  }
87 
88 private:
89  llvm::DenseMap<const Expr *, AllocationSite> AllocationSites;
90 
91  using PoolAllocTy = llvm::BumpPtrAllocatorImpl<llvm::MallocAllocator>;
92  PoolAllocTy DescAllocator;
93 
94  /// Allocates a new descriptor.
95  template <typename... Ts> Descriptor *allocateDescriptor(Ts &&...Args) {
96  return new (DescAllocator) Descriptor(std::forward<Ts>(Args)...);
97  }
98 };
99 
100 } // namespace interp
101 } // namespace clang
102 #endif
const Decl * D
const CFGBlock * Block
Definition: HTMLLogger.cpp:153
This represents one expression.
Definition: Expr.h:110
A memory block, either on the stack or in the heap.
Definition: InterpBlock.h:49
Manages dynamic memory allocations done during bytecode interpretation.
bool deallocate(const Expr *Source, const Block *BlockToDelete, InterpState &S)
Deallocate the given source+block combination.
bool isArrayAllocation(const Expr *Source) const
Checks whether the allocation done at the given source is an array allocation.
Block * allocate(const Descriptor *D, unsigned EvalID)
Allocate ONE element of the given descriptor.
llvm::iterator_range< const_virtual_iter > allocation_sites() const
llvm::DenseMap< const Expr *, AllocationSite >::const_iterator const_virtual_iter
Allocation site iterator.
Interpreter context.
Definition: InterpState.h:36
PrimType
Enumeration of the primitive types of the VM.
Definition: PrimType.h:33
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T
Describes a memory block created by an allocation site.
Definition: Descriptor.h:111