18static char SccsId[] =
"@(#)agc.c 1.3 3/15/90";
32#define errout GLOBAL_stderr
35static void RestoreEntries(
PropEntry *,
int USES_REGS);
36static void CleanCode(
PredEntry * USES_REGS);
37static void RestoreDBTerm(
DBTerm *dbr,
bool src,
int attachments USES_REGS);
39#define AtomMarkedBit 1
44 CELL c = (CELL)(ae->NextOfAE);
46 ae->NextOfAE = (
Atom)c;
52 CELL c = (CELL)(ae->NextOfAE);
53 if (c & AtomMarkedBit) {
55 ae->NextOfAE = (
Atom)c;
62CleanAtomMarkedBit(
Atom a)
73 if (!IsExtensionFunctor(f)) {
74 AtomEntry *ae = RepAtom(NameOfFunctor(f));
90TermToGlobalOrAtomAdjust(Term t)
92 if (t && IsAtomTerm(t))
93 return AtomTermAdjust(t);
101 if (a == NIL)
return(a);
107#define IsOldCode(P) FALSE
108#define IsOldCodeCellPtr(P) FALSE
109#define IsOldDelay(P) FALSE
110#define IsOldDelayPtr(P) FALSE
111#define IsOldLocalInTR(P) FALSE
112#define IsOldLocalInTRPtr(P) FALSE
113#define IsOldGlobal(P) FALSE
114#define IsOldGlobalPtr(P) FALSE
115#define IsOldTrail(P) FALSE
116#define IsOldTrailPtr(P) FALSE
118#define CharP(X) ((char *)(X))
120#define REINIT_LOCK(P)
121#define REINIT_RWLOCK(P)
122#define BlobTypeAdjust(P) (P)
123#define NoAGCAtomAdjust(P) (P)
124#define OrArgAdjust(P)
125#define TabEntryAdjust(P)
126#define IntegerAdjust(D) (D)
127#define AddrAdjust(P) (P)
128#define MFileAdjust(P) (P)
129#define CodeVarAdjust(P) (P)
130#define ConstantAdjust(P) (P)
131#define ArityAdjust(P) (P)
132#define DoubleInCodeAdjust(P)
133#define IntegerInCodeAdjust(P)
134#define OpcodeAdjust(P) (P)
135#define ModuleAdjust(P) (P)
136#define ExternalFunctionAdjust(P) (P)
137#define DBRecordAdjust(P) (P)
138#define PredEntryAdjust(P) (P)
139#define ModEntryPtrAdjust(P) (P)
140#define AtomEntryAdjust(P) (P)
141#define GlobalEntryAdjust(P) (P)
142#define BlobTermInCodeAdjust(P) (P)
143#define CellPtoHeapAdjust(P) (P)
144#define PtoAtomHashEntryAdjust(P) (P)
145#define CellPtoHeapCellAdjust(P) (P)
146#define CellPtoTRAdjust(P) (P)
147#define CodeAddrAdjust(P) (P)
148#define ConsultObjAdjust(P) (P)
149#define DelayAddrAdjust(P) (P)
150#define DelayAdjust(P) (P)
151#define GlobalAdjust(P) (P)
152#define DBRefAdjust(P,REF) (P)
153#define DBRefPAdjust(P) (P)
154#define DBTermAdjust(P) (P)
155#define LUIndexAdjust(P) (P)
156#define SIndexAdjust(P) (P)
157#define LocalAddrAdjust(P) (P)
158#define GlobalAddrAdjust(P) (P)
159#define OpListAdjust(P) (P)
160#define PtoLUCAdjust(P) (P)
161#define PtoStCAdjust(P) (P)
162#define PtoArrayEAdjust(P) (P)
163#define PtoArraySAdjust(P) (P)
164#define PtoGlobalEAdjust(P) (P)
165#define PtoDelayAdjust(P) (P)
166#define PtoGloAdjust(P) (P)
167#define PtoLocAdjust(P) (P)
168#define PtoHeapCellAdjust(P) (P)
169#define TermToGlobalAdjust(P) (P)
170#define PtoOpAdjust(P) (P)
171#define PtoLUClauseAdjust(P) (P)
172#define PtoLUIndexAdjust(P) (P)
173#define PtoDBTLAdjust(P) (P)
174#define PtoPredAdjust(P) (P)
175#define PtoPtoPredAdjust(P) (P)
176#define OpRTableAdjust(P) (P)
177#define OpEntryAdjust(P) (P)
178#define PropAdjust(P) (P)
179#define TrailAddrAdjust(P) (P)
180#define XAdjust(P) (P)
181#define YAdjust(P) (P)
182#define HoldEntryAdjust(P) (P)
183#define CodeCharPAdjust(P) (P)
184#define CodeConstCharPAdjust(P) (P)
185#define CodeVoidPAdjust(P) (P)
186#define HaltHookAdjust(P) (P)
188#define recompute_mask(dbr)
190#define rehash(oldcode, NOfE, KindOfEntries)
192#define RestoreSWIHash()
198 if (IsVarTerm(tarr[i].at)) {
199 RestoreDBTerm( tarr[i].DBT,
false, 0 PASS_REGS );
200 }
else if (IsAtomTerm( tarr[i].at ) )
201 tarr[i].at = AtomTermAdjust(tarr[i].at);
204static void RestoreFlags( UInt NFlags )
211 for (i=0; i<GLOBAL_flagCount; i++) {
212 AdjustTermFlag( tarr, i);
215 for (i=0; i<LOCAL_flagCount; i++) {
216 AdjustTermFlag( tarr, i);
223RestoreHashPreds( USES_REGS1 )
228static void init_reg_copies(USES_REGS1)
231 LOCAL_OldLCL0 = LCL0;
233 LOCAL_OldGlobalBase = (CELL *)LOCAL_GlobalBase;
236 LOCAL_OldTrailBase = LOCAL_TrailBase;
237 LOCAL_OldTrailTop = LOCAL_TrailTop;
238 LOCAL_OldHeapBase = Yap_HeapBase;
239 LOCAL_OldHeapTop = HeapTop;
244RestoreAtomList(
Atom atm USES_REGS)
252 RestoreAtom(atm PASS_REGS);
253 atm = CleanAtomMarkedBit(at->NextOfAE);
255 }
while (!EndOfPAEntr(at));
259mark_trail(USES_REGS1)
261 register tr_fr_ptr pt;
265 while (pt != (tr_fr_ptr)LOCAL_TrailBase) {
266 CELL reg = TrailTerm(pt-1);
268 if (!IsVarTerm(reg)) {
269 if (IsAtomTerm(reg)) {
270 MarkAtomEntry(RepAtom(AtomOfTerm(reg)));
279mark_registers(USES_REGS1)
285 while (pt != XREGS+MaxTemps) {
288 if (!IsVarTerm(reg)) {
289 if (IsAtomTerm(reg)) {
290 MarkAtomEntry(RepAtom(AtomOfTerm(reg)));
297mark_local(USES_REGS1)
307 if (!IsVarTerm(reg)) {
313 && reg > Yap_page_size
316 MarkAtomEntry(RepAtom(AtomOfTerm(reg)));
323mark_global_cell(CELL *pt)
327 if (IsVarTerm(reg)) {
330 case (CELL)FunctorDouble:
331#if SIZEOF_DOUBLE == 2*SIZEOF_INT_P
336 case (CELL)FunctorString:
337 return pt + 3 + pt[1];
338 case (CELL)FunctorBigInt:
342 (((
MP_INT *)(pt+2))->_mp_alloc*
sizeof(mp_limb_t)))/
sizeof(CELL);
345 case (CELL)FunctorBlob:
347 YAP_Opaque_CallOnGCMark f;
348 YAP_Opaque_CallOnGCRelocate f2;
349 Term t = AbsAppl(pt);
351 if ( (f = Yap_blob_gc_mark_handler(t)) ) {
353 Int i,n = (f)(Yap_BlobTag(t), Yap_BlobInfo(t), ar, 256);
355 Yap_Error(RESOURCE_ERROR_HEAP,TermNil,
"not enough space for slot internal variables in agc");
357 for (i = 0; i< n; i++) {
360 if (!IsVarTerm(reg) && IsAtomTerm(reg)) {
361 *pt = AtomTermAdjust(reg);
364 if ( (f2 = Yap_blob_gc_relocate_handler(t)) < 0 ) {
365 int out = (f2)(Yap_BlobTag(t), Yap_BlobInfo(t), ar, n);
367 Yap_Error(RESOURCE_ERROR_HEAP,TermNil,
"bad restore of slot internal variables in agc");
373 case (CELL)FunctorLongInt:
377 }
else if (IsAtomTerm(reg)) {
378 MarkAtomEntry(RepAtom(AtomOfTerm(reg)));
385mark_global(USES_REGS1)
395 pt = mark_global_cell(pt);
400mark_stacks(USES_REGS1)
402 mark_registers(PASS_REGS1);
403 mark_trail(PASS_REGS1);
404 mark_local(PASS_REGS1);
405 mark_global(PASS_REGS1);
411 Atom atm = HashPtr->Entry;
412 Atom *patm = &(HashPtr->Entry);
415 if (AtomResetMark(at) ||
416 ( at->PropsOfAE != NIL && !IsBlob(at) ) ||
417 (GLOBAL_AGCHook != NULL && !GLOBAL_AGCHook(atm))) {
418 patm = &(at->NextOfAE);
424 if (b->NextOfPE != NIL) {
425 patm = &(at->NextOfAE);
432 Yap_FreeCodeSpace((
char *)b);
434 GLOBAL_agc_collected +=
sizeof(
AtomEntry)+
sizeof(
size_t)+at->rep.blob->length;
437 fprintf(stderr,
"Purged %p:%s patm=%p %p\n", at, at->StrOfAE, patm, at->NextOfAE);
439 GLOBAL_agc_collected +=
sizeof(
AtomEntry)+strlen((
const char *)at->StrOfAE);
441 *patm = atm = at->NextOfAE;
443 Yap_FreeCodeSpace((
char *)at);
457 AtomResetMark(AtomFoundVar);
458 AtomResetMark(AtomFreeTerm);
459 for (i = 0; i < AtomHashTableSize; ++i) {
460 clean_atom_list(HashPtr);
463 clean_atom_list(&INVISIBLECHAIN);
467 clean_atom_list(&list);
474 bool gc_verbose = Yap_is_gc_verbose();
478 UInt time_start, agc_time;
479#if defined(YAPOR) || defined(THREADS)
483 if (Yap_GetValue(AtomGcTrace) != TermNil)
487 GLOBAL_agc_collected = 0;
490 fprintf(stderr,
"%% agc:\n");
491 }
else if (gc_verbose) {
492 fprintf(stderr,
"%% Start of atom garbage collection %d:\n", GLOBAL_agc_calls);
494 time_start = Yap_cputime();
496 YAPEnterCriticalSection();
497 init_reg_copies(PASS_REGS1);
498 mark_stacks(PASS_REGS1);
501 NOfBlobsMax = NOfBlobs+(NOfBlobs/2+256< 1024 ? NOfBlobs/2+256 : 1024);
502 YAPLeaveCriticalSection();
503 agc_time = Yap_cputime()-time_start;
504 GLOBAL_tot_agc_time += agc_time;
505 GLOBAL_tot_agc_recovered += GLOBAL_agc_collected;
508 fprintf(stderr,
"%% Collected %I64d bytes.\n", GLOBAL_agc_collected);
510 fprintf(stderr,
"%% Collected %lld bytes.\n", GLOBAL_agc_collected);
512 fprintf(stderr,
"%% GC %d took %g sec, total of %g sec doing GC so far.\n", GLOBAL_agc_calls, (
double)agc_time/1000, (
double)GLOBAL_tot_agc_time/1000);
517Yap_atom_gc(USES_REGS1)
532p_inform_agc(USES_REGS1)
534 Term tn = MkIntegerTerm(GLOBAL_tot_agc_time);
535 Term tt = MkIntegerTerm(GLOBAL_agc_calls);
536 Term ts = MkIntegerTerm(GLOBAL_tot_agc_recovered);
539 Yap_unify(tn, ARG2) &&
540 Yap_unify(tt, ARG1) &&
548 Yap_InitCPred(
"$atom_gc", 0, p_atom_gc, 0);
549 Yap_InitCPred(
"$inform_agc", 3, p_inform_agc, 0);
load_foreign_files/3 has works for the following configurations:
@ gc_trace
show activity in garbag collector
a flag is represented as a Prolog term