2 % (c) The AQUA Project, Glasgow University, 1992-1994
9 This stuff needs to be documented. KH
12 /* In the Storage Manager we use the global register mapping */
13 /* We turn off STG-machine register declarations */
15 #if ! (defined(MAIN_REG_MAP) || defined(NULL_REG_MAP) || defined(MARK_REG_MAP) || defined(SCAN_REG_MAP) || defined(SCAV_REG_MAP))
16 **** please set your REG_MAP ****
21 #ifdef HAVE_SYS_VADVISE_H
22 #include <sys/vadvise.h>
25 extern I_ SM_force_gc;
29 extern I_ SM_word_heap_size; /* all defined in SMinit.lc */
30 extern I_ SM_alloc_min;
31 extern StgFloat SM_pc_free_heap;
32 extern I_ SM_alloc_size;
33 extern I_ SM_major_gen_size;
34 /*moved: extern I_ SM_word_stk_size; */
35 extern FILE *SM_statsfile;
37 extern I_ SM_stats_summary;
38 extern I_ SM_stats_verbose;
39 extern I_ SM_ring_bell;
44 extern void stat_init PROTO((char *collector, char *c1, char *c2));
45 extern void stat_startGC PROTO((I_ alloc));
46 extern void stat_endGC PROTO((I_ alloc, I_ collect, I_ live, char *comment));
47 extern void stat_exit PROTO((I_ alloc));
49 extern I_ MaxResidency; /* in words; for stats only */
50 extern I_ ResidencySamples; /* for stats only */
52 #define DO_MAX_RESIDENCY(r) /* saves typing */ \
56 if (resid > MaxResidency) { \
57 MaxResidency = resid; \
61 extern StgFunPtr _Dummy_entry(STG_NO_ARGS);
62 extern char *xmalloc PROTO((size_t));
64 #if defined(_GC_DEBUG)
65 #define DEBUG_SCAN(str, pos, to, topos) \
66 if (SM_trace & 2) fprintf(stderr, "%s: 0x%lx, %s 0x%lx\n", str, pos, to, topos)
67 #define DEBUG_STRING(str) \
68 if (SM_trace & 2) fprintf(stderr, "%s\n", str)
70 #define DEBUG_SCAN(str, pos, to, topos)
71 #define DEBUG_STRING(str)
74 /************************ Default HEAP and STACK sizes **********************/
76 #define DEFAULT_STACKS_SIZE 0x10002 /* 2^16 = 16Kwords = 64Kbytes */
78 #define DEFAULT_HEAP_SIZE 0x100002 /* 2^20 = 1Mwords = 4Mbytes */
79 #define DEFAULT_ALLOC_SIZE 0x4002 /* 2^14 = 16k words = 64k bytes */
80 #define DEFAULT_PC_FREE 3 /* 3% */
82 /* I added a couple of extra words above, to be more sure of avoiding
83 bad effects on direct-mapped caches. (WDP)
86 #define NEXT_SEMI_SPACE(space) ((space + 1) % 2)
88 /************************ Random stuff **********************/
90 /* This should be really big */
91 #define BIG_STRING_LEN 512
93 /************************** TWO SPACE COPYING (2s) **************************/
98 P_ base; /* First word allocatable in semispace */
99 P_ lim; /* Last word allocatable in semispace */
102 extern I_ semispace; /* 0 or 1 -- indexes semispaceInfo */
103 extern semispaceData semispaceInfo[2];
108 /*********************** SINGLE SPACE COMPACTION (1s) ***********************/
113 P_ base; /* First word allocatable in heap */
114 P_ lim; /* Last word allocatable in heap */
115 BitWord *bits; /* Area for marking bits */
116 I_ bit_words; /* Size of marking bit area (in words) */
117 I_ heap_words; /* Size of heap area (in words) */
120 extern compactingData compactingInfo;
125 /****************************** DUAL MODE (du) ******************************/
131 StgFloat resid_to_compact;
132 StgFloat resid_from_compact;
134 P_ base; /* First word allocatable in this mode */
135 P_ lim; /* Last word allocatable in this mode */
136 I_ heap_words; /* Size of area (in words) */
139 BitWord *bits; /* Area for marking bits */
140 I_ bit_words; /* Size of marking bit area (in words) */
143 extern dualmodeData dualmodeInfo;
145 #define DEFAULT_RESID_TO_COMPACT 0.25
146 #define DEFAULT_RESID_FROM_COMPACT 0.20
148 #define TWO_SPACE_BOT 0
149 #define TWO_SPACE_TOP 1
154 /*************************** APPELS COLLECTOR (ap) **************************/
159 P_ oldbase; /* first word allocatable in oldgen */
160 P_ oldlim; /* last word allocated in oldgen */
161 P_ oldlast; /* oldlim after last major collection */
162 P_ oldthresh; /* threshold of oldgen occupancy */
163 P_ oldmax; /* maximum allocatable in oldgen before heap deemed full */
165 I_ newfixed; /* The size of the new generation, if fixed */
166 I_ newmin; /* The minimum size of the new generation */
167 P_ newbase; /* First word allocatable in newgen top space */
168 P_ newlim; /* Last word allocatable in newgen top space */
170 BitWord *bits; /* Area for marking bits */
172 P_ OldCAFlist; /* CAFs promoted to old generation */
173 I_ OldCAFno; /* No of CAFs promoted to old generation */
174 I_ bit_words; /* Size of marking bit area (in words) */
176 P_ PromMutables; /* List of recently promoted mutable closures */
178 I_ semi_space; /* -F forced 2s collector */
180 P_ base; /* First word allocatable in semispace */
181 P_ lim; /* Last word allocatable in semispace */
186 /* UPDATE INFO - Stored in sm info structure:
187 Additional info required when updating to keep track of
188 new generation roots residing in the old generation
189 (old -> new inter-generation pointers)
192 extern appelData appelInfo;
197 /************************ GENERATIONAL COLLECTOR (gn) ***********************/
202 I_ alloc_words; /* Size of allocation space */
203 /* May be large enough for bit array */
204 I_ new_words; /* Size of new generation semi-space */
205 /* Must be large enough for bit array */
206 I_ old_words; /* Size of old generation */
208 I_ minor_since_major;
209 /* No of minor collections since last major */
211 P_ allocbase; /* First word allocatable in oldgen */
212 P_ alloclim; /* Last word allocatable in oldgen */
214 I_ curnew; /* New gen semi-space currently in use */
216 P_ newbase; /* First word allocatable in newgen semispace */
217 P_ newlim; /* Last word allocated in new semi-space */
220 P_ oldbase; /* First word allocatable in oldgen */
221 P_ oldend; /* Last word allocatable in oldgen */
222 P_ oldwas; /* Limit of oldgen after last major collection */
223 P_ oldlim; /* Last word allocated in oldgen */
224 P_ oldthresh; /* Oldgen threshold: less than new_words free */
225 BitWord *bit_vect; /* Marking bits -- alloc area or old generation */
227 P_ OldInNew; /* Old roots pointing to new generation */
228 I_ OldInNewno; /* No of Old roots pointing to new generation */
229 P_ NewCAFlist; /* CAFs in new generation */
230 I_ NewCAFno; /* No of CAFs in new generation */
231 P_ OldCAFlist; /* CAFs promoted to old generation */
232 I_ OldCAFno; /* No of CAFs promoted to old generation */
234 P_ PromMutables; /* List of recently promoted mutable closures */
236 I_ semi_space; /* -F forced 2s collector */
238 P_ base; /* First word allocatable in semispace */
239 P_ lim; /* Last word allocatable in semispace */
243 extern genData genInfo;
245 /* Update INFO - Stored in sm info structure:
246 Additional info required when updating to keep track of
247 new generation roots residing in the old generation
248 (old -> new inter-generation pointers)
253 /****************************** COPYING ******************************/
256 #if defined(_INFO_COPYING)
258 #define EVAC_CODE(infoptr) ((StgEvacPtr) ((P_)(INFO_RTBL(infoptr)))[COPY_INFO_OFFSET])
259 #define SCAV_CODE(infoptr) ((StgScavPtr) ((P_)(INFO_RTBL(infoptr)))[COPY_INFO_OFFSET+1])
261 extern void Scavenge(STG_NO_ARGS);
262 extern void _Scavenge_Forward_Ref(STG_NO_ARGS);
264 /* Note: any change to FORWARD_ADDRESS should be
265 reflected in layout of MallocPtrs (includes/SMClosures.lh)
268 #define FORWARD_ADDRESS(closure) (*(((P_)(closure)) + FIXED_HS))
270 #define FORWARDREF_ITBL(infolbl,entry,localness,evac_forward) \
271 CAT_DECLARE(infolbl,INTERNAL_KIND,"FORWARD_REF","FORWARD_REF") \
272 localness W_ infolbl[] = { \
274 ,(W_) INFO_OTHER_TAG \
275 ,(W_) MK_REP_REF(,evac_forward,) \
276 INCLUDE_PROFILING_INFO(infolbl) \
279 P_ _Evacuate_Old_Forward_Ref PROTO((P_));
280 P_ _Evacuate_New_Forward_Ref PROTO((P_));
281 P_ _Evacuate_OldRoot_Forward PROTO((P_));
282 P_ _Evacuate_Forward_Ref PROTO((P_));
284 MAYBE_DECLARE_RTBL(,_Evacuate_Old_Forward_Ref,)
285 MAYBE_DECLARE_RTBL(,_Evacuate_New_Forward_Ref,)
286 MAYBE_DECLARE_RTBL(,_Evacuate_OldRoot_Forward,)
287 MAYBE_DECLARE_RTBL(,_Evacuate_Forward_Ref,)
289 #define FORWARDREF_RTBL(evac_forward) \
290 const W_ MK_REP_LBL(,evac_forward,)[] = { \
291 INCLUDE_TYPE_INFO(INTERNAL) \
292 INCLUDE_SIZE_INFO(INFO_UNUSED,INFO_UNUSED) \
294 INCLUDE_COPYING_INFO(evac_forward,_Scavenge_Forward_Ref)\
295 INCLUDE_COMPACTING_INFO(INFO_UNUSED,INFO_UNUSED,INFO_UNUSED,INFO_UNUSED) \
298 EXTDATA_RO(Caf_Evac_Upd_info);
299 extern StgEvacFun _Evacuate_Caf_Evac_Upd;
301 #define CAF_EVAC_UPD_ITBL(infolbl,entry,localness) \
302 CAT_DECLARE(infolbl,INTERNAL_KIND,"CAF_EVAC_UPD","CAF_EVAC_UPD") \
303 localness W_ infolbl[] = { \
305 ,(W_) INFO_OTHER_TAG \
306 ,(W_) MK_REP_REF(Caf_Evac_Upd,,) \
307 INCLUDE_PROFILING_INFO(infolbl) \
310 MAYBE_DECLARE_RTBL(Caf_Evac_Upd,,)
312 #define CAF_EVAC_UPD_RTBL() \
313 const W_ MK_REP_LBL(Caf_Evac_Upd,,)[] = { \
314 INCLUDE_TYPE_INFO(INTERNAL) \
315 INCLUDE_SIZE_INFO(MIN_UPD_SIZE,INFO_UNUSED) \
317 INCLUDE_COPYING_INFO(_Evacuate_Caf_Evac_Upd,_Scavenge_Caf) \
318 INCLUDE_COMPACTING_INFO(INFO_UNUSED,INFO_UNUSED,INFO_UNUSED,INFO_UNUSED) \
321 #define EVACUATE_CLOSURE(closure) \
322 (EVAC_CODE(INFO_PTR(closure)))(closure)
324 #endif /* _INFO_COPYING */
327 /****************************** MARKING ******************************/
329 #if defined(_INFO_MARKING)
331 extern I_ markHeapRoots PROTO((smInfo *sm, P_ cafs1, P_ cafs2,
332 P_ base, P_ lim, BitWord *bit_array));
334 #define PRMARK_CODE(infoptr) \
335 (((FP_)(INFO_RTBL(infoptr)))[COMPACTING_INFO_OFFSET+1])
337 /* Applied to unmarked or marking info pointer */
338 #define PRRETURN_CODE(infoptr) \
339 (((FP_)(INFO_RTBL(infoptr)))[COMPACTING_INFO_OFFSET+3])
341 /* This placed on bottom of PR Marking Stack */
343 #define DUMMY_PRRETURN_CLOSURE(closure_name, table_name, prreturn_code, dummy_code) \
344 const W_ table_name[] = { \
346 ,(W_) INFO_OTHER_TAG \
347 ,(W_) MK_REP_REF(,prreturn_code,) \
348 INCLUDE_PROFILING_INFO(Dummy_PrReturn) \
350 W_ closure_name = (W_) table_name
352 EXTFUN(_Dummy_PRReturn_entry);
353 EXTFUN(_PRMarking_MarkNextRoot);
354 EXTFUN(_PRMarking_MarkNextCAF);
357 EXTFUN(_PRMarking_MarkNextSpark);
361 EXTFUN(_PRMarking_MarkNextGA);
362 MAYBE_DECLARE_RTBL(,_PRMarking_MarkNextGA,)
365 EXTFUN(_PRMarking_MarkNextAStack);
366 EXTFUN(_PRMarking_MarkNextBStack);
368 MAYBE_DECLARE_RTBL(,_PRMarking_MarkNextAStack,)
369 MAYBE_DECLARE_RTBL(,_PRMarking_MarkNextBStack,)
374 MAYBE_DECLARE_RTBL(,_PRMarking_MarkNextSpark,)
377 MAYBE_DECLARE_RTBL(,_PRMarking_MarkNextRoot,)
378 MAYBE_DECLARE_RTBL(,_PRMarking_MarkNextCAF,)
380 #define DUMMY_PRRETURN_RTBL(prreturn_code,dummy_code) \
381 const W_ MK_REP_LBL(,prreturn_code,)[] = { \
382 INCLUDE_TYPE_INFO(INTERNAL) \
383 INCLUDE_SIZE_INFO(INFO_UNUSED,INFO_UNUSED) \
385 INCLUDE_COPYING_INFO(dummy_code,dummy_code) \
386 INCLUDE_COMPACTING_INFO(dummy_code,dummy_code,dummy_code,prreturn_code) \
389 /* Unused "Code to avoid explicit updating of CAF references" used to live here
393 #endif /* _INFO_MARKING */
396 /****************************** COMPACTING ******************************/
398 #if defined(_INFO_COMPACTING)
401 P_ Inplace_Compaction PROTO((P_ base, P_ lim,
402 P_ scanbase, P_ scablim,
403 BitWord *bit_array, I_ bit_array_words,
404 StgPtr *MallocPtrList));
406 P_ Inplace_Compaction PROTO((P_ base, P_ lim,
407 P_ scanbase, P_ scablim,
408 BitWord *bit_array, I_ bit_array_words));
410 /* Applied to marked info pointers */
412 #define SCAN_LINK_CODE(infoptr) \
413 ((StgScanPtr) ((P_)(INFO_RTBL(infoptr)))[COMPACTING_INFO_OFFSET])
414 #define SCAN_MOVE_CODE(infoptr) \
415 ((StgScanPtr) ((P_)(INFO_RTBL(infoptr)))[COMPACTING_INFO_OFFSET+2])
418 This fragment tests whether we're in global garbage collection during parallel
419 evaluation. If so, then we check the global address of the closure \tr{loc}
420 and evacuate it in the IMUs if it's a legal global address.
423 #define LINK_GLOBALADDRESS(loc)
427 extern StgScavFun _Scavenge_OldRoot; /* Allocated Old -> New root, just skip */
428 extern StgEvacFun _Evacuate_OldRoot; /* Should not occur */
430 extern StgFunPtr _PRStart_OldRoot(STG_NO_ARGS); /* Marking old root -- Short circut if points to oldgen */
431 extern StgScanFun _ScanMove_OldRoot; /* Scanning old root -- Rebuild old root list */
433 EXTDATA_RO(OldRoot_info);
435 #define OLDROOT_ITBL(infolbl,ind_code,localness,entry_localness)\
436 CAT_DECLARE(infolbl,INTERNAL_KIND,"OLDROOT","OLDROOT") \
437 entry_localness(ind_code); \
438 localness W_ infolbl[] = { \
440 ,(W_) INFO_OTHER_TAG \
441 ,(W_) MK_REP_REF(OldRoot,,) \
442 INCLUDE_PROFILING_INFO(infolbl) \
445 MAYBE_DECLARE_RTBL(OldRoot,,)
447 #define OLDROOT_RTBL() \
448 const W_ MK_REP_LBL(OldRoot,,)[] = { \
449 INCLUDE_TYPE_INFO(SPEC_U) \
450 INCLUDE_SIZE_INFO(2,1) /* deeply hardwired size/ptrs */ \
452 INCLUDE_COPYING_INFO(_Evacuate_OldRoot,_Scavenge_OldRoot) \
453 SPEC_COMPACTING_INFO(_ScanLink_2_1,_PRStart_OldRoot,_ScanMove_OldRoot,_PRIn_1) \
456 #define LINK_LOCATION_TO_CLOSURE(loc,linklim) \
457 { P_ _temp = (P_) *(loc); \
458 DEBUG_LINK_LOCATION(loc, _temp, linklim); \
459 if (DYNAMIC_CLOSURE(_temp) && (_temp <= linklim)) { \
460 *((P_)(loc)) = (W_) INFO_PTR(_temp); \
461 INFO_PTR(_temp) = MARK_LOCATION(loc); \
466 #define LINK_LOCATION_TO_CLOSURE(loc) \
467 { P_ _temp = (P_) *(loc); \
468 DEBUG_LINK_LOCATION(loc, _temp); \
469 if (DYNAMIC_CLOSURE(_temp)) { \
470 *((P_)(loc)) = (W_) INFO_PTR(_temp); \
471 INFO_PTR(_temp) = MARK_LOCATION(loc); \
476 #if defined(_GC_DEBUG)
479 #define DEBUG_LINK_LOCATION(location, closure, linklim) \
480 if (SM_trace & 4) { \
481 if (DYNAMIC_CLOSURE(closure) && (closure <= linklim)) \
482 fprintf(stderr, " Link Loc: 0x%lx to 0x%lx\n", location, closure); \
483 else if (! DYNAMIC_CLOSURE(closure)) \
484 fprintf(stderr, " Link Loc: 0x%lx to 0x%lx Static Closure -- Not Done\n", location, closure); \
486 fprintf(stderr, " Link Loc: 0x%lx to 0x%lx OutOfRange Closure -- Not Done\n", location, closure); \
489 #define DEBUG_LINK_LOCATION(location, closure) \
490 if (SM_trace & 4) { \
491 if (DYNAMIC_CLOSURE(closure)) \
492 fprintf(stderr, " Link Loc: 0x%lx to 0x%lx\n", location, closure); \
494 fprintf(stderr, " Link Loc: 0x%lx to 0x%lx Static Closure -- Not Done\n", location, closure); \
498 #define DEBUG_UNLINK_LOCATION(location, closure, newlocation) \
500 fprintf(stderr, " UnLink Loc: 0x%lx, 0x%lx -> 0x%lx\n", location, closure, newlocation)
502 #define DEBUG_LINK_CAF(caf) \
504 fprintf(stderr, "Caf: 0x%lx Closure: 0x%lx\n", caf, IND_CLOSURE_PTR(caf))
506 #define DEBUG_SET_MARK(closure, hp_word) \
508 fprintf(stderr, " Set Mark Bit: 0x%lx, word %ld, bit_word %ld, bit %d\n", closure, hp_word, hp_word / BITS_IN(BitWord), hp_word & (BITS_IN(BitWord) - 1))
512 #define DEBUG_LINK_LOCATION(location, closure, linklim)
514 #define DEBUG_LINK_LOCATION(location, closure)
516 #define DEBUG_UNLINK_LOCATION(location, closure, newlocation)
517 #define DEBUG_LINK_CAF(caf)
518 #define DEBUG_SET_MARK(closure, hp_word)
521 #endif /* _INFO_COMPACTING */
523 #endif /* SMinternals_H */