/* * 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. */ # ifndef GC←HEADERS←H # define GC←HEADERS←H typedef struct hblkhdr hdr; # if CPP←WORDSZ != 32 && CPP←WORDSZ < 36 --> Get a real machine. # endif /* * The 2 level tree data structure that is used to find block headers. * If there are more than 32 bits in a pointer, the top level is a hash * table. */ # if CPP←WORDSZ > 32 # define HASH←TL # endif /* Define appropriate out-degrees for each of the two tree levels */ # define LOG←BOTTOM←SZ 10 # ifndef HASH←TL # define LOG←TOP←SZ (WORDSZ - LOG←BOTTOM←SZ - LOG←HBLKSIZE) # else # define LOG←TOP←SZ 11 # endif # define TOP←SZ (1 << LOG←TOP←SZ) # define BOTTOM←SZ (1 << LOG←BOTTOM←SZ) typedef struct bi { hdr * index[BOTTOM←SZ]; /* * The bottom level index contains one of three kinds of values: * 0 means we're not responsible for this block. * 1 < (long)X <= MAX←JUMP means the block starts at least * X * HBLKSIZE bytes before the current address. * A valid pointer points to a hdr structure. (The above can't be * valid pointers due to the GET←MEM return convention.) */ struct bi * asc←link; /* All indices are linked in */ /* ascending order. */ word key; /* high order address bits. */ # ifdef HASH←TL struct bi * hash←link; /* Hash chain link. */ # endif } bottom←index; /* extern bottom←index GC←all←nils; - really part of GC←arrays */ /* extern bottom←index * GC←top←index []; - really part of GC←arrays */ /* Each entry points to a bottom←index. */ /* On a 32 bit machine, it points to */ /* the index for a set of high order */ /* bits equal to the index. For longer */ /* addresses, we hash the high order */ /* bits to compute the index in */ /* GC←top←index, and each entry points */ /* to a hash chain. */ /* The last entry in each chain is */ /* GC←all←nils. */ # define MAX←JUMP (HBLKSIZE - 1) # ifndef HASH←TL # define BI(p) (GC←top←index \ [(word)(p) >> (LOG←BOTTOM←SZ + LOG←HBLKSIZE)]) # define HDR(p) (BI(p)->index \ [((word)(p) >> LOG←HBLKSIZE) & (BOTTOM←SZ - 1)]) # define GET←BI(p, bottom←indx) (bottom←indx) = BI(p) # define GET←HDR(p, hhdr) (hhdr) = HDR(p) # define SET←HDR(p, hhdr) HDR(p) = (hhdr) # define GET←HDR←ADDR(p, ha) (ha) = &(HDR(p)) # else /* hash */ /* Hash function for tree top level */ # define TL←HASH(hi) ((hi) & (TOP←SZ - 1)) /* Set bottom←indx to point to the bottom index for address p */ # define GET←BI(p, bottom←indx) \ { \ register word hi = \ (word)(p) >> (LOG←BOTTOM←SZ + LOG←HBLKSIZE); \ register bottom←index * ←bi = GC←top←index[TL←HASH(hi)]; \ \ while (←bi -> key != hi && ←bi != &GC←all←nils) \ ←bi = ←bi -> hash←link; \ (bottom←indx) = ←bi; \ } # define GET←HDR←ADDR(p, ha) \ { \ register bottom←index * bi; \ \ GET←BI(p, bi); \ (ha) = &(bi->index[((unsigned long)(p)>>LOG←HBLKSIZE) \ & (BOTTOM←SZ - 1)]); \ } # define GET←HDR(p, hhdr) { register hdr ** ←ha; GET←HDR←ADDR(p, ←ha); \ (hhdr) = *←ha; } # define SET←HDR(p, hhdr) { register hdr ** ←ha; GET←HDR←ADDR(p, ←ha); \ *←ha = (hhdr); } # define HDR(p) GC←find←header(p) # endif /* Is the result a forwarding address to someplace closer to the */ /* beginning of the block or NIL? */ # define IS←FORWARDING←ADDR←OR←NIL(hhdr) ((unsigned long) (hhdr) <= MAX←JUMP) /* Get an HBLKSIZE aligned address closer to the beginning of the block */ /* h. Assumes hhdr == HDR(h) and IS←FORWARDING←ADDR(hhdr). */ # define FORWARDED←ADDR(h, hhdr) ((struct hblk *)(h) - (unsigned long)(hhdr)) # endif /* GC←HEADERS←H */