PatchSet 6939 Date: 2005/10/01 18:25:00 Author: guilhem Branch: HEAD Tag: (none) Log: Boehm GC fixes.
* kaffe/kaffevm/boehm-gc/gc-refs.c, kaffe/kaffevm/boehm-gc/gc-refs.h, kaffe/kaffevm/boehm-gc/gc2.c, kaffe/kaffevm/boehm-gc/gc2.h: Fixed Boehm-GC adaptation layer. * kaffe/kaffevm/boehm-gc/boehm/pthread_support.c (pthread_join) In some case a thread may be detached just after the UNLOCK(). Members: ChangeLog:1.4461->1.4462 kaffe/kaffevm/boehm-gc/gc-refs.c:1.4->1.5 kaffe/kaffevm/boehm-gc/gc-refs.h:1.2->1.3 kaffe/kaffevm/boehm-gc/gc2.c:1.12->1.13 kaffe/kaffevm/boehm-gc/gc2.h:1.3->1.4 kaffe/kaffevm/boehm-gc/boehm/pthread_support.c:1.3->1.4 Index: kaffe/ChangeLog diff -u kaffe/ChangeLog:1.4461 kaffe/ChangeLog:1.4462 --- kaffe/ChangeLog:1.4461 Sat Oct 1 02:59:48 2005 +++ kaffe/ChangeLog Sat Oct 1 18:25:00 2005 @@ -1,3 +1,15 @@ +2005-10-01 Guilhem Lavaux <[EMAIL PROTECTED]> + + * kaffe/kaffevm/boehm-gc/gc-refs.c, + kaffe/kaffevm/boehm-gc/gc-refs.h, + kaffe/kaffevm/boehm-gc/gc2.c, + kaffe/kaffevm/boehm-gc/gc2.h: + Fixed Boehm-GC adaptation layer. + + * kaffe/kaffevm/boehm-gc/boehm/pthread_support.c + (pthread_join) + In some case a thread may be detached just after the UNLOCK(). + 2005-10-01 Jim Huang <[EMAIL PROTECTED]> * libraries/javalib/gnu/java/net/PlainSocketImpl.java (getOption): Index: kaffe/kaffe/kaffevm/boehm-gc/gc-refs.c diff -u kaffe/kaffe/kaffevm/boehm-gc/gc-refs.c:1.4 kaffe/kaffe/kaffevm/boehm-gc/gc-refs.c:1.5 --- kaffe/kaffe/kaffevm/boehm-gc/gc-refs.c:1.4 Sat Dec 25 19:09:14 2004 +++ kaffe/kaffe/kaffevm/boehm-gc/gc-refs.c Sat Oct 1 18:25:04 2005 @@ -42,6 +42,9 @@ typedef struct _weakRefObject { const void * mem; unsigned int ref; + unsigned int allRefSize; + unsigned short keep_object; + bool destroyed; void *** allRefs; struct _weakRefObject *next; } weakRefObject; @@ -52,6 +55,8 @@ static strongRefTable strongRefObjects; static weakRefTable weakRefObjects; +static iStaticLock strongRefLock; +static iStaticLock weakRefLock; /* This is a bit homemade. We need a 7-bit hash from the address here */ #define REFOBJHASH(V) ((((uintp)(V) >> 2) ^ ((uintp)(V) >> 9))%REFOBJHASHSZ) @@ -60,7 +65,7 @@ * Add a persistent reference to an object. */ bool -KaffeGC_addRef(Collector *collector, const void* mem) +KaffeGC_addRef(Collector *collector UNUSED, const void* mem) { uint32 idx; strongRefObject* obj; @@ -81,17 +86,82 @@ obj->mem = ALIGN_BACKWARD(mem); obj->ref = 1; + lockStaticMutex(&strongRefLock); obj->next = strongRefObjects.hash[idx]; strongRefObjects.hash[idx] = obj; + unlockStaticMutex(&strongRefLock); return true; } +/** + * Grow the weak reference list for a weakly referenced object. + * Assert: weakRefLock is held by the calling thread. + */ +static bool +resizeWeakReferenceObject(Collector *collector, weakRefObject *obj, unsigned int size) +{ + unsigned int previousSize; + void ***refs, ***oldRefs; + + if (size == 0) + { + obj->allRefSize = 0; + oldRefs = obj->allRefs; + obj->allRefs = NULL; + + unlockStaticMutex(&weakRefLock); + KGC_free(collector, oldRefs); + lockStaticMutex(&weakRefLock); + return true; + } + + obj->keep_object++; + do + { + previousSize = obj->allRefSize; + unlockStaticMutex(&weakRefLock); + refs = GC_malloc_uncollectable(size * sizeof(void **)); + lockStaticMutex(&weakRefLock); + if (refs == NULL) + { + obj->keep_object--; + return false; + } + + /* Check that nothing has changed. */ + if (previousSize != obj->allRefSize) + { + unlockStaticMutex(&weakRefLock); + GC_free(refs); + lockStaticMutex(&weakRefLock); + continue; + } + + obj->allRefSize = size; + + oldRefs = obj->allRefs; + obj->allRefs = refs; + if (oldRefs != NULL) + { + memcpy(refs, oldRefs, sizeof(void **) * obj->ref); + + unlockStaticMutex(&weakRefLock); + GC_free(oldRefs); + lockStaticMutex(&weakRefLock); + } + + obj->keep_object--; + return true; + } + while (1); +} + /* * Remove a persistent reference to an object. If the count becomes * zero then the reference is removed. */ bool -KaffeGC_rmRef(Collector *collector, const void* mem) +KaffeGC_rmRef(Collector *collector UNUSED, const void* mem) { uint32 idx; strongRefObject** objp; @@ -100,6 +170,7 @@ idx = REFOBJHASH(mem); mem = ALIGN_BACKWARD(mem); + lockStaticMutex(&strongRefLock); for (objp = &strongRefObjects.hash[idx]; *objp != 0; objp = &obj->next) { obj = *objp; /* Found it - just decrease reference */ @@ -109,9 +180,11 @@ *objp = obj->next; GC_free(obj); } + unlockStaticMutex(&strongRefLock); return true; } } + unlockStaticMutex(&strongRefLock); /* Not found!! */ return false; @@ -124,38 +197,50 @@ weakRefObject* obj; idx = REFOBJHASH(mem); + + lockStaticMutex(&weakRefLock); for (obj = weakRefObjects.hash[idx]; obj != 0; obj = obj->next) { /* Found it - just register a new weak reference */ if (obj->mem == mem) { - void ***newRefs; obj->ref++; - newRefs = (void ***)GC_malloc_uncollectable(sizeof(void ***)*obj->ref); - memcpy(newRefs, obj->allRefs, sizeof(void ***)*(obj->ref-1)); - GC_free(obj->allRefs); + if (obj->ref >= obj->allRefSize) + if (!resizeWeakReferenceObject(collector, obj, obj->ref * 2 + 1)) + { + unlockStaticMutex(&weakRefLock); + return false; + } - obj->allRefs = newRefs; obj->allRefs[obj->ref-1] = refobj; + + unlockStaticMutex(&weakRefLock); return true; } } /* Not found - create a new one */ obj = (weakRefObject*)GC_malloc_uncollectable(sizeof(weakRefObject)); - if (!obj) - return false; + if (obj == NULL) + { + unlockStaticMutex(&weakRefLock); + return false; + } obj->mem = mem; obj->ref = 1; - obj->allRefs = (void ***)GC_malloc_uncollectable(sizeof(void ***)); + unlockStaticMutex(&weakRefLock); + obj->allRefs = (void ***)GC_malloc(sizeof(void ***)); + lockStaticMutex(&weakRefLock); obj->allRefs[0] = refobj; obj->next = weakRefObjects.hash[idx]; weakRefObjects.hash[idx] = obj; + unlockStaticMutex(&weakRefLock); + return true; } bool -KaffeGC_rmWeakRef(Collector *collector, void* mem, void** refobj) +KaffeGC_rmWeakRef(Collector *collector UNUSED, void* mem, void** refobj) { uint32 idx; weakRefObject** objp; @@ -163,36 +248,47 @@ unsigned int i; idx = REFOBJHASH(mem); + + lockStaticMutex(&weakRefLock); + for (objp = &weakRefObjects.hash[idx]; *objp != 0; objp = &obj->next) { obj = *objp; /* Found it - just decrease reference */ if (obj->mem == mem) { + bool found = false; + for (i = 0; i < obj->ref; i++) { if (obj->allRefs[i] == refobj) { - void ***newRefs; - + memcpy(&obj->allRefs[i], &obj->allRefs[i+1], sizeof(obj->allRefs[0]) * (obj->ref - i)); obj->ref--; - newRefs = (void ***)GC_malloc_uncollectable(sizeof(void ***)*obj->ref); - memcpy(newRefs, obj->allRefs, i*sizeof(void ***)); - memcpy(&newRefs[i], &obj->allRefs[i+1], obj->ref*sizeof(void ***)); - GC_free(obj->allRefs); - obj->allRefs = newRefs; + found = true; break; } } - if (i == obj->ref) - return false; + if (obj->ref == 0) { - *objp = obj->next; + if (!obj->destroyed) + *objp = obj->next; + + obj->next = NULL; + obj->destroyed = true; + + unlockStaticMutex(&weakRefLock); + if (obj->allRefs != NULL) + GC_free(obj->allRefs); GC_free(obj); + lockStaticMutex(&weakRefLock); } - return true; + unlockStaticMutex(&weakRefLock); + return found; } } + unlockStaticMutex(&weakRefLock); + /* Not found!! */ return false; } @@ -213,6 +309,8 @@ unsigned int i; idx = REFOBJHASH(mem); + + lockStaticMutex(&weakRefLock); for (objp = &weakRefObjects.hash[idx]; *objp != 0; objp = &obj->next) { obj = *objp; @@ -221,11 +319,32 @@ { for (i = 0; i < obj->ref; i++) *(obj->allRefs[i]) = NULL; - GC_free(obj->allRefs); + obj->ref = 0; - *objp = obj->next; - GC_free(obj); + if (obj->allRefs != NULL) + { + GC_free(obj->allRefs); + obj->allRefs = NULL; + } + + obj->allRefSize = 0; + + if (!obj->destroyed) + *objp = obj->next; + obj->next = NULL; + obj->destroyed = true; + if (obj->keep_object == 0) + GC_free(obj); + + unlockStaticMutex(&weakRefLock); return; } } + unlockStaticMutex(&weakRefLock); +} + +void KaffeGC_initRefs() +{ + initStaticLock(&strongRefLock); + initStaticLock(&weakRefLock); } Index: kaffe/kaffe/kaffevm/boehm-gc/gc-refs.h diff -u kaffe/kaffe/kaffevm/boehm-gc/gc-refs.h:1.2 kaffe/kaffe/kaffevm/boehm-gc/gc-refs.h:1.3 --- kaffe/kaffe/kaffevm/boehm-gc/gc-refs.h:1.2 Sat Dec 25 19:09:14 2004 +++ kaffe/kaffe/kaffevm/boehm-gc/gc-refs.h Sat Oct 1 18:25:04 2005 @@ -21,5 +21,6 @@ bool KaffeGC_addWeakRef(struct _Collector *collector, void *mem, void **obj); bool KaffeGC_rmWeakRef(struct _Collector *collector, void *mem, void **obj); void KaffeGC_clearWeakRef(struct _Collector *collector, void *mem); +void KaffeGC_initRefs(); #endif /* __gcrefs_h */ Index: kaffe/kaffe/kaffevm/boehm-gc/gc2.c diff -u kaffe/kaffe/kaffevm/boehm-gc/gc2.c:1.12 kaffe/kaffe/kaffevm/boehm-gc/gc2.c:1.13 --- kaffe/kaffe/kaffevm/boehm-gc/gc2.c:1.12 Sat May 14 21:46:32 2005 +++ kaffe/kaffe/kaffevm/boehm-gc/gc2.c Sat Oct 1 18:25:04 2005 @@ -142,8 +142,13 @@ assert(desc->magic == MAGIC_GC); - if (f->final != KGC_OBJECT_NORMAL && f->final != NULL) - f->final(&boehm_gc.collector, ALIGN_FORWARD(ob)); + if (f->final != KGC_OBJECT_NORMAL && f->final != NULL && desc->needFinal) + { + f->final(&boehm_gc.collector, ALIGN_FORWARD(ob)); + desc->needFinal = false; + GC_REGISTER_FINALIZER_NO_ORDER(ob, finalizeObject, 0, 0, 0); + return; + } KaffeGC_clearWeakRef(&boehm_gc.collector, ALIGN_FORWARD(ob)); @@ -289,6 +294,7 @@ } desc->memtype = type; desc->memsize = sz; + desc->needFinal = true; return ALIGN_FORWARD(new_ptr); } @@ -320,6 +326,7 @@ desc.memtype = type; desc.memsize = sz; desc.magic = MAGIC_GC; + desc.needFinal = true; // Allocate memory if (gcFunctions[type].final == KGC_OBJECT_FIXED) { @@ -334,7 +341,7 @@ // Attach finalizer if (mem != 0) { clearAndAddDescriptor(mem, &desc); - + if ( gcFunctions[type].final != KGC_OBJECT_FIXED && (gcFunctions[type].final != KGC_OBJECT_NORMAL || gcFunctions[type].destroy != NULL)) { @@ -585,6 +592,8 @@ initStaticLock(&gcman_lock); initStaticLock(&gcmanend_lock); initStaticLock(&finman_lock); + + KaffeGC_initRefs(); return (&boehm_gc.collector); } Index: kaffe/kaffe/kaffevm/boehm-gc/gc2.h diff -u kaffe/kaffe/kaffevm/boehm-gc/gc2.h:1.3 kaffe/kaffe/kaffevm/boehm-gc/gc2.h:1.4 --- kaffe/kaffe/kaffevm/boehm-gc/gc2.h:1.3 Tue Apr 5 12:49:12 2005 +++ kaffe/kaffe/kaffevm/boehm-gc/gc2.h Sat Oct 1 18:25:04 2005 @@ -24,9 +24,10 @@ } gcMark; typedef struct { - uint32 magic; - uint8 memtype; - size_t memsize; + uint32 magic; + uint8 memtype; + uint8 needFinal; + size_t memsize; } MemDescriptor; #define SIZEOF_DESC (((sizeof(MemDescriptor) + ALIGNMENTOF_VOIDP - 1) / ALIGNMENTOF_VOIDP) * ALIGNMENTOF_VOIDP) Index: kaffe/kaffe/kaffevm/boehm-gc/boehm/pthread_support.c diff -u kaffe/kaffe/kaffevm/boehm-gc/boehm/pthread_support.c:1.3 kaffe/kaffe/kaffevm/boehm-gc/boehm/pthread_support.c:1.4 --- kaffe/kaffe/kaffevm/boehm-gc/boehm/pthread_support.c:1.3 Fri May 6 17:02:55 2005 +++ kaffe/kaffe/kaffevm/boehm-gc/boehm/pthread_support.c Sat Oct 1 18:25:04 2005 @@ -607,10 +607,12 @@ register GC_thread p = GC_threads[hv]; register GC_thread prev = 0; - while (p != gc_id) { + while (p != gc_id && p != 0) { prev = p; p = p -> next; } + if (p == 0) + return; if (prev == 0) { GC_threads[hv] = p -> next; } else { _______________________________________________ kaffe mailing list kaffe@kaffe.org http://kaffe.org/cgi-bin/mailman/listinfo/kaffe