[Serialization] Give generic environments identitity.

Serialize generic environments via a generic environment ID with a
separte offset table, so we have identity for the generic environments
and will share generic environments on deserialization.
This commit is contained in:
Doug Gregor
2016-12-13 16:55:21 -08:00
parent 2ff90611a8
commit 821965dee4
9 changed files with 427 additions and 303 deletions

View File

@@ -256,6 +256,9 @@ private:
/// Types referenced by this module.
std::vector<Serialized<Type>> Types;
/// Generic environments referenced by this module.
std::vector<Serialized<GenericEnvironment *>> GenericEnvironments;
/// Represents an identifier that may or may not have been deserialized yet.
///
/// If \c Offset is non-zero, the identifier has not been loaded yet.
@@ -313,9 +316,6 @@ private:
std::unique_ptr<GroupNameTable> GroupNamesMap;
std::unique_ptr<SerializedDeclCommentTable> DeclCommentTable;
/// Saved type substitution maps for lazily-created generic environments.
std::vector<std::unique_ptr<TypeSubstitutionMap>> GenericEnvironmentMaps;
struct ModuleBits {
/// The decl ID of the main class in this module file, if it has one.
unsigned EntryPointDeclID : 31;
@@ -449,35 +449,12 @@ private:
void readGenericRequirements(SmallVectorImpl<Requirement> &requirements,
llvm::BitstreamCursor &Cursor);
/// Allocate a lazy generic environment map for use with lazily deserialized
/// generic environments.
uint64_t allocateLazyGenericEnvironmentMap(TypeSubstitutionMap &&map);
/// Set up a lazy generic environment for the given type or extension.
void readLazyGenericEnvironment(
llvm::PointerUnion<GenericTypeDecl *, ExtensionDecl *> typeOrExt);
/// Read the generic signature and type substitution map for a
/// generic environment from \c Cursor.
std::pair<GenericSignature *, TypeSubstitutionMap>
readGenericEnvironmentPieces(llvm::BitstreamCursor &Cursor,
Optional<ArrayRef<Requirement>> optRequirements
= None);
/// Reads a GenericEnvironment from \c Cursor.
///
/// The optional requirements are used to construct the signature without
/// attempting to deserialize any requirements, such as when reading SIL.
GenericEnvironment *readGenericEnvironment(
llvm::BitstreamCursor &Cursor,
Optional<ArrayRef<Requirement>> optRequirements = None);
/// Reads a GenericEnvironment followed by requirements from \c DeclTypeCursor.
///
/// Returns the GenericEnvironment.
///
/// Returns nullptr if there's no generic signature here.
GenericEnvironment *maybeReadGenericEnvironment();
/// Set up a (potentially lazy) generic environment for the given type,
/// function or extension.
void configureGenericEnvironment(
llvm::PointerUnion3<GenericTypeDecl *, ExtensionDecl *,
AbstractFunctionDecl *> genericDecl,
serialization::GenericEnvironmentID envID);
/// Populates the vector with members of a DeclContext from \c DeclTypeCursor.
///
@@ -729,6 +706,35 @@ public:
/// is loaded instead.
Module *getModule(ArrayRef<Identifier> name);
/// Return the generic signature or environment at the current position in
/// the given cursor.
///
/// \param cursor The cursor to read from.
/// \param wantEnvironment Whether we always want to receive a generic
/// environment vs. being able to handle the generic signature.
/// \param optRequirements If not \c None, use these generic requirements
/// rather than deserializing requirements.
llvm::PointerUnion<GenericSignature *, GenericEnvironment *>
readGenericSignatureOrEnvironment(
llvm::BitstreamCursor &cursor,
bool wantEnvironment,
Optional<ArrayRef<Requirement>> optRequirements);
/// Returns the generic signature or environment for the given ID,
/// deserializing it if needed.
///
/// \param wantEnvironment If true, always return the full generic
/// environment. Otherwise, only return the generic environment if it's
/// already been constructed, and the signature in other cases.
llvm::PointerUnion<GenericSignature *, GenericEnvironment *>
getGenericSignatureOrEnvironment(serialization::GenericEnvironmentID ID,
bool wantEnvironment = false);
/// Returns the generic environment for the given ID, deserializing it if
/// needed.
GenericEnvironment *getGenericEnvironment(
serialization::GenericEnvironmentID ID);
/// Reads a substitution record from \c DeclTypeCursor.
///
/// If the record at the cursor is not a substitution, returns None.