Skip to content

Commit 4f07c06

Browse files
committed
Future proof the initRawStructMetadata entrypoint
1 parent 7cd4248 commit 4f07c06

File tree

5 files changed

+59
-17
lines changed

5 files changed

+59
-17
lines changed

include/swift/ABI/MetadataValues.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1525,6 +1525,29 @@ static inline bool isValueWitnessTableMutable(EnumLayoutFlags flags) {
15251525
return uintptr_t(flags) & uintptr_t(EnumLayoutFlags::IsVWTMutable);
15261526
}
15271527

1528+
/// Flags for raw layout.
1529+
enum class RawLayoutFlags : uintptr_t {
1530+
/// Whether or not we're initializing an array like raw layout type.
1531+
IsArray = 0x1,
1532+
1533+
/// Whether or not this raw layout type was declared 'movesAsLike'.
1534+
MovesAsLike = 0x2,
1535+
};
1536+
static inline RawLayoutFlags operator|(RawLayoutFlags lhs,
1537+
RawLayoutFlags rhs) {
1538+
return RawLayoutFlags(uintptr_t(lhs) | uintptr_t(rhs));
1539+
}
1540+
static inline RawLayoutFlags &operator|=(RawLayoutFlags &lhs,
1541+
RawLayoutFlags rhs) {
1542+
return (lhs = (lhs | rhs));
1543+
}
1544+
static inline bool isRawLayoutArray(RawLayoutFlags flags) {
1545+
return uintptr_t(flags) & uintptr_t(RawLayoutFlags::IsArray);
1546+
}
1547+
static inline bool shouldRawLayoutMoveAsLike(RawLayoutFlags flags) {
1548+
return uintptr_t(flags) & uintptr_t(RawLayoutFlags::MovesAsLike);
1549+
}
1550+
15281551
namespace SpecialPointerAuthDiscriminators {
15291552
// All of these values are the stable string hash of the corresponding
15301553
// variable name:

include/swift/Runtime/Metadata.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,9 +1057,10 @@ void _swift_registerConcurrencyStandardTypeDescriptors(
10571057
/// as the basis for the layout.
10581058
SWIFT_RUNTIME_EXPORT
10591059
void swift_initRawStructMetadata(StructMetadata *self,
1060-
StructLayoutFlags flags,
1060+
StructLayoutFlags structLayoutFlags,
10611061
const TypeLayout *likeType,
1062-
ssize_t count);
1062+
ssize_t count,
1063+
RawLayoutFlags rawLayoutFlags);
10631064

10641065
/// Check if the given generic arguments are valid inputs for the generic type
10651066
/// context and if so call the metadata access function and return the metadata.

include/swift/Runtime/RuntimeFunctions.def

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2823,14 +2823,16 @@ FUNCTION(GenericInstantiateLayoutString,
28232823
UNKNOWN_MEMEFFECTS)
28242824

28252825
// void swift_initRawStructMetadata(Metadata *structType,
2826-
// StructLayoutFlags flags,
2826+
// StructLayoutFlags structLayoutFlags,
28272827
// const TypeLayout *likeType,
2828-
// ssize_t count);
2828+
// ssize_t count,
2829+
// RawLayoutFlags rawLayoutFlags);
28292830
FUNCTION(InitRawStructMetadata,
28302831
swift_initRawStructMetadata,
28312832
C_CC, AlwaysAvailable,
28322833
RETURNS(VoidTy),
2833-
ARGS(TypeMetadataPtrTy, SizeTy, Int8PtrPtrTy->getPointerTo(0), SizeTy),
2834+
ARGS(TypeMetadataPtrTy, SizeTy, Int8PtrPtrTy->getPointerTo(0), SizeTy,
2835+
SizeTy),
28342836
ATTRS(NoUnwind),
28352837
EFFECT(MetaData),
28362838
UNKNOWN_MEMEFFECTS)

lib/IRGen/GenMeta.cpp

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3315,19 +3315,29 @@ static void emitInitializeRawLayout(IRGenFunction &IGF, SILType likeType,
33153315
}
33163316

33173317
auto &IGM = IGF.IGM;
3318+
auto rawLayout = T.getRawLayout();
33183319
auto likeTypeLayout = emitTypeLayoutRef(IGF, likeType, collector);
3319-
StructLayoutFlags flags = StructLayoutFlags::Swift5Algorithm;
3320+
auto structLayoutflags = StructLayoutFlags::Swift5Algorithm;
3321+
RawLayoutFlags rawLayoutFlags;
3322+
3323+
if (rawLayout->shouldMoveAsLikeType())
3324+
rawLayoutFlags |= RawLayoutFlags::MovesAsLike;
33203325

3321-
// If we don't have a count, then we're the 'like:' variant and we need to
3322-
// pass '-1' to the runtime call.
3326+
// If we don't have a count, then we're the 'like:' variant so just pass some
3327+
// 0 to the runtime call.
33233328
if (!count) {
3324-
count = llvm::ConstantInt::get(IGF.IGM.SizeTy, -1);
3329+
count = IGM.getSize(Size(0));
3330+
} else {
3331+
rawLayoutFlags |= RawLayoutFlags::IsArray;
33253332
}
33263333

33273334
// Call swift_initRawStructMetadata().
33283335
IGF.Builder.CreateCall(IGM.getInitRawStructMetadataFunctionPointer(),
3329-
{metadata, IGM.getSize(Size(uintptr_t(flags))),
3330-
likeTypeLayout, count});
3336+
{metadata,
3337+
IGM.getSize(Size(uintptr_t(structLayoutflags))),
3338+
likeTypeLayout,
3339+
count,
3340+
IGM.getSize(Size(uintptr_t(rawLayoutFlags)))});
33313341
}
33323342

33333343
static void emitInitializeValueMetadata(IRGenFunction &IGF,

stdlib/public/runtime/Metadata.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3028,10 +3028,11 @@ void swift::_swift_addRefCountStringForMetatype(LayoutStringWriter &writer,
30283028
/// Initialize the value witness table for a @_rawLayout struct.
30293029
SWIFT_RUNTIME_EXPORT
30303030
void swift::swift_initRawStructMetadata(StructMetadata *structType,
3031-
StructLayoutFlags layoutFlags,
3031+
StructLayoutFlags structLayoutFlags,
30323032
const TypeLayout *likeTypeLayout,
3033-
ssize_t count) {
3034-
auto vwtable = getMutableVWTableForInit(structType, layoutFlags);
3033+
ssize_t count,
3034+
RawLayoutFlags rawLayoutFlags) {
3035+
auto vwtable = getMutableVWTableForInit(structType, structLayoutFlags);
30353036

30363037
// The existing vwt function entries are all fine to preserve, the only thing
30373038
// we need to initialize is the actual type layout.
@@ -3040,9 +3041,8 @@ void swift::swift_initRawStructMetadata(StructMetadata *structType,
30403041
auto alignMask = likeTypeLayout->flags.getAlignmentMask();
30413042
auto extraInhabitantCount = likeTypeLayout->extraInhabitantCount;
30423043

3043-
// If our count is not -1, we're dealing an array like layout.
3044-
if (count != -1) {
3045-
stride *= (size_t)count;
3044+
if (isRawLayoutArray(rawLayoutFlags)) {
3045+
stride *= std::min(count, (ssize_t)0);
30463046
size = stride;
30473047
}
30483048

@@ -3052,6 +3052,12 @@ void swift::swift_initRawStructMetadata(StructMetadata *structType,
30523052
.withAlignmentMask(alignMask)
30533053
.withCopyable(false);
30543054
vwtable->extraInhabitantCount = extraInhabitantCount;
3055+
3056+
if (shouldRawLayoutMoveAsLike(rawLayoutFlags)) {
3057+
vwtable->flags = vwtable->flags
3058+
.withBitwiseTakable(likeTypeLayout->flags.isBitwiseTakable())
3059+
.withInlineStorage(likeTypeLayout->flags.isInlineStorage());
3060+
}
30553061
}
30563062

30573063
/***************************************************************************/

0 commit comments

Comments
 (0)