From b1e546e405ab09a6c28605c22404e359ebf58106 Mon Sep 17 00:00:00 2001 From: Lars Eggert Date: Fri, 25 Sep 2026 11:51:22 +0300 Subject: [PATCH] Bug 1496426 - Use GCC atomic builtins for Linux x86/x86_64 Match ppc64/mips/riscv/loongarch: use `__sync_*` builtins instead of hand-written asm, requiring `__GNUC__` (and `__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4` for i386, matching `pratom.h`). Stop building the now-unused `.s` files. Matches Arch and RHEL packaging patches. https://bugzilla.mozilla.org/show_bug.cgi?id=1496426 Needs a perf/try comparison before merging. --- configure | 5 +- configure.in | 5 +- pr/include/md/_linux.h | 30 ++++++------ pr/src/md/unix/os_Linux_x86.s | 84 -------------------------------- pr/src/md/unix/os_Linux_x86_64.s | 73 --------------------------- 5 files changed, 16 insertions(+), 181 deletions(-) delete mode 100644 pr/src/md/unix/os_Linux_x86.s delete mode 100644 pr/src/md/unix/os_Linux_x86_64.s diff --git a/configure b/configure index 4630319e0..bec21d302 100755 --- a/configure +++ b/configure @@ -7386,22 +7386,19 @@ tools are selected during the Xcode/Developer Tools installation." "$LINENO" 5 i*86) printf "%s\n" "#define i386 1" >>confdefs.h - PR_MD_ASFILES=os_Linux_x86.s ;; ia64) PR_MD_ASFILES=os_Linux_ia64.s ;; x86_64) if test -n "$USE_64"; then - PR_MD_ASFILES=os_Linux_x86_64.s + : elif test -n "$USE_X32"; then - PR_MD_ASFILES=os_Linux_x86_64.s CC="$CC -mx32" CXX="$CXX -mx32" else printf "%s\n" "#define i386 1" >>confdefs.h - PR_MD_ASFILES=os_Linux_x86.s CC="$CC -m32" CXX="$CXX -m32" fi diff --git a/configure.in b/configure.in index d520cd836..d5287e82a 100644 --- a/configure.in +++ b/configure.in @@ -1431,21 +1431,18 @@ tools are selected during the Xcode/Developer Tools installation.]) ;; i*86) AC_DEFINE(i386) - PR_MD_ASFILES=os_Linux_x86.s ;; ia64) PR_MD_ASFILES=os_Linux_ia64.s ;; x86_64) if test -n "$USE_64"; then - PR_MD_ASFILES=os_Linux_x86_64.s + : elif test -n "$USE_X32"; then - PR_MD_ASFILES=os_Linux_x86_64.s CC="$CC -mx32" CXX="$CXX -mx32" else AC_DEFINE(i386) - PR_MD_ASFILES=os_Linux_x86.s CC="$CC -m32" CXX="$CXX -m32" fi diff --git a/pr/include/md/_linux.h b/pr/include/md/_linux.h index ccd6e5272..bb9fda9bf 100644 --- a/pr/include/md/_linux.h +++ b/pr/include/md/_linux.h @@ -105,16 +105,15 @@ #endif #if defined(__i386__) +#if defined(__GNUC__) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) +/* Use GCC built-in functions */ #define _PR_HAVE_ATOMIC_OPS #define _MD_INIT_ATOMIC() -extern PRInt32 _PR_x86_AtomicIncrement(PRInt32* val); -#define _MD_ATOMIC_INCREMENT _PR_x86_AtomicIncrement -extern PRInt32 _PR_x86_AtomicDecrement(PRInt32* val); -#define _MD_ATOMIC_DECREMENT _PR_x86_AtomicDecrement -extern PRInt32 _PR_x86_AtomicAdd(PRInt32* ptr, PRInt32 val); -#define _MD_ATOMIC_ADD _PR_x86_AtomicAdd -extern PRInt32 _PR_x86_AtomicSet(PRInt32* val, PRInt32 newval); -#define _MD_ATOMIC_SET _PR_x86_AtomicSet +#define _MD_ATOMIC_INCREMENT(ptr) __sync_add_and_fetch(ptr, 1) +#define _MD_ATOMIC_DECREMENT(ptr) __sync_sub_and_fetch(ptr, 1) +#define _MD_ATOMIC_ADD(ptr, i) __sync_add_and_fetch(ptr, i) +#define _MD_ATOMIC_SET(ptr, nv) __sync_lock_test_and_set(ptr, nv) +#endif #endif #if defined(__ia64__) @@ -131,16 +130,15 @@ extern PRInt32 _PR_ia64_AtomicSet(PRInt32* val, PRInt32 newval); #endif #if defined(__x86_64__) +#if defined(__GNUC__) +/* Use GCC built-in functions */ #define _PR_HAVE_ATOMIC_OPS #define _MD_INIT_ATOMIC() -extern PRInt32 _PR_x86_64_AtomicIncrement(PRInt32* val); -#define _MD_ATOMIC_INCREMENT _PR_x86_64_AtomicIncrement -extern PRInt32 _PR_x86_64_AtomicDecrement(PRInt32* val); -#define _MD_ATOMIC_DECREMENT _PR_x86_64_AtomicDecrement -extern PRInt32 _PR_x86_64_AtomicAdd(PRInt32* ptr, PRInt32 val); -#define _MD_ATOMIC_ADD _PR_x86_64_AtomicAdd -extern PRInt32 _PR_x86_64_AtomicSet(PRInt32* val, PRInt32 newval); -#define _MD_ATOMIC_SET _PR_x86_64_AtomicSet +#define _MD_ATOMIC_INCREMENT(ptr) __sync_add_and_fetch(ptr, 1) +#define _MD_ATOMIC_DECREMENT(ptr) __sync_sub_and_fetch(ptr, 1) +#define _MD_ATOMIC_ADD(ptr, i) __sync_add_and_fetch(ptr, i) +#define _MD_ATOMIC_SET(ptr, nv) __sync_lock_test_and_set(ptr, nv) +#endif #endif #if defined(__loongarch__) diff --git a/pr/src/md/unix/os_Linux_x86.s b/pr/src/md/unix/os_Linux_x86.s deleted file mode 100644 index bd19dc309..000000000 --- a/pr/src/md/unix/os_Linux_x86.s +++ /dev/null @@ -1,84 +0,0 @@ -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -// PRInt32 _PR_x86_AtomicIncrement(PRInt32 *val) -// -// Atomically increment the integer pointed to by 'val' and return -// the result of the increment. -// - .text - .globl _PR_x86_AtomicIncrement - .align 4 -_PR_x86_AtomicIncrement: - movl 4(%esp), %ecx - movl $1, %eax - lock - xaddl %eax, (%ecx) - incl %eax - ret - -// PRInt32 _PR_x86_AtomicDecrement(PRInt32 *val) -// -// Atomically decrement the integer pointed to by 'val' and return -// the result of the decrement. -// - .text - .globl _PR_x86_AtomicDecrement - .align 4 -_PR_x86_AtomicDecrement: - movl 4(%esp), %ecx - movl $-1, %eax - lock - xaddl %eax, (%ecx) - decl %eax - ret - -// PRInt32 _PR_x86_AtomicSet(PRInt32 *val, PRInt32 newval) -// -// Atomically set the integer pointed to by 'val' to the new -// value 'newval' and return the old value. -// -// An alternative implementation: -// .text -// .globl _PR_x86_AtomicSet -// .align 4 -//_PR_x86_AtomicSet: -// movl 4(%esp), %ecx -// movl 8(%esp), %edx -// movl (%ecx), %eax -//retry: -// lock -// cmpxchgl %edx, (%ecx) -// jne retry -// ret -// - .text - .globl _PR_x86_AtomicSet - .align 4 -_PR_x86_AtomicSet: - movl 4(%esp), %ecx - movl 8(%esp), %eax - xchgl %eax, (%ecx) - ret - -// PRInt32 _PR_x86_AtomicAdd(PRInt32 *ptr, PRInt32 val) -// -// Atomically add 'val' to the integer pointed to by 'ptr' -// and return the result of the addition. -// - .text - .globl _PR_x86_AtomicAdd - .align 4 -_PR_x86_AtomicAdd: - movl 4(%esp), %ecx - movl 8(%esp), %eax - movl %eax, %edx - lock - xaddl %eax, (%ecx) - addl %edx, %eax - ret - -// Magic indicating no need for an executable stack -.section .note.GNU-stack, "", @progbits diff --git a/pr/src/md/unix/os_Linux_x86_64.s b/pr/src/md/unix/os_Linux_x86_64.s deleted file mode 100644 index b9310dd5d..000000000 --- a/pr/src/md/unix/os_Linux_x86_64.s +++ /dev/null @@ -1,73 +0,0 @@ -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -// PRInt32 _PR_x86_64_AtomicIncrement(PRInt32 *val) -// -// Atomically increment the integer pointed to by 'val' and return -// the result of the increment. -// - .text - .globl _PR_x86_64_AtomicIncrement - .type _PR_x86_64_AtomicIncrement, @function - .align 4 -_PR_x86_64_AtomicIncrement: - movl $1, %eax - lock - xaddl %eax, (%rdi) - incl %eax - ret - .size _PR_x86_64_AtomicIncrement, .-_PR_x86_64_AtomicIncrement - -// PRInt32 _PR_x86_64_AtomicDecrement(PRInt32 *val) -// -// Atomically decrement the integer pointed to by 'val' and return -// the result of the decrement. -// - .text - .globl _PR_x86_64_AtomicDecrement - .type _PR_x86_64_AtomicDecrement, @function - .align 4 -_PR_x86_64_AtomicDecrement: - movl $-1, %eax - lock - xaddl %eax, (%rdi) - decl %eax - ret - .size _PR_x86_64_AtomicDecrement, .-_PR_x86_64_AtomicDecrement - -// PRInt32 _PR_x86_64_AtomicSet(PRInt32 *val, PRInt32 newval) -// -// Atomically set the integer pointed to by 'val' to the new -// value 'newval' and return the old value. -// - .text - .globl _PR_x86_64_AtomicSet - .type _PR_x86_64_AtomicSet, @function - .align 4 -_PR_x86_64_AtomicSet: - movl %esi, %eax - xchgl %eax, (%rdi) - ret - .size _PR_x86_64_AtomicSet, .-_PR_x86_64_AtomicSet - -// PRInt32 _PR_x86_64_AtomicAdd(PRInt32 *ptr, PRInt32 val) -// -// Atomically add 'val' to the integer pointed to by 'ptr' -// and return the result of the addition. -// - .text - .globl _PR_x86_64_AtomicAdd - .type _PR_x86_64_AtomicAdd, @function - .align 4 -_PR_x86_64_AtomicAdd: - movl %esi, %eax - lock - xaddl %eax, (%rdi) - addl %esi, %eax - ret - .size _PR_x86_64_AtomicAdd, .-_PR_x86_64_AtomicAdd - -// Magic indicating no need for an executable stack -.section .note.GNU-stack, "", @progbits