Skip to content

Commit

Permalink
Define CAST_THRU_UINTPTR and CAST_AWAY_VOLATILE_PVOID internal macros
Browse files Browse the repository at this point in the history
(refactoring)

Issue #627 (bdwgc).

* alloc.c (GC_clear_a_few_frames): Use CAST_AWAY_VOLATILE_PVOID()
instead of a direct no-volatile cast.
* mach_dep.c (GC_with_callee_saves_pushed): Likewise.
* misc.c (GC_clear_stack, GC_clear_stack_inner): Likewise.
* os_dep.c [!ANY_MSWIN && (SVR4 || AIX || DGUX)] (GC_SysVGetDataStart):
Likewise.
* os_dep.c [!GC_DISABLE_INCREMENTAL] (GC_read_dirty): Likewise.
* specific.c (GC_setspecific): Likewise.
* win32_threads.c (GC_start_world): Likewise.
* gcj_mlc.c [FUNCPTR_IS_DATAPTR] (GC_init_gcj_malloc): Use
CAST_THRU_UINTPTR().
* include/private/gc_priv.h (NONNULL_ARG_NOT_NULL): Likewise.
* mark.c (GC_push_marked): Likewise.
* os_dep.c [GWW_VDB && MSWINRT_FLAVOR && FUNCPTR_IS_DATAPTR]
(detect_GetWriteWatch): Likewise.
* pthread_support.c [GC_PTHREADS && !SN_TARGET_ORBIS
&& !SN_TARGET_PSP2 && DEBUG_THREADS && FUNCPTR_IS_DATAPTR]
(GC_start_rtn_prepare_thread): Likewise.
* tests/gctest.c (reverse_test_inner): Likewise.
* win32_threads.c [((!HAVE_PTHREAD_SETNAME_NP_WITH_TID && !MSWINCE
&& PARALLEL_MARK) || WOW64_THREAD_CONTEXT_WORKAROUND) && MSWINRT_FLAVOR
&& FUNCPTR_IS_DATAPTR] (GC_thr_init): Likewise.
* include/private/gc_priv.h (CAST_THRU_UINTPTR,
CAST_AWAY_VOLATILE_PVOID): New macro.
* pthread_support.c [GC_USE_DLOPEN_WRAP] (TYPED_DLSYM): Likewise.
* pthread_support.c [GC_USE_DLOPEN_WRAP] (GC_init_real_syms): Use
TYPED_DLSYM().
  • Loading branch information
ivmai committed Jun 12, 2024
1 parent cab2216 commit 6040089
Show file tree
Hide file tree
Showing 11 changed files with 99 additions and 83 deletions.
4 changes: 2 additions & 2 deletions alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -397,8 +397,8 @@ STATIC void GC_clear_a_few_frames(void)
# define CLEAR_NWORDS 64
# endif
volatile word frames[CLEAR_NWORDS];
BZERO((/* no volatile */ word *)((word)frames),
CLEAR_NWORDS * sizeof(word));

BZERO(CAST_AWAY_VOLATILE_PVOID(frames), sizeof(frames));
}

GC_API void GC_CALL GC_start_incremental_collection(void)
Expand Down
3 changes: 2 additions & 1 deletion gcj_mlc.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ STATIC struct GC_ms_entry *GC_CALLBACK GC_gcj_fake_mark_proc(word *addr,
#ifdef FUNCPTR_IS_DATAPTR
GC_API void GC_CALL GC_init_gcj_malloc(int mp_index, void *mp)
{
GC_init_gcj_malloc_mp((unsigned)mp_index, (GC_mark_proc)(word)mp);
GC_init_gcj_malloc_mp((unsigned)mp_index,
CAST_THRU_UINTPTR(GC_mark_proc, mp));
}
#endif /* FUNCPTR_IS_DATAPTR */

Expand Down
12 changes: 10 additions & 2 deletions include/private/gc_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,13 @@ typedef struct hblkhdr hdr;
/* */
/*********************************/

/* Prevent certain compiler warnings by making a cast through */
/* a pointer-sized numeric type. */
#define CAST_THRU_UINTPTR(t, x) ((t)(GC_uintptr_t)(x))

#define CAST_AWAY_VOLATILE_PVOID(p) \
CAST_THRU_UINTPTR(/* no volatile */ void *, p)

#define GC_WORD_MAX (~(word)0)

/* Convert given pointer to its address. Result is of word type. */
Expand Down Expand Up @@ -3047,9 +3054,10 @@ GC_INNER void *GC_store_debug_info_inner(void *p, word sz, const char *str,
/* Runtime check for an argument declared as non-null is actually not null. */
#if GC_GNUC_PREREQ(4, 0)
/* Workaround tautological-pointer-compare Clang warning. */
# define NONNULL_ARG_NOT_NULL(arg) (*(volatile void **)(word)(&(arg)) != NULL)
# define NONNULL_ARG_NOT_NULL(arg) \
(*CAST_THRU_UINTPTR(volatile void **, &(arg)) != NULL)
#else
# define NONNULL_ARG_NOT_NULL(arg) (NULL != (arg))
# define NONNULL_ARG_NOT_NULL(arg) ((arg) != NULL)
#endif

#define COND_DUMP_CHECKS \
Expand Down
2 changes: 1 addition & 1 deletion mach_dep.c
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ GC_INNER void GC_with_callee_saves_pushed(GC_with_callee_saves_func fn,
/* callees don't really need it. */
/* Cast fn to a volatile type to prevent call inlining. */
(*(GC_with_callee_saves_func volatile *)&fn)(volatile_arg,
(/* no volatile */ void *)(word)context);
CAST_AWAY_VOLATILE_PVOID(context));
/* Strongly discourage the compiler from treating the above */
/* as a tail-call, since that would pop the register */
/* contents before we get a chance to look at them. */
Expand Down
4 changes: 2 additions & 2 deletions mark.c
Original file line number Diff line number Diff line change
Expand Up @@ -1932,7 +1932,7 @@ STATIC void GC_push_marked(struct hblk *h, const hdr *hhdr)
# endif
default:
lim = sz > MAXOBJBYTES ? h -> hb_body
: (ptr_t)((word)(h + 1) -> hb_body - sz);
: CAST_THRU_UINTPTR(ptr_t, (h + 1) -> hb_body) - sz;
mark_stack_top = GC_mark_stack_top;
for (p = h -> hb_body, bit_no = 0; ADDR_GE(lim, p);
p += sz, bit_no += MARK_BIT_OFFSET(sz)) {
Expand Down Expand Up @@ -1972,7 +1972,7 @@ STATIC void GC_push_marked(struct hblk *h, const hdr *hhdr)
# endif
GC_objects_are_marked = TRUE;
lim = sz > MAXOBJBYTES ? h -> hb_body
: (ptr_t)((word)(h + 1) -> hb_body - sz);
: CAST_THRU_UINTPTR(ptr_t, (h + 1) -> hb_body) - sz;
mark_stack_top = GC_mark_stack_top;
for (p = h -> hb_body; ADDR_GE(lim, p); p += sz) {
if ((*(word *)p & 0x3) != 0) {
Expand Down
7 changes: 4 additions & 3 deletions misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,8 @@ STATIC void GC_init_size_map(void)
{
# ifndef STACK_NOT_SCANNED
word volatile dummy[SMALL_CLEAR_SIZE];
BZERO((/* no volatile */ word *)((word)dummy), sizeof(dummy));

BZERO(CAST_AWAY_VOLATILE_PVOID(dummy), sizeof(dummy));
# endif
return arg;
}
Expand Down Expand Up @@ -310,7 +311,7 @@ STATIC void GC_init_size_map(void)
# define CLEAR_SIZE 213 /* granularity */
volatile word dummy[CLEAR_SIZE];

BZERO((/* no volatile */ word *)((word)dummy), sizeof(dummy));
BZERO(CAST_AWAY_VOLATILE_PVOID(dummy), sizeof(dummy));
if (HOTTER_THAN((/* no volatile */ ptr_t)limit, GC_approx_sp())) {
(void)GC_clear_stack_inner(arg, limit);
}
Expand Down Expand Up @@ -380,7 +381,7 @@ STATIC void GC_init_size_map(void)
/* implementations of GC_clear_stack_inner. */
return GC_clear_stack_inner(arg, limit);
}
BZERO((/* no volatile */ void *)dummy, SMALL_CLEAR_SIZE * sizeof(word));
BZERO(CAST_AWAY_VOLATILE_PVOID(dummy), sizeof(dummy));
# else
if (GC_gc_no != GC_stack_last_cleared) {
/* Start things over, so we clear the entire stack again. */
Expand Down
94 changes: 48 additions & 46 deletions os_dep.c
Original file line number Diff line number Diff line change
Expand Up @@ -1712,11 +1712,13 @@ void GC_register_data_segments(void)
}
# endif

# ifdef MSWINRT_FLAVOR
# if defined(MSWINRT_FLAVOR) && defined(FUNCPTR_IS_DATAPTR)
{
MEMORY_BASIC_INFORMATION memInfo;
SIZE_T result = VirtualQuery((void*)(word)GetProcAddress,
&memInfo, sizeof(memInfo));
SIZE_T result
= VirtualQuery(CAST_THRU_UINTPTR(void*, GetProcAddress),
&memInfo, sizeof(memInfo));

if (result != sizeof(memInfo))
ABORT("Weird VirtualQuery result");
hK32 = (HMODULE)memInfo.AllocationBase;
Expand Down Expand Up @@ -1979,45 +1981,47 @@ void GC_register_data_segments(void)

# else /* !ANY_MSWIN */

# if (defined(SVR4) || defined(AIX) || defined(DGUX)) && !defined(PCR)
ptr_t GC_SysVGetDataStart(size_t max_page_size, ptr_t etext_addr)
{
word page_offset = ADDR(PTR_ALIGN_UP(etext_addr, sizeof(ptr_t)))
& ((word)max_page_size - 1);
volatile ptr_t result = PTR_ALIGN_UP(etext_addr, max_page_size)
+ page_offset;
/* Note that this isn't equivalent to just adding */
/* max_page_size to &etext if etext is at a page boundary. */
# if (defined(SVR4) || defined(AIX) || defined(DGUX)) && !defined(PCR)
ptr_t GC_SysVGetDataStart(size_t max_page_size, ptr_t etext_addr)
{
word page_offset = ADDR(PTR_ALIGN_UP(etext_addr, sizeof(ptr_t)))
& ((word)max_page_size - 1);
volatile ptr_t result = PTR_ALIGN_UP(etext_addr, max_page_size)
+ page_offset;
/* Note that this is not equivalent to just adding */
/* max_page_size to &etext if etext is at a page boundary. */

GC_ASSERT(max_page_size % sizeof(ptr_t) == 0);
GC_setup_temporary_fault_handler();
if (SETJMP(GC_jmp_buf) == 0) {
/* Try writing to the address. */
# ifdef AO_HAVE_fetch_and_add
volatile AO_t zero = 0;

GC_ASSERT(max_page_size % sizeof(ptr_t) == 0);
GC_setup_temporary_fault_handler();
if (SETJMP(GC_jmp_buf) == 0) {
/* Try writing to the address. */
# ifdef AO_HAVE_fetch_and_add
volatile AO_t zero = 0;
(void)AO_fetch_and_add((volatile AO_t *)result, zero);
# else
/* Fallback to non-atomic fetch-and-store. */
char v = *result;
# if defined(CPPCHECK)
GC_noop1_ptr(&v);
(void)AO_fetch_and_add((volatile AO_t *)result, zero);
# else
/* Fallback to non-atomic fetch-and-store. */
char v = *result;

# if defined(CPPCHECK)
GC_noop1_ptr(&v);
# endif
*result = v;
# endif
*result = v;
# endif
GC_reset_fault_handler();
} else {
GC_reset_fault_handler();
/* We got here via a longjmp. The address is not readable. */
/* This is known to happen under Solaris 2.4 + gcc, which */
/* places string constants in the text segment, but after */
/* etext. Use plan B. Note that we now know there is a gap */
/* between text and data segments, so plan A brought us */
/* something. */
result = (char *)GC_find_limit(DATAEND, FALSE);
}
return (/* no volatile */ ptr_t)(word)result;
}
# endif
GC_reset_fault_handler();
} else {
GC_reset_fault_handler();
/* We got here via a longjmp. The address is not readable. */
/* This is known to happen under Solaris 2.4 + gcc, which */
/* places string constants in the text segment, but after */
/* etext. Use plan B. Note that we now know there is a gap */
/* between text and data segments, so plan A brought us */
/* something. */
result = (char *)GC_find_limit(DATAEND, FALSE);
}
return (ptr_t)CAST_AWAY_VOLATILE_PVOID(result);
}
# endif /* SVR4 || AIX || DGUX */

#ifdef DATASTART_USES_BSDGETDATASTART
/* It's unclear whether this should be identical to the above, or */
Expand Down Expand Up @@ -4267,10 +4271,9 @@ GC_INNER GC_bool GC_dirty_init(void)
# endif
) {
if (!output_unneeded)
BCOPY((/* no volatile */ void *)(word)GC_dirty_pages,
GC_grungy_pages, sizeof(GC_dirty_pages));
BZERO((/* no volatile */ void *)(word)GC_dirty_pages,
sizeof(GC_dirty_pages));
BCOPY(CAST_AWAY_VOLATILE_PVOID(GC_dirty_pages), GC_grungy_pages,
sizeof(GC_dirty_pages));
BZERO(CAST_AWAY_VOLATILE_PVOID(GC_dirty_pages), sizeof(GC_dirty_pages));
# ifdef MPROTECT_VDB
if (!GC_manual_vdb)
GC_protect_heap();
Expand Down Expand Up @@ -4301,8 +4304,7 @@ GC_INNER GC_bool GC_dirty_init(void)
}
# endif
# if defined(CHECK_SOFT_VDB) /* && MPROTECT_VDB */
BZERO((/* no volatile */ void *)(word)GC_dirty_pages,
sizeof(GC_dirty_pages));
BZERO(CAST_AWAY_VOLATILE_PVOID(GC_dirty_pages), sizeof(GC_dirty_pages));
GC_protect_heap();
# endif
}
Expand Down
30 changes: 17 additions & 13 deletions pthread_support.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,10 @@
# ifdef GC_USE_DLOPEN_WRAP
STATIC GC_bool GC_syms_initialized = FALSE;

/* Resolve a symbol from the dynamic library (given by a handle) */
/* and cast it to the given functional type. */
# define TYPED_DLSYM(fn, h, name) CAST_THRU_UINTPTR(fn, dlsym(h, name))

STATIC void GC_init_real_syms(void)
{
void *dl_handle;
Expand All @@ -226,28 +230,28 @@
if (NULL == dl_handle) ABORT("Couldn't open libpthread");
}
# endif
REAL_FUNC(pthread_create) = (GC_pthread_create_t)(word)
dlsym(dl_handle, "pthread_create");
REAL_FUNC(pthread_create) = TYPED_DLSYM(GC_pthread_create_t, dl_handle,
"pthread_create");
# ifdef RTLD_NEXT
if (REAL_FUNC(pthread_create) == 0)
ABORT("pthread_create not found"
" (probably -lgc is specified after -lpthread)");
# endif
# ifndef GC_NO_PTHREAD_SIGMASK
REAL_FUNC(pthread_sigmask) = (GC_pthread_sigmask_t)(word)
dlsym(dl_handle, "pthread_sigmask");
REAL_FUNC(pthread_sigmask) = TYPED_DLSYM(GC_pthread_sigmask_t,
dl_handle, "pthread_sigmask");
# endif
REAL_FUNC(pthread_join) = (GC_pthread_join_t)(word)
dlsym(dl_handle, "pthread_join");
REAL_FUNC(pthread_detach) = (GC_pthread_detach_t)(word)
dlsym(dl_handle, "pthread_detach");
REAL_FUNC(pthread_join) = TYPED_DLSYM(GC_pthread_join_t, dl_handle,
"pthread_join");
REAL_FUNC(pthread_detach) = TYPED_DLSYM(GC_pthread_detach_t, dl_handle,
"pthread_detach");
# ifndef GC_NO_PTHREAD_CANCEL
REAL_FUNC(pthread_cancel) = (GC_pthread_cancel_t)(word)
dlsym(dl_handle, "pthread_cancel");
REAL_FUNC(pthread_cancel) = TYPED_DLSYM(GC_pthread_cancel_t,
dl_handle, "pthread_cancel");
# endif
# ifdef GC_HAVE_PTHREAD_EXIT
REAL_FUNC(pthread_exit) = (GC_pthread_exit_t)(word)
dlsym(dl_handle, "pthread_exit");
REAL_FUNC(pthread_exit) = TYPED_DLSYM(GC_pthread_exit_t, dl_handle,
"pthread_exit");
# endif
GC_syms_initialized = TRUE;
}
Expand Down Expand Up @@ -2480,7 +2484,7 @@ GC_API int GC_CALL GC_register_my_thread(const struct GC_stack_base *sb)
*pstart = psi -> start_routine;
*pstart_arg = psi -> arg;
# if defined(DEBUG_THREADS) && defined(FUNCPTR_IS_DATAPTR)
GC_log_printf("start_routine= %p\n", (void *)(word)(*pstart));
GC_log_printf("start_routine= %p\n", CAST_THRU_UINTPTR(void*, *pstart));
# endif
sem_post(&(psi -> registered)); /* Last action on *psi; */
/* OK to deallocate. */
Expand Down
8 changes: 4 additions & 4 deletions specific.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,9 @@ GC_INNER int GC_setspecific(tsd * key, void * value)
/* There can only be one writer at a time, but this needs to be */
/* atomic with respect to concurrent readers. */
AO_store_release(&key->hash[hash_val].ao, (AO_t)entry);
GC_dirty((/* no volatile */ void *)(word)entry);
GC_dirty(key->hash + hash_val);
if (pthread_mutex_unlock(&key->lock) != 0)
GC_dirty(CAST_AWAY_VOLATILE_PVOID(entry));
GC_dirty(key -> hash + hash_val);
if (pthread_mutex_unlock(&(key -> lock)) != 0)
ABORT("pthread_mutex_unlock failed (setspecific)");
return 0;
}
Expand Down Expand Up @@ -140,7 +140,7 @@ GC_INNER void GC_remove_specific_after_fork(tsd * key, pthread_t t)
/* With GC, we're done, since the pointers from the cache will */
/* be overwritten, all local pointers to the entries will be */
/* dropped, and the entry will then be reclaimed. */
if (pthread_mutex_unlock(&key->lock) != 0)
if (pthread_mutex_unlock(&(key -> lock)) != 0)
ABORT("pthread_mutex_unlock failed (remove_specific after fork)");
}

Expand Down
4 changes: 2 additions & 2 deletions tests/gctest.c
Original file line number Diff line number Diff line change
Expand Up @@ -985,8 +985,8 @@ static void *GC_CALLBACK reverse_test_inner(void *data)
# ifndef THREADS
a_set(NULL);
# endif
*(sexpr volatile *)(GC_word)&b = 0;
*(sexpr volatile *)(GC_word)&c = 0;
*CAST_THRU_UINTPTR(volatile sexpr *, &b) = 0;
*CAST_THRU_UINTPTR(volatile sexpr *, &c) = 0;
return 0;
}

Expand Down
14 changes: 7 additions & 7 deletions win32_threads.c
Original file line number Diff line number Diff line change
Expand Up @@ -580,9 +580,9 @@ GC_INNER void GC_start_world(void)
# ifdef DEBUG_THREADS
GC_log_printf("Resuming 0x%x\n", (int)p->id);
# endif
GC_ASSERT(p -> id != self_id
&& *(/* no volatile */ ptr_t *)
(word)(&(p -> crtn -> stack_end)) != NULL);
GC_ASSERT(p -> id != self_id);
GC_ASSERT(*(ptr_t *)CAST_AWAY_VOLATILE_PVOID(
&(p -> crtn -> stack_end)) != NULL);
if (ResumeThread(THREAD_HANDLE(p)) == (DWORD)-1)
ABORT("ResumeThread failed");
p -> flags &= (unsigned char)~IS_SUSPENDED;
Expand Down Expand Up @@ -1650,11 +1650,11 @@ GC_INNER void GC_thr_init(void)
# if (!defined(HAVE_PTHREAD_SETNAME_NP_WITH_TID) && !defined(MSWINCE) \
&& defined(PARALLEL_MARK)) || defined(WOW64_THREAD_CONTEXT_WORKAROUND)
HMODULE hK32;
# ifdef MSWINRT_FLAVOR
# if defined(MSWINRT_FLAVOR) && defined(FUNCPTR_IS_DATAPTR)
MEMORY_BASIC_INFORMATION memInfo;

if (VirtualQuery((void*)(word)GetProcAddress, &memInfo, sizeof(memInfo))
!= sizeof(memInfo))
if (VirtualQuery(CAST_THRU_UINTPTR(void*, GetProcAddress),
&memInfo, sizeof(memInfo)) != sizeof(memInfo))
ABORT("Weird VirtualQuery result");
hK32 = (HMODULE)memInfo.AllocationBase;
# else
Expand Down Expand Up @@ -1820,7 +1820,7 @@ GC_INNER void GC_thr_init(void)
GC_get_stack_base(&sb);
GC_ASSERT(sb_result == GC_SUCCESS);
GC_register_my_thread_inner(&sb, self_id);
} /* o.w. we already did it during GC_thr_init, called by GC_init */
} /* else we already did it during GC_thr_init, called by GC_init */
break;

case DLL_THREAD_DETACH:
Expand Down

0 comments on commit 6040089

Please sign in to comment.