|
82 | 82 | #define COMPATIBILITY_OVERRIDE_H |
83 | 83 |
|
84 | 84 | #include "../runtime/Private.h" |
| 85 | +#include "swift/Runtime/CMakeConfig.h" |
85 | 86 | #include "swift/Runtime/Concurrency.h" |
86 | 87 | #include "swift/Runtime/Metadata.h" |
87 | | -#include "swift/Runtime/Once.h" |
88 | | -#include "swift/Runtime/CMakeConfig.h" |
| 88 | +#include <atomic> |
89 | 89 | #include <type_traits> |
90 | 90 |
|
91 | 91 | namespace swift { |
@@ -192,15 +192,38 @@ namespace swift { |
192 | 192 | /// functionality must be available as swift_funcNameHereImpl. |
193 | 193 | #define COMPATIBILITY_OVERRIDE(name, ret, attrs, ccAttrs, namespace, \ |
194 | 194 | typedArgs, namedArgs) \ |
| 195 | + /* We are creating this separate function for the override case, */ \ |
| 196 | + /* to prevent a stack frame from being created for the default case. */ \ |
| 197 | + SWIFT_NOINLINE \ |
| 198 | + static ret swift_##name##Slow(COMPATIBILITY_UNPAREN_WITH_COMMA(typedArgs) \ |
| 199 | + std::atomic<uintptr_t> &Override, \ |
| 200 | + uintptr_t fn, Original_##name defaultImpl) { \ |
| 201 | + constexpr uintptr_t DEFAULT_IMPL_SENTINEL = 0x1; \ |
| 202 | + if (SWIFT_UNLIKELY(fn == 0x0)) { \ |
| 203 | + fn = (uintptr_t)getOverride_##name(); \ |
| 204 | + if (fn == 0x0) { \ |
| 205 | + Override.store(DEFAULT_IMPL_SENTINEL, \ |
| 206 | + std::memory_order::memory_order_relaxed); \ |
| 207 | + return defaultImpl COMPATIBILITY_PAREN(namedArgs); \ |
| 208 | + } \ |
| 209 | + Override.store(fn, std::memory_order::memory_order_relaxed); \ |
| 210 | + } \ |
| 211 | + return ((Override_##name)fn)(COMPATIBILITY_UNPAREN_WITH_COMMA(namedArgs) \ |
| 212 | + defaultImpl); \ |
| 213 | + } \ |
195 | 214 | 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); \ |
| 215 | + constexpr uintptr_t DEFAULT_IMPL_SENTINEL = 0x1; \ |
| 216 | + static std::atomic<uintptr_t> Override; \ |
| 217 | + uintptr_t fn = Override.load(std::memory_order::memory_order_relaxed); \ |
| 218 | + if (SWIFT_LIKELY(fn == DEFAULT_IMPL_SENTINEL)) { \ |
| 219 | + return swift_##name##Impl COMPATIBILITY_PAREN(namedArgs); \ |
| 220 | + } else if (SWIFT_UNLIKELY(fn == 0x0)) { \ |
| 221 | + return swift_##name##Slow(COMPATIBILITY_UNPAREN_WITH_COMMA(namedArgs) \ |
| 222 | + Override, \ |
| 223 | + fn, &swift_##name##Impl); \ |
| 224 | + } \ |
| 225 | + return ((Override_##name)fn)(COMPATIBILITY_UNPAREN_WITH_COMMA(namedArgs) & \ |
| 226 | + swift_##name##Impl); \ |
204 | 227 | } |
205 | 228 |
|
206 | 229 | #endif // #else SWIFT_STDLIB_SUPPORT_BACK_DEPLOYMENT |
|
0 commit comments