[Serialization] Factor out common loop in writing AST block entities

No intended functionality change (other than a small reorder).
This commit is contained in:
Jordan Rose
2019-08-23 13:58:15 -07:00
parent 9e1b206984
commit 6bd0421989
2 changed files with 45 additions and 54 deletions

View File

@@ -1177,7 +1177,7 @@ void Serializer::writeGenericRequirements(ArrayRef<Requirement> requirements,
} }
} }
void Serializer::writeGenericSignature(const GenericSignature *sig) { void Serializer::writeASTBlockEntity(const GenericSignature *sig) {
using namespace decls_block; using namespace decls_block;
assert(sig != nullptr); assert(sig != nullptr);
@@ -1257,7 +1257,7 @@ void Serializer::writeGenericEnvironment(const GenericEnvironment *env) {
DeclTypeAbbrCodes); DeclTypeAbbrCodes);
} }
void Serializer::writeSubstitutionMap(const SubstitutionMap substitutions) { void Serializer::writeASTBlockEntity(const SubstitutionMap substitutions) {
using namespace decls_block; using namespace decls_block;
assert(substitutions); assert(substitutions);
assert(SubstitutionMapsToSerialize.hasRef(substitutions)); assert(SubstitutionMapsToSerialize.hasRef(substitutions));
@@ -1277,7 +1277,7 @@ void Serializer::writeSubstitutionMap(const SubstitutionMap substitutions) {
writeConformances(substitutions.getConformances(), DeclTypeAbbrCodes); writeConformances(substitutions.getConformances(), DeclTypeAbbrCodes);
} }
void Serializer::writeSILLayout(const SILLayout *layout) { void Serializer::writeASTBlockEntity(const SILLayout *layout) {
using namespace decls_block; using namespace decls_block;
assert(SILLayoutsToSerialize.hasRef(layout)); assert(SILLayoutsToSerialize.hasRef(layout));
@@ -1301,7 +1301,7 @@ void Serializer::writeSILLayout(const SILLayout *layout) {
data); data);
} }
void Serializer::writeNormalConformance( void Serializer::writeASTBlockEntity(
const NormalProtocolConformance *conformance) { const NormalProtocolConformance *conformance) {
using namespace decls_block; using namespace decls_block;
@@ -1925,11 +1925,11 @@ void Serializer::writeAbstractClosureExpr(const DeclContext *parentContext,
parentID.getOpaqueValue()); parentID.getOpaqueValue());
} }
void Serializer::writeLocalDeclContext(const DeclContext *DC) { void Serializer::writeASTBlockEntity(const DeclContext *DC) {
using namespace decls_block; using namespace decls_block;
assert(shouldSerializeAsLocalContext(DC) && assert(shouldSerializeAsLocalContext(DC) &&
"Can't serialize as local context"); "should be serialized as a Decl instead");
assert(LocalDeclContextsToSerialize.hasRef(DC)); assert(LocalDeclContextsToSerialize.hasRef(DC));
switch (DC->getContextKind()) { switch (DC->getContextKind()) {
@@ -3577,7 +3577,7 @@ public:
} }
}; };
void Serializer::writeDecl(const Decl *D) { void Serializer::writeASTBlockEntity(const Decl *D) {
using namespace decls_block; using namespace decls_block;
PrettyStackTraceDecl trace("serializing", D); PrettyStackTraceDecl trace("serializing", D);
@@ -4103,7 +4103,7 @@ public:
} }
}; };
void Serializer::writeType(Type ty) { void Serializer::writeASTBlockEntity(Type ty) {
using namespace decls_block; using namespace decls_block;
PrettyStackTraceType traceRAII(ty->getASTContext(), "serializing", ty); PrettyStackTraceType traceRAII(ty->getASTContext(), "serializing", ty);
assert(TypesToSerialize.hasRef(ty)); assert(TypesToSerialize.hasRef(ty));
@@ -4120,6 +4120,16 @@ void Serializer::writeType(Type ty) {
TypeSerializer(*this).visit(ty); TypeSerializer(*this).visit(ty);
} }
template <typename SpecificASTBlockRecordKeeper>
bool Serializer::writeASTBlockEntitiesIfNeeded(
SpecificASTBlockRecordKeeper &entities) {
if (!entities.hasMoreToSerialize())
return false;
while (auto next = entities.popNext(Out.GetCurrentBitNo()))
writeASTBlockEntity(next.getValue());
return true;
}
void Serializer::writeAllDeclsAndTypes() { void Serializer::writeAllDeclsAndTypes() {
BCBlockRAII restoreBlock(Out, DECLS_AND_TYPES_BLOCK_ID, 8); BCBlockRAII restoreBlock(Out, DECLS_AND_TYPES_BLOCK_ID, 8);
using namespace decls_block; using namespace decls_block;
@@ -4234,50 +4244,25 @@ void Serializer::writeAllDeclsAndTypes() {
// until /all/ of the pending lists are empty. // until /all/ of the pending lists are empty.
wroteSomething = false; wroteSomething = false;
while (auto next = DeclsToSerialize.popNext(Out.GetCurrentBitNo())) { wroteSomething |= writeASTBlockEntitiesIfNeeded(DeclsToSerialize);
writeDecl(next.getValue()); wroteSomething |= writeASTBlockEntitiesIfNeeded(TypesToSerialize);
wroteSomething = true; wroteSomething |=
} writeASTBlockEntitiesIfNeeded(LocalDeclContextsToSerialize);
wroteSomething |=
while (auto next = TypesToSerialize.popNext(Out.GetCurrentBitNo())) { writeASTBlockEntitiesIfNeeded(GenericSignaturesToSerialize);
writeType(next.getValue()); wroteSomething |=
wroteSomething = true; writeASTBlockEntitiesIfNeeded(SubstitutionMapsToSerialize);
} wroteSomething |=
writeASTBlockEntitiesIfNeeded(NormalConformancesToSerialize);
while (auto next = wroteSomething |= writeASTBlockEntitiesIfNeeded(SILLayoutsToSerialize);
LocalDeclContextsToSerialize.popNext(Out.GetCurrentBitNo())) {
writeLocalDeclContext(next.getValue());
wroteSomething = true;
}
while (auto next =
GenericSignaturesToSerialize.popNext(Out.GetCurrentBitNo())) {
writeGenericSignature(next.getValue());
wroteSomething = true;
}
// Generic environments are recorded in a funny way; see
// writeNextGenericEnvironment() for why they can't just use the same logic
// as everything else.
while (GenericEnvironmentsToSerialize.hasMoreToSerialize()) { while (GenericEnvironmentsToSerialize.hasMoreToSerialize()) {
writeNextGenericEnvironment(); writeNextGenericEnvironment();
wroteSomething = true; wroteSomething = true;
} }
while (auto next =
SubstitutionMapsToSerialize.popNext(Out.GetCurrentBitNo())) {
writeSubstitutionMap(next.getValue());
wroteSomething = true;
}
while (auto next =
NormalConformancesToSerialize.popNext(Out.GetCurrentBitNo())) {
writeNormalConformance(next.getValue());
wroteSomething = true;
}
while (auto next = SILLayoutsToSerialize.popNext(Out.GetCurrentBitNo())) {
writeSILLayout(next.getValue());
wroteSomething = true;
}
} while (wroteSomething); } while (wroteSomething);
} }

View File

@@ -299,10 +299,10 @@ private:
void writeCrossReference(const Decl *D); void writeCrossReference(const Decl *D);
/// Writes the given decl. /// Writes the given decl.
void writeDecl(const Decl *D); void writeASTBlockEntity(const Decl *D);
/// Write a DeclContext as a local DeclContext at the current offset. /// Write a DeclContext as a local DeclContext at the current offset.
void writeLocalDeclContext(const DeclContext *DC); void writeASTBlockEntity(const DeclContext *DC);
/// Write the components of a PatternBindingInitializer as a local context. /// Write the components of a PatternBindingInitializer as a local context.
void writePatternBindingInitializer(PatternBindingDecl *binding, void writePatternBindingInitializer(PatternBindingDecl *binding,
@@ -315,10 +315,10 @@ private:
void writeAbstractClosureExpr(const DeclContext *parentContext, Type Ty, bool isImplicit, unsigned discriminator); void writeAbstractClosureExpr(const DeclContext *parentContext, Type Ty, bool isImplicit, unsigned discriminator);
/// Writes the given type. /// Writes the given type.
void writeType(Type ty); void writeASTBlockEntity(Type ty);
/// Writes a generic signature. /// Writes a generic signature.
void writeGenericSignature(const GenericSignature *sig); void writeASTBlockEntity(const GenericSignature *sig);
/// Writes the next generic environment in #GenericEnvironmentsToSerialize. /// Writes the next generic environment in #GenericEnvironmentsToSerialize.
/// ///
@@ -330,7 +330,7 @@ private:
void writeGenericEnvironment(const GenericEnvironment *env); void writeGenericEnvironment(const GenericEnvironment *env);
/// Writes a substitution map. /// Writes a substitution map.
void writeSubstitutionMap(const SubstitutionMap substitutions); void writeASTBlockEntity(const SubstitutionMap substitutions);
/// Registers the abbreviation for the given decl or type layout. /// Registers the abbreviation for the given decl or type layout.
template <typename Layout> template <typename Layout>
@@ -341,6 +341,12 @@ private:
DeclTypeAbbrCodes[Layout::Code] = Layout::emitAbbrev(Out); DeclTypeAbbrCodes[Layout::Code] = Layout::emitAbbrev(Out);
} }
/// Writes all queued \p entities until there are no more.
///
/// \returns true if any entities were written
template <typename SpecificASTBlockRecordKeeper>
bool writeASTBlockEntitiesIfNeeded(SpecificASTBlockRecordKeeper &entities);
/// Writes all decls and types in the DeclsToWrite queue. /// Writes all decls and types in the DeclsToWrite queue.
/// ///
/// This will continue until the queue is empty, even if the items currently /// This will continue until the queue is empty, even if the items currently
@@ -470,10 +476,10 @@ public:
IdentifierID addContainingModuleRef(const DeclContext *DC); IdentifierID addContainingModuleRef(const DeclContext *DC);
/// Write a normal protocol conformance. /// Write a normal protocol conformance.
void writeNormalConformance(const NormalProtocolConformance *conformance); void writeASTBlockEntity(const NormalProtocolConformance *conformance);
/// Write a SILLayout. /// Write a SILLayout.
void writeSILLayout(const SILLayout *layout); void writeASTBlockEntity(const SILLayout *layout);
/// Writes a protocol conformance. /// Writes a protocol conformance.
/// ///