forked from OSchip/llvm-project
[ORC] Re-apply just the AsynchronousSymbolLookup class from r321838 while I
investigate builder / test failures. llvm-svn: 321910
This commit is contained in:
parent
b96a3a4fe5
commit
1097dc47eb
|
@ -48,7 +48,9 @@ public:
|
|||
Weak = 1U << 1,
|
||||
Common = 1U << 2,
|
||||
Absolute = 1U << 3,
|
||||
Exported = 1U << 4
|
||||
Exported = 1U << 4,
|
||||
NotMaterialized = 1U << 5,
|
||||
Materializing = 1U << 6
|
||||
};
|
||||
|
||||
/// @brief Default-construct a JITSymbolFlags instance.
|
||||
|
@ -67,6 +69,15 @@ public:
|
|||
return (Flags & HasError) == HasError;
|
||||
}
|
||||
|
||||
/// @brief Returns true if this symbol has been fully materialized (i.e. is
|
||||
/// callable).
|
||||
bool isMaterialized() const { return !(Flags & NotMaterialized); }
|
||||
|
||||
/// @brief Returns true if this symbol is in the process of being
|
||||
/// materialized. This is generally only of interest as an
|
||||
/// implementation detail to JIT infrastructure.
|
||||
bool isMaterializing() const { return Flags & Materializing; }
|
||||
|
||||
/// @brief Returns true if the Weak flag is set.
|
||||
bool isWeak() const {
|
||||
return (Flags & Weak) == Weak;
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
//===------ Core.h -- Core ORC APIs (Layer, JITDylib, etc.) -----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Contains core ORC APIs.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_EXECUTIONENGINE_ORC_CORE_H
|
||||
#define LLVM_EXECUTIONENGINE_ORC_CORE_H
|
||||
|
||||
#include "llvm/ExecutionEngine/JITSymbol.h"
|
||||
#include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
namespace llvm {
|
||||
namespace orc {
|
||||
|
||||
/// @brief A set of symbol names (represented by SymbolStringPtrs for
|
||||
// efficiency).
|
||||
using SymbolNameSet = std::set<SymbolStringPtr>;
|
||||
|
||||
/// @brief A map from symbol names (as SymbolStringPtrs) to JITSymbols
|
||||
/// (address/flags pairs).
|
||||
using SymbolMap = std::map<SymbolStringPtr, JITSymbol>;
|
||||
|
||||
/// @brief A symbol query that returns results via a callback when results are
|
||||
/// ready.
|
||||
///
|
||||
/// makes a callback when all symbols are available.
|
||||
class AsynchronousSymbolQuery {
|
||||
public:
|
||||
|
||||
/// @brief Callback to notify client that symbols have been resolved.
|
||||
using SymbolsResolvedCallback = std::function<void(Expected<SymbolMap>)>;
|
||||
|
||||
/// @brief Callback to notify client that symbols are ready for execution.
|
||||
using SymbolsReadyCallback = std::function<void(Error)>;
|
||||
|
||||
/// @brief Create a query for the given symbols, notify-resolved and
|
||||
/// notify-ready callbacks.
|
||||
AsynchronousSymbolQuery(const SymbolNameSet &Symbols,
|
||||
SymbolsResolvedCallback NotifySymbolsResolved,
|
||||
SymbolsReadyCallback NotifySymbolsReady);
|
||||
|
||||
/// @brief Notify client that the query failed.
|
||||
///
|
||||
/// If the notify-resolved callback has not been made yet, then it is called
|
||||
/// with the given error, and the notify-finalized callback is never made.
|
||||
///
|
||||
/// If the notify-resolved callback has already been made then then the
|
||||
/// notify-finalized callback is called with the given error.
|
||||
///
|
||||
/// It is illegal to call setFailed after both callbacks have been made.
|
||||
void setFailed(Error Err);
|
||||
|
||||
/// @brief Set the resolved symbol information for the given symbol name.
|
||||
///
|
||||
/// If this symbol was the last one not resolved, this will trigger a call to
|
||||
/// the notify-finalized callback passing the completed sybol map.
|
||||
void setDefinition(SymbolStringPtr Name, JITSymbol Sym);
|
||||
|
||||
/// @brief Notify the query that a requested symbol is ready for execution.
|
||||
///
|
||||
/// This decrements the query's internal count of not-yet-ready symbols. If
|
||||
/// this call to notifySymbolFinalized sets the counter to zero, it will call
|
||||
/// the notify-finalized callback with Error::success as the value.
|
||||
void notifySymbolFinalized();
|
||||
private:
|
||||
SymbolMap Symbols;
|
||||
size_t OutstandingResolutions = 0;
|
||||
size_t OutstandingFinalizations = 0;
|
||||
SymbolsResolvedCallback NotifySymbolsResolved;
|
||||
SymbolsReadyCallback NotifySymbolsReady;
|
||||
};
|
||||
|
||||
} // End namespace orc
|
||||
} // End namespace llvm
|
||||
|
||||
#endif // LLVM_EXECUTIONENGINE_ORC_CORE_H
|
|
@ -22,7 +22,8 @@ namespace orc {
|
|||
|
||||
enum class OrcErrorCode : int {
|
||||
// RPC Errors
|
||||
JITSymbolNotFound = 1,
|
||||
DuplicateDefinition = 1,
|
||||
JITSymbolNotFound,
|
||||
RemoteAllocatorDoesNotExist,
|
||||
RemoteAllocatorIdAlreadyInUse,
|
||||
RemoteMProtectAddrUnrecognized,
|
||||
|
@ -39,6 +40,18 @@ enum class OrcErrorCode : int {
|
|||
|
||||
std::error_code orcError(OrcErrorCode ErrCode);
|
||||
|
||||
class DuplicateDefinition : public ErrorInfo<DuplicateDefinition> {
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
DuplicateDefinition(std::string SymbolName);
|
||||
std::error_code convertToErrorCode() const override;
|
||||
void log(raw_ostream &OS) const override;
|
||||
const std::string &getSymbolName() const;
|
||||
private:
|
||||
std::string SymbolName;
|
||||
};
|
||||
|
||||
class JITSymbolNotFound : public ErrorInfo<JITSymbolNotFound> {
|
||||
public:
|
||||
static char ID;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
add_llvm_library(LLVMOrcJIT
|
||||
Core.cpp
|
||||
ExecutionUtils.cpp
|
||||
IndirectionUtils.cpp
|
||||
NullResolver.cpp
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
//===--------- Core.cpp - Core ORC APIs (SymbolSource, VSO, etc.) ---------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/ExecutionEngine/Orc/Core.h"
|
||||
#include "llvm/ExecutionEngine/Orc/OrcError.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace orc {
|
||||
|
||||
AsynchronousSymbolQuery::AsynchronousSymbolQuery(
|
||||
const SymbolNameSet &Symbols,
|
||||
SymbolsResolvedCallback NotifySymbolsResolved,
|
||||
SymbolsReadyCallback NotifySymbolsReady)
|
||||
: NotifySymbolsResolved(std::move(NotifySymbolsResolved)),
|
||||
NotifySymbolsReady(std::move(NotifySymbolsReady)) {
|
||||
assert(this->NotifySymbolsResolved &&
|
||||
"Symbols resolved callback must be set");
|
||||
assert(this->NotifySymbolsReady && "Symbols ready callback must be set");
|
||||
OutstandingResolutions = OutstandingFinalizations = Symbols.size();
|
||||
}
|
||||
|
||||
void AsynchronousSymbolQuery::setFailed(Error Err) {
|
||||
OutstandingResolutions = OutstandingFinalizations = 0;
|
||||
if (NotifySymbolsResolved)
|
||||
NotifySymbolsResolved(std::move(Err));
|
||||
else
|
||||
NotifySymbolsReady(std::move(Err));
|
||||
}
|
||||
|
||||
void AsynchronousSymbolQuery::setDefinition(SymbolStringPtr Name,
|
||||
JITSymbol Sym) {
|
||||
// If OutstandingResolutions is zero we must have errored out already. Just
|
||||
// ignore this.
|
||||
if (OutstandingResolutions == 0)
|
||||
return;
|
||||
|
||||
assert(!Symbols.count(Name) &&
|
||||
"Symbol has already been assigned an address");
|
||||
Symbols.insert(std::make_pair(std::move(Name), std::move(Sym)));
|
||||
--OutstandingResolutions;
|
||||
if (OutstandingResolutions == 0) {
|
||||
NotifySymbolsResolved(std::move(Symbols));
|
||||
// Null out NotifySymbolsResolved to indicate that we've already called it.
|
||||
NotifySymbolsResolved = {};
|
||||
}
|
||||
}
|
||||
|
||||
void AsynchronousSymbolQuery::notifySymbolFinalized() {
|
||||
// If OutstandingFinalizations is zero we must have errored out already. Just
|
||||
// ignore this.
|
||||
if (OutstandingFinalizations == 0)
|
||||
return;
|
||||
|
||||
assert(OutstandingFinalizations > 0 && "All symbols already finalized");
|
||||
--OutstandingFinalizations;
|
||||
if (OutstandingFinalizations == 0)
|
||||
NotifySymbolsReady(Error::success());
|
||||
}
|
||||
|
||||
} // End namespace orc.
|
||||
} // End namespace llvm.
|
|
@ -29,6 +29,10 @@ public:
|
|||
|
||||
std::string message(int condition) const override {
|
||||
switch (static_cast<OrcErrorCode>(condition)) {
|
||||
case OrcErrorCode::DuplicateDefinition:
|
||||
return "Duplicate symbol definition";
|
||||
case OrcErrorCode::JITSymbolNotFound:
|
||||
return "JIT symbol not found";
|
||||
case OrcErrorCode::RemoteAllocatorDoesNotExist:
|
||||
return "Remote allocator does not exist";
|
||||
case OrcErrorCode::RemoteAllocatorIdAlreadyInUse:
|
||||
|
@ -45,8 +49,6 @@ public:
|
|||
return "Could not negotiate RPC function";
|
||||
case OrcErrorCode::RPCResponseAbandoned:
|
||||
return "RPC response abandoned";
|
||||
case OrcErrorCode::JITSymbolNotFound:
|
||||
return "JIT symbol not found";
|
||||
case OrcErrorCode::UnexpectedRPCCall:
|
||||
return "Unexpected RPC call";
|
||||
case OrcErrorCode::UnexpectedRPCResponse:
|
||||
|
@ -67,6 +69,7 @@ static ManagedStatic<OrcErrorCategory> OrcErrCat;
|
|||
namespace llvm {
|
||||
namespace orc {
|
||||
|
||||
char DuplicateDefinition::ID = 0;
|
||||
char JITSymbolNotFound::ID = 0;
|
||||
|
||||
std::error_code orcError(OrcErrorCode ErrCode) {
|
||||
|
@ -74,6 +77,22 @@ std::error_code orcError(OrcErrorCode ErrCode) {
|
|||
return std::error_code(static_cast<UT>(ErrCode), *OrcErrCat);
|
||||
}
|
||||
|
||||
|
||||
DuplicateDefinition::DuplicateDefinition(std::string SymbolName)
|
||||
: SymbolName(std::move(SymbolName)) {}
|
||||
|
||||
std::error_code DuplicateDefinition::convertToErrorCode() const {
|
||||
return orcError(OrcErrorCode::DuplicateDefinition);
|
||||
}
|
||||
|
||||
void DuplicateDefinition::log(raw_ostream &OS) const {
|
||||
OS << "Duplicate definition of symbol '" << SymbolName << "'";
|
||||
}
|
||||
|
||||
const std::string &DuplicateDefinition::getSymbolName() const {
|
||||
return SymbolName;
|
||||
}
|
||||
|
||||
JITSymbolNotFound::JITSymbolNotFound(std::string SymbolName)
|
||||
: SymbolName(std::move(SymbolName)) {}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ set(LLVM_LINK_COMPONENTS
|
|||
|
||||
add_llvm_unittest(OrcJITTests
|
||||
CompileOnDemandLayerTest.cpp
|
||||
CoreAPIsTest.cpp
|
||||
IndirectionUtilsTest.cpp
|
||||
GlobalMappingLayerTest.cpp
|
||||
LazyEmittingLayerTest.cpp
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
//===----------- CoreAPIsTest.cpp - Unit tests for Core ORC APIs ----------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/ExecutionEngine/Orc/Core.h"
|
||||
#include "OrcTestCommon.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
using namespace llvm;
|
||||
using namespace llvm::orc;
|
||||
|
||||
namespace {
|
||||
|
||||
TEST(CoreAPIsTest, AsynchronousSymbolQuerySuccessfulResolutionOnly) {
|
||||
SymbolStringPool SP;
|
||||
auto Foo = SP.intern("foo");
|
||||
constexpr JITTargetAddress FakeAddr = 0xdeadbeef;
|
||||
SymbolNameSet Names({Foo});
|
||||
|
||||
bool OnResolutionRun = false;
|
||||
bool OnReadyRun = false;
|
||||
auto OnResolution =
|
||||
[&](Expected<SymbolMap> Result) {
|
||||
EXPECT_TRUE(!!Result) << "Resolution unexpectedly returned error";
|
||||
auto I = Result->find(Foo);
|
||||
EXPECT_NE(I, Result->end()) << "Could not find symbol definition";
|
||||
EXPECT_EQ(cantFail(I->second.getAddress()), FakeAddr)
|
||||
<< "Resolution returned incorrect result";
|
||||
OnResolutionRun = true;
|
||||
};
|
||||
auto OnReady =
|
||||
[&](Error Err) {
|
||||
cantFail(std::move(Err));
|
||||
OnResolutionRun = true;
|
||||
};
|
||||
|
||||
AsynchronousSymbolQuery Q(Names, OnResolution, OnReady);
|
||||
|
||||
Q.setDefinition(Foo, JITSymbol(FakeAddr, JITSymbolFlags::Exported));
|
||||
|
||||
EXPECT_TRUE(OnResolutionRun) << "OnResolutionCallback was not run";
|
||||
EXPECT_FALSE(OnReadyRun) << "OnReady unexpectedly run";
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue