Skip to content

Commit ad24e0f

Browse files
authored
Merge pull request #12669 from graydon/named-lazy-member-loading-3
[WIP] Named lazy member loading 3
2 parents 0d98c4c + 1cd7810 commit ad24e0f

26 files changed

+1040
-110
lines changed

include/swift/AST/DeclContext.h

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "swift/Basic/LLVM.h"
2727
#include "swift/Basic/SourceLoc.h"
2828
#include "swift/Basic/STLExtras.h"
29+
#include "llvm/ADT/PointerEmbeddedInt.h"
2930
#include "llvm/ADT/PointerIntPair.h"
3031
#include "llvm/ADT/PointerUnion.h"
3132

@@ -67,6 +68,10 @@ namespace swift {
6768
class SerializedTopLevelCodeDecl;
6869
class StructDecl;
6970

71+
namespace serialization {
72+
using DeclID = llvm::PointerEmbeddedInt<unsigned, 31>;
73+
}
74+
7075
enum class DeclContextKind : uint8_t {
7176
AbstractClosureExpr,
7277
Initializer,
@@ -604,6 +609,10 @@ class IterableDeclContext {
604609
mutable llvm::PointerIntPair<Decl *, 2, IterableDeclContextKind>
605610
LastDeclAndKind;
606611

612+
// The DeclID this IDC was deserialized from, if any. Used for named lazy
613+
// member loading, as a key when doing lookup in this IDC.
614+
serialization::DeclID SerialID;
615+
607616
template<class A, class B, class C>
608617
friend struct ::llvm::cast_convert_val;
609618

@@ -631,14 +640,33 @@ class IterableDeclContext {
631640
/// Check whether there are lazily-loaded members.
632641
bool hasLazyMembers() const {
633642
return FirstDeclAndLazyMembers.getInt();
634-
}
643+
}
635644

636645
/// Setup the loader for lazily-loaded members.
637646
void setMemberLoader(LazyMemberLoader *loader, uint64_t contextData);
638647

639648
/// Load all of the members of this context.
640649
void loadAllMembers() const;
641650

651+
/// Determine whether this was deserialized (and thus SerialID is
652+
/// valid).
653+
bool wasDeserialized() const;
654+
655+
/// Return 'this' as a \c Decl.
656+
const Decl *getDecl() const;
657+
658+
/// Get the DeclID this Decl was deserialized from.
659+
serialization::DeclID getDeclID() const {
660+
assert(wasDeserialized());
661+
return SerialID;
662+
}
663+
664+
/// Set the DeclID this Decl was deserialized from.
665+
void setDeclID(serialization::DeclID d) {
666+
assert(wasDeserialized());
667+
SerialID = d;
668+
}
669+
642670
// Some Decls are IterableDeclContexts, but not all.
643671
static bool classof(const Decl *D);
644672

include/swift/AST/LazyResolver.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ namespace swift {
2626
class AssociatedTypeDecl;
2727
class Decl;
2828
class DeclContext;
29+
class IterableDeclContext;
2930
class ExtensionDecl;
3031
class Identifier;
3132
class NominalTypeDecl;
@@ -224,13 +225,14 @@ class alignas(void*) LazyMemberLoader {
224225
virtual void
225226
loadAllMembers(Decl *D, uint64_t contextData) = 0;
226227

227-
/// Populates a vector with all members of \p D that have DeclName
228+
/// Populates a vector with all members of \p IDC that have DeclName
228229
/// matching \p N.
229230
///
230231
/// Returns None if an error occurred \em or named member-lookup
231232
/// was otherwise unsupported in this implementation or Decl.
232233
virtual Optional<TinyPtrVector<ValueDecl *>>
233-
loadNamedMembers(const Decl *D, DeclName N, uint64_t contextData) = 0;
234+
loadNamedMembers(const IterableDeclContext *IDC, DeclName N,
235+
uint64_t contextData) = 0;
234236

235237
/// Populates the given vector with all conformances for \p D.
236238
///

include/swift/Serialization/ModuleFile.h

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ class ModuleFile
6666

6767
llvm::BitstreamCursor SILCursor;
6868
llvm::BitstreamCursor SILIndexCursor;
69+
llvm::BitstreamCursor DeclMemberTablesCursor;
6970

7071
/// The name of the module.
7172
StringRef Name;
@@ -335,14 +336,26 @@ class ModuleFile
335336
using SerializedNestedTypeDeclsTable =
336337
llvm::OnDiskIterableChainedHashTable<NestedTypeDeclsTableInfo>;
337338

339+
class DeclMemberNamesTableInfo;
340+
using SerializedDeclMemberNamesTable =
341+
llvm::OnDiskIterableChainedHashTable<DeclMemberNamesTableInfo>;
342+
343+
class DeclMembersTableInfo;
344+
using SerializedDeclMembersTable =
345+
llvm::OnDiskIterableChainedHashTable<DeclMembersTableInfo>;
346+
338347
std::unique_ptr<SerializedDeclTable> TopLevelDecls;
339348
std::unique_ptr<SerializedDeclTable> OperatorDecls;
340349
std::unique_ptr<SerializedDeclTable> PrecedenceGroupDecls;
341-
std::unique_ptr<SerializedDeclTable> ClassMembersByName;
350+
std::unique_ptr<SerializedDeclTable> ClassMembersForDynamicLookup;
342351
std::unique_ptr<SerializedDeclTable> OperatorMethodDecls;
343352
std::unique_ptr<SerializedExtensionTable> ExtensionDecls;
344353
std::unique_ptr<SerializedLocalDeclTable> LocalTypeDecls;
345354
std::unique_ptr<SerializedNestedTypeDeclsTable> NestedTypeDecls;
355+
std::unique_ptr<SerializedDeclMemberNamesTable> DeclMemberNames;
356+
357+
llvm::DenseMap<uint32_t,
358+
std::unique_ptr<SerializedDeclMembersTable>> DeclMembersTables;
346359

347360
class ObjCMethodTableInfo;
348361
using SerializedObjCMethodTable =
@@ -477,6 +490,21 @@ class ModuleFile
477490
std::unique_ptr<SerializedNestedTypeDeclsTable>
478491
readNestedTypeDeclsTable(ArrayRef<uint64_t> fields, StringRef blobData);
479492

493+
/// Read an on-disk local decl-name hash table stored in
494+
/// index_block::DeclMemberNamesLayout format.
495+
std::unique_ptr<SerializedDeclMemberNamesTable>
496+
readDeclMemberNamesTable(ArrayRef<uint64_t> fields, StringRef blobData);
497+
498+
/// Read an on-disk local decl-members hash table stored in
499+
/// index_block::DeclMembersLayout format.
500+
std::unique_ptr<SerializedDeclMembersTable>
501+
readDeclMembersTable(ArrayRef<uint64_t> fields, StringRef blobData);
502+
503+
/// Main logic of getDeclChecked.
504+
llvm::Expected<Decl *>
505+
getDeclCheckedImpl(serialization::DeclID DID,
506+
Optional<DeclContext *> ForcedContext = None);
507+
480508
/// Reads the index block, which contains global tables.
481509
///
482510
/// Returns false if there was an error.
@@ -702,7 +730,7 @@ class ModuleFile
702730

703731
virtual
704732
Optional<TinyPtrVector<ValueDecl *>>
705-
loadNamedMembers(const Decl *D, DeclName N,
733+
loadNamedMembers(const IterableDeclContext *IDC, DeclName N,
706734
uint64_t contextData) override;
707735

708736
virtual void

include/swift/Serialization/ModuleFormat.h

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,8 @@ const uint16_t VERSION_MAJOR = 0;
5454
/// in source control, you should also update the comment to briefly
5555
/// describe what change you made. The content of this comment isn't important;
5656
/// it just ensures a conflict if two people change the module format.
57-
const uint16_t VERSION_MINOR = 377; // Last change: SILFunctionType witness_method conformances
57+
const uint16_t VERSION_MINOR = 378; // Last change: DECL_MEMBER_NAMES
5858

59-
using DeclID = PointerEmbeddedInt<unsigned, 31>;
6059
using DeclIDField = BCFixed<31>;
6160

6261
// TypeID must be the same as DeclID because it is stored in the same way.
@@ -464,7 +463,12 @@ enum BlockID {
464463
/// The comment block, which contains documentation comments.
465464
///
466465
/// \sa comment_block
467-
COMMENT_BLOCK_ID
466+
COMMENT_BLOCK_ID,
467+
468+
/// The declaration member-tables index block, a sub-blocb of the index block.
469+
///
470+
/// \sa decl_member_tables_block
471+
DECL_MEMBER_TABLES_BLOCK_ID
468472
};
469473

470474
/// The record types within the control block.
@@ -1499,7 +1503,7 @@ namespace index_block {
14991503
TOP_LEVEL_DECLS,
15001504
OPERATORS,
15011505
EXTENSIONS,
1502-
CLASS_MEMBERS,
1506+
CLASS_MEMBERS_FOR_DYNAMIC_LOOKUP,
15031507
OPERATOR_METHODS,
15041508

15051509
/// The Objective-C method index, which contains a mapping from
@@ -1517,8 +1521,9 @@ namespace index_block {
15171521

15181522
PRECEDENCE_GROUPS,
15191523
NESTED_TYPE_DECLS,
1524+
DECL_MEMBER_NAMES,
15201525

1521-
LastRecordKind = PRECEDENCE_GROUPS,
1526+
LastRecordKind = DECL_MEMBER_NAMES,
15221527
};
15231528

15241529
constexpr const unsigned RecordIDFieldWidth = 5;
@@ -1560,12 +1565,32 @@ namespace index_block {
15601565
BCBlob // map from identifier strings to decl kinds / decl IDs
15611566
>;
15621567

1568+
using DeclMemberNamesLayout = BCRecordLayout<
1569+
DECL_MEMBER_NAMES, // record ID
1570+
BCVBR<16>, // table offset within the blob (see below)
1571+
BCBlob // map from member DeclBaseNames to offsets of DECL_MEMBERS records
1572+
>;
1573+
15631574
using EntryPointLayout = BCRecordLayout<
15641575
ENTRY_POINT,
15651576
DeclIDField // the ID of the main class; 0 if there was a main source file
15661577
>;
15671578
}
15681579

1580+
/// \sa DECL_MEMBER_TABLES_BLOCK_ID
1581+
namespace decl_member_tables_block {
1582+
enum RecordKind {
1583+
DECL_MEMBERS = 1,
1584+
};
1585+
1586+
using DeclMembersLayout = BCRecordLayout<
1587+
DECL_MEMBERS, // record ID
1588+
BCVBR<16>, // table offset within the blob (see below)
1589+
BCBlob // maps from DeclIDs to DeclID vectors
1590+
>;
1591+
1592+
}
1593+
15691594
/// \sa COMMENT_BLOCK_ID
15701595
namespace comment_block {
15711596
enum RecordKind {

include/swift/Serialization/SerializationOptions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ namespace swift {
3737

3838
bool AutolinkForceLoad = false;
3939
bool EnableNestedTypeLookupTable = false;
40+
bool EnableDeclMemberNamesTable = false;
4041
bool SerializeAllSIL = false;
4142
bool SerializeOptionsForDebugging = false;
4243
bool IsSIB = false;

lib/AST/DeclContext.cpp

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -867,18 +867,24 @@ unsigned DeclContext::printContext(raw_ostream &OS, unsigned indent) const {
867867
return Depth + 1;
868868
}
869869

870-
ASTContext &IterableDeclContext::getASTContext() const {
870+
const Decl *
871+
IterableDeclContext::getDecl() const {
871872
switch (getIterableContextKind()) {
872873
case IterableDeclContextKind::NominalTypeDecl:
873-
return cast<NominalTypeDecl>(this)->getASTContext();
874+
return cast<NominalTypeDecl>(this);
875+
break;
874876

875877
case IterableDeclContextKind::ExtensionDecl:
876-
return cast<ExtensionDecl>(this)->getASTContext();
878+
return cast<ExtensionDecl>(this);
879+
break;
877880
}
878-
879881
llvm_unreachable("Unhandled IterableDeclContextKind in switch.");
880882
}
881883

884+
ASTContext &IterableDeclContext::getASTContext() const {
885+
return getDecl()->getASTContext();
886+
}
887+
882888
DeclRange IterableDeclContext::getMembers() const {
883889
loadAllMembers();
884890

@@ -963,17 +969,7 @@ void IterableDeclContext::loadAllMembers() const {
963969
/*lazyLoader=*/nullptr);
964970
FirstDeclAndLazyMembers.setInt(false);
965971

966-
const Decl *container = nullptr;
967-
switch (getIterableContextKind()) {
968-
case IterableDeclContextKind::NominalTypeDecl:
969-
container = cast<NominalTypeDecl>(this);
970-
break;
971-
972-
case IterableDeclContextKind::ExtensionDecl:
973-
container = cast<ExtensionDecl>(this);
974-
break;
975-
}
976-
972+
const Decl *container = getDecl();
977973
contextInfo->loader->loadAllMembers(const_cast<Decl *>(container),
978974
contextInfo->memberData);
979975

@@ -983,6 +979,14 @@ void IterableDeclContext::loadAllMembers() const {
983979
s->getFrontendCounters().NumUnloadedLazyIterableDeclContexts--;
984980
}
985981

982+
bool IterableDeclContext::wasDeserialized() const {
983+
const DeclContext *DC = cast<DeclContext>(getDecl());
984+
if (auto F = dyn_cast<FileUnit>(DC->getModuleScopeContext())) {
985+
return F->getKind() == FileUnitKind::SerializedAST;
986+
}
987+
return false;
988+
}
989+
986990
bool IterableDeclContext::classof(const Decl *D) {
987991
switch (D->getKind()) {
988992
#define DECL(ID, PARENT) case DeclKind::ID: return false;

0 commit comments

Comments
 (0)