/* * Copyright 1988, 1989 Hans-J. Boehm, Alan J. Demers * Copyright (c) 1991, 1992 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 copy this garbage collector for any purpose, * provided the above notices are retained on all copies. */ # include "gc←private.h" # ifdef PCR /* * Note that POSIX PCR requires an ANSI C compiler. Hence we are allowed * to make the same assumption here. * We wrap all of the allocator functions to avoid questions of * compatibility between the prototyped and nonprototyped versions of the f */ # include "pcr/mm/PCR←MM.h" # define MY←MAGIC 17L void * GC←AllocProc(size←t size, PCR←Bool ptrFree, PCR←Bool clear ) { if (ptrFree) { void * result = (void *)GC←malloc←atomic(size); if (clear && result != 0) bzero(result, size); return(result); } else { return((void *)GC←malloc(size)); } } # define GC←ReallocProc GC←realloc # define GC←FreeProc GC←free typedef struct { PCR←ERes (*ed←proc)(void *p, size←t size, PCR←Any data); bool ed←pointerfree; PCR←ERes ed←fail←code; PCR←Any ed←client←data; } enumerate←data; void GC←enumerate←block(h, ed) register struct hblk *h; enumerate←data * ed; { register hdr * hhdr; register int sz; word *p; word * lim; hhdr = HDR(h); sz = hhdr -> hb←sz; if (sz >= 0 && ed -> ed←pointerfree || sz <= 0 && !(ed -> ed←pointerfree)) return; if (sz < 0) sz = -sz; lim = (word *)(h+1) - sz; p = (word *)h; do { if (PCR←ERes←IsErr(ed -> ed←fail←code)) return; ed -> ed←fail←code = (*(ed -> ed←proc))(p, WORDS←TO←BYTES(sz), ed -> ed←client←data); p+= sz; } while (p <= lim); } struct PCR←MM←ProcsRep * GC←old←allocator = 0; PCR←ERes GC←EnumerateProc( PCR←Bool ptrFree, PCR←ERes (*proc)(void *p, size←t size, PCR←Any data), PCR←Any data ) { enumerate←data ed; ed.ed←proc = proc; ed.ed←pointerfree = ptrFree; ed.ed←fail←code = PCR←ERes←okay; ed.ed←client←data = data; GC←apply←to←all←blocks(GC←enumerate←block, &ed); if (ed.ed←fail←code != PCR←ERes←okay) { return(ed.ed←fail←code); } else { /* Also enumerate objects allocated by my predecessors */ return((*(GC←old←allocator->mmp←enumerate))(ptrFree, proc, data)); } } void GC←DummyFreeProc(void *p) {}; void GC←DummyShutdownProc(void) {}; struct PCR←MM←ProcsRep GC←Rep = { MY←MAGIC, GC←AllocProc, GC←ReallocProc, GC←DummyFreeProc, /* mmp←free */ GC←FreeProc, /* mmp←unsafeFree */ GC←EnumerateProc, GC←DummyShutdownProc /* mmp←shutdown */ }; void GC←pcr←install() { PCR←MM←Install(&GC←Rep, &GC←old←allocator); } # endif