Erik M. Bray [Tue, 17 Oct 2017 08:50:03 +0000 (11:50 +0300)]
Use mprotect instead of mmap in GC_unmap() on Cygwin
Issue #187 (BDWGC).
* configure.ac [$enable_munmap!="" && $enable_munmap!=no]
(USE_WINALLOC): Replace AC_DEFINE with AH_TEMPLATE; remove comment
about a workaround for Cygwin; remove "if $host=*-*-cygwin*".
* os_dep.c [CYGWIN32 && USE_MUNMAP] (GC_setpagesize): Set GC_page_size
to dwAllocationGranularity (instead of dwPageSize); add comment; add
assertion that dwAllocationGranularity is not less than dwPageSize.
* os_dep.c [USE_MUNMAP && CYGWIN32 && !USE_WINALLOC] (GC_unmap,
GC_unmap_gap): Call mprotect() instead of mmap(); add comment.
Ivan Maidanski [Mon, 16 Oct 2017 21:02:27 +0000 (00:02 +0300)]
Fix 'package requirements (atomic_ops) were not met' configure error
(fix commit 3d34335)
* configure.ac [$missing_libatomic_ops] (PKG_CHECK_MODULES):
Pass no-op to action-if-not-found parameter (because the default
action-if-not-found ends the execution with an error in case of the
missing dependency).
Ivan Maidanski [Mon, 16 Oct 2017 08:00:53 +0000 (11:00 +0300)]
Allow PKG_CHECK_MODULES in configure.ac to be commented out easily
(code refactoring)
* configure.ac [$with_libatomic_ops!=no && $with_libatomic_ops!=none]
(missing_libatomic_ops): Set to true (before PKG_CHECK_MODULES).
* configure.ac [$missing_libatomic_ops] (PKG_CHECK_MODULES): Set
missing_libatomic_ops back to false if atomic_ops module is not found;
add comment (about pkg-config and the possibility to comment out
PKG_CHECK_MODULES).
Ivan Maidanski [Mon, 16 Oct 2017 07:25:57 +0000 (10:25 +0300)]
New API function (GC_is_init_called) to check if BDWGC is initialized
Issue #186 (bdwgc).
* include/gc.h (GC_is_init_called): New API function declaration.
* misc.c (GC_is_init_called): New API function definition.
* tests/test.c (check_heap_stats): Add a test that GC is initialized.
Ivan Maidanski [Mon, 9 Oct 2017 19:07:24 +0000 (22:07 +0300)]
Eliminate TSan warnings for all counters and A.aa variable (gctest)
Now most of the counters in gctest are updated using atomic increment.
And, the values of gctest dropped_something and A.aa variables are
updated and fetch using the atomic primitives.
* tests/test.c [!AO_CLEAR] (AO_t): Define.
* tests/test.c [!AO_HAVE_load] (AO_load): Define (as a non-atomic
operation).
* tests/test.c [!AO_HAVE_store] (AO_store): Likewise.
* tests/test.c [!AO_HAVE_fetch_and_add1] (AO_fetch_and_add1): Likewise.
* tests/test.c (stubborn_count, uncollectable_count,
collectable_count, atomic_count, realloc_count): Change type from int
to AO_t; add volatile qualifier; update comment; remove FIXME.
* tests/test.c (extra_count): Define unconditionally; change type from
int to AO_t; add volatile qualifier; update comment.
* tests/test.c [!VERY_SMALL_CONFIG] (cons): Use AO_fetch_and_add1 to
get and update the values of extra_count and stubborn_count.
* tests/test.c (small_cons_uncollectable): Use AO_fetch_and_add1 to
update the value of uncollectable_count.
* tests/test.c [!DBG_HDRS_ALL] (run_one_test): Likewise.
* tests/test.c [GC_GCJ_SUPPORT] (gcj_cons): Remove obj_cnt static
variable; use extra_count instead of obj_cnt; use AO_fetch_and_add1 to
get and update the value of extra_count.
* tests/test.c (A): Add volatile qualifier; change the type of aa
field from sexpr to AO_t.
* tests/test.c (a): Do not define (and undefine).
* tests/test.c (a_set, a_get): New macro (that uses AO_store/load).
* tests/test.c (reverse_test_inner): Use a_set() and a_get() to store
and fetch the value of a, respectively; use AO_fetch_and_add1 to
update the value of realloc_count.
* tests/test.c (dropped_something): Change type from int to AO_t.
* tests/test.c (counter): Remove.
* tests/test.c (mktree): Use extra_count instead of counter; use
AO_fetch_and_add1 to update the value of extra_count.
* tests/test.c [GC_PTHREADS && !SMALL_CONFIG && !GC_DEBUG]
(alloc8bytes): Use AO_fetch_and_add1 to update the value of
uncollectable_count.
* tests/test.c (alloc_small, run_one_test): Use AO_fetch_and_add1 to
update the value of atomic_count.
* tests/test.c (tree_test): Use AO_load and AO_store to get and set
the value of dropped_something, respectively.
* tests/test.c (check_heap_stats): Cast uncollectable_count,
atomic_count, stubborn_count, realloc_count to int in printf() call.
Ivan Maidanski [Fri, 6 Oct 2017 08:14:23 +0000 (11:14 +0300)]
Eliminate TSan warnings for print_proc variables assignment (gctest)
Now GC_is_valid_displacement_print_proc and GC_is_visible_print_proc
are set only once (before the first invocation of run_one_test).
* tests/test.c [DBG_HDRS_ALL] (set_print_procs): New macro (defined
to (void)0).
* tests/test.c [!DBG_HDRS_ALL] (set_print_procs): New function (which
sets GC_is_valid_displacement_print_proc and GC_is_visible_print_proc).
* tests/test.c (fail_count, fail_proc1, TEST_FAIL_COUNT): Do not
define if DBG_HDRS_ALL.
* tests/test.c [!DBG_HDRS_ALL] (run_one_test): Do not set
GC_is_valid_displacement_print_proc and GC_is_visible_print_proc.
* tests/test.c (main): Call set_print_procs() before run_one_test().
* tests/test.c [PCR] (test): Likewise.
Ivan Maidanski [Wed, 27 Sep 2017 23:06:31 +0000 (02:06 +0300)]
Support GC_init (and get_stack_base) from non-main thread on FreeBSD
Issue #180 (bdwgc).
Now GC_get_[main_]stack_base uses pthread_attr_get_np() and
pthread_attr_getstack() to determine the stack base address.
* os_dep.c [FREEBSD && !NO_PTHREAD_ATTR_GET_NP && (THREADS
|| USE_GET_STACKBASE_FOR_MAIN)]: Include pthread.h and pthread_np.h.
* os_dep.c [FREEBSD && !NO_PTHREAD_ATTR_GET_NP
&& (USE_GET_STACKBASE_FOR_MAIN || THREADS && !REDIRECT_MALLOC)]
(GC_get_main_stack_base): Call pthread_attr_init, pthread_attr_get_np
and pthread_attr_getstack to determine the stack base address of the
current thread (fall back to GC_freebsd_main_stack_base in case of
failure).
* os_dep.c [(GC_FREEBSD_THREADS && !NO_PTHREAD_ATTR_GET_NP]
(GC_get_stack_base): Call pthread_attr_init, pthread_attr_get_np and
pthread_attr_getstack to determine the stack base address of the
current thread.
Ivan Maidanski [Wed, 27 Sep 2017 22:46:20 +0000 (01:46 +0300)]
Fix data race in collectable_count (gctest)
* tests/test.c [THREADS && (GC_BUILTIN_ATOMIC || PARALLEL_MARK
|| !GC_WIN32_THREADS)]: Include gc_atomic_ops.h.
* tests/test.c [AO_HAVE_fetch_and_add1] (collectable_count): Change
type to volatile AO_t (and make it static to initalize it without "=0").
* tests/test.c [!AO_HAVE_fetch_and_add1] (AO_fetch_and_add1): Define
to a non-atomic increment (for a single-threaded build).
* tests/test.c (small_cons, reverse_test_inner, mktree, chktree,
alloc8bytes, typed_test, run_one_test): Use
AO_fetch_and_add1(&collectable_count) instead of collectable_count++.
* tests/test.c (check_heap_stats): Cast collectable_count to int in
GC_printf() call.
Ivan Maidanski [Wed, 27 Sep 2017 08:22:18 +0000 (11:22 +0300)]
Eliminate 'non-null arg compared to null' warning in toggleref_add (GCC)
(fix commit 86991cb)
* finalize.c [!GC_TOGGLE_REFS_NOT_NEEDED] (GC_toggleref_add): Use
NONNULL_ARG_NOT_NULL to check pointer argument marked as non-null (in
the function declaration) is actually non-null.
Ivan Maidanski [Wed, 27 Sep 2017 07:52:09 +0000 (10:52 +0300)]
Fix pthread_detach for threads not yet registered (Cygwin, winpthreads)
* win32_threads.c [GC_PTHREADS] (GC_pthread_detach): Repeat
GC_lookup_pthread() (with a 10 msec delay) while t is null; add comment
and TODO; remove ABORT if t is null (as t is never null after
pthread_detach call).
Ivan Maidanski [Tue, 26 Sep 2017 21:56:14 +0000 (00:56 +0300)]
Fix get_maps on proc maps file asynchronous growth
Issue #179 (bdwgc).
Asynchronous growth of /proc/self/maps could be caused by some thread
which is not currently registered (e.g. stack allocation on thread
creation or a non-GC heap allocation from an unregistered thread).
Ivan Maidanski [Tue, 26 Sep 2017 08:44:44 +0000 (11:44 +0300)]
Fix pthread_join when thread is registered in thread key destructor
* pthread_support.c (WRAP_FUNC(pthread_join)): Remove assertion that
thread is finished; call GC_delete_gc_thread only if thread is
finished; add comment.
* win32_threads.c [GC_PTHREADS] (GC_pthread_join): Call
GC_delete_gc_thread_no_free and GC_INTERNAL_FREE only if thread is
finished.
Ivan Maidanski [Tue, 26 Sep 2017 08:29:54 +0000 (11:29 +0300)]
Fix pthread_join to avoid thread removal on failure (Cygwin, winpthreads)
* win32_threads.c [GC_WIN32_PTHREADS] (GC_pthread_join): Do not call
GC_lookup_pthread if pthread_join failed.
* win32_threads.c [GC_PTHREADS] (GC_pthread_join): Do not call
GC_delete_gc_thread_no_free, GC_INTERNAL_FREE if pthread_join failed.
* win32_threads.c [GC_PTHREADS && DEBUG_THREADS] (GC_pthread_join):
Log whether pthread_join succeeded or failed.
Ivan Maidanski [Tue, 26 Sep 2017 08:01:29 +0000 (11:01 +0300)]
Fix removal of dead threads in a child process
GC_threads table may contain several elements with the same pthread id,
so GC_remove_all_threads_but_me should remove all elements except for
the first found element matching the id of the current thread.
* pthread_support.c [CAN_HANDLE_FORK] (GC_remove_all_threads_but_me):
Do not assign me if it is already non-null; add comment.
* win32_threads.c [CAN_HANDLE_FORK] (GC_remove_all_threads_but_me):
Likewise.
* win32_threads.c [CAN_HANDLE_FORK] (GC_remove_all_threads_but_me):
Remove GC_ASSERT(me==NULL).
Ivan Maidanski [Mon, 25 Sep 2017 21:52:49 +0000 (00:52 +0300)]
Do not disable parallel mark for WRAP_MARK_SOME
Issue #179 (bdwgc).
Now, if there is a chance of unmapping of root segments, the latter
ones are scanned immediately by GC_push_roots thus preventing memory
protection faults in GC_mark_local.
* include/private/gc_priv.h (GC_PUSH_CONDITIONAL): Move definition to
mark_rts.c.
* include/private/gcconfig.h [WRAP_MARK_SOME && PARALLEL_MARK]
(PARALLEL_MARK): Do not undefine; remove TODO item.
* mark.c [WRAP_MARK_SOME && PARALLEL_MARK] (GC_push_conditional_eager):
New internal function; add TODO item.
* mark_rts.c [WRAP_MARK_SOME && PARALLEL_MARK]
(GC_push_conditional_eager): Declare function.
* mark_rts.c [WRAP_MARK_SOME && PARALLEL_MARK] (GC_PUSH_CONDITIONAL):
Define to GC_push_conditional_eager if GC_parallel.
Ivan Maidanski [Fri, 22 Sep 2017 18:37:42 +0000 (21:37 +0300)]
Align local_mark_stack in help_marker explicitly
* mark.c [PARALLEL_MARK] (GC_help_marker): Declare my_id_mse local
variable (of mse type) instead of unsigned my_id; define my_id as
macro to my_id_mse.mse_descr.w; cast my_id to unsigned or int in
GC_helper_count assignment and GC_mark_local() call.
Ivan Maidanski [Tue, 19 Sep 2017 07:51:24 +0000 (10:51 +0300)]
Fix infinite mark_some calls after memory mapping disappeared (Glibc)
Issue #179 (bdwgc).
* mark.c [WRAP_MARK_SOME && REGISTER_LIBRARIES_EARLY] (GC_mark_some):
Call GC_cond_register_dynamic_libraries (with the world running)
before GC_invalidate_mark_state().
Ivan Maidanski [Tue, 19 Sep 2017 07:38:39 +0000 (10:38 +0300)]
Fix 'undefined reference to GC_wait_for_reclaim' linker error
(fix commit f4d690e)
Issue #179 (bdwgc).
* include/private/gc_pmark.h [HAVE_CONFIG_H]: Do not include config.h
if already included from gc_priv.h (to avoid PARALLEL_MARK macro
redefinition in config.h after it was undefined in gcconfig.h).
Ivan Maidanski [Tue, 19 Sep 2017 07:08:38 +0000 (10:08 +0300)]
Add TODO item to suppress 'called on pointer without debugging info'
* dbg_mlc.c [REDIRECT_FREE && USE_PROC_FOR_LIBRARIES] (GC_debug_free):
Add TODO item not to call GC_err_printf() when free() is called from
libpthread or libdl.
Ivan Maidanski [Mon, 18 Sep 2017 07:54:37 +0000 (10:54 +0300)]
Fix SIGSEGV in mark_from called from do_local_mark if WRAP_MARK_SOME
Issue #179 (bdwgc).
Parallel marker is disabled (for now) if there is a chance of
scanning unmapped data roots (because GC_do_local_mark is not
prepared to deal with memory protection faults gracefully).
Ivan Maidanski [Wed, 30 Aug 2017 07:00:46 +0000 (10:00 +0300)]
Remove unnecessary type casts of printf arguments to unsigned long
(code refactoring)
* alloc.c [!NO_DEBUGGING] (GC_print_heap_sects): Remove unnecessary
cast to unsigned long in GC_*_printf call and adjust printf format
specifier to match the argument type.
* checksums.c [CHECKSUMS] (GC_checksum): Likewise.
* mark.c [PARALLEL_MARK] (GC_mark_local): Likewise.
* tests/test.c (typed_test): Likewise.
* checksums.c [CHECKSUMS] (GC_checksum): Change type of GC_n_clean,
GC_n_dirty from int to unsigned long.
Ivan Maidanski [Mon, 28 Aug 2017 06:27:07 +0000 (09:27 +0300)]
Fix GC_remove_specific invocation from remove_all_threads_but_me
(fix commits fcfae7f, 38e65ea)
* include/private/specific.h (GC_remove_specific): Define as macro
(calls GC_remove_specific_after_fork).
* include/private/specific.h (GC_remove_specific_after_fork): New
GC_INNER function declaration.
* include/private/thread_local_alloc.h [USE_PTHREAD_SPECIFIC
|| USE_COMPILER_TLS || USE_WIN32_COMPILER_TLS || USE_WIN32_SPECIFIC]
(GC_remove_specific_after_fork): New macro (defined to no-op).
* pthread_support.c [CAN_HANDLE_FORK && THREAD_LOCAL_ALLOC]
(GC_remove_all_threads_but_me): Call GC_remove_specific_after_fork
instead of GC_remove_specific (i.e. delete thread-specific control data
for the given thread instead of the current one).
* win32_threads.c [CAN_HANDLE_FORK && THREAD_LOCAL_ALLOC] Like
* specific.c [USE_CUSTOM_SPECIFIC] (GC_setspecific): Add assertion that
the allocation lock is held; remove the corresponding comment.
* specific.c [USE_CUSTOM_SPECIFIC] (GC_remove_specific): Replace to
GC_remove_specific_after_fork (add t argument); replace self local
variable with t argument; update comment;
* specific.c [USE_CUSTOM_SPECIFIC && CAN_HANDLE_FORK]
(GC_remove_specific_after_fork): Add assertion that the allocation lock
is held; add comment.
Ivan Maidanski [Thu, 24 Aug 2017 22:05:16 +0000 (01:05 +0300)]
Add debug logging to new_thread about GC_threads hash table collisions
* pthread_support.c [DEBUG_THREADS] (GC_new_thread): Call GC_log_printf
(with the appropriate message) if a GC_threads[] entry already exists
at the given hv index (excluding the detached threads those id is
already reused).
* win32_threads.c [DEBUG_THREADS] (GC_new_thread): Call GC_log_printf
to report that a new thread is created; call GC_log_printf (with the
appropriate message) if a GC_threads[] entry already exists at the
given hv index; remove useless comment about the result of
GC_INTERNAL_MALLOC.
Ivan Maidanski [Thu, 24 Aug 2017 08:34:05 +0000 (11:34 +0300)]
Eliminate most of collisions in GC_threads on Linux/x64
On some targets (e.g., Linux/x64) pthread_t values always have zero
in the lowest byte (e.g. if pthread_t is actually a page-aligned
pointer) thus causing all the created thread descriptors to have
a collision at GC_threads[0]. This commit mixes 3 lowest bytes
of thread id with a XOR operation (thus greatly reduces the
probability of collisions in GC_threads).
* include/private/pthread_support.h (THREAD_TABLE_SZ): Do not
define if already defined; refine comment.
* pthread_support.c (THREAD_TABLE_INDEX): New macro (similar to that
in win32_threads.c).
* pthread_support.c (GC_new_thread, GC_delete_thread,
GC_delete_gc_thread, GC_lookup_thread): Replace
NUMERIC_THREAD_ID(id)%THREAD_TABLE_SZ to THREAD_TABLE_INDEX(id).
* pthread_support.c (GC_lookup_thread): Remove hv local variable.
* win32_threads.c (THREAD_TABLE_INDEX): Replace (id>>2) to
((id>>16)^(id>>8)^id).
* win32_threads.c [GC_PTHREADS] (GC_lookup_pthread): Define win32_id
local variable to pass it to THREAD_TABLE_INDEX() instead of passing
GET_PTHREAD_MAP_CACHE(id) directly.
Ivan Maidanski [Wed, 23 Aug 2017 08:46:41 +0000 (11:46 +0300)]
Change type of THREAD_TABLE_INDEX result to int in win32_threads.c
(code refactoring)
* win32_threads.c (THREAD_TABLE_INDEX): Cast result to int; remove cast
of argument to word type; add comment.
* win32_threads.c (GC_new_thread, GC_delete_gc_thread_no_free,
GC_delete_thread): Change type of hv local variable from word to int.
* win32_threads.c (GC_lookup_thread_inner): Remove hv local variable;
remove "register" keyword for p local variable.
* win32_threads.c (GC_lookup_pthread): Change type of hv_guess local
variable from word to int.
Ivan Maidanski [Tue, 22 Aug 2017 08:23:27 +0000 (11:23 +0300)]
Fix deadlock in GC_help_marker caused by use of mark_cv of parent process
The marker threads of the parent process are blocked on mark_cv at
fork. So pthread_cond_wait() malfunction (hang) is possible in the
child process without mark_cv state cleanup (reinitialization).
* pthread_support.c [PARALLEL_MARK] (mark_cv): Move static variable
definition upper to be before GC_start_mark_threads_inner).
* win32_threads.c [GC_PTHREADS_PARAMARK] (mark_cv): Likewise.
* pthread_support.c [PARALLEL_MARK && CAN_HANDLE_FORK] (mark_cv):
Do not initialize statically; add comment.
* win32_threads.c [GC_PTHREADS_PARAMARK && CAN_HANDLE_FORK] (mark_cv):
Likewise.
* pthread_support.c [PARALLEL_MARK && CAN_HANDLE_FORK]
(GC_start_mark_threads_inner): Initialize mark_cv to
PTHREAD_COND_INITIALIZER (unless available_markers_m1 <= 0 or
GC_parallel); add comment.
* win32_threads.c [GC_PTHREADS_PARAMARK && CAN_HANDLE_FORK]
(GC_start_mark_threads_inner): Likewise.
* pthread_support.c [PARALLEL_MARK] (GC_wait_marker,
GC_notify_all_marker): Add assertion that GC_parallel is true (so
mark_cv is initialized).
* win32_threads.c [GC_PTHREADS_PARAMARK] (GC_wait_marker,
GC_notify_all_marker): Likewise.
Ivan Maidanski [Tue, 22 Aug 2017 05:56:31 +0000 (08:56 +0300)]
Avoid busy waiting in mark_thread while GC_parallel is false
* mark.c [PARALLEL_MARK] (GC_help_marker): Add assertion that
GC_parallel is true (i.e. GC_markers_m1 is non-zero).
* pthread_support.c [PARALLEL_MARK && CAN_HANDLE_FORK]
(GC_start_mark_threads_inner): Set GC_markers_m1 value before starting
the first marker thread (it is already set if fork handling is off).
* win32_threads.c [GC_PTHREADS_PARAMARK && CAN_HANDLE_FORK]
(GC_start_mark_threads_inner): Likewise.
* pthread_support.c [PARALLEL_MARK] (GC_start_mark_threads_inner):
Adjust GC_markers_m1 value only if pthread_create failed.
* win32_threads.c [GC_PTHREADS_PARAMARK] (GC_start_mark_threads_inner):
Likewise.
Ivan Maidanski [Mon, 21 Aug 2017 22:09:59 +0000 (01:09 +0300)]
Eliminate unsigned fl_builder_count underflow in mark_thread
(refactor commit 0ca6d3f)
* include/private/gc_priv.h [PARALLEL_MARK] (GC_fl_builder_count):
Change type from word to signed_word.
* reclaim.c [PARALLEL_MARK] (GC_fl_builder_count): Likewise.
* mark.c [PARALLEL_MARK] (GC_wait_for_markers_init): Change type of
count local variable to signed_word; add assertion that count is
non-negative.
* pthread_support.c [PARALLEL_MARK] (GC_mark_thread): Add comment that
GC_fl_builder_count can be negative here.
* win32_threads.c [PARALLEL_MARK] (GC_mark_thread): Likewise.
* reclaim.c [PARALLEL_MARK] (GC_fl_builder_count): Refine comment.
Ivan Maidanski [Wed, 16 Aug 2017 22:39:16 +0000 (01:39 +0300)]
Fix visibility of __asan_default_options in case of shared library
(fix commit ce75cf1)
* os_dep.c [ADDRESS_SANITIZER && (UNIX_LIKE || NEED_FIND_LIMIT
|| MPROTECT_VDB)] (__asan_default_options): Do not define if
CUSTOM_ASAN_DEF_OPTIONS is defined; export it (use GC_API).
Ivan Maidanski [Wed, 9 Aug 2017 21:47:18 +0000 (00:47 +0300)]
Allow gctest and thread_leak_test with zero NTHREADS
* tests/test.c [GC_PTHREADS || GC_WIN32_THREADS] (reverse_test_inner):
Do not call fork_a_thread() if NTHREADS is 0.
* tests/test.c (MAX_FINALIZED): Increase to be correct for the case of
NTHREADS is 0.
* tests/test.c [GC_PTHREADS] (main): Do not declare and do not use th,
i local variables if NTHREADS is 0.
* tests/thread_leak_test.c (NTHREADS): Do not define if already defined.
* tests/thread_leak_test.c (main): Do not declare and do not use i,
code, t, thread_id local variables if NTHREADS is 0.
Ivan Maidanski [Wed, 9 Aug 2017 08:35:25 +0000 (11:35 +0300)]
Fix array_mark_proc to request global mark stack growth on overflow
(fix commit 3f06655)
* typd_mlc.c [PARALLEL_MARK] (GC_array_mark_proc): Set
GC_mark_stack_too_small to true if GC_push_complex_descriptor()
returned null and mark_stack_limit belongs to the global mark stack
(even if GC_parallel is true).
Ivan Maidanski [Mon, 7 Aug 2017 08:37:30 +0000 (11:37 +0300)]
Fix leak_test crash in print_callers if free() is redirected
* dbg_mlc.c [REDIRECT_MALLOC && (GC_LINUX_THREADS || GC_SOLARIS_THREADS
|| MSWIN32 || NEED_CALLINFO && GC_HAVE_BUILTIN_BACKTRACE)]
(GC_debug_free): If the object is not in the GC heap then just return
(instead of ABORT).
* malloc.c [REDIRECT_MALLOC && NEED_CALLINFO
&& GC_HAVE_BUILTIN_BACKTRACE] (GC_free): If hhdr is null (i.e. the
object is not in the GC heap) then return without the object
deallocation; add comment.
* os_dep.c [NEED_CALLINFO && GC_HAVE_BUILTIN_BACKTRACE
&& !GC_BACKTRACE_SYMBOLS_BROKEN] (GC_print_callers): Adjust comment
for free().
Ivan Maidanski [Wed, 2 Aug 2017 21:37:09 +0000 (00:37 +0300)]
Fix undefined HEAP_START in register_dynamic_libraries
* include/private/gcconfig.h [!HEAP_START] (HEAP_START): Define to 0 by
default (if not previously defined in the file).
* os_dep.c (HEAP_START): Remove.
Ivan Maidanski [Wed, 2 Aug 2017 08:13:23 +0000 (11:13 +0300)]
Fix bytes count passed to add_to_our_memory in backgraph new_back_edges
(fix commit 180b56c)
* backgraph.c [MAKE_BACK_GRAPH] (new_back_edges): Pass bytes_to_get to
GC_add_to_our_memory() (i.e. pass the same number of bytes as passed
to GET_MEM() even in case of MMAP_SUPPORTED).
Ivan Maidanski [Tue, 1 Aug 2017 22:13:37 +0000 (01:13 +0300)]
Use heap-allocated memory for local mark stack of non-marker thread
Issue #159 (bdwgc).
The memory is allocated using GET_MEM to avoid to make sure that
it is not accidentally scanned by the collector.
* include/private/gcconfig.h [!PARALLEL_MARK && THREADS]
(MIN_STACK_SIZE): Do not define.
* include/private/gcconfig.h [PARALLEL_MARK] (MIN_STACK_SIZE): Add
comment.
* mark.c [PARALLEL_MARK] (main_local_mark_stack): New static variable.
* mark.c [PARALLEL_MARK] (GC_wait_for_markers_init): Declare bytes_to_get
local variable; allocate local mark stack (using GET_MEM) and set
main_local_mark_stack (if not yet allocated by the parent process).
* mark [PARALLEL_MARK] (GC_do_parallel_mark): Remove local_mark_stack
huge local variable; use main_local_mark_stack instead of
local_mark_stack.
* pthread_support.c [GC_ASSERTIONS] (WRAP_FUNC(pthread_create)): Use
hard-coded value (65536) instead of MIN_STACK_SIZE in GC_ASSERT.
* tests/test.c [GC_PTHREADS && DEFAULT_STACK_MAYBE_SMALL]
(fork_a_thread): Do not set stack size for the created threads.
* tests/test.c [GC_PTHREADS] (main): Do not check
DEFAULT_STACK_MAYBE_SMALL.
Ivan Maidanski [Fri, 21 Jul 2017 18:42:18 +0000 (21:42 +0300)]
New API function (GC_is_incremental_mode)
* alloc.c (GC_is_incremental_mode): New public function definition.
* include/gc.h (GC_full_freq): Update comment.
* include/gc.h (GC_is_incremental_mode): New public function
declaration.
* tests/test.c [!GC_WIN32_THREADS && !GC_PTHREADS] (main): Print
"Switched to incremental mode" and friend messages only if
GC_is_incremental_mode().
* tests/test.c [!GC_PTHREADS] (main): Likewise.
Ivan Maidanski [Fri, 21 Jul 2017 17:27:12 +0000 (20:27 +0300)]
Fix deadlock in GC_suspend_thread when thread is rebuilding free list
(fix commits 62097c3, 59e2bcf)
* pthread_stop_world.c [GC_ENABLE_SUSPEND_THREAD] (GC_suspend_thread):
Move DISABLE_CANCEL() upper to cover also GC_wait_for_reclaim() and
RAISE_SIGNAL() calls.
* pthread_stop_world.c [GC_ENABLE_SUSPEND_THREAD && PARALLEL_MARK]
(GC_suspend_thread): If GC_parallel then call GC_wait_for_reclaim()
holding the allocation lock before RAISE_SIGNAL() call; add comment.
Ivan Maidanski [Thu, 20 Jul 2017 09:11:22 +0000 (12:11 +0300)]
Do not use tkill (Android)
tkill() has been deprecated in Android. Starting from NDK r11 (which
introduced android-23 API), the call exists only in libc.a (but not
in libc.so). The comment in Bionic says that tkill exists only for
Mono clients (and only for 32-bit targets).
* include/private/gcconfig.h [PLATFORM_ANDROID && CPP_WORDSZ==32]
(USE_TKILL_ON_ANDROID): Do not define if __ANDROID_API__ >= 23; add
comment.
Ivan Maidanski [Thu, 20 Jul 2017 08:39:29 +0000 (11:39 +0300)]
Replace deprecated rewind to fseek in cordxtra
rewind (unlike fseek) does not report whether the operation failed.
* cord/cordxtra.c (CORD_from_file_lazy_inner, CORD_from_file_lazy,
CORD_from_file): Replace rewind(f) to fseek(f, 0l, SEEK_SET) with
error checking; adjust ABORT message in case of fseek and ftell failure.
Ivan Maidanski [Fri, 14 Jul 2017 17:02:44 +0000 (20:02 +0300)]
Refactoring of USE_MMAP/USE_MMAP_ANON pairs definition in gcconfig.h
* include/private/gcconfig.h [POWERPC && (DARWIN || AIX) || NACL
|| I386 && (HURD || DARWIN) || (AARCH64 || ARM32 || X86_64) && DARWIN]
(USE_MMAP): Do not define explicitly (as USE_MMAP_ANON is defined
explicitly).
* include/private/gcconfig.h [NACL] (USE_MMAP_FIXED): Do not undefine
explicitly (as it is not defined by default).
* include/private/gcconfig.h [I386 && NACL] (HEAP_START): Do not define
value for the case of no USE_MMAP (as the latter is always defined).
* include/private/gcconfig.h [USE_MMAP_ANON && !USE_MMAP] (USE_MMAP):
Define.
Ivan Maidanski [Fri, 14 Jul 2017 08:11:13 +0000 (11:11 +0300)]
Fix SIGSEGV in GC_is_marked when gc_cleanup is used in leak-finding mode
Issue #162 (bdwgc).
Now finalizers and disappearing links registration is a no-op in case
of the leak-finding mode.
* finalize.c (GC_register_disappearing_link_inner): Do nothing (return
GC_UNIMPLEMENTED) if GC_find_leak.
* finalize.c (GC_register_finalizer_inner): Do nothing if GC_find_leak.
* include/gc.h (GC_find_leak): More verbose comment.
* include/gc.h (GC_debug_register_finalizer,
GC_general_register_disappearing_link): Document the case of
GC_find_leak.
Ivan Maidanski [Tue, 11 Jul 2017 22:10:42 +0000 (01:10 +0300)]
Fix deadlock in GC_suspend_thread when thread is finished
(fix commits 62097c3, 59e2bcf)
* pthread_stop_world.c [GC_ENABLE_SUSPEND_THREAD] (GC_suspend_thread):
Do not call RAISE_SIGNAL() and sem_wait() if thread has FINISHED flag
set; do not handle ESRCH error result of RAISE_SIGNAL(); add comment.