Hamayama [Thu, 7 Feb 2019 21:51:25 +0000 (00:51 +0300)]
Fix GetThreadContext stale register values use if WoW64 (Win32)
(a cherry-pick of commit 8bba28b6 from 'release-7_6')
Issue #262 (bdwgc).
* win32_threads.c [I386] (isWow64): New static variable.
* win32_threads.c [I386] (GC_push_stack_for): If isWow64 then set also
CONTEXT_EXCEPTION_REQUEST and CONTEXT_SEGMENTS bits in ContextFlags;
if isWow64, and CONTEXT_EXCEPTION_REPORTING and
CONTEXT_EXCEPTION_ACTIVE are set on return from GetThreadContext then
call GetThreadSelectorEntry and use StackLimit of FS selector to set
sp local variable (instead of context.Esp); add comment.
* win32_threads.c [I386 && DEBUG_THREADS] (GC_push_stack_for): Call
GC_log_printf() to report TIB stack limit/base and the case when
CONTEXT_EXCEPTION_REQUEST is not supported.
* win32_threads.c [I386] (GC_thr_init): Set isWow64 by IsWow64Process()
if the later is available.
Ivan Maidanski [Mon, 21 Jan 2019 22:01:45 +0000 (01:01 +0300)]
Fix 'unexpected mark stack overflow' abort in push_all_stack
(a cherry-pick of commit 420a4768 from 'release-7_6')
Issue #260 (bdwgc).
* mark.c [!(THREADS && MPROTECT_VDB)]
(GC_push_all_stack): Call GC_push_all_eager() instead of GC_push_all()
if GC_mark_stack_top is rather close to GC_mark_stack_limit.
Ivan Maidanski [Fri, 4 Jan 2019 16:37:50 +0000 (19:37 +0300)]
Fix BSD_TIME variant of MS_TIME_DIFF for the case of a.tv_usec < b.tv_usec
(a cherry-pick of commit 610012f0 from 'release-7_4')
* include/private/gc_priv.h [BSD_TIME] (MS_TIME_DIFF):
Cast the result of a.tv_usec-b.tv_usec to long (so that the result of
the division should be negative if a.tv_usec is less than b.tv_usec).
Ivan Maidanski [Sat, 5 Jan 2019 08:52:53 +0000 (11:52 +0300)]
Fix invalid initializer of CLOCK_TYPE variables if BSD_TIME
(a cherry-pick of commit 0e12ebaf from 'release-7_4')
* alloc.c [!SMALL_CONFIG] (GC_start_time): Initialize to
CLOCK_TYPE_INITIALIZER (instead of 0).
* alloc.c [!SMALL_CONFIG] (GC_try_to_collect_inner, GC_stopped_mark,
GC_finish_collection): Initialize local variable of CLOCK_TYPE type to
CLOCK_TYPE_INITIALIZER (instead of 0); remove comment (duplicating that
in gc_priv.h).
* reclaim.c [!SMALL_CONFIG] (GC_reclaim_all): Likewise.
* include/private/gc_priv.h (CLOCK_TYPE_INITIALIZER):
Define macro.
Demyan Kimitsa [Tue, 28 Aug 2018 16:40:47 +0000 (19:40 +0300)]
Fix start_world not resuming all threads on Darwin
(back-port of commit c4ac42bc9 from 'release-7_4')
Issue #231 (bdwgc).
This happens due mach thread ports are released in GC_stop_world as
a result in some cases the system creates new one and GC_start_world
will not find the thread to resume; in turn, the threads will stay
suspended. When this happens to GDC threads, the application is
terminated as the message loop is halt.
The high-level description of the change: thread mach port is not
deallocated when thread is saved in GC_mach_threads as it causes thread
not being resumed as thread port object can be changed; threads are now
being suspended without check of suspend_count (as it can be suspended
by client); the logic of resume is changed, now the primary cycle
iterates threads to resume in GC_mach_threads.
* darwin_stop_world.c (struct GC_mach_thread): Rename already_suspended
field to suspended.
* darwin_stop_world.c [!GC_NO_THREADS_DISCOVERY]
(GC_suspend_thread_list): Add my_task argument; remove info an outCount
local variables; call mach_port_deallocate unless threaded is added to
GC_mach_threads; do not call thread_info; update the relevant comments.
* darwin_stop_world.c [!GC_NO_THREADS_DISCOVERY] (GC_stop_world):
Remove i local variable; do not call mach_port_deallocate for prevlist
items; add comment.
* darwin_stop_world.c (GC_thread_resume): Call WARN instead of ABORT
if thread_resume failed.
* darwin_stop_world.c [!GC_NO_THREADS_DISCOVERY] (GC_start_world):
Initialize j to listcount; iterate over GC_mach_threads in the outer
loop; if thread is suspended then find it in act_list; if found then
resume thread; call mach_port_deallocate for act_list items.
Ivan Maidanski [Fri, 3 Aug 2018 16:43:18 +0000 (19:43 +0300)]
Fix incorrect roots order after root removal in remove_roots_subregion
(fix of commits 38d194a, e849b45)
Issue #218 (bdwgc).
* mark_rts.c [USE_PROC_FOR_LIBRARIES] (swap_static_roots): New inline
function.
* mark_rts.c [USE_PROC_FOR_LIBRARIES] (GC_remove_roots_subregion):
Use swap_static_roots (after GC_add_roots_inner); if there is
a temporary root after GC_remove_root_at_pos then swap it with the
appropriate non-temporary one to ensure all temporary roots are
grouped at the end.
Ivan Maidanski [Wed, 11 Jul 2018 20:09:00 +0000 (23:09 +0300)]
Fix GC_is_valid_displacement and GC_is_visible for non-small objects
(a cherry-pick of commit d4205267 from 'release-7_4')
* ptr_chck.c (GC_is_valid_displacement): Remove redundant
IS_FORWARDING_ADDR_OR_NIL(hhdr) call if GC_all_interior_pointers.
* ptr_chck.c (GC_is_valid_displacement): Do not goto fail if
p+sz-offset > h+1 but IS_FORWARDING_ADDR_OR_NIL(HDR(h+1)).
* ptr_chck.c (GC_is_visible): Transform comment about GC_base to
a TODO item; set hhdr to HDR(base) instead of HDR(p)
if HBLKPTR(base)!=HBLKPTR(p).
Ivan Maidanski [Thu, 14 Jun 2018 23:27:11 +0000 (02:27 +0300)]
Fix large object base computation in PUSH_CONTENTS() if MARK_BIT_PER_OBJ
(a cherry-pick of commit a213fb52 from 'release-7_4')
Issue #177 (bdwgc).
* include/private/gc_pmark.h [MARK_BIT_PER_OBJ] (PUSH_CONTENTS_HDR):
Do not call LONG_MULT() if inv_sz == LARGE_INV_SZ; set base to
hhdr->hb_block if inv_sz == LARGE_INV_SZ regardless of low_prod>>16
value; use EXPECT(FALSE) for inv_sz == LARGE_INV_SZ expression;
remove FIXME about offset; adjust assertion to allow hb_block==current.
Ivan Maidanski [Mon, 15 Jan 2018 05:20:02 +0000 (08:20 +0300)]
Fix global operator delete definition for C++14 in gc_cpp
(a cherry-pick of commit ede8f8c8 from 'release-7_6')
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 [Wed, 11 Jul 2018 06:07:30 +0000 (09:07 +0300)]
Fix 'pointer arithmetic with NULL' code defect in print_callers
(a cherry-pick of commit 18fda2a1 from 'release-7_4')
* os_dep.c [NEED_CALLINFO && LINUX && !SMALL_CONFIG] (GC_print_callers):
If nl is null then pass result_len (instead of nl-result_buf) to strncmp;
adjust code indentation.
Ivan Maidanski [Fri, 22 Jun 2018 22:17:46 +0000 (01:17 +0300)]
Fix mark stack overflow checking in push_selected
(a cherry-pick of commit 84053cd2 from 'release-7_4')
* mark.c (GC_push_selected): In case of a danger of mark stack overflow
after the first GC_push_all() call then call GC_push_all(bottom, top)
and return; remove redundant checking of GC_mark_stack_top at the end
of the function (overflow is already checked in GC_push_all).
Ivan Maidanski [Wed, 20 Jun 2018 07:56:19 +0000 (10:56 +0300)]
Fix VirtualQuery call in case of malloc failure (Win32)
* os_dep.c [!REDIRECT_MALLOC && USE_WINALLOC]
(GC_add_current_malloc_heap): Do not call GC_get_allocation_base(new_l)
if new_l is null; cast malloc() result to the type of new_l.
Ivan Maidanski [Fri, 18 May 2018 18:36:37 +0000 (21:36 +0300)]
Fix comments style in configure.ac and Makefile.am
(a cherry-pick of commit 0641f668 from 'release-7_4')
Do not allow the comments that are meaningless in the auto-generated
configure and Makefile.in to be put to these files.
* Makefile.am (EXTRA_DIST,
include doc/doc.am): Change comment style from "#" to "##".
* Makefile.am (CPLUSPLUS): Move "#" inside the conditional block.
* configure.ac: Update the copyright.
* configure.ac: Change comment style from "#" to "dnl" for the comments
that are meaningless in auto-generated configure file.
Naoyuki Sawa [Wed, 2 May 2018 04:10:23 +0000 (13:10 +0900)]
Fix register_dynamic_libraries on Windows 10
Issue #219 (bdwgc).
In the past (Windows XP, Windows 7, and older Windows 10), VirtualQuery
always returned PAGE_READWRITE for the data section.
In the April 2018 Update of Windows 10, it seems that PAGE_WRITECOPY
is returned sometimes (thus causing GC_register_dynamic_libraries not
to call GC_cond_add_roots for the section).
* dyn_load.c [MSWIN32 || MSWINCE || CYGWIN32]
(GC_register_dynamic_libraries): Call GC_cond_add_roots()
also for PAGE_EXECUTE_WRITECOPY and PAGE_WRITECOPY pages.
Ivan Maidanski [Tue, 10 Apr 2018 08:07:08 +0000 (11:07 +0300)]
Fix data race during apply_to_each_object(reset_back_edge)
(back-port of commit 144 from 'release-7_4')
Issue #144 (bdwgc).
* backgraph.c [MAKE_BACK_GRAPH] (GC_print_back_graph_stats): Add
assertion that the allocation lock is held; store GC_deepest_obj to
obj local variable (while holding the lock); place UNLOCK/LOCK around
GC_print_heap_obj() call; pass obj to GC_print_heap_obj(); replace
GC_printf() to GC_err_printf() call to print the header for
GC_print_heap_obj().
* finalize.c [MAKE_BACK_GRAPH] (GC_notify_or_invoke_finalizers): Remove
UNLOCK/LOCK around GC_print_back_graph_stats() call.
Ivan Maidanski [Tue, 17 Apr 2018 21:20:46 +0000 (00:20 +0300)]
Fix the collector hang when it is configured with --enable-gc-debug
(back-port of commit 7d6106bc from 'release-7_4')
Issue #205 (bdwgc).
* dbg_mlc.c (GC_store_debug_info_inner): Remove comment (as it exists
in the header); change from STATIC to GC_INNER; change p type from
ptr_t to void*.
* dbg_mlc.c [GC_ASSERTIONS] (GC_store_debug_info_inner): Cast p to
ptr_t when passed to CROSSES_HBLK().
* dbg_mlc.c (GC_store_debug_info): Change from GC_INNER to static;
remove GC_ prefix; replace ptr_t to void*; add fn argument;
replace "const char *string, int linenum" with GC_EXTRA_PARAMS;
change "word sz" argument to "size_t lb"; allow p to be null (print
error message in this case); call GC_start_debugging_inner unless
GC_debugging_started; call ADD_CALL_CHAIN.
* dbg_mlc.c (GC_start_debugging_inner): Define as GC_INNER (instead of
STATIC); call GC_register_displacement_inner() instead of
GC_register_displacement().
* dbg_mlc.c (GC_start_debugging): Remove.
* dbg_mlc.c (GC_debug_malloc, GC_debug_malloc_ignore_off_page,
GC_debug_malloc_atomic_ignore_off_page, GC_debug_generic_malloc,
GC_debug_malloc_atomic, GC_debug_malloc_uncollectable): Call
store_debug_info() instead of checking result for null and calling
GC_start_debugging, ADD_CALL_CHAIN, GC_store_debug_info; use OPT_RA.
* dbg_mlc.c [STUBBORN_ALLOC] (GC_debug_malloc_stubborn): Likewise.
* dbg_mlc.c [GC_ATOMIC_UNCOLLECTABLE]
(GC_debug_malloc_atomic_uncollectable): Likewise.
* gcj_mlc.c [GC_GCJ_SUPPORT] (GC_debug_gcj_malloc): Call ADD_CALL_CHAIN
while holding the lock; call GC_store_debug_info_inner (holding the
lock) instead of GC_store_debug_info.
* gcj_mlc.c (GC_debug_gcj_malloc): Call GC_start_debugging_inner
(holding the lock) instead of GC_start_debugging.
* include/private/dbg_mlc.h (ADD_CALL_CHAIN): Update comment.
* include/private/gc_priv.h (GC_store_debug_info): Replace with
GC_store_debug_info_inner; update comment; change ptr_t to void*.
* include/private/gc_priv.h (GC_start_debugging): Rename to
GC_start_debugging_inner; improve usage comment.
* os_dep.c [SAVE_CALL_CHAIN] (GC_save_callers): Add assertion that the
allocation lock is held; add comment.
Ivan Maidanski [Fri, 6 Apr 2018 16:07:50 +0000 (19:07 +0300)]
Fix null dereference in print_callers on backtrace_symbols failure
(back-port of commit e045f6fe from 'release-7_4')
* os_dep.c [NEED_CALLINFO && GC_HAVE_BUILTIN_BACKTRACE
&& !GC_BACKTRACE_SYMBOLS_BROKEN] (GC_print_callers): If sym_name is
NULL then print info[i].ci_pc to buf and set name to buf (instead of
to sym_name[0]).
* os_dep.c [NEED_CALLINFO && GC_HAVE_BUILTIN_BACKTRACE
&& !GC_BACKTRACE_SYMBOLS_BROKEN] (GC_print_callers): Do not call
free(sym_name) if sym_name is NULL.
Ivan Maidanski [Fri, 23 Mar 2018 08:13:23 +0000 (11:13 +0300)]
Fix thread_suspend fail for threads registered from key destructor (OS X)
Issue #213 (bdwgc).
* pthread_support.c [GC_DARWIN_THREADS] (GC_register_my_thread):
Reinitialize stop_info.mach_thread if the thread is registered from
the client thread key destructor; add comment.
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 [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.
Ivan Maidanski [Fri, 1 Dec 2017 16:38:02 +0000 (19:38 +0300)]
Fix data race in do_local_mark when comparing active_count to helper_count
(Cherry-pick commit ec713485 from 'release-7_4' branch.)
* mark.c [PARALLEL_MARK] (has_inactive_helpers): New static function
(which compares GC_active_count to GC_helper_count with the mark lock
held).
* mark.c [PARALLEL_MARK && GC_ASSERTIONS] (GC_do_local_mark): Remove
GC_acquire_mark_lock() with immediate GC_acquire_mark_unlock(); add
the appropriate comment to the function description instead.
* mark.c [PARALLEL_MARK] (GC_do_local_mark): Call has_inactive_helpers()
instead of GC_active_count<GC_helper_count; do not call
has_inactive_helpers() unless local_top>local_mark_stack+1.
Ivan Maidanski [Thu, 23 Nov 2017 23:21:46 +0000 (02:21 +0300)]
Fix lack of barriers to synchronize memory for suspend_handler
(Cherry-pick commit 62ad477c from 'release-7_4' branch.)
pthread_kill is not on the list of functions which synchronize memory.
* pthread_stop_world.c [!GC_OPENBSD_THREADS && !NACL]
(GC_world_is_stopped): Reformat comment.
* pthread_stop_world.c [!GC_OPENBSD_THREADS && !NACL]
(GC_suspend_handler_inner): Use AO_load_acquire instead of AO_load
to fetch the value of GC_stop_count; add comment.
* pthread_stop_world.c [!GC_OPENBSD_THREADS && !NACL]
(GC_start_world): Use AO_store_release instead of AO_store to reset
GC_world_is_stopped; add comment.
Ivan Maidanski [Thu, 23 Nov 2017 17:15:54 +0000 (20:15 +0300)]
Fix data race in last_stop_count access (suspend_handler_inner)
(Cherry-pick commit 7de43fef from 'release-7_4' branch.)
* include/private/pthread_stop_world.h [!GC_OPENBSD_THREADS]
(thread_stop_info.last_stop_count): Change the
type from word to AO_t; add volatile qualifier; fix a typo in comment
("GC_stop_count").
* pthread_stop_world.c [!GC_OPENBSD_THREADS && !NACL]
(GC_suspend_handler_inner): Replace
me->stop_info.last_stop_count=my_stop_count with
AO_store_release(&me->stop_info.last_stop_count,my_stop_count).
Ivan Maidanski [Fri, 10 Nov 2017 17:07:16 +0000 (20:07 +0300)]
Fix data race when getting object size in explicitly-typed allocators
(Cherry-pick commit eb33bda5 from 'release-7_6' branch.)
* typd_mlc.c (COMPLEX): Reformat comment.
* typd_mlc.c (GC_malloc_explicitly_typed,
GC_malloc_explicitly_typed_ignore_off_page, GC_calloc_explicitly_typed):
Always use BYTES_TO_GRANULES(GC_size(op)) instead of GC_size_map[lb] to
determine size of the allocated object in granules (because the value
of GC_size_map[lb] might be updated by another thread since the value
use in GC_malloc_kind); add comment.
Ivan Maidanski [Fri, 3 Nov 2017 17:08:09 +0000 (20:08 +0300)]
Fix data race in a list referenced by A.aa (gctest)
(Cherry-pick commit 483f767f from 'release-7_4' branch.)
* tests/test.c [!AO_CLEAR] (AO_t): Define.
* tests/test.c [!AO_HAVE_load_acquire] (AO_load_acquire): New static
function (which uses FINALIZER_LOCK/FINALIZER_UNLOCK).
* tests/test.c [!AO_HAVE_store_release] (AO_store_release): Likewise.
* 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 (based on AO_store_release
and AO_load_acquire, respectively).
* tests/test.c (reverse_test_inner): Use a_set() and a_get() to store
and fetch the value of a, respectively.
Ivan Maidanski [Tue, 1 Sep 2015 06:57:38 +0000 (09:57 +0300)]
Fix data race in GC_init_explicit_typing
(Cherry-pick commits 69527f2, c0492a7 from 'release-7_4' branch.)
* typd_mlc.c: Force include atomic_ops.h if
GC_FORCE_INCLUDE_ATOMIC_OPS (by default it is included if
PARALLEL_MARK or pthreads are used).
* typd_mlc.c (GC_explicit_typing_initialized): Use volatile AO_t if
AO_load_acquire() and AO_store_release() are both available.
* typd_mlc.c (GC_init_explicit_typing): Move locking (and
GC_explicit_typing_initialized access) outside to the caller
(GC_make_descriptor); remove comment; remove "register" keyword for
local variable.
* typd_mlc.c (GC_make_descriptor): Use AO_load_acquire (if available)
to fetch GC_explicit_typing_initialized value and AO_store_release to
set GC_explicit_typing_initialized (to avoid data race and avoid lock
acquiring on each call); otherwise use locked checking of
GC_explicit_typing_initialized.
* typd_mlc.c (GC_explicit_typing_initialized,
GC_malloc_explicitly_typed_ignore_off_page,
GC_calloc_explicitly_typed): Add assertion on
GC_explicit_typing_initialized is true.
Ivan Maidanski [Fri, 3 Nov 2017 08:03:04 +0000 (11:03 +0300)]
Avoid data race in finalized_count (gctest)
(Cherry-pick commit 0c7fdf4d from 'release-7_4' branch.)
* tests/test.c (FINALIZER_LOCK, FINALIZER_UNLOCK): New macro.
* tests/test.c [GC_PTHREADS] (incr_lock): Move static variable out
of finalizer() and mktree() (use a single lock variable to access
finalized_count in finalizer, mktree and tree_test).
* tests/test.c (dropped_something): Change type back to int; remove
volatile.
* tests/test.c (finalizer, mktree): Use FINALIZER_[UN]LOCK() instead
of PCR_ThCrSec_Enter/ExitSys(), pthread_mutex_[un]lock(),
Enter/LeaveCriticalSection().
* tests/test.c (tree_test): Use FINALIZER_[UN]LOCK() to avoid data
race when accessing finalized_count and dropped_something.