LLVM: lib/ExecutionEngine/Orc/Core.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

10

12#include "llvm/Config/llvm-config.h"

18

19#include <condition_variable>

20#include

21#include

22

23#define DEBUG_TYPE "orc"

24

25namespace llvm {

26namespace orc {

27

37

40

41void MaterializationUnit::anchor() {}

42

44 assert((reinterpret_cast<uintptr_t>(JD.get()) & 0x1) == 0 &&

45 "JITDylib must be two byte aligned");

46 JD->Retain();

47 JDAndFlag.store(reinterpret_cast<uintptr_t>(JD.get()));

48}

49

54

58

62

63void ResourceTracker::makeDefunct() {

64 uintptr_t Val = JDAndFlag.load();

65 Val |= 0x1U;

66 JDAndFlag.store(Val);

67}

68

70

73

77

79 OS << "Resource tracker " << (void *)RT.get() << " became defunct";

80}

81

83 std::shared_ptr SSP,

84 std::shared_ptr Symbols)

86 assert(this->SSP && "String pool cannot be null");

87 assert(!this->Symbols->empty() && "Can not fail to resolve an empty set");

88

89

90

91 for (auto &[JD, Syms] : *this->Symbols)

92 JD->Retain();

93}

94

96 for (auto &[JD, Syms] : *Symbols)

97 JD->Release();

98}

99

103

105 OS << "Failed to materialize symbols: " << *Symbols;

106}

107

109 std::shared_ptr SSP, JITDylibSP JD,

111 std::string Explanation)

113 FailedSymbols(std::move(FailedSymbols)), BadDeps(std::move(BadDeps)),

114 Explanation(std::move(Explanation)) {}

115

119

121 OS << "In " << JD->getName() << ", failed to materialize " << FailedSymbols

122 << ", due to unsatisfied dependencies " << BadDeps;

123 if (!Explanation.empty())

124 OS << " (" << Explanation << ")";

125}

126

131 assert(!this->Symbols.empty() && "Can not fail to resolve an empty set");

132}

133

137 assert(!this->Symbols.empty() && "Can not fail to resolve an empty set");

138}

139

143

145 OS << "Symbols not found: " << Symbols;

146}

147

149 std::shared_ptr SSP, SymbolNameSet Symbols)

151 assert(!this->Symbols.empty() && "Can not fail to resolve an empty set");

152}

153

157

159 OS << "Symbols could not be removed: " << Symbols;

160}

161

165

167 OS << "Missing definitions in module " << ModuleName

168 << ": " << Symbols;

169}

170

174

176 OS << "Unexpected definitions in module " << ModuleName

177 << ": " << Symbols;

178}

179

181 JD->getExecutionSession().lookup(

184 [OnComplete = std::move(OnComplete)

185#ifndef NDEBUG

186 ,

187 Name = this->Name

188#endif

191 assert(Result->size() == 1 && "Unexpected number of results");

193 "Result does not contain expected symbol");

194 OnComplete(Result->begin()->second);

195 } else

196 OnComplete(Result.takeError());

197 },

199}

200

204 : NotifyComplete(std::move(NotifyComplete)), RequiredState(RequiredState) {

206 "Cannot query for a symbols that have not reached the resolve state "

207 "yet");

208

209 OutstandingSymbolsCount = Symbols.size();

210

211 for (auto &[Name, Flags] : Symbols)

213}

214

217 auto I = ResolvedSymbols.find(Name);

218 assert(I != ResolvedSymbols.end() &&

219 "Resolving symbol outside the requested set");

221 "Redundantly resolving symbol Name");

222

223

224

226 ResolvedSymbols.erase(I);

227 else

228 I->second = std::move(Sym);

229 --OutstandingSymbolsCount;

230}

231

232void AsynchronousSymbolQuery::handleComplete(ExecutionSession &ES) {

233 assert(OutstandingSymbolsCount == 0 &&

234 "Symbols remain, handleComplete called prematurely");

235

236 class RunQueryCompleteTask : public Task {

237 public:

238 RunQueryCompleteTask(SymbolMap ResolvedSymbols,

240 : ResolvedSymbols(std::move(ResolvedSymbols)),

241 NotifyComplete(std::move(NotifyComplete)) {}

242 void printDescription(raw_ostream &OS) override {

243 OS << "Execute query complete callback for " << ResolvedSymbols;

244 }

245 void run() override { NotifyComplete(std::move(ResolvedSymbols)); }

246

247 private:

250 };

251

252 auto T = std::make_unique(std::move(ResolvedSymbols),

253 std::move(NotifyComplete));

256}

257

258void AsynchronousSymbolQuery::handleFailed(Error Err) {

259 assert(QueryRegistrations.empty() && ResolvedSymbols.empty() &&

260 OutstandingSymbolsCount == 0 &&

261 "Query should already have been abandoned");

262 NotifyComplete(std::move(Err));

264}

265

266void AsynchronousSymbolQuery::addQueryDependence(JITDylib &JD,

268 bool Added = QueryRegistrations[&JD].insert(std::move(Name)).second;

269 (void)Added;

270 assert(Added && "Duplicate dependence notification?");

271}

272

273void AsynchronousSymbolQuery::removeQueryDependence(

275 auto QRI = QueryRegistrations.find(&JD);

276 assert(QRI != QueryRegistrations.end() &&

277 "No dependencies registered for JD");

278 assert(QRI->second.count(Name) && "No dependency on Name in JD");

279 QRI->second.erase(Name);

280 if (QRI->second.empty())

281 QueryRegistrations.erase(QRI);

282}

283

284void AsynchronousSymbolQuery::dropSymbol(const SymbolStringPtr &Name) {

285 auto I = ResolvedSymbols.find(Name);

286 assert(I != ResolvedSymbols.end() &&

287 "Redundant removal of weakly-referenced symbol");

288 ResolvedSymbols.erase(I);

289 --OutstandingSymbolsCount;

290}

291

292void AsynchronousSymbolQuery::detach() {

293 ResolvedSymbols.clear();

294 OutstandingSymbolsCount = 0;

295 for (auto &[JD, Syms] : QueryRegistrations)

296 JD->detachQueryHelper(*this, Syms);

297 QueryRegistrations.clear();

298}

299

304 SourceJDLookupFlags(SourceJDLookupFlags), Aliases(std::move(Aliases)) {}

305

307 return "";

308}

309

310void ReExportsMaterializationUnit::materialize(

311 std::unique_ptr R) {

312

313 auto &ES = R->getTargetJITDylib().getExecutionSession();

314 JITDylib &TgtJD = R->getTargetJITDylib();

315 JITDylib &SrcJD = SourceJD ? *SourceJD : TgtJD;

316

317

318

319

320 auto RequestedSymbols = R->getRequestedSymbols();

322

323 for (auto &Name : RequestedSymbols) {

324 auto I = Aliases.find(Name);

325 assert(I != Aliases.end() && "Symbol not found in aliases map?");

326 RequestedAliases[Name] = std::move(I->second);

328 }

329

332 dbgs() << "materializing reexports: target = " << TgtJD.getName()

333 << ", source = " << SrcJD.getName() << " " << RequestedAliases

334 << "\n";

335 });

336 });

337

338 if (!Aliases.empty()) {

339 auto Err = SourceJD ? R->replace(reexports(*SourceJD, std::move(Aliases),

340 SourceJDLookupFlags))

342

343 if (Err) {

344

345

347 R->failMaterialization();

348 return;

349 }

350 }

351

352

353

354 struct OnResolveInfo {

355 OnResolveInfo(std::unique_ptr R,

356 SymbolAliasMap Aliases)

357 : R(std::move(R)), Aliases(std::move(Aliases)) {}

358

359 std::unique_ptr R;

361 std::vector SDGs;

362 };

363

364

365

366

367

368

369

370

371

372 std::vector<std::pair<SymbolLookupSet, std::shared_ptr>>

373 QueryInfos;

374 while (!RequestedAliases.empty()) {

375 SymbolNameSet ResponsibilitySymbols;

376 SymbolLookupSet QuerySymbols;

377 SymbolAliasMap QueryAliases;

378

379

380 for (auto &KV : RequestedAliases) {

381

382 if (&SrcJD == &TgtJD && (QueryAliases.count(KV.second.Aliasee) ||

383 RequestedAliases.count(KV.second.Aliasee)))

384 continue;

385

386 ResponsibilitySymbols.insert(KV.first);

387 QuerySymbols.add(KV.second.Aliasee,

388 KV.second.AliasFlags.hasMaterializationSideEffectsOnly()

389 ? SymbolLookupFlags::WeaklyReferencedSymbol

390 : SymbolLookupFlags::RequiredSymbol);

391 QueryAliases[KV.first] = std::move(KV.second);

392 }

393

394

395 for (auto &KV : QueryAliases)

396 RequestedAliases.erase(KV.first);

397

398 assert(!QuerySymbols.empty() && "Alias cycle detected!");

399

400 auto NewR = R->delegate(ResponsibilitySymbols);

401 if (!NewR) {

403 R->failMaterialization();

404 return;

405 }

406

407 auto QueryInfo = std::make_shared(std::move(*NewR),

408 std::move(QueryAliases));

409 QueryInfos.push_back(

410 make_pair(std::move(QuerySymbols), std::move(QueryInfo)));

411 }

412

413

414 while (!QueryInfos.empty()) {

415 auto QuerySymbols = std::move(QueryInfos.back().first);

416 auto QueryInfo = std::move(QueryInfos.back().second);

417

418 QueryInfos.pop_back();

419

420 auto RegisterDependencies = [QueryInfo,

422

423 if (Deps.empty())

424 return;

425

426

427 assert(Deps.size() == 1 && Deps.count(&SrcJD) &&

428 "Unexpected dependencies for reexports");

429

430 auto &SrcJDDeps = Deps.find(&SrcJD)->second;

431

432 for (auto &[Alias, AliasInfo] : QueryInfo->Aliases)

433 if (SrcJDDeps.count(AliasInfo.Aliasee))

434 QueryInfo->SDGs.push_back({{Alias}, {{&SrcJD, {AliasInfo.Aliasee}}}});

435 };

436

437 auto OnComplete = [QueryInfo](Expected Result) {

438 auto &ES = QueryInfo->R->getTargetJITDylib().getExecutionSession();

441 for (auto &KV : QueryInfo->Aliases) {

442 assert((KV.second.AliasFlags.hasMaterializationSideEffectsOnly() ||

443 Result->count(KV.second.Aliasee)) &&

444 "Result map missing entry?");

445

446 if (KV.second.AliasFlags.hasMaterializationSideEffectsOnly())

447 continue;

448

449 ResolutionMap[KV.first] = {(*Result)[KV.second.Aliasee].getAddress(),

450 KV.second.AliasFlags};

451 }

452 if (auto Err = QueryInfo->R->notifyResolved(ResolutionMap)) {

454 QueryInfo->R->failMaterialization();

455 return;

456 }

457 if (auto Err = QueryInfo->R->notifyEmitted(QueryInfo->SDGs)) {

459 QueryInfo->R->failMaterialization();

460 return;

461 }

462 } else {

464 QueryInfo->R->failMaterialization();

465 }

466 };

467

471 std::move(RegisterDependencies));

472 }

473}

474

475void ReExportsMaterializationUnit::discard(const JITDylib &JD,

476 const SymbolStringPtr &Name) {

477 assert(Aliases.count(Name) &&

478 "Symbol not covered by this MaterializationUnit");

479 Aliases.erase(Name);

480}

481

482MaterializationUnit::Interface

483ReExportsMaterializationUnit::extractFlags(const SymbolAliasMap &Aliases) {

485 for (auto &KV : Aliases)

486 SymbolFlags[KV.first] = KV.second.AliasFlags;

487

488 return MaterializationUnit::Interface(std::move(SymbolFlags), nullptr);

489}

490

497

498 if (!Flags)

499 return Flags.takeError();

500

502 for (auto &Name : Symbols) {

503 assert(Flags->count(Name) && "Missing entry in flags map");

505 }

506

508}

509

511public:

512

513

514

522 virtual void complete(std::unique_ptr IPLS) = 0;

524

529

534

535 enum {

539 } GenState = NotInGenerator;

541};

542

544public:

550 OnComplete(std::move(OnComplete)) {}

551

552 void complete(std::unique_ptr IPLS) override {

553 auto &ES = SearchOrder.front().first->getExecutionSession();

554 ES.OL_completeLookupFlags(std::move(IPLS), std::move(OnComplete));

555 }

556

557 void fail(Error Err) override { OnComplete(std::move(Err)); }

558

559private:

561};

562

564public:

568 std::shared_ptr Q,

572 Q(std::move(Q)), RegisterDependencies(std::move(RegisterDependencies)) {

573 }

574

575 void complete(std::unique_ptr IPLS) override {

576 auto &ES = SearchOrder.front().first->getExecutionSession();

577 ES.OL_completeLookup(std::move(IPLS), std::move(Q),

578 std::move(RegisterDependencies));

579 }

580

582 Q->detach();

583 Q->handleFailed(std::move(Err));

584 }

585

586private:

587 std::shared_ptr Q;

589};

590

594 : SourceJD(SourceJD), SourceJDLookupFlags(SourceJDLookupFlags),

595 Allow(std::move(Allow)) {}

596

601 assert(&JD != &SourceJD && "Cannot re-export from the same dylib");

602

603

605 K, {{&SourceJD, JDLookupFlags}}, LookupSet);

606 if (!Flags)

607 return Flags.takeError();

608

609

611 for (auto &KV : *Flags)

612 if (!Allow || Allow(KV.first))

614

615 if (AliasMap.empty())

617

618

619 return JD.define(reexports(SourceJD, AliasMap, SourceJDLookupFlags));

620}

621

623 : IPLS(std::move(IPLS)) {}

624

625void LookupState::reset(InProgressLookupState *IPLS) { this->IPLS.reset(IPLS); }

626

631

633 assert(IPLS && "Cannot call continueLookup on empty LookupState");

634 auto &ES = IPLS->SearchOrder.begin()->first->getExecutionSession();

635 ES.OL_applyQueryPhase1(std::move(IPLS), std::move(Err));

636}

637

639 std::deque LookupsToFail;

640 {

641 std::lock_guardstd::mutex Lock(M);

642 std::swap(PendingLookups, LookupsToFail);

643 InUse = false;

644 }

645

646 for (auto &LS : LookupsToFail)

648 "Query waiting on DefinitionGenerator that was destroyed",

650}

651

655

657 std::vector TrackersToRemove;

658 ES.runSessionLocked([&]() {

659 assert(State != Closed && "JD is defunct");

660 for (auto &KV : TrackerSymbols)

661 TrackersToRemove.push_back(KV.first);

663 });

664

666 for (auto &RT : TrackersToRemove)

667 Err = joinErrors(std::move(Err), RT->remove());

668 return Err;

669}

670

672 return ES.runSessionLocked([this] {

673 assert(State != Closed && "JD is defunct");

674 if (!DefaultTracker)

676 return DefaultTracker;

677 });

678}

679

681 return ES.runSessionLocked([this] {

682 assert(State == Open && "JD is defunct");

684 return RT;

685 });

686}

687

689

690

691 std::shared_ptr TmpDG;

692

693 ES.runSessionLocked([&] {

694 assert(State == Open && "JD is defunct");

696 [&](const std::shared_ptr &H) {

697 return H.get() == &G;

698 });

699 assert(I != DefGenerators.end() && "Generator not found");

700 TmpDG = std::move(*I);

701 DefGenerators.erase(I);

702 });

703}

704

708

710 if (FromMR.RT->isDefunct())

712

713 std::vector AddedSyms;

714 std::vector RejectedWeakDefs;

715

716 for (auto &[Name, Flags] : SymbolFlags) {

717 auto EntryItr = Symbols.find(Name);

718

719

720 if (EntryItr != Symbols.end()) {

721

722

723 if (!Flags.isWeak()) {

724

725 for (auto &S : AddedSyms)

727

728

730 std::string(*Name), "defineMaterializing operation");

731 }

732

733

734 RejectedWeakDefs.push_back(NonOwningSymbolStringPtr(Name));

735 continue;

736 } else

737 EntryItr =

738 Symbols.insert(std::make_pair(Name, SymbolTableEntry(Flags))).first;

739

740 AddedSyms.push_back(NonOwningSymbolStringPtr(Name));

742 }

743

744

745 while (!RejectedWeakDefs.empty()) {

747 RejectedWeakDefs.pop_back();

748 }

749

751 });

752}

753

755 std::unique_ptr MU) {

756 assert(MU != nullptr && "Can not replace with a null MaterializationUnit");

757 std::unique_ptr MustRunMU;

758 std::unique_ptr MustRunMR;

759

760 auto Err =

761 ES.runSessionLocked([&, this]() -> Error {

762 if (FromMR.RT->isDefunct())

764

765#ifndef NDEBUG

766 for (auto &KV : MU->getSymbols()) {

767 auto SymI = Symbols.find(KV.first);

768 assert(SymI != Symbols.end() && "Replacing unknown symbol");

770 "Can not replace a symbol that ha is not materializing");

771 assert(!SymI->second.hasMaterializerAttached() &&

772 "Symbol should not have materializer attached already");

773 assert(UnmaterializedInfos.count(KV.first) == 0 &&

774 "Symbol being replaced should have no UnmaterializedInfo");

775 }

776#endif

777

778

779

780

781

782 for (auto &KV : MU->getSymbols()) {

783 auto MII = MaterializingInfos.find(KV.first);

784 if (MII != MaterializingInfos.end()) {

785 if (MII->second.hasQueriesPending()) {

786 MustRunMR = ES.createMaterializationResponsibility(

787 *FromMR.RT, std::move(MU->SymbolFlags),

788 std::move(MU->InitSymbol));

789 MustRunMU = std::move(MU);

791 }

792 }

793 }

794

795

796 auto UMI = std::make_shared(std::move(MU),

797 FromMR.RT.get());

798 for (auto &KV : UMI->MU->getSymbols()) {

799 auto SymI = Symbols.find(KV.first);

801 "Can not replace a symbol that is not materializing");

802 assert(!SymI->second.hasMaterializerAttached() &&

803 "Can not replace a symbol that has a materializer attached");

804 assert(UnmaterializedInfos.count(KV.first) == 0 &&

805 "Unexpected materializer entry in map");

806 SymI->second.setAddress(SymI->second.getAddress());

807 SymI->second.setMaterializerAttached(true);

808

809 auto &UMIEntry = UnmaterializedInfos[KV.first];

810 assert((!UMIEntry || !UMIEntry->MU) &&

811 "Replacing symbol with materializer still attached");

812 UMIEntry = UMI;

813 }

814

816 });

817

818 if (Err)

819 return Err;

820

821 if (MustRunMU) {

822 assert(MustRunMR && "MustRunMU set implies MustRunMR set");

823 ES.dispatchTask(std::make_unique(

824 std::move(MustRunMU), std::move(MustRunMR)));

825 } else {

826 assert(!MustRunMR && "MustRunMU unset implies MustRunMR unset");

827 }

828

830}

831

832Expected<std::unique_ptr>

835

836 return ES.runSessionLocked(

837 [&]() -> Expected<std::unique_ptr> {

838 if (FromMR.RT->isDefunct())

840

841 return ES.createMaterializationResponsibility(

842 *FromMR.RT, std::move(SymbolFlags), std::move(InitSymbol));

843 });

844}

845

847JITDylib::getRequestedSymbols(const SymbolFlagsMap &SymbolFlags) const {

848 return ES.runSessionLocked([&]() {

850

851 for (auto &KV : SymbolFlags) {

852 assert(Symbols.count(KV.first) && "JITDylib does not cover this symbol?");

853 assert(Symbols.find(KV.first)->second.getState() !=

856 "getRequestedSymbols can only be called for symbols that have "

857 "started materializing");

858 auto I = MaterializingInfos.find(KV.first);

859 if (I == MaterializingInfos.end())

860 continue;

861

862 if (I->second.hasQueriesPending())

863 RequestedSymbols.insert(KV.first);

864 }

865

866 return RequestedSymbols;

867 });

868}

869

872 AsynchronousSymbolQuerySet CompletedQueries;

873

874 if (auto Err = ES.runSessionLocked([&, this]() -> Error {

875 if (MR.RT->isDefunct())

876 return make_error(MR.RT);

877

878 if (State != Open)

879 return make_error("JITDylib " + getName() +

880 " is defunct",

881 inconvertibleErrorCode());

882

883 struct WorklistEntry {

884 SymbolTable::iterator SymI;

885 ExecutorSymbolDef ResolvedSym;

886 };

887

889 std::vector Worklist;

891

892

894

895 assert(!KV.second.getFlags().hasError() &&

896 "Resolution result can not have error flag set");

897

898 auto SymI = Symbols.find(KV.first);

899

900 assert(SymI != Symbols.end() && "Symbol not found");

901 assert(!SymI->second.hasMaterializerAttached() &&

902 "Resolving symbol with materializer attached?");

904 "Symbol should be materializing");

905 assert(SymI->second.getAddress() == ExecutorAddr() &&

906 "Symbol has already been resolved");

907

908 if (SymI->second.getFlags().hasError())

909 SymbolsInErrorState.insert(KV.first);

910 else {

912 [[maybe_unused]] auto WeakOrCommon =

914 assert((KV.second.getFlags() & WeakOrCommon) &&

915 "Common symbols must be resolved as common or weak");

916 assert((KV.second.getFlags() & ~WeakOrCommon) ==

918 "Resolving symbol with incorrect flags");

919

920 } else

921 assert(KV.second.getFlags() == SymI->second.getFlags() &&

922 "Resolved flags should match the declared flags");

923

924 Worklist.push_back(

925 {SymI, {KV.second.getAddress(), SymI->second.getFlags()}});

926 }

927 }

928

929

930 if (!SymbolsInErrorState.empty()) {

931 auto FailedSymbolsDepMap = std::make_shared();

932 (*FailedSymbolsDepMap)[this] = std::move(SymbolsInErrorState);

933 return make_error(

934 getExecutionSession().getSymbolStringPool(),

935 std::move(FailedSymbolsDepMap));

936 }

937

938 while (!Worklist.empty()) {

939 auto SymI = Worklist.back().SymI;

940 auto ResolvedSym = Worklist.back().ResolvedSym;

941 Worklist.pop_back();

942

943 auto &Name = SymI->first;

944

945

946 JITSymbolFlags ResolvedFlags = ResolvedSym.getFlags();

947 SymI->second.setAddress(ResolvedSym.getAddress());

948 SymI->second.setFlags(ResolvedFlags);

949 SymI->second.setState(SymbolState::Resolved);

950

951 auto MII = MaterializingInfos.find(Name);

952 if (MII == MaterializingInfos.end())

953 continue;

954

955 auto &MI = MII->second;

956 for (auto &Q : MI.takeQueriesMeeting(SymbolState::Resolved)) {

957 Q->notifySymbolMetRequiredState(Name, ResolvedSym);

958 if (Q->isComplete())

959 CompletedQueries.insert(std::move(Q));

960 }

961 }

962

964 }))

965 return Err;

966

967

968 for (auto &Q : CompletedQueries) {

969 assert(Q->isComplete() && "Q not completed");

970 Q->handleComplete(ES);

971 }

972

974}

975

976void JITDylib::unlinkMaterializationResponsibility(

977 MaterializationResponsibility &MR) {

979 auto I = TrackerMRs.find(MR.RT.get());

980 assert(I != TrackerMRs.end() && "No MRs in TrackerMRs list for RT");

981 assert(I->second.count(&MR) && "MR not in TrackerMRs list for RT");

982 I->second.erase(&MR);

983 if (I->second.empty())

984 TrackerMRs.erase(MR.RT.get());

985 });

986}

987

988void JITDylib::shrinkMaterializationInfoMemory() {

989

990

991

992 if (UnmaterializedInfos.empty())

993 UnmaterializedInfos.clear();

994

995 if (MaterializingInfos.empty())

996 MaterializingInfos.clear();

997}

998

1000 bool LinkAgainstThisJITDylibFirst) {

1001 ES.runSessionLocked([&]() {

1002 assert(State == Open && "JD is defunct");

1003 if (LinkAgainstThisJITDylibFirst) {

1004 LinkOrder.clear();

1005 if (NewLinkOrder.empty() || NewLinkOrder.front().first != this)

1006 LinkOrder.push_back(

1009 } else

1010 LinkOrder = std::move(NewLinkOrder);

1011 });

1012}

1013

1015 ES.runSessionLocked([&]() {

1016 for (auto &KV : NewLinks) {

1017

1019 continue;

1020

1021 LinkOrder.push_back(std::move(KV));

1022 }

1023 });

1024}

1025

1027 ES.runSessionLocked([&]() { LinkOrder.push_back({&JD, JDLookupFlags}); });

1028}

1029

1032 ES.runSessionLocked([&]() {

1033 assert(State == Open && "JD is defunct");

1034 for (auto &KV : LinkOrder)

1035 if (KV.first == &OldJD) {

1036 KV = {&NewJD, JDLookupFlags};

1037 break;

1038 }

1039 });

1040}

1041

1043 ES.runSessionLocked([&]() {

1044 assert(State == Open && "JD is defunct");

1046 [&](const JITDylibSearchOrder::value_type &KV) {

1047 return KV.first == &JD;

1048 });

1049 if (I != LinkOrder.end())

1050 LinkOrder.erase(I);

1051 });

1052}

1053

1055 return ES.runSessionLocked([&]() -> Error {

1056 assert(State == Open && "JD is defunct");

1057 using SymbolMaterializerItrPair =

1058 std::pair<SymbolTable::iterator, UnmaterializedInfosMap::iterator>;

1059 std::vector SymbolsToRemove;

1062

1063 for (auto &Name : Names) {

1064 auto I = Symbols.find(Name);

1065

1066

1067 if (I == Symbols.end()) {

1068 Missing.insert(Name);

1069 continue;

1070 }

1071

1072

1076 continue;

1077 }

1078

1079 auto UMII = I->second.hasMaterializerAttached()

1080 ? UnmaterializedInfos.find(Name)

1081 : UnmaterializedInfos.end();

1082 SymbolsToRemove.push_back(std::make_pair(I, UMII));

1083 }

1084

1085

1086 if (!Missing.empty())

1088 std::move(Missing));

1089

1090

1094

1095

1096 for (auto &SymbolMaterializerItrPair : SymbolsToRemove) {

1097 auto UMII = SymbolMaterializerItrPair.second;

1098

1099

1100 if (UMII != UnmaterializedInfos.end()) {

1101 UMII->second->MU->doDiscard(*this, UMII->first);

1102 UnmaterializedInfos.erase(UMII);

1103 }

1104

1105 auto SymI = SymbolMaterializerItrPair.first;

1106 Symbols.erase(SymI);

1107 }

1108

1109 shrinkMaterializationInfoMemory();

1110

1112 });

1113}

1114

1116 ES.runSessionLocked([&, this]() {

1117 OS << "JITDylib \"" << getName() << "\" (ES: "

1118 << format("0x%016" PRIx64, reinterpret_cast<uintptr_t>(&ES))

1119 << ", State = ";

1120 switch (State) {

1121 case Open:

1122 OS << "Open";

1123 break;

1124 case Closing:

1125 OS << "Closing";

1126 break;

1127 case Closed:

1128 OS << "Closed";

1129 break;

1130 }

1131 OS << ")\n";

1132 if (State == Closed)

1133 return;

1134 OS << "Link order: " << LinkOrder << "\n"

1135 << "Symbol table:\n";

1136

1137

1138 std::vector<std::pair<SymbolStringPtr, SymbolTableEntry *>> SymbolsSorted;

1139 for (auto &KV : Symbols)

1140 SymbolsSorted.emplace_back(KV.first, &KV.second);

1141 std::sort(SymbolsSorted.begin(), SymbolsSorted.end(),

1142 [](const auto &L, const auto &R) { return *L.first < *R.first; });

1143

1144 for (auto &KV : SymbolsSorted) {

1145 OS << " \"" << *KV.first << "\": ";

1146 if (auto Addr = KV.second->getAddress())

1147 OS << Addr;

1148 else

1149 OS << " ";

1150

1151 OS << " " << KV.second->getFlags() << " " << KV.second->getState();

1152

1153 if (KV.second->hasMaterializerAttached()) {

1154 OS << " (Materializer ";

1155 auto I = UnmaterializedInfos.find(KV.first);

1156 assert(I != UnmaterializedInfos.end() &&

1157 "Lazy symbol should have UnmaterializedInfo");

1158 OS << I->second->MU.get() << ", " << I->second->MU->getName() << ")\n";

1159 } else

1160 OS << "\n";

1161 }

1162

1163 if (!MaterializingInfos.empty())

1164 OS << " MaterializingInfos entries:\n";

1165 for (auto &KV : MaterializingInfos) {

1166 OS << " \"" << *KV.first << "\":\n"

1167 << " " << KV.second.pendingQueries().size()

1168 << " pending queries: { ";

1169 for (const auto &Q : KV.second.pendingQueries())

1170 OS << Q.get() << " (" << Q->getRequiredState() << ") ";

1171 OS << "}\n";

1172 }

1173 });

1174}

1175

1176void JITDylib::MaterializingInfo::addQuery(

1177 std::shared_ptr Q) {

1178

1180 llvm::reverse(PendingQueries), Q->getRequiredState(),

1181 [](const std::shared_ptr &V, SymbolState S) {

1182 return V->getRequiredState() <= S;

1183 });

1184 PendingQueries.insert(I.base(), std::move(Q));

1185}

1186

1187void JITDylib::MaterializingInfo::removeQuery(

1188 const AsynchronousSymbolQuery &Q) {

1189

1191 PendingQueries, [&Q](const std::shared_ptr &V) {

1192 return V.get() == &Q;

1193 });

1194 if (I != PendingQueries.end())

1195 PendingQueries.erase(I);

1196}

1197

1198JITDylib::AsynchronousSymbolQueryList

1199JITDylib::MaterializingInfo::takeQueriesMeeting(SymbolState RequiredState) {

1200 AsynchronousSymbolQueryList Result;

1201 while (!PendingQueries.empty()) {

1202 if (PendingQueries.back()->getRequiredState() > RequiredState)

1203 break;

1204

1205 Result.push_back(std::move(PendingQueries.back()));

1206 PendingQueries.pop_back();

1207 }

1208

1210}

1211

1212JITDylib::JITDylib(ExecutionSession &ES, std::string Name)

1213 : JITLinkDylib(std::move(Name)), ES(ES) {

1215}

1216

1217JITDylib::RemoveTrackerResult JITDylib::IL_removeTracker(ResourceTracker &RT) {

1218

1219 assert(State != Closed && "JD is defunct");

1220

1223

1224 if (&RT == DefaultTracker.get()) {

1226 for (auto &KV : TrackerSymbols)

1228

1229 for (auto &KV : Symbols) {

1230 auto &Sym = KV.first;

1231 if (!TrackedSymbols.count(Sym))

1232 SymbolsToRemove.push_back(Sym);

1233 }

1234

1235 DefaultTracker.reset();

1236 } else {

1237

1238 auto I = TrackerSymbols.find(&RT);

1239 if (I != TrackerSymbols.end()) {

1240 SymbolsToRemove = std::move(I->second);

1241 TrackerSymbols.erase(I);

1242 }

1243

1244 }

1245

1246 for (auto &Sym : SymbolsToRemove) {

1247 assert(Symbols.count(Sym) && "Symbol not in symbol table");

1248

1249

1250 auto MII = MaterializingInfos.find(Sym);

1251 if (MII != MaterializingInfos.end())

1252 SymbolsToFail.push_back(Sym);

1253 }

1254

1255 auto [QueriesToFail, FailedSymbols] =

1256 ES.IL_failSymbols(*this, std::move(SymbolsToFail));

1257

1258 std::vector<std::unique_ptr> DefunctMUs;

1259

1260

1261 for (auto &Sym : SymbolsToRemove) {

1262 auto I = Symbols.find(Sym);

1263 assert(I != Symbols.end() && "Symbol not present in table");

1264

1265

1266 if (I->second.hasMaterializerAttached()) {

1267

1268 auto J = UnmaterializedInfos.find(Sym);

1269 assert(J != UnmaterializedInfos.end() &&

1270 "Symbol table indicates MU present, but no UMI record");

1271 if (J->second->MU)

1272 DefunctMUs.push_back(std::move(J->second->MU));

1273 UnmaterializedInfos.erase(J);

1274 } else {

1275 assert(!UnmaterializedInfos.count(Sym) &&

1276 "Symbol has materializer attached");

1277 }

1278

1279 Symbols.erase(I);

1280 }

1281

1282 shrinkMaterializationInfoMemory();

1283

1284 return {std::move(QueriesToFail), std::move(FailedSymbols),

1285 std::move(DefunctMUs)};

1286}

1287

1289 assert(State != Closed && "JD is defunct");

1290 assert(&DstRT != &SrcRT && "No-op transfers shouldn't call transferTracker");

1291 assert(&DstRT.getJITDylib() == this && "DstRT is not for this JITDylib");

1292 assert(&SrcRT.getJITDylib() == this && "SrcRT is not for this JITDylib");

1293

1294

1295 for (auto &KV : UnmaterializedInfos) {

1296 if (KV.second->RT == &SrcRT)

1297 KV.second->RT = &DstRT;

1298 }

1299

1300

1301 {

1302 auto I = TrackerMRs.find(&SrcRT);

1303 if (I != TrackerMRs.end()) {

1304 auto &SrcMRs = I->second;

1305 auto &DstMRs = TrackerMRs[&DstRT];

1306 for (auto *MR : SrcMRs)

1307 MR->RT = &DstRT;

1308 if (DstMRs.empty())

1309 DstMRs = std::move(SrcMRs);

1310 else

1311 DstMRs.insert_range(SrcMRs);

1312

1313

1314 TrackerMRs.erase(&SrcRT);

1315 }

1316 }

1317

1318

1319

1320 if (&DstRT == DefaultTracker.get()) {

1321 TrackerSymbols.erase(&SrcRT);

1322 return;

1323 }

1324

1325

1326

1327 if (&SrcRT == DefaultTracker.get()) {

1328 assert(!TrackerSymbols.count(&SrcRT) &&

1329 "Default tracker should not appear in TrackerSymbols");

1330

1332

1334 for (auto &KV : TrackerSymbols)

1335 CurrentlyTrackedSymbols.insert_range(KV.second);

1336

1337 for (auto &KV : Symbols) {

1338 auto &Sym = KV.first;

1339 if (!CurrentlyTrackedSymbols.count(Sym))

1340 SymbolsToTrack.push_back(Sym);

1341 }

1342

1343 TrackerSymbols[&DstRT] = std::move(SymbolsToTrack);

1344 return;

1345 }

1346

1347 auto &DstTrackedSymbols = TrackerSymbols[&DstRT];

1348

1349

1350

1351 auto SI = TrackerSymbols.find(&SrcRT);

1352 if (SI == TrackerSymbols.end())

1353 return;

1354

1355 DstTrackedSymbols.reserve(DstTrackedSymbols.size() + SI->second.size());

1356 for (auto &Sym : SI->second)

1357 DstTrackedSymbols.push_back(std::move(Sym));

1358 TrackerSymbols.erase(SI);

1359}

1360

1362 LLVM_DEBUG({ dbgs() << " " << MU.getSymbols() << "\n"; });

1363

1365 std::vector ExistingDefsOverridden;

1366 std::vector MUDefsOverridden;

1367

1368 for (const auto &KV : MU.getSymbols()) {

1369 auto I = Symbols.find(KV.first);

1370

1371 if (I != Symbols.end()) {

1372 if (KV.second.isStrong()) {

1373 if (I->second.getFlags().isStrong() ||

1375 Duplicates.insert(KV.first);

1376 else {

1378 "Overridden existing def should be in the never-searched "

1379 "state");

1380 ExistingDefsOverridden.push_back(KV.first);

1381 }

1382 } else

1383 MUDefsOverridden.push_back(KV.first);

1384 }

1385 }

1386

1387

1388 if (!Duplicates.empty()) {

1390 { dbgs() << " Error: Duplicate symbols " << Duplicates << "\n"; });

1392 MU.getName().str());

1393 }

1394

1395

1397 if (!MUDefsOverridden.empty())

1398 dbgs() << " Defs in this MU overridden: " << MUDefsOverridden << "\n";

1399 });

1400 for (auto &S : MUDefsOverridden)

1401 MU.doDiscard(*this, S);

1402

1403

1405 if (!ExistingDefsOverridden.empty())

1406 dbgs() << " Existing defs overridden by this MU: " << MUDefsOverridden

1407 << "\n";

1408 });

1409 for (auto &S : ExistingDefsOverridden) {

1410

1411 auto UMII = UnmaterializedInfos.find(S);

1412 assert(UMII != UnmaterializedInfos.end() &&

1413 "Overridden existing def should have an UnmaterializedInfo");

1414 UMII->second->MU->doDiscard(*this, S);

1415 }

1416

1417

1418 for (auto &KV : MU.getSymbols()) {

1419 auto &SymEntry = Symbols[KV.first];

1420 SymEntry.setFlags(KV.second);

1422 SymEntry.setMaterializerAttached(true);

1423 }

1424

1426}

1427

1428void JITDylib::installMaterializationUnit(

1429 std::unique_ptr MU, ResourceTracker &RT) {

1430

1431

1432 if (&RT != DefaultTracker.get()) {

1433 auto &TS = TrackerSymbols[&RT];

1434 TS.reserve(TS.size() + MU->getSymbols().size());

1435 for (auto &KV : MU->getSymbols())

1436 TS.push_back(KV.first);

1437 }

1438

1439 auto UMI = std::make_shared(std::move(MU), &RT);

1440 for (auto &KV : UMI->MU->getSymbols())

1441 UnmaterializedInfos[KV.first] = UMI;

1442}

1443

1446 for (auto &QuerySymbol : QuerySymbols) {

1447 auto MII = MaterializingInfos.find(QuerySymbol);

1448 if (MII != MaterializingInfos.end())

1449 MII->second.removeQuery(Q);

1450 }

1451}

1452

1454

1458

1461 std::mutex LookupMutex;

1462 std::condition_variable CV;

1464

1466 dbgs() << "Issuing init-symbol lookup:\n";

1467 for (auto &KV : InitSyms)

1468 dbgs() << " " << KV.first->getName() << ": " << KV.second << "\n";

1469 });

1470

1471 for (auto &KV : InitSyms) {

1472 auto *JD = KV.first;

1473 auto Names = std::move(KV.second);

1479 {

1480 std::lock_guardstd::mutex Lock(LookupMutex);

1484 "Duplicate JITDylib in lookup?");

1485 CompoundResult[JD] = std::move(*Result);

1486 } else

1487 CompoundErr =

1489 }

1490 CV.notify_one();

1491 },

1493 }

1494

1495 std::unique_lockstd::mutex Lock(LookupMutex);

1496 CV.wait(Lock, [&] { return Count == 0; });

1497

1498 if (CompoundErr)

1499 return std::move(CompoundErr);

1500

1501 return std::move(CompoundResult);

1502}

1503

1507

1508 class TriggerOnComplete {

1509 public:

1511 TriggerOnComplete(OnCompleteFn OnComplete)

1512 : OnComplete(std::move(OnComplete)) {}

1513 ~TriggerOnComplete() { OnComplete(std::move(LookupResult)); }

1514 void reportResult(Error Err) {

1515 std::lock_guardstd::mutex Lock(ResultMutex);

1516 LookupResult = joinErrors(std::move(LookupResult), std::move(Err));

1517 }

1518

1519 private:

1520 std::mutex ResultMutex;

1522 OnCompleteFn OnComplete;

1523 };

1524

1526 dbgs() << "Issuing init-symbol lookup:\n";

1527 for (auto &KV : InitSyms)

1528 dbgs() << " " << KV.first->getName() << ": " << KV.second << "\n";

1529 });

1530

1531 auto TOC = std::make_shared(std::move(OnComplete));

1532

1533 for (auto &KV : InitSyms) {

1534 auto *JD = KV.first;

1535 auto Names = std::move(KV.second);

1541 TOC->reportResult(Result.takeError());

1542 },

1544 }

1545}

1546

1548

1549 if (MR)

1550 MR->failMaterialization();

1551}

1552

1554 OS << "Materialization task: " << MU->getName() << " in "

1555 << MR->getTargetJITDylib().getName();

1556}

1557

1559 assert(MU && "MU should not be null");

1560 assert(MR && "MR should not be null");

1561 MU->materialize(std::move(MR));

1562}

1563

1565

1567

1570

1571 this->EPC->ES = this;

1572}

1573

1575

1576 assert(!SessionOpen &&

1577 "Session still open. Did you forget to call endSession?");

1578}

1579

1581 LLVM_DEBUG(dbgs() << "Ending ExecutionSession " << this << "\n");

1582

1584

1585#ifdef EXPENSIVE_CHECKS

1586 verifySessionState("Entering ExecutionSession::endSession");

1587#endif

1588

1589 SessionOpen = false;

1590 return JDs;

1591 });

1592

1593 std::reverse(JDsToRemove.begin(), JDsToRemove.end());

1594

1596

1597 Err = joinErrors(std::move(Err), EPC->disconnect());

1598

1599 return Err;

1600}

1601

1605

1608 assert(!ResourceManagers.empty() && "No managers registered");

1609 if (ResourceManagers.back() == &RM)

1610 ResourceManagers.pop_back();

1611 else {

1612 auto I = llvm::find(ResourceManagers, &RM);

1613 assert(I != ResourceManagers.end() && "RM not registered");

1614 ResourceManagers.erase(I);

1615 }

1616 });

1617}

1618

1621 for (auto &JD : JDs)

1622 if (JD->getName() == Name)

1623 return JD.get();

1624 return nullptr;

1625 });

1626}

1627

1631 assert(SessionOpen && "Cannot create JITDylib after session is closed");

1632 JDs.push_back(new JITDylib(*this, std::move(Name)));

1633 return *JDs.back();

1634 });

1635}

1636

1639 if (P)

1640 if (auto Err = P->setupJITDylib(JD))

1641 return std::move(Err);

1642 return JD;

1643}

1644

1646

1648 for (auto &JD : JDsToRemove) {

1649 assert(JD->State == JITDylib::Open && "JD already closed");

1650 JD->State = JITDylib::Closing;

1652 assert(I != JDs.end() && "JD does not appear in session JDs");

1653 JDs.erase(I);

1654 }

1655 });

1656

1657

1659 for (auto JD : JDsToRemove) {

1660 Err = joinErrors(std::move(Err), JD->clear());

1661 if (P)

1662 Err = joinErrors(std::move(Err), P->teardownJITDylib(*JD));

1663 }

1664

1665

1667 for (auto &JD : JDsToRemove) {

1668 assert(JD->State == JITDylib::Closing && "JD should be closing");

1669 JD->State = JITDylib::Closed;

1670 assert(JD->Symbols.empty() && "JD.Symbols is not empty after clear");

1671 assert(JD->UnmaterializedInfos.empty() &&

1672 "JD.UnmaterializedInfos is not empty after clear");

1673 assert(JD->MaterializingInfos.empty() &&

1674 "JD.MaterializingInfos is not empty after clear");

1675 assert(JD->TrackerSymbols.empty() &&

1676 "TrackerSymbols is not empty after clear");

1677 JD->DefGenerators.clear();

1678 JD->LinkOrder.clear();

1679 }

1680 });

1681

1682 return Err;

1683}

1684

1687 if (JDs.empty())

1688 return std::vector();

1689

1690 auto &ES = JDs.front()->getExecutionSession();

1691 return ES.runSessionLocked([&]() -> Expected<std::vector> {

1693 std::vector Result;

1694

1695 for (auto &JD : JDs) {

1696

1697 if (JD->State != Open)

1699 "Error building link order: " + JD->getName() + " is defunct",

1701 if (Visited.count(JD.get()))

1702 continue;

1703

1706 Visited.insert(JD.get());

1707

1708 while (!WorkStack.empty()) {

1709 Result.push_back(std::move(WorkStack.back()));

1711

1713 auto &JD = *KV.first;

1714 if (!Visited.insert(&JD).second)

1715 continue;

1717 }

1718 }

1719 }

1721 });

1722}

1723

1731

1735

1739

1743

1744 OL_applyQueryPhase1(std::make_unique(

1745 K, std::move(SearchOrder), std::move(LookupSet),

1746 std::move(OnComplete)),

1748}

1749

1753

1754 std::promise<MSVCPExpected> ResultP;

1755 OL_applyQueryPhase1(std::make_unique(

1756 K, std::move(SearchOrder), std::move(LookupSet),

1758 ResultP.set_value(std::move(Result));

1759 }),

1761

1762 auto ResultF = ResultP.get_future();

1763 return ResultF.get();

1764}

1765

1771

1774 dbgs() << "Looking up " << Symbols << " in " << SearchOrder

1775 << " (required state: " << RequiredState << ")\n";

1776 });

1777 });

1778

1779

1780

1781

1782 dispatchOutstandingMUs();

1783

1784 auto Unresolved = std::move(Symbols);

1785 auto Q = std::make_shared(Unresolved, RequiredState,

1786 std::move(NotifyComplete));

1787

1788 auto IPLS = std::make_unique(

1789 K, SearchOrder, std::move(Unresolved), RequiredState, std::move(Q),

1790 std::move(RegisterDependencies));

1791

1792 OL_applyQueryPhase1(std::move(IPLS), Error::success());

1793}

1794

1800#if LLVM_ENABLE_THREADS

1801

1802 std::promise<MSVCPExpected> PromisedResult;

1803

1805 PromisedResult.set_value(std::move(R));

1806 };

1807

1808#else

1811

1814 if (R)

1815 Result = std::move(*R);

1816 else

1817 ResolutionError = R.takeError();

1818 };

1819#endif

1820

1821

1822 lookup(K, SearchOrder, std::move(Symbols), RequiredState,

1823 std::move(NotifyComplete), RegisterDependencies);

1824

1825#if LLVM_ENABLE_THREADS

1826 return PromisedResult.get_future().get();

1827#else

1828 if (ResolutionError)

1829 return std::move(ResolutionError);

1830

1832#endif

1833}

1834

1839

1842 assert(ResultMap->size() == 1 && "Unexpected number of results");

1843 assert(ResultMap->count(Name) && "Missing result for symbol");

1844 return std::move(ResultMap->begin()->second);

1845 } else

1846 return ResultMap.takeError();

1847}

1848

1854

1858 return lookup(SearchOrder, intern(Name), RequiredState);

1859}

1860

1863

1867 if (!TagSyms)

1868 return TagSyms.takeError();

1869

1870

1871 std::lock_guardstd::mutex Lock(JITDispatchHandlersMutex);

1872

1873

1874 for (auto &[TagName, TagSym] : *TagSyms) {

1875 auto TagAddr = TagSym.getAddress();

1876 if (JITDispatchHandlers.count(TagAddr))

1878 " (for " + *TagName +

1879 ") already registered",

1881 }

1882

1883

1884 for (auto &[TagName, TagSym] : *TagSyms) {

1885 auto TagAddr = TagSym.getAddress();

1886 auto I = WFs.find(TagName);

1888 "JITDispatchHandler implementation missing");

1889 JITDispatchHandlers[TagAddr] =

1890 std::make_shared(std::move(I->second));

1892 dbgs() << "Associated function tag \"" << *TagName << "\" ("

1893 << formatv("{0:x}", TagAddr) << ") with handler\n";

1894 });

1895 }

1896

1898}

1899

1903

1904 std::shared_ptr F;

1905 {

1906 std::lock_guardstd::mutex Lock(JITDispatchHandlersMutex);

1907 auto I = JITDispatchHandlers.find(HandlerFnTagAddr);

1908 if (I != JITDispatchHandlers.end())

1909 F = I->second;

1910 }

1911

1912 if (F)

1913 (*F)(std::move(SendResult), ArgBuffer.data(), ArgBuffer.size());

1914 else

1916 ("No function registered for tag " +

1917 formatv("{0:x16}", HandlerFnTagAddr))

1918 .str()));

1919}

1920

1923 for (auto &JD : JDs)

1924 JD->dump(OS);

1925 });

1926}

1927

1928#ifdef EXPENSIVE_CHECKS

1929bool ExecutionSession::verifySessionState(Twine Phase) {

1931 bool AllOk = true;

1932

1933 for (auto &JD : JDs) {

1934

1936 auto &Stream = errs();

1937 if (AllOk)

1938 Stream << "ERROR: Bad ExecutionSession state detected " << Phase

1939 << "\n";

1940 Stream << " In JITDylib " << JD->getName() << ", ";

1941 AllOk = false;

1942 return Stream;

1943 };

1944

1945 if (JD->State != JITDylib::Open) {

1946 LogFailure()

1947 << "state is not Open, but JD is in ExecutionSession list.";

1948 }

1949

1950

1951

1952

1953

1954

1955 for (auto &[Sym, Entry] : JD->Symbols) {

1956

1958 if (Entry.getAddress()) {

1959 LogFailure() << "symbol " << Sym << " has state "

1960 << Entry.getState()

1961 << " (not-yet-resolved) but non-null address "

1962 << Entry.getAddress() << ".\n";

1963 }

1964 }

1965

1966

1967 auto UMIItr = JD->UnmaterializedInfos.find(Sym);

1968 if (Entry.hasMaterializerAttached()) {

1969 if (UMIItr == JD->UnmaterializedInfos.end()) {

1970 LogFailure() << "symbol " << Sym

1971 << " entry claims materializer attached, but "

1972 "UnmaterializedInfos has no corresponding entry.\n";

1973 }

1974 } else if (UMIItr != JD->UnmaterializedInfos.end()) {

1975 LogFailure()

1976 << "symbol " << Sym

1977 << " entry claims no materializer attached, but "

1978 "UnmaterializedInfos has an unexpected entry for it.\n";

1979 }

1980 }

1981

1982

1983

1984 for (auto &[Sym, UMI] : JD->UnmaterializedInfos) {

1985 auto SymItr = JD->Symbols.find(Sym);

1986 if (SymItr == JD->Symbols.end()) {

1987 LogFailure()

1988 << "symbol " << Sym

1989 << " has UnmaterializedInfos entry, but no Symbols entry.\n";

1990 }

1991 }

1992

1993

1994 for (auto &[Sym, MII] : JD->MaterializingInfos) {

1995

1996 auto SymItr = JD->Symbols.find(Sym);

1997 if (SymItr == JD->Symbols.end()) {

1998

1999

2000 LogFailure()

2001 << "symbol " << Sym

2002 << " has MaterializingInfos entry, but no Symbols entry.\n";

2003 } else {

2004

2005

2006

2008 LogFailure()

2009 << "symbol " << Sym

2010 << " is in Ready state, should not have MaterializingInfo.\n";

2011 }

2012

2013

2014 auto CurState = static_cast<SymbolState>(

2015 static_cast<std::underlying_type_t>(

2016 SymItr->second.getState()) + 1);

2017 for (auto &Q : MII.PendingQueries) {

2018 if (Q->getRequiredState() != CurState) {

2019 if (Q->getRequiredState() > CurState)

2020 CurState = Q->getRequiredState();

2021 else

2022 LogFailure() << "symbol " << Sym

2023 << " has stale or misordered queries.\n";

2024 }

2025 }

2026 }

2027 }

2028 }

2029

2030 return AllOk;

2031 });

2032}

2033#endif

2034

2035void ExecutionSession::dispatchOutstandingMUs() {

2036 LLVM_DEBUG(dbgs() << "Dispatching MaterializationUnits...\n");

2037 while (true) {

2038 std::optional<std::pair<std::unique_ptr,

2039 std::unique_ptr>>

2040 JMU;

2041

2042 {

2043 std::lock_guardstd::recursive\_mutex Lock(OutstandingMUsMutex);

2044 if (!OutstandingMUs.empty()) {

2045 JMU.emplace(std::move(OutstandingMUs.back()));

2046 OutstandingMUs.pop_back();

2047 }

2048 }

2049

2050 if (!JMU)

2051 break;

2052

2053 assert(JMU->first && "No MU?");

2054 LLVM_DEBUG(dbgs() << " Dispatching \"" << JMU->first->getName() << "\"\n");

2055 dispatchTask(std::make_unique(std::move(JMU->first),

2056 std::move(JMU->second)));

2057 }

2058 LLVM_DEBUG(dbgs() << "Done dispatching MaterializationUnits.\n");

2059}

2060

2063 dbgs() << "In " << RT.getJITDylib().getName() << " removing tracker "

2064 << formatv("{0:x}", RT.getKeyUnsafe()) << "\n";

2065 });

2066 std::vector<ResourceManager *> CurrentResourceManagers;

2067

2068 JITDylib::RemoveTrackerResult R;

2069

2071 CurrentResourceManagers = ResourceManagers;

2072 RT.makeDefunct();

2073 R = RT.getJITDylib().IL_removeTracker(RT);

2074 });

2075

2076

2077 R.DefunctMUs.clear();

2078

2080

2081 auto &JD = RT.getJITDylib();

2082 for (auto *L : reverse(CurrentResourceManagers))

2084 L->handleRemoveResources(JD, RT.getKeyUnsafe()));

2085

2086 for (auto &Q : R.QueriesToFail)

2088 R.FailedSymbols));

2089

2090 return Err;

2091}

2092

2093void ExecutionSession::transferResourceTracker(ResourceTracker &DstRT,

2096 dbgs() << "In " << SrcRT.getJITDylib().getName()

2097 << " transfering resources from tracker "

2098 << formatv("{0:x}", SrcRT.getKeyUnsafe()) << " to tracker "

2099 << formatv("{0:x}", DstRT.getKeyUnsafe()) << "\n";

2100 });

2101

2102

2103 if (&DstRT == &SrcRT)

2104 return;

2105

2106 assert(&DstRT.getJITDylib() == &SrcRT.getJITDylib() &&

2107 "Can't transfer resources between JITDylibs");

2109 SrcRT.makeDefunct();

2110 auto &JD = DstRT.getJITDylib();

2111 JD.transferTracker(DstRT, SrcRT);

2112 for (auto *L : reverse(ResourceManagers))

2113 L->handleTransferResources(JD, DstRT.getKeyUnsafe(),

2114 SrcRT.getKeyUnsafe());

2115 });

2116}

2117

2118void ExecutionSession::destroyResourceTracker(ResourceTracker &RT) {

2121 dbgs() << "In " << RT.getJITDylib().getName() << " destroying tracker "

2122 << formatv("{0:x}", RT.getKeyUnsafe()) << "\n";

2123 });

2124 if (!RT.isDefunct())

2125 transferResourceTracker(*RT.getJITDylib().getDefaultResourceTracker(),

2126 RT);

2127 });

2128}

2129

2130Error ExecutionSession::IL_updateCandidatesFor(

2133 return Candidates.forEachWithRemoval(

2134 [&](const SymbolStringPtr &Name,

2136

2137

2138 auto SymI = JD.Symbols.find(Name);

2139 if (SymI == JD.Symbols.end())

2140 return false;

2141

2142

2143

2144

2145

2146

2147 if (!SymI->second.getFlags().isExported() &&

2149 if (NonCandidates)

2150 NonCandidates->add(Name, SymLookupFlags);

2151 return true;

2152 }

2153

2154

2155

2156

2157

2158

2159 if (SymI->second.getFlags().hasMaterializationSideEffectsOnly() &&

2163

2164

2165

2166 if (SymI->second.getFlags().hasError()) {

2167 auto FailedSymbolsMap = std::make_shared();

2168 (*FailedSymbolsMap)[&JD] = {Name};

2170 std::move(FailedSymbolsMap));

2171 }

2172

2173

2174 return true;

2175 });

2176}

2177

2178void ExecutionSession::OL_resumeLookupAfterGeneration(

2180

2182 "Should not be called for not-in-generator lookups");

2184

2186

2187 if (auto DG = IPLS.CurDefGeneratorStack.back().lock()) {

2188 IPLS.CurDefGeneratorStack.pop_back();

2189 std::lock_guardstd::mutex Lock(DG->M);

2190

2191

2192

2193 if (DG->PendingLookups.empty()) {

2194 DG->InUse = false;

2195 return;

2196 }

2197

2198

2199 LS = std::move(DG->PendingLookups.front());

2200 DG->PendingLookups.pop_front();

2201 }

2202

2203 if (LS.IPLS) {

2205 dispatchTask(std::make_unique(std::move(LS)));

2206 }

2207}

2208

2209void ExecutionSession::OL_applyQueryPhase1(

2210 std::unique_ptr IPLS, Error Err) {

2211

2213 dbgs() << "Entering OL_applyQueryPhase1:\n"

2214 << " Lookup kind: " << IPLS->K << "\n"

2215 << " Search order: " << IPLS->SearchOrder

2216 << ", Current index = " << IPLS->CurSearchOrderIndex

2217 << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n"

2218 << " Lookup set: " << IPLS->LookupSet << "\n"

2219 << " Definition generator candidates: "

2220 << IPLS->DefGeneratorCandidates << "\n"

2221 << " Definition generator non-candidates: "

2222 << IPLS->DefGeneratorNonCandidates << "\n";

2223 });

2224

2226 OL_resumeLookupAfterGeneration(*IPLS);

2227

2229 "Lookup should not be in InGenerator state here");

2230

2231

2232

2233

2234

2235

2236 while (IPLS->CurSearchOrderIndex != IPLS->SearchOrder.size()) {

2237

2238

2239

2240

2241 if (Err)

2242 return IPLS->fail(std::move(Err));

2243

2244

2245 auto &KV = IPLS->SearchOrder[IPLS->CurSearchOrderIndex];

2246 auto &JD = *KV.first;

2247 auto JDLookupFlags = KV.second;

2248

2250 dbgs() << "Visiting \"" << JD.getName() << "\" (" << JDLookupFlags

2251 << ") with lookup set " << IPLS->LookupSet << ":\n";

2252 });

2253

2254

2255 if (IPLS->NewJITDylib) {

2256

2257

2258

2259 SymbolLookupSet Tmp;

2260 std::swap(IPLS->DefGeneratorNonCandidates, Tmp);

2261 IPLS->DefGeneratorCandidates.append(std::move(Tmp));

2262

2264 dbgs() << " First time visiting " << JD.getName()

2265 << ", resetting candidate sets and building generator stack\n";

2266 });

2267

2268

2270 IPLS->CurDefGeneratorStack.reserve(JD.DefGenerators.size());

2272 reverse(JD.DefGenerators));

2273 });

2274

2275

2276 IPLS->NewJITDylib = false;

2277 }

2278

2279

2280

2282

2283

2284 LLVM_DEBUG(dbgs() << " Updating candidate set...\n");

2285 Err = IL_updateCandidatesFor(

2286 JD, JDLookupFlags, IPLS->DefGeneratorCandidates,

2287 JD.DefGenerators.empty() ? nullptr

2288 : &IPLS->DefGeneratorNonCandidates);

2290 dbgs() << " Remaining candidates = " << IPLS->DefGeneratorCandidates

2291 << "\n";

2292 });

2293

2294

2295

2296

2298 IPLS->DefGeneratorCandidates.empty())

2299 OL_resumeLookupAfterGeneration(*IPLS);

2300 });

2301

2302

2303

2304 if (Err)

2305 return IPLS->fail(std::move(Err));

2306

2307

2309 if (IPLS->CurDefGeneratorStack.empty())

2310 LLVM_DEBUG(dbgs() << " No generators to run for this JITDylib.\n");

2311 else if (IPLS->DefGeneratorCandidates.empty())

2312 LLVM_DEBUG(dbgs() << " No candidates to generate.\n");

2313 else

2314 dbgs() << " Running " << IPLS->CurDefGeneratorStack.size()

2315 << " remaining generators for "

2316 << IPLS->DefGeneratorCandidates.size() << " candidates\n";

2317 });

2318 while (!IPLS->CurDefGeneratorStack.empty() &&

2319 !IPLS->DefGeneratorCandidates.empty()) {

2320 auto DG = IPLS->CurDefGeneratorStack.back().lock();

2321

2322 if (!DG)

2324 "DefinitionGenerator removed while lookup in progress",

2326

2327

2328

2329

2330

2331

2332

2333

2334

2335

2337 std::lock_guardstd::mutex Lock(DG->M);

2338 if (DG->InUse) {

2339 DG->PendingLookups.push_back(std::move(IPLS));

2340 return;

2341 }

2342 DG->InUse = true;

2343 }

2344

2346

2347 auto K = IPLS->K;

2348 auto &LookupSet = IPLS->DefGeneratorCandidates;

2349

2350

2351

2352 {

2353 LLVM_DEBUG(dbgs() << " Attempting to generate " << LookupSet << "\n");

2355 Err = DG->tryToGenerate(LS, K, JD, JDLookupFlags, LookupSet);

2356 IPLS = std::move(LS.IPLS);

2357 }

2358

2359

2360

2361 if (IPLS)

2362 OL_resumeLookupAfterGeneration(*IPLS);

2363

2364

2365 if (Err) {

2367 dbgs() << " Error attempting to generate " << LookupSet << "\n";

2368 });

2369 assert(IPLS && "LS cannot be retained if error is returned");

2370 return IPLS->fail(std::move(Err));

2371 }

2372

2373

2374 if (!IPLS) {

2376 { dbgs() << " LookupState captured. Exiting phase1 for now.\n"; });

2377 return;

2378 }

2379

2380

2381

2383 LLVM_DEBUG(dbgs() << " Updating candidate set post-generation\n");

2384 Err = IL_updateCandidatesFor(

2385 JD, JDLookupFlags, IPLS->DefGeneratorCandidates,

2386 JD.DefGenerators.empty() ? nullptr

2387 : &IPLS->DefGeneratorNonCandidates);

2388 });

2389

2390

2391 if (Err) {

2392 LLVM_DEBUG(dbgs() << " Error encountered while updating candidates\n");

2393 return IPLS->fail(std::move(Err));

2394 }

2395 }

2396

2397 if (IPLS->DefGeneratorCandidates.empty() &&

2398 IPLS->DefGeneratorNonCandidates.empty()) {

2399

2401 IPLS->CurSearchOrderIndex = IPLS->SearchOrder.size();

2402 break;

2403 } else {

2404

2405

2406 LLVM_DEBUG(dbgs() << "Phase 1 moving to next JITDylib.\n");

2407 ++IPLS->CurSearchOrderIndex;

2408 IPLS->NewJITDylib = true;

2409 }

2410 }

2411

2412

2413 IPLS->DefGeneratorCandidates.remove_if(

2414 [](const SymbolStringPtr &Name, SymbolLookupFlags SymLookupFlags) {

2416 });

2417

2418

2419

2420

2421 if (IPLS->DefGeneratorCandidates.empty()) {

2423 IPLS->complete(std::move(IPLS));

2424 } else {

2425 LLVM_DEBUG(dbgs() << "Phase 1 failed with unresolved symbols.\n");

2428 }

2429}

2430

2431void ExecutionSession::OL_completeLookup(

2432 std::unique_ptr IPLS,

2433 std::shared_ptr Q,

2435

2437 dbgs() << "Entering OL_completeLookup:\n"

2438 << " Lookup kind: " << IPLS->K << "\n"

2439 << " Search order: " << IPLS->SearchOrder

2440 << ", Current index = " << IPLS->CurSearchOrderIndex

2441 << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n"

2442 << " Lookup set: " << IPLS->LookupSet << "\n"

2443 << " Definition generator candidates: "

2444 << IPLS->DefGeneratorCandidates << "\n"

2445 << " Definition generator non-candidates: "

2446 << IPLS->DefGeneratorNonCandidates << "\n";

2447 });

2448

2449 bool QueryComplete = false;

2450 DenseMap<JITDylib *, JITDylib::UnmaterializedInfosList> CollectedUMIs;

2451

2453 for (auto &KV : IPLS->SearchOrder) {

2454 auto &JD = *KV.first;

2455 auto JDLookupFlags = KV.second;

2457 dbgs() << "Visiting \"" << JD.getName() << "\" (" << JDLookupFlags

2458 << ") with lookup set " << IPLS->LookupSet << ":\n";

2459 });

2460

2461 auto Err = IPLS->LookupSet.forEachWithRemoval(

2462 [&](const SymbolStringPtr &Name,

2465 dbgs() << " Attempting to match \"" << Name << "\" ("

2466 << SymLookupFlags << ")... ";

2467 });

2468

2469

2470

2471 auto SymI = JD.Symbols.find(Name);

2472 if (SymI == JD.Symbols.end()) {

2474 return false;

2475 }

2476

2477

2478

2479 if (!SymI->second.getFlags().isExported() &&

2480 JDLookupFlags ==

2483 return false;

2484 }

2485

2486

2487

2488

2489

2490

2491 if (SymI->second.getFlags().hasMaterializationSideEffectsOnly() &&

2494 dbgs() << "error: "

2495 "required, but symbol is has-side-effects-only\n";

2496 });

2499 }

2500

2501

2502

2503 if (SymI->second.getFlags().hasError()) {

2504 LLVM_DEBUG(dbgs() << "error: symbol is in error state\n");

2505 auto FailedSymbolsMap = std::make_shared();

2506 (*FailedSymbolsMap)[&JD] = {Name};

2509 }

2510

2511

2512

2513

2514

2515 if (SymI->second.getState() >= Q->getRequiredState()) {

2517 << "matched, symbol already in required state\n");

2518 Q->notifySymbolMetRequiredState(Name, SymI->second.getSymbol());

2519

2520

2521

2523 Q->addQueryDependence(JD, Name);

2524

2525 return true;

2526 }

2527

2528

2529

2530

2531 if (SymI->second.hasMaterializerAttached()) {

2532 assert(SymI->second.getAddress() == ExecutorAddr() &&

2533 "Symbol not resolved but already has address?");

2534 auto UMII = JD.UnmaterializedInfos.find(Name);

2535 assert(UMII != JD.UnmaterializedInfos.end() &&

2536 "Lazy symbol should have UnmaterializedInfo");

2537

2538 auto UMI = UMII->second;

2539 assert(UMI->MU && "Materializer should not be null");

2540 assert(UMI->RT && "Tracker should not be null");

2542 dbgs() << "matched, preparing to dispatch MU@" << UMI->MU.get()

2543 << " (" << UMI->MU->getName() << ")\n";

2544 });

2545

2546

2547

2548 for (auto &KV : UMI->MU->getSymbols()) {

2549 auto SymK = JD.Symbols.find(KV.first);

2550 assert(SymK != JD.Symbols.end() &&

2551 "No entry for symbol covered by MaterializationUnit");

2552 SymK->second.setMaterializerAttached(false);

2554 JD.UnmaterializedInfos.erase(KV.first);

2555 }

2556

2557

2558 CollectedUMIs[&JD].push_back(std::move(UMI));

2559 } else

2561

2562

2563

2566 "By this line the symbol should be materializing");

2567 auto &MI = JD.MaterializingInfos[Name];

2568 MI.addQuery(Q);

2569 Q->addQueryDependence(JD, Name);

2570

2571 return true;

2572 });

2573

2574 JD.shrinkMaterializationInfoMemory();

2575

2576

2577 if (Err) {

2578

2580 dbgs() << "Lookup failed. Detaching query and replacing MUs.\n";

2581 });

2582

2583

2584 Q->detach();

2585

2586

2587 for (auto &KV : CollectedUMIs) {

2588 auto &JD = *KV.first;

2589 for (auto &UMI : KV.second)

2590 for (auto &KV2 : UMI->MU->getSymbols()) {

2591 assert(!JD.UnmaterializedInfos.count(KV2.first) &&

2592 "Unexpected materializer in map");

2593 auto SymI = JD.Symbols.find(KV2.first);

2594 assert(SymI != JD.Symbols.end() && "Missing symbol entry");

2596 "Can not replace symbol that is not materializing");

2597 assert(!SymI->second.hasMaterializerAttached() &&

2598 "MaterializerAttached flag should not be set");

2599 SymI->second.setMaterializerAttached(true);

2600 JD.UnmaterializedInfos[KV2.first] = UMI;

2601 }

2602 }

2603

2604 return Err;

2605 }

2606 }

2607

2608 LLVM_DEBUG(dbgs() << "Stripping unmatched weakly-referenced symbols\n");

2609 IPLS->LookupSet.forEachWithRemoval(

2610 [&](const SymbolStringPtr &Name, SymbolLookupFlags SymLookupFlags) {

2612 Q->dropSymbol(Name);

2613 return true;

2614 } else

2615 return false;

2616 });

2617

2618 if (!IPLS->LookupSet.empty()) {

2619 LLVM_DEBUG(dbgs() << "Failing due to unresolved symbols\n");

2621 IPLS->LookupSet.getSymbolNames());

2622 }

2623

2624

2625 QueryComplete = Q->isComplete();

2626

2628 dbgs() << "Query successfully "

2629 << (QueryComplete ? "completed" : "lodged") << "\n";

2630 });

2631

2632

2633 if (!CollectedUMIs.empty()) {

2634 std::lock_guardstd::recursive\_mutex Lock(OutstandingMUsMutex);

2635

2637 for (auto &KV : CollectedUMIs) {

2639 auto &JD = *KV.first;

2640 dbgs() << " For " << JD.getName() << ": Adding " << KV.second.size()

2641 << " MUs.\n";

2642 });

2643 for (auto &UMI : KV.second) {

2644 auto MR = createMaterializationResponsibility(

2645 *UMI->RT, std::move(UMI->MU->SymbolFlags),

2646 std::move(UMI->MU->InitSymbol));

2647 OutstandingMUs.push_back(

2648 std::make_pair(std::move(UMI->MU), std::move(MR)));

2649 }

2650 }

2651 } else

2653

2654 if (RegisterDependencies && !Q->QueryRegistrations.empty()) {

2656 RegisterDependencies(Q->QueryRegistrations);

2657 } else

2658 LLVM_DEBUG(dbgs() << "No dependencies to register\n");

2659

2661 });

2662

2663 if (LodgingErr) {

2665 Q->detach();

2666 Q->handleFailed(std::move(LodgingErr));

2667 return;

2668 }

2669

2670 if (QueryComplete) {

2672 Q->handleComplete(*this);

2673 }

2674

2675 dispatchOutstandingMUs();

2676}

2677

2678void ExecutionSession::OL_completeLookupFlags(

2679 std::unique_ptr IPLS,

2680 unique_function<void(Expected)> OnComplete) {

2681

2684 dbgs() << "Entering OL_completeLookupFlags:\n"

2685 << " Lookup kind: " << IPLS->K << "\n"

2686 << " Search order: " << IPLS->SearchOrder

2687 << ", Current index = " << IPLS->CurSearchOrderIndex

2688 << (IPLS->NewJITDylib ? " (entering new JITDylib)" : "") << "\n"

2689 << " Lookup set: " << IPLS->LookupSet << "\n"

2690 << " Definition generator candidates: "

2691 << IPLS->DefGeneratorCandidates << "\n"

2692 << " Definition generator non-candidates: "

2693 << IPLS->DefGeneratorNonCandidates << "\n";

2694 });

2695

2697

2698

2699 for (auto &KV : IPLS->SearchOrder) {

2700 auto &JD = *KV.first;

2701 auto JDLookupFlags = KV.second;

2703 dbgs() << "Visiting \"" << JD.getName() << "\" (" << JDLookupFlags

2704 << ") with lookup set " << IPLS->LookupSet << ":\n";

2705 });

2706

2707 IPLS->LookupSet.forEachWithRemoval([&](const SymbolStringPtr &Name,

2710 dbgs() << " Attempting to match \"" << Name << "\" ("

2711 << SymLookupFlags << ")... ";

2712 });

2713

2714

2715

2716 auto SymI = JD.Symbols.find(Name);

2717 if (SymI == JD.Symbols.end()) {

2719 return false;

2720 }

2721

2722

2723 if (!SymI->second.getFlags().isExported() &&

2726 return false;

2727 }

2728

2730 dbgs() << "matched, \"" << Name << "\" -> " << SymI->second.getFlags()

2731 << "\n";

2732 });

2733 Result[Name] = SymI->second.getFlags();

2734 return true;

2735 });

2736 }

2737

2738

2739 IPLS->LookupSet.remove_if(

2740 [](const SymbolStringPtr &Name, SymbolLookupFlags SymLookupFlags) {

2742 });

2743

2744 if (!IPLS->LookupSet.empty()) {

2745 LLVM_DEBUG(dbgs() << "Failing due to unresolved symbols\n");

2747 IPLS->LookupSet.getSymbolNames());

2748 }

2749

2752 });

2753

2754

2755 LLVM_DEBUG(dbgs() << "Sending result to handler.\n");

2756 OnComplete(std::move(Result));

2757}

2758

2759void ExecutionSession::OL_destroyMaterializationResponsibility(

2761

2762 assert(MR.SymbolFlags.empty() &&

2763 "All symbols should have been explicitly materialized or failed");

2764 MR.JD.unlinkMaterializationResponsibility(MR);

2765}

2766

2767SymbolNameSet ExecutionSession::OL_getRequestedSymbols(

2769 return MR.JD.getRequestedSymbols(MR.SymbolFlags);

2770}

2771

2775 dbgs() << "In " << MR.JD.getName() << " resolving " << Symbols << "\n";

2776 });

2777#ifndef NDEBUG

2778 for (auto &KV : Symbols) {

2779 auto I = MR.SymbolFlags.find(KV.first);

2780 assert(I != MR.SymbolFlags.end() &&

2781 "Resolving symbol outside this responsibility set");

2782 assert(I->second.hasMaterializationSideEffectsOnly() &&

2783 "Can't resolve materialization-side-effects-only symbol");

2786 assert((KV.second.getFlags() & WeakOrCommon) &&

2787 "Common symbols must be resolved as common or weak");

2788 assert((KV.second.getFlags() & ~WeakOrCommon) ==

2790 "Resolving symbol with incorrect flags");

2791 } else

2792 assert(KV.second.getFlags() == I->second &&

2793 "Resolving symbol with incorrect flags");

2794 }

2795#endif

2796

2797 return MR.JD.resolve(MR, Symbols);

2798}

2799

2801ExecutionSession::IL_getSymbolState(JITDylib *JD,

2803 if (JD->State != JITDylib::Open)

2804 return WaitingOnGraph::ExternalState::Failed;

2805

2806 auto I = JD->Symbols.find_as(Name);

2807

2808

2809 if (I == JD->Symbols.end())

2810 return WaitingOnGraph::ExternalState::Failed;

2811

2812 if (I->second.getFlags().hasError())

2813 return WaitingOnGraph::ExternalState::Failed;

2814

2816 return WaitingOnGraph::ExternalState::Ready;

2817

2818 return WaitingOnGraph::ExternalState::None;

2819}

2820

2821template <typename UpdateSymbolFn, typename UpdateQueryFn>

2822void ExecutionSession::IL_collectQueries(

2823 JITDylib::AsynchronousSymbolQuerySet &Qs,

2825 UpdateSymbolFn &&UpdateSymbol, UpdateQueryFn &&UpdateQuery) {

2826

2827 for (auto &[JD, Symbols] : QualifiedSymbols) {

2828

2829

2830

2831

2832 assert(JD->State == JITDylib::Open &&

2833 "WaitingOnGraph includes definition in defunct JITDylib");

2834 for (auto &Symbol : Symbols) {

2835

2836 auto I = JD->Symbols.find_as(Symbol);

2837 assert(I != JD->Symbols.end() &&

2838 "Failed Symbol missing from JD symbol table");

2839 auto &Entry = I->second;

2840 UpdateSymbol(Entry);

2841

2842

2843 auto J = JD->MaterializingInfos.find_as(Symbol);

2844 if (J != JD->MaterializingInfos.end()) {

2845 for (auto &Q : J->second.takeAllPendingQueries()) {

2846 UpdateQuery(*Q, *JD, Symbol, Entry);

2847 Qs.insert(std::move(Q));

2848 }

2849 JD->MaterializingInfos.erase(J);

2850 }

2851 }

2852 }

2853}

2854

2855ExpectedExecutionSession::EmitQueries

2857 WaitingOnGraph::SimplifyResult SR) {

2858

2859 if (MR.RT->isDefunct())

2861

2862 auto &TargetJD = MR.getTargetJITDylib();

2863 if (TargetJD.State != JITDylib::Open)

2865 " is defunct",

2867

2868#ifdef EXPENSIVE_CHECKS

2869 verifySessionState("entering ExecutionSession::IL_emit");

2870#endif

2871

2872 auto ER = G.emit(std::move(SR),

2873 [this](JITDylib *JD, NonOwningSymbolStringPtr Name) {

2874 return IL_getSymbolState(JD, Name);

2875 });

2876

2877 EmitQueries EQ;

2878

2879

2880 for (auto &SN : ER.Failed)

2881 IL_collectQueries(

2882 EQ.Failed, SN->defs(),

2883 [](JITDylib::SymbolTableEntry &E) {

2884 E.setFlags(E.getFlags() = JITSymbolFlags::HasError);

2885 },

2886 [&](AsynchronousSymbolQuery &Q, JITDylib &JD,

2887 NonOwningSymbolStringPtr Name, JITDylib::SymbolTableEntry &E) {

2888 auto &FS = EQ.FailedSymsForQuery[&Q];

2889 if (!FS)

2890 FS = std::make_shared();

2891 (*FS)[&JD].insert(SymbolStringPtr(Name));

2892 });

2893

2894 for (auto &FQ : EQ.Failed)

2895 FQ->detach();

2896

2897 for (auto &SN : ER.Ready)

2898 IL_collectQueries(

2899 EQ.Completed, SN->defs(),

2900 [](JITDylib::SymbolTableEntry &E) { E.setState(SymbolState::Ready); },

2901 [](AsynchronousSymbolQuery &Q, JITDylib &JD,

2902 NonOwningSymbolStringPtr Name, JITDylib::SymbolTableEntry &E) {

2903 Q.notifySymbolMetRequiredState(SymbolStringPtr(Name), E.getSymbol());

2904 });

2905

2906

2907

2908 for (auto it = EQ.Completed.begin(), end = EQ.Completed.end(); it != end;) {

2909 if ((*it)->isComplete()) {

2910 ++it;

2911 } else {

2912 it = EQ.Completed.erase(it);

2913 }

2914 }

2915

2916#ifdef EXPENSIVE_CHECKS

2917 verifySessionState("exiting ExecutionSession::IL_emit");

2918#endif

2919

2920 return std::move(EQ);

2921}

2922

2923Error ExecutionSession::OL_notifyEmitted(

2927 dbgs() << "In " << MR.JD.getName() << " emitting " << MR.SymbolFlags

2928 << "\n";

2929 if (!DepGroups.empty()) {

2930 dbgs() << " Initial dependencies:\n";

2931 for (auto &SDG : DepGroups) {

2932 dbgs() << " Symbols: " << SDG.Symbols

2933 << ", Dependencies: " << SDG.Dependencies << "\n";

2934 }

2935 }

2936 });

2937

2938#ifndef NDEBUG

2940 for (auto &DG : DepGroups) {

2941 for (auto &Sym : DG.Symbols) {

2942 assert(MR.SymbolFlags.count(Sym) &&

2943 "DG contains dependence for symbol outside this MR");

2944 assert(Visited.insert(Sym).second &&

2945 "DG contains duplicate entries for Name");

2946 }

2947 }

2948#endif

2949

2950 std::vector<std::unique_ptrWaitingOnGraph::SuperNode> SNs;

2952 {

2953 auto &JDResidual = Residual[&MR.getTargetJITDylib()];

2954 for (auto &[Name, Flags] : MR.getSymbols())

2955 JDResidual.insert(NonOwningSymbolStringPtr(Name));

2956

2957 for (auto &SDG : DepGroups) {

2959 assert(!SDG.Symbols.empty());

2960 auto &JDDefs = Defs[&MR.getTargetJITDylib()];

2961 for (auto &Def : SDG.Symbols) {

2962 JDDefs.insert(NonOwningSymbolStringPtr(Def));

2963 JDResidual.erase(NonOwningSymbolStringPtr(Def));

2964 }

2966 if (!SDG.Dependencies.empty()) {

2967 for (auto &[JD, Syms] : SDG.Dependencies) {

2968 auto &JDDeps = Deps[JD];

2969 for (auto &Dep : Syms)

2970 JDDeps.insert(NonOwningSymbolStringPtr(Dep));

2971 }

2972 }

2973 SNs.push_back(std::make_uniqueWaitingOnGraph::SuperNode(

2974 std::move(Defs), std::move(Deps)));

2975 }

2976 if (!JDResidual.empty())

2977 SNs.push_back(std::make_uniqueWaitingOnGraph::SuperNode(

2979 }

2980

2982

2984 dbgs() << " Simplified dependencies:\n";

2985 for (auto &SN : SR.superNodes()) {

2986

2988 std::vector<JITDylib *> JDs;

2989 for (auto &[JD, _] : C)

2990 JDs.push_back(JD);

2992 return LHS->getName() < RHS->getName();

2993 });

2994 return JDs;

2995 };

2996

2998 std::vector Names(Elems.begin(), Elems.end());

2999 llvm::sort(Names, [](const NonOwningSymbolStringPtr &LHS,

3000 const NonOwningSymbolStringPtr &RHS) {

3002 });

3003 return Names;

3004 };

3005

3006 dbgs() << " Defs: {";

3007 for (auto *JD : SortedLibs(SN->defs())) {

3008 dbgs() << " (" << JD->getName() << ", [";

3009 for (auto &Sym : SortedNames(SN->defs()[JD]))

3010 dbgs() << " " << Sym;

3011 dbgs() << " ])";

3012 }

3013 dbgs() << " }, Deps: {";

3014 for (auto *JD : SortedLibs(SN->deps())) {

3015 dbgs() << " (" << JD->getName() << ", [";

3016 for (auto &Sym : SortedNames(SN->deps()[JD]))

3017 dbgs() << " " << Sym;

3018 dbgs() << " ])";

3019 }

3020 dbgs() << " }\n";

3021 }

3022 });

3023 auto EmitQueries =

3024 runSessionLocked([&]() { return IL_emit(MR, std::move(SR)); });

3025

3026

3027 if (!EmitQueries)

3028 return EmitQueries.takeError();

3029

3030

3031

3032

3033

3035 {

3036 for (auto &FQ : EmitQueries->Failed) {

3037 FQ->detach();

3038 assert(EmitQueries->FailedSymsForQuery.count(FQ.get()) &&

3039 "Missing failed symbols for query");

3040 auto FailedSyms = std::move(EmitQueries->FailedSymsForQuery[FQ.get()]);

3041 for (auto &[JD, Syms] : *FailedSyms) {

3042 auto &BadDepsForJD = BadDeps[JD];

3043 for (auto &Sym : Syms)

3044 BadDepsForJD.insert(Sym);

3045 }

3047 std::move(FailedSyms)));

3048 }

3049 }

3050

3051 for (auto &UQ : EmitQueries->Completed)

3052 UQ->handleComplete(*this);

3053

3054

3055 if (!BadDeps.empty()) {

3057

3058

3059

3060

3061 for (auto &[Name, Flags] : MR.getSymbols())

3062 BadNames.insert(Name);

3063 MR.SymbolFlags.clear();

3066 std::move(BadDeps), "dependencies removed or in error state");

3067 }

3068

3069 MR.SymbolFlags.clear();

3071}

3072

3073Error ExecutionSession::OL_defineMaterializing(

3075

3077 dbgs() << "In " << MR.JD.getName() << " defining materializing symbols "

3078 << NewSymbolFlags << "\n";

3079 });

3080 if (auto AcceptedDefs =

3081 MR.JD.defineMaterializing(MR, std::move(NewSymbolFlags))) {

3082

3083 for (auto &KV : *AcceptedDefs)

3084 MR.SymbolFlags.insert(KV);

3086 } else

3087 return AcceptedDefs.takeError();

3088}

3089

3090std::pair<JITDylib::AsynchronousSymbolQuerySet,

3091 std::shared_ptr>

3092ExecutionSession::IL_failSymbols(JITDylib &JD,

3094

3095#ifdef EXPENSIVE_CHECKS

3096 verifySessionState("entering ExecutionSession::IL_failSymbols");

3097#endif

3098

3099 JITDylib::AsynchronousSymbolQuerySet FailedQueries;

3100 auto Fail = [&](JITDylib *FailJD, NonOwningSymbolStringPtr FailSym) {

3101 auto I = FailJD->Symbols.find_as(FailSym);

3102 assert(I != FailJD->Symbols.end());

3104 auto J = FailJD->MaterializingInfos.find_as(FailSym);

3105 if (J != FailJD->MaterializingInfos.end()) {

3106 for (auto &Q : J->second.takeAllPendingQueries())

3107 FailedQueries.insert(std::move(Q));

3108 FailJD->MaterializingInfos.erase(J);

3109 }

3110 };

3111

3112 auto FailedSymbolsMap = std::make_shared();

3113

3114 {

3115 auto &FailedSymsForJD = (*FailedSymbolsMap)[&JD];

3116 for (auto &Sym : SymbolsToFail) {

3117 FailedSymsForJD.insert(Sym);

3118 Fail(&JD, NonOwningSymbolStringPtr(Sym));

3119 }

3120 }

3121

3123 auto &JDToFail = ToFail[&JD];

3124 for (auto &Sym : SymbolsToFail)

3125 JDToFail.insert(NonOwningSymbolStringPtr(Sym));

3126

3127 auto FailedSNs = G.fail(ToFail);

3128

3129 for (auto &SN : FailedSNs) {

3130 for (auto &[FailJD, Defs] : SN->defs()) {

3131 auto &FailedSymsForFailJD = (*FailedSymbolsMap)[FailJD];

3132 for (auto &Def : Defs) {

3133 FailedSymsForFailJD.insert(SymbolStringPtr(Def));

3134 Fail(FailJD, Def);

3135 }

3136 }

3137 }

3138

3139

3140 for (auto &Q : FailedQueries)

3141 Q->detach();

3142

3143#ifdef EXPENSIVE_CHECKS

3144 verifySessionState("exiting ExecutionSession::IL_failSymbols");

3145#endif

3146

3147 return std::make_pair(std::move(FailedQueries), std::move(FailedSymbolsMap));

3148}

3149

3151

3153 dbgs() << "In " << MR.JD.getName() << " failing materialization for "

3154 << MR.SymbolFlags << "\n";

3155 });

3156

3157 if (MR.SymbolFlags.empty())

3158 return;

3159

3161 for (auto &[Name, Flags] : MR.SymbolFlags)

3162 SymbolsToFail.push_back(Name);

3163 MR.SymbolFlags.clear();

3164

3165 JITDylib::AsynchronousSymbolQuerySet FailedQueries;

3166 std::shared_ptr FailedSymbols;

3167

3168 std::tie(FailedQueries, FailedSymbols) = runSessionLocked([&]() {

3169

3170 if (MR.RT->isDefunct())

3171 return std::pair<JITDylib::AsynchronousSymbolQuerySet,

3172 std::shared_ptr>();

3173 return IL_failSymbols(MR.getTargetJITDylib(), SymbolsToFail);

3174 });

3175

3176 for (auto &Q : FailedQueries) {

3177 Q->detach();

3178 Q->handleFailed(

3180 }

3181}

3182

3184 std::unique_ptr MU) {

3185 for (auto &KV : MU->getSymbols()) {

3186 assert(MR.SymbolFlags.count(KV.first) &&

3187 "Replacing definition outside this responsibility set");

3188 MR.SymbolFlags.erase(KV.first);

3189 }

3190

3191 if (MU->getInitializerSymbol() == MR.InitSymbol)

3192 MR.InitSymbol = nullptr;

3193

3194 LLVM_DEBUG(MR.JD.getExecutionSession().runSessionLocked([&]() {

3195 dbgs() << "In " << MR.JD.getName() << " replacing symbols with " << *MU

3196 << "\n";

3197 }););

3198

3199 return MR.JD.replace(MR, std::move(MU));

3200}

3201

3202Expected<std::unique_ptr>

3205

3206 SymbolStringPtr DelegatedInitSymbol;

3208

3209 for (auto &Name : Symbols) {

3210 auto I = MR.SymbolFlags.find(Name);

3211 assert(I != MR.SymbolFlags.end() &&

3212 "Symbol is not tracked by this MaterializationResponsibility "

3213 "instance");

3214

3215 DelegatedFlags[Name] = std::move(I->second);

3216 if (Name == MR.InitSymbol)

3217 std::swap(MR.InitSymbol, DelegatedInitSymbol);

3218

3219 MR.SymbolFlags.erase(I);

3220 }

3221

3222 return MR.JD.delegate(MR, std::move(DelegatedFlags),

3223 std::move(DelegatedInitSymbol));

3224}

3225

3226#ifndef NDEBUG

3227void ExecutionSession::dumpDispatchInfo(Task &T) {

3229 dbgs() << "Dispatching: ";

3230 T.printDescription(dbgs());

3231 dbgs() << "\n";

3232 });

3233}

3234#endif

3235

3236}

3237}

for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))

aarch64 falkor hwpf fix Falkor HW Prefetch Fix Late Phase

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

static StringRef getName(Value *V)

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

const T & front() const

front - Get the first element.

size_t size() const

size - Get the array size.

bool empty() const

empty - Check if the array is empty.

iterator find(const_arg_type_t< KeyT > Val)

bool erase(const KeyT &Val)

iterator find_as(const LookupKeyT &Val)

Alternate version of find() which allows a different, and possibly less expensive,...

size_type count(const_arg_type_t< KeyT > Val) const

Return 1 if the specified key is in the map, 0 otherwise.

std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)

Implements a dense probed hash-table based set.

Helper for Errors used as out-parameters.

Lightweight error class with error context and mandatory checking.

static ErrorSuccess success()

Create a success value.

Tagged union holding either a T or a Error.

reference get()

Returns a reference to the stored T value.

bool hasMaterializationSideEffectsOnly() const

Returns true if this symbol is a materialization-side-effects-only symbol.

void push_back(const T &Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

StringRef - Represent a constant reference to a string, i.e.

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

std::pair< iterator, bool > insert(const ValueT &V)

void reserve(size_t Size)

Grow the DenseSet so that it can contain at least NumEntries items before resizing again.

void insert_range(Range &&R)

size_type count(const_arg_type_t< ValueT > V) const

Return 1 if the specified key is in the set, 0 otherwise.

const std::string & getName() const

Get the name for this JITLinkDylib.

A symbol query that returns results via a callback when results are ready.

LLVM_ABI AsynchronousSymbolQuery(const SymbolLookupSet &Symbols, SymbolState RequiredState, SymbolsResolvedCallback NotifyComplete)

Create a query for the given symbols.

Definition Core.cpp:201

LLVM_ABI void notifySymbolMetRequiredState(const SymbolStringPtr &Name, ExecutorSymbolDef Sym)

Notify the query that a requested symbol has reached the required state.

Definition Core.cpp:215

Definition generators can be attached to JITDylibs to generate new definitions for otherwise unresolv...

virtual ~DefinitionGenerator()

Definition Core.cpp:638

An ExecutionSession represents a running JIT program.

LLVM_ABI Error endSession()

End the session.

Definition Core.cpp:1580

unique_function< void(shared::WrapperFunctionResult)> SendResultFunction

Send a result to the remote.

void reportError(Error Err)

Report a error for this execution session.

LLVM_ABI void lookupFlags(LookupKind K, JITDylibSearchOrder SearchOrder, SymbolLookupSet Symbols, unique_function< void(Expected< SymbolFlagsMap >)> OnComplete)

Search the given JITDylibs to find the flags associated with each of the given symbols.

Definition Core.cpp:1740

SymbolStringPtr intern(StringRef SymName)

Add a symbol name to the SymbolStringPool and return a pointer to it.

LLVM_ABI JITDylib * getJITDylibByName(StringRef Name)

Return a pointer to the "name" JITDylib.

Definition Core.cpp:1619

LLVM_ABI JITDylib & createBareJITDylib(std::string Name)

Add a new bare JITDylib to this ExecutionSession.

Definition Core.cpp:1628

std::shared_ptr< SymbolStringPool > getSymbolStringPool()

Get the SymbolStringPool for this instance.

LLVM_ABI void lookup(LookupKind K, const JITDylibSearchOrder &SearchOrder, SymbolLookupSet Symbols, SymbolState RequiredState, SymbolsResolvedCallback NotifyComplete, RegisterDependenciesFunction RegisterDependencies)

Search the given JITDylibs for the given symbols.

Definition Core.cpp:1766

LLVM_ABI Error registerJITDispatchHandlers(JITDylib &JD, JITDispatchHandlerAssociationMap WFs)

For each tag symbol name, associate the corresponding AsyncHandlerWrapperFunction with the address of...

Definition Core.cpp:1861

LLVM_ABI void registerResourceManager(ResourceManager &RM)

Register the given ResourceManager with this ExecutionSession.

Definition Core.cpp:1602

LLVM_ABI ~ExecutionSession()

Destroy an ExecutionSession.

Definition Core.cpp:1574

LLVM_ABI void runJITDispatchHandler(SendResultFunction SendResult, ExecutorAddr HandlerFnTagAddr, ArrayRef< char > ArgBuffer)

Run a registered jit-side wrapper function.

Definition Core.cpp:1900

LLVM_ABI void deregisterResourceManager(ResourceManager &RM)

Deregister the given ResourceManager with this ExecutionSession.

Definition Core.cpp:1606

LLVM_ABI ExecutionSession(std::unique_ptr< ExecutorProcessControl > EPC)

Construct an ExecutionSession with the given ExecutorProcessControl object.

Definition Core.cpp:1568

decltype(auto) runSessionLocked(Func &&F)

Run the given lambda with the session mutex locked.

LLVM_ABI void dump(raw_ostream &OS)

Dump the state of all the JITDylibs in this session.

Definition Core.cpp:1921

LLVM_ABI Error removeJITDylibs(std::vector< JITDylibSP > JDsToRemove)

Removes the given JITDylibs from the ExecutionSession.

Definition Core.cpp:1645

LLVM_ABI Expected< JITDylib & > createJITDylib(std::string Name)

Add a new JITDylib to this ExecutionSession.

Definition Core.cpp:1637

void dispatchTask(std::unique_ptr< Task > T)

Materialize the given unit.

DenseMap< SymbolStringPtr, JITDispatchHandlerFunction > JITDispatchHandlerAssociationMap

A map associating tag names with asynchronous wrapper function implementations in the JIT.

Represents an address in the executor process.

Represents a defining location for a JIT symbol.

const JITSymbolFlags & getFlags() const

FailedToMaterialize(std::shared_ptr< SymbolStringPool > SSP, std::shared_ptr< SymbolDependenceMap > Symbols)

Definition Core.cpp:82

std::error_code convertToErrorCode() const override

Convert this error to a std::error_code.

Definition Core.cpp:100

~FailedToMaterialize() override

Definition Core.cpp:95

void log(raw_ostream &OS) const override

Print an error message to an output stream.

Definition Core.cpp:104

InProgressFullLookupState(LookupKind K, JITDylibSearchOrder SearchOrder, SymbolLookupSet LookupSet, SymbolState RequiredState, std::shared_ptr< AsynchronousSymbolQuery > Q, RegisterDependenciesFunction RegisterDependencies)

Definition Core.cpp:565

void complete(std::unique_ptr< InProgressLookupState > IPLS) override

Definition Core.cpp:575

void fail(Error Err) override

Definition Core.cpp:581

void complete(std::unique_ptr< InProgressLookupState > IPLS) override

Definition Core.cpp:552

void fail(Error Err) override

Definition Core.cpp:557

InProgressLookupFlagsState(LookupKind K, JITDylibSearchOrder SearchOrder, SymbolLookupSet LookupSet, unique_function< void(Expected< SymbolFlagsMap >)> OnComplete)

Definition Core.cpp:545

virtual ~InProgressLookupState()=default

LookupKind K

Definition Core.cpp:525

SymbolLookupSet DefGeneratorCandidates

Definition Core.cpp:532

JITDylibSearchOrder SearchOrder

Definition Core.cpp:526

std::vector< std::weak_ptr< DefinitionGenerator > > CurDefGeneratorStack

Definition Core.cpp:540

@ ResumedForGenerator

Definition Core.cpp:537

@ InGenerator

Definition Core.cpp:538

@ NotInGenerator

Definition Core.cpp:536

size_t CurSearchOrderIndex

Definition Core.cpp:530

SymbolLookupSet LookupSet

Definition Core.cpp:527

virtual void complete(std::unique_ptr< InProgressLookupState > IPLS)=0

InProgressLookupState(LookupKind K, JITDylibSearchOrder SearchOrder, SymbolLookupSet LookupSet, SymbolState RequiredState)

Definition Core.cpp:515

SymbolState RequiredState

Definition Core.cpp:528

SymbolLookupSet DefGeneratorNonCandidates

Definition Core.cpp:533

virtual void fail(Error Err)=0

bool NewJITDylib

Definition Core.cpp:531

Represents a JIT'd dynamic library.

LLVM_ABI ~JITDylib()

Definition Core.cpp:652

LLVM_ABI Error remove(const SymbolNameSet &Names)

Tries to remove the given symbols.

Definition Core.cpp:1054

LLVM_ABI Error clear()

Calls remove on all trackers currently associated with this JITDylib.

Definition Core.cpp:656

LLVM_ABI void dump(raw_ostream &OS)

Dump current JITDylib state to OS.

Definition Core.cpp:1115

LLVM_ABI void replaceInLinkOrder(JITDylib &OldJD, JITDylib &NewJD, JITDylibLookupFlags JDLookupFlags=JITDylibLookupFlags::MatchExportedSymbolsOnly)

Replace OldJD with NewJD in the link order if OldJD is present.

Definition Core.cpp:1030

Error define(std::unique_ptr< MaterializationUnitType > &&MU, ResourceTrackerSP RT=nullptr)

Define all symbols provided by the materialization unit to be part of this JITDylib.

ExecutionSession & getExecutionSession() const

Get a reference to the ExecutionSession for this JITDylib.

LLVM_ABI void addToLinkOrder(const JITDylibSearchOrder &NewLinks)

Append the given JITDylibSearchOrder to the link order for this JITDylib (discarding any elements alr...

Definition Core.cpp:1014

LLVM_ABI ResourceTrackerSP createResourceTracker()

Create a resource tracker for this JITDylib.

Definition Core.cpp:680

LLVM_ABI void removeFromLinkOrder(JITDylib &JD)

Remove the given JITDylib from the link order for this JITDylib if it is present.

Definition Core.cpp:1042

LLVM_ABI void setLinkOrder(JITDylibSearchOrder NewSearchOrder, bool LinkAgainstThisJITDylibFirst=true)

Set the link order to be used when fixing up definitions in JITDylib.

Definition Core.cpp:999

LLVM_ABI Expected< std::vector< JITDylibSP > > getReverseDFSLinkOrder()

Rteurn this JITDylib and its transitive dependencies in reverse DFS order based on linkage relationsh...

Definition Core.cpp:1736

LLVM_ABI ResourceTrackerSP getDefaultResourceTracker()

Get the default resource tracker for this JITDylib.

Definition Core.cpp:671

JITDylib(const JITDylib &)=delete

LLVM_ABI void removeGenerator(DefinitionGenerator &G)

Remove a definition generator from this JITDylib.

Definition Core.cpp:688

LLVM_ABI Expected< std::vector< JITDylibSP > > getDFSLinkOrder()

Return this JITDylib and its transitive dependencies in DFS order based on linkage relationships.

Definition Core.cpp:1732

Wraps state for a lookup-in-progress.

LLVM_ABI void continueLookup(Error Err)

Continue the lookup.

Definition Core.cpp:632

LLVM_ABI LookupState & operator=(LookupState &&)

void run() override

Definition Core.cpp:1566

void printDescription(raw_ostream &OS) override

Definition Core.cpp:1564

Tracks responsibility for materialization, and mediates interactions between MaterializationUnits and...

void run() override

Definition Core.cpp:1558

void printDescription(raw_ostream &OS) override

Definition Core.cpp:1553

~MaterializationTask() override

Definition Core.cpp:1547

A MaterializationUnit represents a set of symbol definitions that can be materialized as a group,...

MaterializationUnit(Interface I)

std::error_code convertToErrorCode() const override

Convert this error to a std::error_code.

Definition Core.cpp:162

void log(raw_ostream &OS) const override

Print an error message to an output stream.

Definition Core.cpp:166

Non-owning SymbolStringPool entry pointer.

static void lookupInitSymbolsAsync(unique_function< void(Error)> OnComplete, ExecutionSession &ES, const DenseMap< JITDylib *, SymbolLookupSet > &InitSyms)

Performs an async lookup for the given symbols in each of the given JITDylibs, calling the given hand...

Definition Core.cpp:1504

static Expected< DenseMap< JITDylib *, SymbolMap > > lookupInitSymbols(ExecutionSession &ES, const DenseMap< JITDylib *, SymbolLookupSet > &InitSyms)

A utility function for looking up initializer symbols.

Definition Core.cpp:1455

StringRef getName() const override

Return the name of this materialization unit.

Definition Core.cpp:306

ReExportsMaterializationUnit(JITDylib *SourceJD, JITDylibLookupFlags SourceJDLookupFlags, SymbolAliasMap Aliases)

SourceJD is allowed to be nullptr, in which case the source JITDylib is taken to be whatever JITDylib...

Definition Core.cpp:300

std::function< bool(SymbolStringPtr)> SymbolPredicate

Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD, JITDylibLookupFlags JDLookupFlags, const SymbolLookupSet &LookupSet) override

DefinitionGenerators should override this method to insert new definitions into the parent JITDylib.

Definition Core.cpp:597

ReexportsGenerator(JITDylib &SourceJD, JITDylibLookupFlags SourceJDLookupFlags, SymbolPredicate Allow=SymbolPredicate())

Create a reexports generator.

Definition Core.cpp:591

Listens for ResourceTracker operations.

virtual ~ResourceManager()

ResourceTrackerDefunct(ResourceTrackerSP RT)

Definition Core.cpp:71

void log(raw_ostream &OS) const override

Print an error message to an output stream.

Definition Core.cpp:78

std::error_code convertToErrorCode() const override

Convert this error to a std::error_code.

Definition Core.cpp:74

API to remove / transfer ownership of JIT resources.

JITDylib & getJITDylib() const

Return the JITDylib targeted by this tracker.

LLVM_ABI void transferTo(ResourceTracker &DstRT)

Transfer all resources associated with this key to the given tracker, which must target the same JITD...

Definition Core.cpp:59

LLVM_ABI ~ResourceTracker()

Definition Core.cpp:50

ResourceTracker(const ResourceTracker &)=delete

LLVM_ABI Error remove()

Remove all resources associated with this key.

Definition Core.cpp:55

LLVM_ABI void lookupAsync(LookupAsyncOnCompleteFn OnComplete) const

Definition Core.cpp:180

unique_function< void(Expected< ExecutorSymbolDef >)> LookupAsyncOnCompleteFn

A set of symbols to look up, each associated with a SymbolLookupFlags value.

static SymbolLookupSet fromMapKeys(const DenseMap< SymbolStringPtr, ValT > &M, SymbolLookupFlags Flags=SymbolLookupFlags::RequiredSymbol)

Construct a SymbolLookupSet from DenseMap keys.

Pointer to a pooled string representing a symbol name.

std::error_code convertToErrorCode() const override

Convert this error to a std::error_code.

Definition Core.cpp:154

void log(raw_ostream &OS) const override

Print an error message to an output stream.

Definition Core.cpp:158

SymbolsCouldNotBeRemoved(std::shared_ptr< SymbolStringPool > SSP, SymbolNameSet Symbols)

Definition Core.cpp:148

void log(raw_ostream &OS) const override

Print an error message to an output stream.

Definition Core.cpp:144

SymbolsNotFound(std::shared_ptr< SymbolStringPool > SSP, SymbolNameSet Symbols)

Definition Core.cpp:127

std::error_code convertToErrorCode() const override

Convert this error to a std::error_code.

Definition Core.cpp:140

Represents an abstract task for ORC to run.

std::error_code convertToErrorCode() const override

Convert this error to a std::error_code.

Definition Core.cpp:171

void log(raw_ostream &OS) const override

Print an error message to an output stream.

Definition Core.cpp:175

void log(raw_ostream &OS) const override

Print an error message to an output stream.

Definition Core.cpp:120

std::error_code convertToErrorCode() const override

Convert this error to a std::error_code.

Definition Core.cpp:116

UnsatisfiedSymbolDependencies(std::shared_ptr< SymbolStringPool > SSP, JITDylibSP JD, SymbolNameSet FailedSymbols, SymbolDependenceMap BadDeps, std::string Explanation)

Definition Core.cpp:108

DenseSet< ElementId > ElementSet

DenseMap< ContainerId, ElementSet > ContainerElementsMap

static SimplifyResult simplify(std::vector< std::unique_ptr< SuperNode > > SNs)

A raw_ostream that writes to a file descriptor.

This class implements an extremely fast bulk output stream that can only output to a stream.

unique_function is a type-erasing functor similar to std::function.

@ C

The default llvm calling convention, compatible with C.

JITDylibSearchOrder makeJITDylibSearchOrder(ArrayRef< JITDylib * > JDs, JITDylibLookupFlags Flags=JITDylibLookupFlags::MatchExportedSymbolsOnly)

Convenience function for creating a search order from an ArrayRef of JITDylib*, all with the same fla...

std::vector< std::pair< JITDylib *, JITDylibLookupFlags > > JITDylibSearchOrder

A list of (JITDylib*, JITDylibLookupFlags) pairs to be used as a search order during symbol lookup.

IntrusiveRefCntPtr< JITDylib > JITDylibSP

IntrusiveRefCntPtr< ResourceTracker > ResourceTrackerSP

@ MissingSymbolDefinitions

@ UnexpectedSymbolDefinitions

std::unique_ptr< ReExportsMaterializationUnit > symbolAliases(SymbolAliasMap Aliases)

Create a ReExportsMaterializationUnit with the given aliases.

std::function< void(const SymbolDependenceMap &)> RegisterDependenciesFunction

Callback to register the dependencies for a given query.

SymbolLookupFlags

Lookup flags that apply to each symbol in a lookup.

std::unique_ptr< ReExportsMaterializationUnit > reexports(JITDylib &SourceJD, SymbolAliasMap Aliases, JITDylibLookupFlags SourceJDLookupFlags=JITDylibLookupFlags::MatchExportedSymbolsOnly)

Create a materialization unit for re-exporting symbols from another JITDylib with alternative names/f...

LLVM_ABI Expected< SymbolAliasMap > buildSimpleReexportsAliasMap(JITDylib &SourceJD, const SymbolNameSet &Symbols)

Build a SymbolAliasMap for the common case where you want to re-export symbols from another JITDylib ...

JITDylibLookupFlags

Lookup flags that apply to each dylib in the search order for a lookup.

@ MatchExportedSymbolsOnly

DenseMap< SymbolStringPtr, ExecutorSymbolDef > SymbolMap

A map from symbol names (as SymbolStringPtrs) to JITSymbols (address/flags pairs).

LookupKind

Describes the kind of lookup being performed.

LLVM_ABI RegisterDependenciesFunction NoDependenciesToRegister

This can be used as the value for a RegisterDependenciesFunction if there are no dependants to regist...

Definition Core.cpp:38

std::vector< SymbolStringPtr > SymbolNameVector

A vector of symbol names.

DenseMap< JITDylib *, SymbolNameSet > SymbolDependenceMap

A map from JITDylibs to sets of symbols.

DenseSet< SymbolStringPtr > SymbolNameSet

A set of symbol names (represented by SymbolStringPtrs for.

SymbolState

Represents the state that a symbol has reached during materialization.

@ Materializing

Added to the symbol table, never queried.

@ NeverSearched

No symbol should be in this state.

@ Ready

Emitted to memory, but waiting on transitive dependencies.

@ Resolved

Queried, materialization begun.

DenseMap< SymbolStringPtr, SymbolAliasMapEntry > SymbolAliasMap

A map of Symbols to (Symbol, Flags) pairs.

LLVM_ABI std::error_code orcError(OrcErrorCode ErrCode)

unique_function< void(Expected< SymbolMap >)> SymbolsResolvedCallback

Callback to notify client that symbols have been resolved.

DenseMap< SymbolStringPtr, JITSymbolFlags > SymbolFlagsMap

A map from symbol names (as SymbolStringPtrs) to JITSymbolFlags.

This is an optimization pass for GlobalISel generic memory operations.

auto find(R &&Range, const T &Val)

Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.

LLVM_ABI std::error_code inconvertibleErrorCode()

The value returned by this function can be returned from convertToErrorCode for Error values where no...

void append_range(Container &C, Range &&R)

Wrapper function to append range R to container C.

auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)

auto reverse(ContainerTy &&C)

Error joinErrors(Error E1, Error E2)

Concatenate errors.

void sort(IteratorTy Start, IteratorTy End)

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

FunctionAddr VTableAddr Count

format_object< Ts... > format(const char *Fmt, const Ts &... Vals)

These are helper functions used to produce formatted output.

Error make_error(ArgTs &&... Args)

Make a Error instance representing failure using the given error info type.

LLVM_ABI raw_fd_ostream & errs()

This returns a reference to a raw_ostream for standard error.

auto lower_bound(R &&Range, T &&Value)

Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...

ArrayRef(const T &OneElt) -> ArrayRef< T >

OutputIt move(R &&Range, OutputIt Out)

Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.

auto find_if(R &&Range, UnaryPredicate P)

Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.

bool is_contained(R &&Range, const E &Element)

Returns true if Element is found in Range.

Implement std::hash so that hash_code can be used in STL containers.

void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)

Implement std::swap in terms of BitVector swap.