Skip to content

Commit 99a36b3

Browse files
authored
Merge pull request #68229 from drexin/wip-114575149
Fixes for layout strings enum support
2 parents 857987f + 6e3d1ae commit 99a36b3

File tree

2 files changed

+77
-38
lines changed

2 files changed

+77
-38
lines changed

lib/IRGen/TypeLayout.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2408,7 +2408,6 @@ bool EnumTypeLayoutEntry::refCountString(IRGenModule &IGM,
24082408

24092409
auto *accessor = createMetatypeAccessorFunction(IGM, ty, genericSig);
24102410
B.addFixedEnumRefCount(accessor);
2411-
B.addSkip(fixedSize(IGM)->getValue());
24122411
return true;
24132412
}
24142413
}

stdlib/public/runtime/BytecodeLayouts.cpp

Lines changed: 77 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -662,9 +662,13 @@ static void objcStrongDestroyBranchless(const Metadata *metadata,
662662
LayoutStringReader1 &reader,
663663
uintptr_t &addrOffset,
664664
uint8_t *addr) {
665-
objc_object *object = (objc_object*)(*(uintptr_t *)(addr + addrOffset));
665+
uintptr_t object = *(uintptr_t *)(addr + addrOffset);
666666
addrOffset += sizeof(objc_object*);
667-
objc_release(object);
667+
if (object & _swift_abi_ObjCReservedBitsMask)
668+
return;
669+
670+
object &= ~_swift_abi_SwiftSpareBitsMask;
671+
objc_release((objc_object *)object);
668672
}
669673
#endif
670674

@@ -697,7 +701,9 @@ static void resilientDestroyBranchless(const Metadata *metadata,
697701
uintptr_t &addrOffset,
698702
uint8_t *addr) {
699703
auto *type = getResilientTypeMetadata(metadata, reader);
700-
type->vw_destroy((OpaqueValue *)(addr + addrOffset));
704+
auto *object = (OpaqueValue *)(addr + addrOffset);
705+
addrOffset += type->vw_size();
706+
type->vw_destroy(object);
701707
}
702708

703709
typedef void (*DestrFnBranchless)(const Metadata *metadata,
@@ -891,10 +897,13 @@ static void objcStrongRetainBranchless(const Metadata *metadata,
891897
uint8_t *dest,
892898
uint8_t *src) {
893899
uintptr_t _addrOffset = addrOffset;
894-
objc_object *object = (objc_object*)(*(uintptr_t *)(src + _addrOffset));
895-
memcpy(dest + _addrOffset, &object, sizeof(objc_object*));
896-
addrOffset = _addrOffset + sizeof(objc_object*);
897-
objc_retain(object);
900+
uintptr_t object = *(uintptr_t *)(src + _addrOffset);
901+
memcpy(dest + _addrOffset, &object, sizeof(objc_object *));
902+
addrOffset = _addrOffset + sizeof(objc_object *);
903+
if (object & _swift_abi_ObjCReservedBitsMask)
904+
return;
905+
object &= ~_swift_abi_SwiftSpareBitsMask;
906+
objc_retain((objc_object *)object);
898907
}
899908
#endif
900909

@@ -1004,6 +1013,8 @@ swift_generic_initWithCopy(swift::OpaqueValue *dest, swift::OpaqueValue *src,
10041013
uintptr_t addrOffset = 0;
10051014
handleRefCountsInitWithCopy(metadata, reader, addrOffset, (uint8_t *)dest, (uint8_t *)src);
10061015

1016+
assert(addrOffset == metadata->vw_size());
1017+
10071018
return dest;
10081019
}
10091020

@@ -1062,8 +1073,10 @@ static void existentialInitWithTake(const Metadata *metadata,
10621073
auto *destObject = (OpaqueValue *)(dest + _addrOffset);
10631074
auto *srcObject = (OpaqueValue *)(src + _addrOffset);
10641075
addrOffset = _addrOffset + (sizeof(uintptr_t) * NumWords_ValueBuffer);
1065-
if (SWIFT_UNLIKELY(!type->getValueWitnesses()->isBitwiseTakable())) {
1076+
if (type->getValueWitnesses()->isValueInline()) {
10661077
type->vw_initializeWithTake(destObject, srcObject);
1078+
} else {
1079+
memcpy(destObject, srcObject, sizeof(uintptr_t));
10671080
}
10681081
}
10691082

@@ -1150,6 +1163,8 @@ swift_generic_initWithTake(swift::OpaqueValue *dest, swift::OpaqueValue *src,
11501163

11511164
handleRefCountsInitWithTake(metadata, reader, addrOffset, (uint8_t *)dest, (uint8_t *)src);
11521165

1166+
assert(addrOffset == metadata->vw_size());
1167+
11531168
return dest;
11541169
}
11551170

@@ -1282,12 +1297,20 @@ static void objcStrongAssignWithCopy(const Metadata *metadata,
12821297
uint8_t *dest,
12831298
uint8_t *src) {
12841299
uintptr_t _addrOffset = addrOffset;
1285-
objc_object *destObject = (objc_object*)(*(uintptr_t *)(dest + _addrOffset));
1286-
objc_object *srcObject = (objc_object*)(*(uintptr_t *)(src + _addrOffset));
1300+
uintptr_t destObject = *(uintptr_t *)(dest + _addrOffset);
1301+
uintptr_t srcObject = *(uintptr_t *)(src + _addrOffset);
12871302
memcpy(dest + _addrOffset, &srcObject, sizeof(objc_object*));
12881303
addrOffset = _addrOffset + sizeof(objc_object*);
1289-
objc_release(destObject);
1290-
objc_retain(srcObject);
1304+
1305+
if (!(destObject & _swift_abi_ObjCReservedBitsMask)) {
1306+
destObject &= ~_swift_abi_SwiftSpareBitsMask;
1307+
objc_release((objc_object *)destObject);
1308+
}
1309+
1310+
if (!(srcObject & _swift_abi_ObjCReservedBitsMask)) {
1311+
srcObject &= ~_swift_abi_SwiftSpareBitsMask;
1312+
objc_retain((objc_object *)srcObject);
1313+
}
12911314
}
12921315
#endif
12931316

@@ -1599,7 +1622,7 @@ static void multiPayloadEnumFNAssignWithCopy(const Metadata *metadata,
15991622
if (trailingBytes)
16001623
memcpy(dest + nestedAddrOffset, src + nestedAddrOffset, trailingBytes);
16011624
return;
1602-
} else if (destTag > numPayloads) {
1625+
} else if (srcTag < numPayloads) {
16031626
addrOffset += enumSize;
16041627
size_t refCountOffset = nestedReader.peekBytes<size_t>(srcTag * sizeof(size_t));
16051628
nestedReader.skip((numPayloads * sizeof(size_t)) + refCountOffset);
@@ -1608,7 +1631,10 @@ static void multiPayloadEnumFNAssignWithCopy(const Metadata *metadata,
16081631
if (trailingBytes)
16091632
memcpy(dest + nestedAddrOffset, src + nestedAddrOffset, trailingBytes);
16101633
return;
1611-
} else if (srcTag > numPayloads) {
1634+
} else if (destTag < numPayloads) {
1635+
size_t refCountOffset =
1636+
nestedReader.peekBytes<size_t>(destTag * sizeof(size_t));
1637+
nestedReader.skip((numPayloads * sizeof(size_t)) + refCountOffset);
16121638
handleRefCountsDestroy(metadata, nestedReader, nestedAddrOffset, dest);
16131639
}
16141640

@@ -1654,7 +1680,7 @@ static void multiPayloadEnumFNResolvedAssignWithCopy(const Metadata *metadata,
16541680
if (trailingBytes)
16551681
memcpy(dest + nestedAddrOffset, src + nestedAddrOffset, trailingBytes);
16561682
return;
1657-
} else if (destTag > numPayloads) {
1683+
} else if (srcTag < numPayloads) {
16581684
addrOffset += enumSize;
16591685
size_t refCountOffset = nestedReader.peekBytes<size_t>(srcTag * sizeof(size_t));
16601686
nestedReader.skip((numPayloads * sizeof(size_t)) + refCountOffset);
@@ -1663,7 +1689,10 @@ static void multiPayloadEnumFNResolvedAssignWithCopy(const Metadata *metadata,
16631689
if (trailingBytes)
16641690
memcpy(dest + nestedAddrOffset, src + nestedAddrOffset, trailingBytes);
16651691
return;
1666-
} else if (srcTag > numPayloads) {
1692+
} else if (destTag < numPayloads) {
1693+
size_t refCountOffset =
1694+
nestedReader.peekBytes<size_t>(destTag * sizeof(size_t));
1695+
nestedReader.skip((numPayloads * sizeof(size_t)) + refCountOffset);
16671696
handleRefCountsDestroy(metadata, nestedReader, nestedAddrOffset, dest);
16681697
}
16691698

@@ -1711,7 +1740,7 @@ static void multiPayloadEnumGenericAssignWithCopy(const Metadata *metadata,
17111740
if (trailingBytes)
17121741
memcpy(dest + nestedAddrOffset, src + nestedAddrOffset, trailingBytes);
17131742
return;
1714-
} else if (destTag > numPayloads) {
1743+
} else if (srcTag < numPayloads) {
17151744
addrOffset += enumSize;
17161745
size_t refCountOffset = nestedReader.peekBytes<size_t>(srcTag * sizeof(size_t));
17171746
nestedReader.skip((numPayloads * sizeof(size_t)) + refCountOffset);
@@ -1720,7 +1749,10 @@ static void multiPayloadEnumGenericAssignWithCopy(const Metadata *metadata,
17201749
if (trailingBytes)
17211750
memcpy(dest + nestedAddrOffset, src + nestedAddrOffset, trailingBytes);
17221751
return;
1723-
} else if (srcTag > numPayloads) {
1752+
} else if (destTag < numPayloads) {
1753+
size_t refCountOffset =
1754+
nestedReader.peekBytes<size_t>(destTag * sizeof(size_t));
1755+
nestedReader.skip((numPayloads * sizeof(size_t)) + refCountOffset);
17241756
handleRefCountsDestroy(metadata, nestedReader, nestedAddrOffset, dest);
17251757
}
17261758

@@ -1784,12 +1816,17 @@ static void handleRefCountsAssignWithCopy(const Metadata *metadata,
17841816
extern "C" swift::OpaqueValue *
17851817
swift_generic_assignWithCopy(swift::OpaqueValue *dest, swift::OpaqueValue *src,
17861818
const Metadata *metadata) {
1787-
const uint8_t *layoutStr = metadata->getLayoutString();
1788-
LayoutStringReader1 reader{layoutStr + layoutStringHeaderSize};
1789-
uintptr_t addrOffset = 0;
1790-
handleRefCountsAssignWithCopy(metadata, reader, addrOffset, (uint8_t *)dest, (uint8_t *)src);
1819+
// const uint8_t *layoutStr = metadata->getLayoutString();
1820+
// LayoutStringReader1 reader{layoutStr + layoutStringHeaderSize};
1821+
// uintptr_t addrOffset = 0;
1822+
// handleRefCountsAssignWithCopy(metadata, reader, addrOffset, (uint8_t
1823+
// *)dest, (uint8_t *)src);
17911824

1792-
return dest;
1825+
// assert(addrOffset == metadata->vw_size());
1826+
swift_generic_destroy(dest, metadata);
1827+
return swift_generic_initWithCopy(dest, src, metadata);
1828+
1829+
// return dest;
17931830
}
17941831

17951832
extern "C" swift::OpaqueValue *
@@ -1864,12 +1901,13 @@ extern "C" unsigned swift_enumSimple_getEnumTag(swift::OpaqueValue *address,
18641901
uint64_t zeroTagValue, uint8_t xiTagBytesPattern,
18651902
unsigned xiTagBytesOffset, size_t payloadSize,
18661903
uint8_t numExtraTagBytes) -> unsigned {
1867-
auto xiTagBytes = 1 << (xiTagBytesPattern - 1);
1868-
uint64_t tagBytes =
1869-
readTagBytes(addr + xiTagBytesOffset, xiTagBytes) -
1870-
zeroTagValue;
1871-
if (tagBytes < payloadNumExtraInhabitants) {
1872-
return tagBytes + 1;
1904+
if (xiTagBytesPattern) {
1905+
auto xiTagBytes = 1 << (xiTagBytesPattern - 1);
1906+
uint64_t tagBytes =
1907+
readTagBytes(addr + xiTagBytesOffset, xiTagBytes) - zeroTagValue;
1908+
if (tagBytes < payloadNumExtraInhabitants) {
1909+
return tagBytes + 1;
1910+
}
18731911
}
18741912

18751913
return 0;
@@ -1917,16 +1955,18 @@ extern "C" void swift_enumSimple_destructiveInjectEnumTag(
19171955
uint64_t zeroTagValue, uint8_t xiTagBytesPattern,
19181956
unsigned xiTagBytesOffset, size_t payloadSize,
19191957
uint8_t numExtraTagBytes) -> bool {
1920-
auto xiTagBytes = 1 << (xiTagBytesPattern - 1);
1921-
if (tag <= payloadNumExtraInhabitants) {
1922-
if (numExtraTagBytes != 0)
1923-
storeEnumElement(addr + payloadSize, 0, numExtraTagBytes);
1958+
if (xiTagBytesPattern) {
1959+
auto xiTagBytes = 1 << (xiTagBytesPattern - 1);
1960+
if (tag <= payloadNumExtraInhabitants) {
1961+
if (numExtraTagBytes != 0)
1962+
storeEnumElement(addr + payloadSize, 0, numExtraTagBytes);
19241963

1925-
if (tag == 0)
1926-
return true;
1964+
if (tag == 0)
1965+
return true;
19271966

1928-
storeEnumElement(addr + xiTagBytesOffset, tag - 1 + zeroTagValue,
1929-
xiTagBytes);
1967+
storeEnumElement(addr + xiTagBytesOffset, tag - 1 + zeroTagValue,
1968+
xiTagBytes);
1969+
}
19301970
}
19311971
return true;
19321972
};

0 commit comments

Comments
 (0)