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/InterpBlock.cpp
213799 views
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 "InterpBlock.h"
14
#include "Pointer.h"
15
16
using namespace clang;
17
using namespace clang::interp;
18
19
void Block::addPointer(Pointer *P) {
20
assert(P);
21
if (IsStatic) {
22
assert(!Pointers);
23
return;
24
}
25
26
#ifndef NDEBUG
27
assert(!hasPointer(P));
28
#endif
29
if (Pointers)
30
Pointers->Prev = P;
31
P->Next = Pointers;
32
P->Prev = nullptr;
33
Pointers = P;
34
#ifndef NDEBUG
35
assert(hasPointer(P));
36
#endif
37
}
38
39
void Block::removePointer(Pointer *P) {
40
assert(P->isBlockPointer());
41
assert(P);
42
if (IsStatic) {
43
assert(!Pointers);
44
return;
45
}
46
47
#ifndef NDEBUG
48
assert(hasPointer(P));
49
#endif
50
51
if (Pointers == P)
52
Pointers = P->Next;
53
54
if (P->Prev)
55
P->Prev->Next = P->Next;
56
if (P->Next)
57
P->Next->Prev = P->Prev;
58
P->PointeeStorage.BS.Pointee = nullptr;
59
#ifndef NDEBUG
60
assert(!hasPointer(P));
61
#endif
62
}
63
64
void Block::cleanup() {
65
if (Pointers == nullptr && IsDead)
66
(reinterpret_cast<DeadBlock *>(this + 1) - 1)->free();
67
}
68
69
void Block::replacePointer(Pointer *Old, Pointer *New) {
70
assert(Old);
71
assert(New);
72
assert(Old != New);
73
if (IsStatic) {
74
assert(!Pointers);
75
return;
76
}
77
#ifndef NDEBUG
78
assert(hasPointer(Old));
79
#endif
80
81
if (Old->Prev)
82
Old->Prev->Next = New;
83
if (Old->Next)
84
Old->Next->Prev = New;
85
New->Prev = Old->Prev;
86
New->Next = Old->Next;
87
if (Pointers == Old)
88
Pointers = New;
89
90
Old->PointeeStorage.BS.Pointee = nullptr;
91
New->PointeeStorage.BS.Pointee = this;
92
#ifndef NDEBUG
93
assert(!hasPointer(Old));
94
assert(hasPointer(New));
95
#endif
96
}
97
98
#ifndef NDEBUG
99
bool Block::hasPointer(const Pointer *P) const {
100
for (const Pointer *C = Pointers; C; C = C->Next) {
101
if (C == P)
102
return true;
103
}
104
return false;
105
}
106
#endif
107
108
DeadBlock::DeadBlock(DeadBlock *&Root, Block *Blk)
109
: Root(Root), B(~0u, Blk->Desc, Blk->IsStatic, Blk->IsExtern, Blk->IsWeak,
110
/*isDead=*/true) {
111
// Add the block to the chain of dead blocks.
112
if (Root)
113
Root->Prev = this;
114
115
Next = Root;
116
Prev = nullptr;
117
Root = this;
118
119
B.IsDynamic = Blk->IsDynamic;
120
121
// Transfer pointers.
122
B.Pointers = Blk->Pointers;
123
for (Pointer *P = Blk->Pointers; P; P = P->Next)
124
P->PointeeStorage.BS.Pointee = &B;
125
Blk->Pointers = nullptr;
126
}
127
128
void DeadBlock::free() {
129
if (B.IsInitialized)
130
B.invokeDtor();
131
132
if (Prev)
133
Prev->Next = Next;
134
if (Next)
135
Next->Prev = Prev;
136
if (Root == this)
137
Root = Next;
138
std::free(this);
139
}
140
141