Skip to content

Commit 70d9f16

Browse files
authored
Merge pull request #60497 from augusto2112/swift-meta-cache
Introduce ExternalTypeRefInfoProvider
2 parents e1bb0bb + 63a2c76 commit 70d9f16

File tree

5 files changed

+197
-44
lines changed

5 files changed

+197
-44
lines changed

include/swift/Reflection/ReflectionContext.h

Lines changed: 34 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -211,9 +211,10 @@ class ReflectionContext
211211
uint32_t ThreadPort;
212212
};
213213

214-
explicit ReflectionContext(std::shared_ptr<MemoryReader> reader)
215-
: super(std::move(reader), *this)
216-
{}
214+
explicit ReflectionContext(
215+
std::shared_ptr<MemoryReader> reader,
216+
remote::ExternalTypeRefCache *externalCache = nullptr)
217+
: super(std::move(reader), *this, externalCache) {}
217218

218219
ReflectionContext(const ReflectionContext &other) = delete;
219220
ReflectionContext &operator=(const ReflectionContext &other) = delete;
@@ -227,8 +228,10 @@ class ReflectionContext
227228
return sizeof(StoredPointer) * 2;
228229
}
229230

231+
/// On success returns the ID of the newly registered Reflection Info.
230232
template <typename T>
231-
bool readMachOSections(
233+
llvm::Optional<uint32_t>
234+
readMachOSections(
232235
RemoteAddress ImageStart,
233236
llvm::SmallVector<llvm::StringRef, 1> PotentialModuleNames = {}) {
234237
auto Buf =
@@ -350,7 +353,7 @@ class ReflectionContext
350353
{MPEnumMdSec.first, MPEnumMdSec.second},
351354
PotentialModuleNames};
352355

353-
this->addReflectionInfo(info);
356+
auto InfoID = this->addReflectionInfo(info);
354357

355358
// Find the __DATA segment.
356359
for (unsigned I = 0; I < NumCommands; ++I) {
@@ -374,10 +377,11 @@ class ReflectionContext
374377

375378
savedBuffers.push_back(std::move(Buf));
376379
savedBuffers.push_back(std::move(Sections));
377-
return true;
380+
return InfoID;
378381
}
379382

380-
bool readPECOFFSections(
383+
/// On success returns the ID of the newly registered Reflection Info.
384+
llvm::Optional<uint32_t> readPECOFFSections(
381385
RemoteAddress ImageStart,
382386
llvm::SmallVector<llvm::StringRef, 1> PotentialModuleNames = {}) {
383387
auto DOSHdrBuf = this->getReader().readBytes(
@@ -477,11 +481,11 @@ class ReflectionContext
477481
{ConformMdSec.first, ConformMdSec.second},
478482
{MPEnumMdSec.first, MPEnumMdSec.second},
479483
PotentialModuleNames};
480-
this->addReflectionInfo(Info);
481-
return true;
484+
return this->addReflectionInfo(Info);
482485
}
483486

484-
bool readPECOFF(RemoteAddress ImageStart,
487+
/// On success returns the ID of the newly registered Reflection Info.
488+
llvm::Optional<uint32_t> readPECOFF(RemoteAddress ImageStart,
485489
llvm::SmallVector<llvm::StringRef, 1> PotentialModuleNames = {}) {
486490
auto Buf = this->getReader().readBytes(ImageStart,
487491
sizeof(llvm::object::dos_header));
@@ -504,8 +508,9 @@ class ReflectionContext
504508
return readPECOFFSections(ImageStart, PotentialModuleNames);
505509
}
506510

511+
/// On success returns the ID of the newly registered Reflection Info.
507512
template <typename T>
508-
bool readELFSections(
513+
llvm::Optional<uint32_t> readELFSections(
509514
RemoteAddress ImageStart,
510515
llvm::Optional<llvm::sys::MemoryBlock> FileBuffer,
511516
llvm::SmallVector<llvm::StringRef, 1> PotentialModuleNames = {}) {
@@ -673,8 +678,7 @@ class ReflectionContext
673678
{MPEnumMdSec.first, MPEnumMdSec.second},
674679
PotentialModuleNames};
675680

676-
this->addReflectionInfo(info);
677-
return true;
681+
return this->addReflectionInfo(info);
678682
}
679683

680684
/// Parses metadata information from an ELF image. Because the Section
@@ -693,22 +697,22 @@ class ReflectionContext
693697
/// instance's memory reader.
694698
///
695699
/// \return
696-
/// /b True if the metadata information was parsed successfully,
697-
/// /b false otherwise.
698-
bool
700+
/// \b The newly added reflection info ID if successful,
701+
/// \b llvm::None otherwise.
702+
llvm::Optional<uint32_t>
699703
readELF(RemoteAddress ImageStart,
700704
llvm::Optional<llvm::sys::MemoryBlock> FileBuffer,
701705
llvm::SmallVector<llvm::StringRef, 1> PotentialModuleNames = {}) {
702706
auto Buf =
703707
this->getReader().readBytes(ImageStart, sizeof(llvm::ELF::Elf64_Ehdr));
704708
if (!Buf)
705-
return false;
709+
return llvm::None;
706710

707711
// Read the header.
708712
auto Hdr = reinterpret_cast<const llvm::ELF::Elf64_Ehdr *>(Buf.get());
709713

710714
if (!Hdr->checkMagic())
711-
return false;
715+
return llvm::None;
712716

713717
// Check if we have a ELFCLASS32 or ELFCLASS64
714718
unsigned char FileClass = Hdr->getFileClass();
@@ -719,11 +723,12 @@ class ReflectionContext
719723
return readELFSections<ELFTraits<llvm::ELF::ELFCLASS32>>(
720724
ImageStart, FileBuffer, PotentialModuleNames);
721725
} else {
722-
return false;
726+
return llvm::None;
723727
}
724728
}
725729

726-
bool
730+
/// On success returns the ID of the newly registered Reflection Info.
731+
llvm::Optional<uint32_t>
727732
addImage(RemoteAddress ImageStart,
728733
llvm::SmallVector<llvm::StringRef, 1> PotentialModuleNames = {}) {
729734
// Read the first few bytes to look for a magic header.
@@ -761,7 +766,7 @@ class ReflectionContext
761766
}
762767

763768
// We don't recognize the format.
764-
return false;
769+
return llvm::None;
765770
}
766771

767772
/// Adds an image using the FindSection closure to find the swift metadata
@@ -770,9 +775,9 @@ class ReflectionContext
770775
/// of freeing the memory buffer in the RemoteRef return value.
771776
/// process.
772777
/// \return
773-
/// \b True if any of the reflection sections were registered,
774-
/// \b false otherwise.
775-
bool
778+
/// \b The newly added reflection info ID if successful,
779+
/// \b llvm::None otherwise.
780+
llvm::Optional<uint32_t>
776781
addImage(llvm::function_ref<
777782
std::pair<RemoteRef<void>, uint64_t>(ReflectionSectionKind)>
778783
FindSection,
@@ -798,7 +803,7 @@ class ReflectionContext
798803

799804
// If we didn't find any sections, return.
800805
if (llvm::all_of(Pairs, [](const auto &Pair) { return !Pair.first; }))
801-
return false;
806+
return {};
802807

803808
ReflectionInfo Info = {{Pairs[0].first, Pairs[0].second},
804809
{Pairs[1].first, Pairs[1].second},
@@ -809,12 +814,12 @@ class ReflectionContext
809814
{Pairs[6].first, Pairs[6].second},
810815
{Pairs[7].first, Pairs[7].second},
811816
PotentialModuleNames};
812-
this->addReflectionInfo(Info);
813-
return true;
817+
return addReflectionInfo(Info);
814818
}
815819

816-
void addReflectionInfo(ReflectionInfo I) {
817-
getBuilder().addReflectionInfo(I);
820+
/// Adds the reflection info and returns it's id.
821+
uint32_t addReflectionInfo(ReflectionInfo I) {
822+
return getBuilder().addReflectionInfo(I);
818823
}
819824

820825
bool ownsObject(RemoteAddress ObjectAddress) {

include/swift/Reflection/TypeRefBuilder.h

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#ifndef SWIFT_REFLECTION_TYPEREFBUILDER_H
1919
#define SWIFT_REFLECTION_TYPEREFBUILDER_H
2020

21+
#include "swift/Remote/ExternalTypeRefCache.h"
2122
#include "swift/Remote/MetadataReader.h"
2223
#include "swift/Reflection/MetadataSourceBuilder.h"
2324
#include "swift/Reflection/Records.h"
@@ -426,6 +427,8 @@ class TypeRefBuilder {
426427
TypeConverter TC;
427428
MetadataSourceBuilder MSB;
428429

430+
remote::ExternalTypeRefCache *ExternalTypeRefCache = nullptr;
431+
429432
#define TYPEREF(Id, Parent) \
430433
std::unordered_map<TypeRefID, const Id##TypeRef *, \
431434
TypeRefID::Hash, TypeRefID::Equal> Id##TypeRefs;
@@ -915,10 +918,17 @@ class TypeRefBuilder {
915918
/// Parsing reflection metadata
916919
///
917920

918-
void addReflectionInfo(ReflectionInfo I) {
921+
/// Add the ReflectionInfo and return a unique ID for the reflection image
922+
/// added. Since we only add reflection infos, the ID can be its index.
923+
/// We return a uint32_t since it's extremely unlikely we'll run out of
924+
/// indexes.
925+
uint32_t addReflectionInfo(ReflectionInfo I) {
919926
ReflectionInfos.push_back(I);
927+
auto InfoID = ReflectionInfos.size() - 1;
928+
assert(InfoID <= UINT32_MAX && "ReflectionInfo ID overflow");
929+
return InfoID;
920930
}
921-
931+
922932
const std::vector<ReflectionInfo> &getReflectionInfos() {
923933
return ReflectionInfos;
924934
}
@@ -943,6 +953,9 @@ class TypeRefBuilder {
943953
llvm::Optional<RemoteRef<FieldDescriptor>>
944954
findFieldDescriptorAtIndex(size_t Index, const std::string &MangledName);
945955

956+
llvm::Optional<RemoteRef<FieldDescriptor>>
957+
getFieldDescriptorFromExternalCache(const std::string &MangledName);
958+
946959
public:
947960
RemoteRef<char> readTypeRef(uint64_t remoteAddr);
948961

@@ -983,8 +996,9 @@ class TypeRefBuilder {
983996

984997
public:
985998
template<typename Runtime>
986-
TypeRefBuilder(remote::MetadataReader<Runtime, TypeRefBuilder> &reader)
987-
: TC(*this),
999+
TypeRefBuilder(remote::MetadataReader<Runtime, TypeRefBuilder> &reader,
1000+
remote::ExternalTypeRefCache *externalCache = nullptr)
1001+
: TC(*this), ExternalTypeRefCache(externalCache),
9881002
PointerSize(sizeof(typename Runtime::StoredPointer)),
9891003
TypeRefDemangler(
9901004
[this, &reader](RemoteRef<char> string, bool useOpaqueTypeSymbolicReferences) -> Demangle::Node * {
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
//===--- ExternalTypeRefCache.h - Abstract access to external caches of
2+
//typeref ------*- C++ -*-===//
3+
//
4+
// This source file is part of the Swift.org open source project
5+
//
6+
// Copyright (c) 2022 Apple Inc. and the Swift project authors
7+
// Licensed under Apache License v2.0 with Runtime Library Exception
8+
//
9+
// See https://swift.org/LICENSE.txt for license information
10+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
11+
//
12+
//===----------------------------------------------------------------------===//
13+
//
14+
/// @file
15+
/// This file declares an abstract interface for external caches of
16+
/// typeref information.
17+
//
18+
//===----------------------------------------------------------------------===//
19+
20+
#ifndef SWIFT_REMOTE_EXTERNALTYPEREFCACHE_H
21+
#define SWIFT_REMOTE_EXTERNALTYPEREFCACHE_H
22+
23+
#include "llvm/ADT/ArrayRef.h"
24+
#include "llvm/ADT/StringRef.h"
25+
#include "llvm/ADT/Optional.h"
26+
27+
#include <string>
28+
29+
namespace swift {
30+
namespace reflection {
31+
32+
template <typename T>
33+
class ReflectionSection;
34+
class FieldDescriptorIterator;
35+
using FieldSection = ReflectionSection<FieldDescriptorIterator>;
36+
}
37+
38+
namespace remote {
39+
/// A struct with the information required to locate a specific field
40+
/// descriptor.
41+
struct FieldDescriptorLocator {
42+
/// The reflection info ID the field descriptor belongs to.
43+
uint64_t InfoID;
44+
45+
/// The offset of the field descriptor in the FieldSection buffer.
46+
uint64_t Offset;
47+
};
48+
49+
/// An abstract interface for providing external type layout information.
50+
struct ExternalTypeRefCache {
51+
virtual ~ExternalTypeRefCache() = default;
52+
53+
/// Cache the field descriptors of a reflection info with a given id with
54+
/// their corresponding mangled names. The amount of field descriptors and
55+
/// mangled names must be the same. If a field descriptor does not have a
56+
/// mangled name a corresponding empty string must be in the mangled_names
57+
/// array.
58+
virtual void
59+
cacheFieldDescriptors(uint64_t InfoID,
60+
const swift::reflection::FieldSection &FieldDescriptors,
61+
llvm::ArrayRef<std::string> MangledNames) = 0;
62+
63+
/// Retrieve a pair representing the reflection info id and the offset of a
64+
/// field descriptor in the field section buffer, if available.
65+
virtual llvm::Optional<FieldDescriptorLocator>
66+
getFieldDescriptorLocator(const std::string &Name) = 0;
67+
68+
/// Returns whether the reflection info with the corresponding ID has been
69+
/// cached already.
70+
virtual bool isReflectionInfoCached(uint64_t InfoID) = 0;
71+
};
72+
73+
} // namespace remote
74+
} // namespace swift
75+
#endif

0 commit comments

Comments
 (0)