[project @ 1998-11-26 09:17:22 by sof]
[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 #if defined(GRAN)
334 EXTFUN(_PRMarking_MarkNextEvent);
335 EXTFUN(_PRMarking_MarkNextClosureInFetchBuffer);
336 #endif
337
338 #ifdef PAR
339 EXTFUN(_PRMarking_MarkNextGA);
340 MAYBE_DECLARE_RTBL(,_PRMarking_MarkNextGA,)
341 #else
342
343 EXTFUN(_PRMarking_MarkNextAStack);
344 EXTFUN(_PRMarking_MarkNextBStack);
345
346 MAYBE_DECLARE_RTBL(,_PRMarking_MarkNextAStack,)
347 MAYBE_DECLARE_RTBL(,_PRMarking_MarkNextBStack,)
348
349 #endif /* PAR */
350
351 #ifdef CONCURRENT
352 MAYBE_DECLARE_RTBL(,_PRMarking_MarkNextSpark,)
353 #endif
354
355 #if defined(GRAN)
356 MAYBE_DECLARE_RTBL(,_PRMarking_MarkNextEvent,)
357 MAYBE_DECLARE_RTBL(,_PRMarking_MarkNextClosureInFetchBuffer,)
358 #endif
359
360 MAYBE_DECLARE_RTBL(,_PRMarking_MarkNextRoot,)
361 MAYBE_DECLARE_RTBL(,_PRMarking_MarkNextCAF,)
362
363 #define DUMMY_PRRETURN_RTBL(prreturn_code,dummy_code)   \
364     const W_ MK_REP_LBL(,prreturn_code,)[] = {          \
365         INCLUDE_TYPE_INFO(INTERNAL)                     \
366         INCLUDE_SIZE_INFO(INFO_UNUSED,INFO_UNUSED)      \
367         INCLUDE_PAR_INFO                                \
368         INCLUDE_COPYING_INFO(dummy_code,dummy_code)     \
369         INCLUDE_COMPACTING_INFO(dummy_code,dummy_code,dummy_code,prreturn_code) \
370     }
371
372 /* Unused "Code to avoid explicit updating of CAF references" used to live here
373     (WDP 94/11)
374 */ 
375
376 #endif /* _INFO_MARKING */
377
378
379 /****************************** COMPACTING ******************************/
380
381 #if defined(_INFO_COMPACTING)
382
383 #ifndef PAR
384 P_ Inplace_Compaction PROTO((P_ base, P_ lim,
385                              P_ scanbase, P_ scablim,
386                              BitWord *bit_array, I_ bit_array_words,
387                              StgPtr *MallocPtrList));
388 #else
389 P_ Inplace_Compaction PROTO((P_ base, P_ lim,
390                              P_ scanbase, P_ scablim,
391                              BitWord *bit_array, I_ bit_array_words));
392 #endif
393 /* Applied to marked info pointers */
394
395 #define SCAN_LINK_CODE(infoptr) \
396           ((StgScanPtr) ((P_)(INFO_RTBL(infoptr)))[COMPACTING_INFO_OFFSET])
397 #define SCAN_MOVE_CODE(infoptr) \
398           ((StgScanPtr) ((P_)(INFO_RTBL(infoptr)))[COMPACTING_INFO_OFFSET+2])
399
400 /*
401         This fragment tests whether we're in global garbage collection during parallel
402         evaluation.  If so, then we check the global address of the closure \tr{loc}
403         and evacuate it in the IMUs if it's a legal global address.
404 */
405
406 #define  LINK_GLOBALADDRESS(loc)
407
408 #if defined(GCgn)
409
410 extern StgScavFun _Scavenge_OldRoot;               /* Allocated Old -> New root, just skip */
411 extern StgEvacFun _Evacuate_OldRoot;               /* Should not occur */
412
413 extern StgFunPtr  _PRStart_OldRoot(STG_NO_ARGS);   /* Marking old root -- Short circut if points to oldgen */
414 extern StgScanFun _ScanMove_OldRoot;               /* Scanning old root -- Rebuild old root list */
415
416 EXTDATA_RO(OldRoot_info);
417
418 #define OLDROOT_ITBL(infolbl,ind_code,localness,entry_localness)\
419     CAT_DECLARE(infolbl,INTERNAL_KIND,"OLDROOT","OLDROOT")      \
420     entry_localness(ind_code);                                  \
421     localness W_ infolbl[] = {                                  \
422         (W_) ind_code                                           \
423         ,(W_) INFO_OTHER_TAG                                    \
424         ,(W_) MK_REP_REF(OldRoot,,)                             \
425         INCLUDE_PROFILING_INFO(infolbl)                         \
426         }
427
428 MAYBE_DECLARE_RTBL(OldRoot,,)
429
430 #define OLDROOT_RTBL()                                                  \
431     const W_ MK_REP_LBL(OldRoot,,)[] = {                                \
432         INCLUDE_TYPE_INFO(SPEC_U)                                       \
433         INCLUDE_SIZE_INFO(2,1)  /* deeply hardwired size/ptrs */        \
434         INCLUDE_PAR_INFO                        \
435         INCLUDE_COPYING_INFO(_Evacuate_OldRoot,_Scavenge_OldRoot)       \
436         SPEC_COMPACTING_INFO(_ScanLink_2_1,_PRStart_OldRoot,_ScanMove_OldRoot,_PRIn_1) \
437         }
438
439 #define LINK_LOCATION_TO_CLOSURE(loc,linklim)                   \
440           { P_ _temp = (P_) *(loc);                             \
441           DEBUG_LINK_LOCATION(loc, _temp, linklim);             \
442           if (DYNAMIC_CLOSURE(_temp) && (_temp <= linklim)) {   \
443               *((P_)(loc)) = (W_) INFO_PTR(_temp);              \
444               INFO_PTR(_temp)  = MARK_LOCATION(loc);            \
445           }}
446
447 #else /* ! GCgn */
448
449 #define LINK_LOCATION_TO_CLOSURE(loc)           \
450           { P_ _temp = (P_) *(loc);     \
451           DEBUG_LINK_LOCATION(loc, _temp);      \
452           if (DYNAMIC_CLOSURE(_temp)) {         \
453               *((P_)(loc)) = (W_) INFO_PTR(_temp); \
454               INFO_PTR(_temp) = MARK_LOCATION(loc);     \
455           }}
456
457 #endif /* ! GCgn */
458
459 #if defined(DEBUG)
460
461 #if defined(GCgn)
462 #define DEBUG_LINK_LOCATION(location, closure, linklim) \
463     if (RTSflags.GcFlags.trace & DEBUG_TRACE_MAJOR_GC) {                                \
464         if (DYNAMIC_CLOSURE(closure) && (closure <= linklim)) \
465             fprintf(stderr, "  Link Loc: 0x%lx to 0x%lx\n", location, closure); \
466         else if (! DYNAMIC_CLOSURE(closure))    \
467              fprintf(stderr, "  Link Loc: 0x%lx to 0x%lx Static Closure -- Not Done\n", location, closure); \
468         else                                    \
469              fprintf(stderr, "  Link Loc: 0x%lx to 0x%lx OutOfRange Closure -- Not Done\n", location, closure); \
470     }
471 #else /* ! GCgn */
472 #define DEBUG_LINK_LOCATION(location, closure)  \
473     if (RTSflags.GcFlags.trace & DEBUG_TRACE_MAJOR_GC) {                                \
474         if (DYNAMIC_CLOSURE(closure))           \
475             fprintf(stderr, "  Link Loc: 0x%lx to 0x%lx\n", location, closure); \
476         else                                    \
477             fprintf(stderr, "  Link Loc: 0x%lx to 0x%lx Static Closure -- Not Done\n", location, closure); \
478     }
479 #endif /* ! GCgn */
480
481 #define DEBUG_UNLINK_LOCATION(location, closure, newlocation)   \
482     if (RTSflags.GcFlags.trace & DEBUG_TRACE_MAJOR_GC)                                          \
483         fprintf(stderr, "  UnLink Loc: 0x%lx, 0x%lx -> 0x%lx\n", location, closure, newlocation)
484
485 #define DEBUG_LINK_CAF(caf) \
486     if (RTSflags.GcFlags.trace & DEBUG_TRACE_MAJOR_GC)          \
487         fprintf(stderr, "Caf: 0x%lx  Closure: 0x%lx\n", caf, IND_CLOSURE_PTR(caf))
488
489 #define DEBUG_SET_MARK(closure, hp_word) \
490     if (RTSflags.GcFlags.trace & DEBUG_TRACE_MARKING)                    \
491         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))
492
493 #else
494 #if defined(GCgn)
495 #define DEBUG_LINK_LOCATION(location, closure, linklim)
496 #else
497 #define DEBUG_LINK_LOCATION(location, closure)
498 #endif
499 #define DEBUG_UNLINK_LOCATION(location, closure, newlocation)
500 #define DEBUG_LINK_CAF(caf)
501 #define DEBUG_SET_MARK(closure, hp_word)
502 #endif
503
504 #endif /* _INFO_COMPACTING */
505
506 #endif /* SMinternals_H */
507
508 \end{code}