1a07aba5dSTimm Baeder //===--- Block.cpp - Allocated blocks for the interpreter -------*- C++ -*-===// 2a07aba5dSTimm Baeder // 3a07aba5dSTimm Baeder // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4a07aba5dSTimm Baeder // See https://llvm.org/LICENSE.txt for license information. 5a07aba5dSTimm Baeder // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6a07aba5dSTimm Baeder // 7a07aba5dSTimm Baeder //===----------------------------------------------------------------------===// 8a07aba5dSTimm Baeder // 9a07aba5dSTimm Baeder // Defines the classes describing allocated blocks. 10a07aba5dSTimm Baeder // 11a07aba5dSTimm Baeder //===----------------------------------------------------------------------===// 12a07aba5dSTimm Baeder 13a07aba5dSTimm Baeder #include "InterpBlock.h" 14a07aba5dSTimm Baeder #include "Pointer.h" 15a07aba5dSTimm Baeder 16a07aba5dSTimm Baeder using namespace clang; 17a07aba5dSTimm Baeder using namespace clang::interp; 18a07aba5dSTimm Baeder 19a07aba5dSTimm Baeder void Block::addPointer(Pointer *P) { 20a07aba5dSTimm Baeder assert(P); 21a07aba5dSTimm Baeder if (IsStatic) { 22a07aba5dSTimm Baeder assert(!Pointers); 23a07aba5dSTimm Baeder return; 24a07aba5dSTimm Baeder } 25a07aba5dSTimm Baeder 26a07aba5dSTimm Baeder #ifndef NDEBUG 27a07aba5dSTimm Baeder assert(!hasPointer(P)); 28a07aba5dSTimm Baeder #endif 29a07aba5dSTimm Baeder if (Pointers) 30a07aba5dSTimm Baeder Pointers->Prev = P; 31a07aba5dSTimm Baeder P->Next = Pointers; 32a07aba5dSTimm Baeder P->Prev = nullptr; 33a07aba5dSTimm Baeder Pointers = P; 34a07aba5dSTimm Baeder #ifndef NDEBUG 35a07aba5dSTimm Baeder assert(hasPointer(P)); 36a07aba5dSTimm Baeder #endif 37a07aba5dSTimm Baeder } 38a07aba5dSTimm Baeder 39a07aba5dSTimm Baeder void Block::removePointer(Pointer *P) { 40a07aba5dSTimm Baeder assert(P->isBlockPointer()); 41a07aba5dSTimm Baeder assert(P); 42a07aba5dSTimm Baeder if (IsStatic) { 43a07aba5dSTimm Baeder assert(!Pointers); 44a07aba5dSTimm Baeder return; 45a07aba5dSTimm Baeder } 46a07aba5dSTimm Baeder 47a07aba5dSTimm Baeder #ifndef NDEBUG 48a07aba5dSTimm Baeder assert(hasPointer(P)); 49a07aba5dSTimm Baeder #endif 50a07aba5dSTimm Baeder 51a07aba5dSTimm Baeder if (Pointers == P) 52a07aba5dSTimm Baeder Pointers = P->Next; 53a07aba5dSTimm Baeder 54a07aba5dSTimm Baeder if (P->Prev) 55a07aba5dSTimm Baeder P->Prev->Next = P->Next; 56a07aba5dSTimm Baeder if (P->Next) 57a07aba5dSTimm Baeder P->Next->Prev = P->Prev; 58a07aba5dSTimm Baeder P->PointeeStorage.BS.Pointee = nullptr; 59a07aba5dSTimm Baeder #ifndef NDEBUG 60a07aba5dSTimm Baeder assert(!hasPointer(P)); 61a07aba5dSTimm Baeder #endif 62a07aba5dSTimm Baeder } 63a07aba5dSTimm Baeder 64a07aba5dSTimm Baeder void Block::cleanup() { 65a07aba5dSTimm Baeder if (Pointers == nullptr && IsDead) 66a07aba5dSTimm Baeder (reinterpret_cast<DeadBlock *>(this + 1) - 1)->free(); 67a07aba5dSTimm Baeder } 68a07aba5dSTimm Baeder 69a07aba5dSTimm Baeder void Block::replacePointer(Pointer *Old, Pointer *New) { 70a07aba5dSTimm Baeder assert(Old); 71a07aba5dSTimm Baeder assert(New); 72a07aba5dSTimm Baeder if (IsStatic) { 73a07aba5dSTimm Baeder assert(!Pointers); 74a07aba5dSTimm Baeder return; 75a07aba5dSTimm Baeder } 76a07aba5dSTimm Baeder 77a07aba5dSTimm Baeder #ifndef NDEBUG 78a07aba5dSTimm Baeder assert(hasPointer(Old)); 79a07aba5dSTimm Baeder #endif 80a07aba5dSTimm Baeder 81a07aba5dSTimm Baeder removePointer(Old); 82a07aba5dSTimm Baeder addPointer(New); 83a07aba5dSTimm Baeder 84a07aba5dSTimm Baeder Old->PointeeStorage.BS.Pointee = nullptr; 85a07aba5dSTimm Baeder 86a07aba5dSTimm Baeder #ifndef NDEBUG 87a07aba5dSTimm Baeder assert(!hasPointer(Old)); 88a07aba5dSTimm Baeder assert(hasPointer(New)); 89a07aba5dSTimm Baeder #endif 90a07aba5dSTimm Baeder } 91a07aba5dSTimm Baeder 92a07aba5dSTimm Baeder #ifndef NDEBUG 93a07aba5dSTimm Baeder bool Block::hasPointer(const Pointer *P) const { 94a07aba5dSTimm Baeder for (const Pointer *C = Pointers; C; C = C->Next) { 95a07aba5dSTimm Baeder if (C == P) 96a07aba5dSTimm Baeder return true; 97a07aba5dSTimm Baeder } 98a07aba5dSTimm Baeder return false; 99a07aba5dSTimm Baeder } 100a07aba5dSTimm Baeder #endif 101a07aba5dSTimm Baeder 102a07aba5dSTimm Baeder DeadBlock::DeadBlock(DeadBlock *&Root, Block *Blk) 103*4e5f8a8fSTimm Baeder : Root(Root), B(~0u, Blk->Desc, Blk->IsStatic, Blk->IsExtern, Blk->IsWeak, 104*4e5f8a8fSTimm Baeder /*isDead=*/true) { 105a07aba5dSTimm Baeder // Add the block to the chain of dead blocks. 106a07aba5dSTimm Baeder if (Root) 107a07aba5dSTimm Baeder Root->Prev = this; 108a07aba5dSTimm Baeder 109a07aba5dSTimm Baeder Next = Root; 110a07aba5dSTimm Baeder Prev = nullptr; 111a07aba5dSTimm Baeder Root = this; 112a07aba5dSTimm Baeder 113df11ee21STimm Baeder B.IsDynamic = Blk->IsDynamic; 114df11ee21STimm Baeder 115a07aba5dSTimm Baeder // Transfer pointers. 116a07aba5dSTimm Baeder B.Pointers = Blk->Pointers; 117a07aba5dSTimm Baeder for (Pointer *P = Blk->Pointers; P; P = P->Next) 118a07aba5dSTimm Baeder P->PointeeStorage.BS.Pointee = &B; 119a07aba5dSTimm Baeder Blk->Pointers = nullptr; 120a07aba5dSTimm Baeder } 121a07aba5dSTimm Baeder 122a07aba5dSTimm Baeder void DeadBlock::free() { 123a07aba5dSTimm Baeder if (B.IsInitialized) 124a07aba5dSTimm Baeder B.invokeDtor(); 125a07aba5dSTimm Baeder 126a07aba5dSTimm Baeder if (Prev) 127a07aba5dSTimm Baeder Prev->Next = Next; 128a07aba5dSTimm Baeder if (Next) 129a07aba5dSTimm Baeder Next->Prev = Prev; 130a07aba5dSTimm Baeder if (Root == this) 131a07aba5dSTimm Baeder Root = Next; 132a07aba5dSTimm Baeder std::free(this); 133a07aba5dSTimm Baeder } 134