[Mono-bugs] [Bug 53177][Nor] Changed - WaitHandles are not finalizing

bugzilla-daemon@bugzilla.ximian.com bugzilla-daemon@bugzilla.ximian.com
Sat, 24 Jan 2004 03:42:51 -0500 (EST)


Please do not reply to this email- if you want to comment on the bug, go to the
URL shown below and enter your comments there.

Changed by derek.mcumber@datamtnsol.com.

http://bugzilla.ximian.com/show_bug.cgi?id=53177

--- shadow/53177	2004-01-23 11:44:37.000000000 -0500
+++ shadow/53177.tmp.4803	2004-01-24 03:42:51.000000000 -0500
@@ -1,12 +1,12 @@
 Bug#: 53177
 Product: Mono/Runtime
 Version: unspecified
 OS: unknown
 OS Details: 
-Status: REOPENED   
+Status: CLOSED   
 Resolution: 
 Severity: Unknown
 Priority: Normal
 Component: misc
 AssignedTo: mono-bugs@ximian.com                            
 ReportedBy: derek.mcumber@datamtnsol.com               
@@ -251,6 +251,200 @@
 ------- Additional Comments From derek.mcumber@datamtnsol.com  2004-01-23 11:44 -------
 I think you need to do:
 
 export GC_PRINT_STATS=true
 
 as well.....
+
+------- Additional Comments From derek.mcumber@datamtnsol.com  2004-01-24 03:42 -------
+It's finished!
+
+There were a few problems in GC6.2 that are probably on all platforms
+that cause detrimental memory leaks.
+
+Most notable:
+
+1.  malloc.c puts every object on the heap 2 to infinite times with my
+gcc compiler with this code in malloc.c:
+
+     h = GC_allochblk(blah);
+     ...
+     while (0 == h && GC_collect_or_expand(n_blocks, (flags != 0))) {
+	h = GC_allochblk(lw, k, flags);
+     }
+
+use this instead====
+/* Allocate a large block of size lw words.	*/
+/* The block is not cleared.			*/
+/* Flags is 0 or IGNORE_OFF_PAGE.		*/
+ptr_t GC_alloc_large(lw, k, flags)
+word lw;
+int k;
+unsigned flags;
+{
+    struct hblk * h;
+    word n_blocks = OBJ_SZ_TO_BLOCKS(lw);
+    ptr_t result;
+	
+    if (!GC_is_initialized) GC_init_inner();
+    /* Do our share of marking work */
+        if(GC_incremental && !GC_dont_gc)
+	    GC_collect_a_little_inner((int)n_blocks);
+
+    h = GC_allochblk(lw, k, flags);
+#   ifdef USE_MUNMAP
+	if (0 == h) {
+	    GC_merge_unmapped();
+	    h = GC_allochblk(lw, k, flags);
+	}
+#   endif
+
+    if (0 == h) {
+	/* GC_print_hblkfreelist();
+	GC_printf0("Previous allochblk returned 0, calling
+collect_or_expand\n"); */	
+    	while (0 == h && GC_collect_or_expand(n_blocks, (flags != 0))) {
+		h = GC_allochblk(lw, k, flags);
+    	}
+    }
+    if (0 == h) {
+	result = 0;
+    } else {
+	int total_bytes = BYTES_TO_WORDS(n_blocks * HBLKSIZE);
+	if (n_blocks > 1) {
+	    GC_large_allocd_bytes += n_blocks * HBLKSIZE;
+	    if (GC_large_allocd_bytes > GC_max_large_allocd_bytes)
+	        GC_max_large_allocd_bytes = GC_large_allocd_bytes;
+	}
+	result = (ptr_t) (h -> hb_body);
+	GC_words_wasted += total_bytes - lw;
+    }
+    return result;
+}
+============
+
+2.  Algoritm in alloc.c increased heap by 8 meg at minimum and didn't
+allow garbage to collect properly (for continuous programs like xsp.exe)
+    
+use this instead=======
+/*
+ * this explicitly increases the size of the heap.  It is used
+ * internally, but may also be invoked from GC_expand_hp by the user.
+ * The argument is in units of HBLKSIZE.
+ * Tiny values of n are rounded up.
+ * Returns FALSE on failure.
+ */
+GC_bool GC_expand_hp_inner(n)
+word n;
+{
+    word bytes;
+    struct hblk * space;
+    word expansion_slop;	/* Number of bytes by which we expect the */
+    				/* heap to expand soon.			  */
+
+#	ifdef CONDPRINT
+	  if (GC_print_stats) {
+	GC_printf1(
+	    "Inside expand_hp_inner for %ld hblocks\n",
+	   	  (long)WORDS_TO_BYTES(n));
+	  }
+#       endif
+
+    if (n < MINHINCR) n = MINHINCR;
+
+    bytes = n * HBLKSIZE;
+    /* Make sure bytes is a multiple of GC_page_size */
+      {
+	word mask = GC_page_size - 1;
+	bytes += mask;
+	bytes &= ~mask;
+      }
+    
+    if (GC_max_heapsize != 0 && GC_heapsize + bytes > GC_max_heapsize) {
+        /* Exceeded self-imposed limit */
+        return(FALSE);
+    }
+    space = GET_MEM(bytes);
+    if( space == 0 ) {
+#	ifdef CONDPRINT
+	  if (GC_print_stats) {
+	    GC_printf1("Failed to expand heap by %ld bytes\n",
+		       (unsigned long)bytes);
+	  }
+#       endif
+	return(FALSE);
+    }
+#   ifdef CONDPRINT
+      if (GC_print_stats) {
+	GC_printf2("Increasing heap size by %lu after %lu allocated bytes\n",
+	           (unsigned long)bytes,
+	           (unsigned long)WORDS_TO_BYTES(GC_words_allocd));
+# 	ifdef UNDEFINED
+	  GC_printf1("Root size = %lu\n", GC_root_size);
+	  GC_print_block_list(); GC_print_hblkfreelist();
+	  GC_printf0("\n");
+#	endif
+      }
+#   endif
+    expansion_slop = 8 * WORDS_TO_BYTES(min_words_allocd());
+    if (5 * HBLKSIZE * MAXHINCR > expansion_slop) {
+        expansion_slop = 5 * HBLKSIZE * MAXHINCR;
+    }
+    if (GC_last_heap_addr == 0 && !((word)space & SIGNB)
+        || GC_last_heap_addr != 0 && GC_last_heap_addr < (ptr_t)space) {
+        /* Assume the heap is growing up */
+        GC_greatest_plausible_heap_addr =
+            GC_max(GC_greatest_plausible_heap_addr,
+                   (ptr_t)space + bytes + expansion_slop);
+    } else {
+        /* Heap is growing down */
+        GC_least_plausible_heap_addr =
+            GC_min(GC_least_plausible_heap_addr,
+                   (ptr_t)space - expansion_slop);
+    }
+    GC_prev_heap_addr = GC_last_heap_addr;
+    GC_last_heap_addr = (ptr_t)space;
+    GC_add_to_heap(space, bytes);
+    return(TRUE);
+}
+
+3.  make sure all GC_allochblk's are flags == IGNORE_OFF_PAGE in
+    allochblk.c 
+
+use this instead========
+/*
+ * Allocate (and return pointer to) a heap block
+ *   for objects of size sz words, searching the nth free list.
+ *
+ * NOTE: We set obj_map field in header correctly.
+ *       Caller is responsible for building an object freelist in block.
+ *
+ * Unlike older versions of the collectors, the client is responsible
+ * for clearing the block, if necessary.
+ */
+struct hblk *
+GC_allochblk(sz, kind, flags)
+word sz;
+int kind;
+unsigned flags;  /* IGNORE_OFF_PAGE or 0 */
+{
+    word blocks = OBJ_SZ_TO_BLOCKS(sz);
+    int start_list = GC_hblk_fl_from_blocks(blocks);
+    int i;
+    if (flags == IGNORE_OFF_PAGE) {
+	/* GC_printf0("flags == IGNORE_OFF_PAGE\n"); */	
+    } else {
+	flags = IGNORE_OFF_PAGE;
+    }
+    for (i = start_list; i <= N_HBLK_FLS; ++i) {
+	struct hblk * result = GC_allochblk_nth(sz, kind, flags, i);
+	if (0 != result) {
+	    return result;
+	}
+    }
+    return 0;
+}
+==========
+
+I can build you a diff of my libgc and MONO's to get the little stuff.
+ How and where do you want this?
+