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 ForeignObjs which are still alive get
43 added to this list. [ADR] */
44 StgPtr NewForeignObjList;
48 Inplace_Compaction(base, lim, scanbase, scanlim, bit_array, bit_array_words
60 StgPtr *ForeignObjList;
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 NewForeignObjList = NULL; /* initialise new ForeignObjList */
98 /* As we move ForeignObjs 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 ((W_) 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 ((W_) 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_ForeignObjList( NewForeignObjList );
207 *ForeignObjList = NewForeignObjList;
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 ForeignObj list link - instead link moved object into
314 @NewForeignObjList@ */
316 #define ForeignObj_SLIDE_DATA \
317 ForeignObj_CLOSURE_DATA(New) = ForeignObj_CLOSURE_DATA(Scan); \
318 ForeignObj_CLOSURE_FINALISER(New) = ForeignObj_CLOSURE_FINALISER(Scan)
319 #define ForeignObj_RELINK \
321 ForeignObj_CLOSURE_LINK(New) = NewForeignObjList; \
322 NewForeignObjList = New; \
326 /* The SLIDE_FIXED_HDR macro is dependent on the No of FIXED_HS */
329 #define SLIDE_FIXED_HDR /* Already Assigned INFO_PTR */
332 #define SLIDE_FIXED_HDR SLIDE_WORD(1)
335 #define SLIDE_FIXED_HDR SLIDE_WORD(1);SLIDE_WORD(2)
337 /* I don't think this will be needed (ToDo: #error?) */
345 #define DEBUG_SCAN_LINK(type, sizevar, ptrvar) \
346 if (RTSflags.GcFlags.trace & DEBUG_TRACE_MINOR_GC) \
347 fprintf(stderr, "Scan Link (%s): 0x%lx -> 0x%lx, info 0x%lx, size %ld, ptrs %ld\n", \
348 type, Scan, New, INFO_PTR(Scan), sizevar, ptrvar)
350 #define DEBUG_SCAN_MOVE(type, sizevar) \
351 if (RTSflags.GcFlags.trace & DEBUG_TRACE_MINOR_GC) \
352 fprintf(stderr, "Scan Move (%s): 0x%lx -> 0x%lx, info 0x%lx, size %ld\n", \
353 type, Scan, New, INFO_PTR(New), sizevar)
358 #define DEBUG_SCAN_LINK(type, sizevar, ptrvar)
359 #define DEBUG_SCAN_MOVE(type, sizevar)
363 /*** LINKING CLOSURES ***/
367 _ScanLink_0_0(STG_NO_ARGS) {
368 I_ size = 0; /* NB: SPEC_VHS is *defined* to be zero */
369 DEBUG_SCAN_LINK("SPEC", size, 0);
370 return(FIXED_HS + size);
375 _ScanLink_1_0(STG_NO_ARGS) {
376 I_ size = 1; /* NB: SPEC_VHS is *defined* to be zero */
377 DEBUG_SCAN_LINK("SPEC", size, 0);
378 return(FIXED_HS + size);
381 _ScanLink_1_1(STG_NO_ARGS) {
383 DEBUG_SCAN_LINK("SPEC", size, 1);
384 SPEC_LINK_LOCATION(1);
385 return(FIXED_HS + size);
388 _ScanLink_2_0(STG_NO_ARGS) {
390 DEBUG_SCAN_LINK("SPEC", size, 0);
391 return(FIXED_HS + size);
394 _ScanLink_2_1(STG_NO_ARGS) {
396 DEBUG_SCAN_LINK("SPEC", size, 1);
397 SPEC_LINK_LOCATION(1);
398 return(FIXED_HS + size);
401 _ScanLink_2_2(STG_NO_ARGS) {
403 DEBUG_SCAN_LINK("SPEC", size, 2);
404 SPEC_LINK_LOCATION(1);
405 SPEC_LINK_LOCATION(2);
406 return(FIXED_HS + size);
409 _ScanLink_3_0(STG_NO_ARGS) {
411 DEBUG_SCAN_LINK("SPEC", size, 0);
412 return(FIXED_HS + size);
415 _ScanLink_3_1(STG_NO_ARGS) {
417 DEBUG_SCAN_LINK("SPEC", size, 1);
418 SPEC_LINK_LOCATION(1);
419 return(FIXED_HS + size);
422 _ScanLink_3_2(STG_NO_ARGS) {
424 DEBUG_SCAN_LINK("SPEC", size, 2);
425 SPEC_LINK_LOCATION(1);
426 SPEC_LINK_LOCATION(2);
427 return(FIXED_HS + size);
430 _ScanLink_3_3(STG_NO_ARGS) {
432 DEBUG_SCAN_LINK("SPEC", size, 3);
433 SPEC_LINK_LOCATION(1);
434 SPEC_LINK_LOCATION(2);
435 SPEC_LINK_LOCATION(3);
436 return(FIXED_HS + size);
439 _ScanLink_4_0(STG_NO_ARGS) {
441 DEBUG_SCAN_LINK("SPEC", size, 0);
442 return(FIXED_HS + size);
445 _ScanLink_4_4(STG_NO_ARGS) {
447 DEBUG_SCAN_LINK("SPEC", size, 4);
448 SPEC_LINK_LOCATION(1);
449 SPEC_LINK_LOCATION(2);
450 SPEC_LINK_LOCATION(3);
451 SPEC_LINK_LOCATION(4);
452 return(FIXED_HS + size);
455 _ScanLink_5_0(STG_NO_ARGS) {
457 DEBUG_SCAN_LINK("SPEC", size, 0);
458 return(FIXED_HS + size);
461 _ScanLink_5_5(STG_NO_ARGS) {
463 DEBUG_SCAN_LINK("SPEC", size, 5);
464 SPEC_LINK_LOCATION(1);
465 SPEC_LINK_LOCATION(2);
466 SPEC_LINK_LOCATION(3);
467 SPEC_LINK_LOCATION(4);
468 SPEC_LINK_LOCATION(5);
469 return(FIXED_HS + size);
472 _ScanLink_6_6(STG_NO_ARGS) {
474 DEBUG_SCAN_LINK("SPEC", size, 6);
475 SPEC_LINK_LOCATION(1);
476 SPEC_LINK_LOCATION(2);
477 SPEC_LINK_LOCATION(3);
478 SPEC_LINK_LOCATION(4);
479 SPEC_LINK_LOCATION(5);
480 SPEC_LINK_LOCATION(6);
481 return(FIXED_HS + size);
484 _ScanLink_7_7(STG_NO_ARGS) {
486 DEBUG_SCAN_LINK("SPEC", size, 7);
487 SPEC_LINK_LOCATION(1);
488 SPEC_LINK_LOCATION(2);
489 SPEC_LINK_LOCATION(3);
490 SPEC_LINK_LOCATION(4);
491 SPEC_LINK_LOCATION(5);
492 SPEC_LINK_LOCATION(6);
493 SPEC_LINK_LOCATION(7);
494 return(FIXED_HS + size);
497 _ScanLink_8_8(STG_NO_ARGS) {
499 DEBUG_SCAN_LINK("SPEC", size, 8);
500 SPEC_LINK_LOCATION(1);
501 SPEC_LINK_LOCATION(2);
502 SPEC_LINK_LOCATION(3);
503 SPEC_LINK_LOCATION(4);
504 SPEC_LINK_LOCATION(5);
505 SPEC_LINK_LOCATION(6);
506 SPEC_LINK_LOCATION(7);
507 SPEC_LINK_LOCATION(8);
508 return(FIXED_HS + size);
511 _ScanLink_9_9(STG_NO_ARGS) {
513 DEBUG_SCAN_LINK("SPEC", size, 9);
514 SPEC_LINK_LOCATION(1);
515 SPEC_LINK_LOCATION(2);
516 SPEC_LINK_LOCATION(3);
517 SPEC_LINK_LOCATION(4);
518 SPEC_LINK_LOCATION(5);
519 SPEC_LINK_LOCATION(6);
520 SPEC_LINK_LOCATION(7);
521 SPEC_LINK_LOCATION(8);
522 SPEC_LINK_LOCATION(9);
523 return(FIXED_HS + size);
526 _ScanLink_10_10(STG_NO_ARGS) {
528 DEBUG_SCAN_LINK("SPEC", size, 10);
529 SPEC_LINK_LOCATION(1);
530 SPEC_LINK_LOCATION(2);
531 SPEC_LINK_LOCATION(3);
532 SPEC_LINK_LOCATION(4);
533 SPEC_LINK_LOCATION(5);
534 SPEC_LINK_LOCATION(6);
535 SPEC_LINK_LOCATION(7);
536 SPEC_LINK_LOCATION(8);
537 SPEC_LINK_LOCATION(9);
538 SPEC_LINK_LOCATION(10);
539 return(FIXED_HS + size);
542 _ScanLink_11_11(STG_NO_ARGS) {
544 DEBUG_SCAN_LINK("SPEC", size, 11);
545 SPEC_LINK_LOCATION(1);
546 SPEC_LINK_LOCATION(2);
547 SPEC_LINK_LOCATION(3);
548 SPEC_LINK_LOCATION(4);
549 SPEC_LINK_LOCATION(5);
550 SPEC_LINK_LOCATION(6);
551 SPEC_LINK_LOCATION(7);
552 SPEC_LINK_LOCATION(8);
553 SPEC_LINK_LOCATION(9);
554 SPEC_LINK_LOCATION(10);
555 SPEC_LINK_LOCATION(11);
556 return(FIXED_HS + size);
559 _ScanLink_12_12(STG_NO_ARGS) {
561 DEBUG_SCAN_LINK("SPEC", size, 12);
562 SPEC_LINK_LOCATION(1);
563 SPEC_LINK_LOCATION(2);
564 SPEC_LINK_LOCATION(3);
565 SPEC_LINK_LOCATION(4);
566 SPEC_LINK_LOCATION(5);
567 SPEC_LINK_LOCATION(6);
568 SPEC_LINK_LOCATION(7);
569 SPEC_LINK_LOCATION(8);
570 SPEC_LINK_LOCATION(9);
571 SPEC_LINK_LOCATION(10);
572 SPEC_LINK_LOCATION(11);
573 SPEC_LINK_LOCATION(12);
574 return(FIXED_HS + size);
578 Scan-linking revertible black holes with underlying @SPEC@ closures.
582 #if defined(PAR) || defined(GRAN)
584 _ScanLink_RBH_2_1(STG_NO_ARGS)
586 I_ size = 2 + SPEC_RBH_VHS;
587 DEBUG_SCAN_LINK("SRBH", size, 1);
588 LINK_LOCATION(SPEC_RBH_BQ_LOCN);
589 return(FIXED_HS + size);
592 _ScanLink_RBH_3_1(STG_NO_ARGS)
594 I_ size = 3 + SPEC_RBH_VHS;
595 DEBUG_SCAN_LINK("SRBH", size, 1);
596 LINK_LOCATION(SPEC_RBH_BQ_LOCN);
597 return(FIXED_HS + size);
600 _ScanLink_RBH_3_3(STG_NO_ARGS)
602 I_ size = 3 + SPEC_RBH_VHS;
603 DEBUG_SCAN_LINK("SRBH", size, 3);
604 LINK_LOCATION(SPEC_RBH_BQ_LOCN);
605 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 1);
606 return(FIXED_HS + size);
609 _ScanLink_RBH_4_1(STG_NO_ARGS)
611 I_ size = 4 + SPEC_RBH_VHS;
612 DEBUG_SCAN_LINK("SRBH", size, 1);
613 LINK_LOCATION(SPEC_RBH_BQ_LOCN);
614 return(FIXED_HS + size);
617 _ScanLink_RBH_4_4(STG_NO_ARGS)
619 I_ size = 4 + SPEC_RBH_VHS;
620 DEBUG_SCAN_LINK("SRBH", size, 4);
621 LINK_LOCATION(SPEC_RBH_BQ_LOCN);
622 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 1);
623 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 2);
624 return(FIXED_HS + size);
627 _ScanLink_RBH_5_1(STG_NO_ARGS)
629 I_ size = 5 + SPEC_RBH_VHS;
630 DEBUG_SCAN_LINK("SRBH", size, 1);
631 LINK_LOCATION(SPEC_RBH_BQ_LOCN);
632 return(FIXED_HS + size);
635 _ScanLink_RBH_5_5(STG_NO_ARGS)
637 I_ size = 5 + SPEC_RBH_VHS;
638 DEBUG_SCAN_LINK("SRBH", size, 5);
639 LINK_LOCATION(SPEC_RBH_BQ_LOCN);
640 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 1);
641 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 2);
642 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 3);
643 return(FIXED_HS + size);
646 _ScanLink_RBH_6_6(STG_NO_ARGS)
648 I_ size = 6 + SPEC_RBH_VHS;
649 DEBUG_SCAN_LINK("SRBH", size, 6);
650 LINK_LOCATION(SPEC_RBH_BQ_LOCN);
651 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 1);
652 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 2);
653 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 3);
654 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 4);
655 return(FIXED_HS + size);
658 _ScanLink_RBH_7_7(STG_NO_ARGS)
660 I_ size = 7 + SPEC_RBH_VHS;
661 DEBUG_SCAN_LINK("SRBH", size, 7);
662 LINK_LOCATION(SPEC_RBH_BQ_LOCN);
663 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 1);
664 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 2);
665 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 3);
666 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 4);
667 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 5);
668 return(FIXED_HS + size);
671 _ScanLink_RBH_8_8(STG_NO_ARGS)
673 I_ size = 8 + SPEC_RBH_VHS;
674 DEBUG_SCAN_LINK("SRBH", size, 8);
675 LINK_LOCATION(SPEC_RBH_BQ_LOCN);
676 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 1);
677 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 2);
678 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 3);
679 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 4);
680 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 5);
681 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 6);
682 return(FIXED_HS + size);
685 _ScanLink_RBH_9_9(STG_NO_ARGS)
687 I_ size = 9 + SPEC_RBH_VHS;
688 DEBUG_SCAN_LINK("SRBH", size, 9);
689 LINK_LOCATION(SPEC_RBH_BQ_LOCN);
690 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 1);
691 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 2);
692 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 3);
693 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 4);
694 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 5);
695 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 6);
696 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 7);
697 return(FIXED_HS + size);
700 _ScanLink_RBH_10_10(STG_NO_ARGS)
702 I_ size = 10 + SPEC_RBH_VHS;
703 DEBUG_SCAN_LINK("SRBH", size, 10);
704 LINK_LOCATION(SPEC_RBH_BQ_LOCN);
705 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 1);
706 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 2);
707 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 3);
708 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 4);
709 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 5);
710 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 6);
711 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 7);
712 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 8);
713 return(FIXED_HS + size);
716 _ScanLink_RBH_11_11(STG_NO_ARGS)
718 I_ size = 11 + SPEC_RBH_VHS;
719 DEBUG_SCAN_LINK("SRBH", size, 11);
720 LINK_LOCATION(SPEC_RBH_BQ_LOCN);
721 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 1);
722 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 2);
723 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 3);
724 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 4);
725 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 5);
726 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 6);
727 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 7);
728 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 8);
729 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 9);
730 return(FIXED_HS + size);
733 _ScanLink_RBH_12_12(STG_NO_ARGS)
735 I_ size = 12 + SPEC_RBH_VHS;
736 DEBUG_SCAN_LINK("SRBH", size, 12);
737 LINK_LOCATION(SPEC_RBH_BQ_LOCN);
738 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 1);
739 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 2);
740 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 3);
741 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 4);
742 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 5);
743 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 6);
744 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 7);
745 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 8);
746 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 9);
747 LINK_LOCATION(SPEC_RBH_BQ_LOCN + 10);
748 return(FIXED_HS + size);
753 Scan-linking a ForeignObj is straightforward: exactly the same as
754 @_ScanLink_[ForeignObj_SIZE]_0@.
759 _ScanLink_ForeignObj(STG_NO_ARGS) {
760 I_ size = ForeignObj_SIZE;
761 DEBUG_SCAN_LINK("ForeignObj", size, 0);
762 return(FIXED_HS + size);
767 Back to the main feature...
771 /*** MOVING CLOSURES ***/
775 _ScanMove_0(STG_NO_ARGS) {
776 I_ size = 0; /* NB: SPEC_VHS defined to be zero, so 0 really is the "size" */
777 DEBUG_SCAN_MOVE("CONST", size);
779 return(FIXED_HS + size);
783 _ScanMove_1(STG_NO_ARGS) {
784 I_ size = 1; /* NB: SPEC_VHS defined to be zero, so 1 really is the "size" */
785 DEBUG_SCAN_MOVE("SPEC", size);
788 return(FIXED_HS + size);
791 _ScanMove_2(STG_NO_ARGS) {
793 DEBUG_SCAN_MOVE("SPEC", size);
797 return(FIXED_HS + size);
800 _ScanMove_3(STG_NO_ARGS) {
802 DEBUG_SCAN_MOVE("SPEC", size);
807 return(FIXED_HS + size);
810 _ScanMove_4(STG_NO_ARGS) {
812 DEBUG_SCAN_MOVE("SPEC", size);
818 return(FIXED_HS + size);
821 _ScanMove_5(STG_NO_ARGS) {
823 DEBUG_SCAN_MOVE("SPEC", size);
830 return(FIXED_HS + size);
833 _ScanMove_6(STG_NO_ARGS) {
835 DEBUG_SCAN_MOVE("SPEC", size);
843 return(FIXED_HS + size);
846 _ScanMove_7(STG_NO_ARGS) {
848 DEBUG_SCAN_MOVE("SPEC", size);
857 return(FIXED_HS + size);
860 _ScanMove_8(STG_NO_ARGS) {
862 DEBUG_SCAN_MOVE("SPEC", size);
872 return(FIXED_HS + size);
875 _ScanMove_9(STG_NO_ARGS) {
877 DEBUG_SCAN_MOVE("SPEC", size);
888 return(FIXED_HS + size);
891 _ScanMove_10(STG_NO_ARGS) {
893 DEBUG_SCAN_MOVE("SPEC", size);
905 return(FIXED_HS + size);
908 _ScanMove_11(STG_NO_ARGS) {
910 DEBUG_SCAN_MOVE("SPEC", size);
923 return(FIXED_HS + size);
926 _ScanMove_12(STG_NO_ARGS) {
928 DEBUG_SCAN_MOVE("SPEC", size);
942 return(FIXED_HS + size);
945 #if (defined(PAR) || defined(GRAN)) && defined(GC_MUT_REQUIRED)
947 _ScanMove_RBH_2(STG_NO_ARGS) {
948 I_ size = 2 + SPEC_RBH_VHS;
949 DEBUG_SCAN_MOVE("SRBH", size);
951 SLIDE_WORD(SPEC_RBH_HS + 0);
953 /* Build new OldMutables list */
954 MUT_LINK(New) = (W_) StorageMgrInfo.OldMutables;
955 StorageMgrInfo.OldMutables = (P_) New;
957 return(FIXED_HS + size);
960 _ScanMove_RBH_3(STG_NO_ARGS) {
961 I_ size = 3 + SPEC_RBH_VHS;
962 DEBUG_SCAN_MOVE("SRBH", size);
964 SLIDE_WORD(SPEC_RBH_HS + 0);
965 SLIDE_WORD(SPEC_RBH_HS + 1);
967 /* Build new OldMutables list */
968 MUT_LINK(New) = (W_) StorageMgrInfo.OldMutables;
969 StorageMgrInfo.OldMutables = (P_) New;
971 return(FIXED_HS + size);
974 _ScanMove_RBH_4(STG_NO_ARGS) {
975 I_ size = 4 + SPEC_RBH_VHS;
976 DEBUG_SCAN_MOVE("SRBH", size);
978 SLIDE_WORD(SPEC_RBH_HS + 0);
979 SLIDE_WORD(SPEC_RBH_HS + 1);
980 SLIDE_WORD(SPEC_RBH_HS + 2);
982 /* Build new OldMutables list */
983 MUT_LINK(New) = (W_) StorageMgrInfo.OldMutables;
984 StorageMgrInfo.OldMutables = (P_) New;
986 return(FIXED_HS + size);
989 _ScanMove_RBH_5(STG_NO_ARGS) {
990 I_ size = 5 + SPEC_RBH_VHS;
991 DEBUG_SCAN_MOVE("SRBH", size);
993 SLIDE_WORD(SPEC_RBH_HS + 0);
994 SLIDE_WORD(SPEC_RBH_HS + 1);
995 SLIDE_WORD(SPEC_RBH_HS + 2);
996 SLIDE_WORD(SPEC_RBH_HS + 3);
998 /* Build new OldMutables list */
999 MUT_LINK(New) = (W_) StorageMgrInfo.OldMutables;
1000 StorageMgrInfo.OldMutables = (P_) New;
1002 return(FIXED_HS + size);
1005 _ScanMove_RBH_6(STG_NO_ARGS) {
1006 I_ size = 6 + SPEC_RBH_VHS;
1007 DEBUG_SCAN_MOVE("SRBH", size);
1009 SLIDE_WORD(SPEC_RBH_HS + 0);
1010 SLIDE_WORD(SPEC_RBH_HS + 1);
1011 SLIDE_WORD(SPEC_RBH_HS + 2);
1012 SLIDE_WORD(SPEC_RBH_HS + 3);
1013 SLIDE_WORD(SPEC_RBH_HS + 4);
1015 /* Build new OldMutables list */
1016 MUT_LINK(New) = (W_) StorageMgrInfo.OldMutables;
1017 StorageMgrInfo.OldMutables = (P_) New;
1019 return(FIXED_HS + size);
1022 _ScanMove_RBH_7(STG_NO_ARGS) {
1023 I_ size = 7 + SPEC_RBH_VHS;
1024 DEBUG_SCAN_MOVE("SRBH", size);
1026 SLIDE_WORD(SPEC_RBH_HS + 0);
1027 SLIDE_WORD(SPEC_RBH_HS + 1);
1028 SLIDE_WORD(SPEC_RBH_HS + 2);
1029 SLIDE_WORD(SPEC_RBH_HS + 3);
1030 SLIDE_WORD(SPEC_RBH_HS + 4);
1031 SLIDE_WORD(SPEC_RBH_HS + 5);
1033 /* Build new OldMutables list */
1034 MUT_LINK(New) = (W_) StorageMgrInfo.OldMutables;
1035 StorageMgrInfo.OldMutables = (P_) New;
1037 return(FIXED_HS + size);
1040 _ScanMove_RBH_8(STG_NO_ARGS) {
1041 I_ size = 8 + SPEC_RBH_VHS;
1042 DEBUG_SCAN_MOVE("SRBH", size);
1044 SLIDE_WORD(SPEC_RBH_HS + 0);
1045 SLIDE_WORD(SPEC_RBH_HS + 1);
1046 SLIDE_WORD(SPEC_RBH_HS + 2);
1047 SLIDE_WORD(SPEC_RBH_HS + 3);
1048 SLIDE_WORD(SPEC_RBH_HS + 4);
1049 SLIDE_WORD(SPEC_RBH_HS + 5);
1050 SLIDE_WORD(SPEC_RBH_HS + 6);
1052 /* Build new OldMutables list */
1053 MUT_LINK(New) = (W_) StorageMgrInfo.OldMutables;
1054 StorageMgrInfo.OldMutables = (P_) New;
1056 return(FIXED_HS + size);
1059 _ScanMove_RBH_9(STG_NO_ARGS) {
1060 I_ size = 9 + SPEC_RBH_VHS;
1061 DEBUG_SCAN_MOVE("SRBH", size);
1063 SLIDE_WORD(SPEC_RBH_HS + 0);
1064 SLIDE_WORD(SPEC_RBH_HS + 1);
1065 SLIDE_WORD(SPEC_RBH_HS + 2);
1066 SLIDE_WORD(SPEC_RBH_HS + 3);
1067 SLIDE_WORD(SPEC_RBH_HS + 4);
1068 SLIDE_WORD(SPEC_RBH_HS + 5);
1069 SLIDE_WORD(SPEC_RBH_HS + 6);
1070 SLIDE_WORD(SPEC_RBH_HS + 7);
1072 /* Build new OldMutables list */
1073 MUT_LINK(New) = (W_) StorageMgrInfo.OldMutables;
1074 StorageMgrInfo.OldMutables = (P_) New;
1076 return(FIXED_HS + size);
1079 _ScanMove_RBH_10(STG_NO_ARGS) {
1080 I_ size = 10 + SPEC_RBH_VHS;
1081 DEBUG_SCAN_MOVE("SRBH", size);
1083 SLIDE_WORD(SPEC_RBH_HS + 0);
1084 SLIDE_WORD(SPEC_RBH_HS + 1);
1085 SLIDE_WORD(SPEC_RBH_HS + 2);
1086 SLIDE_WORD(SPEC_RBH_HS + 3);
1087 SLIDE_WORD(SPEC_RBH_HS + 4);
1088 SLIDE_WORD(SPEC_RBH_HS + 5);
1089 SLIDE_WORD(SPEC_RBH_HS + 6);
1090 SLIDE_WORD(SPEC_RBH_HS + 7);
1091 SLIDE_WORD(SPEC_RBH_HS + 8);
1093 /* Build new OldMutables list */
1094 MUT_LINK(New) = (W_) StorageMgrInfo.OldMutables;
1095 StorageMgrInfo.OldMutables = (P_) New;
1097 return(FIXED_HS + size);
1100 _ScanMove_RBH_11(STG_NO_ARGS) {
1101 I_ size = 11 + SPEC_RBH_VHS;
1102 DEBUG_SCAN_MOVE("SRBH", size);
1104 SLIDE_WORD(SPEC_RBH_HS + 0);
1105 SLIDE_WORD(SPEC_RBH_HS + 1);
1106 SLIDE_WORD(SPEC_RBH_HS + 2);
1107 SLIDE_WORD(SPEC_RBH_HS + 3);
1108 SLIDE_WORD(SPEC_RBH_HS + 4);
1109 SLIDE_WORD(SPEC_RBH_HS + 5);
1110 SLIDE_WORD(SPEC_RBH_HS + 6);
1111 SLIDE_WORD(SPEC_RBH_HS + 7);
1112 SLIDE_WORD(SPEC_RBH_HS + 8);
1113 SLIDE_WORD(SPEC_RBH_HS + 9);
1115 /* Build new OldMutables list */
1116 MUT_LINK(New) = (W_) StorageMgrInfo.OldMutables;
1117 StorageMgrInfo.OldMutables = (P_) New;
1119 return(FIXED_HS + size);
1122 _ScanMove_RBH_12(STG_NO_ARGS) {
1123 I_ size = 12 + SPEC_RBH_VHS;
1124 DEBUG_SCAN_MOVE("SRBH", size);
1126 SLIDE_WORD(SPEC_RBH_HS + 0);
1127 SLIDE_WORD(SPEC_RBH_HS + 1);
1128 SLIDE_WORD(SPEC_RBH_HS + 2);
1129 SLIDE_WORD(SPEC_RBH_HS + 3);
1130 SLIDE_WORD(SPEC_RBH_HS + 4);
1131 SLIDE_WORD(SPEC_RBH_HS + 5);
1132 SLIDE_WORD(SPEC_RBH_HS + 6);
1133 SLIDE_WORD(SPEC_RBH_HS + 7);
1134 SLIDE_WORD(SPEC_RBH_HS + 8);
1135 SLIDE_WORD(SPEC_RBH_HS + 9);
1136 SLIDE_WORD(SPEC_RBH_HS + 10);
1138 /* Build new OldMutables list */
1139 MUT_LINK(New) = (W_) StorageMgrInfo.OldMutables;
1140 StorageMgrInfo.OldMutables = (P_) New;
1142 return(FIXED_HS + size);
1147 Moving a Foreign Object is a little tricky: we want to copy the actual
1148 pointer unchanged (easy) but we want to link the ForeignObj into the
1149 new ForeignObj list.
1154 _ScanMove_ForeignObj(STG_NO_ARGS) {
1155 I_ size = ForeignObj_SIZE;
1156 DEBUG_SCAN_MOVE("ForeignObj", size);
1159 if (RTSflags.GcFlags.trace & DEBUG_TRACE_FOREIGNOBJS) {
1160 fprintf(stderr,"Moving ForeignObj(%x)=<%x,%x,%x>", Scan, Scan[0], Scan[1], Scan[2]);
1161 fprintf(stderr," Data = %x, Finaliser = %x, Next = %x\n",
1162 ForeignObj_CLOSURE_DATA(Scan),
1163 ForeignObj_CLOSURE_FINALISER(Scan),
1164 ForeignObj_CLOSURE_LINK(Scan) );
1169 ForeignObj_SLIDE_DATA;
1173 if (RTSflags.GcFlags.trace & DEBUG_TRACE_FOREIGNOBJS) {
1174 fprintf(stderr,"Moved ForeignObj(%x)=<%x,_,%x,%x,%x>", New, New[0], New[1], New[2], New[3]);
1175 fprintf(stderr," Data = %x, Finaliser = %x, Next = %x",
1176 ForeignObj_CLOSURE_DATA(New),
1177 ForeignObj_CLOSURE_FINALISER(New),
1178 ForeignObj_CLOSURE_LINK(New) );
1179 fprintf(stderr,", NewForeignObjList = %x\n", NewForeignObjList );
1183 return(FIXED_HS + size);
1188 Now back to the main feature...
1192 /*** GENERIC Linking and Marking Routines */
1195 _ScanLink_S_N(STG_NO_ARGS) {
1196 I_ count = GEN_HS - 1;
1197 /* Offset of first ptr word, less 1 */
1198 I_ ptrs = count + GEN_CLOSURE_NoPTRS(Scan);
1199 /* Offset of last ptr word */
1200 I_ size = GEN_CLOSURE_SIZE(Scan);
1202 DEBUG_SCAN_LINK("GEN ", size, ptrs);
1203 while (++count <= ptrs) {
1204 LINK_LOCATION(count);
1206 return(FIXED_HS + size);
1210 _ScanMove_S(STG_NO_ARGS) {
1211 I_ count = FIXED_HS - 1;
1212 I_ size = GEN_CLOSURE_SIZE(New);
1214 DEBUG_SCAN_MOVE("GEN ", size);
1217 while (++count <= size + (FIXED_HS - 1)) {
1220 return(FIXED_HS + size);
1225 The linking code for revertible black holes with underlying @GEN@ closures.
1228 #if defined(PAR) || defined(GRAN)
1231 _ScanLink_RBH_N(STG_NO_ARGS)
1233 I_ count = GEN_RBH_HS - 1; /* Offset of first ptr word, less 1 */
1234 I_ ptrs = GEN_RBH_CLOSURE_NoPTRS(Scan);
1235 I_ size = GEN_RBH_CLOSURE_SIZE(Scan);
1238 * Get pointer count from original closure and adjust for one pointer
1239 * in the first two words of the RBH.
1246 ptrs += count; /* Offset of last ptr word */
1248 DEBUG_SCAN_LINK("GRBH", size, ptrs);
1249 while (++count <= ptrs) {
1250 LINK_LOCATION(count);
1252 return(FIXED_HS + size);
1255 #ifdef GC_MUT_REQUIRED
1258 _ScanMove_RBH_S(STG_NO_ARGS) {
1259 I_ count = GEN_RBH_HS - 1;
1260 I_ size = GEN_RBH_CLOSURE_SIZE(New);
1262 DEBUG_SCAN_MOVE("GRBH", size);
1265 while (++count <= size + (FIXED_HS - 1)) {
1269 /* Build new OldMutables list */
1270 MUT_LINK(New) = (W_) StorageMgrInfo.OldMutables;
1271 StorageMgrInfo.OldMutables = (P_) New;
1273 return(FIXED_HS + size);
1284 _ScanLink_Dyn(STG_NO_ARGS) {
1285 I_ count = DYN_HS - 1;
1286 /* Offset of first ptr word, less 1 */
1287 I_ ptrs = count + DYN_CLOSURE_NoPTRS(Scan);
1288 /* Offset of last ptr word */
1289 I_ size = DYN_CLOSURE_SIZE(Scan);
1291 DEBUG_SCAN_LINK("DYN ", size, ptrs-count);
1293 while (++count <= ptrs) {
1294 LINK_LOCATION(count);
1296 return(FIXED_HS + size);
1300 _ScanMove_Dyn(STG_NO_ARGS) {
1301 I_ count = FIXED_HS - 1;
1302 I_ size = DYN_CLOSURE_SIZE(Scan);
1304 DEBUG_SCAN_MOVE("DYN ", size);
1307 while (++count <= size + (FIXED_HS - 1)) {
1310 return(FIXED_HS + size);
1314 _ScanLink_Tuple(STG_NO_ARGS) {
1315 I_ count = TUPLE_HS - 1;
1316 /* Offset of first ptr word, less 1 */
1317 I_ ptrs = count + TUPLE_CLOSURE_NoPTRS(Scan);
1318 /* Offset of last ptr word */
1319 I_ size = TUPLE_CLOSURE_SIZE(Scan);
1321 DEBUG_SCAN_LINK("TUPL", size, ptrs-count);
1323 while (++count <= ptrs) {
1324 LINK_LOCATION(count);
1326 return(FIXED_HS + size);
1330 _ScanMove_Tuple(STG_NO_ARGS) {
1331 I_ count = FIXED_HS - 1;
1332 I_ size = TUPLE_CLOSURE_SIZE(Scan);
1334 DEBUG_SCAN_MOVE("TUPL", size);
1337 while (++count <= size + (FIXED_HS - 1)) {
1340 return(FIXED_HS + size);
1343 /*** MUTUPLE CLOSURE -- NO PTRS STORED IN CLOSURE -- NO DATA ***/
1344 /* Only if special GC treatment required */
1346 #ifdef GC_MUT_REQUIRED
1348 _ScanLink_MuTuple(STG_NO_ARGS) {
1349 I_ count = MUTUPLE_HS - 1;
1350 /* Offset of first ptr word, less 1 */
1351 I_ ptrs = count + MUTUPLE_CLOSURE_NoPTRS(Scan);
1352 /* Offset of last ptr word */
1353 I_ size = MUTUPLE_CLOSURE_SIZE(Scan);
1355 DEBUG_SCAN_LINK("MUT ", size, ptrs-count);
1357 while (++count <= ptrs) {
1358 LINK_LOCATION(count);
1360 return(FIXED_HS + size);
1364 _ScanMove_MuTuple(STG_NO_ARGS) {
1365 I_ count = FIXED_HS - 1;
1366 I_ size = MUTUPLE_CLOSURE_SIZE(Scan);
1368 DEBUG_SCAN_MOVE("MUT ", size);
1371 while (++count <= size + (FIXED_HS - 1)) {
1375 /* Build new OldMutables list */
1376 MUT_LINK(New) = (W_) StorageMgrInfo.OldMutables;
1377 StorageMgrInfo.OldMutables = (P_) New;
1379 return(FIXED_HS + size);
1383 _ScanMove_ImmuTuple(STG_NO_ARGS) {
1384 I_ count = FIXED_HS - 1;
1385 I_ size = MUTUPLE_CLOSURE_SIZE(Scan);
1387 DEBUG_SCAN_MOVE("IMUT", size);
1390 while (++count <= size + (FIXED_HS - 1)) {
1394 /* Dont add to OldMutables list */
1396 return(FIXED_HS + size);
1398 #endif /* GCap || GCgn */
1402 _ScanLink_Data(STG_NO_ARGS) {
1403 I_ size = DATA_CLOSURE_SIZE(Scan);
1404 DEBUG_SCAN_LINK("DATA", size, 0);
1405 return(FIXED_HS + size);
1409 _ScanMove_Data(STG_NO_ARGS) {
1410 I_ count = FIXED_HS - 1;
1411 I_ size = DATA_CLOSURE_SIZE(Scan);
1413 DEBUG_SCAN_MOVE("DATA", size);
1416 while (++count <= size + (FIXED_HS - 1)) {
1419 return(FIXED_HS + size);
1424 _ScanLink_BH_U(STG_NO_ARGS) {
1425 I_ size = BH_U_SIZE;
1426 DEBUG_SCAN_LINK("BH ", size, 0);
1427 return(FIXED_HS + size);
1431 _ScanMove_BH_U(STG_NO_ARGS) {
1432 I_ size = BH_U_SIZE;
1433 DEBUG_SCAN_MOVE("BH ", size);
1435 return(FIXED_HS + size);
1439 _ScanLink_BH_N(STG_NO_ARGS) {
1440 I_ size = BH_N_SIZE;
1441 DEBUG_SCAN_LINK("BH N", size, 0);
1442 return(FIXED_HS + size);
1446 _ScanMove_BH_N(STG_NO_ARGS) {
1447 I_ size = BH_N_SIZE;
1448 DEBUG_SCAN_MOVE("BH N", size);
1450 return(FIXED_HS + size);
1453 #if defined(PROFILING) || defined(TICKY_TICKY)
1455 _ScanLink_PI(STG_NO_ARGS) {
1456 I_ size = IND_CLOSURE_SIZE(dummy);
1457 DEBUG_SCAN_LINK("PI ", size, 1);
1458 LINK_LOCATION(IND_HS);
1459 return(FIXED_HS + size);
1463 _ScanMove_PI(STG_NO_ARGS) {
1464 I_ size = IND_CLOSURE_SIZE(dummy);
1465 DEBUG_SCAN_MOVE("PI ", size);
1468 return(FIXED_HS + size);
1474 Linking and Marking Routines for FetchMes and stack objects.
1478 #if defined(CONCURRENT)
1483 _ScanLink_FetchMe(STG_NO_ARGS) {
1484 I_ size = FETCHME_CLOSURE_SIZE(dummy);
1485 DEBUG_SCAN_LINK("FME ", size, 0);
1486 return(FIXED_HS + size);
1490 _ScanMove_FetchMe(STG_NO_ARGS) {
1491 I_ size = FETCHME_CLOSURE_SIZE(dummy);
1492 DEBUG_SCAN_MOVE("FME ", size);
1494 SLIDE_WORD(FETCHME_GA_LOCN);
1495 ASSERT(GALAlookup(FETCHME_GA(New)) != NULL);
1497 #ifdef GC_MUT_REQUIRED
1498 /* Build new OldMutables list */
1499 MUT_LINK(New) = (W_) StorageMgrInfo.OldMutables;
1500 StorageMgrInfo.OldMutables = (P_) New;
1503 return(FIXED_HS + size);
1507 _ScanLink_BF(STG_NO_ARGS)
1509 I_ size = BF_CLOSURE_SIZE(dummy);
1510 DEBUG_SCAN_LINK("BF", size, 2);
1512 LINK_LOCATION(BF_LINK_LOCN);
1513 LINK_LOCATION(BF_NODE_LOCN);
1514 return(FIXED_HS + size);
1518 _ScanMove_BF(STG_NO_ARGS)
1521 I_ size = BF_CLOSURE_SIZE(dummy);
1524 for (count = FIXED_HS; count < FIXED_HS + BF_VHS; count++) {
1527 SLIDE_WORD(BF_LINK_LOCN);
1528 SLIDE_WORD(BF_NODE_LOCN);
1529 SLIDE_WORD(BF_GTID_LOCN);
1530 SLIDE_WORD(BF_SLOT_LOCN);
1531 SLIDE_WORD(BF_WEIGHT_LOCN);
1533 #ifdef GC_MUT_REQUIRED
1534 /* Build new OldMutables list */
1535 MUT_LINK(New) = (W_) StorageMgrInfo.OldMutables;
1536 StorageMgrInfo.OldMutables = (P_) New;
1539 return(FIXED_HS + size);
1545 _ScanLink_BQ(STG_NO_ARGS) {
1546 I_ size = BQ_CLOSURE_SIZE(dummy);
1547 DEBUG_SCAN_LINK("BQ ", size, BQ_CLOSURE_NoPTRS(Scan));
1548 LINK_LOCATION(BQ_HS);
1549 return(FIXED_HS + size);
1553 _ScanMove_BQ(STG_NO_ARGS) {
1554 I_ size = BQ_CLOSURE_SIZE(dummy);
1555 DEBUG_SCAN_MOVE("BQ ", size);
1560 #ifdef GC_MUT_REQUIRED
1561 /* Build new OldMutables list */
1562 MUT_LINK(New) = (W_) StorageMgrInfo.OldMutables;
1563 StorageMgrInfo.OldMutables = (P_) New;
1566 return(FIXED_HS + size);
1570 _ScanLink_TSO(STG_NO_ARGS)
1572 STGRegisterTable *r = TSO_INTERNAL_PTR(Scan);
1573 W_ liveness = r->rLiveness;
1575 I_ size = TSO_VHS + TSO_CTS_SIZE;
1577 DEBUG_SCAN_LINK("TSO", size, 0/*wrong*/);
1579 LINK_LOCATION(TSO_LINK_LOCN);
1580 LINK_LOCATION(((P_) &r->rStkO) - Scan);
1581 for(i = 0; liveness != 0; liveness >>= 1, i++) {
1583 LINK_LOCATION(((P_) &r->rR[i].p) - Scan)
1586 return(FIXED_HS + size);
1590 _ScanMove_TSO(STG_NO_ARGS)
1593 I_ size = TSO_VHS + TSO_CTS_SIZE;
1596 for (count = FIXED_HS; count < FIXED_HS + TSO_VHS; count++) {
1600 for(count = 0; count < BYTES_TO_STGWORDS(sizeof(STGRegisterTable)); count++)
1601 /* Do it this way in case there's a shift of just one word */
1602 ((P_) TSO_INTERNAL_PTR(New))[count] = ((P_) TSO_INTERNAL_PTR(Scan))[count];
1604 #ifdef GC_MUT_REQUIRED
1605 /* Build new OldMutables list */
1606 MUT_LINK(New) = (W_) StorageMgrInfo.OldMutables;
1607 StorageMgrInfo.OldMutables = (P_) New;
1610 return(FIXED_HS + size);
1614 _ScanLink_StkO(STG_NO_ARGS) {
1616 I_ size = STKO_CLOSURE_SIZE(Scan);
1617 I_ cts_size = STKO_CLOSURE_CTS_SIZE(Scan);
1618 I_ sub = STKO_SuB_OFFSET(Scan); /* Offset of first update frame in B stack */
1621 LINK_LOCATION(STKO_LINK_LOCN);
1623 /* Link the locations in the A stack */
1624 DEBUG_SCAN_LINK("STKO", size, cts_size - STKO_SpA_OFFSET(Scan) + 1);
1625 for (count = STKO_SpA_OFFSET(Scan); count <= cts_size; count++) {
1626 STKO_LINK_LOCATION(count);
1629 /* Now link the updatees in the update stack */
1633 STKO_LINK_LOCATION(sub + BREL(UF_UPDATEE));
1634 subptr = GRAB_SuB(STKO_CLOSURE_ADDR(Scan,sub));
1635 sub = STKO_CLOSURE_OFFSET(Scan, subptr);
1638 ASSERT(sanityChk_StkO(Scan));
1640 return(FIXED_HS + size);
1643 /* We move first and then repair, so that we can handle an overlapping source
1648 _ScanMove_StkO(STG_NO_ARGS) {
1650 I_ size = STKO_CLOSURE_SIZE(Scan);
1651 I_ cts_size = STKO_CLOSURE_CTS_SIZE(Scan);
1652 I_ spa_offset = STKO_SpA_OFFSET(Scan);
1653 I_ spb_offset = STKO_SpB_OFFSET(Scan);
1654 I_ sub_offset = STKO_SuB_OFFSET(Scan);
1657 DEBUG_SCAN_MOVE("STKO", size);
1661 SLIDE_WORD(STKO_ADEP_LOCN);
1662 SLIDE_WORD(STKO_BDEP_LOCN);
1664 SLIDE_WORD(STKO_SIZE_LOCN);
1665 SLIDE_WORD(STKO_RETURN_LOCN);
1666 SLIDE_WORD(STKO_LINK_LOCN);
1668 /* Adjust the four stack pointers...*IN ORDER* */
1669 offset = New - Scan;
1670 STKO_SuB(New) = STKO_SuB(Scan) + offset;
1671 STKO_SpB(New) = STKO_SpB(Scan) + offset;
1672 STKO_SpA(New) = STKO_SpA(Scan) + offset;
1673 STKO_SuA(New) = STKO_SuA(Scan) + offset;
1675 /* Slide the B stack */
1676 for (count = 1; count <= spb_offset; count++) {
1677 SLIDE_WORD((STKO_HS-1) + count);
1680 /* Slide the A stack */
1681 for (count = spa_offset; count <= cts_size; count++) {
1682 SLIDE_WORD((STKO_HS-1) + count);
1685 /* Repair internal pointers */
1686 while (sub_offset > 0) {
1688 ADJUST_WORD((STKO_HS-1) + sub_offset + BREL(UF_SUA),offset);
1689 ADJUST_WORD((STKO_HS-1) + sub_offset + BREL(UF_SUB),offset);
1690 subptr = GRAB_SuB(STKO_CLOSURE_ADDR(New,sub_offset));
1691 sub_offset = STKO_CLOSURE_OFFSET(New, subptr);
1694 #ifdef GC_MUT_REQUIRED
1695 /* Build new OldMutables list */
1696 MUT_LINK(New) = (W_) StorageMgrInfo.OldMutables;
1697 StorageMgrInfo.OldMutables = (P_) New;
1700 /* ToDo: ASSERT(sanityChk_StkO(Scan or New)); ??? */
1702 return(FIXED_HS + size);
1705 #endif /* CONCURRENT */
1710 /*** Dummy Entries -- Should not be entered ***/
1712 /* Should not be in a .lc file either... --JSM */
1714 STGFUN(_Dummy_Static_entry) {
1715 fprintf(stderr,"Called _Dummy_Static_entry\nShould never occur!\n");
1719 STGFUN(_Dummy_Ind_entry) {
1720 fprintf(stderr,"Called _Dummy_Ind_entry\nShould never occur!\n");
1724 STGFUN(_Dummy_Caf_entry) {
1725 fprintf(stderr,"Called _Dummy_Caf_Ind_entry\nShould never occur!\n");
1729 STGFUN(_Dummy_Const_entry) {
1730 fprintf(stderr,"Called _Dummy_Const_entry\nShould never occur!\n");
1734 STGFUN(_Dummy_CharLike_entry) {
1735 fprintf(stderr,"Called _Dummy_CharLike_entry\nShould never occur!\n");
1739 #endif /* _INFO_COMPACTING */