Fwd: Re[3]: Boehm GC API update backport
Ivan Maidanski <[email protected]> Tue, 14 Jun 2016 22:00:18 +0300
| Newsgroups | gmane.comp.gcc.java.patches |
|---|---|
| Message-ID | <[email protected]> |
Hello, Is there anything more preventing it to be merged to trunk? The patches (rebased to recent trunk) are attached. (Actually only the first one is updated due to merge conflict in ChangeLog files.) Thank you. Regards, Ivan >Wed, 20 Jan 2016, 1:41 +03:00 from Ivan Maidanski < [email protected] >: > >Hello Matthias, > >I've checked objc tests - same as without the patches. >Actually objc uses only GC_malloc/realloc and GC typed API - these are not affected. > >Regards, >Ivan > >> Sun, 17 Jan 2016, 1:55 +01:00 from Matthias Klose < [email protected] >: >> >> On 16.01.2016 13:19, Ivan Maidanski wrote: >> > Hello, >> > >> > Proposed 4 commits are code refactoring of boehm-gc (and libjava/boehm.cc, accordingly) to match API of recent BDWGC master ( https://github.com/ivmai/bdwgc ). This should simplify optional replacement of internal boehm-gcc with the external one. >> > All gcj tests pass. >> > >> > Some of the benefits of using mainline boehm gc: >> > * has no compiler warning >> > * more targets supported (e.g. arm64) >> > * no trouble with back-porting gc patches Similar thing was proposed for the Mono community - https://github.com/mono/mono/pull/2247 (the patches were accepted recently) >> > >> > References: >> > [1] The proposed patches in GCC unofficial git mirror fork - https://github.com/ivmai/gcc/tree/match-bdwgc-api >> >> for completeness, please check an ObjC enabled build configured with >> --enable-objc-gc >> >> Matthias >>
0001-Change-GC_set_free_space_divisor-prototy pe-in-boehm-.patch
(application/x-patch, 3.7 KB)
From 50a20b00b55e7e116c60b479fa26dcf534b88941 Mon Sep 17 00:00:00 2001 From: Ivan Maidanski <[email protected]> Date: Thu, 3 Dec 2015 01:48:30 +0300 Subject: [PATCH 1/4] Change GC_set_free_space_divisor prototype in boehm-gc (code refactoring to match BDWGC v7 API) boehm-gc/ * include/gc.h (GC_set_free_space_divisor): Change return type from word to void. (GC_get_free_space_divisor): New function. * misc.c (GC_set_free_space_divisor): Decouple to setter and getter. libjava/ * boehm.cc (_Jv_SetGCFreeSpaceDivisor): Use GC_get_free_space_divisor to get old_div (before GC_set_free_space_divisor call). --- boehm-gc/ChangeLog | 7 +++++++ boehm-gc/include/gc.h | 6 +++--- boehm-gc/misc.c | 11 +++++++---- libjava/ChangeLog | 5 +++++ libjava/boehm.cc | 4 +++- 5 files changed, 25 insertions(+), 8 deletions(-) diff --git a/boehm-gc/ChangeLog b/boehm-gc/ChangeLog index 6896c67..532b889 100644 --- a/boehm-gc/ChangeLog +++ b/boehm-gc/ChangeLog @@ -1,3 +1,10 @@ +2015-12-03 Ivan Maidanski <[email protected]> + + * include/gc.h (GC_set_free_space_divisor): Change return type from + word to void. + (GC_get_free_space_divisor): New function. + * misc.c (GC_set_free_space_divisor): Decouple to setter and getter. + 2016-03-29 Samuel Thibault <[email protected]> * configure.host: Set gc_use_mmap on *-kfreebsd-gnu* and *-gnu*. diff --git a/boehm-gc/include/gc.h b/boehm-gc/include/gc.h index 6b38f2d..d02dab2 100644 --- a/boehm-gc/include/gc.h +++ b/boehm-gc/include/gc.h @@ -803,9 +803,9 @@ typedef void (*GC_warn_proc) GC_PROTO((char *msg, GC_word arg)); GC_API GC_warn_proc GC_set_warn_proc GC_PROTO((GC_warn_proc p)); /* Returns old warning procedure. */ -GC_API GC_word GC_set_free_space_divisor GC_PROTO((GC_word value)); - /* Set free_space_divisor. See above for definition. */ - /* Returns old value. */ +GC_API void GC_set_free_space_divisor GC_PROTO((GC_word value)); +GC_API GC_word GC_get_free_space_divisor GC_PROTO((void)); + /* Set and get free_space_divisor. See above for the definition. */ /* The following is intended to be used by a higher level */ /* (e.g. Java-like) finalization facility. It is expected */ diff --git a/boehm-gc/misc.c b/boehm-gc/misc.c index 069c7d5..c1faed0 100644 --- a/boehm-gc/misc.c +++ b/boehm-gc/misc.c @@ -1048,15 +1048,18 @@ GC_warn_proc GC_current_warn_proc = GC_default_warn_proc; } # if defined(__STDC__) || defined(__cplusplus) - GC_word GC_set_free_space_divisor (GC_word value) + void GC_set_free_space_divisor (GC_word value) # else - GC_word GC_set_free_space_divisor (value) + void GC_set_free_space_divisor (value) GC_word value; # endif { - GC_word old = GC_free_space_divisor; GC_free_space_divisor = value; - return old; +} + +GC_word GC_get_free_space_divisor GC_PROTO((void)) +{ + return GC_free_space_divisor; } #ifndef PCR diff --git a/libjava/ChangeLog b/libjava/ChangeLog index a3bead2..e98fe56 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,8 @@ +2015-12-03 Ivan Maidanski <[email protected]> + + * boehm.cc (_Jv_SetGCFreeSpaceDivisor): Use GC_get_free_space_divisor + to get old_div (before GC_set_free_space_divisor call). + 2016-06-01 Matthias Klose <[email protected]> * libtool-version: Bump soversion. diff --git a/libjava/boehm.cc b/libjava/boehm.cc index 043fd00..34a6ead 100644 --- a/libjava/boehm.cc +++ b/libjava/boehm.cc @@ -468,7 +468,9 @@ _Jv_GCSetMaximumHeapSize (size_t size) int _Jv_SetGCFreeSpaceDivisor (int div) { - return (int)GC_set_free_space_divisor ((GC_word)div); + int old_div = (int)GC_get_free_space_divisor (); + GC_set_free_space_divisor ((GC_word)div); + return old_div; } void -- 2.8.2
0002-Move-extern-C-from-boehm.cc-to-boehm-gc- header-files.patch
(application/x-patch, 8.3 KB)
From 6c3c544918a3d6c0e10ac84df937be7c82849f11 Mon Sep 17 00:00:00 2001 From: Ivan Maidanski <[email protected]> Date: Sat, 5 Dec 2015 19:28:20 +0300 Subject: [PATCH 2/4] Move 'extern C' from boehm.cc to boehm-gc header files; avoid explicit include gc_local_alloc.h from boehm.cc; remove GC_enable/disable duplicate prototyping (code refactoring to match BDWGC v7 API) boehm-gc/ * include/gc.h (GC_suspend_thread, GC_resume_thread, GC_is_thread_suspended): Move inside 'extern "C"' block. [GC_REDIRECT_TO_LOCAL]: Include gc_local_alloc.h outside 'extern "C"' block; do not include gc_local_alloc.h if gc.h is included from gc_gcj.h (so that GC_[LOCAL_]GCJ_MALLOC to be defined after other GCJ symbols). * include/gc_gcj.h [__cplusplus]: Wrap all declarations into 'extern "C"' block. * include/gc_local_alloc.h [__cplusplus]: Likewise. * include/javaxfc.h [__cplusplus]: Likewise. * include/gc_gcj.h [GC_REDIRECT_TO_LOCAL]: Include gc_local_alloc.h. libjava/ * boehm.cc (GC_enable, GC_disable): Remove prototype (as declared in boehm-gc/include/gc.h). [THREAD_LOCAL_ALLOC] (GC_REDIRECT_TO_LOCAL): Define before include gc_gcj.h file. * boehm.cc: Remove 'extern "C"' for included boehm-gc/include header files (they are properly decorated inside now); remove include "gc_local_alloc.h" (as it is implicitly included now by boehm-gc/include/gc_gcj.h); include "gc_gcj.h" before any other boehm-gc header file (to let GC_GCJ_MALLOC be properly redefined to a thread-local allocator in boehm-gc/include/gc_local_alloc.h). --- boehm-gc/ChangeLog | 14 ++++++++++++++ boehm-gc/include/gc.h | 22 ++++++++++++++-------- boehm-gc/include/gc_gcj.h | 12 ++++++++++++ boehm-gc/include/gc_local_alloc.h | 8 ++++++++ boehm-gc/include/gc_mark.h | 9 ++++++++- boehm-gc/include/javaxfc.h | 8 +++++++- libjava/ChangeLog | 13 +++++++++++++ libjava/boehm.cc | 14 +++----------- 8 files changed, 79 insertions(+), 21 deletions(-) diff --git a/boehm-gc/ChangeLog b/boehm-gc/ChangeLog index 532b889..8a4b8d6 100644 --- a/boehm-gc/ChangeLog +++ b/boehm-gc/ChangeLog @@ -1,3 +1,17 @@ +2015-12-05 Ivan Maidanski <[email protected]> + + * include/gc.h (GC_suspend_thread, GC_resume_thread, + GC_is_thread_suspended): Move inside 'extern "C"' block. + [GC_REDIRECT_TO_LOCAL]: Include gc_local_alloc.h outside 'extern "C"' + block; do not include gc_local_alloc.h if gc.h is included from + gc_gcj.h (so that GC_[LOCAL_]GCJ_MALLOC to be defined after other GCJ + symbols). + * include/gc_gcj.h [__cplusplus]: Wrap all declarations into + 'extern "C"' block. + * include/gc_local_alloc.h [__cplusplus]: Likewise. + * include/javaxfc.h [__cplusplus]: Likewise. + * include/gc_gcj.h [GC_REDIRECT_TO_LOCAL]: Include gc_local_alloc.h. + 2015-12-03 Ivan Maidanski <[email protected]> * include/gc.h (GC_set_free_space_divisor): Change return type from diff --git a/boehm-gc/include/gc.h b/boehm-gc/include/gc.h index d02dab2..f193065 100644 --- a/boehm-gc/include/gc.h +++ b/boehm-gc/include/gc.h @@ -1061,14 +1061,6 @@ GC_API void GC_register_has_static_roots_callback # include "gc_amiga_redirects.h" #endif -#if defined(GC_REDIRECT_TO_LOCAL) && !defined(GC_LOCAL_ALLOC_H) -# include "gc_local_alloc.h" -#endif - -#ifdef __cplusplus - } /* end of extern "C" */ -#endif - /* External thread suspension support. These functions do not implement * suspension counts or any other higher-level abstraction. Threads which * have been suspended numerous times will resume with the very first call @@ -1080,4 +1072,18 @@ GC_API void GC_suspend_thread GC_PROTO((pthread_t)); GC_API void GC_resume_thread GC_PROTO((pthread_t)); GC_API int GC_is_thread_suspended GC_PROTO((pthread_t)); #endif + +#ifdef __cplusplus + } /* end of extern "C" */ +#endif + +#if defined(GC_REDIRECT_TO_LOCAL) && !defined(GC_LOCAL_ALLOC_H) \ + && !defined(GC_GCJ_H) + /* In case of gc.h is included from gc_gcj.h file, gc_local_alloc.h */ + /* should be included at the end of gc_gcj.h instead of gc.h to have */ + /* all GCJ symbols defined before some of them are redefined to */ + /* their thread-local counterparts. */ +# include "gc_local_alloc.h" +#endif + #endif /* _GC_H */ diff --git a/boehm-gc/include/gc_gcj.h b/boehm-gc/include/gc_gcj.h index 5e79e27..b771734 100644 --- a/boehm-gc/include/gc_gcj.h +++ b/boehm-gc/include/gc_gcj.h @@ -44,6 +44,10 @@ # include "gc.h" #endif +#ifdef __cplusplus + extern "C" { +#endif + /* The following allocators signal an out of memory condition with */ /* return GC_oom_fn(bytes); */ @@ -110,4 +114,12 @@ extern int GC_gcj_debug_kind; GC_gcj_malloc_ignore_off_page(s,d) # endif +#ifdef __cplusplus + } /* end of extern "C" */ +#endif + +#if defined(GC_REDIRECT_TO_LOCAL) +# include "gc_local_alloc.h" +#endif + #endif /* GC_GCJ_H */ diff --git a/boehm-gc/include/gc_local_alloc.h b/boehm-gc/include/gc_local_alloc.h index 1874c7b..e4fe205 100644 --- a/boehm-gc/include/gc_local_alloc.h +++ b/boehm-gc/include/gc_local_alloc.h @@ -49,6 +49,10 @@ # include "gc_gcj.h" #endif +#ifdef __cplusplus + extern "C" { +#endif + /* We assume ANSI C for this interface. */ GC_PTR GC_local_malloc(size_t bytes); @@ -86,4 +90,8 @@ GC_PTR GC_local_malloc_atomic(size_t bytes); # endif # endif +#ifdef __cplusplus + } /* end of extern "C" */ +#endif + #endif /* GC_LOCAL_ALLOC_H */ diff --git a/boehm-gc/include/gc_mark.h b/boehm-gc/include/gc_mark.h index 953bb74..7c92946 100644 --- a/boehm-gc/include/gc_mark.h +++ b/boehm-gc/include/gc_mark.h @@ -29,6 +29,10 @@ # include "gc.h" # endif +# ifdef __cplusplus + extern "C" { +# endif + /* A client supplied mark procedure. Returns new mark stack pointer. */ /* Primary effect should be to push new entries on the mark stack. */ /* Mark stack pointer values are passed and returned explicitly. */ @@ -199,5 +203,8 @@ void GC_register_describe_type_fn GC_PROTO((int kind, GC_describe_type_fn knd)); /* to be used when printing objects */ /* of a particular kind. */ -#endif /* GC_MARK_H */ +# ifdef __cplusplus + } /* end of extern "C" */ +# endif +#endif /* GC_MARK_H */ diff --git a/boehm-gc/include/javaxfc.h b/boehm-gc/include/javaxfc.h index 23e0100..669ba64 100644 --- a/boehm-gc/include/javaxfc.h +++ b/boehm-gc/include/javaxfc.h @@ -2,6 +2,10 @@ # include "gc.h" # endif +#ifdef __cplusplus + extern "C" { +#endif + /* * Invoke all remaining finalizers that haven't yet been run. * This is needed for strict compliance with the Java standard, @@ -18,4 +22,6 @@ */ void GC_finalize_all(); - +#ifdef __cplusplus + } /* end of extern "C" */ +#endif diff --git a/libjava/ChangeLog b/libjava/ChangeLog index e98fe56..28adfaf 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,16 @@ +2015-12-05 Ivan Maidanski <[email protected]> + + * boehm.cc (GC_enable, GC_disable): Remove prototype (as declared in + boehm-gc/include/gc.h). + [THREAD_LOCAL_ALLOC] (GC_REDIRECT_TO_LOCAL): Define before include + gc_gcj.h file. + * boehm.cc: Remove 'extern "C"' for included boehm-gc/include header + files (they are properly decorated inside now); remove include + "gc_local_alloc.h" (as it is implicitly included now by + boehm-gc/include/gc_gcj.h); include "gc_gcj.h" before any other + boehm-gc header file (to let GC_GCJ_MALLOC be properly redefined to + a thread-local allocator in boehm-gc/include/gc_local_alloc.h). + 2015-12-03 Ivan Maidanski <[email protected]> * boehm.cc (_Jv_SetGCFreeSpaceDivisor): Use GC_get_free_space_divisor diff --git a/libjava/boehm.cc b/libjava/boehm.cc index 34a6ead..39563f0 100644 --- a/libjava/boehm.cc +++ b/libjava/boehm.cc @@ -38,8 +38,6 @@ details. */ #include <dlfcn.h> #endif -extern "C" -{ #include <gc_config.h> // Set GC_DEBUG before including gc.h! @@ -47,19 +45,13 @@ extern "C" # define GC_DEBUG #endif -#include <gc_mark.h> -#include <gc_gcj.h> -#include <javaxfc.h> // GC_finalize_all declaration. - #ifdef THREAD_LOCAL_ALLOC # define GC_REDIRECT_TO_LOCAL -# include <gc_local_alloc.h> #endif +#include <gc_gcj.h> // includes gc.h and gc_local_alloc.h - // From boehm's misc.c - void GC_enable(); - void GC_disable(); -}; +#include <gc_mark.h> +#include <javaxfc.h> // GC_finalize_all declaration. #define MAYBE_MARK(Obj, Top, Limit, Source) \ Top=GC_MARK_AND_PUSH((GC_PTR) Obj, Top, Limit, (GC_PTR *) Source) -- 2.8.2
0004-Change-GC_-un-register_my_thread-prototy pes-in-boehm.patch
(application/x-patch, 9.2 KB)
From 270c3e2c4c2f314b9ee083350f4670cbac167424 Mon Sep 17 00:00:00 2001 From: Ivan Maidanski <[email protected]> Date: Thu, 17 Dec 2015 00:51:21 +0300 Subject: [PATCH 4/4] Change GC_[un]register_my_thread prototypes in boehm-gc (code refactoring to match BDWGC v7 API) boehm-gc/ * include/gc.h (GC_DUPLICATE): New public macro. (GC_register_my_thread): Change prototype (accept GC_stack_base*). (GC_register_my_thread, GC_unregister_my_thread): Change prototype (return operation completion status); update comment. * pthread_support.c (GC_register_my_thread): Change prototype; change "sb" type to pointer; do not call GC_get_stack_base (it is called by GC_register_my_thread caller now); return GC_DUPLICATE or GC_SUCCESS. (GC_unregister_my_thread): Change prototype; return GC_SUCCESS. * win32_threads.c (GC_register_my_thread, GC_unregister_my_thread): New function (stub returning GC_DUPLICATE if threads are registered implicitly otherwise GC_UNIMPLEMENTED). libjava/ * boehm.cc (_Jv_GCAttachThread, _Jv_GCDetachThread): Do not test HAVE_PTHREAD_GETATTR_NP and GC_SOLARIS_THREADS macros, test GC_PTHREADS macro instead (i.e., invoke GC thread register/unregister for all multi-threaded targets); remove the relevant comment. (_Jv_GCAttachThread): Declare "sb" local variable; invoke GC_get_stack_base (pass obtained stack base to GC_register_my_thread); call JvFail with the appropriate message in case of GC_get_stack_base or GC_register_my_thread failure (but handle properly the case when GC_get_stack_base returns GC_UNIMPLEMENTED but the thread is already registered implicitly). --- boehm-gc/ChangeLog | 14 ++++++++++++++ boehm-gc/include/gc.h | 15 +++++++-------- boehm-gc/pthread_support.c | 17 +++++++---------- boehm-gc/win32_threads.c | 17 +++++++++++++++++ libjava/ChangeLog | 13 +++++++++++++ libjava/boehm.cc | 22 ++++++++++++++-------- 6 files changed, 72 insertions(+), 26 deletions(-) diff --git a/boehm-gc/ChangeLog b/boehm-gc/ChangeLog index af44b3e..4e0483a 100644 --- a/boehm-gc/ChangeLog +++ b/boehm-gc/ChangeLog @@ -1,3 +1,17 @@ +2015-12-17 Ivan Maidanski <[email protected]> + + * include/gc.h (GC_DUPLICATE): New public macro. + (GC_register_my_thread): Change prototype (accept GC_stack_base*). + (GC_register_my_thread, GC_unregister_my_thread): Change prototype + (return operation completion status); update comment. + * pthread_support.c (GC_register_my_thread): Change prototype; change + "sb" type to pointer; do not call GC_get_stack_base (it is called by + GC_register_my_thread caller now); return GC_DUPLICATE or GC_SUCCESS. + (GC_unregister_my_thread): Change prototype; return GC_SUCCESS. + * win32_threads.c (GC_register_my_thread, GC_unregister_my_thread): + New function (stub returning GC_DUPLICATE if threads are registered + implicitly otherwise GC_UNIMPLEMENTED). + 2015-12-10 Ivan Maidanski <[email protected]> * AmigaOS.c (GC_get_stack_base): Rename to GC_get_main_stack_base. diff --git a/boehm-gc/include/gc.h b/boehm-gc/include/gc.h index 6ba20e6..99adedd 100644 --- a/boehm-gc/include/gc.h +++ b/boehm-gc/include/gc.h @@ -935,6 +935,7 @@ struct GC_stack_base { }; #define GC_SUCCESS 0 +#define GC_DUPLICATE 1 /* Was already registered. */ #define GC_UNIMPLEMENTED 3 /* Not yet implemented on the platform. */ /* Attempt to fill in the GC_stack_base structure with the stack base */ @@ -954,15 +955,13 @@ GC_API int GC_get_stack_base GC_PROTO((struct GC_stack_base *)); /* a thread can allocate garbage collected memory, or assign pointers */ /* to the garbage collected heap. Once registered, a thread will be */ /* stopped during garbage collections. */ -GC_API void GC_register_my_thread GC_PROTO((void)); +/* Returns GC_SUCCESS on success, GC_DUPLICATE if already done. */ +/* On some platforms it returns GC_UNIMPLEMENTED. */ +GC_API int GC_register_my_thread GC_PROTO((struct GC_stack_base *)); -/* Register the current thread, with the indicated stack base, as */ -/* a new thread whose stack(s) should be traced by the GC. If a */ -/* platform does not implicitly do so, this must be called before a */ -/* thread can allocate garbage collected memory, or assign pointers */ -/* to the garbage collected heap. Once registered, a thread will be */ -/* stopped during garbage collections. */ -GC_API void GC_unregister_my_thread GC_PROTO((void)); +/* Unregister the current thread. */ +/* Returns GC_SUCCESS or GC_UNIMPLEMENTED. */ +GC_API int GC_unregister_my_thread GC_PROTO((void)); /* This returns a list of objects, linked through their first */ /* word. Its use can greatly reduce lock contention problems, since */ diff --git a/boehm-gc/pthread_support.c b/boehm-gc/pthread_support.c index e077abb..acb1a55 100644 --- a/boehm-gc/pthread_support.c +++ b/boehm-gc/pthread_support.c @@ -1170,15 +1170,10 @@ int GC_get_stack_base(struct GC_stack_base *sb) # endif } -void GC_register_my_thread() +int GC_register_my_thread(struct GC_stack_base *sb) { GC_thread me; pthread_t my_pthread; -# if !defined(GC_DARWIN_THREADS) || defined(IA64) - struct GC_stack_base sb; - if (GC_get_stack_base(&sb) == GC_UNIMPLEMENTED) - ABORT("Can not determine stack base for attached thread"); -# endif my_pthread = pthread_self(); # ifdef DEBUG_THREADS @@ -1195,7 +1190,7 @@ void GC_register_my_thread() # ifdef DEBUG_THREADS GC_printf1("Attempt to re-attach known thread 0x%lx\n", my_pthread); # endif - return; + return GC_DUPLICATE; } LOCK(); @@ -1208,7 +1203,7 @@ void GC_register_my_thread() #ifdef GC_DARWIN_THREADS me -> stop_info.mach_thread = mach_thread_self(); #else - me -> stack_end = sb.mem_base; + me -> stack_end = sb -> mem_base; # ifdef STACK_GROWS_DOWN me -> stop_info.stack_ptr = me -> stack_end - 0x10; @@ -1218,16 +1213,17 @@ void GC_register_my_thread() #endif # ifdef IA64 - me -> backing_store_end = sb.reg_base; + me -> backing_store_end = sb -> reg_base; # endif /* IA64 */ # if defined(THREAD_LOCAL_ALLOC) && !defined(DBG_HDRS_ALL) GC_init_thread_local(me); # endif UNLOCK(); + return GC_SUCCESS; } -void GC_unregister_my_thread() +int GC_unregister_my_thread GC_PROTO((void)) { pthread_t my_pthread; @@ -1238,6 +1234,7 @@ void GC_unregister_my_thread() # endif GC_thread_exit_proc (0); + return GC_SUCCESS; } void * GC_start_routine(void * arg) diff --git a/boehm-gc/win32_threads.c b/boehm-gc/win32_threads.c index 354e5a7..a32bf8d 100644 --- a/boehm-gc/win32_threads.c +++ b/boehm-gc/win32_threads.c @@ -527,6 +527,23 @@ static DWORD WINAPI thread_start(LPVOID arg) #endif /* !CYGWIN32 */ +int GC_register_my_thread(struct GC_stack_base *sb) +{ +# if defined(GC_DLL) && !defined(CYGWIN32) && !defined(MSWINCE) + /* Registered by DllMain. */ + return GC_DUPLICATE; +# else + /* TODO: Implement. */ + return GC_UNIMPLEMENTED; +# endif +} + +int GC_unregister_my_thread GC_PROTO((void)) +{ + /* TODO: Implement. */ + return GC_UNIMPLEMENTED; +} + #ifdef MSWINCE typedef struct { diff --git a/libjava/ChangeLog b/libjava/ChangeLog index 28adfaf..7f52a3f 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,16 @@ +2015-12-17 Ivan Maidanski <[email protected]> + + * boehm.cc (_Jv_GCAttachThread, _Jv_GCDetachThread): Do not test + HAVE_PTHREAD_GETATTR_NP and GC_SOLARIS_THREADS macros, test + GC_PTHREADS macro instead (i.e., invoke GC thread register/unregister + for all multi-threaded targets); remove the relevant comment. + (_Jv_GCAttachThread): Declare "sb" local variable; invoke + GC_get_stack_base (pass obtained stack base to GC_register_my_thread); + call JvFail with the appropriate message in case of GC_get_stack_base + or GC_register_my_thread failure (but handle properly the case when + GC_get_stack_base returns GC_UNIMPLEMENTED but the thread is already + registered implicitly). + 2015-12-05 Ivan Maidanski <[email protected]> * boehm.cc (GC_enable, GC_disable): Remove prototype (as declared in diff --git a/libjava/boehm.cc b/libjava/boehm.cc index 39563f0..4ec91af 100644 --- a/libjava/boehm.cc +++ b/libjava/boehm.cc @@ -738,20 +738,26 @@ _Jv_IsThreadSuspended (_Jv_Thread_t *thread) void _Jv_GCAttachThread () { - // The registration interface is only defined on posixy systems and - // only actually works if pthread_getattr_np is defined. - // FIXME: until gc7 it is simpler to disable this on solaris. -#if defined(HAVE_PTHREAD_GETATTR_NP) && !defined(GC_SOLARIS_THREADS) \ - && !defined(GC_WIN32_THREADS) - GC_register_my_thread (); +#if defined(GC_PTHREADS) || defined(GC_WIN32_THREADS) + struct GC_stack_base sb; + + if (GC_get_stack_base (&sb) == GC_UNIMPLEMENTED) + { + // Do not fail in case of implicitly registered threads. + sb.mem_base = &sb; + if (GC_register_my_thread (&sb) != GC_DUPLICATE) + JvFail ("Cannot determine stack base for attached thread"); + return; + } + if (GC_register_my_thread (&sb) == GC_UNIMPLEMENTED) + JvFail ("Cannot attach thread"); #endif } void _Jv_GCDetachThread () { -#if defined(HAVE_PTHREAD_GETATTR_NP) && !defined(GC_SOLARIS_THREADS) \ - && !defined(GC_WIN32_THREADS) +#if defined(GC_PTHREADS) || defined(GC_WIN32_THREADS) GC_unregister_my_thread (); #endif } -- 2.8.2
0003-Change-GC_get_-thread-main_-stack_base-p rototypes.patch
(application/x-patch, 16 KB)
From 5109009195e8d53597edce62778ed4466e811fc1 Mon Sep 17 00:00:00 2001 From: Ivan Maidanski <[email protected]> Date: Thu, 10 Dec 2015 21:46:54 +0300 Subject: [PATCH 3/4] Change GC_get_[thread/main_]stack_base prototypes (code refactoring to match BDWGC v7 API) GC_get_stack_base renamed to GC_get_main_stack_base; ptr_t GC_get_thread_stack_base() public prototype changed to int GC_get_stack_base(struct GC_stack_base*); GC_get_stack_base now defined for all targets (but returns GC_UNIMPLEMENTED if no implementation for the target). boehm-gc/ * AmigaOS.c (GC_get_stack_base): Rename to GC_get_main_stack_base. * include/private/gc_priv.h (GC_get_stack_base): Likewise. * include/gc.h (struct GC_stack_base): New public type. (GC_SUCCESS, GC_UNIMPLEMENTED): New public macro. (GC_get_thread_stack_base): Replace with int GC_get_stack_base(struct GC_stack_base*); declare even in a single-threaded case; refine comment. * misc.c (GC_init_inner): Rename GC_get_stack_base to GC_get_main_stack_base. (GC_init_inner): Replace GC_get_thread_stack_base to GC_get_stack_base. * win32_threads.c [CYGWIN32] (GC_get_thread_stack_base): Likewise. * os_dep.c [MSWIN32 || MSWINCE || BEOS || OS2] (GC_get_stack_base): Accommodate to GC_get_stack_base prototype change. * win32_threads.c (GC_new_thread): Likewise. * os_dep.c (HAVE_GET_STACK_BASE): Define in every case when target-specific GC_get_stack_base is defined (including for cases when GC_get_stack_base is pthread_support.c or win32_threads.c). (GC_get_stack_base): Rename to GC_get_main_stack_base (except for Win32, WinCE, BeOS and OS/2). (GET_MAIN_STACKBASE_SPECIAL): Define in every case when target-specific GC_get_main_stack_base is defined. [!HAVE_GET_STACK_BASE] (GC_get_stack_base): Define with the default implementation. [!GET_MAIN_STACKBASE_SPECIAL] (GC_get_main_stack_base): Likewise. * pthread_support.c (GC_get_thread_stack_base): Replace to GC_get_stack_base; set reg_base for IA64. [!GC_DARWIN_THREADS] (GC_register_my_thread): Call GC_get_stack_base instead of GC_get_thread_stack_base and GC_save_regs_in_stack. --- boehm-gc/AmigaOS.c | 4 +-- boehm-gc/ChangeLog | 32 +++++++++++++++++++ boehm-gc/include/gc.h | 20 ++++++++++-- boehm-gc/include/private/gc_priv.h | 2 +- boehm-gc/misc.c | 8 +++-- boehm-gc/os_dep.c | 63 ++++++++++++++++++++++++++++++++------ boehm-gc/pthread_support.c | 30 ++++++++++-------- boehm-gc/win32_threads.c | 14 +++++---- 8 files changed, 139 insertions(+), 34 deletions(-) diff --git a/boehm-gc/AmigaOS.c b/boehm-gc/AmigaOS.c index f4024a7..b76f446 100644 --- a/boehm-gc/AmigaOS.c +++ b/boehm-gc/AmigaOS.c @@ -40,7 +40,7 @@ Find the base of the stack. ******************************************************************/ -ptr_t GC_get_stack_base() +ptr_t GC_get_main_stack_base() { struct Process *proc = (struct Process*)SysBase->ThisTask; @@ -58,7 +58,7 @@ ptr_t GC_get_stack_base() } #if 0 /* old version */ -ptr_t GC_get_stack_base() +ptr_t GC_get_main_stack_base() { extern struct WBStartup *_WBenchMsg; extern long __base; diff --git a/boehm-gc/ChangeLog b/boehm-gc/ChangeLog index 8a4b8d6..af44b3e 100644 --- a/boehm-gc/ChangeLog +++ b/boehm-gc/ChangeLog @@ -1,3 +1,35 @@ +2015-12-10 Ivan Maidanski <[email protected]> + + * AmigaOS.c (GC_get_stack_base): Rename to GC_get_main_stack_base. + * include/private/gc_priv.h (GC_get_stack_base): Likewise. + * include/gc.h (struct GC_stack_base): New public type. + (GC_SUCCESS, GC_UNIMPLEMENTED): New public macro. + (GC_get_thread_stack_base): Replace with + int GC_get_stack_base(struct GC_stack_base*); declare even in + a single-threaded case; refine comment. + * misc.c (GC_init_inner): Rename GC_get_stack_base to + GC_get_main_stack_base. + (GC_init_inner): Replace GC_get_thread_stack_base to + GC_get_stack_base. + * win32_threads.c [CYGWIN32] (GC_get_thread_stack_base): Likewise. + * os_dep.c [MSWIN32 || MSWINCE || BEOS || OS2] (GC_get_stack_base): + Accommodate to GC_get_stack_base prototype change. + * win32_threads.c (GC_new_thread): Likewise. + * os_dep.c (HAVE_GET_STACK_BASE): Define in every case when + target-specific GC_get_stack_base is defined (including for cases + when GC_get_stack_base is pthread_support.c or win32_threads.c). + (GC_get_stack_base): Rename to GC_get_main_stack_base (except for + Win32, WinCE, BeOS and OS/2). + (GET_MAIN_STACKBASE_SPECIAL): Define in every case when + target-specific GC_get_main_stack_base is defined. + [!HAVE_GET_STACK_BASE] (GC_get_stack_base): Define with the default + implementation. + [!GET_MAIN_STACKBASE_SPECIAL] (GC_get_main_stack_base): Likewise. + * pthread_support.c (GC_get_thread_stack_base): Replace to + GC_get_stack_base; set reg_base for IA64. + [!GC_DARWIN_THREADS] (GC_register_my_thread): Call GC_get_stack_base + instead of GC_get_thread_stack_base and GC_save_regs_in_stack. + 2015-12-05 Ivan Maidanski <[email protected]> * include/gc.h (GC_suspend_thread, GC_resume_thread, diff --git a/boehm-gc/include/gc.h b/boehm-gc/include/gc.h index f193065..6ba20e6 100644 --- a/boehm-gc/include/gc.h +++ b/boehm-gc/include/gc.h @@ -926,6 +926,24 @@ GC_API void (*GC_is_visible_print_proc) # include "gc_pthread_redirects.h" #endif +/* Structure representing the base of a thread stack. */ +struct GC_stack_base { + void * mem_base; /* Base of memory stack. */ +# if defined(__ia64) || defined(__ia64__) || defined(_M_IA64) + void * reg_base; /* Base of separate register stack. */ +# endif +}; + +#define GC_SUCCESS 0 +#define GC_UNIMPLEMENTED 3 /* Not yet implemented on the platform. */ + +/* Attempt to fill in the GC_stack_base structure with the stack base */ +/* for this thread. This appears to be required to implement anything */ +/* like the JNI AttachCurrentThread in an environment in which new */ +/* threads are not automatically registered with the collector. */ +/* Returns GC_SUCCESS or GC_UNIMPLEMENTED. */ +GC_API int GC_get_stack_base GC_PROTO((struct GC_stack_base *)); + # if defined(PCR) || defined(GC_SOLARIS_THREADS) || \ defined(GC_PTHREADS) || defined(GC_WIN32_THREADS) /* Any flavor of threads except SRC_M3. */ @@ -946,8 +964,6 @@ GC_API void GC_register_my_thread GC_PROTO((void)); /* stopped during garbage collections. */ GC_API void GC_unregister_my_thread GC_PROTO((void)); -GC_API GC_PTR GC_get_thread_stack_base GC_PROTO((void)); - /* This returns a list of objects, linked through their first */ /* word. Its use can greatly reduce lock contention problems, since */ /* the allocation lock can be acquired and released many fewer times. */ diff --git a/boehm-gc/include/private/gc_priv.h b/boehm-gc/include/private/gc_priv.h index 4dbfa7d..a6fda46 100644 --- a/boehm-gc/include/private/gc_priv.h +++ b/boehm-gc/include/private/gc_priv.h @@ -1493,7 +1493,7 @@ GC_bool GC_register_main_static_data GC_PROTO((void)); /* dynamic library registration. */ /* Machine dependent startup routines */ -ptr_t GC_get_stack_base GC_PROTO((void)); /* Cold end of stack */ +ptr_t GC_get_main_stack_base GC_PROTO((void)); /* Cold end of stack */ #ifdef IA64 ptr_t GC_get_register_stack_base GC_PROTO((void)); /* Cold end of register stack. */ diff --git a/boehm-gc/misc.c b/boehm-gc/misc.c index c1faed0..0f4edff 100644 --- a/boehm-gc/misc.c +++ b/boehm-gc/misc.c @@ -677,10 +677,14 @@ void GC_init_inner() # if defined(GC_PTHREADS) && ! defined(GC_SOLARIS_THREADS) /* Use thread_stack_base if available, as GC could be initialized from a thread that is not the "main" thread. */ - GC_stackbottom = GC_get_thread_stack_base(); + struct GC_stack_base sb; + sb.mem_base = NULL; + (void)GC_get_stack_base(&sb); + /* In case of failure, mem_base remains NULL. */ + GC_stackbottom = sb.mem_base; # endif if (GC_stackbottom == 0) - GC_stackbottom = GC_get_stack_base(); + GC_stackbottom = GC_get_main_stack_base(); # if (defined(LINUX) || defined(HPUX)) && defined(IA64) GC_register_stackbottom = GC_get_register_stack_base(); # endif diff --git a/boehm-gc/os_dep.c b/boehm-gc/os_dep.c index 60cbc2b..f8da082 100644 --- a/boehm-gc/os_dep.c +++ b/boehm-gc/os_dep.c @@ -639,42 +639,53 @@ word GC_get_writable_length(ptr_t p, ptr_t *base) return(buf.RegionSize); } -ptr_t GC_get_stack_base() +int GC_get_stack_base(struct GC_stack_base *sb) { int dummy; ptr_t sp = (ptr_t)(&dummy); ptr_t trunc_sp = (ptr_t)((word)sp & ~(GC_page_size - 1)); word size = GC_get_writable_length(trunc_sp, 0); - return(trunc_sp + size); + sb -> mem_base = trunc_sp + size; + return GC_SUCCESS; } +# define HAVE_GET_STACK_BASE +# elif defined(CYGWIN32) && defined(GC_WIN32_THREADS) + + /* GC_get_stack_base() is defined in win32_threads.c. */ +# define HAVE_GET_STACK_BASE # endif /* MS Windows */ # ifdef BEOS # include <kernel/OS.h> -ptr_t GC_get_stack_base(){ +int GC_get_stack_base(struct GC_stack_base *sb) +{ thread_info th; get_thread_info(find_thread(NULL),&th); - return th.stack_end; + sb -> mem_base = th.stack_end; + return GC_SUCCESS; } +# define HAVE_GET_STACK_BASE # endif /* BEOS */ # ifdef OS2 -ptr_t GC_get_stack_base() +int GC_get_stack_base(struct GC_stack_base *sb) { PTIB ptib; PPIB ppib; if (DosGetInfoBlocks(&ptib, &ppib) != NO_ERROR) { GC_err_printf0("DosGetInfoBlocks failed\n"); - ABORT("DosGetInfoBlocks failed\n"); + return GC_UNIMPLEMENTED; } - return((ptr_t)(ptib -> tib_pstacklimit)); + sb -> mem_base = (void *)(ptib -> tib_pstacklimit); + return GC_SUCCESS; } +# define HAVE_GET_STACK_BASE # endif /* OS2 */ @@ -682,6 +693,7 @@ ptr_t GC_get_stack_base() # define GC_AMIGA_SB # include "AmigaOS.c" # undef GC_AMIGA_SB +# define GET_MAIN_STACKBASE_SPECIAL # endif /* AMIGA */ # if defined(NEED_FIND_LIMIT) || defined(UNIX_LIKE) @@ -819,10 +831,11 @@ ptr_t GC_get_stack_base() # endif #if defined(ECOS) || defined(NOSYS) - ptr_t GC_get_stack_base() + ptr_t GC_get_main_stack_base GC_PROTO((void)) { return STACKBOTTOM; } +# define GET_MAIN_STACKBASE_SPECIAL #endif #ifdef HPUX_STACKBOTTOM @@ -1059,7 +1072,7 @@ ptr_t GC_get_stack_base() #if !defined(BEOS) && !defined(AMIGA) && !defined(MSWIN32) \ && !defined(MSWINCE) && !defined(OS2) && !defined(NOSYS) && !defined(ECOS) -ptr_t GC_get_stack_base() +ptr_t GC_get_main_stack_base GC_PROTO((void)) { # if defined(HEURISTIC1) || defined(HEURISTIC2) || \ defined(LINUX_STACKBOTTOM) || defined(FREEBSD_STACKBOTTOM) || \ @@ -1118,9 +1131,41 @@ ptr_t GC_get_stack_base() return(result); # endif /* STACKBOTTOM */ } +# define GET_MAIN_STACKBASE_SPECIAL # endif /* ! AMIGA, !OS 2, ! MS Windows, !BEOS, !NOSYS, !ECOS */ +#if defined(GC_PTHREADS) && !defined(GC_SOLARIS_THREADS) \ + && !defined(GC_WIN32_THREADS) + /* GC_get_stack_base() is defined in pthread_support.c. */ +# define HAVE_GET_STACK_BASE +#endif + +#ifndef HAVE_GET_STACK_BASE + int GC_get_stack_base(struct GC_stack_base *sb) + { +# if defined(GET_MAIN_STACKBASE_SPECIAL) && !defined(THREADS) \ + && !defined(IA64) + sb->mem_base = GC_get_main_stack_base(); + return GC_SUCCESS; +# else + return GC_UNIMPLEMENTED; +# endif + } +#endif /* !HAVE_GET_STACK_BASE */ + +#ifndef GET_MAIN_STACKBASE_SPECIAL + /* This is always called from the main thread. Default implementation. */ + ptr_t GC_get_main_stack_base GC_PROTO((void)) + { + struct GC_stack_base sb; + + if (GC_get_stack_base(&sb) != GC_SUCCESS) + ABORT("GC_get_stack_base failed"); + return (ptr_t)sb.mem_base; + } +#endif /* !GET_MAIN_STACKBASE_SPECIAL */ + /* * Register static data segment(s) as roots. * If more data segments are added later then they need to be registered diff --git a/boehm-gc/pthread_support.c b/boehm-gc/pthread_support.c index 6d8f020..e077abb 100644 --- a/boehm-gc/pthread_support.c +++ b/boehm-gc/pthread_support.c @@ -1127,7 +1127,7 @@ WRAP_FUNC(pthread_detach)(pthread_t thread) GC_bool GC_in_thread_creation = FALSE; -GC_PTR GC_get_thread_stack_base() +int GC_get_stack_base(struct GC_stack_base *sb) { # ifdef HAVE_PTHREAD_GETATTR_NP pthread_t my_pthread; @@ -1141,7 +1141,7 @@ GC_PTR GC_get_thread_stack_base() # ifdef DEBUG_THREADS GC_printf0("Can not determine stack base for attached thread"); # endif - return 0; + return GC_UNIMPLEMENTED; } pthread_attr_getstack (&attr, (void **) &stack_addr, &stack_size); pthread_attr_destroy (&attr); @@ -1151,16 +1151,22 @@ GC_PTR GC_get_thread_stack_base() # endif # ifdef STACK_GROWS_DOWN - return stack_addr + stack_size; + sb -> mem_base = stack_addr + stack_size; # else - return stack_addr; + sb -> mem_base = stack_addr; # endif +# ifdef IA64 + sb -> reg_base = (void*)(GC_save_regs_in_stack() & ~(GC_page_size - 1)); + /* This is not 100% convincing. We should also read this */ + /* from /proc, but the hook to do so isn't there yet. */ +# endif + return GC_SUCCESS; # else # ifdef DEBUG_THREADS GC_printf0("Can not determine stack base for attached thread"); # endif - return 0; + return GC_UNIMPLEMENTED; # endif } @@ -1168,6 +1174,11 @@ void GC_register_my_thread() { GC_thread me; pthread_t my_pthread; +# if !defined(GC_DARWIN_THREADS) || defined(IA64) + struct GC_stack_base sb; + if (GC_get_stack_base(&sb) == GC_UNIMPLEMENTED) + ABORT("Can not determine stack base for attached thread"); +# endif my_pthread = pthread_self(); # ifdef DEBUG_THREADS @@ -1197,9 +1208,7 @@ void GC_register_my_thread() #ifdef GC_DARWIN_THREADS me -> stop_info.mach_thread = mach_thread_self(); #else - me -> stack_end = GC_get_thread_stack_base(); - if (me -> stack_end == 0) - GC_abort("Can not determine stack base for attached thread"); + me -> stack_end = sb.mem_base; # ifdef STACK_GROWS_DOWN me -> stop_info.stack_ptr = me -> stack_end - 0x10; @@ -1209,10 +1218,7 @@ void GC_register_my_thread() #endif # ifdef IA64 - me -> backing_store_end = (ptr_t) - (GC_save_regs_in_stack() & ~(GC_page_size - 1)); - /* This is also < 100% convincing. We should also read this */ - /* from /proc, but the hook to do so isn't there yet. */ + me -> backing_store_end = sb.reg_base; # endif /* IA64 */ # if defined(THREAD_LOCAL_ALLOC) && !defined(DBG_HDRS_ALL) diff --git a/boehm-gc/win32_threads.c b/boehm-gc/win32_threads.c index 2de1c69..354e5a7 100644 --- a/boehm-gc/win32_threads.c +++ b/boehm-gc/win32_threads.c @@ -80,6 +80,7 @@ extern LONG WINAPI GC_write_fault_handler(struct _EXCEPTION_POINTERS *exc_info); */ static GC_thread GC_new_thread(void) { int i; + struct GC_stack_base sb; /* It appears to be unsafe to acquire a lock here, since this */ /* code is apparently not preeemptible on some systems. */ /* (This is based on complaints, not on Microsoft's official */ @@ -131,11 +132,11 @@ static GC_thread GC_new_thread(void) { GC_printf1("Last error code: %lx\n", last_error); ABORT("DuplicateHandle failed"); } - thread_table[i].stack_base = GC_get_stack_base(); + if (GC_get_stack_base(&sb) == GC_UNIMPLEMENTED) + ABORT("Failed to find stack base in GC_new_thread"); + thread_table[i].stack_base = sb.mem_base; /* Up until this point, GC_push_all_stacks considers this thread */ /* invalid. */ - if (thread_table[i].stack_base == NULL) - ABORT("Failed to find stack base in GC_new_thread"); /* Up until this point, this entry is viewed as reserved but invalid */ /* by GC_delete_thread. */ thread_table[i].id = GetCurrentThreadId(); @@ -757,14 +758,15 @@ int GC_pthread_detach(pthread_t thread) return result; } -GC_PTR GC_get_thread_stack_base() +int GC_get_stack_base(struct GC_stack_base *sb) { #ifdef __x86_64__ - return ((NT_TIB*)NtCurrentTeb())->StackBase; + sb -> mem_base = ((NT_TIB*)NtCurrentTeb())->StackBase; #else extern GC_PTR _tlsbase __asm__ ("%fs:4"); - return _tlsbase; + sb -> mem_base = _tlsbase; #endif + return GC_SUCCESS; } #else /* !CYGWIN32 */ -- 2.8.2