1 /*************************************************************************
4 This file contains the basic routines required for inplace compacting
5 garbage collection. It is based on Jonkers's algorithm.
7 There is a compacting routine as well as all the basic routines which
8 are placed in the info tables of the appropriate closures.
10 ToDo: Remove Fillers -- Compiler
11 Remove Dummy Filler Macros -- SMupdate.lh
12 Remove special "shrinking" info_upd stuff -- Compiler
13 Remove special "shrinking" info_upd stuff -- SMinterface.lh
15 Updateable closure size can now be relaxed
17 May want to allocate larger closures to enable updates inplace
18 eg Int 1 MkInt etc fit
20 STree 3 Leaf(2) Branch(3) fit
21 STree 2 Leaf(2) fits, Branch(3) fails
22 Tuple4 1 MkTuple4 fails
24 Need BHs of appropriate sizes (reserve BHed space for update)
25 For Appel will require BH_1 to grow to size 2 when collected.
27 *************************************************************************/
32 #include "SMinternal.h"
34 #if defined(_INFO_COMPACTING)
36 /* Define appropriate global variables as potential register variables */
37 /* Assume GC code saves and restores global registers used */
39 RegisterTable ScanRegTable;
42 /* As we perform compaction, those CHP's which are still alive get
43 added to this list. [ADR] */
44 StgPtr NewMallocPtrList;
48 Inplace_Compaction(base, lim, scanbase, scanlim, bit_array, bit_array_words
60 StgPtr *MallocPtrList;
63 BitWord *bit_array_ptr, *bit_array_end;
64 P_ scan_w_start, info;
67 LinkLim = lim; /* Only checked for generational collection */
71 /* Scan collected new gen semi-space linking pointers to old gen */
72 /* No closures to unlink (no new ptrs will be linked) */
73 /* Have to reset closure to unmarked if it has been marked */
74 /* If not marked, we will still link (and unlink) as we need to */
75 /* get the size to find next closure. */
76 /* It will be collected next minor collection as no root exists*/
78 DEBUG_SCAN("Scan Link Area: Base", scanbase, "Lim", scanlim);
81 New = 0; /* unused -- except by debugging message */
83 while (Scan < scanlim) {
84 info = (P_) UNMARK_LOCATION(INFO_PTR(Scan));
85 Scan += (*SCAN_LINK_CODE(info))();
89 DEBUG_SCAN("Scan Link Bits: Base", base, "Bits", bit_array);
91 bit_array_ptr = bit_array;
92 bit_array_end = bit_array + bit_array_words;
94 New = base; /* used to unwind */
97 NewMallocPtrList = NULL; /* initialise new MallocPtrList */
98 /* As we move MallocPtrs over, we'll add them to this list. */
101 while (bit_array_ptr < bit_array_end) {
102 BitWord w = *(bit_array_ptr++);
107 if (! (w & 0x1)) { /* bit not set */
108 Scan++; /* look at next bit */
111 } else { /* Bit Set -- Enter ScanLink for closure */
112 info = (P_) INFO_PTR(Scan);
113 while (MARKED_LOCATION(info)) {
115 info = UNMARK_LOCATION(info);
117 DEBUG_UNLINK_LOCATION(info, Scan, New);
121 INFO_PTR(Scan) = (W_) info;
123 size = (*SCAN_LINK_CODE(info))();
126 New += size; /* set New address of next closure */
128 Scan += size; /* skip size bits */
130 if (size >= BITS_IN(BitWord)) break;
131 /* NOTA BENE: if size >= # bits in BitWord, then the result
132 of this operation is undefined! Hence the need for
137 scan_w_start += BITS_IN(BitWord);
139 DEBUG_SCAN("Scan Link Bits: End", Scan, "New", New);
141 bit_array_ptr = bit_array;
142 bit_array_end = bit_array + bit_array_words;
143 scan_w_start = base; /* Points to the heap word corresponding to the
144 first bit of *bit_array_ptr */
146 New = base; /* used to unwind and move */
148 DEBUG_SCAN("Scan Move Bits: Base", base, "Bits", bit_array);
149 while (bit_array_ptr < bit_array_end) {
151 /* Grab bit word and clear (its the last scan) */
152 /* Dont need to clear for Appel or Generational major collection */
153 /* Why not??? I think it's because they have a pass which zaps all
154 the bit array to zero. But why do they need it? Or, why
155 doesn't dual-mode need it?
157 It's probably easier just to *always* to zap at the beginning of
158 GC, and remove this conditional compilation here. */
159 #if defined(GCap) || defined(GCgn)
160 BitWord w = (I_) *(bit_array_ptr++);
162 BitWord w = (I_) *bit_array_ptr;
163 *(bit_array_ptr++) = 0;
168 if (! (w & 0x1)) { /* bit not set */
169 Scan++; /* look at next bit */
172 } else { /* Bit Set -- Enter ScanMove for closure*/
173 info = (P_) INFO_PTR(Scan);
174 while (MARKED_LOCATION(info)) {
176 info = UNMARK_LOCATION(info);
178 DEBUG_UNLINK_LOCATION(info, Scan, New);
182 INFO_PTR(New) = (W_) info;
184 size = (*SCAN_MOVE_CODE(info))();
185 New += size; /* set New address of next closure */
186 Scan += size; /* skip size bits */
188 if (size >= BITS_IN(BitWord)) break;
189 /* NOTA BENE: if size >= # bits in BitWord, then the result
190 of this operation is undefined! Hence the need for
192 w >>= size; /* NB: comment above about shifts */
196 /* At this point we've exhausted one word of mark bits */
197 /* Make scan_w_start point to the heap word corresponding to the
198 first bit of the next word of mark bits */
199 scan_w_start += BITS_IN(BitWord);
201 DEBUG_SCAN("Scan Link Bits: End", Scan, "New", New);
206 VALIDATE_MallocPtrList( NewMallocPtrList );
207 *MallocPtrList = NewMallocPtrList;
215 /*************************************************************************
216 Basic SCAN LINK and SCAN MOVE Routines
218 First Scan on Closures
221 Retrieved using SCAN_LINK_CODE(infoptr) (for a true unmarked infoptr)
223 Links the closure's ptr locations to the info pointer of the closure's
224 they actually point. Returns the size of the closure so New can be updated
225 to point to next closure. This also allows sequential scan (if there are no
226 holes i.e. it has already been collected).
228 Must first unwind the locations linked to this closure updating with
229 the new location of this closure before entering the code. The code
230 can only be access from the info pointer at the end of this location
231 list, which must be restored before entering.
233 Calling Conventions (After unwinding and updating locations pointed to):
234 Scan -- points to this closure
235 LinkLim -- points to end of heap are requiring pointer to be linked
237 New (optional) -- points to the new location that this closure will reside
238 this is only required for meaningful debugging meassge
240 Second Scan on Closures
243 Retrieved using SCAN_MOVE_CODE(infoptr) (for a true unmarked infoptr)
245 Slides the closure down to its new location, New. Returns the size of
246 the closure so New can be updated to point to the next closure.
248 Must first unwind the locations linked to this closure updating with
249 the new location of this closure before entering the code. The code
250 can only be access from the info pointer at the end of this location
251 list, which must be restored before entering.
253 Calling Conventions (After unwinding and updating locations pointed to):
254 Scan -- points to this closure
255 New -- points to the new location that this closure will reside
258 Will have MARKING routines in info tables as well:
263 Retrieved using PRMARK_CODE(infoptr)
265 Returning To A Closure Being Marked:
269 Retrieved using PRRETURN_CODE(infoptr)
273 May have COPYING routines in info tables as well:
275 Evacuation code: _Evacuate_S
276 Scavenging code: _Scavenge_S_N
278 See GCscav.lhc GCevac.lc
282 The following registers are used by the Compacting collection:
284 New -- The new address of a closure
285 Scan -- The current address of a closure
286 LinkLim -- The limit of the heap requiring to be linked & moved
288 **************************************************************************/
293 #define LINK_LOCATION(i) LINK_LOCATION_TO_CLOSURE((Scan+(i)),LinkLim)
295 #define LINK_LOCATION(i) LINK_LOCATION_TO_CLOSURE(Scan+(i))
298 /* Link location of nth pointer in SPEC/STKO closure (starting at 1) */
299 #define SPEC_LINK_LOCATION(ptr) LINK_LOCATION((SPEC_HS-1) + (ptr))
300 #define STKO_LINK_LOCATION(ptr) LINK_LOCATION((STKO_HS-1) + (ptr))
303 /* Slide the ith word (starting at 0) */
304 #define SLIDE_WORD(position) New[position] = Scan[position]
306 /* Slide the ith ptr (starting at 0), adjusting by offset */
307 #define ADJUST_WORD(pos,off) ((PP_)New)[pos] += (off)
309 /* Slide the nth free var word in a SPEC closure (starting at 1) */
310 #define SPEC_SLIDE_WORD(n) SLIDE_WORD((SPEC_HS-1) + (n))
313 /* Don't slide the MallocPtr list link - instead link moved object into
314 @NewMallocPtrList@ */
316 #define MallocPtr_SLIDE_DATA \
317 MallocPtr_CLOSURE_DATA(New) = MallocPtr_CLOSURE_DATA(Scan)
318 #define MallocPtr_RELINK \
320 MallocPtr_CLOSURE_LINK(New) = NewMallocPtrList; \
321 NewMallocPtrList = New; \
325 /* The SLIDE_FIXED_HDR macro is dependent on the No of FIXED_HS */
328 #define SLIDE_FIXED_HDR /* Already Assigned INFO_PTR */
331 #define SLIDE_FIXED_HDR SLIDE_WORD(1)
334 #define SLIDE_FIXED_HDR SLIDE_WORD(1);SLIDE_WORD(2)
336 /* I don't think this will be needed (ToDo: #error?) */
344 #define DEBUG_SCAN_LINK(type, sizevar, ptrvar) \
345 if (RTSflags.GcFlags.trace & DEBUG_TRACE_MINOR_GC) \
346 fprintf(stderr, "Scan Link (%s): 0x%lx -> 0x%lx, info 0x%lx, size %ld, ptrs %ld\n", \
347 type, Scan, New, INFO_PTR(Scan), sizevar, ptrvar)
349 #define DEBUG_SCAN_MOVE(type, sizevar) \
350 if (RTSflags.GcFlags.trace & DEBUG_TRACE_MINOR_GC) \
351 fprintf(stderr, "Scan Move (%s): 0x%lx -> 0x%lx, info 0x%lx, size %ld\n", \
352 type, Scan, New, INFO_PTR(New), sizevar)
357 #define DEBUG_SCAN_LINK(type, sizevar, ptrvar)
358 #define DEBUG_SCAN_MOVE(type, sizevar)
362 /*** LINKING CLOSURES ***/
366 _ScanLink_0_0(STG_NO_ARGS) {
367 I_ size = 0; /* NB: SPEC_VHS is *defined* to be zero */
368 DEBUG_SCAN_LINK("SPEC", size, 0);
369 return(FIXED_HS + size);
374 _ScanLink_1_0(STG_NO_ARGS) {
375 I_ size = 1; /* NB: SPEC_VHS is *defined* to be zero */
376 DEBUG_SCAN_LINK("SPEC", size, 0);
377 return(FIXED_HS + size);
380 _ScanLink_1_1(STG_NO_ARGS) {
382 DEBUG_SCAN_LINK("SPEC", size, 1);
383 SPEC_LINK_LOCATION(1);
384 return(FIXED_HS + size);
387 _ScanLink_2_0(STG_NO_ARGS) {
389 DEBUG_SCAN_LINK("SPEC", size, 0);
390 return(FIXED_HS + size);
393 _ScanLink_2_1(STG_NO_ARGS) {
395 DEBUG_SCAN_LINK("SPEC", size, 1);
396 SPEC_LINK_LOCATION(1);
397 return(FIXED_HS + size);
400 _ScanLink_2_2(STG_NO_ARGS) {
402 DEBUG_SCAN_LINK("SPEC", size, 2);
403 SPEC_LINK_LOCATION(1);
404 SPEC_LINK_LOCATION(2);
405 return(FIXED_HS + size);
408 _ScanLink_3_0(STG_NO_ARGS) {
410 DEBUG_SCAN_LINK("SPEC", size, 0);
411 return(FIXED_HS + size);
414 _ScanLink_3_1(STG_NO_ARGS) {
416 DEBUG_SCAN_LINK("SPEC", size, 1);
417 SPEC_LINK_LOCATION(1);
418 return(FIXED_HS + size);
421 _ScanLink_3_2(STG_NO_ARGS) {
423 DEBUG_SCAN_LINK("SPEC", size, 2);
424 SPEC_LINK_LOCATION(1);
425 SPEC_LINK_LOCATION(2);
426 return(FIXED_HS + size);
429 _ScanLink_3_3(STG_NO_ARGS) {
431 DEBUG_SCAN_LINK("SPEC", size, 3);
432 SPEC_LINK_LOCATION(1);
433 SPEC_LINK_LOCATION(2);
434 SPEC_LINK_LOCATION(3);
435 return(FIXED_HS + size);
438 _ScanLink_4_0(STG_NO_ARGS) {
440 DEBUG_SCAN_LINK("SPEC", size, 0);
441 return(FIXED_HS + size);
444 _ScanLink_4_4(STG_NO_ARGS) {
446 DEBUG_SCAN_LINK("SPEC", size, 4);
447 SPEC_LINK_LOCATION(1);
448 SPEC_LINK_LOCATION(2);
449 SPEC_LINK_LOCATION(3);
450 SPEC_LINK_LOCATION(4);
451 return(FIXED_HS + size);
454 _ScanLink_5_0(STG_NO_ARGS) {
456 DEBUG_SCAN_LINK("SPEC", size, 0);
457 return(FIXED_HS + size);
460 _ScanLink_5_5(STG_NO_ARGS) {
462 DEBUG_SCAN_LINK("SPEC", size, 5);
463 SPEC_LINK_LOCATION(1);
464 SPEC_LINK_LOCATION(2);
465 SPEC_LINK_LOCATION(3);
466 SPEC_LINK_LOCATION(4);
467 SPEC_LINK_LOCATION(5);
468 return(FIXED_HS + size);
471 _ScanLink_6_6(STG_NO_ARGS) {
473 DEBUG_SCAN_LINK("SPEC", size, 6);
474 SPEC_LINK_LOCATION(1);
475 SPEC_LINK_LOCATION(2);
476 SPEC_LINK_LOCATION(3);
477 SPEC_LINK_LOCATION(4);
478 SPEC_LINK_LOCATION(5);
479 SPEC_LINK_LOCATION(6);
480 return(FIXED_HS + size);
483 _ScanLink_7_7(STG_NO_ARGS) {
485 DEBUG_SCAN_LINK("SPEC", size, 7);
486 SPEC_LINK_LOCATION(1);
487 SPEC_LINK_LOCATION(2);
488 SPEC_LINK_LOCATION(3);
489 SPEC_LINK_LOCATION(4);
490 SPEC_LINK_LOCATION(5);
491 SPEC_LINK_LOCATION(6);
492 SPEC_LINK_LOCATION(7);
493 return(FIXED_HS + size);
496 _ScanLink_8_8(STG_NO_ARGS) {
498 DEBUG_SCAN_LINK("SPEC", size, 8);
499 SPEC_LINK_LOCATION(1);
500 SPEC_LINK_LOCATION(2);
501 SPEC_LINK_LOCATION(3);
502 SPEC_LINK_LOCATION(4);
503 SPEC_LINK_LOCATION(5);
504 SPEC_LINK_LOCATION(6);
505 SPEC_LINK_LOCATION(7);
506 SPEC_LINK_LOCATION(8);
507 return(FIXED_HS + size);
510 _ScanLink_9_9(STG_NO_ARGS) {
512 DEBUG_SCAN_LINK("SPEC", size, 9);
513 SPEC_LINK_LOCATION(1);
514 SPEC_LINK_LOCATION(2);
515 SPEC_LINK_LOCATION(3);
516 SPEC_LINK_LOCATION(4);
517 SPEC_LINK_LOCATION(5);
518 SPEC_LINK_LOCATION(6);
519 SPEC_LINK_LOCATION(7);
520 SPEC_LINK_LOCATION(8);
521 SPEC_LINK_LOCATION(9);
522 return(FIXED_HS + size);
525 _ScanLink_10_10(STG_NO_ARGS) {
527 DEBUG_SCAN_LINK("SPEC", size, 10);
528 SPEC_LINK_LOCATION(1);
529 SPEC_LINK_LOCATION(2);
530 SPEC_LINK_LOCATION(3);
531 SPEC_LINK_LOCATION(4);
532 SPEC_LINK_LOCATION(5);
533 SPEC_LINK_LOCATION(6);
534 SPEC_LINK_LOCATION(7);
535 SPEC_LINK_LOCATION(8);
536 SPEC_LINK_LOCATION(9);
537 SPEC_LINK_LOCATION(10);
538 return(FIXED_HS + size);
541 _ScanLink_11_11(STG_NO_ARGS) {
543 DEBUG_SCAN_LINK("SPEC", size, 11);
544 SPEC_LINK_LOCATION(1);
545 SPEC_LINK_LOCATION(2);
546 SPEC_LINK_LOCATION(3);
547 SPEC_LINK_LOCATION(4);
548 SPEC_LINK_LOCATION(5);
549 SPEC_LINK_LOCATION(6);
550 SPEC_LINK_LOCATION(7);
551 SPEC_LINK_LOCATION(8);
552 SPEC_LINK_LOCATION(9);
553 SPEC_LINK_LOCATION(10);
554 SPEC_LINK_LOCATION(11);
555 return(FIXED_HS + size);
558 _ScanLink_12_12(STG_NO_ARGS) {
560 DEBUG_SCAN_LINK("SPEC", size, 12);
561 SPEC_LINK_LOCATION(1);
562 SPEC_LINK_LOCATION(2);
563 SPEC_LINK_LOCATION(3);
564 SPEC_LINK_LOCATION(4);
565 SPEC_LINK_LOCATION(5);
566 SPEC_LINK_LOCATION(6);
567 SPEC_LINK_LOCATION(7);
568 SPEC_LINK_LOCATION(8);
569 SPEC_LINK_LOCATION(9);
570 SPEC_LINK_LOCATION(10);
571 SPEC_LINK_LOCATION(11);
572 SPEC_LINK_LOCATION(12);
573 return(FIXED_HS + size);
577 Scan-linking revertible black holes with underlying @SPEC@ closures.
583 _ScanLink_RBH_2_1(STG_NO_ARGS)
585 I_ size = 2 + SPEC_RBH_VHS;
586 DEBUG_SCAN_LINK("SRBH", size, 1);
587 LINK_LOCATION(SPEC_RBH_BQ_LOCN);
588 return(FIXED_HS + size);
591 _ScanLink_RBH_3_1(STG_NO_ARGS)
593 I_ size = 3 + SPEC_RBH_VHS;
594 DEBUG_SCAN_LINK("SRBH", size, 1);
595 LINK_LOCATION(SPEC_RBH_BQ_LOCN);
596 return(FIXED_HS + size);
599 _ScanLink_RBH_3_3(STG_NO_ARGS)
601 I_ size = 3 + SPEC_RBH_VHS;
602 DEBUG_SCAN_LINK("SRBH", size, 3);
603 LINK_LOCATION(SPEC_RBH_BQ_LOCN);
604 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 1);
605 return(FIXED_HS + size);
608 _ScanLink_RBH_4_1(STG_NO_ARGS)
610 I_ size = 4 + SPEC_RBH_VHS;
611 DEBUG_SCAN_LINK("SRBH", size, 1);
612 LINK_LOCATION(SPEC_RBH_BQ_LOCN);
613 return(FIXED_HS + size);
616 _ScanLink_RBH_4_4(STG_NO_ARGS)
618 I_ size = 4 + SPEC_RBH_VHS;
619 DEBUG_SCAN_LINK("SRBH", size, 4);
620 LINK_LOCATION(SPEC_RBH_BQ_LOCN);
621 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 1);
622 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 2);
623 return(FIXED_HS + size);
626 _ScanLink_RBH_5_1(STG_NO_ARGS)
628 I_ size = 5 + SPEC_RBH_VHS;
629 DEBUG_SCAN_LINK("SRBH", size, 1);
630 LINK_LOCATION(SPEC_RBH_BQ_LOCN);
631 return(FIXED_HS + size);
634 _ScanLink_RBH_5_5(STG_NO_ARGS)
636 I_ size = 5 + SPEC_RBH_VHS;
637 DEBUG_SCAN_LINK("SRBH", size, 5);
638 LINK_LOCATION(SPEC_RBH_BQ_LOCN);
639 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 1);
640 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 2);
641 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 3);
642 return(FIXED_HS + size);
645 _ScanLink_RBH_6_6(STG_NO_ARGS)
647 I_ size = 6 + SPEC_RBH_VHS;
648 DEBUG_SCAN_LINK("SRBH", size, 6);
649 LINK_LOCATION(SPEC_RBH_BQ_LOCN);
650 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 1);
651 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 2);
652 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 3);
653 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 4);
654 return(FIXED_HS + size);
657 _ScanLink_RBH_7_7(STG_NO_ARGS)
659 I_ size = 7 + SPEC_RBH_VHS;
660 DEBUG_SCAN_LINK("SRBH", size, 7);
661 LINK_LOCATION(SPEC_RBH_BQ_LOCN);
662 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 1);
663 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 2);
664 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 3);
665 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 4);
666 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 5);
667 return(FIXED_HS + size);
670 _ScanLink_RBH_8_8(STG_NO_ARGS)
672 I_ size = 8 + SPEC_RBH_VHS;
673 DEBUG_SCAN_LINK("SRBH", size, 8);
674 LINK_LOCATION(SPEC_RBH_BQ_LOCN);
675 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 1);
676 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 2);
677 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 3);
678 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 4);
679 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 5);
680 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 6);
681 return(FIXED_HS + size);
684 _ScanLink_RBH_9_9(STG_NO_ARGS)
686 I_ size = 9 + SPEC_RBH_VHS;
687 DEBUG_SCAN_LINK("SRBH", size, 9);
688 LINK_LOCATION(SPEC_RBH_BQ_LOCN);
689 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 1);
690 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 2);
691 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 3);
692 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 4);
693 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 5);
694 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 6);
695 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 7);
696 return(FIXED_HS + size);
699 _ScanLink_RBH_10_10(STG_NO_ARGS)
701 I_ size = 10 + SPEC_RBH_VHS;
702 DEBUG_SCAN_LINK("SRBH", size, 10);
703 LINK_LOCATION(SPEC_RBH_BQ_LOCN);
704 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 1);
705 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 2);
706 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 3);
707 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 4);
708 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 5);
709 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 6);
710 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 7);
711 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 8);
712 return(FIXED_HS + size);
715 _ScanLink_RBH_11_11(STG_NO_ARGS)
717 I_ size = 11 + SPEC_RBH_VHS;
718 DEBUG_SCAN_LINK("SRBH", size, 11);
719 LINK_LOCATION(SPEC_RBH_BQ_LOCN);
720 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 1);
721 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 2);
722 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 3);
723 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 4);
724 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 5);
725 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 6);
726 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 7);
727 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 8);
728 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 9);
729 return(FIXED_HS + size);
732 _ScanLink_RBH_12_12(STG_NO_ARGS)
734 I_ size = 12 + SPEC_RBH_VHS;
735 DEBUG_SCAN_LINK("SRBH", size, 12);
736 LINK_LOCATION(SPEC_RBH_BQ_LOCN);
737 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 1);
738 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 2);
739 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 3);
740 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 4);
741 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 5);
742 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 6);
743 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 7);
744 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 8);
745 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 9);
746 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 10);
747 return(FIXED_HS + size);
752 Scan-linking a MallocPtr is straightforward: exactly the same as
753 @_ScanLink_[MallocPtr_SIZE]_0@.
758 _ScanLink_MallocPtr(STG_NO_ARGS) {
759 I_ size = MallocPtr_SIZE;
760 DEBUG_SCAN_LINK("MallocPtr", size, 0);
761 return(FIXED_HS + size);
766 Back to the main feature...
770 /*** MOVING CLOSURES ***/
774 _ScanMove_0(STG_NO_ARGS) {
775 I_ size = 0; /* NB: SPEC_VHS defined to be zero, so 0 really is the "size" */
776 DEBUG_SCAN_MOVE("CONST", size);
778 return(FIXED_HS + size);
782 _ScanMove_1(STG_NO_ARGS) {
783 I_ size = 1; /* NB: SPEC_VHS defined to be zero, so 1 really is the "size" */
784 DEBUG_SCAN_MOVE("SPEC", size);
787 return(FIXED_HS + size);
790 _ScanMove_2(STG_NO_ARGS) {
792 DEBUG_SCAN_MOVE("SPEC", size);
796 return(FIXED_HS + size);
799 _ScanMove_3(STG_NO_ARGS) {
801 DEBUG_SCAN_MOVE("SPEC", size);
806 return(FIXED_HS + size);
809 _ScanMove_4(STG_NO_ARGS) {
811 DEBUG_SCAN_MOVE("SPEC", size);
817 return(FIXED_HS + size);
820 _ScanMove_5(STG_NO_ARGS) {
822 DEBUG_SCAN_MOVE("SPEC", size);
829 return(FIXED_HS + size);
832 _ScanMove_6(STG_NO_ARGS) {
834 DEBUG_SCAN_MOVE("SPEC", size);
842 return(FIXED_HS + size);
845 _ScanMove_7(STG_NO_ARGS) {
847 DEBUG_SCAN_MOVE("SPEC", size);
856 return(FIXED_HS + size);
859 _ScanMove_8(STG_NO_ARGS) {
861 DEBUG_SCAN_MOVE("SPEC", size);
871 return(FIXED_HS + size);
874 _ScanMove_9(STG_NO_ARGS) {
876 DEBUG_SCAN_MOVE("SPEC", size);
887 return(FIXED_HS + size);
890 _ScanMove_10(STG_NO_ARGS) {
892 DEBUG_SCAN_MOVE("SPEC", size);
904 return(FIXED_HS + size);
907 _ScanMove_11(STG_NO_ARGS) {
909 DEBUG_SCAN_MOVE("SPEC", size);
922 return(FIXED_HS + size);
925 _ScanMove_12(STG_NO_ARGS) {
927 DEBUG_SCAN_MOVE("SPEC", size);
941 return(FIXED_HS + size);
944 #if defined(PAR) && defined(GC_MUT_REQUIRED)
946 _ScanMove_RBH_2(STG_NO_ARGS) {
947 I_ size = 2 + SPEC_RBH_VHS;
948 DEBUG_SCAN_MOVE("SRBH", size);
950 SLIDE_WORD(SPEC_RBH_HS + 0);
952 /* Build new OldMutables list */
953 MUT_LINK(New) = (W_) StorageMgrInfo.OldMutables;
954 StorageMgrInfo.OldMutables = (P_) New;
956 return(FIXED_HS + size);
959 _ScanMove_RBH_3(STG_NO_ARGS) {
960 I_ size = 3 + SPEC_RBH_VHS;
961 DEBUG_SCAN_MOVE("SRBH", size);
963 SLIDE_WORD(SPEC_RBH_HS + 0);
964 SLIDE_WORD(SPEC_RBH_HS + 1);
966 /* Build new OldMutables list */
967 MUT_LINK(New) = (W_) StorageMgrInfo.OldMutables;
968 StorageMgrInfo.OldMutables = (P_) New;
970 return(FIXED_HS + size);
973 _ScanMove_RBH_4(STG_NO_ARGS) {
974 I_ size = 4 + SPEC_RBH_VHS;
975 DEBUG_SCAN_MOVE("SRBH", size);
977 SLIDE_WORD(SPEC_RBH_HS + 0);
978 SLIDE_WORD(SPEC_RBH_HS + 1);
979 SLIDE_WORD(SPEC_RBH_HS + 2);
981 /* Build new OldMutables list */
982 MUT_LINK(New) = (W_) StorageMgrInfo.OldMutables;
983 StorageMgrInfo.OldMutables = (P_) New;
985 return(FIXED_HS + size);
988 _ScanMove_RBH_5(STG_NO_ARGS) {
989 I_ size = 5 + SPEC_RBH_VHS;
990 DEBUG_SCAN_MOVE("SRBH", size);
992 SLIDE_WORD(SPEC_RBH_HS + 0);
993 SLIDE_WORD(SPEC_RBH_HS + 1);
994 SLIDE_WORD(SPEC_RBH_HS + 2);
995 SLIDE_WORD(SPEC_RBH_HS + 3);
997 /* Build new OldMutables list */
998 MUT_LINK(New) = (W_) StorageMgrInfo.OldMutables;
999 StorageMgrInfo.OldMutables = (P_) New;
1001 return(FIXED_HS + size);
1004 _ScanMove_RBH_6(STG_NO_ARGS) {
1005 I_ size = 6 + SPEC_RBH_VHS;
1006 DEBUG_SCAN_MOVE("SRBH", size);
1008 SLIDE_WORD(SPEC_RBH_HS + 0);
1009 SLIDE_WORD(SPEC_RBH_HS + 1);
1010 SLIDE_WORD(SPEC_RBH_HS + 2);
1011 SLIDE_WORD(SPEC_RBH_HS + 3);
1012 SLIDE_WORD(SPEC_RBH_HS + 4);
1014 /* Build new OldMutables list */
1015 MUT_LINK(New) = (W_) StorageMgrInfo.OldMutables;
1016 StorageMgrInfo.OldMutables = (P_) New;
1018 return(FIXED_HS + size);
1021 _ScanMove_RBH_7(STG_NO_ARGS) {
1022 I_ size = 7 + SPEC_RBH_VHS;
1023 DEBUG_SCAN_MOVE("SRBH", size);
1025 SLIDE_WORD(SPEC_RBH_HS + 0);
1026 SLIDE_WORD(SPEC_RBH_HS + 1);
1027 SLIDE_WORD(SPEC_RBH_HS + 2);
1028 SLIDE_WORD(SPEC_RBH_HS + 3);
1029 SLIDE_WORD(SPEC_RBH_HS + 4);
1030 SLIDE_WORD(SPEC_RBH_HS + 5);
1032 /* Build new OldMutables list */
1033 MUT_LINK(New) = (W_) StorageMgrInfo.OldMutables;
1034 StorageMgrInfo.OldMutables = (P_) New;
1036 return(FIXED_HS + size);
1039 _ScanMove_RBH_8(STG_NO_ARGS) {
1040 I_ size = 8 + SPEC_RBH_VHS;
1041 DEBUG_SCAN_MOVE("SRBH", size);
1043 SLIDE_WORD(SPEC_RBH_HS + 0);
1044 SLIDE_WORD(SPEC_RBH_HS + 1);
1045 SLIDE_WORD(SPEC_RBH_HS + 2);
1046 SLIDE_WORD(SPEC_RBH_HS + 3);
1047 SLIDE_WORD(SPEC_RBH_HS + 4);
1048 SLIDE_WORD(SPEC_RBH_HS + 5);
1049 SLIDE_WORD(SPEC_RBH_HS + 6);
1051 /* Build new OldMutables list */
1052 MUT_LINK(New) = (W_) StorageMgrInfo.OldMutables;
1053 StorageMgrInfo.OldMutables = (P_) New;
1055 return(FIXED_HS + size);
1058 _ScanMove_RBH_9(STG_NO_ARGS) {
1059 I_ size = 9 + SPEC_RBH_VHS;
1060 DEBUG_SCAN_MOVE("SRBH", size);
1062 SLIDE_WORD(SPEC_RBH_HS + 0);
1063 SLIDE_WORD(SPEC_RBH_HS + 1);
1064 SLIDE_WORD(SPEC_RBH_HS + 2);
1065 SLIDE_WORD(SPEC_RBH_HS + 3);
1066 SLIDE_WORD(SPEC_RBH_HS + 4);
1067 SLIDE_WORD(SPEC_RBH_HS + 5);
1068 SLIDE_WORD(SPEC_RBH_HS + 6);
1069 SLIDE_WORD(SPEC_RBH_HS + 7);
1071 /* Build new OldMutables list */
1072 MUT_LINK(New) = (W_) StorageMgrInfo.OldMutables;
1073 StorageMgrInfo.OldMutables = (P_) New;
1075 return(FIXED_HS + size);
1078 _ScanMove_RBH_10(STG_NO_ARGS) {
1079 I_ size = 10 + SPEC_RBH_VHS;
1080 DEBUG_SCAN_MOVE("SRBH", size);
1082 SLIDE_WORD(SPEC_RBH_HS + 0);
1083 SLIDE_WORD(SPEC_RBH_HS + 1);
1084 SLIDE_WORD(SPEC_RBH_HS + 2);
1085 SLIDE_WORD(SPEC_RBH_HS + 3);
1086 SLIDE_WORD(SPEC_RBH_HS + 4);
1087 SLIDE_WORD(SPEC_RBH_HS + 5);
1088 SLIDE_WORD(SPEC_RBH_HS + 6);
1089 SLIDE_WORD(SPEC_RBH_HS + 7);
1090 SLIDE_WORD(SPEC_RBH_HS + 8);
1092 /* Build new OldMutables list */
1093 MUT_LINK(New) = (W_) StorageMgrInfo.OldMutables;
1094 StorageMgrInfo.OldMutables = (P_) New;
1096 return(FIXED_HS + size);
1099 _ScanMove_RBH_11(STG_NO_ARGS) {
1100 I_ size = 11 + SPEC_RBH_VHS;
1101 DEBUG_SCAN_MOVE("SRBH", size);
1103 SLIDE_WORD(SPEC_RBH_HS + 0);
1104 SLIDE_WORD(SPEC_RBH_HS + 1);
1105 SLIDE_WORD(SPEC_RBH_HS + 2);
1106 SLIDE_WORD(SPEC_RBH_HS + 3);
1107 SLIDE_WORD(SPEC_RBH_HS + 4);
1108 SLIDE_WORD(SPEC_RBH_HS + 5);
1109 SLIDE_WORD(SPEC_RBH_HS + 6);
1110 SLIDE_WORD(SPEC_RBH_HS + 7);
1111 SLIDE_WORD(SPEC_RBH_HS + 8);
1112 SLIDE_WORD(SPEC_RBH_HS + 9);
1114 /* Build new OldMutables list */
1115 MUT_LINK(New) = (W_) StorageMgrInfo.OldMutables;
1116 StorageMgrInfo.OldMutables = (P_) New;
1118 return(FIXED_HS + size);
1121 _ScanMove_RBH_12(STG_NO_ARGS) {
1122 I_ size = 12 + SPEC_RBH_VHS;
1123 DEBUG_SCAN_MOVE("SRBH", size);
1125 SLIDE_WORD(SPEC_RBH_HS + 0);
1126 SLIDE_WORD(SPEC_RBH_HS + 1);
1127 SLIDE_WORD(SPEC_RBH_HS + 2);
1128 SLIDE_WORD(SPEC_RBH_HS + 3);
1129 SLIDE_WORD(SPEC_RBH_HS + 4);
1130 SLIDE_WORD(SPEC_RBH_HS + 5);
1131 SLIDE_WORD(SPEC_RBH_HS + 6);
1132 SLIDE_WORD(SPEC_RBH_HS + 7);
1133 SLIDE_WORD(SPEC_RBH_HS + 8);
1134 SLIDE_WORD(SPEC_RBH_HS + 9);
1135 SLIDE_WORD(SPEC_RBH_HS + 10);
1137 /* Build new OldMutables list */
1138 MUT_LINK(New) = (W_) StorageMgrInfo.OldMutables;
1139 StorageMgrInfo.OldMutables = (P_) New;
1141 return(FIXED_HS + size);
1146 Moving a Malloc Pointer is a little tricky: we want to copy the actual
1147 pointer unchanged (easy) but we want to link the MallocPtr into the
1153 _ScanMove_MallocPtr(STG_NO_ARGS) {
1154 I_ size = MallocPtr_SIZE;
1155 DEBUG_SCAN_MOVE("MallocPtr", size);
1158 if (RTSflags.GcFlags.trace & DEBUG_TRACE_MALLOCPTRS) {
1159 printf("Moving MallocPtr(%x)=<%x,%x,%x>", Scan, Scan[0], Scan[1], Scan[2]);
1160 printf(" Data = %x, Next = %x\n",
1161 MallocPtr_CLOSURE_DATA(Scan), MallocPtr_CLOSURE_LINK(Scan) );
1166 MallocPtr_SLIDE_DATA;
1170 if (RTSflags.GcFlags.trace & DEBUG_TRACE_MALLOCPTRS) {
1171 printf("Moved MallocPtr(%x)=<%x,_,%x,%x,%x>", New, New[0], New[1], New[2], New[3]);
1172 printf(" Data = %x, Next = %x",
1173 MallocPtr_CLOSURE_DATA(New), MallocPtr_CLOSURE_LINK(New) );
1174 printf(", NewMallocPtrList = %x\n", NewMallocPtrList );
1178 return(FIXED_HS + size);
1183 Now back to the main feature...
1187 /*** GENERIC Linking and Marking Routines */
1190 _ScanLink_S_N(STG_NO_ARGS) {
1191 I_ count = GEN_HS - 1;
1192 /* Offset of first ptr word, less 1 */
1193 I_ ptrs = count + GEN_CLOSURE_NoPTRS(Scan);
1194 /* Offset of last ptr word */
1195 I_ size = GEN_CLOSURE_SIZE(Scan);
1197 DEBUG_SCAN_LINK("GEN ", size, ptrs);
1198 while (++count <= ptrs) {
1199 LINK_LOCATION(count);
1201 return(FIXED_HS + size);
1205 _ScanMove_S(STG_NO_ARGS) {
1206 I_ count = FIXED_HS - 1;
1207 I_ size = GEN_CLOSURE_SIZE(New);
1209 DEBUG_SCAN_MOVE("GEN ", size);
1212 while (++count <= size + (FIXED_HS - 1)) {
1215 return(FIXED_HS + size);
1220 The linking code for revertible black holes with underlying @GEN@ closures.
1226 _ScanLink_RBH_N(STG_NO_ARGS)
1228 I_ count = GEN_RBH_HS - 1; /* Offset of first ptr word, less 1 */
1229 I_ ptrs = GEN_RBH_CLOSURE_NoPTRS(Scan);
1230 I_ size = GEN_RBH_CLOSURE_SIZE(Scan);
1233 * Get pointer count from original closure and adjust for one pointer
1234 * in the first two words of the RBH.
1241 ptrs += count; /* Offset of last ptr word */
1243 DEBUG_SCAN_LINK("GRBH", size, ptrs);
1244 while (++count <= ptrs) {
1245 LINK_LOCATION(count);
1247 return(FIXED_HS + size);
1250 #ifdef GC_MUT_REQUIRED
1253 _ScanMove_RBH_S(STG_NO_ARGS) {
1254 I_ count = GEN_RBH_HS - 1;
1255 I_ size = GEN_RBH_CLOSURE_SIZE(New);
1257 DEBUG_SCAN_MOVE("GRBH", size);
1260 while (++count <= size + (FIXED_HS - 1)) {
1264 /* Build new OldMutables list */
1265 MUT_LINK(New) = (W_) StorageMgrInfo.OldMutables;
1266 StorageMgrInfo.OldMutables = (P_) New;
1268 return(FIXED_HS + size);
1279 _ScanLink_Dyn(STG_NO_ARGS) {
1280 I_ count = DYN_HS - 1;
1281 /* Offset of first ptr word, less 1 */
1282 I_ ptrs = count + DYN_CLOSURE_NoPTRS(Scan);
1283 /* Offset of last ptr word */
1284 I_ size = DYN_CLOSURE_SIZE(Scan);
1286 DEBUG_SCAN_LINK("DYN ", size, ptrs-count);
1288 while (++count <= ptrs) {
1289 LINK_LOCATION(count);
1291 return(FIXED_HS + size);
1295 _ScanMove_Dyn(STG_NO_ARGS) {
1296 I_ count = FIXED_HS - 1;
1297 I_ size = DYN_CLOSURE_SIZE(Scan);
1299 DEBUG_SCAN_MOVE("DYN ", size);
1302 while (++count <= size + (FIXED_HS - 1)) {
1305 return(FIXED_HS + size);
1309 _ScanLink_Tuple(STG_NO_ARGS) {
1310 I_ count = TUPLE_HS - 1;
1311 /* Offset of first ptr word, less 1 */
1312 I_ ptrs = count + TUPLE_CLOSURE_NoPTRS(Scan);
1313 /* Offset of last ptr word */
1314 I_ size = TUPLE_CLOSURE_SIZE(Scan);
1316 DEBUG_SCAN_LINK("TUPL", size, ptrs-count);
1318 while (++count <= ptrs) {
1319 LINK_LOCATION(count);
1321 return(FIXED_HS + size);
1325 _ScanMove_Tuple(STG_NO_ARGS) {
1326 I_ count = FIXED_HS - 1;
1327 I_ size = TUPLE_CLOSURE_SIZE(Scan);
1329 DEBUG_SCAN_MOVE("TUPL", size);
1332 while (++count <= size + (FIXED_HS - 1)) {
1335 return(FIXED_HS + size);
1338 /*** MUTUPLE CLOSURE -- NO PTRS STORED IN CLOSURE -- NO DATA ***/
1339 /* Only if special GC treatment required */
1341 #ifdef GC_MUT_REQUIRED
1343 _ScanLink_MuTuple(STG_NO_ARGS) {
1344 I_ count = MUTUPLE_HS - 1;
1345 /* Offset of first ptr word, less 1 */
1346 I_ ptrs = count + MUTUPLE_CLOSURE_NoPTRS(Scan);
1347 /* Offset of last ptr word */
1348 I_ size = MUTUPLE_CLOSURE_SIZE(Scan);
1350 DEBUG_SCAN_LINK("MUT ", size, ptrs-count);
1352 while (++count <= ptrs) {
1353 LINK_LOCATION(count);
1355 return(FIXED_HS + size);
1359 _ScanMove_MuTuple(STG_NO_ARGS) {
1360 I_ count = FIXED_HS - 1;
1361 I_ size = MUTUPLE_CLOSURE_SIZE(Scan);
1363 DEBUG_SCAN_MOVE("MUT ", size);
1366 while (++count <= size + (FIXED_HS - 1)) {
1370 /* Build new OldMutables list */
1371 MUT_LINK(New) = (W_) StorageMgrInfo.OldMutables;
1372 StorageMgrInfo.OldMutables = (P_) New;
1374 return(FIXED_HS + size);
1378 _ScanMove_ImmuTuple(STG_NO_ARGS) {
1379 I_ count = FIXED_HS - 1;
1380 I_ size = MUTUPLE_CLOSURE_SIZE(Scan);
1382 DEBUG_SCAN_MOVE("IMUT", size);
1385 while (++count <= size + (FIXED_HS - 1)) {
1389 /* Dont add to OldMutables list */
1391 return(FIXED_HS + size);
1393 #endif /* GCap || GCgn */
1397 _ScanLink_Data(STG_NO_ARGS) {
1398 I_ size = DATA_CLOSURE_SIZE(Scan);
1399 DEBUG_SCAN_LINK("DATA", size, 0);
1400 return(FIXED_HS + size);
1404 _ScanMove_Data(STG_NO_ARGS) {
1405 I_ count = FIXED_HS - 1;
1406 I_ size = DATA_CLOSURE_SIZE(Scan);
1408 DEBUG_SCAN_MOVE("DATA", size);
1411 while (++count <= size + (FIXED_HS - 1)) {
1414 return(FIXED_HS + size);
1419 _ScanLink_BH_U(STG_NO_ARGS) {
1420 I_ size = BH_U_SIZE;
1421 DEBUG_SCAN_LINK("BH ", size, 0);
1422 return(FIXED_HS + size);
1426 _ScanMove_BH_U(STG_NO_ARGS) {
1427 I_ size = BH_U_SIZE;
1428 DEBUG_SCAN_MOVE("BH ", size);
1430 return(FIXED_HS + size);
1434 _ScanLink_BH_N(STG_NO_ARGS) {
1435 I_ size = BH_N_SIZE;
1436 DEBUG_SCAN_LINK("BH N", size, 0);
1437 return(FIXED_HS + size);
1441 _ScanMove_BH_N(STG_NO_ARGS) {
1442 I_ size = BH_N_SIZE;
1443 DEBUG_SCAN_MOVE("BH N", size);
1445 return(FIXED_HS + size);
1448 #if defined(PROFILING) || defined(TICKY_TICKY)
1450 _ScanLink_PI(STG_NO_ARGS) {
1451 I_ size = IND_CLOSURE_SIZE(dummy);
1452 DEBUG_SCAN_LINK("PI ", size, 1);
1453 LINK_LOCATION(IND_HS);
1454 return(FIXED_HS + size);
1458 _ScanMove_PI(STG_NO_ARGS) {
1459 I_ size = IND_CLOSURE_SIZE(dummy);
1460 DEBUG_SCAN_MOVE("PI ", size);
1463 return(FIXED_HS + size);
1469 Linking and Marking Routines for FetchMes and stack objects.
1473 #if defined(CONCURRENT)
1478 _ScanLink_FetchMe(STG_NO_ARGS) {
1479 I_ size = FETCHME_CLOSURE_SIZE(dummy);
1480 DEBUG_SCAN_LINK("FME ", size, 0);
1481 return(FIXED_HS + size);
1485 _ScanMove_FetchMe(STG_NO_ARGS) {
1486 I_ size = FETCHME_CLOSURE_SIZE(dummy);
1487 DEBUG_SCAN_MOVE("FME ", size);
1489 SLIDE_WORD(FETCHME_GA_LOCN);
1490 ASSERT(GALAlookup(FETCHME_GA(New)) != NULL);
1492 #ifdef GC_MUT_REQUIRED
1493 /* Build new OldMutables list */
1494 MUT_LINK(New) = (W_) StorageMgrInfo.OldMutables;
1495 StorageMgrInfo.OldMutables = (P_) New;
1498 return(FIXED_HS + size);
1502 _ScanLink_BF(STG_NO_ARGS)
1504 I_ size = BF_CLOSURE_SIZE(dummy);
1505 DEBUG_SCAN_LINK("BF", size, 2);
1507 LINK_LOCATION(BF_LINK_LOCN);
1508 LINK_LOCATION(BF_NODE_LOCN);
1509 return(FIXED_HS + size);
1513 _ScanMove_BF(STG_NO_ARGS)
1516 I_ size = BF_CLOSURE_SIZE(dummy);
1519 for (count = FIXED_HS; count < FIXED_HS + BF_VHS; count++) {
1522 SLIDE_WORD(BF_LINK_LOCN);
1523 SLIDE_WORD(BF_NODE_LOCN);
1524 SLIDE_WORD(BF_GTID_LOCN);
1525 SLIDE_WORD(BF_SLOT_LOCN);
1526 SLIDE_WORD(BF_WEIGHT_LOCN);
1528 #ifdef GC_MUT_REQUIRED
1529 /* Build new OldMutables list */
1530 MUT_LINK(New) = (W_) StorageMgrInfo.OldMutables;
1531 StorageMgrInfo.OldMutables = (P_) New;
1534 return(FIXED_HS + size);
1540 _ScanLink_BQ(STG_NO_ARGS) {
1541 I_ size = BQ_CLOSURE_SIZE(dummy);
1542 DEBUG_SCAN_LINK("BQ ", size, BQ_CLOSURE_NoPTRS(Scan));
1543 LINK_LOCATION(BQ_HS);
1544 return(FIXED_HS + size);
1548 _ScanMove_BQ(STG_NO_ARGS) {
1549 I_ size = BQ_CLOSURE_SIZE(dummy);
1550 DEBUG_SCAN_MOVE("BQ ", size);
1555 #ifdef GC_MUT_REQUIRED
1556 /* Build new OldMutables list */
1557 MUT_LINK(New) = (W_) StorageMgrInfo.OldMutables;
1558 StorageMgrInfo.OldMutables = (P_) New;
1561 return(FIXED_HS + size);
1565 _ScanLink_TSO(STG_NO_ARGS)
1567 STGRegisterTable *r = TSO_INTERNAL_PTR(Scan);
1568 W_ liveness = r->rLiveness;
1570 I_ size = TSO_VHS + TSO_CTS_SIZE;
1572 DEBUG_SCAN_LINK("TSO", size, 0/*wrong*/);
1574 LINK_LOCATION(TSO_LINK_LOCN);
1575 LINK_LOCATION(((P_) &r->rStkO) - Scan);
1576 for(i = 0; liveness != 0; liveness >>= 1, i++) {
1578 LINK_LOCATION(((P_) &r->rR[i].p) - Scan)
1581 return(FIXED_HS + size);
1585 _ScanMove_TSO(STG_NO_ARGS)
1588 I_ size = TSO_VHS + TSO_CTS_SIZE;
1591 for (count = FIXED_HS; count < FIXED_HS + TSO_VHS; count++) {
1595 for(count = 0; count < BYTES_TO_STGWORDS(sizeof(STGRegisterTable)); count++)
1596 /* Do it this way in case there's a shift of just one word */
1597 ((P_) TSO_INTERNAL_PTR(New))[count] = ((P_) TSO_INTERNAL_PTR(Scan))[count];
1599 #ifdef GC_MUT_REQUIRED
1600 /* Build new OldMutables list */
1601 MUT_LINK(New) = (W_) StorageMgrInfo.OldMutables;
1602 StorageMgrInfo.OldMutables = (P_) New;
1605 return(FIXED_HS + size);
1609 _ScanLink_StkO(STG_NO_ARGS) {
1611 I_ size = STKO_CLOSURE_SIZE(Scan);
1612 I_ cts_size = STKO_CLOSURE_CTS_SIZE(Scan);
1613 I_ sub = STKO_SuB_OFFSET(Scan); /* Offset of first update frame in B stack */
1616 LINK_LOCATION(STKO_LINK_LOCN);
1618 /* Link the locations in the A stack */
1619 DEBUG_SCAN_LINK("STKO", size, cts_size - STKO_SpA_OFFSET(Scan) + 1);
1620 for (count = STKO_SpA_OFFSET(Scan); count <= cts_size; count++) {
1621 STKO_LINK_LOCATION(count);
1624 /* Now link the updatees in the update stack */
1628 STKO_LINK_LOCATION(sub + BREL(UF_UPDATEE));
1629 subptr = GRAB_SuB(STKO_CLOSURE_ADDR(Scan,sub));
1630 sub = STKO_CLOSURE_OFFSET(Scan, subptr);
1633 ASSERT(sanityChk_StkO(Scan));
1635 return(FIXED_HS + size);
1638 /* We move first and then repair, so that we can handle an overlapping source
1643 _ScanMove_StkO(STG_NO_ARGS) {
1645 I_ size = STKO_CLOSURE_SIZE(Scan);
1646 I_ cts_size = STKO_CLOSURE_CTS_SIZE(Scan);
1647 I_ spa_offset = STKO_SpA_OFFSET(Scan);
1648 I_ spb_offset = STKO_SpB_OFFSET(Scan);
1649 I_ sub_offset = STKO_SuB_OFFSET(Scan);
1652 DEBUG_SCAN_MOVE("STKO", size);
1656 SLIDE_WORD(STKO_ADEP_LOCN);
1657 SLIDE_WORD(STKO_BDEP_LOCN);
1659 SLIDE_WORD(STKO_SIZE_LOCN);
1660 SLIDE_WORD(STKO_RETURN_LOCN);
1661 SLIDE_WORD(STKO_LINK_LOCN);
1663 /* Adjust the four stack pointers...*IN ORDER* */
1664 offset = New - Scan;
1665 STKO_SuB(New) = STKO_SuB(Scan) + offset;
1666 STKO_SpB(New) = STKO_SpB(Scan) + offset;
1667 STKO_SpA(New) = STKO_SpA(Scan) + offset;
1668 STKO_SuA(New) = STKO_SuA(Scan) + offset;
1670 /* Slide the B stack */
1671 for (count = 1; count <= spb_offset; count++) {
1672 SLIDE_WORD((STKO_HS-1) + count);
1675 /* Slide the A stack */
1676 for (count = spa_offset; count <= cts_size; count++) {
1677 SLIDE_WORD((STKO_HS-1) + count);
1680 /* Repair internal pointers */
1681 while (sub_offset > 0) {
1683 ADJUST_WORD((STKO_HS-1) + sub_offset + BREL(UF_SUA),offset);
1684 ADJUST_WORD((STKO_HS-1) + sub_offset + BREL(UF_SUB),offset);
1685 subptr = GRAB_SuB(STKO_CLOSURE_ADDR(New,sub_offset));
1686 sub_offset = STKO_CLOSURE_OFFSET(New, subptr);
1689 #ifdef GC_MUT_REQUIRED
1690 /* Build new OldMutables list */
1691 MUT_LINK(New) = (W_) StorageMgrInfo.OldMutables;
1692 StorageMgrInfo.OldMutables = (P_) New;
1695 /* ToDo: ASSERT(sanityChk_StkO(Scan or New)); ??? */
1697 return(FIXED_HS + size);
1700 #endif /* CONCURRENT */
1705 /*** Dummy Entries -- Should not be entered ***/
1707 /* Should not be in a .lc file either... --JSM */
1709 STGFUN(_Dummy_Static_entry) {
1710 fprintf(stderr,"Called _Dummy_Static_entry\nShould never occur!\n");
1714 STGFUN(_Dummy_Ind_entry) {
1715 fprintf(stderr,"Called _Dummy_Ind_entry\nShould never occur!\n");
1719 STGFUN(_Dummy_Caf_entry) {
1720 fprintf(stderr,"Called _Dummy_Caf_Ind_entry\nShould never occur!\n");
1724 STGFUN(_Dummy_Const_entry) {
1725 fprintf(stderr,"Called _Dummy_Const_entry\nShould never occur!\n");
1729 STGFUN(_Dummy_CharLike_entry) {
1730 fprintf(stderr,"Called _Dummy_CharLike_entry\nShould never occur!\n");
1734 #endif /* _INFO_COMPACTING */