diff --git a/gc-7.4.0-disclaim_test-fail.patch b/gc-7.4.0-disclaim_test-fail.patch new file mode 100644 index 0000000..0ee9454 --- /dev/null +++ b/gc-7.4.0-disclaim_test-fail.patch @@ -0,0 +1,118 @@ +From 33535060b4898c7883c3d98c4591bfc964541830 Mon Sep 17 00:00:00 2001 +From: Petter Urkedal +Date: Sun, 25 May 2014 15:57:03 +0200 +Subject: [PATCH 1/3] Fix GC_finalized_malloc failure on disclaim_test (revert + part of commit 63fd11d) + +The finalizer closure is placed in the first word in order to use the +lower bits to distinguish live objects from objects on the free list. +The downside of this is that we need one-word offset interior pointers, +and that GC_base does not return the start of the user region. + +* fnlz_mlc.c (GC_finalized_disclaim): Move finalizer closure for +finalized object kinds back to the start of objects. +* fnlz_mlc.c (GC_init_finalized_malloc): Call +GC_register_displacement_inner() as GC_finalized_malloc returns +displaced pointer. +* fnlz_mlc.c (GC_core_finalized_malloc, GC_finalized_malloc): Store +fclos in first word of created object (instead of the last word); +return pointer to object displaced by 1 word. +--- + +diff --git a/fnlz_mlc.c b/fnlz_mlc.c +old mode 100755 +new mode 100644 +index 0dad28a..b8478d2 +--- a/fnlz_mlc.c ++++ b/fnlz_mlc.c +@@ -28,13 +28,10 @@ STATIC int GC_finalized_kind = 0; + + STATIC int GC_CALLBACK GC_finalized_disclaim(void *obj) + { +- void **fc_addr; +- const struct GC_finalizer_closure *fc; ++ word fc_word = *(word *)obj; + +- fc_addr = &((void **)obj)[GC_size(obj) / sizeof(void *) - 1]; +- fc = *fc_addr; +- if (fc != NULL) { +- /* [1] The disclaim function may be passed fragments from the */ ++ if ((fc_word & 1) != 0) { ++ /* The disclaim function may be passed fragments from the */ + /* free-list, on which it should not run finalization. */ + /* To recognize this case, we use the fact that the first word */ + /* on such fragments are always even (a link to the next */ +@@ -42,8 +39,8 @@ STATIC int GC_CALLBACK GC_finalized_disclaim(void *obj) + /* which does not use the first word for storing finalization */ + /* info, GC_reclaim_with_finalization must be extended to clear */ + /* fragments so that the assumption holds for the selected word. */ +- (*fc->proc)(obj, fc->cd); +- *fc_addr = NULL; ++ const struct GC_finalizer_closure *fc = (void *)(fc_word & ~(word)1); ++ (*fc->proc)((word *)obj + 1, fc->cd); + } + return 0; + } +@@ -62,6 +59,13 @@ GC_API void GC_CALL GC_init_finalized_malloc(void) + } + done_init = TRUE; + ++ /* The finalizer closure is placed in the first word in order to */ ++ /* use the lower bits to distinguish live objects from objects on */ ++ /* the free list. The downside of this is that we need one-word */ ++ /* offset interior pointers, and that GC_base does not return the */ ++ /* start of the user region. */ ++ GC_register_displacement_inner(sizeof(word)); ++ + GC_finalized_objfreelist = (ptr_t *)GC_new_free_list_inner(); + GC_finalized_kind = GC_new_kind_inner((void **)GC_finalized_objfreelist, + GC_DS_LENGTH, TRUE, TRUE); +@@ -90,7 +94,7 @@ GC_API void GC_CALL GC_register_disclaim_proc(int kind, GC_disclaim_proc proc, + word lg; + DCL_LOCK_STATE; + +- lb += sizeof(void *); ++ lb += sizeof(word); + GC_ASSERT(done_init); + if (SMALL_OBJ(lb)) { + GC_DBG_COLLECT_AT_MALLOC(lb); +@@ -112,7 +116,6 @@ GC_API void GC_CALL GC_register_disclaim_proc(int kind, GC_disclaim_proc proc, + UNLOCK(); + } + GC_ASSERT(lg > 0); +- ((const void **)op)[GRANULES_TO_WORDS(lg) - 1] = fclos; + } else { + size_t op_sz; + +@@ -121,16 +124,16 @@ GC_API void GC_CALL GC_register_disclaim_proc(int kind, GC_disclaim_proc proc, + return NULL; + op_sz = GC_size(op); + GC_ASSERT(op_sz >= lb); +- ((const void **)op)[op_sz / sizeof(void *) - 1] = fclos; + } +- return GC_clear_stack(op); ++ *(word *)op = (word)fclos | 1; ++ return GC_clear_stack((word *)op + 1); + } + + #ifdef THREAD_LOCAL_ALLOC + GC_API void * GC_CALL GC_finalized_malloc(size_t client_lb, + const struct GC_finalizer_closure *fclos) + { +- size_t lb = client_lb + sizeof(void *); ++ size_t lb = client_lb + sizeof(word); + size_t lg = ROUNDED_UP_GRANULES(lb); + GC_tlfs tsd; + void *result; +@@ -163,9 +166,9 @@ GC_API void GC_CALL GC_register_disclaim_proc(int kind, GC_disclaim_proc proc, + result = (void *)my_entry; + *my_fl = next; + obj_link(result) = 0; +- ((const void **)result)[GRANULES_TO_WORDS(lg) - 1] = fclos; ++ *(word *)result = (word)fclos | 1; + PREFETCH_FOR_WRITE(next); +- return result; ++ return (word *)result + 1; + } + #endif /* THREAD_LOCAL_ALLOC */ + diff --git a/gc.spec b/gc.spec index 1981709..c480519 100644 --- a/gc.spec +++ b/gc.spec @@ -2,12 +2,14 @@ Summary: A garbage collector for C and C++ Name: gc Version: 7.4.0 -Release: 3%{?dist} +Release: 4%{?dist} License: BSD Url: http://www.hboehm.info/gc/ Source0: http://www.hboehm.info/gc/gc_source/gc-%{version}%{?pre}.tar.gz +Patch0: gc-7.4.0-disclaim_test-fail.patch + ## upstreamable patches ## upstream patches @@ -35,6 +37,7 @@ Provides: libgc-devel = %{version}-%{release} %prep %setup -q -n gc-%{version}%{?pre} +%patch0 -p1 -b .disclaim_test # refresh auto*/libtool to purge rpaths rm -f libtool libtool.m4 @@ -69,10 +72,6 @@ rm -fv %{buildroot}%{_libdir}/lib*.la %check -# ignore failures on powerpc temporarily (#1101996) -%ifarch ppc ppc64 ppc64le -%global arch_ignore ||: -%endif make check %{?arch_ignore} %post -p /sbin/ldconfig @@ -97,6 +96,9 @@ make check %{?arch_ignore} %changelog +* Wed Jun 11 2014 Pavel Raiskup - 7.4.0-4 +- backport upstream fix for disclaim_test fail on ppc (#1101996) + * Sat Jun 07 2014 Fedora Release Engineering - 7.4.0-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild