Skip to content

[Runtime] Extract some layout string functionality into separate func… #66577

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions include/swift/Runtime/Metadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,36 @@ void swift_initStructMetadataWithLayoutString(StructMetadata *self,
const uint8_t *fieldTags,
uint32_t *fieldOffsets);

SWIFT_RUNTIME_STDLIB_INTERNAL
size_t _swift_refCountBytesForMetatype(const Metadata *type);

enum LayoutStringFlags : uint64_t {
Empty = 0,
// TODO: Track other useful information tha can be used to optimize layout
// strings, like different reference kinds contained in the string
// number of ref counting operations (maybe up to 4), so we can
// use witness functions optimized for these cases.
HasRelativePointers = (1ULL << 63),
};

inline bool operator&(LayoutStringFlags a, LayoutStringFlags b) {
return (uint64_t(a) & uint64_t(b)) != 0;
}
inline LayoutStringFlags operator|(LayoutStringFlags a, LayoutStringFlags b) {
return LayoutStringFlags(uint64_t(a) | uint64_t(b));
}
inline LayoutStringFlags &operator|=(LayoutStringFlags &a, LayoutStringFlags b) {
return a = (a | b);
}

SWIFT_RUNTIME_STDLIB_INTERNAL
void _swift_addRefCountStringForMetatype(uint8_t *layoutStr,
size_t &layoutStrOffset,
LayoutStringFlags &flags,
const Metadata *fieldType,
size_t &fullOffset,
size_t &previousFieldOffset);

/// Allocate the metadata for a class and copy fields from the given pattern.
/// The final size of the metadata is calculated at runtime from the metadata
/// bounds in the class descriptor.
Expand Down
60 changes: 60 additions & 0 deletions stdlib/public/runtime/Enum.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,66 @@ swift::swift_initEnumMetadataMultiPayload(EnumMetadata *enumType,
vwtable->publishLayout(layout);
}

// void
// swift::swift_initEnumMetadataMultiPayloadWithLayoutString(EnumMetadata *enumType,
// EnumLayoutFlags layoutFlags,
// unsigned numPayloads,
// const TypeLayout * const *payloadLayouts) {
// // Accumulate the layout requirements of the payloads.
// size_t payloadSize = 0, alignMask = 0;
// bool isPOD = true, isBT = true;
// for (unsigned i = 0; i < numPayloads; ++i) {
// const TypeLayout *payloadLayout = payloadLayouts[i];
// payloadSize
// = std::max(payloadSize, (size_t)payloadLayout->size);
// alignMask |= payloadLayout->flags.getAlignmentMask();
// isPOD &= payloadLayout->flags.isPOD();
// isBT &= payloadLayout->flags.isBitwiseTakable();
// }

// // Store the max payload size in the metadata.
// assignUnlessEqual(enumType->getPayloadSize(), payloadSize);

// // The total size includes space for the tag.
// auto tagCounts = getEnumTagCounts(payloadSize,
// enumType->getDescription()->getNumEmptyCases(),
// numPayloads);
// unsigned totalSize = payloadSize + tagCounts.numTagBytes;

// // See whether there are extra inhabitants in the tag.
// unsigned numExtraInhabitants = tagCounts.numTagBytes == 4
// ? INT_MAX
// : (1 << (tagCounts.numTagBytes * 8)) - tagCounts.numTags;
// numExtraInhabitants = std::min(numExtraInhabitants,
// unsigned(ValueWitnessFlags::MaxNumExtraInhabitants));

// auto vwtable = getMutableVWTableForInit(enumType, layoutFlags);

// // Set up the layout info in the vwtable.
// auto rawStride = (totalSize + alignMask) & ~alignMask;
// TypeLayout layout{totalSize,
// rawStride == 0 ? 1 : rawStride,
// ValueWitnessFlags()
// .withAlignmentMask(alignMask)
// .withPOD(isPOD)
// .withBitwiseTakable(isBT)
// .withEnumWitnesses(true)
// .withInlineStorage(ValueWitnessTable::isValueInline(
// isBT, totalSize, alignMask + 1)),
// numExtraInhabitants};

// installCommonValueWitnesses(layout, vwtable);

// // Unconditionally overwrite the enum-tag witnesses.
// // The compiler does not generate meaningful enum-tag witnesses for
// // enums in this state.
// vwtable->getEnumTagSinglePayload = swift_getMultiPayloadEnumTagSinglePayload;
// vwtable->storeEnumTagSinglePayload =
// swift_storeMultiPayloadEnumTagSinglePayload;

// vwtable->publishLayout(layout);
//}

namespace {
struct MultiPayloadLayout {
size_t payloadSize;
Expand Down