clang 24.0.0git
Block.cpp
Go to the documentation of this file.
1//===--- Block.cpp - Allocated blocks for the interpreter -------*- 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// Defines the classes describing allocated blocks.
10//
11//===----------------------------------------------------------------------===//
12
13#include "Block.h"
14#include "Pointer.h"
15
16using namespace clang;
17using namespace clang::interp;
18
19void Block::addPointer(Pointer *P) {
20 assert(P);
21
22#ifndef NDEBUG
23 assert(!hasPointer(P));
24#endif
25 if (Pointers)
26 Pointers->BS.Prev = P;
27 P->BS.Next = Pointers;
28 P->BS.Prev = nullptr;
29 Pointers = P;
30#ifndef NDEBUG
31 assert(hasPointer(P));
32#endif
33}
34
35void Block::removePointer(Pointer *P) {
36 assert(P->isBlockPointer());
37 assert(P);
38
39#ifndef NDEBUG
40 assert(hasPointer(P));
41#endif
42
43 BlockPointer &BP = P->BS;
44
45 if (Pointers == P)
46 Pointers = BP.Next;
47
48 if (BP.Prev)
49 BP.Prev->BS.Next = BP.Next;
50 if (BP.Next)
51 BP.Next->BS.Prev = BP.Prev;
52 P->BS.Pointee = nullptr;
53#ifndef NDEBUG
54 assert(!hasPointer(P));
55#endif
56}
57
58void Block::cleanup() {
59 if (Pointers == nullptr && !isDynamic() && isDead())
60 (reinterpret_cast<DeadBlock *>(this + 1) - 1)->free();
61}
62
63void Block::replacePointer(Pointer *Old, Pointer *New) {
64 assert(Old);
65 assert(Old->isBlockPointer());
66 assert(New);
67 assert(New->isBlockPointer());
68 assert(Old != New);
69#ifndef NDEBUG
70 assert(hasPointer(Old));
71#endif
72
73 BlockPointer &OldBP = Old->BS;
74 BlockPointer &NewBP = New->BS;
75
76 if (OldBP.Prev)
77 OldBP.Prev->BS.Next = New;
78 if (OldBP.Next)
79 OldBP.Next->BS.Prev = New;
80 NewBP.Prev = OldBP.Prev;
81 NewBP.Next = OldBP.Next;
82 if (Pointers == Old)
83 Pointers = New;
84
85 OldBP.Pointee = nullptr;
86 NewBP.Pointee = this;
87#ifndef NDEBUG
88 assert(!hasPointer(Old));
89 assert(hasPointer(New));
90#endif
91}
92
93#ifndef NDEBUG
94bool Block::hasPointer(const Pointer *P) const {
95 for (const Pointer *C = Pointers; C; C = C->asBlockPointer().Next) {
96 if (C == P)
97 return true;
98 }
99 return false;
100}
101#endif
102
104 assert(B != this);
105
106 while (Pointers) {
107 Pointer *P = Pointers;
108 this->removePointer(P);
109 P->BS.Pointee = B;
110 B->addPointer(P);
111 }
112 assert(!this->hasPointers());
113}
114
116 Pointer *P = Pointers;
117 while (P) {
118 Pointer *Next = P->BS.Next;
119 P->BS.Pointee = nullptr;
120 P->BS.Prev = nullptr;
121 P->BS.Next = nullptr;
122 P = Next;
123 }
124 Pointers = nullptr;
125}
126
128 : Root(Root), B(~0u, Blk->Desc, Blk->Kind, Blk->Flags.withDead()) {
129 // Add the block to the chain of dead blocks.
130 if (Root)
131 Root->Prev = this;
132
133 Next = Root;
134 Prev = nullptr;
135 Root = this;
136
137 B.DynAllocId = Blk->DynAllocId;
138
139 // Transfer pointers.
140 B.Pointers = Blk->Pointers;
141 for (Pointer *P = Blk->Pointers; P; P = P->asBlockPointer().Next)
142 P->BS.Pointee = &B;
143 Blk->Pointers = nullptr;
144}
145
146void DeadBlock::free() {
147 assert(!B.isInitialized());
148
149 if (Prev)
150 Prev->Next = Next;
151 if (Next)
152 Next->Prev = Prev;
153 if (Root == this)
154 Root = Next;
155 std::free(this);
156}
FormatToken * Next
The next token in the unwrapped line.
friend class Pointer
Definition Block.h:192
bool isDead() const
Definition Block.h:117
void movePointersTo(Block *B)
Move all pointers from this block to.
Definition Block.cpp:103
Block(unsigned EvalID, UnsignedOrNone DeclID, const Descriptor *Desc, BlockKind K, BlockFlags Flags=BlockFlags::empty())
Definition Block.h:72
bool isInitialized() const
Returns whether the data of this block has been initialized via invoking the Ctor func.
Definition Block.h:130
bool isDynamic() const
Definition Block.h:111
friend class DeadBlock
Definition Block.h:193
bool hasPointers() const
Checks if the block has any live pointers.
Definition Block.h:105
void removePointers()
Make all pointers that currently point to this block point to nullptr.
Definition Block.cpp:115
friend class Block
Definition Block.h:259
DeadBlock(DeadBlock *&Root, Block *Blk)
Copies the block.
Definition Block.cpp:127
A pointer to a memory block, live or dead.
Definition Pointer.h:547
bool isBlockPointer() const
Definition Pointer.h:873
const BlockPointer & asBlockPointer() const
Definition Pointer.h:848
Top level wrappers for InstallAPI frontend operations.
for(const auto &A :T->param_types())
Pointer * Prev
Previous link in the pointer chain.
Definition Pointer.h:356
Pointer * Next
Next link in the pointer chain.
Definition Pointer.h:358
Block * Pointee
The block the pointer is pointing to.
Definition Pointer.h:352