1*e4df934cSFangrui Song //===--- Block.cpp - Allocated blocks for the interpreter -------*- C++ -*-===//
2*e4df934cSFangrui Song //
3*e4df934cSFangrui Song // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*e4df934cSFangrui Song // See https://llvm.org/LICENSE.txt for license information.
5*e4df934cSFangrui Song // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*e4df934cSFangrui Song //
7*e4df934cSFangrui Song //===----------------------------------------------------------------------===//
8*e4df934cSFangrui Song //
9*e4df934cSFangrui Song // Defines the classes describing allocated blocks.
10*e4df934cSFangrui Song //
11*e4df934cSFangrui Song //===----------------------------------------------------------------------===//
12*e4df934cSFangrui Song 
13*e4df934cSFangrui Song #include "InterpBlock.h"
14*e4df934cSFangrui Song #include "Pointer.h"
15*e4df934cSFangrui Song 
16*e4df934cSFangrui Song using namespace clang;
17*e4df934cSFangrui Song using namespace clang::interp;
18*e4df934cSFangrui Song 
19*e4df934cSFangrui Song 
20*e4df934cSFangrui Song 
addPointer(Pointer * P)21*e4df934cSFangrui Song void Block::addPointer(Pointer *P) {
22*e4df934cSFangrui Song   if (IsStatic)
23*e4df934cSFangrui Song     return;
24*e4df934cSFangrui Song   if (Pointers)
25*e4df934cSFangrui Song     Pointers->Prev = P;
26*e4df934cSFangrui Song   P->Next = Pointers;
27*e4df934cSFangrui Song   P->Prev = nullptr;
28*e4df934cSFangrui Song   Pointers = P;
29*e4df934cSFangrui Song }
30*e4df934cSFangrui Song 
removePointer(Pointer * P)31*e4df934cSFangrui Song void Block::removePointer(Pointer *P) {
32*e4df934cSFangrui Song   if (IsStatic)
33*e4df934cSFangrui Song     return;
34*e4df934cSFangrui Song   if (Pointers == P)
35*e4df934cSFangrui Song     Pointers = P->Next;
36*e4df934cSFangrui Song   if (P->Prev)
37*e4df934cSFangrui Song     P->Prev->Next = P->Next;
38*e4df934cSFangrui Song   if (P->Next)
39*e4df934cSFangrui Song     P->Next->Prev = P->Prev;
40*e4df934cSFangrui Song }
41*e4df934cSFangrui Song 
cleanup()42*e4df934cSFangrui Song void Block::cleanup() {
43*e4df934cSFangrui Song   if (Pointers == nullptr && IsDead)
44*e4df934cSFangrui Song     (reinterpret_cast<DeadBlock *>(this + 1) - 1)->free();
45*e4df934cSFangrui Song }
46*e4df934cSFangrui Song 
movePointer(Pointer * From,Pointer * To)47*e4df934cSFangrui Song void Block::movePointer(Pointer *From, Pointer *To) {
48*e4df934cSFangrui Song   if (IsStatic)
49*e4df934cSFangrui Song     return;
50*e4df934cSFangrui Song   To->Prev = From->Prev;
51*e4df934cSFangrui Song   if (To->Prev)
52*e4df934cSFangrui Song     To->Prev->Next = To;
53*e4df934cSFangrui Song   To->Next = From->Next;
54*e4df934cSFangrui Song   if (To->Next)
55*e4df934cSFangrui Song     To->Next->Prev = To;
56*e4df934cSFangrui Song   if (Pointers == From)
57*e4df934cSFangrui Song     Pointers = To;
58*e4df934cSFangrui Song 
59*e4df934cSFangrui Song   From->Prev = nullptr;
60*e4df934cSFangrui Song   From->Next = nullptr;
61*e4df934cSFangrui Song }
62*e4df934cSFangrui Song 
DeadBlock(DeadBlock * & Root,Block * Blk)63*e4df934cSFangrui Song DeadBlock::DeadBlock(DeadBlock *&Root, Block *Blk)
64*e4df934cSFangrui Song     : Root(Root), B(Blk->Desc, Blk->IsStatic, Blk->IsExtern, /*isDead=*/true) {
65*e4df934cSFangrui Song   // Add the block to the chain of dead blocks.
66*e4df934cSFangrui Song   if (Root)
67*e4df934cSFangrui Song     Root->Prev = this;
68*e4df934cSFangrui Song 
69*e4df934cSFangrui Song   Next = Root;
70*e4df934cSFangrui Song   Prev = nullptr;
71*e4df934cSFangrui Song   Root = this;
72*e4df934cSFangrui Song 
73*e4df934cSFangrui Song   // Transfer pointers.
74*e4df934cSFangrui Song   B.Pointers = Blk->Pointers;
75*e4df934cSFangrui Song   for (Pointer *P = Blk->Pointers; P; P = P->Next)
76*e4df934cSFangrui Song     P->Pointee = &B;
77*e4df934cSFangrui Song }
78*e4df934cSFangrui Song 
free()79*e4df934cSFangrui Song void DeadBlock::free() {
80*e4df934cSFangrui Song   if (Prev)
81*e4df934cSFangrui Song     Prev->Next = Next;
82*e4df934cSFangrui Song   if (Next)
83*e4df934cSFangrui Song     Next->Prev = Prev;
84*e4df934cSFangrui Song   if (Root == this)
85*e4df934cSFangrui Song     Root = Next;
86*e4df934cSFangrui Song   ::free(this);
87*e4df934cSFangrui Song }
88