2018-05-22 01:45:40 +02:00
|
|
|
//===-- RTDyldObjectLinkingLayer.cpp - RuntimeDyld backed ORC ObjectLayer -===//
|
|
|
|
//
|
2019-01-19 09:50:56 +01:00
|
|
|
// 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
|
2018-05-22 01:45:40 +02:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
|
2020-01-17 23:48:48 +01:00
|
|
|
#include "llvm/Object/COFF.h"
|
2018-05-22 01:45:40 +02:00
|
|
|
|
2018-07-20 20:31:50 +02:00
|
|
|
namespace {
|
|
|
|
|
|
|
|
using namespace llvm;
|
|
|
|
using namespace llvm::orc;
|
|
|
|
|
2018-08-17 23:18:18 +02:00
|
|
|
class JITDylibSearchOrderResolver : public JITSymbolResolver {
|
2018-07-20 20:31:50 +02:00
|
|
|
public:
|
2018-08-17 23:18:18 +02:00
|
|
|
JITDylibSearchOrderResolver(MaterializationResponsibility &MR) : MR(MR) {}
|
2018-07-20 20:31:50 +02:00
|
|
|
|
2020-07-17 05:38:41 +02:00
|
|
|
void lookup(const LookupSet &Symbols, OnResolvedFunction OnResolved) override {
|
2018-08-17 23:18:18 +02:00
|
|
|
auto &ES = MR.getTargetJITDylib().getExecutionSession();
|
2019-11-26 06:57:27 +01:00
|
|
|
SymbolLookupSet InternedSymbols;
|
2018-07-20 20:31:50 +02:00
|
|
|
|
2018-09-25 21:48:46 +02:00
|
|
|
// Intern the requested symbols: lookup takes interned strings.
|
2018-07-20 20:31:50 +02:00
|
|
|
for (auto &S : Symbols)
|
2019-11-26 06:57:27 +01:00
|
|
|
InternedSymbols.add(ES.intern(S));
|
2018-07-20 20:31:50 +02:00
|
|
|
|
2018-09-25 21:48:46 +02:00
|
|
|
// Build an OnResolve callback to unwrap the interned strings and pass them
|
|
|
|
// to the OnResolved callback.
|
|
|
|
auto OnResolvedWithUnwrap =
|
2019-09-13 13:35:33 +02:00
|
|
|
[OnResolved = std::move(OnResolved)](
|
|
|
|
Expected<SymbolMap> InternedResult) mutable {
|
2018-09-25 21:48:46 +02:00
|
|
|
if (!InternedResult) {
|
|
|
|
OnResolved(InternedResult.takeError());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
LookupResult Result;
|
|
|
|
for (auto &KV : *InternedResult)
|
|
|
|
Result[*KV.first] = std::move(KV.second);
|
|
|
|
OnResolved(Result);
|
|
|
|
};
|
|
|
|
|
|
|
|
// Register dependencies for all symbols contained in this set.
|
2018-07-21 00:22:19 +02:00
|
|
|
auto RegisterDependencies = [&](const SymbolDependenceMap &Deps) {
|
2018-07-21 02:12:05 +02:00
|
|
|
MR.addDependenciesForAll(Deps);
|
2018-07-20 20:31:50 +02:00
|
|
|
};
|
|
|
|
|
2020-05-05 01:43:42 +02:00
|
|
|
JITDylibSearchOrder LinkOrder;
|
|
|
|
MR.getTargetJITDylib().withLinkOrderDo(
|
|
|
|
[&](const JITDylibSearchOrder &LO) { LinkOrder = LO; });
|
|
|
|
ES.lookup(LookupKind::Static, LinkOrder, InternedSymbols,
|
2019-11-26 06:57:27 +01:00
|
|
|
SymbolState::Resolved, std::move(OnResolvedWithUnwrap),
|
|
|
|
RegisterDependencies);
|
2018-07-20 20:31:50 +02:00
|
|
|
}
|
|
|
|
|
2020-07-17 05:38:41 +02:00
|
|
|
Expected<LookupSet> getResponsibilitySet(const LookupSet &Symbols) override {
|
2018-08-28 23:18:05 +02:00
|
|
|
LookupSet Result;
|
2018-07-20 20:31:50 +02:00
|
|
|
|
2018-08-28 23:18:05 +02:00
|
|
|
for (auto &KV : MR.getSymbols()) {
|
|
|
|
if (Symbols.count(*KV.first))
|
|
|
|
Result.insert(*KV.first);
|
|
|
|
}
|
2018-07-20 20:31:50 +02:00
|
|
|
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
MaterializationResponsibility &MR;
|
|
|
|
};
|
|
|
|
|
|
|
|
} // end anonymous namespace
|
|
|
|
|
2018-05-22 01:45:40 +02:00
|
|
|
namespace llvm {
|
|
|
|
namespace orc {
|
|
|
|
|
2021-02-26 13:11:57 +01:00
|
|
|
char RTDyldObjectLinkingLayer::ID;
|
|
|
|
|
|
|
|
using BaseT = RTTIExtends<RTDyldObjectLinkingLayer, ObjectLayer>;
|
|
|
|
|
2018-10-16 00:56:10 +02:00
|
|
|
RTDyldObjectLinkingLayer::RTDyldObjectLinkingLayer(
|
2019-05-02 00:40:23 +02:00
|
|
|
ExecutionSession &ES, GetMemoryManagerFunction GetMemoryManager)
|
2021-02-26 13:11:57 +01:00
|
|
|
: BaseT(ES), GetMemoryManager(GetMemoryManager) {
|
[ORC] Add support for resource tracking/removal (removable code).
This patch introduces new APIs to support resource tracking and removal in Orc.
It is intended as a thread-safe generalization of the removeModule concept from
OrcV1.
Clients can now create ResourceTracker objects (using
JITDylib::createResourceTracker) to track resources for each MaterializationUnit
(code, data, aliases, absolute symbols, etc.) added to the JIT. Every
MaterializationUnit will be associated with a ResourceTracker, and
ResourceTrackers can be re-used for multiple MaterializationUnits. Each JITDylib
has a default ResourceTracker that will be used for MaterializationUnits added
to that JITDylib if no ResourceTracker is explicitly specified.
Two operations can be performed on ResourceTrackers: transferTo and remove. The
transferTo operation transfers tracking of the resources to a different
ResourceTracker object, allowing ResourceTrackers to be merged to reduce
administrative overhead (the source tracker is invalidated in the process). The
remove operation removes all resources associated with a ResourceTracker,
including any symbols defined by MaterializationUnits associated with the
tracker, and also invalidates the tracker. These operations are thread safe, and
should work regardless of the the state of the MaterializationUnits. In the case
of resource transfer any existing resources associated with the source tracker
will be transferred to the destination tracker, and all future resources for
those units will be automatically associated with the destination tracker. In
the case of resource removal all already-allocated resources will be
deallocated, any if any program representations associated with the tracker have
not been compiled yet they will be destroyed. If any program representations are
currently being compiled then they will be prevented from completing: their
MaterializationResponsibility will return errors on any attempt to update the
JIT state.
Clients (usually Layer writers) wishing to track resources can implement the
ResourceManager API to receive notifications when ResourceTrackers are
transferred or removed. The MaterializationResponsibility::withResourceKeyDo
method can be used to create associations between the key for a ResourceTracker
and an allocated resource in a thread-safe way.
RTDyldObjectLinkingLayer and ObjectLinkingLayer are updated to use the
ResourceManager API to enable tracking and removal of memory allocated by the
JIT linker.
The new JITDylib::clear method can be used to trigger removal of every
ResourceTracker associated with the JITDylib (note that this will only
remove resources for the JITDylib, it does not run static destructors).
This patch includes unit tests showing basic usage. A follow-up patch will
update the Kaleidoscope and BuildingAJIT tutorial series to OrcV2 and will
use this API to release code associated with anonymous expressions.
2020-09-11 18:50:41 +02:00
|
|
|
ES.registerResourceManager(*this);
|
|
|
|
}
|
2018-05-22 01:45:40 +02:00
|
|
|
|
2019-12-21 06:08:35 +01:00
|
|
|
RTDyldObjectLinkingLayer::~RTDyldObjectLinkingLayer() {
|
[ORC] Add support for resource tracking/removal (removable code).
This patch introduces new APIs to support resource tracking and removal in Orc.
It is intended as a thread-safe generalization of the removeModule concept from
OrcV1.
Clients can now create ResourceTracker objects (using
JITDylib::createResourceTracker) to track resources for each MaterializationUnit
(code, data, aliases, absolute symbols, etc.) added to the JIT. Every
MaterializationUnit will be associated with a ResourceTracker, and
ResourceTrackers can be re-used for multiple MaterializationUnits. Each JITDylib
has a default ResourceTracker that will be used for MaterializationUnits added
to that JITDylib if no ResourceTracker is explicitly specified.
Two operations can be performed on ResourceTrackers: transferTo and remove. The
transferTo operation transfers tracking of the resources to a different
ResourceTracker object, allowing ResourceTrackers to be merged to reduce
administrative overhead (the source tracker is invalidated in the process). The
remove operation removes all resources associated with a ResourceTracker,
including any symbols defined by MaterializationUnits associated with the
tracker, and also invalidates the tracker. These operations are thread safe, and
should work regardless of the the state of the MaterializationUnits. In the case
of resource transfer any existing resources associated with the source tracker
will be transferred to the destination tracker, and all future resources for
those units will be automatically associated with the destination tracker. In
the case of resource removal all already-allocated resources will be
deallocated, any if any program representations associated with the tracker have
not been compiled yet they will be destroyed. If any program representations are
currently being compiled then they will be prevented from completing: their
MaterializationResponsibility will return errors on any attempt to update the
JIT state.
Clients (usually Layer writers) wishing to track resources can implement the
ResourceManager API to receive notifications when ResourceTrackers are
transferred or removed. The MaterializationResponsibility::withResourceKeyDo
method can be used to create associations between the key for a ResourceTracker
and an allocated resource in a thread-safe way.
RTDyldObjectLinkingLayer and ObjectLinkingLayer are updated to use the
ResourceManager API to enable tracking and removal of memory allocated by the
JIT linker.
The new JITDylib::clear method can be used to trigger removal of every
ResourceTracker associated with the JITDylib (note that this will only
remove resources for the JITDylib, it does not run static destructors).
This patch includes unit tests showing basic usage. A follow-up patch will
update the Kaleidoscope and BuildingAJIT tutorial series to OrcV2 and will
use this API to release code associated with anonymous expressions.
2020-09-11 18:50:41 +02:00
|
|
|
assert(MemMgrs.empty() && "Layer destroyed with resources still attached");
|
2019-12-21 06:08:35 +01:00
|
|
|
}
|
|
|
|
|
2020-09-11 18:23:14 +02:00
|
|
|
void RTDyldObjectLinkingLayer::emit(
|
|
|
|
std::unique_ptr<MaterializationResponsibility> R,
|
|
|
|
std::unique_ptr<MemoryBuffer> O) {
|
2018-05-23 23:27:01 +02:00
|
|
|
assert(O && "Object must not be null");
|
2020-02-24 12:10:13 +01:00
|
|
|
|
2018-09-26 00:57:44 +02:00
|
|
|
auto &ES = getExecutionSession();
|
2018-05-22 01:45:40 +02:00
|
|
|
|
2020-03-20 00:14:18 +01:00
|
|
|
auto Obj = object::ObjectFile::createObjectFile(*O);
|
2018-05-22 01:45:40 +02:00
|
|
|
|
2018-09-26 00:57:44 +02:00
|
|
|
if (!Obj) {
|
|
|
|
getExecutionSession().reportError(Obj.takeError());
|
2020-09-11 18:23:14 +02:00
|
|
|
R->failMaterialization();
|
2018-09-26 00:57:44 +02:00
|
|
|
return;
|
2018-05-22 01:45:40 +02:00
|
|
|
}
|
|
|
|
|
2018-09-26 00:57:44 +02:00
|
|
|
// Collect the internal symbols from the object file: We will need to
|
|
|
|
// filter these later.
|
|
|
|
auto InternalSymbols = std::make_shared<std::set<StringRef>>();
|
2018-05-22 01:45:40 +02:00
|
|
|
{
|
2018-09-26 00:57:44 +02:00
|
|
|
for (auto &Sym : (*Obj)->symbols()) {
|
2020-03-04 01:02:46 +01:00
|
|
|
|
|
|
|
// Skip file symbols.
|
|
|
|
if (auto SymType = Sym.getType()) {
|
|
|
|
if (*SymType == object::SymbolRef::ST_File)
|
|
|
|
continue;
|
|
|
|
} else {
|
|
|
|
ES.reportError(SymType.takeError());
|
2020-09-11 18:23:14 +02:00
|
|
|
R->failMaterialization();
|
2020-03-04 01:02:46 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-04-10 14:24:21 +02:00
|
|
|
Expected<uint32_t> SymFlagsOrErr = Sym.getFlags();
|
|
|
|
if (!SymFlagsOrErr) {
|
|
|
|
// TODO: Test this error.
|
|
|
|
ES.reportError(SymFlagsOrErr.takeError());
|
2020-09-11 18:23:14 +02:00
|
|
|
R->failMaterialization();
|
2020-04-10 14:24:21 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-03-04 01:02:46 +01:00
|
|
|
// Don't include symbols that aren't global.
|
2020-04-10 14:24:21 +02:00
|
|
|
if (!(*SymFlagsOrErr & object::BasicSymbolRef::SF_Global)) {
|
2018-06-18 20:01:43 +02:00
|
|
|
if (auto SymName = Sym.getName())
|
2018-09-26 00:57:44 +02:00
|
|
|
InternalSymbols->insert(*SymName);
|
2018-06-18 20:01:43 +02:00
|
|
|
else {
|
|
|
|
ES.reportError(SymName.takeError());
|
2020-09-11 18:23:14 +02:00
|
|
|
R->failMaterialization();
|
2018-06-18 20:01:43 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-09-26 00:57:44 +02:00
|
|
|
}
|
2018-06-18 20:01:43 +02:00
|
|
|
|
[ORC] Add support for resource tracking/removal (removable code).
This patch introduces new APIs to support resource tracking and removal in Orc.
It is intended as a thread-safe generalization of the removeModule concept from
OrcV1.
Clients can now create ResourceTracker objects (using
JITDylib::createResourceTracker) to track resources for each MaterializationUnit
(code, data, aliases, absolute symbols, etc.) added to the JIT. Every
MaterializationUnit will be associated with a ResourceTracker, and
ResourceTrackers can be re-used for multiple MaterializationUnits. Each JITDylib
has a default ResourceTracker that will be used for MaterializationUnits added
to that JITDylib if no ResourceTracker is explicitly specified.
Two operations can be performed on ResourceTrackers: transferTo and remove. The
transferTo operation transfers tracking of the resources to a different
ResourceTracker object, allowing ResourceTrackers to be merged to reduce
administrative overhead (the source tracker is invalidated in the process). The
remove operation removes all resources associated with a ResourceTracker,
including any symbols defined by MaterializationUnits associated with the
tracker, and also invalidates the tracker. These operations are thread safe, and
should work regardless of the the state of the MaterializationUnits. In the case
of resource transfer any existing resources associated with the source tracker
will be transferred to the destination tracker, and all future resources for
those units will be automatically associated with the destination tracker. In
the case of resource removal all already-allocated resources will be
deallocated, any if any program representations associated with the tracker have
not been compiled yet they will be destroyed. If any program representations are
currently being compiled then they will be prevented from completing: their
MaterializationResponsibility will return errors on any attempt to update the
JIT state.
Clients (usually Layer writers) wishing to track resources can implement the
ResourceManager API to receive notifications when ResourceTrackers are
transferred or removed. The MaterializationResponsibility::withResourceKeyDo
method can be used to create associations between the key for a ResourceTracker
and an allocated resource in a thread-safe way.
RTDyldObjectLinkingLayer and ObjectLinkingLayer are updated to use the
ResourceManager API to enable tracking and removal of memory allocated by the
JIT linker.
The new JITDylib::clear method can be used to trigger removal of every
ResourceTracker associated with the JITDylib (note that this will only
remove resources for the JITDylib, it does not run static destructors).
This patch includes unit tests showing basic usage. A follow-up patch will
update the Kaleidoscope and BuildingAJIT tutorial series to OrcV2 and will
use this API to release code associated with anonymous expressions.
2020-09-11 18:50:41 +02:00
|
|
|
auto MemMgr = GetMemoryManager();
|
|
|
|
auto &MemMgrRef = *MemMgr;
|
2018-08-31 02:53:17 +02:00
|
|
|
|
2020-09-11 18:23:14 +02:00
|
|
|
// Switch to shared ownership of MR so that it can be captured by both
|
|
|
|
// lambdas below.
|
|
|
|
std::shared_ptr<MaterializationResponsibility> SharedR(std::move(R));
|
|
|
|
|
2018-09-26 00:57:44 +02:00
|
|
|
JITDylibSearchOrderResolver Resolver(*SharedR);
|
|
|
|
|
|
|
|
jitLinkForORC(
|
2020-03-20 00:14:18 +01:00
|
|
|
object::OwningBinary<object::ObjectFile>(std::move(*Obj), std::move(O)),
|
[ORC] Add support for resource tracking/removal (removable code).
This patch introduces new APIs to support resource tracking and removal in Orc.
It is intended as a thread-safe generalization of the removeModule concept from
OrcV1.
Clients can now create ResourceTracker objects (using
JITDylib::createResourceTracker) to track resources for each MaterializationUnit
(code, data, aliases, absolute symbols, etc.) added to the JIT. Every
MaterializationUnit will be associated with a ResourceTracker, and
ResourceTrackers can be re-used for multiple MaterializationUnits. Each JITDylib
has a default ResourceTracker that will be used for MaterializationUnits added
to that JITDylib if no ResourceTracker is explicitly specified.
Two operations can be performed on ResourceTrackers: transferTo and remove. The
transferTo operation transfers tracking of the resources to a different
ResourceTracker object, allowing ResourceTrackers to be merged to reduce
administrative overhead (the source tracker is invalidated in the process). The
remove operation removes all resources associated with a ResourceTracker,
including any symbols defined by MaterializationUnits associated with the
tracker, and also invalidates the tracker. These operations are thread safe, and
should work regardless of the the state of the MaterializationUnits. In the case
of resource transfer any existing resources associated with the source tracker
will be transferred to the destination tracker, and all future resources for
those units will be automatically associated with the destination tracker. In
the case of resource removal all already-allocated resources will be
deallocated, any if any program representations associated with the tracker have
not been compiled yet they will be destroyed. If any program representations are
currently being compiled then they will be prevented from completing: their
MaterializationResponsibility will return errors on any attempt to update the
JIT state.
Clients (usually Layer writers) wishing to track resources can implement the
ResourceManager API to receive notifications when ResourceTrackers are
transferred or removed. The MaterializationResponsibility::withResourceKeyDo
method can be used to create associations between the key for a ResourceTracker
and an allocated resource in a thread-safe way.
RTDyldObjectLinkingLayer and ObjectLinkingLayer are updated to use the
ResourceManager API to enable tracking and removal of memory allocated by the
JIT linker.
The new JITDylib::clear method can be used to trigger removal of every
ResourceTracker associated with the JITDylib (note that this will only
remove resources for the JITDylib, it does not run static destructors).
This patch includes unit tests showing basic usage. A follow-up patch will
update the Kaleidoscope and BuildingAJIT tutorial series to OrcV2 and will
use this API to release code associated with anonymous expressions.
2020-09-11 18:50:41 +02:00
|
|
|
MemMgrRef, Resolver, ProcessAllSections,
|
|
|
|
[this, SharedR, &MemMgrRef, InternalSymbols](
|
2020-03-20 00:14:18 +01:00
|
|
|
const object::ObjectFile &Obj,
|
[ORC] Add support for resource tracking/removal (removable code).
This patch introduces new APIs to support resource tracking and removal in Orc.
It is intended as a thread-safe generalization of the removeModule concept from
OrcV1.
Clients can now create ResourceTracker objects (using
JITDylib::createResourceTracker) to track resources for each MaterializationUnit
(code, data, aliases, absolute symbols, etc.) added to the JIT. Every
MaterializationUnit will be associated with a ResourceTracker, and
ResourceTrackers can be re-used for multiple MaterializationUnits. Each JITDylib
has a default ResourceTracker that will be used for MaterializationUnits added
to that JITDylib if no ResourceTracker is explicitly specified.
Two operations can be performed on ResourceTrackers: transferTo and remove. The
transferTo operation transfers tracking of the resources to a different
ResourceTracker object, allowing ResourceTrackers to be merged to reduce
administrative overhead (the source tracker is invalidated in the process). The
remove operation removes all resources associated with a ResourceTracker,
including any symbols defined by MaterializationUnits associated with the
tracker, and also invalidates the tracker. These operations are thread safe, and
should work regardless of the the state of the MaterializationUnits. In the case
of resource transfer any existing resources associated with the source tracker
will be transferred to the destination tracker, and all future resources for
those units will be automatically associated with the destination tracker. In
the case of resource removal all already-allocated resources will be
deallocated, any if any program representations associated with the tracker have
not been compiled yet they will be destroyed. If any program representations are
currently being compiled then they will be prevented from completing: their
MaterializationResponsibility will return errors on any attempt to update the
JIT state.
Clients (usually Layer writers) wishing to track resources can implement the
ResourceManager API to receive notifications when ResourceTrackers are
transferred or removed. The MaterializationResponsibility::withResourceKeyDo
method can be used to create associations between the key for a ResourceTracker
and an allocated resource in a thread-safe way.
RTDyldObjectLinkingLayer and ObjectLinkingLayer are updated to use the
ResourceManager API to enable tracking and removal of memory allocated by the
JIT linker.
The new JITDylib::clear method can be used to trigger removal of every
ResourceTracker associated with the JITDylib (note that this will only
remove resources for the JITDylib, it does not run static destructors).
This patch includes unit tests showing basic usage. A follow-up patch will
update the Kaleidoscope and BuildingAJIT tutorial series to OrcV2 and will
use this API to release code associated with anonymous expressions.
2020-09-11 18:50:41 +02:00
|
|
|
RuntimeDyld::LoadedObjectInfo &LoadedObjInfo,
|
2018-09-26 00:57:44 +02:00
|
|
|
std::map<StringRef, JITEvaluatedSymbol> ResolvedSymbols) {
|
[ORC] Add support for resource tracking/removal (removable code).
This patch introduces new APIs to support resource tracking and removal in Orc.
It is intended as a thread-safe generalization of the removeModule concept from
OrcV1.
Clients can now create ResourceTracker objects (using
JITDylib::createResourceTracker) to track resources for each MaterializationUnit
(code, data, aliases, absolute symbols, etc.) added to the JIT. Every
MaterializationUnit will be associated with a ResourceTracker, and
ResourceTrackers can be re-used for multiple MaterializationUnits. Each JITDylib
has a default ResourceTracker that will be used for MaterializationUnits added
to that JITDylib if no ResourceTracker is explicitly specified.
Two operations can be performed on ResourceTrackers: transferTo and remove. The
transferTo operation transfers tracking of the resources to a different
ResourceTracker object, allowing ResourceTrackers to be merged to reduce
administrative overhead (the source tracker is invalidated in the process). The
remove operation removes all resources associated with a ResourceTracker,
including any symbols defined by MaterializationUnits associated with the
tracker, and also invalidates the tracker. These operations are thread safe, and
should work regardless of the the state of the MaterializationUnits. In the case
of resource transfer any existing resources associated with the source tracker
will be transferred to the destination tracker, and all future resources for
those units will be automatically associated with the destination tracker. In
the case of resource removal all already-allocated resources will be
deallocated, any if any program representations associated with the tracker have
not been compiled yet they will be destroyed. If any program representations are
currently being compiled then they will be prevented from completing: their
MaterializationResponsibility will return errors on any attempt to update the
JIT state.
Clients (usually Layer writers) wishing to track resources can implement the
ResourceManager API to receive notifications when ResourceTrackers are
transferred or removed. The MaterializationResponsibility::withResourceKeyDo
method can be used to create associations between the key for a ResourceTracker
and an allocated resource in a thread-safe way.
RTDyldObjectLinkingLayer and ObjectLinkingLayer are updated to use the
ResourceManager API to enable tracking and removal of memory allocated by the
JIT linker.
The new JITDylib::clear method can be used to trigger removal of every
ResourceTracker associated with the JITDylib (note that this will only
remove resources for the JITDylib, it does not run static destructors).
This patch includes unit tests showing basic usage. A follow-up patch will
update the Kaleidoscope and BuildingAJIT tutorial series to OrcV2 and will
use this API to release code associated with anonymous expressions.
2020-09-11 18:50:41 +02:00
|
|
|
return onObjLoad(*SharedR, Obj, MemMgrRef, LoadedObjInfo,
|
2018-09-26 00:57:44 +02:00
|
|
|
ResolvedSymbols, *InternalSymbols);
|
|
|
|
},
|
[ORC] Add support for resource tracking/removal (removable code).
This patch introduces new APIs to support resource tracking and removal in Orc.
It is intended as a thread-safe generalization of the removeModule concept from
OrcV1.
Clients can now create ResourceTracker objects (using
JITDylib::createResourceTracker) to track resources for each MaterializationUnit
(code, data, aliases, absolute symbols, etc.) added to the JIT. Every
MaterializationUnit will be associated with a ResourceTracker, and
ResourceTrackers can be re-used for multiple MaterializationUnits. Each JITDylib
has a default ResourceTracker that will be used for MaterializationUnits added
to that JITDylib if no ResourceTracker is explicitly specified.
Two operations can be performed on ResourceTrackers: transferTo and remove. The
transferTo operation transfers tracking of the resources to a different
ResourceTracker object, allowing ResourceTrackers to be merged to reduce
administrative overhead (the source tracker is invalidated in the process). The
remove operation removes all resources associated with a ResourceTracker,
including any symbols defined by MaterializationUnits associated with the
tracker, and also invalidates the tracker. These operations are thread safe, and
should work regardless of the the state of the MaterializationUnits. In the case
of resource transfer any existing resources associated with the source tracker
will be transferred to the destination tracker, and all future resources for
those units will be automatically associated with the destination tracker. In
the case of resource removal all already-allocated resources will be
deallocated, any if any program representations associated with the tracker have
not been compiled yet they will be destroyed. If any program representations are
currently being compiled then they will be prevented from completing: their
MaterializationResponsibility will return errors on any attempt to update the
JIT state.
Clients (usually Layer writers) wishing to track resources can implement the
ResourceManager API to receive notifications when ResourceTrackers are
transferred or removed. The MaterializationResponsibility::withResourceKeyDo
method can be used to create associations between the key for a ResourceTracker
and an allocated resource in a thread-safe way.
RTDyldObjectLinkingLayer and ObjectLinkingLayer are updated to use the
ResourceManager API to enable tracking and removal of memory allocated by the
JIT linker.
The new JITDylib::clear method can be used to trigger removal of every
ResourceTracker associated with the JITDylib (note that this will only
remove resources for the JITDylib, it does not run static destructors).
This patch includes unit tests showing basic usage. A follow-up patch will
update the Kaleidoscope and BuildingAJIT tutorial series to OrcV2 and will
use this API to release code associated with anonymous expressions.
2020-09-11 18:50:41 +02:00
|
|
|
[this, SharedR, MemMgr = std::move(MemMgr)](
|
|
|
|
object::OwningBinary<object::ObjectFile> Obj,
|
|
|
|
std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo,
|
|
|
|
Error Err) mutable {
|
|
|
|
onObjEmit(*SharedR, std::move(Obj), std::move(MemMgr),
|
|
|
|
std::move(LoadedObjInfo), std::move(Err));
|
2018-09-26 00:57:44 +02:00
|
|
|
});
|
|
|
|
}
|
2018-08-31 02:53:17 +02:00
|
|
|
|
2020-03-20 00:14:18 +01:00
|
|
|
void RTDyldObjectLinkingLayer::registerJITEventListener(JITEventListener &L) {
|
|
|
|
std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
|
2020-12-18 18:09:04 +01:00
|
|
|
assert(!llvm::is_contained(EventListeners, &L) &&
|
2020-03-20 00:14:18 +01:00
|
|
|
"Listener has already been registered");
|
|
|
|
EventListeners.push_back(&L);
|
|
|
|
}
|
|
|
|
|
|
|
|
void RTDyldObjectLinkingLayer::unregisterJITEventListener(JITEventListener &L) {
|
|
|
|
std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
|
|
|
|
auto I = llvm::find(EventListeners, &L);
|
|
|
|
assert(I != EventListeners.end() && "Listener not registered");
|
|
|
|
EventListeners.erase(I);
|
|
|
|
}
|
|
|
|
|
2018-10-16 00:56:10 +02:00
|
|
|
Error RTDyldObjectLinkingLayer::onObjLoad(
|
[ORC] Add support for resource tracking/removal (removable code).
This patch introduces new APIs to support resource tracking and removal in Orc.
It is intended as a thread-safe generalization of the removeModule concept from
OrcV1.
Clients can now create ResourceTracker objects (using
JITDylib::createResourceTracker) to track resources for each MaterializationUnit
(code, data, aliases, absolute symbols, etc.) added to the JIT. Every
MaterializationUnit will be associated with a ResourceTracker, and
ResourceTrackers can be re-used for multiple MaterializationUnits. Each JITDylib
has a default ResourceTracker that will be used for MaterializationUnits added
to that JITDylib if no ResourceTracker is explicitly specified.
Two operations can be performed on ResourceTrackers: transferTo and remove. The
transferTo operation transfers tracking of the resources to a different
ResourceTracker object, allowing ResourceTrackers to be merged to reduce
administrative overhead (the source tracker is invalidated in the process). The
remove operation removes all resources associated with a ResourceTracker,
including any symbols defined by MaterializationUnits associated with the
tracker, and also invalidates the tracker. These operations are thread safe, and
should work regardless of the the state of the MaterializationUnits. In the case
of resource transfer any existing resources associated with the source tracker
will be transferred to the destination tracker, and all future resources for
those units will be automatically associated with the destination tracker. In
the case of resource removal all already-allocated resources will be
deallocated, any if any program representations associated with the tracker have
not been compiled yet they will be destroyed. If any program representations are
currently being compiled then they will be prevented from completing: their
MaterializationResponsibility will return errors on any attempt to update the
JIT state.
Clients (usually Layer writers) wishing to track resources can implement the
ResourceManager API to receive notifications when ResourceTrackers are
transferred or removed. The MaterializationResponsibility::withResourceKeyDo
method can be used to create associations between the key for a ResourceTracker
and an allocated resource in a thread-safe way.
RTDyldObjectLinkingLayer and ObjectLinkingLayer are updated to use the
ResourceManager API to enable tracking and removal of memory allocated by the
JIT linker.
The new JITDylib::clear method can be used to trigger removal of every
ResourceTracker associated with the JITDylib (note that this will only
remove resources for the JITDylib, it does not run static destructors).
This patch includes unit tests showing basic usage. A follow-up patch will
update the Kaleidoscope and BuildingAJIT tutorial series to OrcV2 and will
use this API to release code associated with anonymous expressions.
2020-09-11 18:50:41 +02:00
|
|
|
MaterializationResponsibility &R, const object::ObjectFile &Obj,
|
|
|
|
RuntimeDyld::MemoryManager &MemMgr,
|
|
|
|
RuntimeDyld::LoadedObjectInfo &LoadedObjInfo,
|
2018-09-26 00:57:44 +02:00
|
|
|
std::map<StringRef, JITEvaluatedSymbol> Resolved,
|
|
|
|
std::set<StringRef> &InternalSymbols) {
|
|
|
|
SymbolFlagsMap ExtraSymbolsToClaim;
|
|
|
|
SymbolMap Symbols;
|
2020-01-17 23:48:48 +01:00
|
|
|
|
|
|
|
// Hack to support COFF constant pool comdats introduced during compilation:
|
|
|
|
// (See http://llvm.org/PR40074)
|
|
|
|
if (auto *COFFObj = dyn_cast<object::COFFObjectFile>(&Obj)) {
|
|
|
|
auto &ES = getExecutionSession();
|
|
|
|
|
|
|
|
// For all resolved symbols that are not already in the responsibilty set:
|
|
|
|
// check whether the symbol is in a comdat section and if so mark it as
|
|
|
|
// weak.
|
|
|
|
for (auto &Sym : COFFObj->symbols()) {
|
2020-04-10 14:24:21 +02:00
|
|
|
// getFlags() on COFF symbols can't fail.
|
|
|
|
uint32_t SymFlags = cantFail(Sym.getFlags());
|
|
|
|
if (SymFlags & object::BasicSymbolRef::SF_Undefined)
|
2020-01-17 23:48:48 +01:00
|
|
|
continue;
|
|
|
|
auto Name = Sym.getName();
|
|
|
|
if (!Name)
|
|
|
|
return Name.takeError();
|
|
|
|
auto I = Resolved.find(*Name);
|
|
|
|
|
|
|
|
// Skip unresolved symbols, internal symbols, and symbols that are
|
|
|
|
// already in the responsibility set.
|
|
|
|
if (I == Resolved.end() || InternalSymbols.count(*Name) ||
|
|
|
|
R.getSymbols().count(ES.intern(*Name)))
|
|
|
|
continue;
|
|
|
|
auto Sec = Sym.getSection();
|
|
|
|
if (!Sec)
|
|
|
|
return Sec.takeError();
|
|
|
|
if (*Sec == COFFObj->section_end())
|
|
|
|
continue;
|
|
|
|
auto &COFFSec = *COFFObj->getCOFFSection(**Sec);
|
|
|
|
if (COFFSec.Characteristics & COFF::IMAGE_SCN_LNK_COMDAT)
|
|
|
|
I->second.setFlags(I->second.getFlags() | JITSymbolFlags::Weak);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-26 00:57:44 +02:00
|
|
|
for (auto &KV : Resolved) {
|
|
|
|
// Scan the symbols and add them to the Symbols map for resolution.
|
|
|
|
|
|
|
|
// We never claim internal symbols.
|
|
|
|
if (InternalSymbols.count(KV.first))
|
|
|
|
continue;
|
|
|
|
|
2018-10-01 01:18:24 +02:00
|
|
|
auto InternedName = getExecutionSession().intern(KV.first);
|
2018-09-26 00:57:44 +02:00
|
|
|
auto Flags = KV.second.getFlags();
|
|
|
|
|
|
|
|
// Override object flags and claim responsibility for symbols if
|
|
|
|
// requested.
|
|
|
|
if (OverrideObjectFlags || AutoClaimObjectSymbols) {
|
|
|
|
auto I = R.getSymbols().find(InternedName);
|
|
|
|
|
|
|
|
if (OverrideObjectFlags && I != R.getSymbols().end())
|
2019-05-29 01:35:44 +02:00
|
|
|
Flags = I->second;
|
2018-09-26 00:57:44 +02:00
|
|
|
else if (AutoClaimObjectSymbols && I == R.getSymbols().end())
|
|
|
|
ExtraSymbolsToClaim[InternedName] = Flags;
|
2018-08-31 02:53:17 +02:00
|
|
|
}
|
|
|
|
|
2018-09-26 00:57:44 +02:00
|
|
|
Symbols[InternedName] = JITEvaluatedSymbol(KV.second.getAddress(), Flags);
|
2018-05-22 01:45:40 +02:00
|
|
|
}
|
|
|
|
|
2020-01-17 23:48:48 +01:00
|
|
|
if (!ExtraSymbolsToClaim.empty()) {
|
2018-09-26 00:57:44 +02:00
|
|
|
if (auto Err = R.defineMaterializing(ExtraSymbolsToClaim))
|
|
|
|
return Err;
|
|
|
|
|
2020-01-17 23:48:48 +01:00
|
|
|
// If we claimed responsibility for any weak symbols but were rejected then
|
|
|
|
// we need to remove them from the resolved set.
|
|
|
|
for (auto &KV : ExtraSymbolsToClaim)
|
|
|
|
if (KV.second.isWeak() && !R.getSymbols().count(KV.first))
|
|
|
|
Symbols.erase(KV.first);
|
|
|
|
}
|
|
|
|
|
2019-08-23 22:37:31 +02:00
|
|
|
if (auto Err = R.notifyResolved(Symbols)) {
|
|
|
|
R.failMaterialization();
|
|
|
|
return Err;
|
|
|
|
}
|
2018-09-26 00:57:44 +02:00
|
|
|
|
2018-05-22 01:45:40 +02:00
|
|
|
if (NotifyLoaded)
|
[ORC] Add support for resource tracking/removal (removable code).
This patch introduces new APIs to support resource tracking and removal in Orc.
It is intended as a thread-safe generalization of the removeModule concept from
OrcV1.
Clients can now create ResourceTracker objects (using
JITDylib::createResourceTracker) to track resources for each MaterializationUnit
(code, data, aliases, absolute symbols, etc.) added to the JIT. Every
MaterializationUnit will be associated with a ResourceTracker, and
ResourceTrackers can be re-used for multiple MaterializationUnits. Each JITDylib
has a default ResourceTracker that will be used for MaterializationUnits added
to that JITDylib if no ResourceTracker is explicitly specified.
Two operations can be performed on ResourceTrackers: transferTo and remove. The
transferTo operation transfers tracking of the resources to a different
ResourceTracker object, allowing ResourceTrackers to be merged to reduce
administrative overhead (the source tracker is invalidated in the process). The
remove operation removes all resources associated with a ResourceTracker,
including any symbols defined by MaterializationUnits associated with the
tracker, and also invalidates the tracker. These operations are thread safe, and
should work regardless of the the state of the MaterializationUnits. In the case
of resource transfer any existing resources associated with the source tracker
will be transferred to the destination tracker, and all future resources for
those units will be automatically associated with the destination tracker. In
the case of resource removal all already-allocated resources will be
deallocated, any if any program representations associated with the tracker have
not been compiled yet they will be destroyed. If any program representations are
currently being compiled then they will be prevented from completing: their
MaterializationResponsibility will return errors on any attempt to update the
JIT state.
Clients (usually Layer writers) wishing to track resources can implement the
ResourceManager API to receive notifications when ResourceTrackers are
transferred or removed. The MaterializationResponsibility::withResourceKeyDo
method can be used to create associations between the key for a ResourceTracker
and an allocated resource in a thread-safe way.
RTDyldObjectLinkingLayer and ObjectLinkingLayer are updated to use the
ResourceManager API to enable tracking and removal of memory allocated by the
JIT linker.
The new JITDylib::clear method can be used to trigger removal of every
ResourceTracker associated with the JITDylib (note that this will only
remove resources for the JITDylib, it does not run static destructors).
This patch includes unit tests showing basic usage. A follow-up patch will
update the Kaleidoscope and BuildingAJIT tutorial series to OrcV2 and will
use this API to release code associated with anonymous expressions.
2020-09-11 18:50:41 +02:00
|
|
|
NotifyLoaded(R, Obj, LoadedObjInfo);
|
2020-03-20 00:14:18 +01:00
|
|
|
|
2018-09-26 00:57:44 +02:00
|
|
|
return Error::success();
|
|
|
|
}
|
2018-05-22 01:45:40 +02:00
|
|
|
|
2019-05-02 00:40:23 +02:00
|
|
|
void RTDyldObjectLinkingLayer::onObjEmit(
|
[ORC] Add support for resource tracking/removal (removable code).
This patch introduces new APIs to support resource tracking and removal in Orc.
It is intended as a thread-safe generalization of the removeModule concept from
OrcV1.
Clients can now create ResourceTracker objects (using
JITDylib::createResourceTracker) to track resources for each MaterializationUnit
(code, data, aliases, absolute symbols, etc.) added to the JIT. Every
MaterializationUnit will be associated with a ResourceTracker, and
ResourceTrackers can be re-used for multiple MaterializationUnits. Each JITDylib
has a default ResourceTracker that will be used for MaterializationUnits added
to that JITDylib if no ResourceTracker is explicitly specified.
Two operations can be performed on ResourceTrackers: transferTo and remove. The
transferTo operation transfers tracking of the resources to a different
ResourceTracker object, allowing ResourceTrackers to be merged to reduce
administrative overhead (the source tracker is invalidated in the process). The
remove operation removes all resources associated with a ResourceTracker,
including any symbols defined by MaterializationUnits associated with the
tracker, and also invalidates the tracker. These operations are thread safe, and
should work regardless of the the state of the MaterializationUnits. In the case
of resource transfer any existing resources associated with the source tracker
will be transferred to the destination tracker, and all future resources for
those units will be automatically associated with the destination tracker. In
the case of resource removal all already-allocated resources will be
deallocated, any if any program representations associated with the tracker have
not been compiled yet they will be destroyed. If any program representations are
currently being compiled then they will be prevented from completing: their
MaterializationResponsibility will return errors on any attempt to update the
JIT state.
Clients (usually Layer writers) wishing to track resources can implement the
ResourceManager API to receive notifications when ResourceTrackers are
transferred or removed. The MaterializationResponsibility::withResourceKeyDo
method can be used to create associations between the key for a ResourceTracker
and an allocated resource in a thread-safe way.
RTDyldObjectLinkingLayer and ObjectLinkingLayer are updated to use the
ResourceManager API to enable tracking and removal of memory allocated by the
JIT linker.
The new JITDylib::clear method can be used to trigger removal of every
ResourceTracker associated with the JITDylib (note that this will only
remove resources for the JITDylib, it does not run static destructors).
This patch includes unit tests showing basic usage. A follow-up patch will
update the Kaleidoscope and BuildingAJIT tutorial series to OrcV2 and will
use this API to release code associated with anonymous expressions.
2020-09-11 18:50:41 +02:00
|
|
|
MaterializationResponsibility &R,
|
2020-03-20 00:14:18 +01:00
|
|
|
object::OwningBinary<object::ObjectFile> O,
|
[ORC] Add support for resource tracking/removal (removable code).
This patch introduces new APIs to support resource tracking and removal in Orc.
It is intended as a thread-safe generalization of the removeModule concept from
OrcV1.
Clients can now create ResourceTracker objects (using
JITDylib::createResourceTracker) to track resources for each MaterializationUnit
(code, data, aliases, absolute symbols, etc.) added to the JIT. Every
MaterializationUnit will be associated with a ResourceTracker, and
ResourceTrackers can be re-used for multiple MaterializationUnits. Each JITDylib
has a default ResourceTracker that will be used for MaterializationUnits added
to that JITDylib if no ResourceTracker is explicitly specified.
Two operations can be performed on ResourceTrackers: transferTo and remove. The
transferTo operation transfers tracking of the resources to a different
ResourceTracker object, allowing ResourceTrackers to be merged to reduce
administrative overhead (the source tracker is invalidated in the process). The
remove operation removes all resources associated with a ResourceTracker,
including any symbols defined by MaterializationUnits associated with the
tracker, and also invalidates the tracker. These operations are thread safe, and
should work regardless of the the state of the MaterializationUnits. In the case
of resource transfer any existing resources associated with the source tracker
will be transferred to the destination tracker, and all future resources for
those units will be automatically associated with the destination tracker. In
the case of resource removal all already-allocated resources will be
deallocated, any if any program representations associated with the tracker have
not been compiled yet they will be destroyed. If any program representations are
currently being compiled then they will be prevented from completing: their
MaterializationResponsibility will return errors on any attempt to update the
JIT state.
Clients (usually Layer writers) wishing to track resources can implement the
ResourceManager API to receive notifications when ResourceTrackers are
transferred or removed. The MaterializationResponsibility::withResourceKeyDo
method can be used to create associations between the key for a ResourceTracker
and an allocated resource in a thread-safe way.
RTDyldObjectLinkingLayer and ObjectLinkingLayer are updated to use the
ResourceManager API to enable tracking and removal of memory allocated by the
JIT linker.
The new JITDylib::clear method can be used to trigger removal of every
ResourceTracker associated with the JITDylib (note that this will only
remove resources for the JITDylib, it does not run static destructors).
This patch includes unit tests showing basic usage. A follow-up patch will
update the Kaleidoscope and BuildingAJIT tutorial series to OrcV2 and will
use this API to release code associated with anonymous expressions.
2020-09-11 18:50:41 +02:00
|
|
|
std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr,
|
|
|
|
std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo, Error Err) {
|
2018-09-26 00:57:44 +02:00
|
|
|
if (Err) {
|
|
|
|
getExecutionSession().reportError(std::move(Err));
|
2018-05-22 01:45:40 +02:00
|
|
|
R.failMaterialization();
|
2018-06-18 20:01:43 +02:00
|
|
|
return;
|
2018-05-22 01:45:40 +02:00
|
|
|
}
|
|
|
|
|
2019-08-23 22:37:31 +02:00
|
|
|
if (auto Err = R.notifyEmitted()) {
|
|
|
|
getExecutionSession().reportError(std::move(Err));
|
|
|
|
R.failMaterialization();
|
|
|
|
return;
|
|
|
|
}
|
2018-05-22 01:45:40 +02:00
|
|
|
|
2020-03-20 00:14:18 +01:00
|
|
|
std::unique_ptr<object::ObjectFile> Obj;
|
|
|
|
std::unique_ptr<MemoryBuffer> ObjBuffer;
|
|
|
|
std::tie(Obj, ObjBuffer) = O.takeBinary();
|
|
|
|
|
|
|
|
// Run EventListener notifyLoaded callbacks.
|
|
|
|
{
|
|
|
|
std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
|
|
|
|
for (auto *L : EventListeners)
|
[ORC] Add support for resource tracking/removal (removable code).
This patch introduces new APIs to support resource tracking and removal in Orc.
It is intended as a thread-safe generalization of the removeModule concept from
OrcV1.
Clients can now create ResourceTracker objects (using
JITDylib::createResourceTracker) to track resources for each MaterializationUnit
(code, data, aliases, absolute symbols, etc.) added to the JIT. Every
MaterializationUnit will be associated with a ResourceTracker, and
ResourceTrackers can be re-used for multiple MaterializationUnits. Each JITDylib
has a default ResourceTracker that will be used for MaterializationUnits added
to that JITDylib if no ResourceTracker is explicitly specified.
Two operations can be performed on ResourceTrackers: transferTo and remove. The
transferTo operation transfers tracking of the resources to a different
ResourceTracker object, allowing ResourceTrackers to be merged to reduce
administrative overhead (the source tracker is invalidated in the process). The
remove operation removes all resources associated with a ResourceTracker,
including any symbols defined by MaterializationUnits associated with the
tracker, and also invalidates the tracker. These operations are thread safe, and
should work regardless of the the state of the MaterializationUnits. In the case
of resource transfer any existing resources associated with the source tracker
will be transferred to the destination tracker, and all future resources for
those units will be automatically associated with the destination tracker. In
the case of resource removal all already-allocated resources will be
deallocated, any if any program representations associated with the tracker have
not been compiled yet they will be destroyed. If any program representations are
currently being compiled then they will be prevented from completing: their
MaterializationResponsibility will return errors on any attempt to update the
JIT state.
Clients (usually Layer writers) wishing to track resources can implement the
ResourceManager API to receive notifications when ResourceTrackers are
transferred or removed. The MaterializationResponsibility::withResourceKeyDo
method can be used to create associations between the key for a ResourceTracker
and an allocated resource in a thread-safe way.
RTDyldObjectLinkingLayer and ObjectLinkingLayer are updated to use the
ResourceManager API to enable tracking and removal of memory allocated by the
JIT linker.
The new JITDylib::clear method can be used to trigger removal of every
ResourceTracker associated with the JITDylib (note that this will only
remove resources for the JITDylib, it does not run static destructors).
This patch includes unit tests showing basic usage. A follow-up patch will
update the Kaleidoscope and BuildingAJIT tutorial series to OrcV2 and will
use this API to release code associated with anonymous expressions.
2020-09-11 18:50:41 +02:00
|
|
|
L->notifyObjectLoaded(pointerToJITTargetAddress(MemMgr.get()), *Obj,
|
|
|
|
*LoadedObjInfo);
|
2020-03-20 00:14:18 +01:00
|
|
|
}
|
|
|
|
|
2018-08-18 04:06:18 +02:00
|
|
|
if (NotifyEmitted)
|
[ORC] Add support for resource tracking/removal (removable code).
This patch introduces new APIs to support resource tracking and removal in Orc.
It is intended as a thread-safe generalization of the removeModule concept from
OrcV1.
Clients can now create ResourceTracker objects (using
JITDylib::createResourceTracker) to track resources for each MaterializationUnit
(code, data, aliases, absolute symbols, etc.) added to the JIT. Every
MaterializationUnit will be associated with a ResourceTracker, and
ResourceTrackers can be re-used for multiple MaterializationUnits. Each JITDylib
has a default ResourceTracker that will be used for MaterializationUnits added
to that JITDylib if no ResourceTracker is explicitly specified.
Two operations can be performed on ResourceTrackers: transferTo and remove. The
transferTo operation transfers tracking of the resources to a different
ResourceTracker object, allowing ResourceTrackers to be merged to reduce
administrative overhead (the source tracker is invalidated in the process). The
remove operation removes all resources associated with a ResourceTracker,
including any symbols defined by MaterializationUnits associated with the
tracker, and also invalidates the tracker. These operations are thread safe, and
should work regardless of the the state of the MaterializationUnits. In the case
of resource transfer any existing resources associated with the source tracker
will be transferred to the destination tracker, and all future resources for
those units will be automatically associated with the destination tracker. In
the case of resource removal all already-allocated resources will be
deallocated, any if any program representations associated with the tracker have
not been compiled yet they will be destroyed. If any program representations are
currently being compiled then they will be prevented from completing: their
MaterializationResponsibility will return errors on any attempt to update the
JIT state.
Clients (usually Layer writers) wishing to track resources can implement the
ResourceManager API to receive notifications when ResourceTrackers are
transferred or removed. The MaterializationResponsibility::withResourceKeyDo
method can be used to create associations between the key for a ResourceTracker
and an allocated resource in a thread-safe way.
RTDyldObjectLinkingLayer and ObjectLinkingLayer are updated to use the
ResourceManager API to enable tracking and removal of memory allocated by the
JIT linker.
The new JITDylib::clear method can be used to trigger removal of every
ResourceTracker associated with the JITDylib (note that this will only
remove resources for the JITDylib, it does not run static destructors).
This patch includes unit tests showing basic usage. A follow-up patch will
update the Kaleidoscope and BuildingAJIT tutorial series to OrcV2 and will
use this API to release code associated with anonymous expressions.
2020-09-11 18:50:41 +02:00
|
|
|
NotifyEmitted(R, std::move(ObjBuffer));
|
|
|
|
|
|
|
|
if (auto Err = R.withResourceKeyDo(
|
|
|
|
[&](ResourceKey K) { MemMgrs[K].push_back(std::move(MemMgr)); })) {
|
|
|
|
getExecutionSession().reportError(std::move(Err));
|
|
|
|
R.failMaterialization();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Error RTDyldObjectLinkingLayer::handleRemoveResources(ResourceKey K) {
|
|
|
|
|
|
|
|
std::vector<MemoryManagerUP> MemMgrsToRemove;
|
|
|
|
|
|
|
|
getExecutionSession().runSessionLocked([&] {
|
|
|
|
auto I = MemMgrs.find(K);
|
|
|
|
if (I != MemMgrs.end()) {
|
|
|
|
std::swap(MemMgrsToRemove, I->second);
|
|
|
|
MemMgrs.erase(I);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
{
|
|
|
|
std::lock_guard<std::mutex> Lock(RTDyldLayerMutex);
|
|
|
|
for (auto &MemMgr : MemMgrsToRemove) {
|
|
|
|
for (auto *L : EventListeners)
|
|
|
|
L->notifyFreeingObject(pointerToJITTargetAddress(MemMgr.get()));
|
|
|
|
MemMgr->deregisterEHFrames();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return Error::success();
|
|
|
|
}
|
|
|
|
|
|
|
|
void RTDyldObjectLinkingLayer::handleTransferResources(ResourceKey DstKey,
|
|
|
|
ResourceKey SrcKey) {
|
|
|
|
auto I = MemMgrs.find(SrcKey);
|
|
|
|
if (I != MemMgrs.end()) {
|
|
|
|
auto &SrcMemMgrs = I->second;
|
|
|
|
auto &DstMemMgrs = MemMgrs[DstKey];
|
|
|
|
DstMemMgrs.reserve(DstMemMgrs.size() + SrcMemMgrs.size());
|
|
|
|
for (auto &MemMgr : SrcMemMgrs)
|
|
|
|
DstMemMgrs.push_back(std::move(MemMgr));
|
|
|
|
|
|
|
|
// Erase SrcKey entry using value rather than iterator I: I may have been
|
|
|
|
// invalidated when we looked up DstKey.
|
|
|
|
MemMgrs.erase(SrcKey);
|
|
|
|
}
|
2018-05-22 01:45:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
} // End namespace orc.
|
|
|
|
} // End namespace llvm.
|