[project @ 1996-01-08 20:28:12 by partain]
[ghc-hetmet.git] / ghc / runtime / storage / SMinternal.lh
1 %
2 % (c) The AQUA Project, Glasgow University, 1992-1994
3 %
4 \begin{code}
5 #ifndef SMinternals_H
6 #define SMinternals_H
7 \end{code}
8
9 This stuff needs to be documented.  KH
10
11 \begin{code}
12 /* In the Storage Manager we use the global register mapping */
13 /* We turn off STG-machine register declarations             */
14
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 ****
17 #endif
18
19 #include "rtsdefs.h"
20
21 #ifdef HAVE_SYS_VADVISE_H
22 #include <sys/vadvise.h>
23 #endif
24
25 extern I_   SM_force_gc;
26 #define USE_2s  1
27 #define USE_1s  2
28
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;
36 extern I_   SM_trace;
37 extern I_   SM_stats_summary;
38 extern I_   SM_stats_verbose;
39 extern I_   SM_ring_bell;
40
41 extern P_ heap_space;
42 extern P_ hp_start;
43
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));
48
49 extern I_ MaxResidency;     /* in words; for stats only */
50 extern I_ ResidencySamples; /* for stats only */
51
52 #define DO_MAX_RESIDENCY(r) /* saves typing */  \
53     do {                                        \
54         I_ resid = (r);                         \
55         ResidencySamples++;                     \
56         if (resid > MaxResidency) {             \
57             MaxResidency = resid;               \
58         }                                       \
59     } while (0)
60
61 extern StgFunPtr _Dummy_entry(STG_NO_ARGS);
62 extern char *xmalloc PROTO((size_t));
63
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)
69 #else
70 #define DEBUG_SCAN(str, pos, to, topos)
71 #define DEBUG_STRING(str)
72 #endif
73
74 /************************ Default HEAP and STACK sizes **********************/
75
76 #define DEFAULT_STACKS_SIZE      0x10002  /* 2^16 = 16Kwords = 64Kbytes */
77
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% */
81
82 /* I added a couple of extra words above, to be more sure of avoiding
83     bad effects on direct-mapped caches. (WDP)
84 */
85
86 #define NEXT_SEMI_SPACE(space) ((space + 1) % 2)
87
88 /************************ Random stuff **********************/
89
90 /* This should be really big */
91 #define BIG_STRING_LEN           512
92
93 /************************** TWO SPACE COPYING (2s) **************************/
94
95 #if defined(GC2s)
96
97 typedef struct {
98     P_ base;    /* First word allocatable in semispace */
99     P_ lim;     /* Last word allocatable in semispace */
100 } semispaceData;
101
102 extern I_ semispace;    /* 0 or 1 -- indexes semispaceInfo */
103 extern semispaceData semispaceInfo[2];
104
105 #endif /* GC2s */
106
107
108 /*********************** SINGLE SPACE COMPACTION (1s) ***********************/
109
110 #if defined(GC1s)
111
112 typedef struct {
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) */
118 } compactingData;
119
120 extern compactingData compactingInfo;
121
122 #endif /* GC1s */
123
124
125 /****************************** DUAL MODE (du) ******************************/
126
127 #if defined(GCdu)
128
129 typedef struct {
130         I_ mode;
131         StgFloat resid_to_compact;
132         StgFloat resid_from_compact;
133         struct {
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) */
137             char *name;
138         } modeinfo[3];
139         BitWord *bits;      /* Area for marking bits */
140         I_ bit_words;   /* Size of marking bit area (in words) */
141 } dualmodeData;
142
143 extern dualmodeData dualmodeInfo;
144
145 #define DEFAULT_RESID_TO_COMPACT   0.25
146 #define DEFAULT_RESID_FROM_COMPACT 0.20
147
148 #define TWO_SPACE_BOT 0
149 #define TWO_SPACE_TOP 1
150 #define COMPACTING    2
151
152 #endif /* GCdu */
153
154 /*************************** APPELS COLLECTOR (ap) **************************/
155
156 #if defined(GCap)
157
158 typedef struct {
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 */
164
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 */
169
170         BitWord *bits;    /* Area for marking bits */
171
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) */
175
176         P_ PromMutables; /* List of recently promoted mutable closures */
177
178         I_ semi_space;   /* -F forced 2s collector */
179         struct {
180             P_ base;  /* First word allocatable in semispace */
181             P_ lim;   /* Last word allocatable in semispace */
182         } space[2];
183
184 } appelData;
185
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)
190 */
191
192 extern appelData appelInfo;
193
194 #endif /* GCap */
195
196
197 /************************ GENERATIONAL COLLECTOR (gn) ***********************/
198
199 #if defined(GCgn)
200
201 typedef struct {
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 */
207
208         I_  minor_since_major;
209                            /* No of minor collections since last major */ 
210
211         P_ allocbase;  /* First word allocatable in oldgen */
212         P_ alloclim;   /* Last word allocatable in oldgen */
213
214         I_ curnew;         /* New gen semi-space currently in use */
215         struct {
216          P_ newbase;   /* First word allocatable in newgen semispace */
217          P_ newlim;    /* Last word allocated in new semi-space */
218         } newgen[2];
219
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 */
226
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 */
233
234         P_ PromMutables; /* List of recently promoted mutable closures */
235
236         I_ semi_space;  /* -F forced 2s collector */
237         struct {
238             P_ base; /* First word allocatable in semispace */
239             P_ lim;  /* Last word allocatable in semispace */
240         } space[2];
241 } genData;
242
243 extern genData genInfo;
244
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)
249 */
250
251 #endif /* GCap */
252
253 /****************************** COPYING ******************************/
254
255
256 #if defined(_INFO_COPYING)
257
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])
260
261 extern void Scavenge(STG_NO_ARGS);
262 extern void  _Scavenge_Forward_Ref(STG_NO_ARGS);
263
264 /* Note: any change to FORWARD_ADDRESS should be
265    reflected in layout of MallocPtrs (includes/SMClosures.lh)
266 */
267
268 #define FORWARD_ADDRESS(closure)  (*(((P_)(closure)) + FIXED_HS))
269
270 #define FORWARDREF_ITBL(infolbl,entry,localness,evac_forward)   \
271 CAT_DECLARE(infolbl,INTERNAL_KIND,"FORWARD_REF","FORWARD_REF")  \
272 localness W_ infolbl[] = {                                      \
273         (W_) entry                                              \
274         ,(W_) INFO_OTHER_TAG                                    \
275         ,(W_) MK_REP_REF(,evac_forward,)                        \
276         INCLUDE_PROFILING_INFO(infolbl)                         \
277         }
278
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_));
283
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,)
288
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)              \
293         INCLUDE_PAR_INFO                                \
294         INCLUDE_COPYING_INFO(evac_forward,_Scavenge_Forward_Ref)\
295         INCLUDE_COMPACTING_INFO(INFO_UNUSED,INFO_UNUSED,INFO_UNUSED,INFO_UNUSED) \
296         }
297
298 EXTDATA_RO(Caf_Evac_Upd_info);
299 extern StgEvacFun _Evacuate_Caf_Evac_Upd;
300
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[] = {                                      \
304         (W_) entry                                              \
305         ,(W_) INFO_OTHER_TAG                                    \
306         ,(W_) MK_REP_REF(Caf_Evac_Upd,,)                        \
307         INCLUDE_PROFILING_INFO(infolbl)                         \
308         }
309
310 MAYBE_DECLARE_RTBL(Caf_Evac_Upd,,)
311
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)             \
316         INCLUDE_PAR_INFO                \
317         INCLUDE_COPYING_INFO(_Evacuate_Caf_Evac_Upd,_Scavenge_Caf) \
318         INCLUDE_COMPACTING_INFO(INFO_UNUSED,INFO_UNUSED,INFO_UNUSED,INFO_UNUSED) \
319     }
320
321 #define EVACUATE_CLOSURE(closure)      \
322         (EVAC_CODE(INFO_PTR(closure)))(closure)
323
324 #endif /* _INFO_COPYING */
325
326
327 /****************************** MARKING ******************************/
328
329 #if defined(_INFO_MARKING)
330
331 extern I_ markHeapRoots PROTO((smInfo *sm, P_ cafs1, P_ cafs2,
332                                 P_ base, P_ lim, BitWord *bit_array));
333
334 #define PRMARK_CODE(infoptr) \
335           (((FP_)(INFO_RTBL(infoptr)))[COMPACTING_INFO_OFFSET+1])
336
337 /* Applied to unmarked or marking info pointer */
338 #define PRRETURN_CODE(infoptr) \
339           (((FP_)(INFO_RTBL(infoptr)))[COMPACTING_INFO_OFFSET+3])
340
341 /* This placed on bottom of PR Marking Stack */
342
343 #define DUMMY_PRRETURN_CLOSURE(closure_name, table_name, prreturn_code, dummy_code) \
344 const W_ table_name[] = {                       \
345         (W_) dummy_code                         \
346         ,(W_) INFO_OTHER_TAG                    \
347         ,(W_) MK_REP_REF(,prreturn_code,)       \
348         INCLUDE_PROFILING_INFO(Dummy_PrReturn)  \
349         };                                      \
350 W_ closure_name = (W_) table_name
351
352 EXTFUN(_Dummy_PRReturn_entry);
353 EXTFUN(_PRMarking_MarkNextRoot);
354 EXTFUN(_PRMarking_MarkNextCAF);
355
356 #ifdef CONCURRENT
357 EXTFUN(_PRMarking_MarkNextSpark);
358 #endif
359
360 #ifdef PAR
361 EXTFUN(_PRMarking_MarkNextGA);
362 MAYBE_DECLARE_RTBL(,_PRMarking_MarkNextGA,)
363 #else
364
365 EXTFUN(_PRMarking_MarkNextAStack);
366 EXTFUN(_PRMarking_MarkNextBStack);
367
368 MAYBE_DECLARE_RTBL(,_PRMarking_MarkNextAStack,)
369 MAYBE_DECLARE_RTBL(,_PRMarking_MarkNextBStack,)
370
371 #endif /* PAR */
372
373 #ifdef CONCURRENT
374 MAYBE_DECLARE_RTBL(,_PRMarking_MarkNextSpark,)
375 #endif
376
377 MAYBE_DECLARE_RTBL(,_PRMarking_MarkNextRoot,)
378 MAYBE_DECLARE_RTBL(,_PRMarking_MarkNextCAF,)
379
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)  \
384         INCLUDE_PAR_INFO   \
385         INCLUDE_COPYING_INFO(dummy_code,dummy_code) \
386         INCLUDE_COMPACTING_INFO(dummy_code,dummy_code,dummy_code,prreturn_code) \
387     }
388
389 /* Unused "Code to avoid explicit updating of CAF references" used to live here
390     (WDP 94/11)
391 */ 
392
393 #endif /* _INFO_MARKING */
394
395
396 /****************************** COMPACTING ******************************/
397
398 #if defined(_INFO_COMPACTING)
399
400 #ifndef PAR
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));
405 #else
406 P_ Inplace_Compaction PROTO((P_ base, P_ lim,
407                              P_ scanbase, P_ scablim,
408                              BitWord *bit_array, I_ bit_array_words));
409 #endif
410 /* Applied to marked info pointers */
411
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])
416
417 /*
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.
421 */
422
423 #define  LINK_GLOBALADDRESS(loc)
424
425 #if defined(GCgn)
426
427 extern StgScavFun _Scavenge_OldRoot;               /* Allocated Old -> New root, just skip */
428 extern StgEvacFun _Evacuate_OldRoot;               /* Should not occur */
429
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 */
432
433 EXTDATA_RO(OldRoot_info);
434
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[] = {                                  \
439         (W_) ind_code                                           \
440         ,(W_) INFO_OTHER_TAG                                    \
441         ,(W_) MK_REP_REF(OldRoot,,)                             \
442         INCLUDE_PROFILING_INFO(infolbl)                         \
443         }
444
445 MAYBE_DECLARE_RTBL(OldRoot,,)
446
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 */        \
451         INCLUDE_PAR_INFO                        \
452         INCLUDE_COPYING_INFO(_Evacuate_OldRoot,_Scavenge_OldRoot)       \
453         SPEC_COMPACTING_INFO(_ScanLink_2_1,_PRStart_OldRoot,_ScanMove_OldRoot,_PRIn_1) \
454         }
455
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);            \
462           }}
463
464 #else /* ! GCgn */
465
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);     \
472           }}
473
474 #endif /* ! GCgn */
475
476 #if defined(_GC_DEBUG)
477
478 #if defined(GCgn)
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); \
485         else                                    \
486              fprintf(stderr, "  Link Loc: 0x%lx to 0x%lx OutOfRange Closure -- Not Done\n", location, closure); \
487     }
488 #else /* ! GCgn */
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); \
493         else                                    \
494             fprintf(stderr, "  Link Loc: 0x%lx to 0x%lx Static Closure -- Not Done\n", location, closure); \
495     }
496 #endif /* ! GCgn */
497
498 #define DEBUG_UNLINK_LOCATION(location, closure, newlocation)   \
499     if (SM_trace & 4)                                           \
500         fprintf(stderr, "  UnLink Loc: 0x%lx, 0x%lx -> 0x%lx\n", location, closure, newlocation)
501
502 #define DEBUG_LINK_CAF(caf) \
503     if (SM_trace & 4)           \
504         fprintf(stderr, "Caf: 0x%lx  Closure: 0x%lx\n", caf, IND_CLOSURE_PTR(caf))
505
506 #define DEBUG_SET_MARK(closure, hp_word) \
507     if (SM_trace & 8)                    \
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))
509
510 #else
511 #if defined(GCgn)
512 #define DEBUG_LINK_LOCATION(location, closure, linklim)
513 #else
514 #define DEBUG_LINK_LOCATION(location, closure)
515 #endif
516 #define DEBUG_UNLINK_LOCATION(location, closure, newlocation)
517 #define DEBUG_LINK_CAF(caf)
518 #define DEBUG_SET_MARK(closure, hp_word)
519 #endif
520
521 #endif /* _INFO_COMPACTING */
522
523 #endif /* SMinternals_H */
524
525 \end{code}