Skip to content

Commit 386aa4a

Browse files
committed
[Runtime] Improve performance and memory footprint of compatibility overrides
rdar://143401725 Replacing the (non-inlined) call to `swift_once` with a relaxed atomic significantly improves the generated code and reduces the memory footprint. The mechanism itself now does not cause a stack frame to be generated and the expected case (no override) should be perfectly predicted and executed in straight line code. The override case should also be well predicted, with only two branches on the same value.
1 parent 59e07f1 commit 386aa4a

File tree

1 file changed

+30
-10
lines changed

1 file changed

+30
-10
lines changed

stdlib/public/CompatibilityOverride/CompatibilityOverride.h

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,10 @@
8282
#define COMPATIBILITY_OVERRIDE_H
8383

8484
#include "../runtime/Private.h"
85+
#include "swift/Runtime/CMakeConfig.h"
8586
#include "swift/Runtime/Concurrency.h"
8687
#include "swift/Runtime/Metadata.h"
87-
#include "swift/Runtime/Once.h"
88-
#include "swift/Runtime/CMakeConfig.h"
88+
#include <atomic>
8989
#include <type_traits>
9090

9191
namespace swift {
@@ -186,21 +186,41 @@ namespace swift {
186186
Override_##name getOverride_##name();
187187
#include "CompatibilityOverrideIncludePath.h"
188188

189+
#define OVERRIDE(name, ret, attrs, ccAttrs, namespace, typedArgs, namedArgs) \
190+
SWIFT_NOINLINE \
191+
static ret swift_##name##Slow(COMPATIBILITY_UNPAREN_WITH_COMMA(typedArgs) \
192+
std::atomic<uintptr_t> &Override, \
193+
uintptr_t fn, Original_##name defaultImpl) { \
194+
constexpr uintptr_t DEFAULT_IMPL_SENTINEL = 0x1; \
195+
if (SWIFT_UNLIKELY(fn == 0x0)) { \
196+
fn = (uintptr_t)getOverride_##name(); \
197+
if (fn == 0x0) { \
198+
Override.store(DEFAULT_IMPL_SENTINEL, \
199+
std::memory_order::memory_order_relaxed); \
200+
return defaultImpl COMPATIBILITY_PAREN(namedArgs); \
201+
} \
202+
Override.store(fn, std::memory_order::memory_order_relaxed); \
203+
} \
204+
return ((Override_##name)fn)(COMPATIBILITY_UNPAREN_WITH_COMMA(namedArgs) \
205+
defaultImpl); \
206+
}
207+
#include "CompatibilityOverrideIncludePath.h"
208+
189209
/// Used to define an override point. The override point #defines the appropriate
190210
/// OVERRIDE macro from CompatibilityOverride.def to this macro, then includes
191211
/// the file to generate the override points. The original implementation of the
192212
/// functionality must be available as swift_funcNameHereImpl.
193213
#define COMPATIBILITY_OVERRIDE(name, ret, attrs, ccAttrs, namespace, \
194214
typedArgs, namedArgs) \
195215
attrs ccAttrs ret namespace swift_##name COMPATIBILITY_PAREN(typedArgs) { \
196-
static Override_##name Override; \
197-
static swift_once_t Predicate; \
198-
swift_once( \
199-
&Predicate, [](void *) { Override = getOverride_##name(); }, nullptr); \
200-
if (Override != nullptr) \
201-
return Override(COMPATIBILITY_UNPAREN_WITH_COMMA(namedArgs) \
202-
swift_##name##Impl); \
203-
return swift_##name##Impl COMPATIBILITY_PAREN(namedArgs); \
216+
constexpr uintptr_t DEFAULT_IMPL_SENTINEL = 0x1; \
217+
static std::atomic<uintptr_t> Override; \
218+
uintptr_t fn = Override.load(std::memory_order::memory_order_relaxed); \
219+
if (SWIFT_LIKELY(fn == DEFAULT_IMPL_SENTINEL)) { \
220+
return swift_##name##Impl COMPATIBILITY_PAREN(namedArgs); \
221+
} \
222+
return ::swift_##name##Slow(COMPATIBILITY_UNPAREN_WITH_COMMA(namedArgs) \
223+
Override, fn, &swift_##name##Impl); \
204224
}
205225

206226
#endif // #else SWIFT_STDLIB_SUPPORT_BACK_DEPLOYMENT

0 commit comments

Comments
 (0)