+++ /dev/null
-****************************************************************************
-
-The files SMevac.lc and SMscav.lhc contain the basic routines required
-for two-space copying garbage collection.
-
-Two files are required as the evac routines are conventional call/return
-routines while the scavenge routines are continuation routines.
-
-This file SMscav.lhc contains the scavenging routines ...
-
-****************************************************************************
-
-
-All the routines are placed in the info tables of the appropriate closures.
-
-
-Evacuation code: _Evacuate_...
-
-USE: new = EVACUATE_CLOSURE(evac)
-
-Evacuates a closure of size S words. Note the size excludes the info
-and any other preceding fields (eg global address in Grip implementation)
-Returns the address of the closures new location via the Evac register.
-
- Calling Conventions:
- arg -- points to the closure
- ToHp -- points to the last allocated word in to-space
- Return Conventions:
- ret -- points to the new address of the closure
- ToHp -- points to the last allocated word in to-space
-
- Example: Cons cell requires _Evacuate_2
-
-Scavenging code: _Scavenge_S_N
-
- Retrieved using SCAV_CODE(infoptr)
-
-Scavenges a closure of size S words, with N pointers and returns.
-If more closures are required to be scavenged the code to
-scan the next closure can be called.
-
- Calling Conventions:
- Scav -- points to the current closure
- ToHp -- points to the last allocated word in to-space
-
- OldGen -- Points to end of old generation (Appels collector only)
-
- Return Conventions:
- Scav -- points to the next closure
- ToHp -- points to the (possibly new) location of the last allocated word
-
- Example: Cons cell requires _Scavenge_2_2
-
-
-The following registers are used by a two-space collection:
-
-Scav -- Points to the current closure being scavenged
- (PS paper = Hscav)
-
-ToHp -- Points to the last word allocated in two-space
- (PS paper = Hnext)
-
-A copying pass is started by:
- -- Setting ToHp to 1 before the start of to-space
- -- Evacuating the roots pointing into from-space
- -- root = EVACUATE_CLOSURE(root)
- -- Setting Scav to point to the first closure in to-space
- -- Execute while (Scav <= ToHp) (SCAV_CODE(INFO_PTR(Scav)))();
-
-When Done ToHp will point to the last word allocated in to-space
-
-
-\begin{code}
-/* The #define and #include come before the test because SMinternal.h
- will suck in includes/SMinterface whcih defines (or doesn't)
- _INFO_COPYING [ADR] */
-
-#define SCAV_REG_MAP
-#include "SMinternal.h"
-
-#if defined(_INFO_COPYING)
-
-RegisterTable ScavRegTable;
-
-/* Moves Scav to point at the info pointer of the next closure to Scavenge */
-#define NEXT_Scav(size) Scav += (size) + FIXED_HS
-
-/*
- When doing a new generation copy collection for Appel's collector
- only evacuate references that point to the new generation.
- OldGen must be set to point to the end of old space.
-*/
-
-#if defined(GCgn)
-
-#define DO_EVACUATE(closure, pos) \
- { P_ evac = (P_) *(((P_)(closure))+(pos)); \
- if (evac > OldGen) { \
- *(((P_)(closure))+(pos)) = (W_) EVACUATE_CLOSURE(evac); \
- }}
-
-#else
-#if defined(GCap)
-
-#define DO_EVACUATE(closure, pos) \
- { P_ evac = (P_) *(((P_)(closure))+(pos)); \
- if (evac > OldGen) { \
- *(((P_)(closure))+(pos)) = (W_) EVACUATE_CLOSURE(evac); \
- }}
-
-#else /* ! GCgn && ! GCap */
-
-#define DO_EVACUATE(closure, pos) \
- { P_ evac = (P_) *(((P_)(closure))+(pos)); \
- *(((P_)(closure))+(pos)) = (W_) EVACUATE_CLOSURE(evac); }
-
-#endif /* ! GCgn && ! GCap */
-#endif
-
-
-/* Evacuate nth pointer in SPEC closure (starting at 1) */
-#define SPEC_DO_EVACUATE(ptr) DO_EVACUATE(Scav, (SPEC_HS-1) + (ptr))
-#define STKO_DO_EVACUATE(ptr) DO_EVACUATE(Scav, (STKO_HS-1) + (ptr))
-
-
-/*** DEBUGGING MACROS ***/
-
-#if defined(DEBUG)
-
-#define DEBUG_SCAV(s,p) \
- if (RTSflags.GcFlags.trace & DEBUG_TRACE_MINOR_GC) \
- fprintf(stderr, "Scav: 0x%lx, info 0x%lx, size %ld, ptrs %ld\n", \
- Scav, INFO_PTR(Scav), s, p)
-
-#define DEBUG_SCAV_GEN(s,p) \
- if (RTSflags.GcFlags.trace & DEBUG_TRACE_MINOR_GC) \
- fprintf(stderr, "Scav: 0x%lx, Gen info 0x%lx, size %ld, ptrs %ld\n", \
- Scav, INFO_PTR(Scav), s, p)
-
-#define DEBUG_SCAV_DYN \
- if (RTSflags.GcFlags.trace & DEBUG_TRACE_MINOR_GC) \
- fprintf(stderr, "Scav: 0x%lx, Dyn info 0x%lx, size %ld, ptrs %ld\n", \
- Scav, INFO_PTR(Scav), DYN_CLOSURE_SIZE(Scav), DYN_CLOSURE_NoPTRS(Scav))
-
-#define DEBUG_SCAV_TUPLE \
- if (RTSflags.GcFlags.trace & DEBUG_TRACE_MINOR_GC) \
- fprintf(stderr, "Scav: 0x%lx, Tuple info 0x%lx, size %ld, ptrs %ld\n", \
- Scav, INFO_PTR(Scav), TUPLE_CLOSURE_SIZE(Scav), TUPLE_CLOSURE_NoPTRS(Scav))
-
-#define DEBUG_SCAV_MUTUPLE \
- if (RTSflags.GcFlags.trace & DEBUG_TRACE_MINOR_GC) \
- fprintf(stderr, "Scav: 0x%lx, MuTuple info 0x%lx, size %ld, ptrs %ld\n", \
- Scav, INFO_PTR(Scav), MUTUPLE_CLOSURE_SIZE(Scav), MUTUPLE_CLOSURE_NoPTRS(Scav))
-
-#define DEBUG_SCAV_DATA \
- if (RTSflags.GcFlags.trace & DEBUG_TRACE_MINOR_GC) \
- fprintf(stderr, "Scav: 0x%lx, Data info 0x%lx, size %ld\n", \
- Scav, INFO_PTR(Scav), DATA_CLOSURE_SIZE(Scav))
-
-#define DEBUG_SCAV_BH(s) \
- if (RTSflags.GcFlags.trace & DEBUG_TRACE_MINOR_GC) \
- fprintf(stderr, "Scav: 0x%lx, BH info 0x%lx, size %ld\n", \
- Scav, INFO_PTR(Scav), s)
-
-#define DEBUG_SCAV_IND \
- if (RTSflags.GcFlags.trace & DEBUG_TRACE_MINOR_GC) \
- fprintf(stderr, "Scav: 0x%lx, IND info 0x%lx, size %ld\n", \
- Scav, INFO_PTR(Scav), IND_CLOSURE_SIZE(Scav))
-
-#define DEBUG_SCAV_PERM_IND \
- if (RTSflags.GcFlags.trace & DEBUG_TRACE_MINOR_GC) \
- fprintf(stderr, "Scav: 0x%lx, PI info 0x%lx, size %ld\n", \
- Scav, INFO_PTR(Scav), IND_CLOSURE_SIZE(Scav))
-
-#define DEBUG_SCAV_OLDROOT(s) \
- if (RTSflags.GcFlags.trace & DEBUG_TRACE_MINOR_GC) \
- fprintf(stderr, "Scav: OLDROOT 0x%lx, info 0x%lx, size %ld\n", \
- Scav, INFO_PTR(Scav), s)
-
-#ifdef CONCURRENT
-#define DEBUG_SCAV_BQ \
- if (RTSflags.GcFlags.trace & DEBUG_TRACE_CONCURRENT) \
- fprintf(stderr, "Scav: 0x%lx, BQ info 0x%lx, size %ld, ptrs %ld\n", \
- Scav, INFO_PTR(Scav), BQ_CLOSURE_SIZE(Scav), BQ_CLOSURE_NoPTRS(Scav))
-
-#define DEBUG_SCAV_TSO \
- if (RTSflags.GcFlags.trace & DEBUG_TRACE_CONCURRENT) \
- fprintf(stderr, "Scav TSO: 0x%lx\n", \
- Scav)
-
-#define DEBUG_SCAV_STKO \
- if (RTSflags.GcFlags.trace & DEBUG_TRACE_CONCURRENT) \
- fprintf(stderr, "Scav StkO: 0x%lx\n", \
- Scav)
-
-# if defined(PAR) || defined(GRAN)
-# define DEBUG_SCAV_RBH(s,p) \
- if (RTSflags.GcFlags.trace & DEBUG_TRACE_CONCURRENT) \
- fprintf(stderr, "Scav RBH: 0x%lx, info 0x%lx, size %ld, ptrs %ld\n", \
- Scav, INFO_PTR(Scav), s, p)
-
-# define DEBUG_SCAV_BF \
- if (RTSflags.GcFlags.trace & DEBUG_TRACE_CONCURRENT) \
- fprintf(stderr, "Scav: 0x%lx, BF info 0x%lx, size %ld, ptrs %ld\n", \
- Scav, INFO_PTR(Scav), BF_CLOSURE_SIZE(dummy), 0)
-# endif
-#endif
-
-#else
-
-#define DEBUG_SCAV(s,p)
-#define DEBUG_SCAV_GEN(s,p)
-#define DEBUG_SCAV_DYN
-#define DEBUG_SCAV_TUPLE
-#define DEBUG_SCAV_MUTUPLE
-#define DEBUG_SCAV_DATA
-#define DEBUG_SCAV_BH(s)
-#define DEBUG_SCAV_IND
-#define DEBUG_SCAV_PERM_IND
-#define DEBUG_SCAV_OLDROOT(s)
-
-#ifdef CONCURRENT
-# define DEBUG_SCAV_BQ
-# define DEBUG_SCAV_TSO
-# define DEBUG_SCAV_STKO
-# if defined(PAR) || defined(GRAN)
-# define DEBUG_SCAV_RBH(s,p)
-# define DEBUG_SCAV_BF
-# endif
-#endif
-
-#endif
-
-#define PROFILE_CLOSURE(closure,size) \
- HEAP_PROFILE_CLOSURE(closure,size)
-
-/*** SPECIALISED CODE ***/
-
-#ifdef TICKY_TICKY
-void
-_Scavenge_0_0(STG_NO_ARGS)
-{
- DEBUG_SCAV(0,0);
- PROFILE_CLOSURE(Scav,0);
- NEXT_Scav(0); /* because "size" is defined to be 0 (size SPEC_VHS == 0) */
- return;
-}
-#endif
-
-void
-_Scavenge_1_0(STG_NO_ARGS)
-{
- DEBUG_SCAV(1,0);
- PROFILE_CLOSURE(Scav,1);
- NEXT_Scav(1); /* because "size" is defined to be 1 (size SPEC_VHS == 0) */
- return;
-}
-void
-_Scavenge_1_1(STG_NO_ARGS)
-{
- DEBUG_SCAV(1,1);
- PROFILE_CLOSURE(Scav,1);
- SPEC_DO_EVACUATE(1);
- NEXT_Scav(1);
- return;
-}
-void
-_Scavenge_2_0(STG_NO_ARGS)
-{
- DEBUG_SCAV(2,0);
- PROFILE_CLOSURE(Scav,2);
- NEXT_Scav(2);
- return;
-}
-void
-_Scavenge_2_1(STG_NO_ARGS)
-{
- DEBUG_SCAV(2,1);
- PROFILE_CLOSURE(Scav,2);
- SPEC_DO_EVACUATE(1);
- NEXT_Scav(2);
- return;
-}
-void
-_Scavenge_2_2(STG_NO_ARGS)
-{
- DEBUG_SCAV(2,2);
- PROFILE_CLOSURE(Scav,2);
- SPEC_DO_EVACUATE(1);
- SPEC_DO_EVACUATE(2);
- NEXT_Scav(2);
- return;
-}
-void
-_Scavenge_3_0(STG_NO_ARGS)
-{
- DEBUG_SCAV(3,0);
- PROFILE_CLOSURE(Scav,3);
- NEXT_Scav(3);
- return;
-}
-void
-_Scavenge_3_1(STG_NO_ARGS)
-{
- DEBUG_SCAV(3,1);
- PROFILE_CLOSURE(Scav,3);
- SPEC_DO_EVACUATE(1);
- NEXT_Scav(3);
- return;
-}
-void
-_Scavenge_3_2(STG_NO_ARGS)
-{
- DEBUG_SCAV(3,2);
- PROFILE_CLOSURE(Scav,3);
- SPEC_DO_EVACUATE(1);
- SPEC_DO_EVACUATE(2);
- NEXT_Scav(3);
- return;
-}
-void
-_Scavenge_3_3(STG_NO_ARGS)
-{
- DEBUG_SCAV(3,3);
- PROFILE_CLOSURE(Scav,3);
- SPEC_DO_EVACUATE(1);
- SPEC_DO_EVACUATE(2);
- SPEC_DO_EVACUATE(3);
- NEXT_Scav(3);
- return;
-}
-void
-_Scavenge_4_0(STG_NO_ARGS)
-{
- DEBUG_SCAV(4,0);
- PROFILE_CLOSURE(Scav,4);
- NEXT_Scav(4);
- return;
-}
-void
-_Scavenge_4_4(STG_NO_ARGS)
-{
- DEBUG_SCAV(4,4);
- PROFILE_CLOSURE(Scav,4);
- SPEC_DO_EVACUATE(1);
- SPEC_DO_EVACUATE(2);
- SPEC_DO_EVACUATE(3);
- SPEC_DO_EVACUATE(4);
- NEXT_Scav(4);
- return;
-}
-void
-_Scavenge_5_0(STG_NO_ARGS)
-{
- DEBUG_SCAV(5,0);
- PROFILE_CLOSURE(Scav,5);
- NEXT_Scav(5);
- return;
-}
-void
-_Scavenge_5_5(STG_NO_ARGS)
-{
- DEBUG_SCAV(5,5);
- PROFILE_CLOSURE(Scav,5);
- SPEC_DO_EVACUATE(1);
- SPEC_DO_EVACUATE(2);
- SPEC_DO_EVACUATE(3);
- SPEC_DO_EVACUATE(4);
- SPEC_DO_EVACUATE(5);
- NEXT_Scav(5);
- return;
-}
-void
-_Scavenge_6_6(STG_NO_ARGS)
-{
- DEBUG_SCAV(6,6);
- PROFILE_CLOSURE(Scav,6);
- SPEC_DO_EVACUATE(1);
- SPEC_DO_EVACUATE(2);
- SPEC_DO_EVACUATE(3);
- SPEC_DO_EVACUATE(4);
- SPEC_DO_EVACUATE(5);
- SPEC_DO_EVACUATE(6);
- NEXT_Scav(6);
- return;
-}
-void
-_Scavenge_7_7(STG_NO_ARGS)
-{
- DEBUG_SCAV(7,7);
- PROFILE_CLOSURE(Scav,7);
- SPEC_DO_EVACUATE(1);
- SPEC_DO_EVACUATE(2);
- SPEC_DO_EVACUATE(3);
- SPEC_DO_EVACUATE(4);
- SPEC_DO_EVACUATE(5);
- SPEC_DO_EVACUATE(6);
- SPEC_DO_EVACUATE(7);
- NEXT_Scav(7);
- return;
-}
-void
-_Scavenge_8_8(STG_NO_ARGS)
-{
- DEBUG_SCAV(8,8);
- PROFILE_CLOSURE(Scav,8);
- SPEC_DO_EVACUATE(1);
- SPEC_DO_EVACUATE(2);
- SPEC_DO_EVACUATE(3);
- SPEC_DO_EVACUATE(4);
- SPEC_DO_EVACUATE(5);
- SPEC_DO_EVACUATE(6);
- SPEC_DO_EVACUATE(7);
- SPEC_DO_EVACUATE(8);
- NEXT_Scav(8);
- return;
-}
-void
-_Scavenge_9_9(STG_NO_ARGS)
-{
- DEBUG_SCAV(9,9);
- PROFILE_CLOSURE(Scav,9);
- SPEC_DO_EVACUATE(1);
- SPEC_DO_EVACUATE(2);
- SPEC_DO_EVACUATE(3);
- SPEC_DO_EVACUATE(4);
- SPEC_DO_EVACUATE(5);
- SPEC_DO_EVACUATE(6);
- SPEC_DO_EVACUATE(7);
- SPEC_DO_EVACUATE(8);
- SPEC_DO_EVACUATE(9);
- NEXT_Scav(9);
- return;
-}
-void
-_Scavenge_10_10(STG_NO_ARGS)
-{
- DEBUG_SCAV(10,10);
- PROFILE_CLOSURE(Scav,10);
- SPEC_DO_EVACUATE(1);
- SPEC_DO_EVACUATE(2);
- SPEC_DO_EVACUATE(3);
- SPEC_DO_EVACUATE(4);
- SPEC_DO_EVACUATE(5);
- SPEC_DO_EVACUATE(6);
- SPEC_DO_EVACUATE(7);
- SPEC_DO_EVACUATE(8);
- SPEC_DO_EVACUATE(9);
- SPEC_DO_EVACUATE(10);
- NEXT_Scav(10);
- return;
-}
-void
-_Scavenge_11_11(STG_NO_ARGS)
-{
- DEBUG_SCAV(11,11);
- PROFILE_CLOSURE(Scav,11);
- SPEC_DO_EVACUATE(1);
- SPEC_DO_EVACUATE(2);
- SPEC_DO_EVACUATE(3);
- SPEC_DO_EVACUATE(4);
- SPEC_DO_EVACUATE(5);
- SPEC_DO_EVACUATE(6);
- SPEC_DO_EVACUATE(7);
- SPEC_DO_EVACUATE(8);
- SPEC_DO_EVACUATE(9);
- SPEC_DO_EVACUATE(10);
- SPEC_DO_EVACUATE(11);
- NEXT_Scav(11);
- return;
-}
-void
-_Scavenge_12_12(STG_NO_ARGS)
-{
- DEBUG_SCAV(12,12);
- PROFILE_CLOSURE(Scav,12);
- SPEC_DO_EVACUATE(1);
- SPEC_DO_EVACUATE(2);
- SPEC_DO_EVACUATE(3);
- SPEC_DO_EVACUATE(4);
- SPEC_DO_EVACUATE(5);
- SPEC_DO_EVACUATE(6);
- SPEC_DO_EVACUATE(7);
- SPEC_DO_EVACUATE(8);
- SPEC_DO_EVACUATE(9);
- SPEC_DO_EVACUATE(10);
- SPEC_DO_EVACUATE(11);
- SPEC_DO_EVACUATE(12);
- NEXT_Scav(12);
- return;
-}
-\end{code}
-
-The scavenge routines for revertible black holes with underlying @SPEC@
-closures.
-
-\begin{code}
-
-#if defined(PAR) || defined(GRAN)
-
-# if defined(GCgn)
-
-# define SCAVENGE_SPEC_RBH_N_1(n) \
-void \
-CAT3(_Scavenge_RBH_,n,_1)(STG_NO_ARGS) \
-{ \
- I_ size = n + SPEC_RBH_VHS; \
- P_ save_Scav; \
- DEBUG_SCAV_RBH(size,1); \
- save_Scav = Scav; \
- Scav = OldGen + 1; \
- DO_EVACUATE(save_Scav, SPEC_RBH_BQ_LOCN); \
- Scav = save_Scav; \
- PROFILE_CLOSURE(Scav,size); \
- NEXT_Scav(size); \
-}
-
-# define SCAVENGE_SPEC_RBH_N_N(n) \
-void \
-CAT4(_Scavenge_RBH_,n,_,n)(STG_NO_ARGS) \
-{ \
- I_ size = n + SPEC_RBH_VHS; \
- int i; \
- P_ save_Scav; \
- DEBUG_SCAV_RBH(size,size-1); \
- save_Scav = Scav; \
- Scav = OldGen + 1; \
- for(i = 0; i < n - 1; i++) { \
- DO_EVACUATE(save_Scav, SPEC_RBH_BQ_LOCN + i); \
- } \
- Scav = save_Scav; \
- PROFILE_CLOSURE(Scav,size); \
- NEXT_Scav(size); \
-}
-
-# else
-
-# define SCAVENGE_SPEC_RBH_N_1(n) \
-void \
-CAT3(_Scavenge_RBH_,n,_1)(STG_NO_ARGS) \
-{ \
- I_ size = n + SPEC_RBH_VHS; \
- DEBUG_SCAV_RBH(size,1); \
- DO_EVACUATE(Scav, SPEC_RBH_BQ_LOCN);\
- PROFILE_CLOSURE(Scav,size); \
- NEXT_Scav(size); \
-}
-
-# define SCAVENGE_SPEC_RBH_N_N(n) \
-void \
-CAT4(_Scavenge_RBH_,n,_,n)(STG_NO_ARGS) \
-{ \
- I_ size = n + SPEC_RBH_VHS; \
- int i; \
- DEBUG_SCAV_RBH(size,size-1); \
- for(i = 0; i < n - 1; i++) { \
- DO_EVACUATE(Scav, SPEC_RBH_BQ_LOCN + i); \
- } \
- PROFILE_CLOSURE(Scav,size); \
- NEXT_Scav(size); \
-}
-
-# endif
-
-SCAVENGE_SPEC_RBH_N_1(2)
-
-SCAVENGE_SPEC_RBH_N_1(3)
-SCAVENGE_SPEC_RBH_N_N(3)
-
-SCAVENGE_SPEC_RBH_N_1(4)
-SCAVENGE_SPEC_RBH_N_N(4)
-
-SCAVENGE_SPEC_RBH_N_1(5)
-SCAVENGE_SPEC_RBH_N_N(5)
-
-SCAVENGE_SPEC_RBH_N_N(6)
-SCAVENGE_SPEC_RBH_N_N(7)
-SCAVENGE_SPEC_RBH_N_N(8)
-SCAVENGE_SPEC_RBH_N_N(9)
-SCAVENGE_SPEC_RBH_N_N(10)
-SCAVENGE_SPEC_RBH_N_N(11)
-SCAVENGE_SPEC_RBH_N_N(12)
-
-#endif
-
-\end{code}
-
-\begin{code}
-
-#ifndef PAR
-/*** Foreign Object -- NOTHING TO SCAVENGE ***/
-
-/* (The ForeignObjList is updated at the end of GC and any unevacuated
- ForeignObjs are finalised) [ADR][SOF]
-*/
-
-void
-_Scavenge_ForeignObj(STG_NO_ARGS)
-{
- I_ size = ForeignObj_SIZE;
- DEBUG_SCAV(size,0);
- PROFILE_CLOSURE(Scav,size);
- NEXT_Scav(size);
- return;
-}
-#endif /* !PAR */
-
-/*** GENERAL CASE CODE ***/
-
-void
-_Scavenge_S_N(STG_NO_ARGS)
-{
- I_ count = GEN_HS - 1;
- /* Offset of first ptr word, less 1 */
- I_ ptrs = count + GEN_CLOSURE_NoPTRS(Scav);
- /* Offset of last ptr word */
- I_ size = GEN_CLOSURE_SIZE(Scav);
-
- DEBUG_SCAV_GEN(size, GEN_CLOSURE_NoPTRS(Scav));
-
- while (++count <= ptrs) {
- DO_EVACUATE(Scav, count);
- }
- PROFILE_CLOSURE(Scav,size);
- NEXT_Scav(size);
- return;
-}
-
-\end{code}
-
-The scavenge code for revertible black holes with underlying @GEN@ closures
-
-\begin{code}
-
-#if defined(PAR) || defined(GRAN)
-
-void
-_Scavenge_RBH_N(STG_NO_ARGS)
-{
-#if defined(GCgn)
- P_ save_Scav;
-#endif
-
- I_ count = GEN_RBH_HS - 1; /* Offset of first ptr word, less 1 */
- I_ ptrs = GEN_RBH_CLOSURE_NoPTRS(Scav);
- I_ size = GEN_RBH_CLOSURE_SIZE(Scav);
-
- /*
- * Get pointer count from original closure and adjust for one pointer
- * in the first two words of the RBH.
- */
- if (ptrs < 2)
- ptrs = 1;
- else
- ptrs--;
-
- ptrs += count; /* Offset of last ptr word */
-
- DEBUG_SCAV_GEN(size, ptrs);
-
-#if defined(GCgn)
- /* No old generation roots should be created for mutable */
- /* pointer fields as they will be explicitly collected */
- /* Ensure this by pointing Scav at the new generation */
- save_Scav = Scav;
- Scav = OldGen + 1;
-
- while (++count <= ptrs) {
- DO_EVACUATE(save_Scav, count);
- }
- Scav = save_Scav;
-#else
- while (++count <= ptrs) {
- DO_EVACUATE(Scav, count);
- }
-#endif
-
- PROFILE_CLOSURE(Scav,size);
- NEXT_Scav(size);
- return;
-}
-
-#endif
-
-\end{code}
-
-\begin{code}
-
-/*** DYNAMIC CLOSURE -- SIZE & PTRS STORED IN CLOSURE ***/
-
-void
-_Scavenge_Dyn(STG_NO_ARGS)
-{
- I_ count = DYN_HS - 1;
- /* Offset of first ptr word, less 1 */
- I_ ptrs = count + DYN_CLOSURE_NoPTRS(Scav);
- /* Offset of last ptr word */
- I_ size = DYN_CLOSURE_SIZE(Scav);
-
- DEBUG_SCAV_DYN;
- while (++count <= ptrs) {
- DO_EVACUATE(Scav, count);
- }
- PROFILE_CLOSURE(Scav,size);
- NEXT_Scav(size);
- return;
-}
-
-/*** TUPLE CLOSURE -- NO PTRS STORED IN CLOSURE -- NO DATA ***/
-
-void
-_Scavenge_Tuple(STG_NO_ARGS)
-{
- I_ count = TUPLE_HS - 1;
- /* Offset of first ptr word, less 1 */
- I_ ptrs = count + TUPLE_CLOSURE_NoPTRS(Scav);
- /* Offset of last ptr word */
- I_ size = TUPLE_CLOSURE_SIZE(Scav);
-
- DEBUG_SCAV_TUPLE;
- while (++count <= ptrs) {
- DO_EVACUATE(Scav, count);
- }
- PROFILE_CLOSURE(Scav,size);
- NEXT_Scav(size);
- return;
-}
-
-/*** DATA CLOSURE -- SIZE STORED IN CLOSURE -- NO POINTERS ***/
-
-void
-_Scavenge_Data(STG_NO_ARGS)
-{
- I_ size = DATA_CLOSURE_SIZE(Scav);
-
- DEBUG_SCAV_DATA;
- PROFILE_CLOSURE(Scav,size);
- NEXT_Scav(size);
- return;
-}
-
-/*** MUTUPLE CLOSURE -- ONLY PTRS STORED IN CLOSURE -- NO DATA ***/
-/* Only if special GC treatment required */
-
-#ifdef GC_MUT_REQUIRED
-void
-_Scavenge_MuTuple(STG_NO_ARGS)
-{
-#if defined(GCgn)
- P_ save_Scav;
-#endif
- I_ count = MUTUPLE_HS - 1;
- /* Offset of first ptr word, less 1 */
- I_ ptrs = count + MUTUPLE_CLOSURE_NoPTRS(Scav);
- /* Offset of last ptr word */
- I_ size = MUTUPLE_CLOSURE_SIZE(Scav);
-
- DEBUG_SCAV_MUTUPLE;
-
-#if defined(GCgn)
- /* No old generation roots should be created for mutable */
- /* pointer fields as they will be explicitly collected */
- /* Ensure this by pointing Scav at the new generation */
- save_Scav = Scav;
- Scav = OldGen + 1;
- while (++count <= ptrs) {
- DO_EVACUATE(save_Scav, count);
- }
- Scav = save_Scav;
-#else /* GCap */
- while (++count <= ptrs) {
- DO_EVACUATE(Scav, count);
- }
-#endif /* GCap */
-
- PROFILE_CLOSURE(Scav,size);
- NEXT_Scav(size);
- return;
-}
-#endif /* something generational */
-
-/*** BH CLOSURES -- NO POINTERS ***/
-
-void
-_Scavenge_BH_U(STG_NO_ARGS)
-{
- I_ size = BH_U_SIZE;
- DEBUG_SCAV_BH(size);
- PROFILE_CLOSURE(Scav,size);
- NEXT_Scav(size);
- return;
-}
-
-void
-_Scavenge_BH_N(STG_NO_ARGS)
-{
- I_ size = BH_N_SIZE;
- DEBUG_SCAV_BH(size);
- PROFILE_CLOSURE(Scav,size);
- NEXT_Scav(size);
- return;
-}
-
-/* This is needed for scavenging indirections that "hang around";
- e.g., because they are on the OldMutables list, or
- because we have "turned off" shorting-out of indirections
- (in SMevac.lc).
-*/
-void
-_Scavenge_Ind(STG_NO_ARGS)
-{
- I_ size = IND_CLOSURE_SIZE(dummy);
- DEBUG_SCAV_IND;
- PROFILE_CLOSURE(Scav,size);
- DO_EVACUATE(Scav, IND_HS);
- NEXT_Scav(size);
- return;
-}
-
-void
-_Scavenge_Caf(STG_NO_ARGS)
-{
- I_ size = IND_CLOSURE_SIZE(dummy);
- DEBUG_SCAV_IND;
- PROFILE_CLOSURE(Scav,size);
- DO_EVACUATE(Scav, IND_HS);
- NEXT_Scav(size);
- return;
-}
-
-#if defined(PROFILING) || defined(TICKY_TICKY)
-
-/* Special permanent indirection for lexical scoping.
- As for _Scavenge_Ind but no PROFILE_CLOSURE.
-*/
-
-void
-_Scavenge_PI(STG_NO_ARGS)
-{
- I_ size = IND_CLOSURE_SIZE(dummy);
- DEBUG_SCAV_PERM_IND;
- /* PROFILE_CLOSURE(Scav,size); */
- DO_EVACUATE(Scav, IND_HS);
- NEXT_Scav(size);
- return;
-}
-#endif /* PROFILING or TICKY */
-
-#ifdef CONCURRENT
-
-void
-_Scavenge_BQ(STG_NO_ARGS)
-{
- I_ size = BQ_CLOSURE_SIZE(dummy);
-#if defined(GCgn)
- P_ save_Scav;
-#endif
-
- DEBUG_SCAV_BQ;
-
-#if defined(GCgn)
- /* No old generation roots should be created for mutable */
- /* pointer fields as they will be explicitly collected */
- /* Ensure this by pointing Scav at the new generation */
- save_Scav = Scav;
- Scav = OldGen + 1;
- DO_EVACUATE(save_Scav, BQ_HS);
- Scav = save_Scav;
-#else /* !GCgn */
- DO_EVACUATE(Scav, BQ_HS);
-#endif /* GCgn */
-
- PROFILE_CLOSURE(Scav,size);
- NEXT_Scav(size);
- return;
-}
-
-void
-_Scavenge_TSO(STG_NO_ARGS)
-{
- I_ size = TSO_VHS + TSO_CTS_SIZE;
-#if defined(GCgn)
- P_ save_Scav;
-#endif
- STGRegisterTable *r = TSO_INTERNAL_PTR(Scav);
- W_ liveness = r->rLiveness;
- I_ i;
-
- DEBUG_SCAV_TSO;
-
-#if defined(GCgn)
- /* old and probably wrong -- deleted (WDP 95/12) */
-#else
- DO_EVACUATE(Scav, TSO_LINK_LOCN);
-
- DO_EVACUATE(Scav, ((P_) &r->rStkO) - Scav);
-
- for (i = 0; liveness != 0; liveness >>= 1, i++) {
- if (liveness & 1) {
- DO_EVACUATE(Scav, ((P_) &r->rR[i].p) - Scav)
- }
- }
-#endif
-
- PROFILE_CLOSURE(Scav, size);
- NEXT_Scav(size);
- return;
-}
-
-int /* ToDo: move? */
-sanityChk_StkO(P_ stko)
-{
- I_ size = STKO_CLOSURE_SIZE(stko);
- I_ cts_size = STKO_CLOSURE_CTS_SIZE(stko);
- I_ count;
- I_ sub = STKO_SuB_OFFSET(stko); /* Offset of first update frame in B stack */
- I_ prev_sub;
- P_ begin_stko = STKO_CLOSURE_ADDR(stko, 0);
- P_ beyond_stko = STKO_CLOSURE_ADDR(stko, cts_size+1);
-
- /*fprintf(stderr, "stko=%lx; SpA offset=%ld; first SuB=%ld, size=%ld; next=%lx\n",stko,STKO_SpA_OFFSET(stko),sub,STKO_CLOSURE_CTS_SIZE(stko),STKO_LINK(stko));*/
-
- /* Evacuate the locations in the A stack */
- for (count = STKO_SpA_OFFSET(stko); count <= cts_size; count++) {
- ASSERT(count >= 0);
- }
-
- while(sub > 0) {
- P_ subptr;
- PP_ suaptr;
- P_ updptr;
- P_ retptr;
-
- ASSERT(sub >= 1);
- ASSERT(sub <= cts_size);
-
- retptr = GRAB_RET(STKO_CLOSURE_ADDR(stko,sub));
- subptr = GRAB_SuB(STKO_CLOSURE_ADDR(stko,sub));
- suaptr = GRAB_SuA(STKO_CLOSURE_ADDR(stko,sub));
- updptr = GRAB_UPDATEE(STKO_CLOSURE_ADDR(stko,sub));
-
- ASSERT(subptr >= begin_stko);
- ASSERT(subptr < beyond_stko);
-
- ASSERT(suaptr >= begin_stko);
- ASSERT(suaptr <= beyond_stko);
-
- /* ToDo: would be nice to chk that retptr is in text space */
-
- sub = STKO_CLOSURE_OFFSET(stko, subptr);
- }
-
- return 1;
-}
-
-void
-_Scavenge_StkO(STG_NO_ARGS)
-{
- I_ size = STKO_CLOSURE_SIZE(Scav);
-#if defined(GCgn)
- P_ save_Scav;
-#endif
- I_ count;
- I_ sub = STKO_SuB_OFFSET(Scav); /* Offset of first update frame in B stack */
-
- DEBUG_SCAV_STKO;
-
-#if defined(GCgn)
- /* deleted; probably wrong */
-#else
- ASSERT(sanityChk_StkO(Scav));
-
- /* Evacuate the link */
- DO_EVACUATE(Scav, STKO_LINK_LOCN);
-
- /* Evacuate the locations in the A stack */
- for (count = STKO_SpA_OFFSET(Scav); count <= STKO_CLOSURE_CTS_SIZE(Scav); count++) {
- STKO_DO_EVACUATE(count);
- }
-
- /* Now evacuate the updatees in the update stack */
- while(sub > 0) {
- P_ subptr;
-
- STKO_DO_EVACUATE(sub + BREL(UF_UPDATEE));
- subptr = GRAB_SuB(STKO_CLOSURE_ADDR(Scav,sub));
-
- sub = STKO_CLOSURE_OFFSET(Scav, subptr);
- }
-
-#endif
- PROFILE_CLOSURE(Scav, size);
- NEXT_Scav(size);
- return;
-}
-
-#ifdef PAR
-
-void
-_Scavenge_FetchMe(STG_NO_ARGS)
-{
- I_ size = FETCHME_CLOSURE_SIZE(dummy);
- DEBUG_SCAV(size,0);
- PROFILE_CLOSURE(Scav,size);
- NEXT_Scav(size);
- return;
-}
-
-void
-_Scavenge_BF(STG_NO_ARGS)
-{
- I_ size = BF_CLOSURE_SIZE(dummy);
-#if defined(GCgn)
- P_ save_Scav;
-#endif
-
- DEBUG_SCAV_BF;
-
-#if defined(GCgn)
- /* No old generation roots should be created for mutable */
- /* pointer fields as they will be explicitly collected */
- /* Ensure this by pointing Scav at the new generation */
- save_Scav = Scav;
- Scav = OldGen + 1;
-
- DO_EVACUATE(save_Scav, BF_LINK_LOCN);
- DO_EVACUATE(save_Scav, BF_NODE_LOCN);
- Scav = save_Scav;
-#else
- DO_EVACUATE(Scav, BF_LINK_LOCN);
- DO_EVACUATE(Scav, BF_NODE_LOCN);
-#endif
-
- PROFILE_CLOSURE(Scav, size);
- NEXT_Scav(size);
- return;
-}
-
-#endif /* PAR */
-#endif /* CONCURRENT */
-
-#if defined(GCgn)
-
-/* Recently allocated old roots for promoted objects refernecing
- the new generation will be scavenged -- Just move to the next
-*/
-
-void
-_Scavenge_OldRoot(STG_NO_ARGS)
-{
- I_ size = ?????
- DEBUG_SCAV_OLDROOT(size);
- NEXT_Scav(size);
- return;
-}
-
-P_
-_Evacuate_OldRoot(evac)
-P_ evac;
-{
- fprintf(stderr,"Called _Evacuate_OldRoot: Closure %lx Info %lx\nShould never occur!\n",
- (W_) evac, (W_) INFO_PTR(evac));
- abort();
-}
-
-#endif /* GCgn */
-
-void
-_Scavenge_Forward_Ref(STG_NO_ARGS)
-{
- fprintf(stderr,"Called _Scavenge_Forward_Ref: Closure %lx Info %lx\nShould never occur!\n",
- (W_) Scav, (W_) INFO_PTR(Scav));
- abort();
-}
-
-
-#endif /* _INFO_COPYING */
-
-\end{code}