mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[NamedLazyMemberLoading] Add initial bits of serialized Decl member tables.
This commit is contained in:
@@ -335,6 +335,14 @@ private:
|
|||||||
using SerializedNestedTypeDeclsTable =
|
using SerializedNestedTypeDeclsTable =
|
||||||
llvm::OnDiskIterableChainedHashTable<NestedTypeDeclsTableInfo>;
|
llvm::OnDiskIterableChainedHashTable<NestedTypeDeclsTableInfo>;
|
||||||
|
|
||||||
|
class DeclMemberNamesTableInfo;
|
||||||
|
using SerializedDeclMemberNamesTable =
|
||||||
|
llvm::OnDiskIterableChainedHashTable<DeclMemberNamesTableInfo>;
|
||||||
|
|
||||||
|
class DeclMembersTableInfo;
|
||||||
|
using SerializedDeclMembersTable =
|
||||||
|
llvm::OnDiskIterableChainedHashTable<DeclMembersTableInfo>;
|
||||||
|
|
||||||
std::unique_ptr<SerializedDeclTable> TopLevelDecls;
|
std::unique_ptr<SerializedDeclTable> TopLevelDecls;
|
||||||
std::unique_ptr<SerializedDeclTable> OperatorDecls;
|
std::unique_ptr<SerializedDeclTable> OperatorDecls;
|
||||||
std::unique_ptr<SerializedDeclTable> PrecedenceGroupDecls;
|
std::unique_ptr<SerializedDeclTable> PrecedenceGroupDecls;
|
||||||
@@ -343,6 +351,10 @@ private:
|
|||||||
std::unique_ptr<SerializedExtensionTable> ExtensionDecls;
|
std::unique_ptr<SerializedExtensionTable> ExtensionDecls;
|
||||||
std::unique_ptr<SerializedLocalDeclTable> LocalTypeDecls;
|
std::unique_ptr<SerializedLocalDeclTable> LocalTypeDecls;
|
||||||
std::unique_ptr<SerializedNestedTypeDeclsTable> NestedTypeDecls;
|
std::unique_ptr<SerializedNestedTypeDeclsTable> NestedTypeDecls;
|
||||||
|
std::unique_ptr<SerializedDeclMemberNamesTable> DeclMemberNames;
|
||||||
|
|
||||||
|
llvm::DenseMap<serialization::BitOffset,
|
||||||
|
std::unique_ptr<SerializedDeclMembersTable>> DeclMembersTables;
|
||||||
|
|
||||||
class ObjCMethodTableInfo;
|
class ObjCMethodTableInfo;
|
||||||
using SerializedObjCMethodTable =
|
using SerializedObjCMethodTable =
|
||||||
@@ -477,6 +489,16 @@ private:
|
|||||||
std::unique_ptr<SerializedNestedTypeDeclsTable>
|
std::unique_ptr<SerializedNestedTypeDeclsTable>
|
||||||
readNestedTypeDeclsTable(ArrayRef<uint64_t> fields, StringRef blobData);
|
readNestedTypeDeclsTable(ArrayRef<uint64_t> fields, StringRef blobData);
|
||||||
|
|
||||||
|
/// Read an on-disk local decl-name hash table stored in
|
||||||
|
/// index_block::DeclMemberNamesLayout format.
|
||||||
|
std::unique_ptr<SerializedDeclMemberNamesTable>
|
||||||
|
readDeclMemberNamesTable(ArrayRef<uint64_t> fields, StringRef blobData);
|
||||||
|
|
||||||
|
/// Read an on-disk local decl-members hash table stored in
|
||||||
|
/// index_block::DeclMembersLayout format.
|
||||||
|
std::unique_ptr<SerializedDeclMembersTable>
|
||||||
|
readDeclMembersTable(ArrayRef<uint64_t> fields, StringRef blobData);
|
||||||
|
|
||||||
/// Main logic of getDeclChecked.
|
/// Main logic of getDeclChecked.
|
||||||
llvm::Expected<Decl *>
|
llvm::Expected<Decl *>
|
||||||
getDeclCheckedImpl(serialization::DeclID DID,
|
getDeclCheckedImpl(serialization::DeclID DID,
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ const uint16_t VERSION_MAJOR = 0;
|
|||||||
/// in source control, you should also update the comment to briefly
|
/// in source control, you should also update the comment to briefly
|
||||||
/// describe what change you made. The content of this comment isn't important;
|
/// describe what change you made. The content of this comment isn't important;
|
||||||
/// it just ensures a conflict if two people change the module format.
|
/// it just ensures a conflict if two people change the module format.
|
||||||
const uint16_t VERSION_MINOR = 377; // Last change: SILFunctionType witness_method conformances
|
const uint16_t VERSION_MINOR = 378; // Last change: DECL_MEMBER_NAMES
|
||||||
|
|
||||||
using DeclIDField = BCFixed<31>;
|
using DeclIDField = BCFixed<31>;
|
||||||
|
|
||||||
@@ -440,6 +440,11 @@ enum BlockID {
|
|||||||
/// \sa index_block
|
/// \sa index_block
|
||||||
INDEX_BLOCK_ID,
|
INDEX_BLOCK_ID,
|
||||||
|
|
||||||
|
/// The declaration member-tables index block, a sub-blocb of the index block.
|
||||||
|
///
|
||||||
|
/// \sa decl_member_tables_block
|
||||||
|
DECL_MEMBER_TABLES_BLOCK_ID,
|
||||||
|
|
||||||
/// The block for SIL functions.
|
/// The block for SIL functions.
|
||||||
///
|
///
|
||||||
/// \sa sil_block
|
/// \sa sil_block
|
||||||
@@ -1516,6 +1521,7 @@ namespace index_block {
|
|||||||
|
|
||||||
PRECEDENCE_GROUPS,
|
PRECEDENCE_GROUPS,
|
||||||
NESTED_TYPE_DECLS,
|
NESTED_TYPE_DECLS,
|
||||||
|
DECL_MEMBER_NAMES,
|
||||||
|
|
||||||
LastRecordKind = PRECEDENCE_GROUPS,
|
LastRecordKind = PRECEDENCE_GROUPS,
|
||||||
};
|
};
|
||||||
@@ -1559,12 +1565,32 @@ namespace index_block {
|
|||||||
BCBlob // map from identifier strings to decl kinds / decl IDs
|
BCBlob // map from identifier strings to decl kinds / decl IDs
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
using DeclMemberNamesLayout = BCRecordLayout<
|
||||||
|
DECL_MEMBER_NAMES, // record ID
|
||||||
|
BCVBR<16>, // table offset within the blob (see below)
|
||||||
|
BCBlob // map from member DeclBaseNames to offsets of DECL_MEMBERS records
|
||||||
|
>;
|
||||||
|
|
||||||
using EntryPointLayout = BCRecordLayout<
|
using EntryPointLayout = BCRecordLayout<
|
||||||
ENTRY_POINT,
|
ENTRY_POINT,
|
||||||
DeclIDField // the ID of the main class; 0 if there was a main source file
|
DeclIDField // the ID of the main class; 0 if there was a main source file
|
||||||
>;
|
>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \sa DECL_MEMBER_TABLES_BLOCK_ID
|
||||||
|
namespace decl_member_tables_block {
|
||||||
|
enum RecordKind {
|
||||||
|
DECL_MEMBERS = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
using DeclMembersLayout = BCRecordLayout<
|
||||||
|
DECL_MEMBERS, // record ID
|
||||||
|
BCVBR<16>, // table offset within the blob (see below)
|
||||||
|
BCBlob // maps from DeclIDs to DeclID vectors
|
||||||
|
>;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/// \sa COMMENT_BLOCK_ID
|
/// \sa COMMENT_BLOCK_ID
|
||||||
namespace comment_block {
|
namespace comment_block {
|
||||||
enum RecordKind {
|
enum RecordKind {
|
||||||
|
|||||||
@@ -504,6 +504,118 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Indexing the members of all Decls (well, NominalTypeDecls anyway) is
|
||||||
|
// accomplished by a 2-level hashtable scheme. The outer table here maps from
|
||||||
|
// DeclBaseNames to serialization::BitOffsets of sub-tables. The sub-tables --
|
||||||
|
// SerializedDeclMembersTables, one table per name -- map from the enclosing
|
||||||
|
// (NominalTypeDecl) DeclID to a vector of DeclIDs of members of the nominal
|
||||||
|
// with the name. See DeclMembersTableInfo below.
|
||||||
|
class ModuleFile::DeclMemberNamesTableInfo {
|
||||||
|
public:
|
||||||
|
using internal_key_type = std::pair<DeclBaseName::Kind, StringRef>;
|
||||||
|
using external_key_type = DeclBaseName;
|
||||||
|
using data_type = serialization::BitOffset;
|
||||||
|
using hash_value_type = uint32_t;
|
||||||
|
using offset_type = unsigned;
|
||||||
|
|
||||||
|
internal_key_type GetInternalKey(external_key_type ID) {
|
||||||
|
if (ID.getKind() == DeclBaseName::Kind::Normal) {
|
||||||
|
return {DeclBaseName::Kind::Normal, ID.getIdentifier().str()};
|
||||||
|
} else {
|
||||||
|
return {ID.getKind(), StringRef()};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hash_value_type ComputeHash(internal_key_type key) {
|
||||||
|
if (key.first == DeclBaseName::Kind::Normal) {
|
||||||
|
return llvm::HashString(key.second);
|
||||||
|
} else {
|
||||||
|
return (hash_value_type)key.first;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool EqualKey(internal_key_type lhs, internal_key_type rhs) {
|
||||||
|
return lhs == rhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::pair<unsigned, unsigned> ReadKeyDataLength(const uint8_t *&data) {
|
||||||
|
unsigned keyLength = endian::readNext<uint16_t, little, unaligned>(data);
|
||||||
|
return { keyLength, sizeof(serialization::BitOffset) };
|
||||||
|
}
|
||||||
|
|
||||||
|
static internal_key_type ReadKey(const uint8_t *data, unsigned length) {
|
||||||
|
uint8_t kind = endian::readNext<uint8_t, little, unaligned>(data);
|
||||||
|
switch (kind) {
|
||||||
|
case static_cast<uint8_t>(DeclNameKind::Normal): {
|
||||||
|
StringRef str(reinterpret_cast<const char *>(data),
|
||||||
|
length - sizeof(uint8_t));
|
||||||
|
return {DeclBaseName::Kind::Normal, str};
|
||||||
|
}
|
||||||
|
case static_cast<uint8_t>(DeclNameKind::Subscript):
|
||||||
|
return {DeclBaseName::Kind::Subscript, StringRef()};
|
||||||
|
case static_cast<uint8_t>(DeclNameKind::Destructor):
|
||||||
|
return {DeclBaseName::Kind::Destructor, StringRef()};
|
||||||
|
default:
|
||||||
|
llvm_unreachable("Unknown DeclNameKind");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static data_type ReadData(internal_key_type key, const uint8_t *data,
|
||||||
|
unsigned length) {
|
||||||
|
assert(length == sizeof(serialization::BitOffset));
|
||||||
|
return endian::readNext<serialization::BitOffset, little, unaligned>(data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Second half of the 2-level member name lookup scheme, see
|
||||||
|
// DeclMemberNamesTableInfo above. There is one of these tables for each member
|
||||||
|
// DeclBaseName N in the module, and it maps from enclosing DeclIDs (say: each
|
||||||
|
// NominalTypeDecl T that has members named N) to the set of N-named members of
|
||||||
|
// T. In other words, there are no names in this table: the names are one level
|
||||||
|
// up, this table just maps { Owner-DeclID => [Member-DeclID, ...] }.
|
||||||
|
class ModuleFile::DeclMembersTableInfo {
|
||||||
|
public:
|
||||||
|
using internal_key_type = uint32_t;
|
||||||
|
using external_key_type = DeclID;
|
||||||
|
using data_type = SmallVector<DeclID, 2>;
|
||||||
|
using hash_value_type = uint32_t;
|
||||||
|
using offset_type = unsigned;
|
||||||
|
|
||||||
|
internal_key_type GetInternalKey(external_key_type ID) {
|
||||||
|
return ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
hash_value_type ComputeHash(internal_key_type key) {
|
||||||
|
return llvm::hash_value(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool EqualKey(internal_key_type lhs, internal_key_type rhs) {
|
||||||
|
return lhs == rhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::pair<unsigned, unsigned> ReadKeyDataLength(const uint8_t *&data) {
|
||||||
|
unsigned keyLength = endian::readNext<uint16_t, little, unaligned>(data);
|
||||||
|
unsigned dataLength = endian::readNext<uint16_t, little, unaligned>(data);
|
||||||
|
return { keyLength, dataLength };
|
||||||
|
}
|
||||||
|
|
||||||
|
static internal_key_type ReadKey(const uint8_t *data, unsigned length) {
|
||||||
|
return endian::readNext<uint32_t, little, unaligned>(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static data_type ReadData(internal_key_type key, const uint8_t *data,
|
||||||
|
unsigned length) {
|
||||||
|
data_type result;
|
||||||
|
while (length > 0) {
|
||||||
|
DeclID declID = endian::readNext<uint32_t, little, unaligned>(data);
|
||||||
|
result.push_back(declID);
|
||||||
|
length -= sizeof(uint32_t);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
std::unique_ptr<ModuleFile::SerializedDeclTable>
|
std::unique_ptr<ModuleFile::SerializedDeclTable>
|
||||||
ModuleFile::readDeclTable(ArrayRef<uint64_t> fields, StringRef blobData) {
|
ModuleFile::readDeclTable(ArrayRef<uint64_t> fields, StringRef blobData) {
|
||||||
uint32_t tableOffset;
|
uint32_t tableOffset;
|
||||||
@@ -549,6 +661,31 @@ ModuleFile::readNestedTypeDeclsTable(ArrayRef<uint64_t> fields,
|
|||||||
base + sizeof(uint32_t), base));
|
base + sizeof(uint32_t), base));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<ModuleFile::SerializedDeclMemberNamesTable>
|
||||||
|
ModuleFile::readDeclMemberNamesTable(ArrayRef<uint64_t> fields,
|
||||||
|
StringRef blobData) {
|
||||||
|
uint32_t tableOffset;
|
||||||
|
index_block::DeclMemberNamesLayout::readRecord(fields, tableOffset);
|
||||||
|
auto base = reinterpret_cast<const uint8_t *>(blobData.data());
|
||||||
|
|
||||||
|
using OwnedTable = std::unique_ptr<SerializedDeclMemberNamesTable>;
|
||||||
|
return OwnedTable(SerializedDeclMemberNamesTable::Create(base + tableOffset,
|
||||||
|
base + sizeof(uint32_t), base));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<ModuleFile::SerializedDeclMembersTable>
|
||||||
|
ModuleFile::readDeclMembersTable(ArrayRef<uint64_t> fields,
|
||||||
|
StringRef blobData) {
|
||||||
|
uint32_t tableOffset;
|
||||||
|
decl_member_tables_block::DeclMembersLayout::readRecord(fields,
|
||||||
|
tableOffset);
|
||||||
|
auto base = reinterpret_cast<const uint8_t *>(blobData.data());
|
||||||
|
|
||||||
|
using OwnedTable = std::unique_ptr<SerializedDeclMembersTable>;
|
||||||
|
return OwnedTable(SerializedDeclMembersTable::Create(base + tableOffset,
|
||||||
|
base + sizeof(uint32_t), base));
|
||||||
|
}
|
||||||
|
|
||||||
/// Used to deserialize entries in the on-disk Objective-C method table.
|
/// Used to deserialize entries in the on-disk Objective-C method table.
|
||||||
class ModuleFile::ObjCMethodTableInfo {
|
class ModuleFile::ObjCMethodTableInfo {
|
||||||
public:
|
public:
|
||||||
@@ -686,6 +823,9 @@ bool ModuleFile::readIndexBlock(llvm::BitstreamCursor &cursor) {
|
|||||||
case index_block::NESTED_TYPE_DECLS:
|
case index_block::NESTED_TYPE_DECLS:
|
||||||
NestedTypeDecls = readNestedTypeDeclsTable(scratch, blobData);
|
NestedTypeDecls = readNestedTypeDeclsTable(scratch, blobData);
|
||||||
break;
|
break;
|
||||||
|
case index_block::DECL_MEMBER_NAMES:
|
||||||
|
DeclMemberNames = readDeclMemberNamesTable(scratch, blobData);
|
||||||
|
break;
|
||||||
case index_block::LOCAL_DECL_CONTEXT_OFFSETS:
|
case index_block::LOCAL_DECL_CONTEXT_OFFSETS:
|
||||||
assert(blobData.empty());
|
assert(blobData.empty());
|
||||||
LocalDeclContexts.assign(scratch.begin(), scratch.end());
|
LocalDeclContexts.assign(scratch.begin(), scratch.end());
|
||||||
|
|||||||
@@ -651,6 +651,10 @@ void Serializer::writeBlockInfoBlock() {
|
|||||||
BLOCK_RECORD(index_block, SIL_LAYOUT_OFFSETS);
|
BLOCK_RECORD(index_block, SIL_LAYOUT_OFFSETS);
|
||||||
BLOCK_RECORD(index_block, PRECEDENCE_GROUPS);
|
BLOCK_RECORD(index_block, PRECEDENCE_GROUPS);
|
||||||
BLOCK_RECORD(index_block, NESTED_TYPE_DECLS);
|
BLOCK_RECORD(index_block, NESTED_TYPE_DECLS);
|
||||||
|
BLOCK_RECORD(index_block, DECL_MEMBER_NAMES);
|
||||||
|
|
||||||
|
BLOCK(DECL_MEMBER_TABLES_BLOCK);
|
||||||
|
BLOCK_RECORD(decl_member_tables_block, DECL_MEMBERS);
|
||||||
|
|
||||||
BLOCK(SIL_BLOCK);
|
BLOCK(SIL_BLOCK);
|
||||||
BLOCK_RECORD(sil_block, SIL_FUNCTION);
|
BLOCK_RECORD(sil_block, SIL_FUNCTION);
|
||||||
|
|||||||
Reference in New Issue
Block a user