Skip to content

Commit 44cccd0

Browse files
authored
Merge pull request #18205 from dcci/valuewittarget
[Runtime] Targetize the layout of ValueWitnessTable.
2 parents a5524d2 + 1c3c190 commit 44cccd0

File tree

5 files changed

+70
-54
lines changed

5 files changed

+70
-54
lines changed

include/swift/ABI/Metadata.h

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,10 @@ using ConstTargetMetadataPointer
136136

137137
template <typename Runtime, typename T>
138138
using TargetPointer = typename Runtime::template Pointer<T>;
139-
139+
140+
template <typename Runtime, typename T>
141+
using ConstTargetPointer = typename Runtime::template Pointer<const T>;
142+
140143
template <typename Runtime, template <typename> class Pointee,
141144
bool Nullable = true>
142145
using ConstTargetFarRelativeDirectPointer
@@ -257,21 +260,28 @@ constexpr inline bool canBeInline(bool isBitwiseTakable) {
257260
return canBeInline(isBitwiseTakable, sizeof(T), alignof(T));
258261
}
259262

260-
struct ValueWitnessTable;
263+
template <typename Runtime> struct TargetValueWitnessTable;
264+
using ValueWitnessTable = TargetValueWitnessTable<InProcess>;
261265

262-
namespace value_witness_types {
266+
template <typename Runtime> class TargetValueWitnessTypes;
267+
using ValueWitnessTypes = TargetValueWitnessTypes<InProcess>;
268+
269+
template <typename Runtime>
270+
class TargetValueWitnessTypes {
271+
public:
272+
using StoredPointer = typename Runtime::StoredPointer;
263273

264274
// Note that, for now, we aren't strict about 'const'.
265275
#define WANT_ALL_VALUE_WITNESSES
266276
#define DATA_VALUE_WITNESS(lowerId, upperId, type)
267277
#define FUNCTION_VALUE_WITNESS(lowerId, upperId, returnType, paramTypes) \
268-
typedef returnType (*lowerId) paramTypes;
269-
#define MUTABLE_VALUE_TYPE OpaqueValue *
270-
#define IMMUTABLE_VALUE_TYPE const OpaqueValue *
271-
#define MUTABLE_BUFFER_TYPE ValueBuffer *
272-
#define IMMUTABLE_BUFFER_TYPE const ValueBuffer *
273-
#define TYPE_TYPE const Metadata *
274-
#define SIZE_TYPE size_t
278+
typedef TargetPointer<Runtime, returnType paramTypes> lowerId;
279+
#define MUTABLE_VALUE_TYPE TargetPointer<Runtime, OpaqueValue>
280+
#define IMMUTABLE_VALUE_TYPE ConstTargetPointer<Runtime, OpaqueValue>
281+
#define MUTABLE_BUFFER_TYPE TargetPointer<Runtime, ValueBuffer>
282+
#define IMMUTABLE_BUFFER_TYPE ConstTargetPointer<Runtime, ValueBuffer>
283+
#define TYPE_TYPE ConstTargetPointer<Runtime, Metadata>
284+
#define SIZE_TYPE StoredSize
275285
#define INT_TYPE int
276286
#define UINT_TYPE unsigned
277287
#define VOID_TYPE void
@@ -284,33 +294,36 @@ namespace value_witness_types {
284294
typedef size_t stride;
285295
typedef ExtraInhabitantFlags extraInhabitantFlags;
286296

287-
} // end namespace value_witness_types
297+
};
288298

289299
struct TypeLayout;
290300

291301
/// A value-witness table. A value witness table is built around
292302
/// the requirements of some specific type. The information in
293303
/// a value-witness table is intended to be sufficient to lay out
294304
/// and manipulate values of an arbitrary type.
295-
struct ValueWitnessTable {
305+
template <typename Runtime> struct TargetValueWitnessTable {
296306
// For the meaning of all of these witnesses, consult the comments
297307
// on their associated typedefs, above.
298308

299309
#define WANT_ONLY_REQUIRED_VALUE_WITNESSES
300310
#define VALUE_WITNESS(LOWER_ID, UPPER_ID) \
301-
value_witness_types::LOWER_ID LOWER_ID;
311+
typename TargetValueWitnessTypes<Runtime>::LOWER_ID LOWER_ID;
302312
#include "swift/ABI/ValueWitness.def"
303313

314+
using StoredSize = typename Runtime::StoredSize;
315+
304316
/// Is the external type layout of this type incomplete?
305317
bool isIncomplete() const {
306318
return flags.isIncomplete();
307319
}
308320

309321
/// Would values of a type with the given layout requirements be
310322
/// allocated inline?
311-
static bool isValueInline(bool isBitwiseTakable, size_t size, size_t alignment) {
312-
return (isBitwiseTakable && size <= sizeof(ValueBuffer) &&
313-
alignment <= alignof(ValueBuffer));
323+
static bool isValueInline(bool isBitwiseTakable, StoredSize size,
324+
StoredSize alignment) {
325+
return (isBitwiseTakable && size <= sizeof(TargetValueBuffer<Runtime>) &&
326+
alignment <= alignof(TargetValueBuffer<Runtime>));
314327
}
315328

316329
/// Are values of this type allocated inline?
@@ -331,18 +344,18 @@ struct ValueWitnessTable {
331344
/// Return the size of this type. Unlike in C, this has not been
332345
/// padded up to the alignment; that value is maintained as
333346
/// 'stride'.
334-
size_t getSize() const {
347+
StoredSize getSize() const {
335348
return size;
336349
}
337350

338351
/// Return the stride of this type. This is the size rounded up to
339352
/// be a multiple of the alignment.
340-
size_t getStride() const {
353+
StoredSize getStride() const {
341354
return stride;
342355
}
343356

344357
/// Return the alignment required by this type, in bytes.
345-
size_t getAlignment() const {
358+
StoredSize getAlignment() const {
346359
return flags.getAlignment();
347360
}
348361

@@ -352,7 +365,7 @@ struct ValueWitnessTable {
352365
///
353366
/// For example, if the type needs to be 8-byte aligned, the value
354367
/// of this witness is 0x7.
355-
size_t getAlignmentMask() const {
368+
StoredSize getAlignmentMask() const {
356369
return flags.getAlignmentMask();
357370
}
358371

@@ -583,7 +596,7 @@ struct TargetMetadata {
583596
#define WANT_ONLY_REQUIRED_VALUE_WITNESSES
584597
#define FUNCTION_VALUE_WITNESS(WITNESS, UPPER, RET_TYPE, PARAM_TYPES) \
585598
template<typename...A> \
586-
_ResultOf<value_witness_types::WITNESS>::type \
599+
_ResultOf<ValueWitnessTypes::WITNESS>::type \
587600
vw_##WITNESS(A &&...args) const { \
588601
return getValueWitnesses()->WITNESS(std::forward<A>(args)..., this); \
589602
}

include/swift/ABI/ValueWitness.def

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@
7272
/// MUTABLE_BUFFER_TYPE - a pointer to a fixed-size value buffer
7373
/// IMMUTABLE_BUFFER_TYPE - a pointer to an immutable fixed-size buffer
7474
/// TYPE_TYPE - a pointer to type metadata
75-
/// SIZE_TYPE - size_t
75+
/// SIZE_TYPE - StoredSize
7676
/// INT_TYPE - int
7777
/// UINT_TYPE - unsigned int
7878
/// VOID_TYPE - void
@@ -193,7 +193,7 @@ FUNCTION_VALUE_WITNESS(storeEnumTagSinglePayload,
193193
END_VALUE_WITNESS_RANGE(RequiredValueWitnessFunction,
194194
StoreEnumTagSinglePayload)
195195

196-
/// size_t size;
196+
/// SIZE_TYPE size;
197197
///
198198
/// The required storage size of a single object of this type.
199199
DATA_VALUE_WITNESS(size,
@@ -206,7 +206,7 @@ BEGIN_VALUE_WITNESS_RANGE(TypeLayoutWitness,
206206
BEGIN_VALUE_WITNESS_RANGE(RequiredTypeLayoutWitness,
207207
Size)
208208

209-
/// size_t flags;
209+
/// SIZE_TYPE flags;
210210
///
211211
/// The ValueWitnessAlignmentMask bits represent the required
212212
/// alignment of the first byte of an object of this type, expressed
@@ -235,7 +235,7 @@ DATA_VALUE_WITNESS(flags,
235235
Flags,
236236
SIZE_TYPE)
237237

238-
/// size_t stride;
238+
/// SIZE_TYPE stride;
239239
///
240240
/// The required size per element of an array of this type. It is at least
241241
/// one, even for zero-sized types, like the empty tuple.
@@ -256,7 +256,7 @@ END_VALUE_WITNESS_RANGE(RequiredValueWitness,
256256
// The following value witnesses are conditionally present based on
257257
// the Enum_HasExtraInhabitants bit of the flags.
258258

259-
/// size_t extraInhabitantFlags;
259+
/// SIZE_TYPE extraInhabitantFlags;
260260
///
261261
/// These bits are always present if the extra inhabitants witnesses are:
262262
///

include/swift/Runtime/Enum.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,11 @@
2222
namespace swift {
2323

2424
struct OpaqueValue;
25-
struct ValueWitnessTable;
26-
2725
struct InProcess;
2826

27+
template <typename Runtime> struct TargetValueWitnessTable;
28+
using ValueWitnessTable = TargetValueWitnessTable<InProcess>;
29+
2930
template <typename Runtime> struct TargetMetadata;
3031
using Metadata = TargetMetadata<InProcess>;
3132

include/swift/Runtime/Metadata.h

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ OpaqueValue *swift_copyPOD(OpaqueValue *dest,
6565
struct ExtraInhabitantsValueWitnessTable : ValueWitnessTable {
6666
#define WANT_ONLY_EXTRA_INHABITANT_VALUE_WITNESSES
6767
#define VALUE_WITNESS(LOWER_ID, UPPER_ID) \
68-
value_witness_types::LOWER_ID LOWER_ID;
68+
ValueWitnessTypes::LOWER_ID LOWER_ID;
6969
#include "swift/ABI/ValueWitness.def"
7070

7171
#define SET_WITNESS(NAME) base.NAME,
@@ -76,9 +76,9 @@ struct ExtraInhabitantsValueWitnessTable : ValueWitnessTable {
7676
getExtraInhabitantIndex(nullptr) {}
7777
constexpr ExtraInhabitantsValueWitnessTable(
7878
const ValueWitnessTable &base,
79-
value_witness_types::extraInhabitantFlags eif,
80-
value_witness_types::storeExtraInhabitant sei,
81-
value_witness_types::getExtraInhabitantIndex geii)
79+
ValueWitnessTypes::extraInhabitantFlags eif,
80+
ValueWitnessTypes::storeExtraInhabitant sei,
81+
ValueWitnessTypes::getExtraInhabitantIndex geii)
8282
: ValueWitnessTable(base),
8383
extraInhabitantFlags(eif),
8484
storeExtraInhabitant(sei),
@@ -95,7 +95,7 @@ struct ExtraInhabitantsValueWitnessTable : ValueWitnessTable {
9595
struct EnumValueWitnessTable : ExtraInhabitantsValueWitnessTable {
9696
#define WANT_ONLY_ENUM_VALUE_WITNESSES
9797
#define VALUE_WITNESS(LOWER_ID, UPPER_ID) \
98-
value_witness_types::LOWER_ID LOWER_ID;
98+
ValueWitnessTypes::LOWER_ID LOWER_ID;
9999
#include "swift/ABI/ValueWitness.def"
100100

101101
constexpr EnumValueWitnessTable()
@@ -105,9 +105,9 @@ struct EnumValueWitnessTable : ExtraInhabitantsValueWitnessTable {
105105
destructiveInjectEnumTag(nullptr) {}
106106
constexpr EnumValueWitnessTable(
107107
const ExtraInhabitantsValueWitnessTable &base,
108-
value_witness_types::getEnumTag getEnumTag,
109-
value_witness_types::destructiveProjectEnumData destructiveProjectEnumData,
110-
value_witness_types::destructiveInjectEnumTag destructiveInjectEnumTag)
108+
ValueWitnessTypes::getEnumTag getEnumTag,
109+
ValueWitnessTypes::destructiveProjectEnumData destructiveProjectEnumData,
110+
ValueWitnessTypes::destructiveInjectEnumTag destructiveInjectEnumTag)
111111
: ExtraInhabitantsValueWitnessTable(base),
112112
getEnumTag(getEnumTag),
113113
destructiveProjectEnumData(destructiveProjectEnumData),
@@ -123,26 +123,26 @@ struct EnumValueWitnessTable : ExtraInhabitantsValueWitnessTable {
123123
/// the value witness functions and includes only the size, alignment,
124124
/// extra inhabitants, and miscellaneous flags about the type.
125125
struct TypeLayout {
126-
value_witness_types::size size;
127-
value_witness_types::flags flags;
128-
value_witness_types::stride stride;
126+
ValueWitnessTypes::size size;
127+
ValueWitnessTypes::flags flags;
128+
ValueWitnessTypes::stride stride;
129129

130130
private:
131131
// Only available if the "hasExtraInhabitants" flag is set.
132-
value_witness_types::extraInhabitantFlags extraInhabitantFlags;
132+
ValueWitnessTypes::extraInhabitantFlags extraInhabitantFlags;
133133

134134
void _static_assert_layout();
135135
public:
136136
TypeLayout() = default;
137-
constexpr TypeLayout(value_witness_types::size size,
138-
value_witness_types::flags flags,
139-
value_witness_types::stride stride,
140-
value_witness_types::extraInhabitantFlags eiFlags =
141-
value_witness_types::extraInhabitantFlags())
137+
constexpr TypeLayout(ValueWitnessTypes::size size,
138+
ValueWitnessTypes::flags flags,
139+
ValueWitnessTypes::stride stride,
140+
ValueWitnessTypes::extraInhabitantFlags eiFlags =
141+
ValueWitnessTypes::extraInhabitantFlags())
142142
: size(size), flags(flags), stride(stride),
143143
extraInhabitantFlags(eiFlags) {}
144144

145-
value_witness_types::extraInhabitantFlags getExtraInhabitantFlags() const {
145+
ValueWitnessTypes::extraInhabitantFlags getExtraInhabitantFlags() const {
146146
assert(flags.hasExtraInhabitants());
147147
return extraInhabitantFlags;
148148
}
@@ -169,6 +169,7 @@ inline void TypeLayout::_static_assert_layout() {
169169
#undef CHECK_TYPE_LAYOUT_OFFSET
170170
}
171171

172+
template <>
172173
inline void ValueWitnessTable::publishLayout(const TypeLayout &layout) {
173174
size = layout.size;
174175
stride = layout.stride;
@@ -184,23 +185,24 @@ inline void ValueWitnessTable::publishLayout(const TypeLayout &layout) {
184185
flags = layout.flags;
185186
}
186187

187-
inline bool ValueWitnessTable::checkIsComplete() const {
188+
template <> inline bool ValueWitnessTable::checkIsComplete() const {
188189
return !flags.isIncomplete();
189190
}
190191

192+
template <>
191193
inline const ExtraInhabitantsValueWitnessTable *
192194
ValueWitnessTable::_asXIVWT() const {
193195
assert(ExtraInhabitantsValueWitnessTable::classof(this));
194196
return static_cast<const ExtraInhabitantsValueWitnessTable *>(this);
195197
}
196-
197-
inline const EnumValueWitnessTable *
198-
ValueWitnessTable::_asEVWT() const {
198+
199+
template <>
200+
inline const EnumValueWitnessTable *ValueWitnessTable::_asEVWT() const {
199201
assert(EnumValueWitnessTable::classof(this));
200202
return static_cast<const EnumValueWitnessTable *>(this);
201203
}
202204

203-
inline unsigned ValueWitnessTable::getNumExtraInhabitants() const {
205+
template <> inline unsigned ValueWitnessTable::getNumExtraInhabitants() const {
204206
// If the table does not have extra inhabitant witnesses, then there are zero.
205207
if (!flags.hasExtraInhabitants())
206208
return 0;

stdlib/public/runtime/Metadata.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1123,7 +1123,7 @@ static void tuple_destroy(OpaqueValue *tuple, const Metadata *_metadata) {
11231123

11241124
// The operation doesn't have to be initializeWithCopy, but they all
11251125
// have basically the same type.
1126-
typedef value_witness_types::initializeWithCopy forEachOperation;
1126+
typedef ValueWitnessTypes::initializeWithCopy forEachOperation;
11271127

11281128
/// Perform an operation for each field of two tuples.
11291129
static OpaqueValue *tuple_forEachField(OpaqueValue *destTuple,
@@ -1726,7 +1726,7 @@ static OpaqueValue *pod_indirect_initializeBufferWithCopyOfBuffer(
17261726
static void pod_noop(void *object, const Metadata *self) {
17271727
}
17281728
#define pod_direct_destroy \
1729-
pointer_function_cast<value_witness_types::destroy>(pod_noop)
1729+
pointer_function_cast<ValueWitnessTypes::destroy>(pod_noop)
17301730
#define pod_indirect_destroy pod_direct_destroy
17311731

17321732
static OpaqueValue *pod_direct_initializeWithCopy(OpaqueValue *dest,
@@ -1737,7 +1737,7 @@ static OpaqueValue *pod_direct_initializeWithCopy(OpaqueValue *dest,
17371737
}
17381738
#define pod_indirect_initializeWithCopy pod_direct_initializeWithCopy
17391739
#define pod_direct_initializeBufferWithCopyOfBuffer \
1740-
pointer_function_cast<value_witness_types::initializeBufferWithCopyOfBuffer> \
1740+
pointer_function_cast<ValueWitnessTypes::initializeBufferWithCopyOfBuffer> \
17411741
(pod_direct_initializeWithCopy)
17421742
#define pod_direct_assignWithCopy pod_direct_initializeWithCopy
17431743
#define pod_indirect_assignWithCopy pod_direct_initializeWithCopy

0 commit comments

Comments
 (0)