[runtime] Remove TwoWordPair and use the Swift calling convention instead. (#13299)

This commit is contained in:
Thomas Roughton
2017-12-08 16:27:24 +13:00
committed by Greg Parker
parent f767040b4a
commit c5bf2ec553
20 changed files with 104 additions and 147 deletions

View File

@@ -121,8 +121,8 @@
// convention.
#define SWIFT_LLVM_CC(CC) SWIFT_LLVM_CC_##CC
// Currently, RuntimeFunction.def uses the following calling conventions:
// DefaultCC, RegisterPreservingCC.
// Currently, RuntimeFunctions.def uses the following calling conventions:
// DefaultCC, RegisterPreservingCC, SwiftCC.
// If new runtime calling conventions are added later, they need to be mapped
// here to something appropriate.
@@ -131,6 +131,8 @@
#define SWIFT_CC_DefaultCC_IMPL SWIFT_CC_c
#define SWIFT_LLVM_CC_DefaultCC llvm::CallingConv::C
#define SWIFT_CC_SwiftCC SWIFT_CC_swift
#define SWIFT_LLVM_CC_RegisterPreservingCC llvm::CallingConv::PreserveMost
#if SWIFT_USE_SWIFTCALL

View File

@@ -97,67 +97,11 @@ HeapObject *swift_initStaticObject(HeapMetadata const *metadata,
SWIFT_RUNTIME_EXPORT
void swift_verifyEndOfLifetime(HeapObject *object);
/// A structure that's two pointers in size.
///
/// C functions can use the TwoWordPair::Return type to return a value in
/// two registers, compatible with Swift's calling convention for tuples
/// and structs of two word-sized elements.
template<typename A, typename B>
struct TwoWordPair {
A first;
B second;
TwoWordPair() = default;
TwoWordPair(A first, B second);
// FIXME: rdar://16257592 arm codegen doesn't call swift_allocBox correctly.
// Structs are returned indirectly on these platforms, but we want to return
// in registers, so cram the result into an unsigned long long.
// Use an enum class with implicit conversions so we don't dirty C callers
// too much.
#if __arm__ || __i386__ || defined(__CYGWIN__) || defined(_MSC_VER)
#if defined(__CYGWIN__)
enum class Return : unsigned __int128 {};
#else
enum class Return : unsigned long long {};
#endif
operator Return() const {
union {
TwoWordPair value;
Return mangled;
} reinterpret = {*this};
return reinterpret.mangled;
}
/*implicit*/ TwoWordPair(Return r) {
union {
Return mangled;
TwoWordPair value;
} reinterpret = {r};
*this = reinterpret.value;
}
#else
using Return = TwoWordPair;
#endif
struct BoxPair {
HeapObject *object;
OpaqueValue *buffer;
};
template<typename A, typename B>
inline TwoWordPair<A,B>::TwoWordPair(A first, B second)
: first(first), second(second)
{
static_assert(sizeof(A) == sizeof(void*),
"first type must be word-sized");
static_assert(sizeof(B) == sizeof(void*),
"second type must be word-sized");
static_assert(alignof(TwoWordPair) == alignof(void*),
"pair must be word-aligned");
}
using BoxPair = TwoWordPair<HeapObject *, OpaqueValue *>;
/// Allocates a heap object that can contain a value of the given type.
/// Returns a Box structure containing a HeapObject* pointer to the
/// allocated object, and a pointer to the value inside the heap object.
@@ -165,19 +109,19 @@ using BoxPair = TwoWordPair<HeapObject *, OpaqueValue *>;
/// appropriate to store a value of the given type.
/// The heap object has an initial retain count of 1, and its metadata is set
/// such that destroying the heap object destroys the contained value.
SWIFT_RUNTIME_EXPORT
BoxPair::Return swift_allocBox(Metadata const *type);
SWIFT_CC(swift) SWIFT_RUNTIME_EXPORT
BoxPair swift_allocBox(Metadata const *type);
SWIFT_RUNTIME_EXPORT
BoxPair::Return (*_swift_allocBox)(Metadata const *type);
SWIFT_CC(swift) SWIFT_RUNTIME_EXPORT
BoxPair (*_swift_allocBox)(Metadata const *type);
/// Performs a uniqueness check on the pointer to a box structure. If the check
/// fails allocates a new box and stores the pointer in the buffer.
///
/// if (!isUnique(buffer[0]))
/// buffer[0] = swift_allocBox(type)
SWIFT_RUNTIME_EXPORT
BoxPair::Return swift_makeBoxUnique(OpaqueValue *buffer, Metadata const *type,
SWIFT_CC(swift) SWIFT_RUNTIME_EXPORT
BoxPair swift_makeBoxUnique(OpaqueValue *buffer, Metadata const *type,
size_t alignMask);
/// Returns the address of a heap object representing all empty box types.
@@ -1242,11 +1186,16 @@ static inline bool swift_unknownUnownedIsEqual(UnownedReference *ref,
#endif /* SWIFT_OBJC_INTEROP */
struct TypeNamePair {
const char *data;
uintptr_t length;
};
/// Return the name of a Swift type represented by a metadata object.
/// func _getTypeName(_ type: Any.Type, qualified: Bool)
/// -> (UnsafePointer<UInt8>, Int)
SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_API
TwoWordPair<const char *, uintptr_t>::Return
TypeNamePair
swift_getTypeName(const Metadata *type, bool qualified);
} // end namespace swift

View File

@@ -26,7 +26,7 @@ HeapObject *(*_swift_allocObject)(HeapMetadata const *metadata,
size_t requiredAlignmentMask);
SWIFT_RUNTIME_EXPORT
BoxPair::Return (*_swift_allocBox)(Metadata const *type);
BoxPair (*swift_allocBox)(Metadata const *type);
SWIFT_RUNTIME_EXPORT
HeapObject *(*_swift_retain)(HeapObject *object);

View File

@@ -50,7 +50,7 @@
#endif
FUNCTION_WITH_GLOBAL_SYMBOL_AND_IMPL(AllocBox, swift_allocBox,
_swift_allocBox, _swift_allocBox_, DefaultCC,
_swift_allocBox, _swift_allocBox_, SwiftCC,
RETURNS(RefCountedPtrTy, OpaquePtrTy),
ARGS(TypeMetadataPtrTy),
ATTRS(NoUnwind))
@@ -58,7 +58,7 @@ FUNCTION_WITH_GLOBAL_SYMBOL_AND_IMPL(AllocBox, swift_allocBox,
// BoxPair swift_makeBoxUnique(OpaqueValue *buffer, Metadata *type, size_t alignMask);
FUNCTION(MakeBoxUnique,
swift_makeBoxUnique,
DefaultCC,
SwiftCC,
RETURNS(RefCountedPtrTy, OpaquePtrTy),
ARGS(OpaquePtrTy, TypeMetadataPtrTy, SizeTy),
ATTRS(NoUnwind))
@@ -1332,7 +1332,7 @@ FUNCTION(DeletedMethodError, swift_deletedMethodError, C_CC,
ARGS(),
ATTRS(NoUnwind))
FUNCTION(AllocError, swift_allocError, C_CC,
FUNCTION(AllocError, swift_allocError, SwiftCC,
RETURNS(ErrorPtrTy, OpaquePtrTy),
ARGS(TypeMetadataPtrTy, WitnessTablePtrTy, OpaquePtrTy, Int1Ty),
ATTRS(NoUnwind))

View File

@@ -610,6 +610,10 @@ llvm::Constant *swift::getWrapperFn(llvm::Module &Module,
RETURNS, ARGS, ATTRS) \
FUNCTION_IMPL(ID, NAME, CC, QUOTE(RETURNS), QUOTE(ARGS), QUOTE(ATTRS))
#define FUNCTION_WITH_GLOBAL_SYMBOL_FOR_CONV_SwiftCC(ID, NAME, SYMBOL, CC, \
RETURNS, ARGS, ATTRS) \
FUNCTION_IMPL(ID, NAME, CC, QUOTE(RETURNS), QUOTE(ARGS), QUOTE(ATTRS))
#define FUNCTION_WITH_GLOBAL_SYMBOL_FOR_CONV_RegisterPreservingCC( \
ID, NAME, SYMBOL, CC, RETURNS, ARGS, ATTRS) \
FUNCTION_WITH_GLOBAL_SYMBOL_IMPL(ID, NAME, SYMBOL, CC, QUOTE(RETURNS), \

View File

@@ -59,9 +59,9 @@ namespace {
template <size_t N>
StringRefLite(const char (&staticStr)[N]) : data(staticStr), length(N) {}
StringRefLite(swift::TwoWordPair<const char *, uintptr_t>::Return rawValue)
: data(swift::TwoWordPair<const char *, uintptr_t>(rawValue).first),
length(swift::TwoWordPair<const char *, uintptr_t>(rawValue).second){}
StringRefLite(swift::TypeNamePair rawValue)
: data(rawValue.data),
length(rawValue.length){}
NS_RETURNS_RETAINED
NSString *newNSStringNoCopy() const {

View File

@@ -113,9 +113,8 @@ std::string swift::nameForMetadata(const Metadata *type,
return result;
}
TwoWordPair<const char *, uintptr_t>::Return
TypeNamePair
swift::swift_getTypeName(const Metadata *type, bool qualified) {
using Pair = TwoWordPair<const char *, uintptr_t>;
using Key = llvm::PointerIntPair<const Metadata *, 1, bool>;
static StaticReadWriteLock TypeNameCacheLock;
@@ -132,7 +131,7 @@ swift::swift_getTypeName(const Metadata *type, bool qualified) {
auto found = cache.find(key);
if (found != cache.end()) {
auto result = found->second;
return Pair{result.first, result.second};
return TypeNamePair{result.first, result.second};
}
}
@@ -145,7 +144,7 @@ swift::swift_getTypeName(const Metadata *type, bool qualified) {
auto found = cache.find(key);
if (found != cache.end()) {
auto result = found->second;
return Pair{result.first, result.second};
return TypeNamePair{result.first, result.second};
}
// Build the metadata name.
@@ -157,7 +156,7 @@ swift::swift_getTypeName(const Metadata *type, bool qualified) {
result[size] = 0;
cache.insert({key, {result, size}});
return Pair{result, size};
return TypeNamePair{result, size};
}
}
@@ -955,7 +954,7 @@ static bool _dynamicCastToExistential(OpaqueValue *dest,
(canConsumeDynamicValue && (flags & DynamicCastFlags::TakeOnSuccess));
BoxPair destBox = swift_allocError(srcDynamicType, errorWitness,
srcDynamicValue, isTake);
*destBoxAddr = reinterpret_cast<SwiftError*>(destBox.first);
*destBoxAddr = reinterpret_cast<SwiftError*>(destBox.object);
maybeDeallocateSource(true);
return true;
}
@@ -1977,7 +1976,7 @@ static id dynamicCastValueToNSError(OpaqueValue *src,
BoxPair errorBox = swift_allocError(srcType, srcErrorWitness, src,
/*isTake*/ flags & DynamicCastFlags::TakeOnSuccess);
return _swift_stdlib_bridgeErrorToNSError((SwiftError*)errorBox.first);
return _swift_stdlib_bridgeErrorToNSError((SwiftError*)errorBox.object);
}
#endif

View File

@@ -171,8 +171,8 @@ struct SwiftError : SwiftErrorHeader {
/// copied (or taken if \c isTake is true) into the newly-allocated error box.
/// If value is null, the box's contents will be left uninitialized, and
/// \c isTake should be false.
SWIFT_RUNTIME_STDLIB_API
BoxPair::Return swift_allocError(const Metadata *type,
SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_API
BoxPair swift_allocError(const Metadata *type,
const WitnessTable *errorConformance,
OpaqueValue *value, bool isTake);

View File

@@ -161,7 +161,7 @@ static Class getSwiftNativeNSErrorClass() {
}
/// Allocate a catchable error object.
BoxPair::Return
BoxPair
swift::swift_allocError(const Metadata *type,
const WitnessTable *errorConformance,
OpaqueValue *initialValue,

View File

@@ -64,7 +64,7 @@ static const FullMetadata<HeapMetadata> ErrorMetadata{
Metadata{MetadataKind::ErrorObject},
};
BoxPair::Return
BoxPair
swift::swift_allocError(const swift::Metadata *type,
const swift::WitnessTable *errorConformance,
OpaqueValue *initialValue,

View File

@@ -203,11 +203,11 @@ public:
static SimpleGlobalCache<BoxCacheEntry> Boxes;
BoxPair::Return swift::swift_allocBox(const Metadata *type) {
BoxPair swift::swift_allocBox(const Metadata *type) {
return SWIFT_RT_ENTRY_REF(swift_allocBox)(type);
}
BoxPair::Return swift::swift_makeBoxUnique(OpaqueValue *buffer, const Metadata *type,
BoxPair swift::swift_makeBoxUnique(OpaqueValue *buffer, const Metadata *type,
size_t alignMask) {
auto *inlineBuffer = reinterpret_cast<ValueBuffer*>(buffer);
HeapObject *box = reinterpret_cast<HeapObject *>(inlineBuffer->PrivateData[0]);
@@ -219,8 +219,8 @@ BoxPair::Return swift::swift_makeBoxUnique(OpaqueValue *buffer, const Metadata *
auto *oldObjectAddr = reinterpret_cast<OpaqueValue *>(
reinterpret_cast<char *>(box) + headerOffset);
// Copy the data.
type->vw_initializeWithCopy(refAndObjectAddr.second, oldObjectAddr);
inlineBuffer->PrivateData[0] = refAndObjectAddr.first;
type->vw_initializeWithCopy(refAndObjectAddr.buffer, oldObjectAddr);
inlineBuffer->PrivateData[0] = refAndObjectAddr.object;
// Release ownership of the old box.
swift_release(box);
return refAndObjectAddr;
@@ -234,7 +234,7 @@ BoxPair::Return swift::swift_makeBoxUnique(OpaqueValue *buffer, const Metadata *
SWIFT_RT_ENTRY_IMPL_VISIBILITY
extern "C"
BoxPair::Return SWIFT_RT_ENTRY_IMPL(swift_allocBox)(const Metadata *type) {
BoxPair SWIFT_RT_ENTRY_IMPL(swift_allocBox)(const Metadata *type) {
// Get the heap metadata for the box.
auto metadata = &Boxes.getOrInsert(type).first->Data;

View File

@@ -636,8 +636,8 @@ static OpaqueValue *tuple_allocateBuffer(ValueBuffer *buffer,
if (IsInline)
return reinterpret_cast<OpaqueValue*>(buffer);
BoxPair refAndValueAddr(swift_allocBox(metatype));
*reinterpret_cast<HeapObject **>(buffer) = refAndValueAddr.first;
return refAndValueAddr.second;
*reinterpret_cast<HeapObject **>(buffer) = refAndValueAddr.object;
return refAndValueAddr.buffer;
}
/// Generic tuple value witness for 'destroy'.
@@ -2542,8 +2542,8 @@ template <> OpaqueValue *Metadata::allocateBoxForExistentialIn(ValueBuffer *buff
// Allocate the box.
BoxPair refAndValueAddr(swift_allocBox(this));
buffer->PrivateData[0] = refAndValueAddr.first;
return refAndValueAddr.second;
buffer->PrivateData[0] = refAndValueAddr.object;
return refAndValueAddr.buffer;
}
template <> OpaqueValue *Metadata::allocateBufferIn(ValueBuffer *buffer) const {

View File

@@ -633,21 +633,21 @@ void swift_EnumMirror_subscript(String *outString,
BoxPair pair = swift_allocBox(boxType);
type->vw_destructiveProjectEnumData(const_cast<OpaqueValue *>(value));
boxType->vw_initializeWithCopy(pair.second, const_cast<OpaqueValue *>(value));
boxType->vw_initializeWithCopy(pair.buffer, const_cast<OpaqueValue *>(value));
type->vw_destructiveInjectEnumTag(const_cast<OpaqueValue *>(value),
(int) (tag - Description.getNumPayloadCases()));
swift_release(owner);
owner = pair.first;
value = pair.second;
owner = pair.object;
value = pair.buffer;
// If the payload is indirect, we need to jump through the box to get it.
if (indirect) {
owner = *reinterpret_cast<HeapObject * const *>(value);
value = swift_projectBox(const_cast<HeapObject *>(owner));
swift_retain(owner);
swift_release(pair.first);
swift_release(pair.object);
}
new (outString) String(getFieldName(Description.CaseNames, tag));
@@ -1035,12 +1035,12 @@ MagicMirror::MagicMirror(OpaqueValue *value, const Metadata *T,
BoxPair box = swift_allocBox(T);
if (take)
T->vw_initializeWithTake(box.second, value);
T->vw_initializeWithTake(box.buffer, value);
else
T->vw_initializeWithCopy(box.second, value);
std::tie(T, Self, MirrorWitness) = getImplementationForType(T, box.second);
T->vw_initializeWithCopy(box.buffer, value);
std::tie(T, Self, MirrorWitness) = getImplementationForType(T, box.buffer);
Data = {box.first, box.second, T};
Data = {box.object, box.buffer, T};
}
/// MagicMirror ownership-sharing subvalue constructor.

View File

@@ -1423,10 +1423,13 @@ bool swift::swift_isUniquelyReferencedOrPinned_nonNull_native(
return object->refCounts.isUniquelyReferencedOrPinned();
}
using ClassExtents = TwoWordPair<size_t, size_t>;
struct ClassExtents {
size_t negative;
size_t positive;
};
SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERNAL
ClassExtents::Return
ClassExtents
_getSwiftClassInstanceExtents(const Metadata *c) {
assert(c && c->isClassObject());
auto metaData = c->getClassObject();
@@ -1439,7 +1442,7 @@ _getSwiftClassInstanceExtents(const Metadata *c) {
#if SWIFT_OBJC_INTEROP
SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERNAL
ClassExtents::Return
ClassExtents
_getObjCClassInstanceExtents(const ClassMetadata* c) {
// Pure ObjC classes never have negative extents.
if (c->isPureObjC())

View File

@@ -366,10 +366,10 @@ static NSString *getValueDescription(_SwiftValue *self) {
return getSwiftValueTypeMetadata(self);
}
- (NSString *)_swiftTypeName {
TwoWordPair<const char *, uintptr_t> typeName
TypeNamePair typeName
= swift_getTypeName(getSwiftValueTypeMetadata(self), true);
return [NSString stringWithUTF8String: typeName.first];
return [NSString stringWithUTF8String: typeName.data];
}
- (const OpaqueValue *)_swiftValue {
return getValueFromSwiftValue(self).second;

View File

@@ -21,7 +21,7 @@ entry(%e : $Error):
// CHECK-LABEL: define{{( protected)?}} swiftcc %swift.error* @alloc_boxed_existential(%swift.opaque* noalias nocapture, %swift.type* %T, i8** %T.Error)
sil @alloc_boxed_existential : $@convention(thin) <T: Error> (@in T) -> @owned Error {
entry(%x : $*T):
// CHECK: [[BOX_PAIR:%.*]] = call { %swift.error*, %swift.opaque* } @swift_allocError(%swift.type* %T, i8** %T.Error, %swift.opaque* null, i1 false)
// CHECK: [[BOX_PAIR:%.*]] = call swiftcc { %swift.error*, %swift.opaque* } @swift_allocError(%swift.type* %T, i8** %T.Error, %swift.opaque* null, i1 false)
// CHECK: [[BOX:%.*]] = extractvalue { %swift.error*, %swift.opaque* } [[BOX_PAIR]], 0
// CHECK: [[ADDR:%.*]] = extractvalue { %swift.error*, %swift.opaque* } [[BOX_PAIR]], 1
%b = alloc_existential_box $Error, $T
@@ -40,7 +40,7 @@ struct SomeError: Error {
// CHECK-LABEL: define{{( protected)?}} swiftcc %swift.error* @alloc_boxed_existential_concrete
sil @alloc_boxed_existential_concrete : $@convention(thin) (@owned SomeError) -> @owned Error {
entry(%x : $SomeError):
// CHECK: [[BOX_PAIR:%.*]] = call { %swift.error*, %swift.opaque* } @swift_allocError(%swift.type* {{.*}} @_T017boxed_existential9SomeErrorVMf, {{.*}}, i8** {{%.*|@_T017boxed_existential9SomeErrorVs0D0AAWP}}, %swift.opaque* null, i1 false)
// CHECK: [[BOX_PAIR:%.*]] = call swiftcc { %swift.error*, %swift.opaque* } @swift_allocError(%swift.type* {{.*}} @_T017boxed_existential9SomeErrorVMf, {{.*}}, i8** {{%.*|@_T017boxed_existential9SomeErrorVs0D0AAWP}}, %swift.opaque* null, i1 false)
// CHECK: [[BOX:%.*]] = extractvalue { %swift.error*, %swift.opaque* } [[BOX_PAIR]], 0
// CHECK: [[OPAQUE_ADDR:%.*]] = extractvalue { %swift.error*, %swift.opaque* } [[BOX_PAIR]], 1
// CHECK: [[ADDR:%.*]] = bitcast %swift.opaque* [[OPAQUE_ADDR]] to %T17boxed_existential9SomeErrorV*

View File

@@ -49,7 +49,7 @@ func b<T : Ordinable>(seq seq: T) -> (Int) -> Int {
func captures_tuple<T, U>(x x: (T, U)) -> () -> (T, U) {
// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_getTupleTypeMetadata2(%swift.type* %T, %swift.type* %U, i8* null, i8** null)
// CHECK-NOT: @swift_getTupleTypeMetadata2
// CHECK: [[BOX:%.*]] = call { %swift.refcounted*, %swift.opaque* } @swift_allocBox(%swift.type* [[METADATA]])
// CHECK: [[BOX:%.*]] = call swiftcc { %swift.refcounted*, %swift.opaque* } @swift_allocBox(%swift.type* [[METADATA]])
// CHECK: [[ADDR:%.*]] = extractvalue { %swift.refcounted*, %swift.opaque* } [[BOX]], 1
// CHECK: bitcast %swift.opaque* [[ADDR]] to <{}>*
return {x}

View File

@@ -54,7 +54,7 @@ entry(%0 : $*T):
// CHECK: ret %swift.opaque* [[EXISTENTIAL_BUFFER_OPAQUE]]
//
// CHECK:allocateBox:
// CHECK: [[CALL:%.*]] = call { %swift.refcounted*, %swift.opaque* } @swift_allocBox(%swift.type* [[METATYPE]])
// CHECK: [[CALL:%.*]] = call swiftcc { %swift.refcounted*, %swift.opaque* } @swift_allocBox(%swift.type* [[METATYPE]])
// CHECK: [[BOX:%.*]] = extractvalue { %swift.refcounted*, %swift.opaque* } [[CALL]], 0
// CHECK: [[ADDR:%.*]] = extractvalue { %swift.refcounted*, %swift.opaque* } [[CALL]], 1
// CHECK: [[ADDR_IN_BUFFER:%.*]] = bitcast [{{(24|12)}} x i8]* [[EXISTENTIAL_BUFFER]] to %swift.refcounted**
@@ -221,7 +221,7 @@ bb0(%0 : $*Existential):
// CHECK: boxed:
// CHECK: [[ALIGNMASK:%.*]] = and {{(i64|i32)}} [[FLAGS]], 65535
// CHECK: [[OPAQUE_ADDR:%.*]] = bitcast [{{(24|12)}} x i8]* %0 to %swift.opaque*
// CHECK: [[REFANDADDR:%.*]] = call { %swift.refcounted*, %swift.opaque* } @swift_makeBoxUnique(%swift.opaque* [[OPAQUE_ADDR]], %swift.type* %1, {{(i64|i32)}} [[ALIGNMASK]])
// CHECK: [[REFANDADDR:%.*]] = call swiftcc { %swift.refcounted*, %swift.opaque* } @swift_makeBoxUnique(%swift.opaque* [[OPAQUE_ADDR]], %swift.type* %1, {{(i64|i32)}} [[ALIGNMASK]])
// CHECK: [[REF:%.*]] = extractvalue { %swift.refcounted*, %swift.opaque* } [[REFANDADDR]], 0
// CHECK: [[ADDR:%.*]] = extractvalue { %swift.refcounted*, %swift.opaque* } [[REFANDADDR]], 1
// CHECK: ret %swift.opaque* [[ADDR]]

View File

@@ -121,7 +121,7 @@ sil @take_t : $@convention(thin) <T> (@in T) -> ()
sil @dyn_box_a : $@convention(thin) <T> () -> () {
entry:
// CHECK: [[METADATA:%.*]] = call %swift.type* @_T011typed_boxes3DynVMa(%swift.type* %T)
// CHECK: [[ALLOC:%.*]] = call { %swift.refcounted*, %swift.opaque* } @swift_allocBox(%swift.type* [[METADATA]])
// CHECK: [[ALLOC:%.*]] = call swiftcc { %swift.refcounted*, %swift.opaque* } @swift_allocBox(%swift.type* [[METADATA]])
// CHECK: [[BOX:%.*]] = extractvalue { %swift.refcounted*, %swift.opaque* } [[ALLOC]], 0
// CHECK: [[PTR:%.*]] = extractvalue { %swift.refcounted*, %swift.opaque* } [[ALLOC]], 1
%a = alloc_box $<τ_0_0> { var τ_0_0 } <Dyn<T>>
@@ -138,7 +138,7 @@ entry:
// CHECK-LABEL: define{{( protected)?}} swiftcc void @dyn_box_b
sil @dyn_box_b : $@convention(thin) <T> () -> () {
entry:
// CHECK: [[ALLOC:%.*]] = call { %swift.refcounted*, %swift.opaque* } @swift_allocBox(%swift.type* %T)
// CHECK: [[ALLOC:%.*]] = call swiftcc { %swift.refcounted*, %swift.opaque* } @swift_allocBox(%swift.type* %T)
// CHECK: [[BOX:%.*]] = extractvalue { %swift.refcounted*, %swift.opaque* } [[ALLOC]], 0
// CHECK: [[PTR:%.*]] = extractvalue { %swift.refcounted*, %swift.opaque* } [[ALLOC]], 1
%a = alloc_box $<τ_0_0> { var τ_0_0 } <T>

View File

@@ -1222,23 +1222,23 @@ TEST(TestOpaqueExistentialBox, test_assignWithCopy_indirect_indirect) {
Metadata *metadata2 = &testMetadata2.base;
auto refAndObjectAddr = BoxPair(swift_allocBox(metadata));
swift_retain(refAndObjectAddr.first);
swift_retain(refAndObjectAddr.object);
auto refAndObjectAddr2 = BoxPair(swift_allocBox(metadata2));
struct {
ValueBuffer buffer;
Metadata *type;
uintptr_t canary;
} existBox{{{refAndObjectAddr.first, nullptr, nullptr}}, metadata, 0x5A5A5A5AU},
existBox2{{{refAndObjectAddr2.first, nullptr, nullptr}}, metadata2, 0xB5A5A5A5U};
} existBox{{{refAndObjectAddr.object, nullptr, nullptr}}, metadata, 0x5A5A5A5AU},
existBox2{{{refAndObjectAddr2.object, nullptr, nullptr}}, metadata2, 0xB5A5A5A5U};
anyVWT->assignWithCopy(reinterpret_cast<OpaqueValue *>(&existBox),
reinterpret_cast<OpaqueValue *>(&existBox2), any);
EXPECT_EQ(existBox.type, metadata2);
EXPECT_EQ(existBox.canary, 0x5A5A5A5AU);
EXPECT_EQ(existBox.buffer.PrivateData[0], refAndObjectAddr2.first);
EXPECT_EQ(swift_retainCount(refAndObjectAddr.first), 1u);
EXPECT_EQ(swift_retainCount(refAndObjectAddr2.first), 2u);
EXPECT_EQ(existBox.buffer.PrivateData[0], refAndObjectAddr2.object);
EXPECT_EQ(swift_retainCount(refAndObjectAddr.object), 1u);
EXPECT_EQ(swift_retainCount(refAndObjectAddr2.object), 2u);
}
TEST(TestOpaqueExistentialBox, test_assignWithTake_indirect_indirect) {
@@ -1258,23 +1258,23 @@ TEST(TestOpaqueExistentialBox, test_assignWithTake_indirect_indirect) {
Metadata *metadata2 = &testMetadata2.base;
auto refAndObjectAddr = BoxPair(swift_allocBox(metadata));
swift_retain(refAndObjectAddr.first);
swift_retain(refAndObjectAddr.object);
auto refAndObjectAddr2 = BoxPair(swift_allocBox(metadata2));
struct {
ValueBuffer buffer;
Metadata *type;
uintptr_t canary;
} existBox{{{refAndObjectAddr.first, nullptr, nullptr}}, metadata, 0x5A5A5A5AU},
existBox2{{{refAndObjectAddr2.first, nullptr, nullptr}}, metadata2, 0xB5A5A5A5U};
} existBox{{{refAndObjectAddr.object, nullptr, nullptr}}, metadata, 0x5A5A5A5AU},
existBox2{{{refAndObjectAddr2.object, nullptr, nullptr}}, metadata2, 0xB5A5A5A5U};
anyVWT->assignWithTake(reinterpret_cast<OpaqueValue *>(&existBox),
reinterpret_cast<OpaqueValue *>(&existBox2), any);
EXPECT_EQ(existBox.type, metadata2);
EXPECT_EQ(existBox.canary, 0x5A5A5A5AU);
EXPECT_EQ(existBox.buffer.PrivateData[0], refAndObjectAddr2.first);
EXPECT_EQ(swift_retainCount(refAndObjectAddr.first), 1u);
EXPECT_EQ(swift_retainCount(refAndObjectAddr2.first), 1u);
EXPECT_EQ(existBox.buffer.PrivateData[0], refAndObjectAddr2.object);
EXPECT_EQ(swift_retainCount(refAndObjectAddr.object), 1u);
EXPECT_EQ(swift_retainCount(refAndObjectAddr2.object), 1u);
}
TEST(TestOpaqueExistentialBox, test_assignWithCopy_pod_indirect) {
@@ -1299,15 +1299,15 @@ TEST(TestOpaqueExistentialBox, test_assignWithCopy_pod_indirect) {
Metadata *type;
uintptr_t canary;
} existBox{{{nullptr, nullptr, nullptr}}, metadata, 0x5A5A5A5AU},
existBox2{{{refAndObjectAddr2.first, nullptr, nullptr}}, metadata2, 0xB5A5A5A5U};
existBox2{{{refAndObjectAddr2.object, nullptr, nullptr}}, metadata2, 0xB5A5A5A5U};
anyVWT->assignWithCopy(reinterpret_cast<OpaqueValue *>(&existBox),
reinterpret_cast<OpaqueValue *>(&existBox2), any);
EXPECT_EQ(existBox.type, metadata2);
EXPECT_EQ(existBox.canary, 0x5A5A5A5AU);
EXPECT_EQ(existBox.buffer.PrivateData[0], refAndObjectAddr2.first);
EXPECT_EQ(swift_retainCount(refAndObjectAddr2.first), 2u);
EXPECT_EQ(existBox.buffer.PrivateData[0], refAndObjectAddr2.object);
EXPECT_EQ(swift_retainCount(refAndObjectAddr2.object), 2u);
}
TEST(TestOpaqueExistentialBox, test_assignWithTake_pod_indirect) {
@@ -1332,15 +1332,15 @@ TEST(TestOpaqueExistentialBox, test_assignWithTake_pod_indirect) {
Metadata *type;
uintptr_t canary;
} existBox{{{nullptr, nullptr, nullptr}}, metadata, 0x5A5A5A5AU},
existBox2{{{refAndObjectAddr2.first, nullptr, nullptr}}, metadata2, 0xB5A5A5A5U};
existBox2{{{refAndObjectAddr2.object, nullptr, nullptr}}, metadata2, 0xB5A5A5A5U};
anyVWT->assignWithTake(reinterpret_cast<OpaqueValue *>(&existBox),
reinterpret_cast<OpaqueValue *>(&existBox2), any);
EXPECT_EQ(existBox.type, metadata2);
EXPECT_EQ(existBox.canary, 0x5A5A5A5AU);
EXPECT_EQ(existBox.buffer.PrivateData[0], refAndObjectAddr2.first);
EXPECT_EQ(swift_retainCount(refAndObjectAddr2.first), 1u);
EXPECT_EQ(existBox.buffer.PrivateData[0], refAndObjectAddr2.object);
EXPECT_EQ(swift_retainCount(refAndObjectAddr2.object), 1u);
}
TEST(TestOpaqueExistentialBox, test_assignWithCopy_indirect_pod) {
@@ -1361,13 +1361,13 @@ TEST(TestOpaqueExistentialBox, test_assignWithCopy_indirect_pod) {
auto refAndObjectAddr2 = BoxPair(swift_allocBox(metadata2));
void *someAddr = &anyVWT;
swift_retain(refAndObjectAddr2.first);
swift_retain(refAndObjectAddr2.object);
struct {
ValueBuffer buffer;
Metadata *type;
uintptr_t canary;
} existBox2{{{someAddr, nullptr, someAddr}}, metadata, 0x5A5A5A5AU},
existBox{{{refAndObjectAddr2.first, nullptr, nullptr}}, metadata2, 0xB5A5A5A5U};
existBox{{{refAndObjectAddr2.object, nullptr, nullptr}}, metadata2, 0xB5A5A5A5U};
anyVWT->assignWithCopy(reinterpret_cast<OpaqueValue *>(&existBox),
reinterpret_cast<OpaqueValue *>(&existBox2), any);
@@ -1377,7 +1377,7 @@ TEST(TestOpaqueExistentialBox, test_assignWithCopy_indirect_pod) {
EXPECT_EQ(existBox.buffer.PrivateData[0], someAddr);
EXPECT_EQ(existBox.buffer.PrivateData[1], nullptr);
EXPECT_EQ(existBox.buffer.PrivateData[2], someAddr);
EXPECT_EQ(swift_retainCount(refAndObjectAddr2.first), 1u);
EXPECT_EQ(swift_retainCount(refAndObjectAddr2.object), 1u);
}
TEST(TestOpaqueExistentialBox, test_assignWithTake_indirect_pod) {
@@ -1398,13 +1398,13 @@ TEST(TestOpaqueExistentialBox, test_assignWithTake_indirect_pod) {
auto refAndObjectAddr2 = BoxPair(swift_allocBox(metadata2));
void *someAddr = &anyVWT;
swift_retain(refAndObjectAddr2.first);
swift_retain(refAndObjectAddr2.object);
struct {
ValueBuffer buffer;
Metadata *type;
uintptr_t canary;
} existBox2{{{someAddr, nullptr, someAddr}}, metadata, 0x5A5A5A5AU},
existBox{{{refAndObjectAddr2.first, nullptr, nullptr}}, metadata2, 0xB5A5A5A5U};
existBox{{{refAndObjectAddr2.object, nullptr, nullptr}}, metadata2, 0xB5A5A5A5U};
anyVWT->assignWithTake(reinterpret_cast<OpaqueValue *>(&existBox),
reinterpret_cast<OpaqueValue *>(&existBox2), any);
@@ -1414,7 +1414,7 @@ TEST(TestOpaqueExistentialBox, test_assignWithTake_indirect_pod) {
EXPECT_EQ(existBox.buffer.PrivateData[0], someAddr);
EXPECT_EQ(existBox.buffer.PrivateData[1], nullptr);
EXPECT_EQ(existBox.buffer.PrivateData[2], someAddr);
EXPECT_EQ(swift_retainCount(refAndObjectAddr2.first), 1u);
EXPECT_EQ(swift_retainCount(refAndObjectAddr2.object), 1u);
}
TEST(TestOpaqueExistentialBox, test_initWithCopy_pod) {
@@ -1507,15 +1507,15 @@ TEST(TestOpaqueExistentialBox, test_initWithCopy_indirect) {
Metadata *type;
uintptr_t canary;
} existBox{{{nullptr, nullptr, nullptr}}, metadata, 0x5A5A5A5AU},
existBox2{{{refAndObjectAddr2.first, nullptr, nullptr}}, metadata2, 0xB5A5A5A5U};
existBox2{{{refAndObjectAddr2.object, nullptr, nullptr}}, metadata2, 0xB5A5A5A5U};
anyVWT->initializeWithCopy(reinterpret_cast<OpaqueValue *>(&existBox),
reinterpret_cast<OpaqueValue *>(&existBox2), any);
EXPECT_EQ(existBox.type, metadata2);
EXPECT_EQ(existBox.canary, 0x5A5A5A5AU);
EXPECT_EQ(existBox.buffer.PrivateData[0], refAndObjectAddr2.first);
EXPECT_EQ(swift_retainCount(refAndObjectAddr2.first), 2u);
EXPECT_EQ(existBox.buffer.PrivateData[0], refAndObjectAddr2.object);
EXPECT_EQ(swift_retainCount(refAndObjectAddr2.object), 2u);
}
TEST(TestOpaqueExistentialBox, test_initWithTake_indirect) {
@@ -1540,13 +1540,13 @@ TEST(TestOpaqueExistentialBox, test_initWithTake_indirect) {
Metadata *type;
uintptr_t canary;
} existBox{{{nullptr, nullptr, nullptr}}, metadata, 0x5A5A5A5AU},
existBox2{{{refAndObjectAddr2.first, nullptr, nullptr}}, metadata2, 0xB5A5A5A5U};
existBox2{{{refAndObjectAddr2.object, nullptr, nullptr}}, metadata2, 0xB5A5A5A5U};
anyVWT->initializeWithTake(reinterpret_cast<OpaqueValue *>(&existBox),
reinterpret_cast<OpaqueValue *>(&existBox2), any);
EXPECT_EQ(existBox.type, metadata2);
EXPECT_EQ(existBox.canary, 0x5A5A5A5AU);
EXPECT_EQ(existBox.buffer.PrivateData[0], refAndObjectAddr2.first);
EXPECT_EQ(swift_retainCount(refAndObjectAddr2.first), 1u);
EXPECT_EQ(existBox.buffer.PrivateData[0], refAndObjectAddr2.object);
EXPECT_EQ(swift_retainCount(refAndObjectAddr2.object), 1u);
}