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