bolt/deps/llvm-18.1.8/llvm/unittests/ExecutionEngine/JITLink/JITLinkMocks.h
2025-02-14 19:21:04 +01:00

228 lines
7.4 KiB
C++

//===----- JITLinkMocks.h - Mock APIs for JITLink unit tests ----*- 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
//
//===----------------------------------------------------------------------===//
//
// Mock APIs for JITLink unit tests.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_UNITTESTS_EXECUTIONENGINE_JITLINK_JITLINKMOCKS_H
#define LLVM_UNITTESTS_EXECUTIONENGINE_JITLINK_JITLINKMOCKS_H
#include "llvm/ExecutionEngine/JITLink/JITLink.h"
class MockJITLinkMemoryManager : public llvm::jitlink::JITLinkMemoryManager {
public:
class Alloc {
public:
virtual ~Alloc() {}
};
class SimpleAlloc : public Alloc {
public:
SimpleAlloc(const llvm::jitlink::JITLinkDylib *JD,
llvm::jitlink::LinkGraph &G) {
for (auto *B : G.blocks())
(void)B->getMutableContent(G);
}
};
class MockInFlightAlloc : public InFlightAlloc {
public:
MockInFlightAlloc(MockJITLinkMemoryManager &MJMM, std::unique_ptr<Alloc> A)
: MJMM(MJMM), A(std::move(A)) {}
void abandon(OnAbandonedFunction OnAbandoned) override {
OnAbandoned(MJMM.Abandon(std::move(A)));
}
void finalize(OnFinalizedFunction OnFinalized) override {
OnFinalized(MJMM.Finalize(std::move(A)));
}
private:
MockJITLinkMemoryManager &MJMM;
std::unique_ptr<Alloc> A;
};
MockJITLinkMemoryManager() {
Allocate = [this](const llvm::jitlink::JITLinkDylib *JD,
llvm::jitlink::LinkGraph &G) {
return defaultAllocate(JD, G);
};
Deallocate = [this](std::vector<FinalizedAlloc> Allocs) {
return defaultDeallocate(std::move(Allocs));
};
Abandon = [this](std::unique_ptr<Alloc> A) {
return defaultAbandon(std::move(A));
};
Finalize = [this](std::unique_ptr<Alloc> A) {
return defaultFinalize(std::move(A));
};
}
void allocate(const llvm::jitlink::JITLinkDylib *JD,
llvm::jitlink::LinkGraph &G,
OnAllocatedFunction OnAllocated) override {
auto A = Allocate(JD, G);
if (!A)
OnAllocated(A.takeError());
else
OnAllocated(std::make_unique<MockInFlightAlloc>(*this, std::move(*A)));
}
void deallocate(std::vector<FinalizedAlloc> Allocs,
OnDeallocatedFunction OnDeallocated) override {
OnDeallocated(Deallocate(std::move(Allocs)));
}
using JITLinkMemoryManager::allocate;
using JITLinkMemoryManager::deallocate;
llvm::Expected<std::unique_ptr<Alloc>>
defaultAllocate(const llvm::jitlink::JITLinkDylib *JD,
llvm::jitlink::LinkGraph &G) {
return std::make_unique<SimpleAlloc>(JD, G);
}
llvm::Error defaultDeallocate(std::vector<FinalizedAlloc> Allocs) {
for (auto &A : Allocs)
delete A.release().toPtr<Alloc *>();
return llvm::Error::success();
}
llvm::Error defaultAbandon(std::unique_ptr<Alloc> A) {
return llvm::Error::success();
}
llvm::Expected<FinalizedAlloc> defaultFinalize(std::unique_ptr<Alloc> A) {
return FinalizedAlloc(llvm::orc::ExecutorAddr::fromPtr(A.release()));
}
llvm::unique_function<llvm::Expected<std::unique_ptr<Alloc>>(
const llvm::jitlink::JITLinkDylib *, llvm::jitlink::LinkGraph &)>
Allocate;
llvm::unique_function<llvm::Error(std::vector<FinalizedAlloc>)> Deallocate;
llvm::unique_function<llvm::Error(std::unique_ptr<Alloc>)> Abandon;
llvm::unique_function<llvm::Expected<FinalizedAlloc>(std::unique_ptr<Alloc>)>
Finalize;
};
void lookupResolveEverythingToNull(
const llvm::jitlink::JITLinkContext::LookupMap &Symbols,
std::unique_ptr<llvm::jitlink::JITLinkAsyncLookupContinuation> LC);
void lookupErrorOut(
const llvm::jitlink::JITLinkContext::LookupMap &Symbols,
std::unique_ptr<llvm::jitlink::JITLinkAsyncLookupContinuation> LC);
class MockJITLinkContext : public llvm::jitlink::JITLinkContext {
public:
using HandleFailedFn = llvm::unique_function<void(llvm::Error)>;
MockJITLinkContext(std::unique_ptr<MockJITLinkMemoryManager> MJMM,
HandleFailedFn HandleFailed)
: JITLinkContext(&JD), MJMM(std::move(MJMM)),
HandleFailed(std::move(HandleFailed)) {}
~MockJITLinkContext() {
if (auto Err = MJMM->deallocate(std::move(FinalizedAllocs)))
notifyFailed(std::move(Err));
}
llvm::jitlink::JITLinkMemoryManager &getMemoryManager() override {
return *MJMM;
}
void notifyFailed(llvm::Error Err) override { HandleFailed(std::move(Err)); }
void lookup(const LookupMap &Symbols,
std::unique_ptr<llvm::jitlink::JITLinkAsyncLookupContinuation> LC)
override {
Lookup(Symbols, std::move(LC));
}
llvm::Error notifyResolved(llvm::jitlink::LinkGraph &G) override {
return NotifyResolved ? NotifyResolved(G) : llvm::Error::success();
}
void notifyFinalized(
llvm::jitlink::JITLinkMemoryManager::FinalizedAlloc Alloc) override {
if (NotifyFinalized)
NotifyFinalized(std::move(Alloc));
else
FinalizedAllocs.push_back(std::move(Alloc));
}
bool shouldAddDefaultTargetPasses(const llvm::Triple &TT) const override {
return true;
}
llvm::jitlink::LinkGraphPassFunction
getMarkLivePass(const llvm::Triple &TT) const override {
return MarkLivePass ? llvm::jitlink::LinkGraphPassFunction(
[this](llvm::jitlink::LinkGraph &G) {
return MarkLivePass(G);
})
: llvm::jitlink::LinkGraphPassFunction(
[](llvm::jitlink::LinkGraph &G) {
return markAllSymbolsLive(G);
});
}
llvm::Error
modifyPassConfig(llvm::jitlink::LinkGraph &G,
llvm::jitlink::PassConfiguration &Config) override {
if (ModifyPassConfig)
return ModifyPassConfig(G, Config);
return llvm::Error::success();
}
llvm::jitlink::JITLinkDylib JD{"JD"};
std::unique_ptr<MockJITLinkMemoryManager> MJMM;
HandleFailedFn HandleFailed;
llvm::unique_function<void(
const LookupMap &,
std::unique_ptr<llvm::jitlink::JITLinkAsyncLookupContinuation>)>
Lookup;
llvm::unique_function<llvm::Error(llvm::jitlink::LinkGraph &)> NotifyResolved;
llvm::unique_function<void(
llvm::jitlink::JITLinkMemoryManager::FinalizedAlloc)>
NotifyFinalized;
mutable llvm::unique_function<llvm::Error(llvm::jitlink::LinkGraph &)>
MarkLivePass;
llvm::unique_function<llvm::Error(llvm::jitlink::LinkGraph &,
llvm::jitlink::PassConfiguration &)>
ModifyPassConfig;
std::vector<llvm::jitlink::JITLinkMemoryManager::FinalizedAlloc>
FinalizedAllocs;
};
std::unique_ptr<MockJITLinkContext> makeMockContext(
llvm::unique_function<void(llvm::Error)> HandleFailed,
llvm::unique_function<void(MockJITLinkMemoryManager &)> SetupMemMgr,
llvm::unique_function<void(MockJITLinkContext &)> SetupContext);
void defaultMemMgrSetup(MockJITLinkMemoryManager &);
void defaultCtxSetup(MockJITLinkContext &);
class JoinErrorsInto {
public:
JoinErrorsInto(llvm::Error &Err) : Err(Err) {}
void operator()(llvm::Error E2) {
Err = llvm::joinErrors(std::move(Err), std::move(E2));
}
private:
llvm::Error &Err;
};
#endif // LLVM_UNITTESTS_EXECUTIONENGINE_JITLINK_JITLINKMOCKS_H