/*
* 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