[runtime] Metadata can be flagged static.

Added a new flag to the GenericMetadataPatternFlags flagset for whether
the metadata has a set of flags at its tail.  When that flag is set,
there will be an extra uint64_t flagset at the end of the metadata.  For
struct metadata, the type of that flagset will be
StructMetadataTrailingFlags.  The first flag in that trailing flagset
indicates whether the metadata was statically specialized.  The second
flag in that trailing flagset indicates whether the metadata is
statically canonical.

When verifying the metadata cache, a check is done for whether the
metadata was statically specialized and whether it was known to be
canonical statically.  If so, verification is skipped.  Skipping it is
necessary because the known-canonical statically specialized metadata
will not be in the cache.  In that case, the canonical statically
specialized metadata will be returned from the metadata accessor and
never be cached.
This commit is contained in:
Nate Chandler
2019-12-04 11:34:19 -08:00
parent cdf3817c04
commit edab098067
3 changed files with 78 additions and 0 deletions

View File

@@ -4630,6 +4630,14 @@ const WitnessTable *swift::swift_getAssociatedConformanceWitness(
template <class Result, class Callbacks>
static Result performOnMetadataCache(const Metadata *metadata,
Callbacks &&callbacks) {
// TODO: Once more than just structs have canonical statically specialized
// metadata, calling an updated
// isCanonicalStaticallySpecializedGenericMetadata would entail
// dyn_casting to the same type more than once. Avoid that by combining
// that function's implementation with the dyn_casts below.
if (metadata->isCanonicalStaticallySpecializedGenericMetadata())
return std::move(callbacks).forOtherMetadata(metadata);
// Handle different kinds of type that can delay their metadata.
const TypeContextDescriptor *description;
if (auto classMetadata = dyn_cast<ClassMetadata>(metadata)) {
@@ -5211,6 +5219,14 @@ bool Metadata::satisfiesClassConstraint() const {
return isAnyClass();
}
template <>
bool Metadata::isCanonicalStaticallySpecializedGenericMetadata() const {
if (auto *metadata = dyn_cast<StructMetadata>(this))
return metadata->isCanonicalStaticallySpecializedGenericMetadata();
return false;
}
#if !NDEBUG
static bool referencesAnonymousContext(Demangle::Node *node) {
if (node->getKind() == Demangle::Node::Kind::AnonymousContext)