ddbb20cf73f019eb320f61798331998a80c5f7af
[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 P_ heap_space;
26 extern P_ hp_start;
27
28 void stat_init    PROTO((char *collector, char *c1, char *c2));
29 void stat_startGC PROTO((I_ alloc));
30 void stat_endGC   PROTO((I_ alloc, I_ collect, I_ live, char *comment));
31 void stat_exit    PROTO((I_ alloc));
32
33 extern I_ MaxResidency;     /* in words; for stats only */
34 extern I_ ResidencySamples; /* for stats only */
35
36 #define DO_MAX_RESIDENCY(r) /* saves typing */  \
37     do {                                        \
38         I_ resid = (r);                         \
39         ResidencySamples++;                     \
40         if (resid > MaxResidency) {             \
41             MaxResidency = resid;               \
42         }                                       \
43     } while (0)
44
45 StgFunPtr _Dummy_entry(STG_NO_ARGS);
46
47 #if defined(DEBUG)
48 #define DEBUG_SCAN(str, pos, to, topos) \
49         if (RTSflags.GcFlags.trace & DEBUG_TRACE_MINOR_GC) \
50             fprintf(stderr, "%s: 0x%lx, %s 0x%lx\n", str, pos, to, topos)
51 #define DEBUG_STRING(str) \
52         if (RTSflags.GcFlags.trace & DEBUG_TRACE_MINOR_GC) \
53             fprintf(stderr, "%s\n", str)
54 #else
55 #define DEBUG_SCAN(str, pos, to, topos)
56 #define DEBUG_STRING(str)
57 #endif
58
59 #define NEXT_SEMI_SPACE(space) ((space + 1) % 2)
60
61 /************************ Random stuff **********************/
62
63 /* This should be really big */
64 #define BIG_STRING_LEN           512
65
66 /************************** TWO SPACE COPYING (2s) **************************/
67
68 #if defined(GC2s)
69
70 typedef struct {
71     P_ base;    /* First word allocatable in semispace */
72     P_ lim;     /* Last word allocatable in semispace */
73 } semispaceData;
74
75 extern I_ semispace;    /* 0 or 1 -- indexes semispaceInfo */
76 extern semispaceData semispaceInfo[2];
77
78 #endif /* GC2s */
79
80
81 /*********************** SINGLE SPACE COMPACTION (1s) ***********************/
82
83 #if defined(GC1s)
84
85 typedef struct {
86     P_ base;  /* First word allocatable in heap */
87     P_ lim;   /* Last word allocatable in heap */
88     BitWord *bits;      /* Area for marking bits */
89     I_ bit_words;       /* Size of marking bit area (in words) */
90     I_ heap_words;      /* Size of heap area (in words) */
91 } compactingData;
92
93 extern compactingData compactingInfo;
94
95 #endif /* GC1s */
96
97
98 /****************************** DUAL MODE (du) ******************************/
99
100 #if defined(GCdu)
101
102 typedef struct {
103         I_ mode;
104         StgFloat resid_to_compact;
105         StgFloat resid_from_compact;
106         struct {
107             P_ base; /* First word allocatable in this mode */
108             P_ lim;  /* Last word allocatable in this mode */
109             I_ heap_words; /* Size of area (in words) */
110             char *name;
111         } modeinfo[3];
112         BitWord *bits;      /* Area for marking bits */
113         I_ bit_words;   /* Size of marking bit area (in words) */
114 } dualmodeData;
115
116 extern dualmodeData dualmodeInfo;
117
118 #define DEFAULT_RESID_TO_COMPACT   0.25
119 #define DEFAULT_RESID_FROM_COMPACT 0.20
120
121 #define TWO_SPACE_BOT 0
122 #define TWO_SPACE_TOP 1
123 #define COMPACTING    2
124
125 #endif /* GCdu */
126
127 /*************************** APPELS COLLECTOR (ap) **************************/
128
129 #if defined(GCap)
130
131 typedef struct {
132         P_ oldbase;   /* first word allocatable in oldgen */
133         P_ oldlim;    /* last word allocated in oldgen */
134         P_ oldlast;   /* oldlim after last major collection */
135         P_ oldthresh; /* threshold of oldgen occupancy */
136         P_ oldmax;    /* maximum allocatable in oldgen before heap deemed full */
137
138         I_ newfixed;  /* The size of the new generation, if fixed */
139         I_ newmin;    /* The minimum size of the new generation */
140         P_ newbase;   /* First word allocatable in newgen top space */
141         P_ newlim;    /* Last word allocatable in newgen top space */
142
143         BitWord *bits;    /* Area for marking bits */
144
145         P_ OldCAFlist; /* CAFs promoted to old generation */
146         I_ OldCAFno;   /* No of CAFs promoted to old generation */
147         I_ bit_words;  /* Size of marking bit area (in words) */
148
149         P_ PromMutables; /* List of recently promoted mutable closures */
150
151         I_ semi_space;   /* -F forced 2s collector */
152         struct {
153             P_ base;  /* First word allocatable in semispace */
154             P_ lim;   /* Last word allocatable in semispace */
155         } space[2];
156
157 } appelData;
158
159 /* UPDATE INFO - Stored in sm info structure:
160       Additional info required when updating to keep track of
161         new generation roots residing in the old generation
162         (old -> new inter-generation pointers)
163 */
164
165 extern appelData appelInfo;
166
167 #endif /* GCap */
168
169
170 /************************ GENERATIONAL COLLECTOR (gn) ***********************/
171
172 #if defined(GCgn)
173
174 typedef struct {
175         I_ alloc_words;  /* Size of allocation space */
176                            /* May be large enough for bit array */
177         I_ new_words;    /* Size of new generation semi-space */
178                            /* Must be large enough for bit array */
179         I_ old_words;    /* Size of old generation */
180
181         I_  minor_since_major;
182                            /* No of minor collections since last major */ 
183
184         P_ allocbase;  /* First word allocatable in oldgen */
185         P_ alloclim;   /* Last word allocatable in oldgen */
186
187         I_ curnew;         /* New gen semi-space currently in use */
188         struct {
189          P_ newbase;   /* First word allocatable in newgen semispace */
190          P_ newlim;    /* Last word allocated in new semi-space */
191         } newgen[2];
192
193         P_ oldbase;    /* First word allocatable in oldgen */
194         P_ oldend;     /* Last word allocatable in oldgen */
195         P_ oldwas;     /* Limit of oldgen after last major collection */
196         P_ oldlim;     /* Last word allocated in oldgen */
197         P_ oldthresh;  /* Oldgen threshold: less than new_words free */
198         BitWord *bit_vect; /* Marking bits -- alloc area or old generation */
199
200         P_ OldInNew;   /* Old roots pointing to new generation */
201         I_ OldInNewno; /* No of Old roots pointing to new generation */
202         P_ NewCAFlist; /* CAFs in new generation */
203         I_ NewCAFno;   /* No of CAFs in new generation */
204         P_ OldCAFlist; /* CAFs promoted to old generation */
205         I_ OldCAFno;   /* No of CAFs promoted to old generation */
206
207         P_ PromMutables; /* List of recently promoted mutable closures */
208
209         I_ semi_space;  /* -F forced 2s collector */
210         struct {
211             P_ base; /* First word allocatable in semispace */
212             P_ lim;  /* Last word allocatable in semispace */
213         } space[2];
214 } genData;
215
216 extern genData genInfo;
217
218 /* Update INFO - Stored in sm info structure:
219       Additional info required when updating to keep track of
220         new generation roots residing in the old generation
221         (old -> new inter-generation pointers)
222 */
223
224 #endif /* GCap */
225
226 /****************************** COPYING ******************************/
227
228
229 #if defined(_INFO_COPYING)
230
231 #define EVAC_CODE(infoptr)  ((StgEvacPtr) ((P_)(INFO_RTBL(infoptr)))[COPY_INFO_OFFSET])
232 #define SCAV_CODE(infoptr)  ((StgScavPtr) ((P_)(INFO_RTBL(infoptr)))[COPY_INFO_OFFSET+1])
233
234 void Scavenge(STG_NO_ARGS);
235 void  _Scavenge_Forward_Ref(STG_NO_ARGS);
236
237 /* Note: any change to FORWARD_ADDRESS should be
238    reflected in layout of MallocPtrs (includes/SMClosures.lh)
239 */
240
241 #define FORWARD_ADDRESS(closure)  (*(((P_)(closure)) + FIXED_HS))
242
243 #define FORWARDREF_ITBL(infolbl,entry,localness,evac_forward)   \
244 CAT_DECLARE(infolbl,INTERNAL_KIND,"FORWARD_REF","FORWARD_REF")  \
245 localness W_ infolbl[] = {                                      \
246         (W_) entry                                              \
247         ,(W_) INFO_OTHER_TAG                                    \
248         ,(W_) MK_REP_REF(,evac_forward,)                        \
249         INCLUDE_PROFILING_INFO(infolbl)                         \
250         }
251
252 P_ _Evacuate_Old_Forward_Ref PROTO((P_));
253 P_ _Evacuate_New_Forward_Ref PROTO((P_));
254 P_ _Evacuate_OldRoot_Forward PROTO((P_));
255 P_ _Evacuate_Forward_Ref PROTO((P_));
256
257 MAYBE_DECLARE_RTBL(,_Evacuate_Old_Forward_Ref,)
258 MAYBE_DECLARE_RTBL(,_Evacuate_New_Forward_Ref,)
259 MAYBE_DECLARE_RTBL(,_Evacuate_OldRoot_Forward,)
260 MAYBE_DECLARE_RTBL(,_Evacuate_Forward_Ref,)
261
262 #define FORWARDREF_RTBL(evac_forward) \
263     const W_ MK_REP_LBL(,evac_forward,)[] = { \
264         INCLUDE_TYPE_INFO(INTERNAL)                             \
265         INCLUDE_SIZE_INFO(INFO_UNUSED,INFO_UNUSED)              \
266         INCLUDE_PAR_INFO                                        \
267         INCLUDE_COPYING_INFO(evac_forward,_Scavenge_Forward_Ref)\
268         INCLUDE_COMPACTING_INFO(INFO_UNUSED,INFO_UNUSED,INFO_UNUSED,INFO_UNUSED) \
269         }
270
271 EXTDATA_RO(Caf_Evac_Upd_info);
272 extern StgEvacFun _Evacuate_Caf_Evac_Upd;
273
274 #define CAF_EVAC_UPD_ITBL(infolbl,entry,localness)              \
275 CAT_DECLARE(infolbl,INTERNAL_KIND,"CAF_EVAC_UPD","CAF_EVAC_UPD") \
276 localness W_ infolbl[] = {                                      \
277         (W_) entry                                              \
278         ,(W_) INFO_OTHER_TAG                                    \
279         ,(W_) MK_REP_REF(Caf_Evac_Upd,,)                        \
280         INCLUDE_PROFILING_INFO(infolbl)                         \
281         }
282
283 MAYBE_DECLARE_RTBL(Caf_Evac_Upd,,)
284
285 #define CAF_EVAC_UPD_RTBL() \
286     const W_ MK_REP_LBL(Caf_Evac_Upd,,)[] = { \
287         INCLUDE_TYPE_INFO(INTERNAL)                             \
288         INCLUDE_SIZE_INFO(MIN_UPD_SIZE,INFO_UNUSED)             \
289         INCLUDE_PAR_INFO                                        \
290         INCLUDE_COPYING_INFO(_Evacuate_Caf_Evac_Upd,_Scavenge_Caf) \
291         INCLUDE_COMPACTING_INFO(INFO_UNUSED,INFO_UNUSED,INFO_UNUSED,INFO_UNUSED) \
292     }
293
294 #define EVACUATE_CLOSURE(closure)      \
295         (EVAC_CODE(INFO_PTR(closure)))(closure)
296
297 #endif /* _INFO_COPYING */
298
299
300 /****************************** MARKING ******************************/
301
302 #if defined(_INFO_MARKING)
303
304 I_ markHeapRoots PROTO((smInfo *sm, P_ cafs1, P_ cafs2,
305                         P_ base, P_ lim, BitWord *bit_array));
306
307 #define PRMARK_CODE(infoptr) \
308           (((FP_)(INFO_RTBL(infoptr)))[COMPACTING_INFO_OFFSET+1])
309
310 /* Applied to unmarked or marking info pointer */
311 #define PRRETURN_CODE(infoptr) \
312           (((FP_)(INFO_RTBL(infoptr)))[COMPACTING_INFO_OFFSET+3])
313
314 /* This placed on bottom of PR Marking Stack */
315
316 #define DUMMY_PRRETURN_CLOSURE(closure_name, table_name, prreturn_code, dummy_code) \
317 const W_ table_name[] = {                       \
318         (W_) dummy_code                         \
319         ,(W_) INFO_OTHER_TAG                    \
320         ,(W_) MK_REP_REF(,prreturn_code,)       \
321         INCLUDE_PROFILING_INFO(Dummy_PrReturn)  \
322         };                                      \
323 W_ closure_name = (W_) table_name
324
325 EXTFUN(_Dummy_PRReturn_entry);
326 EXTFUN(_PRMarking_MarkNextRoot);
327 EXTFUN(_PRMarking_MarkNextCAF);
328
329 #ifdef CONCURRENT
330 EXTFUN(_PRMarking_MarkNextSpark);
331 #endif
332
333 #ifdef PAR
334 EXTFUN(_PRMarking_MarkNextGA);
335 MAYBE_DECLARE_RTBL(,_PRMarking_MarkNextGA,)
336 #else
337
338 EXTFUN(_PRMarking_MarkNextAStack);
339 EXTFUN(_PRMarking_MarkNextBStack);
340
341 MAYBE_DECLARE_RTBL(,_PRMarking_MarkNextAStack,)
342 MAYBE_DECLARE_RTBL(,_PRMarking_MarkNextBStack,)
343
344 #endif /* PAR */
345
346 #ifdef CONCURRENT
347 MAYBE_DECLARE_RTBL(,_PRMarking_MarkNextSpark,)
348 #endif
349
350 MAYBE_DECLARE_RTBL(,_PRMarking_MarkNextRoot,)
351 MAYBE_DECLARE_RTBL(,_PRMarking_MarkNextCAF,)
352
353 #define DUMMY_PRRETURN_RTBL(prreturn_code,dummy_code)   \
354     const W_ MK_REP_LBL(,prreturn_code,)[] = {          \
355         INCLUDE_TYPE_INFO(INTERNAL)                     \
356         INCLUDE_SIZE_INFO(INFO_UNUSED,INFO_UNUSED)      \
357         INCLUDE_PAR_INFO                                \
358         INCLUDE_COPYING_INFO(dummy_code,dummy_code)     \
359         INCLUDE_COMPACTING_INFO(dummy_code,dummy_code,dummy_code,prreturn_code) \
360     }
361
362 /* Unused "Code to avoid explicit updating of CAF references" used to live here
363     (WDP 94/11)
364 */ 
365
366 #endif /* _INFO_MARKING */
367
368
369 /****************************** COMPACTING ******************************/
370
371 #if defined(_INFO_COMPACTING)
372
373 #ifndef PAR
374 P_ Inplace_Compaction PROTO((P_ base, P_ lim,
375                              P_ scanbase, P_ scablim,
376                              BitWord *bit_array, I_ bit_array_words,
377                              StgPtr *MallocPtrList));
378 #else
379 P_ Inplace_Compaction PROTO((P_ base, P_ lim,
380                              P_ scanbase, P_ scablim,
381                              BitWord *bit_array, I_ bit_array_words));
382 #endif
383 /* Applied to marked info pointers */
384
385 #define SCAN_LINK_CODE(infoptr) \
386           ((StgScanPtr) ((P_)(INFO_RTBL(infoptr)))[COMPACTING_INFO_OFFSET])
387 #define SCAN_MOVE_CODE(infoptr) \
388           ((StgScanPtr) ((P_)(INFO_RTBL(infoptr)))[COMPACTING_INFO_OFFSET+2])
389
390 /*
391         This fragment tests whether we're in global garbage collection during parallel
392         evaluation.  If so, then we check the global address of the closure \tr{loc}
393         and evacuate it in the IMUs if it's a legal global address.
394 */
395
396 #define  LINK_GLOBALADDRESS(loc)
397
398 #if defined(GCgn)
399
400 extern StgScavFun _Scavenge_OldRoot;               /* Allocated Old -> New root, just skip */
401 extern StgEvacFun _Evacuate_OldRoot;               /* Should not occur */
402
403 extern StgFunPtr  _PRStart_OldRoot(STG_NO_ARGS);   /* Marking old root -- Short circut if points to oldgen */
404 extern StgScanFun _ScanMove_OldRoot;               /* Scanning old root -- Rebuild old root list */
405
406 EXTDATA_RO(OldRoot_info);
407
408 #define OLDROOT_ITBL(infolbl,ind_code,localness,entry_localness)\
409     CAT_DECLARE(infolbl,INTERNAL_KIND,"OLDROOT","OLDROOT")      \
410     entry_localness(ind_code);                                  \
411     localness W_ infolbl[] = {                                  \
412         (W_) ind_code                                           \
413         ,(W_) INFO_OTHER_TAG                                    \
414         ,(W_) MK_REP_REF(OldRoot,,)                             \
415         INCLUDE_PROFILING_INFO(infolbl)                         \
416         }
417
418 MAYBE_DECLARE_RTBL(OldRoot,,)
419
420 #define OLDROOT_RTBL()                                                  \
421     const W_ MK_REP_LBL(OldRoot,,)[] = {                                \
422         INCLUDE_TYPE_INFO(SPEC_U)                                       \
423         INCLUDE_SIZE_INFO(2,1)  /* deeply hardwired size/ptrs */        \
424         INCLUDE_PAR_INFO                        \
425         INCLUDE_COPYING_INFO(_Evacuate_OldRoot,_Scavenge_OldRoot)       \
426         SPEC_COMPACTING_INFO(_ScanLink_2_1,_PRStart_OldRoot,_ScanMove_OldRoot,_PRIn_1) \
427         }
428
429 #define LINK_LOCATION_TO_CLOSURE(loc,linklim)                   \
430           { P_ _temp = (P_) *(loc);                             \
431           DEBUG_LINK_LOCATION(loc, _temp, linklim);             \
432           if (DYNAMIC_CLOSURE(_temp) && (_temp <= linklim)) {   \
433               *((P_)(loc)) = (W_) INFO_PTR(_temp);              \
434               INFO_PTR(_temp)  = MARK_LOCATION(loc);            \
435           }}
436
437 #else /* ! GCgn */
438
439 #define LINK_LOCATION_TO_CLOSURE(loc)           \
440           { P_ _temp = (P_) *(loc);     \
441           DEBUG_LINK_LOCATION(loc, _temp);      \
442           if (DYNAMIC_CLOSURE(_temp)) {         \
443               *((P_)(loc)) = (W_) INFO_PTR(_temp); \
444               INFO_PTR(_temp) = MARK_LOCATION(loc);     \
445           }}
446
447 #endif /* ! GCgn */
448
449 #if defined(DEBUG)
450
451 #if defined(GCgn)
452 #define DEBUG_LINK_LOCATION(location, closure, linklim) \
453     if (RTSflags.GcFlags.trace & DEBUG_TRACE_MAJOR_GC) {                                \
454         if (DYNAMIC_CLOSURE(closure) && (closure <= linklim)) \
455             fprintf(stderr, "  Link Loc: 0x%lx to 0x%lx\n", location, closure); \
456         else if (! DYNAMIC_CLOSURE(closure))    \
457              fprintf(stderr, "  Link Loc: 0x%lx to 0x%lx Static Closure -- Not Done\n", location, closure); \
458         else                                    \
459              fprintf(stderr, "  Link Loc: 0x%lx to 0x%lx OutOfRange Closure -- Not Done\n", location, closure); \
460     }
461 #else /* ! GCgn */
462 #define DEBUG_LINK_LOCATION(location, closure)  \
463     if (RTSflags.GcFlags.trace & DEBUG_TRACE_MAJOR_GC) {                                \
464         if (DYNAMIC_CLOSURE(closure))           \
465             fprintf(stderr, "  Link Loc: 0x%lx to 0x%lx\n", location, closure); \
466         else                                    \
467             fprintf(stderr, "  Link Loc: 0x%lx to 0x%lx Static Closure -- Not Done\n", location, closure); \
468     }
469 #endif /* ! GCgn */
470
471 #define DEBUG_UNLINK_LOCATION(location, closure, newlocation)   \
472     if (RTSflags.GcFlags.trace & DEBUG_TRACE_MAJOR_GC)                                          \
473         fprintf(stderr, "  UnLink Loc: 0x%lx, 0x%lx -> 0x%lx\n", location, closure, newlocation)
474
475 #define DEBUG_LINK_CAF(caf) \
476     if (RTSflags.GcFlags.trace & DEBUG_TRACE_MAJOR_GC)          \
477         fprintf(stderr, "Caf: 0x%lx  Closure: 0x%lx\n", caf, IND_CLOSURE_PTR(caf))
478
479 #define DEBUG_SET_MARK(closure, hp_word) \
480     if (RTSflags.GcFlags.trace & DEBUG_TRACE_MARKING)                    \
481         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))
482
483 #else
484 #if defined(GCgn)
485 #define DEBUG_LINK_LOCATION(location, closure, linklim)
486 #else
487 #define DEBUG_LINK_LOCATION(location, closure)
488 #endif
489 #define DEBUG_UNLINK_LOCATION(location, closure, newlocation)
490 #define DEBUG_LINK_CAF(caf)
491 #define DEBUG_SET_MARK(closure, hp_word)
492 #endif
493
494 #endif /* _INFO_COMPACTING */
495
496 #endif /* SMinternals_H */
497
498 \end{code}