version 1.3, 2002/07/24 07:46:35 |
version 1.4, 2002/07/24 08:00:20 |
Line 26 typedef struct hblkhdr hdr; |
|
Line 26 typedef struct hblkhdr hdr; |
|
* table. |
* table. |
* |
* |
* This defines HDR, GET_HDR, and SET_HDR, the main macros used to |
* This defines HDR, GET_HDR, and SET_HDR, the main macros used to |
* retrieve and set object headers. We also define some variants to |
* retrieve and set object headers. |
* retrieve 2 unrelated headers in interleaved fashion. This |
|
* slightly improves scheduling. |
|
* |
* |
* Since 5.0 alpha 5, we can also take advantage of a header lookup |
* Since 5.0 alpha 5, we can also take advantage of a header lookup |
* cache. This is a locally declared direct mapped cache, used inside |
* cache. This is a locally declared direct mapped cache, used inside |
* the marker. The HC_GET_HDR and HC_GET_HDR2 macros use and maintain this |
* the marker. The HC_GET_HDR macro uses and maintains this |
* cache. Assuming we get reasonable hit rates, this shaves a few |
* cache. Assuming we get reasonable hit rates, this shaves a few |
* memory references from each pointer validation. |
* memory references from each pointer validation. |
*/ |
*/ |
Line 67 extern hdr * GC_invalid_header; /* header for an imagi |
|
Line 65 extern hdr * GC_invalid_header; /* header for an imagi |
|
|
|
|
|
/* Check whether p and corresponding hhdr point to long or invalid */ |
/* Check whether p and corresponding hhdr point to long or invalid */ |
/* object. If so, advance them to */ |
/* object. If so, advance hhdr to */ |
/* beginning of block, or set hhdr to GC_invalid_header. */ |
/* beginning of block, or set hhdr to GC_invalid_header. */ |
#define ADVANCE(p, hhdr, source) \ |
#define ADVANCE(p, hhdr, source) \ |
if (IS_FORWARDING_ADDR_OR_NIL(hhdr)) { \ |
{ \ |
p = GC_FIND_START(p, hhdr, (word)source); \ |
hdr * new_hdr = GC_invalid_header; \ |
if (p == 0) { \ |
p = GC_find_start(p, hhdr, &new_hdr); \ |
hhdr = GC_invalid_header; \ |
hhdr = new_hdr; \ |
} else { \ |
|
hhdr = GC_find_header(p); \ |
|
} \ |
|
} |
} |
|
|
#ifdef USE_HDR_CACHE |
#ifdef USE_HDR_CACHE |
Line 124 extern hdr * GC_invalid_header; /* header for an imagi |
|
Line 119 extern hdr * GC_invalid_header; /* header for an imagi |
|
} else { \ |
} else { \ |
HC_MISS(); \ |
HC_MISS(); \ |
GET_HDR(p, hhdr); \ |
GET_HDR(p, hhdr); \ |
ADVANCE(p, hhdr, source); \ |
if (IS_FORWARDING_ADDR_OR_NIL(hhdr)) { \ |
hce -> block_addr = (word)(p) >> LOG_HBLKSIZE; \ |
ADVANCE(p, hhdr, source); \ |
hce -> hce_hdr = hhdr; \ |
} else { \ |
|
hce -> block_addr = (word)(p) >> LOG_HBLKSIZE; \ |
|
hce -> hce_hdr = hhdr; \ |
|
} \ |
} \ |
} \ |
} |
} |
|
|
# define HC_GET_HDR2(p1, hhdr1, source1, p2, hhdr2, source2) \ |
|
{ \ |
|
hdr_cache_entry * hce1 = HCE(p1); \ |
|
hdr_cache_entry * hce2 = HCE(p2); \ |
|
if (HCE_VALID_FOR(hce1, p1)) { \ |
|
HC_HIT(); \ |
|
hhdr1 = hce1 -> hce_hdr; \ |
|
} else { \ |
|
HC_MISS(); \ |
|
GET_HDR(p1, hhdr1); \ |
|
ADVANCE(p1, hhdr1, source1); \ |
|
hce1 -> block_addr = (word)(p1) >> LOG_HBLKSIZE; \ |
|
hce1 -> hce_hdr = hhdr1; \ |
|
} \ |
|
if (HCE_VALID_FOR(hce2, p2)) { \ |
|
HC_HIT(); \ |
|
hhdr2 = hce2 -> hce_hdr; \ |
|
} else { \ |
|
HC_MISS(); \ |
|
GET_HDR(p2, hhdr2); \ |
|
ADVANCE(p2, hhdr2, source2); \ |
|
hce2 -> block_addr = (word)(p2) >> LOG_HBLKSIZE; \ |
|
hce2 -> hce_hdr = hhdr2; \ |
|
} \ |
|
} |
|
|
|
#else /* !USE_HDR_CACHE */ |
#else /* !USE_HDR_CACHE */ |
|
|
# define DECLARE_HDR_CACHE |
# define DECLARE_HDR_CACHE |
Line 165 extern hdr * GC_invalid_header; /* header for an imagi |
|
Line 137 extern hdr * GC_invalid_header; /* header for an imagi |
|
# define HC_GET_HDR(p, hhdr, source) \ |
# define HC_GET_HDR(p, hhdr, source) \ |
{ \ |
{ \ |
GET_HDR(p, hhdr); \ |
GET_HDR(p, hhdr); \ |
ADVANCE(p, hhdr, source); \ |
if (IS_FORWARDING_ADDR_OR_NIL(hhdr)) { \ |
|
ADVANCE(p, hhdr, source); \ |
|
} \ |
} |
} |
|
|
# define HC_GET_HDR2(p1, hhdr1, source1, p2, hhdr2, source2) \ |
|
{ \ |
|
GET_HDR2(p1, hhdr1, p2, hhdr2); \ |
|
ADVANCE(p1, hhdr1, source1); \ |
|
ADVANCE(p2, hhdr2, source2); \ |
|
} |
|
|
|
#endif |
#endif |
|
|
typedef struct bi { |
typedef struct bi { |
Line 229 typedef struct bi { |
|
Line 195 typedef struct bi { |
|
# define GET_HDR(p, hhdr) (hhdr) = HDR(p) |
# define GET_HDR(p, hhdr) (hhdr) = HDR(p) |
# define SET_HDR(p, hhdr) HDR_INNER(p) = (hhdr) |
# define SET_HDR(p, hhdr) HDR_INNER(p) = (hhdr) |
# define GET_HDR_ADDR(p, ha) (ha) = &(HDR_INNER(p)) |
# define GET_HDR_ADDR(p, ha) (ha) = &(HDR_INNER(p)) |
# define GET_HDR2(p1, hhdr1, p2, hhdr2) \ |
|
{ GET_HDR(p1, hhdr1); GET_HDR(p2, hhdr2); } |
|
# else /* hash */ |
# else /* hash */ |
/* Hash function for tree top level */ |
/* Hash function for tree top level */ |
# define TL_HASH(hi) ((hi) & (TOP_SZ - 1)) |
# define TL_HASH(hi) ((hi) & (TOP_SZ - 1)) |
Line 257 typedef struct bi { |
|
Line 221 typedef struct bi { |
|
# define SET_HDR(p, hhdr) { register hdr ** _ha; GET_HDR_ADDR(p, _ha); \ |
# define SET_HDR(p, hhdr) { register hdr ** _ha; GET_HDR_ADDR(p, _ha); \ |
*_ha = (hhdr); } |
*_ha = (hhdr); } |
# define HDR(p) GC_find_header((ptr_t)(p)) |
# define HDR(p) GC_find_header((ptr_t)(p)) |
/* And some interleaved versions for two pointers at once. */ |
|
/* This hopefully helps scheduling on processors like IA64. */ |
|
# define GET_BI2(p1, bottom_indx1, p2, bottom_indx2) \ |
|
{ \ |
|
register word hi1 = \ |
|
(word)(p1) >> (LOG_BOTTOM_SZ + LOG_HBLKSIZE); \ |
|
register word hi2 = \ |
|
(word)(p2) >> (LOG_BOTTOM_SZ + LOG_HBLKSIZE); \ |
|
register bottom_index * _bi1 = GC_top_index[TL_HASH(hi1)]; \ |
|
register bottom_index * _bi2 = GC_top_index[TL_HASH(hi2)]; \ |
|
\ |
|
while (_bi1 -> key != hi1 && _bi1 != GC_all_nils) \ |
|
_bi1 = _bi1 -> hash_link; \ |
|
while (_bi2 -> key != hi2 && _bi2 != GC_all_nils) \ |
|
_bi2 = _bi2 -> hash_link; \ |
|
(bottom_indx1) = _bi1; \ |
|
(bottom_indx2) = _bi2; \ |
|
} |
|
# define GET_HDR_ADDR2(p1, ha1, p2, ha2) \ |
|
{ \ |
|
register bottom_index * bi1; \ |
|
register bottom_index * bi2; \ |
|
\ |
|
GET_BI2(p1, bi1, p2, bi2); \ |
|
(ha1) = &(HDR_FROM_BI(bi1, p1)); \ |
|
(ha2) = &(HDR_FROM_BI(bi2, p2)); \ |
|
} |
|
# define GET_HDR2(p1, hhdr1, p2, hhdr2) \ |
|
{ register hdr ** _ha1; \ |
|
register hdr ** _ha2; \ |
|
GET_HDR_ADDR2(p1, _ha1, p2, _ha2); \ |
|
(hhdr1) = *_ha1; \ |
|
(hhdr2) = *_ha2; \ |
|
} |
|
# endif |
# endif |
|
|
/* Is the result a forwarding address to someplace closer to the */ |
/* Is the result a forwarding address to someplace closer to the */ |