summaryrefslogtreecommitdiff
path: root/allchblk.c
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2011-07-26 13:20:24 +0200
committerIvan Maidanski <ivmai@mail.ru>2011-07-26 13:20:24 +0200
commitc521d2cf164f9d7e1fa8be9c0b21d223e265fa64 (patch)
tree82fbd7e60e6be39fbabd946717cf065a698cd038 /allchblk.c
parent7d3768dbd2a1cd4d5c14f773f23aec43bc0651a5 (diff)
gc4.13 tarball importgc4_13
Diffstat (limited to 'allchblk.c')
-rw-r--r--allchblk.c36
1 files changed, 29 insertions, 7 deletions
diff --git a/allchblk.c b/allchblk.c
index 3179c93..026288e 100644
--- a/allchblk.c
+++ b/allchblk.c
@@ -1,6 +1,7 @@
/*
* Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers
* Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved.
+ * Copyright (c) 1998 by Silicon Graphics. All rights reserved.
*
* THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
* OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
@@ -72,7 +73,7 @@ void GC_print_hblkfreelist()
/* Initialize hdr for a block containing the indicated size and */
/* kind of objects. */
/* Return FALSE on failure. */
-static bool setup_header(hhdr, sz, kind, flags)
+static GC_bool setup_header(hhdr, sz, kind, flags)
register hdr * hhdr;
word sz; /* object size in words */
int kind;
@@ -99,6 +100,14 @@ unsigned char flags;
return(TRUE);
}
+#ifdef EXACT_FIRST
+# define LAST_TRIP 2
+#else
+# define LAST_TRIP 1
+#endif
+
+word GC_max_hblk_size = HBLKSIZE;
+
/*
* Allocate (and return pointer to) a heap block
* for objects of size sz words.
@@ -123,9 +132,11 @@ unsigned char flags; /* IGNORE_OFF_PAGE or 0 */
register hdr * phdr; /* Header corr. to prevhbp */
signed_word size_needed; /* number of bytes in requested objects */
signed_word size_avail; /* bytes available in this block */
- bool first_time = TRUE;
+ int trip_count = 0;
size_needed = HBLKSIZE * OBJ_SZ_TO_BLOCKS(sz);
+ if ((word)size_needed > GC_max_hblk_size)
+ GC_max_hblk_size = size_needed;
/* search for a big enough block in free list */
hbp = GC_savhbp;
@@ -137,16 +148,26 @@ unsigned char flags; /* IGNORE_OFF_PAGE or 0 */
hbp = (prevhbp == 0? GC_hblkfreelist : phdr->hb_next);
hhdr = HDR(hbp);
- if( prevhbp == GC_savhbp && !first_time) {
- return(0);
+ if( prevhbp == GC_savhbp) {
+ if (trip_count == LAST_TRIP) return(0);
+ ++trip_count;
}
- first_time = FALSE;
-
if( hbp == 0 ) continue;
size_avail = hhdr->hb_sz;
+# ifdef EXACT_FIRST
+ if (trip_count <= 1 && size_avail != size_needed) continue;
+# endif
if (size_avail < size_needed) continue;
+# ifdef PRESERVE_LAST
+ if (size_avail != size_needed
+ && !GC_incremental
+ && (word)size_needed <= GC_max_hblk_size/2
+ && GC_in_last_heap_sect(hbp) && GC_should_collect()) {
+ continue;
+ }
+# endif
/* If the next heap block is obviously better, go on. */
/* This prevents us from disassembling a single large block */
/* to get tiny blocks. */
@@ -240,7 +261,7 @@ unsigned char flags; /* IGNORE_OFF_PAGE or 0 */
if (GC_savhbp == hbp) GC_savhbp = prevhbp;
hbp = prevhbp;
hhdr = phdr;
- if (hbp == GC_savhbp) first_time = TRUE;
+ if (hbp == GC_savhbp) --trip_count;
}
# endif
}
@@ -280,6 +301,7 @@ unsigned char flags; /* IGNORE_OFF_PAGE or 0 */
/* Notify virtual dirty bit implementation that we are about to write. */
GC_write_hint(thishbp);
+ /* This should deal better with large blocks. */
/* Add it to map of valid blocks */
if (!GC_install_counts(thishbp, (word)size_needed)) return(0);