[ORC] Replace MachOJITDylibInitializers::SectionExtent with ExecutorAddressRange

MachOJITDylibInitializers::SectionExtent represented the address range of a
section as an (address, size) pair. The new ExecutorAddressRange type
generalizes this to an address range (for any object, not necessarily a section)
represented as a (start-address, end-address) pair.

The aim is to express more of ORC (and the ORC runtime) in terms of simple types
that can be serialized/deserialized via SPS. This will simplify SPS-based RPC
involving arguments/return-values of these types.
This commit is contained in:
Lang Hames 2021-07-08 14:10:15 +10:00
parent 88efb59b78
commit 5471766f9d
3 changed files with 115 additions and 45 deletions

View File

@ -17,6 +17,7 @@
#include "llvm/ExecutionEngine/Orc/Core.h"
#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
#include "llvm/ExecutionEngine/Orc/Shared/CommonOrcRuntimeTypes.h"
#include <future>
#include <thread>
@ -31,21 +32,13 @@ bool objCRegistrationEnabled();
class MachOJITDylibInitializers {
public:
struct SectionExtent {
SectionExtent() = default;
SectionExtent(JITTargetAddress Address, uint64_t NumPtrs)
: Address(Address), NumPtrs(NumPtrs) {}
JITTargetAddress Address = 0;
uint64_t NumPtrs = 0;
};
using RawPointerSectionList = std::vector<SectionExtent>;
using RawPointerSectionList = std::vector<shared::ExecutorAddressRange>;
void setObjCImageInfoAddr(JITTargetAddress ObjCImageInfoAddr) {
this->ObjCImageInfoAddr = ObjCImageInfoAddr;
}
void addModInitsSection(SectionExtent ModInit) {
void addModInitsSection(shared::ExecutorAddressRange ModInit) {
ModInitSections.push_back(std::move(ModInit));
}
@ -53,7 +46,7 @@ public:
return ModInitSections;
}
void addObjCSelRefsSection(SectionExtent ObjCSelRefs) {
void addObjCSelRefsSection(shared::ExecutorAddressRange ObjCSelRefs) {
ObjCSelRefsSections.push_back(std::move(ObjCSelRefs));
}
@ -61,7 +54,7 @@ public:
return ObjCSelRefsSections;
}
void addObjCClassListSection(SectionExtent ObjCClassList) {
void addObjCClassListSection(shared::ExecutorAddressRange ObjCClassList) {
ObjCClassListSections.push_back(std::move(ObjCClassList));
}
@ -152,9 +145,9 @@ private:
};
void registerInitInfo(JITDylib &JD, JITTargetAddress ObjCImageInfoAddr,
MachOJITDylibInitializers::SectionExtent ModInits,
MachOJITDylibInitializers::SectionExtent ObjCSelRefs,
MachOJITDylibInitializers::SectionExtent ObjCClassList);
shared::ExecutorAddressRange ModInits,
shared::ExecutorAddressRange ObjCSelRefs,
shared::ExecutorAddressRange ObjCClassList);
ExecutionSession &ES;
ObjectLinkingLayer &ObjLinkingLayer;

View File

@ -0,0 +1,66 @@
//===------------------- CommonOrcRuntimeTypes.h ----------------*- 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
//
//===----------------------------------------------------------------------===//
//
// Generic types usable with SPS and the ORC runtime.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_COMMONORCRUNTIMETYPES_H
#define LLVM_EXECUTIONENGINE_ORC_SHARED_COMMONORCRUNTIMETYPES_H
#include "llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h"
namespace llvm {
namespace orc {
namespace shared {
/// Represents an address range in the exceutor process.
struct ExecutorAddressRange {
ExecutorAddressRange() = default;
ExecutorAddressRange(JITTargetAddress StartAddress,
JITTargetAddress EndAddress)
: StartAddress(StartAddress), EndAddress(EndAddress) {}
bool empty() const { return StartAddress == EndAddress; }
size_t size() const { return EndAddress - StartAddress; }
JITTargetAddress StartAddress = 0;
JITTargetAddress EndAddress = 0;
};
using SPSExecutorAddressRange =
SPSTuple<SPSExecutorAddress, SPSExecutorAddress>;
/// Serialization traits for address ranges.
template <>
class SPSSerializationTraits<SPSExecutorAddressRange, ExecutorAddressRange> {
public:
static size_t size(const ExecutorAddressRange &Value) {
return SPSArgList<SPSExecutorAddress, SPSExecutorAddress>::size(
Value.StartAddress, Value.EndAddress);
}
static bool serialize(SPSOutputBuffer &BOB,
const ExecutorAddressRange &Value) {
return SPSArgList<SPSExecutorAddress, SPSExecutorAddress>::serialize(
BOB, Value.StartAddress, Value.EndAddress);
}
static bool deserialize(SPSInputBuffer &BIB, ExecutorAddressRange &Value) {
return SPSArgList<SPSExecutorAddress, SPSExecutorAddress>::deserialize(
BIB, Value.StartAddress, Value.EndAddress);
}
};
using SPSExecutorAddressRangeSequence = SPSSequence<SPSExecutorAddressRange>;
} // End namespace shared.
} // End namespace orc.
} // End namespace llvm.
#endif // LLVM_EXECUTIONENGINE_ORC_SHARED_COMMONORCRUNTIMETYPES_H

View File

@ -88,11 +88,15 @@ bool objCRegistrationEnabled() {
void MachOJITDylibInitializers::runModInits() const {
for (const auto &ModInit : ModInitSections) {
for (uint64_t I = 0; I != ModInit.NumPtrs; ++I) {
auto *InitializerAddr = jitTargetAddressToPointer<uintptr_t *>(
ModInit.Address + (I * sizeof(uintptr_t)));
auto *Initializer =
jitTargetAddressToFunction<void (*)()>(*InitializerAddr);
assert(ModInit.size() % sizeof(uintptr_t) == 0 &&
"ModInit section size is not a pointer multiple?");
for (uintptr_t *
InitPtr =
jitTargetAddressToPointer<uintptr_t *>(ModInit.StartAddress),
*InitEnd =
jitTargetAddressToPointer<uintptr_t *>(ModInit.EndAddress);
InitPtr != InitEnd; ++InitPtr) {
auto *Initializer = reinterpret_cast<void (*)()>(*InitPtr);
Initializer();
}
}
@ -102,8 +106,11 @@ void MachOJITDylibInitializers::registerObjCSelectors() const {
assert(objCRegistrationEnabled() && "ObjC registration not enabled.");
for (const auto &ObjCSelRefs : ObjCSelRefsSections) {
for (uint64_t I = 0; I != ObjCSelRefs.NumPtrs; ++I) {
auto SelEntryAddr = ObjCSelRefs.Address + (I * sizeof(uintptr_t));
assert(ObjCSelRefs.size() % sizeof(uintptr_t) == 0 &&
"ObjCSelRefs section size is not a pointer multiple?");
for (JITTargetAddress SelEntryAddr = ObjCSelRefs.StartAddress;
SelEntryAddr != ObjCSelRefs.EndAddress;
SelEntryAddr += sizeof(uintptr_t)) {
const auto *SelName =
*jitTargetAddressToPointer<const char **>(SelEntryAddr);
auto Sel = sel_registerName(SelName);
@ -128,8 +135,11 @@ Error MachOJITDylibInitializers::registerObjCClasses() const {
auto ClassSelector = sel_registerName("class");
for (const auto &ObjCClassList : ObjCClassListSections) {
for (uint64_t I = 0; I != ObjCClassList.NumPtrs; ++I) {
auto ClassPtrAddr = ObjCClassList.Address + (I * sizeof(uintptr_t));
assert(ObjCClassList.size() % sizeof(uintptr_t) == 0 &&
"ObjCClassList section size is not a pointer multiple?");
for (JITTargetAddress ClassPtrAddr = ObjCClassList.StartAddress;
ClassPtrAddr != ObjCClassList.EndAddress;
ClassPtrAddr += sizeof(uintptr_t)) {
auto Cls = *jitTargetAddressToPointer<Class *>(ClassPtrAddr);
auto *ClassCompiled =
*jitTargetAddressToPointer<ObjCClassCompiled **>(ClassPtrAddr);
@ -264,37 +274,36 @@ MachOPlatform::getDeinitializerSequence(JITDylib &JD) {
void MachOPlatform::registerInitInfo(
JITDylib &JD, JITTargetAddress ObjCImageInfoAddr,
MachOJITDylibInitializers::SectionExtent ModInits,
MachOJITDylibInitializers::SectionExtent ObjCSelRefs,
MachOJITDylibInitializers::SectionExtent ObjCClassList) {
shared::ExecutorAddressRange ModInits,
shared::ExecutorAddressRange ObjCSelRefs,
shared::ExecutorAddressRange ObjCClassList) {
std::lock_guard<std::mutex> Lock(InitSeqsMutex);
auto &InitSeq = InitSeqs[&JD];
InitSeq.setObjCImageInfoAddr(ObjCImageInfoAddr);
if (ModInits.Address)
if (ModInits.StartAddress)
InitSeq.addModInitsSection(std::move(ModInits));
if (ObjCSelRefs.Address)
if (ObjCSelRefs.StartAddress)
InitSeq.addObjCSelRefsSection(std::move(ObjCSelRefs));
if (ObjCClassList.Address)
if (ObjCClassList.StartAddress)
InitSeq.addObjCClassListSection(std::move(ObjCClassList));
}
static Expected<MachOJITDylibInitializers::SectionExtent>
static Expected<shared::ExecutorAddressRange>
getSectionExtent(jitlink::LinkGraph &G, StringRef SectionName) {
auto *Sec = G.findSectionByName(SectionName);
if (!Sec)
return MachOJITDylibInitializers::SectionExtent();
return shared::ExecutorAddressRange();
jitlink::SectionRange R(*Sec);
if (R.getSize() % G.getPointerSize() != 0)
return make_error<StringError>(SectionName + " section size is not a "
"multiple of the pointer size",
inconvertibleErrorCode());
return MachOJITDylibInitializers::SectionExtent(
R.getStart(), R.getSize() / G.getPointerSize());
return shared::ExecutorAddressRange{R.getStart(), R.getEnd()};
}
void MachOPlatform::InitScraperPlugin::modifyPassConfig(
@ -326,8 +335,7 @@ void MachOPlatform::InitScraperPlugin::modifyPassConfig(
Config.PostFixupPasses.push_back([this, &JD = MR.getTargetJITDylib()](
jitlink::LinkGraph &G) -> Error {
MachOJITDylibInitializers::SectionExtent ModInits, ObjCSelRefs,
ObjCClassList;
shared::ExecutorAddressRange ModInits, ObjCSelRefs, ObjCClassList;
JITTargetAddress ObjCImageInfoAddr = 0;
if (auto *ObjCImageInfoSec =
@ -359,23 +367,26 @@ void MachOPlatform::InitScraperPlugin::modifyPassConfig(
LLVM_DEBUG({
dbgs() << "MachOPlatform: Scraped " << G.getName() << " init sections:\n";
dbgs() << " __objc_selrefs: ";
if (ObjCSelRefs.NumPtrs)
dbgs() << ObjCSelRefs.NumPtrs << " pointer(s) at "
<< formatv("{0:x16}", ObjCSelRefs.Address) << "\n";
auto NumObjCSelRefs = ObjCSelRefs.size() / sizeof(uintptr_t);
if (NumObjCSelRefs)
dbgs() << NumObjCSelRefs << " pointer(s) at "
<< formatv("{0:x16}", ObjCSelRefs.StartAddress) << "\n";
else
dbgs() << "none\n";
dbgs() << " __objc_classlist: ";
if (ObjCClassList.NumPtrs)
dbgs() << ObjCClassList.NumPtrs << " pointer(s) at "
<< formatv("{0:x16}", ObjCClassList.Address) << "\n";
auto NumObjCClasses = ObjCClassList.size() / sizeof(uintptr_t);
if (NumObjCClasses)
dbgs() << NumObjCClasses << " pointer(s) at "
<< formatv("{0:x16}", ObjCClassList.StartAddress) << "\n";
else
dbgs() << "none\n";
dbgs() << " __mod_init_func: ";
if (ModInits.NumPtrs)
dbgs() << ModInits.NumPtrs << " pointer(s) at "
<< formatv("{0:x16}", ModInits.Address) << "\n";
auto NumModInits = ModInits.size() / sizeof(uintptr_t);
if (NumModInits)
dbgs() << NumModInits << " pointer(s) at "
<< formatv("{0:x16}", ModInits.StartAddress) << "\n";
else
dbgs() << "none\n";
});