authorgravatar for kcbanner@gmail.comCasey Banner <kcbanner@gmail.com> 2024-07-13 17:46:24-04:00
committergravatar for kcbanner@gmail.comCasey Banner <kcbanner@gmail.com> 2024-07-13 17:46:24-04:00
logbc28454b43b717dee47cf8c1a1abfb7e8ad09a1e
tree5b451406f50bd24cf9e357a0ff2af788a1798ac5
parent11534aa34d6e9c66081eb2918bfaacbb21db0e56

zig.h: replace `_InterlockedExchangeAdd` with a plain volatile load

This was causing zig2.exe to crash during bootstrap, because there was an atomic load of read-only memory, and the attempt to write to it as part of the (idempotent) atomic exchange was invalid. Aligned reads (of u32 / u64) are atomic on x86 / x64, so this is replaced with an optimization-proof load (`__iso_volatile_load8*`) and a reordering barrier.

2 files changed, 30 insertions(+), 26 deletions(-)

lib/zig.h+13-11
...@@ -3670,7 +3670,7 @@ typedef int zig_memory_order;...@@ -3670,7 +3670,7 @@ typedef int zig_memory_order;
36703670
3671/* TODO: zig_msvc_atomic_load should load 32 bit without interlocked on x86, and load 64 bit without interlocked on x64 */3671/* TODO: zig_msvc_atomic_load should load 32 bit without interlocked on x86, and load 64 bit without interlocked on x64 */
36723672
3673#define zig_msvc_atomics(ZigType, Type, SigType, suffix) \3673#define zig_msvc_atomics(ZigType, Type, SigType, suffix, iso_suffix) \
3674 static inline bool zig_msvc_cmpxchg_##ZigType(Type volatile* obj, Type* expected, Type desired) { \3674 static inline bool zig_msvc_cmpxchg_##ZigType(Type volatile* obj, Type* expected, Type desired) { \
3675 Type comparand = *expected; \3675 Type comparand = *expected; \
3676 Type initial = _InterlockedCompareExchange##suffix((SigType volatile*)obj, (SigType)desired, (SigType)comparand); \3676 Type initial = _InterlockedCompareExchange##suffix((SigType volatile*)obj, (SigType)desired, (SigType)comparand); \
...@@ -3741,21 +3741,23 @@ typedef int zig_memory_order;...@@ -3741,21 +3741,23 @@ typedef int zig_memory_order;
3741 } \3741 } \
3742 static inline void zig_msvc_atomic_store_##ZigType(Type volatile* obj, Type value) { \3742 static inline void zig_msvc_atomic_store_##ZigType(Type volatile* obj, Type value) { \
3743 (void)_InterlockedExchange##suffix((SigType volatile*)obj, (SigType)value); \3743 (void)_InterlockedExchange##suffix((SigType volatile*)obj, (SigType)value); \
3744 } \3744 } \
3745 static inline Type zig_msvc_atomic_load_##ZigType(Type volatile* obj) { \3745 static inline Type zig_msvc_atomic_load_##ZigType(Type volatile* obj) { \
3746 return _InterlockedExchangeAdd##suffix((SigType volatile*)obj, (SigType)0); \3746 Type val = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \
3747 _ReadWriteBarrier(); \
3748 return val; \
3747 }3749 }
37483750
3749zig_msvc_atomics( u8, uint8_t, char, 8)3751zig_msvc_atomics( u8, uint8_t, char, 8, 8)
3750zig_msvc_atomics( i8, int8_t, char, 8)3752zig_msvc_atomics( i8, int8_t, char, 8, 8)
3751zig_msvc_atomics(u16, uint16_t, short, 16)3753zig_msvc_atomics(u16, uint16_t, short, 16, 16)
3752zig_msvc_atomics(i16, int16_t, short, 16)3754zig_msvc_atomics(i16, int16_t, short, 16, 16)
3753zig_msvc_atomics(u32, uint32_t, long, )3755zig_msvc_atomics(u32, uint32_t, long, , 32)
3754zig_msvc_atomics(i32, int32_t, long, )3756zig_msvc_atomics(i32, int32_t, long, , 32)
37553757
3756#if _M_X643758#if _M_X64
3757zig_msvc_atomics(u64, uint64_t, __int64, 64)3759zig_msvc_atomics(u64, uint64_t, __int64, 64, 64)
3758zig_msvc_atomics(i64, int64_t, __int64, 64)3760zig_msvc_atomics(i64, int64_t, __int64, 64, 64)
3759#endif3761#endif
37603762
3761#define zig_msvc_flt_atomics(Type, SigType, suffix) \3763#define zig_msvc_flt_atomics(Type, SigType, suffix) \
stage1/zig.h+17-15
...@@ -207,16 +207,16 @@ typedef char bool;...@@ -207,16 +207,16 @@ typedef char bool;
207 __asm(zig_mangle_c(name) " = " zig_mangle_c(symbol))207 __asm(zig_mangle_c(name) " = " zig_mangle_c(symbol))
208#endif208#endif
209209
210#define zig_mangled_tentative zig_mangled
211#define zig_mangled_final zig_mangled
210#if _MSC_VER212#if _MSC_VER
211#define zig_mangled_tentative(mangled, unmangled)213#define zig_mangled(mangled, unmangled) ; \
212#define zig_mangled_final(mangled, unmangled) ; \
213 zig_export(#mangled, unmangled)214 zig_export(#mangled, unmangled)
214#define zig_mangled_export(mangled, unmangled, symbol) \215#define zig_mangled_export(mangled, unmangled, symbol) \
215 zig_export(unmangled, #mangled) \216 zig_export(unmangled, #mangled) \
216 zig_export(symbol, unmangled)217 zig_export(symbol, unmangled)
217#else /* _MSC_VER */218#else /* _MSC_VER */
218#define zig_mangled_tentative(mangled, unmangled) __asm(zig_mangle_c(unmangled))219#define zig_mangled(mangled, unmangled) __asm(zig_mangle_c(unmangled))
219#define zig_mangled_final(mangled, unmangled) zig_mangled_tentative(mangled, unmangled)
220#define zig_mangled_export(mangled, unmangled, symbol) \220#define zig_mangled_export(mangled, unmangled, symbol) \
221 zig_mangled_final(mangled, unmangled) \221 zig_mangled_final(mangled, unmangled) \
222 zig_export(symbol, unmangled)222 zig_export(symbol, unmangled)
...@@ -3670,7 +3670,7 @@ typedef int zig_memory_order;...@@ -3670,7 +3670,7 @@ typedef int zig_memory_order;
36703670
3671/* TODO: zig_msvc_atomic_load should load 32 bit without interlocked on x86, and load 64 bit without interlocked on x64 */3671/* TODO: zig_msvc_atomic_load should load 32 bit without interlocked on x86, and load 64 bit without interlocked on x64 */
36723672
3673#define zig_msvc_atomics(ZigType, Type, SigType, suffix) \3673#define zig_msvc_atomics(ZigType, Type, SigType, suffix, iso_suffix) \
3674 static inline bool zig_msvc_cmpxchg_##ZigType(Type volatile* obj, Type* expected, Type desired) { \3674 static inline bool zig_msvc_cmpxchg_##ZigType(Type volatile* obj, Type* expected, Type desired) { \
3675 Type comparand = *expected; \3675 Type comparand = *expected; \
3676 Type initial = _InterlockedCompareExchange##suffix((SigType volatile*)obj, (SigType)desired, (SigType)comparand); \3676 Type initial = _InterlockedCompareExchange##suffix((SigType volatile*)obj, (SigType)desired, (SigType)comparand); \
...@@ -3741,21 +3741,23 @@ typedef int zig_memory_order;...@@ -3741,21 +3741,23 @@ typedef int zig_memory_order;
3741 } \3741 } \
3742 static inline void zig_msvc_atomic_store_##ZigType(Type volatile* obj, Type value) { \3742 static inline void zig_msvc_atomic_store_##ZigType(Type volatile* obj, Type value) { \
3743 (void)_InterlockedExchange##suffix((SigType volatile*)obj, (SigType)value); \3743 (void)_InterlockedExchange##suffix((SigType volatile*)obj, (SigType)value); \
3744 } \3744 } \
3745 static inline Type zig_msvc_atomic_load_##ZigType(Type volatile* obj) { \3745 static inline Type zig_msvc_atomic_load_##ZigType(Type volatile* obj) { \
3746 return _InterlockedExchangeAdd##suffix((SigType volatile*)obj, (SigType)0); \3746 Type val = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \
3747 _ReadWriteBarrier(); \
3748 return val; \
3747 }3749 }
37483750
3749zig_msvc_atomics( u8, uint8_t, char, 8)3751zig_msvc_atomics( u8, uint8_t, char, 8, 8)
3750zig_msvc_atomics( i8, int8_t, char, 8)3752zig_msvc_atomics( i8, int8_t, char, 8, 8)
3751zig_msvc_atomics(u16, uint16_t, short, 16)3753zig_msvc_atomics(u16, uint16_t, short, 16, 16)
3752zig_msvc_atomics(i16, int16_t, short, 16)3754zig_msvc_atomics(i16, int16_t, short, 16, 16)
3753zig_msvc_atomics(u32, uint32_t, long, )3755zig_msvc_atomics(u32, uint32_t, long, , 32)
3754zig_msvc_atomics(i32, int32_t, long, )3756zig_msvc_atomics(i32, int32_t, long, , 32)
37553757
3756#if _M_X643758#if _M_X64
3757zig_msvc_atomics(u64, uint64_t, __int64, 64)3759zig_msvc_atomics(u64, uint64_t, __int64, 64, 64)
3758zig_msvc_atomics(i64, int64_t, __int64, 64)3760zig_msvc_atomics(i64, int64_t, __int64, 64, 64)
3759#endif3761#endif
37603762
3761#define zig_msvc_flt_atomics(Type, SigType, suffix) \3763#define zig_msvc_flt_atomics(Type, SigType, suffix) \