Skip to content

Commit 93f5b81

Browse files
committed
runtime: export two symbols used to create static constant arrays.
* `__swiftImmortalRefCount`: The bit pattern of the ref-count field of immortal objects * `__swiftStaticArrayMetadata`: The metadata used for static arrays.
1 parent 0d2ef98 commit 93f5b81

File tree

2 files changed

+48
-3
lines changed

2 files changed

+48
-3
lines changed

stdlib/public/SwiftShims/RefCount.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,13 @@ class RefCountBitsT {
417417
setField(PureSwiftDealloc, value);
418418
}
419419

420+
SWIFT_ALWAYS_INLINE
421+
static constexpr BitsType immortalBits() {
422+
return (BitsType(2) << Offsets::StrongExtraRefCountShift) |
423+
(BitsType(Offsets::IsImmortalMask)) |
424+
(BitsType(1) << Offsets::UseSlowRCShift);
425+
}
426+
420427
SWIFT_ALWAYS_INLINE
421428
RefCountBitsT() = default;
422429

@@ -431,9 +438,7 @@ class RefCountBitsT {
431438
SWIFT_ALWAYS_INLINE
432439
constexpr
433440
RefCountBitsT(Immortal_t immortal)
434-
: bits((BitsType(2) << Offsets::StrongExtraRefCountShift) |
435-
(BitsType(Offsets::IsImmortalMask)) |
436-
(BitsType(1) << Offsets::UseSlowRCShift))
441+
: bits(immortalBits())
437442
{ }
438443

439444
SWIFT_ALWAYS_INLINE

stdlib/public/stubs/GlobalObjects.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,46 @@ swift::_SwiftEmptyArrayStorage swift::_swiftEmptyArrayStorage = {
5353
}
5454
};
5555

56+
// Define required symbols to be used by constant static arrays.
57+
// * `__swiftImmortalRefCount`: The bit pattern for the ref-count field of
58+
// the array buffer.
59+
// * `__swiftStaticArrayMetadata`: The isa-pointer for the array buffer.
60+
//
61+
// TODO: Support constant static arrays on other platforms, too.
62+
// This needs a bit more work because the tricks with absolute symbols and
63+
// symbol aliases don't work this way with other object file formats than Mach-O.
64+
#if defined(__APPLE__)
65+
66+
__asm__(" .globl __swiftImmortalRefCount\n");
67+
68+
#if __POINTER_WIDTH__ == 64
69+
70+
// TODO: is there a way to avoid hard coding this constant in the inline
71+
// assembly string?
72+
static_assert(swift::InlineRefCountBits::immortalBits() == 0x80000004ffffffffull,
73+
"immortal refcount bits changed: correct the inline asm below");
74+
__asm__(".set __swiftImmortalRefCount, 0x80000004ffffffff\n");
75+
76+
#elif __POINTER_WIDTH__ == 32
77+
78+
// TODO: is there a way to avoid hard coding this constant in the inline
79+
// assembly string?
80+
static_assert(swift::InlineRefCountBits::immortalBits() == 0x800004fful,
81+
"immortal refcount bits changed: correct the inline asm below");
82+
__asm__(".set __swiftImmortalRefCount, 0x800004ff\n");
83+
84+
#else
85+
#error("unsupported pointer width")
86+
#endif
87+
88+
// Static arrays can only contain trivial elements. Therefore we can reuse
89+
// the metadata of the empty array buffer. The important thing is that its
90+
// deinit is a no-op and does not actually destroy any elements.
91+
__asm__(" .globl __swiftStaticArrayMetadata\n");
92+
__asm__(".set __swiftStaticArrayMetadata, _$ss19__EmptyArrayStorageCN\n");
93+
94+
#endif
95+
5696
SWIFT_RUNTIME_STDLIB_API
5797
swift::_SwiftEmptyDictionarySingleton swift::_swiftEmptyDictionarySingleton = {
5898
// HeapObject header;

0 commit comments

Comments
 (0)