Files
swift-mirror/stdlib/public/runtime/GenericCacheEntry.h
Augusto Noronha 14bc0a9317 [NFC][Runtime] Remove references to RemoteInspection from Runtime
In an effort to disentangle the three sets of llvm headers the targets
in stlib uses (real llvm headers, RuntimeHeaders/llvm,
stdlib/include/llvm), this patch completely removes the includes from
the runtime to RemoteInspection.

This is the first patch to eventually completely remove
RuntimeHeaders/llvm headers.
2026-02-19 20:43:15 -08:00

139 lines
5.2 KiB
C++

//===--- GenericCacheEntry.h ------------------------------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_RUNTIME_GENERICCACHEENTRY_H
#define SWIFT_RUNTIME_GENERICCACHEENTRY_H
#include "MetadataCache.h"
#include "swift/ABI/Metadata.h"
#include "swift/ABI/MetadataValues.h"
#include "swift/Basic/Unreachable.h"
#include "swift/Runtime/LibPrespecialized.h"
namespace swift {
bool areAllTransitiveMetadataComplete_cheap(const Metadata *type);
PrivateMetadataState inferStateForMetadata(Metadata *metadata);
MetadataDependency checkTransitiveCompleteness(const Metadata *initialType);
struct GenericCacheEntry final
: VariadicMetadataCacheEntryBase<GenericCacheEntry> {
static const char *getName() { return "GenericCache"; }
// The constructor/allocate operations that take a `const Metadata *`
// are used for the insertion of canonical specializations.
// The metadata is always complete after construction.
GenericCacheEntry(MetadataCacheKey key, MetadataWaitQueue::Worker &worker,
MetadataRequest request, const Metadata *candidate)
: VariadicMetadataCacheEntryBase(key, worker,
PrivateMetadataState::Complete,
const_cast<Metadata *>(candidate)) {}
AllocationResult allocate(const Metadata *candidate) {
swift_unreachable("always short-circuited");
}
static bool allowMangledNameVerification(const Metadata *candidate) {
// Disallow mangled name verification for specialized candidates
// because it will trigger recursive entry into the swift_once
// in cacheCanonicalSpecializedMetadata.
// TODO: verify mangled names in a second pass in that function.
return false;
}
// The constructor/allocate operations that take a descriptor
// and arguments are used along the normal allocation path.
GenericCacheEntry(MetadataCacheKey key, MetadataWaitQueue::Worker &worker,
MetadataRequest request,
const TypeContextDescriptor *description,
const void *const *arguments)
: VariadicMetadataCacheEntryBase(key, worker,
PrivateMetadataState::Allocating,
/*candidate*/ nullptr) {}
AllocationResult allocate(const TypeContextDescriptor *description,
const void *const *arguments) {
if (auto *prespecialized =
getLibPrespecializedMetadata(description, arguments))
return {prespecialized, PrivateMetadataState::Complete};
// Find a pattern. Currently we always use the default pattern.
auto &generics = description->getFullGenericContextHeader();
auto pattern = generics.DefaultInstantiationPattern.get();
// Call the pattern's instantiation function.
auto metadata =
pattern->InstantiationFunction(description, arguments, pattern);
// If there's no completion function, do a quick-and-dirty check to
// see if all of the type arguments are already complete. If they
// are, we can broadcast completion immediately and potentially avoid
// some extra locking.
PrivateMetadataState state;
if (pattern->CompletionFunction.isNull()) {
if (areAllTransitiveMetadataComplete_cheap(metadata)) {
state = PrivateMetadataState::Complete;
} else {
state = PrivateMetadataState::NonTransitiveComplete;
}
} else {
state = inferStateForMetadata(metadata);
}
return {metadata, state};
}
static bool
allowMangledNameVerification(const TypeContextDescriptor *description,
const void *const *arguments) {
return true;
}
MetadataStateWithDependency
tryInitialize(Metadata *metadata, PrivateMetadataState state,
PrivateMetadataCompletionContext *context) {
assert(state != PrivateMetadataState::Complete);
// Finish the completion function.
if (state < PrivateMetadataState::NonTransitiveComplete) {
// Find a pattern. Currently we always use the default pattern.
auto &generics =
metadata->getTypeContextDescriptor()->getFullGenericContextHeader();
auto pattern = generics.DefaultInstantiationPattern.get();
// Complete the metadata's instantiation.
auto dependency =
pattern->CompletionFunction(metadata, &context->Public, pattern);
// If this failed with a dependency, infer the current metadata state
// and return.
if (dependency) {
return {inferStateForMetadata(metadata), dependency};
}
}
// Check for transitive completeness.
if (auto dependency = checkTransitiveCompleteness(metadata)) {
return {PrivateMetadataState::NonTransitiveComplete, dependency};
}
// We're done.
return {PrivateMetadataState::Complete, MetadataDependency()};
}
};
} // namespace swift
#endif