Jay Krell [Mon, 12 Feb 2018 21:34:21 +0000 (00:34 +0300)]
Change pointer arguments of push_all[_eager]/conditional API to void* type
Receiving void* instead of char* is easier to use, as it requires
no casting.
A small downside of this change is that anyone using decltype(GC_push)
in C++ function signatures would get a different name mangling.
* include/gc_mark.h (GC_push_all, GC_push_all_eager,
GC_push_conditional): Change type of bottom and top arguments from
char* to void*.
* mark.c (GC_push_all, GC_push_conditional, GC_push_all_eager):
Likewise.
* include/private/gc_priv.h (GC_PUSH_ALL_SYM): Cast away volatile
qualifier for &sym.
* mark.c (GC_push_all): Remove "register" keyword for length local
variable.
* mark.c [!GC_DISABLE_INCREMENTAL] (GC_push_selected): Remove unneeded
casts for GC_push_all arguments.
* mark.c [WRAP_MARK_SOME && PARALLEL_MARK] (GC_push_conditional_eager):
Change type of bottom and top arguments from ptr_t to void*.
* mark_rts.c [WRAP_MARK_SOME && PARALLEL_MARK]
(GC_push_conditional_eager): Likewise.
* mark_rts.c (GC_PUSH_CONDITIONAL): Remove unneeded casts for
GC_push_all and GC_push_conditional arguments.
Hans Boehm [Mon, 12 Feb 2018 08:24:54 +0000 (11:24 +0300)]
Avoid potential race between realloc and clear_hdr_marks/reclaim_generic
GC_realloc might be changing the block size while GC_reclaim_block
or GC_clear_hdr_marks is examining it. The change to the size field
is benign, in that GC_reclaim (and GC_clear_hdr_marks) would work
correctly with either value, since we are not changing the number
of objects in the block. But seeing a half-updated value (though
unlikely to occur in practice) could be probably bad.
Using unordered atomic accesses on the size and hb_descr fields would
solve the issue.
* mallocx.c [AO_HAVE_store] (GC_realloc): Use AO_store() to update
hhdr->hb_sz and hhdr->hb_descr; add static assert that size of
hhdr->hb_sz matches that of AO_t; add comment.
* mallocx.c [!AO_HAVE_store] (GC_realloc): Add LOCK/UNLOCK around
hb_sz and hb_descr fields assignment.
* mark.c [AO_HAVE_load] (GC_clear_hdr_marks): Use AO_load() to get
hhdr->hb_sz value; add comment.
* reclaim.c (IS_PTRFREE_SAFE): New macro (uses AO_load() if available).
* reclaim.c (GC_reclaim_generic, GC_reclaim_block): Replace
(hhdr)->hb_descr==0 with IS_PTRFREE_SAFE(hhdr).
Because it is not a false positive. And we are lying to the compiler
about the value not changing asynchronously, which is never good.
The proper solution could be use of atomic accesses (even unordered)
on the size field.
Ivan Maidanski [Fri, 9 Feb 2018 08:17:29 +0000 (11:17 +0300)]
Fix build of cord tests as C++ files (Makefile.direct)
* Makefile.direct (cords): Do not depend on cord/cordtest.
* Makefile.direct (cord): Remove.
* Makefile.direct (cord/cordbscs.o, cord/cordxtra.o, cord/cordprnt.o):
Do not depend on cord target (folder); add "mkdir cord" (ignoring
errors) before moving .o file to "cord" folder.
Ivan Maidanski [Thu, 8 Feb 2018 08:41:45 +0000 (11:41 +0300)]
Change type of hb_sz field (of hblkhdr) from size_t to word
This is needed to make the size of hb_sz to be the same as of AO_t.
* allchblk.c [USE_MUNMAP] (GC_unmap_old): Cast hhdr->hb_sz to size_t
when passed to GC_unmap().
* allchblk.c (GC_allochblk_nth): Cast hhdr->hb_sz to signed_word when
assigned to size_avail.
* allchblk.c [USE_MUNMAP] (GC_allochblk_nth): Cast hhdr->hb_sz to
size_t when passed to GC_remap().
* alloc.c (GC_set_fl_marks, GC_clear_fl_marks): Change type of sz and
bit_no local variables from size_t/unsigned to word.
* dbg_mlc.c (GC_check_heap_block): Likewise.
* backgraph.c [MAKE_BACK_GRAPH] (per_object_helper): Cast hhdr->hb_sz
to size_t; change type of i local variables from int to size_t.
* checksums.c [CHECKSUMS] (GC_on_free_list): Change type of sz local
variable from size_t to word.
* mark.c (GC_push_marked, GC_push_unconditionally, GC_block_was_dirty):
Likewise.
* reclaim.c (GC_reclaim_small_nonempty_block,
GC_disclaim_and_reclaim_or_free_small_block, GC_reclaim_block,
GC_n_set_marks): Likewise.
* checksums.c [CHECKSUMS] (GC_add_block): Remove bytes local variable
(to avoid casting of hhdr->hb_sz).
* dbg_mlc.c (GC_debug_free): Change type of i and obj_sz local
variables from size_t to word.
* dbg_mlc.c (GC_check_leaked): Likewise.
* extra/pcr_interface.c (GC_enumerate_block): Change type of sz local
variable from int to size_t.
* extra/pcr_interface.c (GC_enumerate_block): Cast hhdr->hb_sz to
size_t when assigned to sz.
* mallocx.c (GC_realloc): Likewise.
* mark.c (GC_set_hdr_marks): Likewise.
* reclaim.c (GC_do_enumerate_reachable_objects): Likewise.
* include/private/gc_pmark.h [MARK_BIT_PER_OBJ] (PUSH_CONTENTS_HDR):
Cast hhdr->hb_sz to size_t in assignment of obj_displ.
* include/private/gc_priv.h (struct hblkhdr): Change type of hb_sz from
size_t to word.
* include/private/gc_priv.h (MARK_BIT_NO): Cast offset argument to word
instead of unsigned.
* malloc.c (GC_free): Cast hhdr->hb_sz to size_t.
* mallocx.c (GC_get_kind_and_size): Likewise.
* mark.c (GC_clear_hdr_marks): Likewise.
* misc.c (GC_size): Likewise.
* misc.c (GC_do_blocking): Remove redundant cast of hhdr->hb_sz.
* reclaim.c (GC_reclaim_clear, GC_reclaim_uninit,
GC_disclaim_and_reclaim, GC_continue_reclaim): Change type of sz
argument from size_t to word.
* typd_mlc.c (GC_array_mark_proc): Change type of sz and nwords local
variables from size_t to word.
Ivan Maidanski [Thu, 8 Feb 2018 06:57:23 +0000 (09:57 +0300)]
Convert cord tests to valid C++ code
Issue #201 (bdwgc).
* cord/tests/de.c (main): Cast buf to char* when passed to setvbuf().
* cord/tests/de_win.c (de_error): Change "char*" to "const char*" for
the argument (because ISO C++ forbids converting a string constant to
char*).
* cord/tests/de_win.h (de_error): Likewise.
* cord/tests/de_win.c (WinMain): Change type of hAccel local variable
from HANDLE to HACCEL; cast GetStockObject(WHITE_BRUSH) result to
HBRUSH type.
* cord/tests/de_win.c (plain_chars, control_chars): Cast
GC_MALLOC_ATOMIC() result to char*.
* cord/tests/de_win.c (WndProc): Change type of hInstance static
variable from HANDLE to HINSTANCE.
Jay Krell [Wed, 7 Feb 2018 22:36:49 +0000 (01:36 +0300)]
Put variable/function declarations into extern 'C' in headers
Issue #201 (bdwgc).
Extern "C" should be only around declarations, not includes.
In particular, do not include 3rd-party headers (as well as our own
files as they could include others).
* include/gc.h [GC_PTHREADS]: Do not wrap include gc_pthread_redirects.h
into extern "C" block.
* include/gc_disclaim.h: Wrap variable and function declarations (but
not included headers).
* include/gc_inline.h: Likewise.
* include/gc_pthread_redirects.h [!GC_PTHREAD_REDIRECTS_ONLY]: Likewise.
* include/private/darwin_semaphore.h: Likewise.
* include/private/darwin_stop_world.h: Likewise.
* include/private/dbg_mlc.h: Likewise.
* include/private/gc_atomic_ops.h [GC_BUILTIN_ATOMIC]: Likewise.
* include/private/gc_hdrs.h: Likewise.
* include/private/gc_locks.h [THREADS]: Likewise.
* include/private/gc_pmark.h: Likewise.
* include/private/gc_priv.h: Likewise.
* include/private/gcconfig.h: Likewise.
* include/private/pthread_stop_world.h: Likewise.
* include/private/pthread_support.h [GC_PTHREADS && !GC_WIN32_THREADS]:
Likewise.
* include/private/specific.h: Likewise.
* include/private/thread_local_alloc.h [THREAD_LOCAL_ALLOC]: Likewise.
Jay Krell [Sun, 4 Feb 2018 08:35:26 +0000 (03:35 -0500)]
Convert tests to valid C++ code
Issue #201 (bdwgc).
* tests/leak_test.c (main): Add explicit casts of void* pointer
(returned by malloc) to the types of the variables the relevant
pointers are assigned to.
* tests/realloc_test.c (main): Likewise.
* tests/smash_test.c (main): Likewise.
* tests/test.c (run_one_test): Likewise.
* tests/test.c (typed_test): Rename "new" local variable to "newP".
Implement FindTopOfStack(0) for ARM and AArch64 (Darwin)
(part of commit 9379c66 from Unity-Technologies/bdwgc)
Issue #173 (bdwgc).
* darwin_stop_world.c [!DARWIN_DONT_PARSE_STACK && (ARM32 || AARCH64)]
(GC_FindTopOfStack): Set proper frame value (using asm instruction)
if stack_start is zero (instead of ABORT).
Ivan Maidanski [Fri, 2 Feb 2018 08:32:10 +0000 (11:32 +0300)]
Always fail if FindTopOfStack(0) is not implemented but called (Darwin)
* darwin_stop_world.c [!DARWIN_DONT_PARSE_STACK] (GC_FindTopOfStack):
Initialize frame local variable first (to stack_start).
* darwin_stop_world.c [!DARWIN_DONT_PARSE_STACK && !POWERPC]
(GC_FindTopOfStack): Call ABORT with the appropriate message (instead
of GC_ASSERT) if stack_start iz zero.
Ivan Maidanski [Thu, 1 Feb 2018 22:21:57 +0000 (01:21 +0300)]
Define ABORT() using _CrtDbgBreak (if available) on Windows host
Issue #173 (bdwgc).
* include/private/gc_priv.h [!CPPCHECK && !PCR && !NO_DEBUGGING
&& (MSWIN32 || MSWINCE)] (ABORT): Use _CrtDbgBreak() instead of
DebugBreak() if _CrtDbgBreak, _DEBUG and _MSC_VER macros are defined.
New macro ALWAYS_SMALL_CLEAR_STACK to avoid clearing large stack sections
(a cherry-pick of commit 95f5767 from Unity-Technologies/bdwgc)
Issue #173 (bdwgc).
Avoid clearing large sections of the stack. It was clearing
up to 16k which may not be available in cases of small stacks or stack
overflow situations (for some targets).
* misc.c [ALWAYS_SMALL_CLEAR_STACK] (GC_clear_stack): Do only BZERO for
dummy where dummy is a local array of length SMALL_CLEAR_SIZE.
Ivan Maidanski [Wed, 31 Jan 2018 08:11:31 +0000 (11:11 +0300)]
Do not define clear_stack_inner and next_random_no if not used
(code refactoring of commits 4eaea0afa, b850e1c9b)
* misc.c (SMALL_CLEAR_SIZE): Do not define if already defined; define
even if THREADS is not defined.
* misc.c [STACK_NOT_SCANNED] (GC_clear_stack): Standalone definition
(just return arg).
* misc.c (BIG_CLEAR_SIZE, GC_stack_last_cleared, GC_min_sp,
GC_high_water, GC_bytes_allocd_at_reset, DEGRADE_RATE,
GC_clear_stack_inner, next_random_no): Do not define if
STACK_NOT_SCANNED.
* misc.c [!STACK_NOT_SCANNED] (CLEAR_SIZE): Do not define if
ASM_CLEAR_CODE.
* misc.c (GC_stack_last_cleared, GC_min_sp, GC_high_water,
GC_bytes_allocd_at_reset, GC_clear_stack_inner, next_random_no,
GC_clear_stack): Adjust indentation.
Gustavo Giraldez [Thu, 18 Jan 2018 21:52:25 +0000 (00:52 +0300)]
Fix GC allocation mutex in child after a fork
Even though after a fork the child only inherits the single thread
that called the fork(), if another thread in the parent was attempting
to lock the mutex while being held in fork_child_prepare(), the mutex
will be left in an inconsistent state in the child after the UNLOCK().
This is the case, at least, in Mac OS X and leads to an unusable GC in
the child which will block when attempting to perform any GC operation
that acquires the mutex.
* pthread_support.c [CAN_HANDLE_FORK && USE_PTHREAD_LOCKS]
(fork_child_proc): Add assertion (after UNLOCK) that the lock is not
held actually, and, then, re-initialize GC_allocate_ml; add comments.
Ivan Maidanski [Wed, 17 Jan 2018 07:42:04 +0000 (10:42 +0300)]
Add note of set_free_space_divisor, set_warn_proc ABI change after gc-7.1
Issue #197 (bdwgc).
GC_set_free_space_divisor() and GC_set_warn_proc() used to return
some value. But starting from version 7.1alpha2, these API functions
do not return any value.
* include/gc.h (GC_set_free_space_divisor, GC_set_warn_proc): Add
comment that the setter used to returned the old value in gc-7.1 (and
previous versions).
Ivan Maidanski [Mon, 15 Jan 2018 05:20:02 +0000 (08:20 +0300)]
Fix global operator delete definition for C++14 in gc_cpp
Issue #195 (bdwgc).
Sized variants of global operator delete should be defined along with
the non-sized ones. Otherwise compiler might invoke the one from the
standard library (as observed in e.g. Cygwin) leading to a crash.
* gc_cpp.cc [!_MSC_VER && __cplusplus>201103L] (operator delete):
Define sized variant (the size argument is ignored for now).
* gc_cpp.cc [!_MSC_VER && __cplusplus>201103L && GC_OPERATOR_NEW_ARRAY
&& !CPPCHECK] (operator delete[]): Likewise.
Ivan Maidanski [Sun, 14 Jan 2018 07:51:06 +0000 (10:51 +0300)]
Fix last_reclaimed..gc_no interval comparison to threshold in unmap_old
(fix commit 14c324f8b)
* allchblk.c [USE_MUNMAP] (GC_unmap_old): Replace
(unsigned short)GC_gc_no-hb_last_reclaimed to
(unsigned short)(GC_gc_no-hb_last_reclaimed) to handle
value wrapping in hb_last_reclaimed (and the truncated GC_gc_no)
correctly.
Peter Wang [Fri, 12 Jan 2018 16:50:47 +0000 (19:50 +0300)]
Remove obsolete advice about linking with _DYNAMIC=0 (Linux)
Issue #196 (bdwgc).
The mentioned GCC option is not needed since gc-5.0alpha3 (when
_DYNAMIC symbol was declared as weak in dyn_load.c).
Even more, the advice is problematic for Alpine Linux (and probably
other systems using musl) as building a program with gcc -static
produces a binary containing a _DYNAMIC symbol with a non-zero address,
and forcing the address to 0 causes a crash during GC initialization.
* doc/README.linux: Remove note that static executable should be
linked with the gcc option "-Wl,-defsym,_DYNAMIC=0".
Ivan Maidanski [Thu, 11 Jan 2018 23:57:32 +0000 (02:57 +0300)]
Add check that gc_cpp operator delete is called (test_cpp)
Issue #195 (bdwgc).
* tests/test_cpp.cc (GC_CHECKED_DELETE): New macro.
* tests/test_cpp.cc (main): Use GC_CHECKED_DELETE() instead of operator
delete (where it is expected that the operator defined in gc_cpp.c/h
is called).
Ivan Maidanski [Thu, 11 Jan 2018 22:08:37 +0000 (01:08 +0300)]
New field (expl_freed_bytes_since_gc) in public prof_stats_s
* include/gc.h (GC_prof_stats_s): Add expl_freed_bytes_since_gc field
(to the end of the structure).
* misc.c [!GC_GET_HEAP_USAGE_NOT_NEEDED] (fill_prof_stats): Store
GC_bytes_freed value to pstats->expl_freed_bytes_since_gc.
Ivan Maidanski [Thu, 11 Jan 2018 21:56:36 +0000 (00:56 +0300)]
New API function (get_expl_freed_bytes_since_gc)
Note: this function could be used in test_cpp to check that the proper
operator delete is called.
* include/gc.h (GC_get_expl_freed_bytes_since_gc): New function
prototype.
* mallocx.c (GC_get_expl_freed_bytes_since_gc): New function definition
(which returns GC_bytes_freed).
Ivan Maidanski [Thu, 28 Dec 2017 08:18:25 +0000 (11:18 +0300)]
Do not call sem_getvalue in stop_world if one thread exists
* pthread_stop_world.c [!GC_OPENBSD_UTHREADS && !NACL] (GC_stop_world):
Do not call sem_getvalue() if n_live_threads is zero (matters only if
GC_retry_signals).
Ivan Maidanski [Wed, 27 Dec 2017 08:09:48 +0000 (11:09 +0300)]
Fix error code in abort message if sem_wait failed in start_world (NetBSD)
* pthread_stop_world.c [GC_NETBSD_THREADS_WORKAROUND] (GC_start_world):
Print errno instead of the value returned by sem_wait if the latter has
failed; remove "code" local variable.
Ivan Maidanski [Fri, 15 Dec 2017 07:15:05 +0000 (10:15 +0300)]
Workaround TSan hang in free_inner when called from at-fork child handler
* pthread_support.c [CAN_HANDLE_FORK] (GC_remove_all_threads_but_me):
Do not call GC_INTERNAL_FREE(p) if THREAD_SANITIZER and CAN_CALL_ATFORK;
add comment.
Ivan Maidanski [Thu, 14 Dec 2017 07:24:34 +0000 (10:24 +0300)]
Workaround TSan false positive in remove_all_threads_but_me
* pthread_support.c [CAN_HANDLE_FORK] (store_to_threads_table): New
static function (defined with GC_ATTR_NO_SANITIZE_THREAD attribute
if CAN_CALL_ATFORK); add comment.
* pthread_support.c [CAN_CALL_ATFORK] (GC_remove_all_threads_but_me):
Call store_to_threads_table instead of GC_threads[hv]=me.