diff options
Diffstat (limited to 'gc/stubborn.c')
-rw-r--r-- | gc/stubborn.c | 326 |
1 files changed, 0 insertions, 326 deletions
diff --git a/gc/stubborn.c b/gc/stubborn.c deleted file mode 100644 index bb13761..0000000 --- a/gc/stubborn.c +++ /dev/null @@ -1,326 +0,0 @@ -/* - * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers - * Copyright (c) 1991-1994 by Xerox Corporation. All rights reserved. - * - * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED - * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. - * - * Permission is hereby granted to use or copy this program - * for any purpose, provided the above notices are retained on all copies. - * Permission to modify the code and to distribute modified code is granted, - * provided the above notices are retained, and a notice that the code was - * modified is included with the above copyright notice. - */ -/* Boehm, July 31, 1995 5:02 pm PDT */ - - -#include "private/gc_priv.h" - -# ifdef STUBBORN_ALLOC -/* Stubborn object (hard to change, nearly immutable) allocation. */ - -extern ptr_t GC_clear_stack(); /* in misc.c, behaves like identity */ - -#define GENERAL_MALLOC(lb,k) \ - (GC_PTR)GC_clear_stack(GC_generic_malloc((word)lb, k)) - -/* Data structure representing immutable objects that */ -/* are still being initialized. */ -/* This is a bit baroque in order to avoid acquiring */ -/* the lock twice for a typical allocation. */ - -GC_PTR * GC_changing_list_start; - -void GC_push_stubborn_structures GC_PROTO((void)) -{ - GC_push_all((ptr_t)(&GC_changing_list_start), - (ptr_t)(&GC_changing_list_start) + sizeof(GC_PTR *)); -} - -# ifdef THREADS - VOLATILE GC_PTR * VOLATILE GC_changing_list_current; -# else - GC_PTR * GC_changing_list_current; -# endif - /* Points at last added element. Also (ab)used for */ - /* synchronization. Updates and reads are assumed atomic. */ - -GC_PTR * GC_changing_list_limit; - /* Points at the last word of the buffer, which is always 0 */ - /* All entries in (GC_changing_list_current, */ - /* GC_changing_list_limit] are 0 */ - - -void GC_stubborn_init() -{ -# define INIT_SIZE 10 - - GC_changing_list_start = (GC_PTR *) - GC_INTERNAL_MALLOC( - (word)(INIT_SIZE * sizeof(GC_PTR)), - PTRFREE); - BZERO(GC_changing_list_start, - INIT_SIZE * sizeof(GC_PTR)); - if (GC_changing_list_start == 0) { - GC_err_printf0("Insufficient space to start up\n"); - ABORT("GC_stubborn_init: put of space"); - } - GC_changing_list_current = GC_changing_list_start; - GC_changing_list_limit = GC_changing_list_start + INIT_SIZE - 1; - * GC_changing_list_limit = 0; -} - -/* Compact and possibly grow GC_uninit_list. The old copy is */ -/* left alone. Lock must be held. */ -/* When called GC_changing_list_current == GC_changing_list_limit */ -/* which is one past the current element. */ -/* When we finish GC_changing_list_current again points one past last */ -/* element. */ -/* Invariant while this is running: GC_changing_list_current */ -/* points at a word containing 0. */ -/* Returns FALSE on failure. */ -GC_bool GC_compact_changing_list() -{ - register GC_PTR *p, *q; - register word count = 0; - word old_size = (char **)GC_changing_list_limit - - (char **)GC_changing_list_start+1; - /* The casts are needed as a workaround for an Amiga bug */ - register word new_size = old_size; - GC_PTR * new_list; - - for (p = GC_changing_list_start; p < GC_changing_list_limit; p++) { - if (*p != 0) count++; - } - if (2 * count > old_size) new_size = 2 * count; - new_list = (GC_PTR *) - GC_INTERNAL_MALLOC( - new_size * sizeof(GC_PTR), PTRFREE); - /* PTRFREE is a lie. But we don't want the collector to */ - /* consider these. We do want the list itself to be */ - /* collectable. */ - if (new_list == 0) return(FALSE); - BZERO(new_list, new_size * sizeof(GC_PTR)); - q = new_list; - for (p = GC_changing_list_start; p < GC_changing_list_limit; p++) { - if (*p != 0) *q++ = *p; - } - GC_changing_list_start = new_list; - GC_changing_list_limit = new_list + new_size - 1; - GC_changing_list_current = q; - return(TRUE); -} - -/* Add p to changing list. Clear p on failure. */ -# define ADD_CHANGING(p) \ - { \ - register struct hblk * h = HBLKPTR(p); \ - register word index = PHT_HASH(h); \ - \ - set_pht_entry_from_index(GC_changed_pages, index); \ - } \ - if (*GC_changing_list_current != 0 \ - && ++GC_changing_list_current == GC_changing_list_limit) { \ - if (!GC_compact_changing_list()) (p) = 0; \ - } \ - *GC_changing_list_current = p; - -void GC_change_stubborn(p) -GC_PTR p; -{ - DCL_LOCK_STATE; - - DISABLE_SIGNALS(); - LOCK(); - ADD_CHANGING(p); - UNLOCK(); - ENABLE_SIGNALS(); -} - -void GC_end_stubborn_change(p) -GC_PTR p; -{ -# ifdef THREADS - register VOLATILE GC_PTR * my_current = GC_changing_list_current; -# else - register GC_PTR * my_current = GC_changing_list_current; -# endif - register GC_bool tried_quick; - DCL_LOCK_STATE; - - if (*my_current == p) { - /* Hopefully the normal case. */ - /* Compaction could not have been running when we started. */ - *my_current = 0; -# ifdef THREADS - if (my_current == GC_changing_list_current) { - /* Compaction can't have run in the interim. */ - /* We got away with the quick and dirty approach. */ - return; - } - tried_quick = TRUE; -# else - return; -# endif - } else { - tried_quick = FALSE; - } - DISABLE_SIGNALS(); - LOCK(); - my_current = GC_changing_list_current; - for (; my_current >= GC_changing_list_start; my_current--) { - if (*my_current == p) { - *my_current = 0; - UNLOCK(); - ENABLE_SIGNALS(); - return; - } - } - if (!tried_quick) { - GC_err_printf1("Bad arg to GC_end_stubborn_change: 0x%lx\n", - (unsigned long)p); - ABORT("Bad arg to GC_end_stubborn_change"); - } - UNLOCK(); - ENABLE_SIGNALS(); -} - -/* Allocate lb bytes of composite (pointerful) data */ -/* No pointer fields may be changed after a call to */ -/* GC_end_stubborn_change(p) where p is the value */ -/* returned by GC_malloc_stubborn. */ -# ifdef __STDC__ - GC_PTR GC_malloc_stubborn(size_t lb) -# else - GC_PTR GC_malloc_stubborn(lb) - size_t lb; -# endif -{ -register ptr_t op; -register ptr_t *opp; -register word lw; -ptr_t result; -DCL_LOCK_STATE; - - if( SMALL_OBJ(lb) ) { -# ifdef MERGE_SIZES - lw = GC_size_map[lb]; -# else - lw = ALIGNED_WORDS(lb); -# endif - opp = &(GC_sobjfreelist[lw]); - FASTLOCK(); - if( !FASTLOCK_SUCCEEDED() || (op = *opp) == 0 ) { - FASTUNLOCK(); - result = GC_generic_malloc((word)lb, STUBBORN); - goto record; - } - *opp = obj_link(op); - obj_link(op) = 0; - GC_words_allocd += lw; - result = (GC_PTR) op; - ADD_CHANGING(result); - FASTUNLOCK(); - return((GC_PTR)result); - } else { - result = (GC_PTR) - GC_generic_malloc((word)lb, STUBBORN); - } -record: - DISABLE_SIGNALS(); - LOCK(); - ADD_CHANGING(result); - UNLOCK(); - ENABLE_SIGNALS(); - return((GC_PTR)GC_clear_stack(result)); -} - - -/* Functions analogous to GC_read_dirty and GC_page_was_dirty. */ -/* Report pages on which stubborn objects were changed. */ -void GC_read_changed() -{ - register GC_PTR * p = GC_changing_list_start; - register GC_PTR q; - register struct hblk * h; - register word index; - - if (p == 0) /* initializing */ return; - BCOPY(GC_changed_pages, GC_prev_changed_pages, - (sizeof GC_changed_pages)); - BZERO(GC_changed_pages, (sizeof GC_changed_pages)); - for (; p <= GC_changing_list_current; p++) { - if ((q = *p) != 0) { - h = HBLKPTR(q); - index = PHT_HASH(h); - set_pht_entry_from_index(GC_changed_pages, index); - } - } -} - -GC_bool GC_page_was_changed(h) -struct hblk * h; -{ - register word index = PHT_HASH(h); - - return(get_pht_entry_from_index(GC_prev_changed_pages, index)); -} - -/* Remove unreachable entries from changed list. Should only be */ -/* called with mark bits consistent and lock held. */ -void GC_clean_changing_list() -{ - register GC_PTR * p = GC_changing_list_start; - register GC_PTR q; - register ptr_t r; - register unsigned long count = 0; - register unsigned long dropped_count = 0; - - if (p == 0) /* initializing */ return; - for (; p <= GC_changing_list_current; p++) { - if ((q = *p) != 0) { - count++; - r = (ptr_t)GC_base(q); - if (r == 0 || !GC_is_marked(r)) { - *p = 0; - dropped_count++; - } - } - } -# ifdef PRINTSTATS - if (count > 0) { - GC_printf2("%lu entries in changing list: reclaimed %lu\n", - (unsigned long)count, (unsigned long)dropped_count); - } -# endif -} - -#else /* !STUBBORN_ALLOC */ - -# ifdef __STDC__ - GC_PTR GC_malloc_stubborn(size_t lb) -# else - GC_PTR GC_malloc_stubborn(lb) - size_t lb; -# endif -{ - return(GC_malloc(lb)); -} - -/*ARGSUSED*/ -void GC_end_stubborn_change(p) -GC_PTR p; -{ -} - -/*ARGSUSED*/ -void GC_change_stubborn(p) -GC_PTR p; -{ -} - -void GC_push_stubborn_structures GC_PROTO((void)) -{ -} - -#endif |