Skip to content

Commit c5bf2ec

Browse files
troughtonGreg Parker
authored andcommitted
[runtime] Remove TwoWordPair and use the Swift calling convention instead. (swiftlang#13299)
1 parent f767040 commit c5bf2ec

20 files changed

+104
-147
lines changed

include/swift/Runtime/Config.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,8 @@
121121
// convention.
122122
#define SWIFT_LLVM_CC(CC) SWIFT_LLVM_CC_##CC
123123

124-
// Currently, RuntimeFunction.def uses the following calling conventions:
125-
// DefaultCC, RegisterPreservingCC.
124+
// Currently, RuntimeFunctions.def uses the following calling conventions:
125+
// DefaultCC, RegisterPreservingCC, SwiftCC.
126126
// If new runtime calling conventions are added later, they need to be mapped
127127
// here to something appropriate.
128128

@@ -131,6 +131,8 @@
131131
#define SWIFT_CC_DefaultCC_IMPL SWIFT_CC_c
132132
#define SWIFT_LLVM_CC_DefaultCC llvm::CallingConv::C
133133

134+
#define SWIFT_CC_SwiftCC SWIFT_CC_swift
135+
134136
#define SWIFT_LLVM_CC_RegisterPreservingCC llvm::CallingConv::PreserveMost
135137

136138
#if SWIFT_USE_SWIFTCALL

include/swift/Runtime/HeapObject.h

Lines changed: 15 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -97,66 +97,10 @@ HeapObject *swift_initStaticObject(HeapMetadata const *metadata,
9797
SWIFT_RUNTIME_EXPORT
9898
void swift_verifyEndOfLifetime(HeapObject *object);
9999

100-
/// A structure that's two pointers in size.
101-
///
102-
/// C functions can use the TwoWordPair::Return type to return a value in
103-
/// two registers, compatible with Swift's calling convention for tuples
104-
/// and structs of two word-sized elements.
105-
template<typename A, typename B>
106-
struct TwoWordPair {
107-
A first;
108-
B second;
109-
110-
TwoWordPair() = default;
111-
TwoWordPair(A first, B second);
112-
113-
// FIXME: rdar://16257592 arm codegen doesn't call swift_allocBox correctly.
114-
// Structs are returned indirectly on these platforms, but we want to return
115-
// in registers, so cram the result into an unsigned long long.
116-
// Use an enum class with implicit conversions so we don't dirty C callers
117-
// too much.
118-
#if __arm__ || __i386__ || defined(__CYGWIN__) || defined(_MSC_VER)
119-
#if defined(__CYGWIN__)
120-
enum class Return : unsigned __int128 {};
121-
#else
122-
enum class Return : unsigned long long {};
123-
#endif
124-
125-
operator Return() const {
126-
union {
127-
TwoWordPair value;
128-
Return mangled;
129-
} reinterpret = {*this};
130-
131-
return reinterpret.mangled;
132-
}
133-
134-
/*implicit*/ TwoWordPair(Return r) {
135-
union {
136-
Return mangled;
137-
TwoWordPair value;
138-
} reinterpret = {r};
139-
140-
*this = reinterpret.value;
141-
}
142-
#else
143-
using Return = TwoWordPair;
144-
#endif
100+
struct BoxPair {
101+
HeapObject *object;
102+
OpaqueValue *buffer;
145103
};
146-
147-
template<typename A, typename B>
148-
inline TwoWordPair<A,B>::TwoWordPair(A first, B second)
149-
: first(first), second(second)
150-
{
151-
static_assert(sizeof(A) == sizeof(void*),
152-
"first type must be word-sized");
153-
static_assert(sizeof(B) == sizeof(void*),
154-
"second type must be word-sized");
155-
static_assert(alignof(TwoWordPair) == alignof(void*),
156-
"pair must be word-aligned");
157-
}
158-
159-
using BoxPair = TwoWordPair<HeapObject *, OpaqueValue *>;
160104

161105
/// Allocates a heap object that can contain a value of the given type.
162106
/// Returns a Box structure containing a HeapObject* pointer to the
@@ -165,19 +109,19 @@ using BoxPair = TwoWordPair<HeapObject *, OpaqueValue *>;
165109
/// appropriate to store a value of the given type.
166110
/// The heap object has an initial retain count of 1, and its metadata is set
167111
/// such that destroying the heap object destroys the contained value.
168-
SWIFT_RUNTIME_EXPORT
169-
BoxPair::Return swift_allocBox(Metadata const *type);
112+
SWIFT_CC(swift) SWIFT_RUNTIME_EXPORT
113+
BoxPair swift_allocBox(Metadata const *type);
170114

171-
SWIFT_RUNTIME_EXPORT
172-
BoxPair::Return (*_swift_allocBox)(Metadata const *type);
115+
SWIFT_CC(swift) SWIFT_RUNTIME_EXPORT
116+
BoxPair (*_swift_allocBox)(Metadata const *type);
173117

174118
/// Performs a uniqueness check on the pointer to a box structure. If the check
175119
/// fails allocates a new box and stores the pointer in the buffer.
176120
///
177121
/// if (!isUnique(buffer[0]))
178122
/// buffer[0] = swift_allocBox(type)
179-
SWIFT_RUNTIME_EXPORT
180-
BoxPair::Return swift_makeBoxUnique(OpaqueValue *buffer, Metadata const *type,
123+
SWIFT_CC(swift) SWIFT_RUNTIME_EXPORT
124+
BoxPair swift_makeBoxUnique(OpaqueValue *buffer, Metadata const *type,
181125
size_t alignMask);
182126

183127
/// Returns the address of a heap object representing all empty box types.
@@ -1242,11 +1186,16 @@ static inline bool swift_unknownUnownedIsEqual(UnownedReference *ref,
12421186

12431187
#endif /* SWIFT_OBJC_INTEROP */
12441188

1189+
struct TypeNamePair {
1190+
const char *data;
1191+
uintptr_t length;
1192+
};
1193+
12451194
/// Return the name of a Swift type represented by a metadata object.
12461195
/// func _getTypeName(_ type: Any.Type, qualified: Bool)
12471196
/// -> (UnsafePointer<UInt8>, Int)
12481197
SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_API
1249-
TwoWordPair<const char *, uintptr_t>::Return
1198+
TypeNamePair
12501199
swift_getTypeName(const Metadata *type, bool qualified);
12511200

12521201
} // end namespace swift

include/swift/Runtime/InstrumentsSupport.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ HeapObject *(*_swift_allocObject)(HeapMetadata const *metadata,
2626
size_t requiredAlignmentMask);
2727

2828
SWIFT_RUNTIME_EXPORT
29-
BoxPair::Return (*_swift_allocBox)(Metadata const *type);
29+
BoxPair (*swift_allocBox)(Metadata const *type);
3030

3131
SWIFT_RUNTIME_EXPORT
3232
HeapObject *(*_swift_retain)(HeapObject *object);

include/swift/Runtime/RuntimeFunctions.def

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,15 @@
5050
#endif
5151

5252
FUNCTION_WITH_GLOBAL_SYMBOL_AND_IMPL(AllocBox, swift_allocBox,
53-
_swift_allocBox, _swift_allocBox_, DefaultCC,
53+
_swift_allocBox, _swift_allocBox_, SwiftCC,
5454
RETURNS(RefCountedPtrTy, OpaquePtrTy),
5555
ARGS(TypeMetadataPtrTy),
5656
ATTRS(NoUnwind))
5757

5858
// BoxPair swift_makeBoxUnique(OpaqueValue *buffer, Metadata *type, size_t alignMask);
5959
FUNCTION(MakeBoxUnique,
6060
swift_makeBoxUnique,
61-
DefaultCC,
61+
SwiftCC,
6262
RETURNS(RefCountedPtrTy, OpaquePtrTy),
6363
ARGS(OpaquePtrTy, TypeMetadataPtrTy, SizeTy),
6464
ATTRS(NoUnwind))
@@ -1332,7 +1332,7 @@ FUNCTION(DeletedMethodError, swift_deletedMethodError, C_CC,
13321332
ARGS(),
13331333
ATTRS(NoUnwind))
13341334

1335-
FUNCTION(AllocError, swift_allocError, C_CC,
1335+
FUNCTION(AllocError, swift_allocError, SwiftCC,
13361336
RETURNS(ErrorPtrTy, OpaquePtrTy),
13371337
ARGS(TypeMetadataPtrTy, WitnessTablePtrTy, OpaquePtrTy, Int1Ty),
13381338
ATTRS(NoUnwind))

lib/IRGen/IRGenModule.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,10 @@ llvm::Constant *swift::getWrapperFn(llvm::Module &Module,
610610
RETURNS, ARGS, ATTRS) \
611611
FUNCTION_IMPL(ID, NAME, CC, QUOTE(RETURNS), QUOTE(ARGS), QUOTE(ATTRS))
612612

613+
#define FUNCTION_WITH_GLOBAL_SYMBOL_FOR_CONV_SwiftCC(ID, NAME, SYMBOL, CC, \
614+
RETURNS, ARGS, ATTRS) \
615+
FUNCTION_IMPL(ID, NAME, CC, QUOTE(RETURNS), QUOTE(ARGS), QUOTE(ATTRS))
616+
613617
#define FUNCTION_WITH_GLOBAL_SYMBOL_FOR_CONV_RegisterPreservingCC( \
614618
ID, NAME, SYMBOL, CC, RETURNS, ARGS, ATTRS) \
615619
FUNCTION_WITH_GLOBAL_SYMBOL_IMPL(ID, NAME, SYMBOL, CC, QUOTE(RETURNS), \

stdlib/public/SDK/Foundation/CheckClass.mm

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,9 @@ static void logIfFirstOccurrence(Class objcClass, void (^log)(void)) {
5959
template <size_t N>
6060
StringRefLite(const char (&staticStr)[N]) : data(staticStr), length(N) {}
6161

62-
StringRefLite(swift::TwoWordPair<const char *, uintptr_t>::Return rawValue)
63-
: data(swift::TwoWordPair<const char *, uintptr_t>(rawValue).first),
64-
length(swift::TwoWordPair<const char *, uintptr_t>(rawValue).second){}
62+
StringRefLite(swift::TypeNamePair rawValue)
63+
: data(rawValue.data),
64+
length(rawValue.length){}
6565

6666
NS_RETURNS_RETAINED
6767
NSString *newNSStringNoCopy() const {

stdlib/public/runtime/Casting.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,8 @@ std::string swift::nameForMetadata(const Metadata *type,
113113
return result;
114114
}
115115

116-
TwoWordPair<const char *, uintptr_t>::Return
116+
TypeNamePair
117117
swift::swift_getTypeName(const Metadata *type, bool qualified) {
118-
using Pair = TwoWordPair<const char *, uintptr_t>;
119118
using Key = llvm::PointerIntPair<const Metadata *, 1, bool>;
120119

121120
static StaticReadWriteLock TypeNameCacheLock;
@@ -132,7 +131,7 @@ swift::swift_getTypeName(const Metadata *type, bool qualified) {
132131
auto found = cache.find(key);
133132
if (found != cache.end()) {
134133
auto result = found->second;
135-
return Pair{result.first, result.second};
134+
return TypeNamePair{result.first, result.second};
136135
}
137136
}
138137

@@ -145,7 +144,7 @@ swift::swift_getTypeName(const Metadata *type, bool qualified) {
145144
auto found = cache.find(key);
146145
if (found != cache.end()) {
147146
auto result = found->second;
148-
return Pair{result.first, result.second};
147+
return TypeNamePair{result.first, result.second};
149148
}
150149

151150
// Build the metadata name.
@@ -157,7 +156,7 @@ swift::swift_getTypeName(const Metadata *type, bool qualified) {
157156
result[size] = 0;
158157

159158
cache.insert({key, {result, size}});
160-
return Pair{result, size};
159+
return TypeNamePair{result, size};
161160
}
162161
}
163162

@@ -955,7 +954,7 @@ static bool _dynamicCastToExistential(OpaqueValue *dest,
955954
(canConsumeDynamicValue && (flags & DynamicCastFlags::TakeOnSuccess));
956955
BoxPair destBox = swift_allocError(srcDynamicType, errorWitness,
957956
srcDynamicValue, isTake);
958-
*destBoxAddr = reinterpret_cast<SwiftError*>(destBox.first);
957+
*destBoxAddr = reinterpret_cast<SwiftError*>(destBox.object);
959958
maybeDeallocateSource(true);
960959
return true;
961960
}
@@ -1977,7 +1976,7 @@ static id dynamicCastValueToNSError(OpaqueValue *src,
19771976

19781977
BoxPair errorBox = swift_allocError(srcType, srcErrorWitness, src,
19791978
/*isTake*/ flags & DynamicCastFlags::TakeOnSuccess);
1980-
return _swift_stdlib_bridgeErrorToNSError((SwiftError*)errorBox.first);
1979+
return _swift_stdlib_bridgeErrorToNSError((SwiftError*)errorBox.object);
19811980
}
19821981

19831982
#endif

stdlib/public/runtime/ErrorObject.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -171,10 +171,10 @@ struct SwiftError : SwiftErrorHeader {
171171
/// copied (or taken if \c isTake is true) into the newly-allocated error box.
172172
/// If value is null, the box's contents will be left uninitialized, and
173173
/// \c isTake should be false.
174-
SWIFT_RUNTIME_STDLIB_API
175-
BoxPair::Return swift_allocError(const Metadata *type,
176-
const WitnessTable *errorConformance,
177-
OpaqueValue *value, bool isTake);
174+
SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_API
175+
BoxPair swift_allocError(const Metadata *type,
176+
const WitnessTable *errorConformance,
177+
OpaqueValue *value, bool isTake);
178178

179179
/// Deallocate an error object whose contained object has already been
180180
/// destroyed.

stdlib/public/runtime/ErrorObject.mm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ static Class getSwiftNativeNSErrorClass() {
161161
}
162162

163163
/// Allocate a catchable error object.
164-
BoxPair::Return
164+
BoxPair
165165
swift::swift_allocError(const Metadata *type,
166166
const WitnessTable *errorConformance,
167167
OpaqueValue *initialValue,

stdlib/public/runtime/ErrorObjectNative.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ static const FullMetadata<HeapMetadata> ErrorMetadata{
6464
Metadata{MetadataKind::ErrorObject},
6565
};
6666

67-
BoxPair::Return
67+
BoxPair
6868
swift::swift_allocError(const swift::Metadata *type,
6969
const swift::WitnessTable *errorConformance,
7070
OpaqueValue *initialValue,

stdlib/public/runtime/HeapObject.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -203,11 +203,11 @@ class BoxCacheEntry {
203203

204204
static SimpleGlobalCache<BoxCacheEntry> Boxes;
205205

206-
BoxPair::Return swift::swift_allocBox(const Metadata *type) {
206+
BoxPair swift::swift_allocBox(const Metadata *type) {
207207
return SWIFT_RT_ENTRY_REF(swift_allocBox)(type);
208208
}
209209

210-
BoxPair::Return swift::swift_makeBoxUnique(OpaqueValue *buffer, const Metadata *type,
210+
BoxPair swift::swift_makeBoxUnique(OpaqueValue *buffer, const Metadata *type,
211211
size_t alignMask) {
212212
auto *inlineBuffer = reinterpret_cast<ValueBuffer*>(buffer);
213213
HeapObject *box = reinterpret_cast<HeapObject *>(inlineBuffer->PrivateData[0]);
@@ -219,8 +219,8 @@ BoxPair::Return swift::swift_makeBoxUnique(OpaqueValue *buffer, const Metadata *
219219
auto *oldObjectAddr = reinterpret_cast<OpaqueValue *>(
220220
reinterpret_cast<char *>(box) + headerOffset);
221221
// Copy the data.
222-
type->vw_initializeWithCopy(refAndObjectAddr.second, oldObjectAddr);
223-
inlineBuffer->PrivateData[0] = refAndObjectAddr.first;
222+
type->vw_initializeWithCopy(refAndObjectAddr.buffer, oldObjectAddr);
223+
inlineBuffer->PrivateData[0] = refAndObjectAddr.object;
224224
// Release ownership of the old box.
225225
swift_release(box);
226226
return refAndObjectAddr;
@@ -234,7 +234,7 @@ BoxPair::Return swift::swift_makeBoxUnique(OpaqueValue *buffer, const Metadata *
234234

235235
SWIFT_RT_ENTRY_IMPL_VISIBILITY
236236
extern "C"
237-
BoxPair::Return SWIFT_RT_ENTRY_IMPL(swift_allocBox)(const Metadata *type) {
237+
BoxPair SWIFT_RT_ENTRY_IMPL(swift_allocBox)(const Metadata *type) {
238238
// Get the heap metadata for the box.
239239
auto metadata = &Boxes.getOrInsert(type).first->Data;
240240

stdlib/public/runtime/Metadata.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -636,8 +636,8 @@ static OpaqueValue *tuple_allocateBuffer(ValueBuffer *buffer,
636636
if (IsInline)
637637
return reinterpret_cast<OpaqueValue*>(buffer);
638638
BoxPair refAndValueAddr(swift_allocBox(metatype));
639-
*reinterpret_cast<HeapObject **>(buffer) = refAndValueAddr.first;
640-
return refAndValueAddr.second;
639+
*reinterpret_cast<HeapObject **>(buffer) = refAndValueAddr.object;
640+
return refAndValueAddr.buffer;
641641
}
642642

643643
/// Generic tuple value witness for 'destroy'.
@@ -2542,8 +2542,8 @@ template <> OpaqueValue *Metadata::allocateBoxForExistentialIn(ValueBuffer *buff
25422542

25432543
// Allocate the box.
25442544
BoxPair refAndValueAddr(swift_allocBox(this));
2545-
buffer->PrivateData[0] = refAndValueAddr.first;
2546-
return refAndValueAddr.second;
2545+
buffer->PrivateData[0] = refAndValueAddr.object;
2546+
return refAndValueAddr.buffer;
25472547
}
25482548

25492549
template <> OpaqueValue *Metadata::allocateBufferIn(ValueBuffer *buffer) const {

stdlib/public/runtime/Reflection.mm

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -633,21 +633,21 @@ void swift_EnumMirror_subscript(String *outString,
633633
BoxPair pair = swift_allocBox(boxType);
634634

635635
type->vw_destructiveProjectEnumData(const_cast<OpaqueValue *>(value));
636-
boxType->vw_initializeWithCopy(pair.second, const_cast<OpaqueValue *>(value));
636+
boxType->vw_initializeWithCopy(pair.buffer, const_cast<OpaqueValue *>(value));
637637
type->vw_destructiveInjectEnumTag(const_cast<OpaqueValue *>(value),
638638
(int) (tag - Description.getNumPayloadCases()));
639639

640640
swift_release(owner);
641641

642-
owner = pair.first;
643-
value = pair.second;
642+
owner = pair.object;
643+
value = pair.buffer;
644644

645645
// If the payload is indirect, we need to jump through the box to get it.
646646
if (indirect) {
647647
owner = *reinterpret_cast<HeapObject * const *>(value);
648648
value = swift_projectBox(const_cast<HeapObject *>(owner));
649649
swift_retain(owner);
650-
swift_release(pair.first);
650+
swift_release(pair.object);
651651
}
652652

653653
new (outString) String(getFieldName(Description.CaseNames, tag));
@@ -1035,12 +1035,12 @@ static Mirror ObjC_getMirrorForSuperclass(Class sup,
10351035
BoxPair box = swift_allocBox(T);
10361036

10371037
if (take)
1038-
T->vw_initializeWithTake(box.second, value);
1038+
T->vw_initializeWithTake(box.buffer, value);
10391039
else
1040-
T->vw_initializeWithCopy(box.second, value);
1041-
std::tie(T, Self, MirrorWitness) = getImplementationForType(T, box.second);
1040+
T->vw_initializeWithCopy(box.buffer, value);
1041+
std::tie(T, Self, MirrorWitness) = getImplementationForType(T, box.buffer);
10421042

1043-
Data = {box.first, box.second, T};
1043+
Data = {box.object, box.buffer, T};
10441044
}
10451045

10461046
/// MagicMirror ownership-sharing subvalue constructor.

0 commit comments

Comments
 (0)