Path: blob/main/contrib/llvm-project/clang/lib/AST/ByteCode/InterpBlock.cpp
213799 views
//===--- Block.cpp - Allocated blocks for the interpreter -------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// Defines the classes describing allocated blocks.9//10//===----------------------------------------------------------------------===//1112#include "InterpBlock.h"13#include "Pointer.h"1415using namespace clang;16using namespace clang::interp;1718void Block::addPointer(Pointer *P) {19assert(P);20if (IsStatic) {21assert(!Pointers);22return;23}2425#ifndef NDEBUG26assert(!hasPointer(P));27#endif28if (Pointers)29Pointers->Prev = P;30P->Next = Pointers;31P->Prev = nullptr;32Pointers = P;33#ifndef NDEBUG34assert(hasPointer(P));35#endif36}3738void Block::removePointer(Pointer *P) {39assert(P->isBlockPointer());40assert(P);41if (IsStatic) {42assert(!Pointers);43return;44}4546#ifndef NDEBUG47assert(hasPointer(P));48#endif4950if (Pointers == P)51Pointers = P->Next;5253if (P->Prev)54P->Prev->Next = P->Next;55if (P->Next)56P->Next->Prev = P->Prev;57P->PointeeStorage.BS.Pointee = nullptr;58#ifndef NDEBUG59assert(!hasPointer(P));60#endif61}6263void Block::cleanup() {64if (Pointers == nullptr && IsDead)65(reinterpret_cast<DeadBlock *>(this + 1) - 1)->free();66}6768void Block::replacePointer(Pointer *Old, Pointer *New) {69assert(Old);70assert(New);71assert(Old != New);72if (IsStatic) {73assert(!Pointers);74return;75}76#ifndef NDEBUG77assert(hasPointer(Old));78#endif7980if (Old->Prev)81Old->Prev->Next = New;82if (Old->Next)83Old->Next->Prev = New;84New->Prev = Old->Prev;85New->Next = Old->Next;86if (Pointers == Old)87Pointers = New;8889Old->PointeeStorage.BS.Pointee = nullptr;90New->PointeeStorage.BS.Pointee = this;91#ifndef NDEBUG92assert(!hasPointer(Old));93assert(hasPointer(New));94#endif95}9697#ifndef NDEBUG98bool Block::hasPointer(const Pointer *P) const {99for (const Pointer *C = Pointers; C; C = C->Next) {100if (C == P)101return true;102}103return false;104}105#endif106107DeadBlock::DeadBlock(DeadBlock *&Root, Block *Blk)108: Root(Root), B(~0u, Blk->Desc, Blk->IsStatic, Blk->IsExtern, Blk->IsWeak,109/*isDead=*/true) {110// Add the block to the chain of dead blocks.111if (Root)112Root->Prev = this;113114Next = Root;115Prev = nullptr;116Root = this;117118B.IsDynamic = Blk->IsDynamic;119120// Transfer pointers.121B.Pointers = Blk->Pointers;122for (Pointer *P = Blk->Pointers; P; P = P->Next)123P->PointeeStorage.BS.Pointee = &B;124Blk->Pointers = nullptr;125}126127void DeadBlock::free() {128if (B.IsInitialized)129B.invokeDtor();130131if (Prev)132Prev->Next = Next;133if (Next)134Next->Prev = Prev;135if (Root == this)136Root = Next;137std::free(this);138}139140141