[kaffe] CVS kaffe (guilhem): Boehm GC fixes.

Kaffe CVS cvs-commits at kaffe.org
Sat Oct 1 11:33:53 PDT 2005


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  <guilhem at kaffe.org>
+
+	* 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  <jserv at kaffe.org>
 
 	* 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 {




More information about the kaffe mailing list