//==-------- DynamicAllocator.cpp - Dynamic allocations ----------*- C++ -*-==//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "DynamicAllocator.h"
#include "InterpBlock.h"
#include "InterpState.h"

using namespace clang;
using namespace clang::interp;

DynamicAllocator::~DynamicAllocator() { cleanup(); }

void DynamicAllocator::cleanup() {
  // Invoke destructors of all the blocks and as a last restort,
  // reset all the pointers pointing to them to null pointees.
  // This should never show up in diagnostics, but it's necessary
  // for us to not cause use-after-free problems.
  for (auto &Iter : AllocationSites) {
    auto &AllocSite = Iter.second;
    for (auto &Alloc : AllocSite.Allocations) {
      Block *B = Alloc.block();
      assert(!B->isDead());
      assert(B->isInitialized());
      B->invokeDtor();

      if (B->hasPointers()) {
        while (B->Pointers) {
          Pointer *Next = B->Pointers->asBlockPointer().Next;
          B->Pointers->BS.Pointee = nullptr;
          B->Pointers = Next;
        }
        B->Pointers = nullptr;
      }
    }
  }

  AllocationSites.clear();
}

Block *DynamicAllocator::allocate(const Expr *Source, PrimType T,
                                  size_t NumElements, unsigned EvalID,
                                  Form AllocForm) {
  // Create a new descriptor for an array of the specified size and
  // element type.
  const Descriptor *D = allocateDescriptor(
      Source, T, Descriptor::InlineDescMD, NumElements, /*IsConst=*/false,
      /*IsTemporary=*/false, /*IsMutable=*/false);

  return allocate(D, EvalID, AllocForm);
}

Block *DynamicAllocator::allocate(const Descriptor *ElementDesc,
                                  size_t NumElements, unsigned EvalID,
                                  Form AllocForm) {
  assert(ElementDesc->getMetadataSize() == 0);
  // Create a new descriptor for an array of the specified size and
  // element type.
  // FIXME: Pass proper element type.
  const Descriptor *D = allocateDescriptor(
      ElementDesc->asExpr(), nullptr, ElementDesc, Descriptor::InlineDescMD,
      NumElements,
      /*IsConst=*/false, /*IsTemporary=*/false, /*IsMutable=*/false);
  return allocate(D, EvalID, AllocForm);
}

Block *DynamicAllocator::allocate(const Descriptor *D, unsigned EvalID,
                                  Form AllocForm) {
  assert(D);
  assert(D->asExpr());

  // Garbage collection. Remove all dead allocations that don't have pointers to
  // them anymore.
  llvm::erase_if(DeadAllocations, [](Allocation &Alloc) -> bool {
    return !Alloc.block()->hasPointers();
  });

  auto Memory =
      std::make_unique<std::byte[]>(sizeof(Block) + D->getAllocSize());
  auto *B = new (Memory.get()) Block(EvalID, D, /*isStatic=*/false);
  B->invokeCtor();

  assert(D->getMetadataSize() == sizeof(InlineDescriptor));
  InlineDescriptor *ID = reinterpret_cast<InlineDescriptor *>(B->rawData());
  ID->Desc = D;
  ID->IsActive = true;
  ID->Offset = sizeof(InlineDescriptor);
  ID->IsBase = false;
  ID->IsFieldMutable = false;
  ID->IsConst = false;
  ID->IsInitialized = false;
  ID->IsVolatile = false;

  if (D->isCompositeArray())
    ID->LifeState = Lifetime::Started;
  else
    ID->LifeState =
        AllocForm == Form::Operator ? Lifetime::Ended : Lifetime::Started;

  if (auto It = AllocationSites.find(D->asExpr());
      It != AllocationSites.end()) {
    It->second.Allocations.emplace_back(std::move(Memory));
    B->setDynAllocId(It->second.NumAllocs);
    ++It->second.NumAllocs;
  } else {
    AllocationSites.insert(
        {D->asExpr(), AllocationSite(std::move(Memory), AllocForm)});
    B->setDynAllocId(0);
  }
  assert(B->isDynamic());
  return B;
}

bool DynamicAllocator::deallocate(const Expr *Source,
                                  const Block *BlockToDelete, InterpState &S) {
  auto It = AllocationSites.find(Source);
  if (It == AllocationSites.end())
    return false;

  auto &Site = It->second;
  assert(!Site.empty());

  // Find the Block to delete.
  auto *AllocIt = llvm::find_if(Site.Allocations, [&](const Allocation &A) {
    return BlockToDelete == A.block();
  });

  assert(AllocIt != Site.Allocations.end());

  Block *B = AllocIt->block();
  assert(B->isInitialized());
  assert(!B->isDead());
  B->invokeDtor();

  // Almost all our dynamic allocations have a pointer pointing to them
  // when we deallocate them, since otherwise we can't call delete() at all.
  // This means that we would usually need to create DeadBlocks for all of them.
  // To work around that, we instead mark them as dead without moving the data
  // over to a DeadBlock and simply keep the block in a separate DeadAllocations
  // list.
  if (B->hasPointers()) {
    B->AccessFlags |= Block::DeadFlag;
    DeadAllocations.push_back(std::move(*AllocIt));
    Site.Allocations.erase(AllocIt);

    if (Site.size() == 0)
      AllocationSites.erase(It);
    return true;
  }

  // Get rid of the allocation altogether.
  Site.Allocations.erase(AllocIt);
  if (Site.empty())
    AllocationSites.erase(It);

  return true;
}
