2002-06-04 19:21:55 +01:00
|
|
|
/*************************************************************************
|
|
|
|
* *
|
|
|
|
* YAP Prolog *
|
|
|
|
* *
|
|
|
|
* Yap Prolog was developed at NCCUP - Universidade do Porto *
|
|
|
|
* *
|
|
|
|
* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 *
|
|
|
|
* *
|
|
|
|
**************************************************************************
|
|
|
|
* *
|
|
|
|
* File: agc.c *
|
|
|
|
* Last rev: *
|
|
|
|
* mods: *
|
|
|
|
* comments: reclaim unused atoms and functors *
|
|
|
|
* *
|
|
|
|
*************************************************************************/
|
|
|
|
#ifdef SCCS
|
|
|
|
static char SccsId[] = "@(#)agc.c 1.3 3/15/90";
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "absmi.h"
|
2009-10-31 00:02:17 +00:00
|
|
|
#include "Foreign.h"
|
2002-06-04 19:21:55 +01:00
|
|
|
#include "alloc.h"
|
2002-06-05 15:23:15 +01:00
|
|
|
#include "yapio.h"
|
2007-02-18 00:26:36 +00:00
|
|
|
#include "iopreds.h"
|
2005-05-27 22:44:00 +01:00
|
|
|
#include "attvar.h"
|
2002-06-04 19:21:55 +01:00
|
|
|
|
|
|
|
#ifdef DEBUG
|
2005-05-30 06:26:50 +01:00
|
|
|
/* #define DEBUG_RESTORE1 1 */
|
2002-06-04 19:21:55 +01:00
|
|
|
/* #define DEBUG_RESTORE2 1 */
|
2007-02-18 00:26:36 +00:00
|
|
|
/* #define DEBUG_RESTORE3 1 */
|
2011-05-25 16:40:36 +01:00
|
|
|
#define errout GLOBAL_stderr
|
2002-06-04 19:21:55 +01:00
|
|
|
#endif
|
|
|
|
|
2013-04-25 23:15:04 +01:00
|
|
|
static void RestoreEntries(PropEntry *, int USES_REGS);
|
|
|
|
static void CleanCode(PredEntry * USES_REGS);
|
2016-02-28 19:30:46 +00:00
|
|
|
static void RestoreDBTerm(DBTerm *dbr, bool src, int attachments USES_REGS);
|
2002-06-04 19:21:55 +01:00
|
|
|
|
|
|
|
#define AtomMarkedBit 1
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
MarkAtomEntry(AtomEntry *ae)
|
|
|
|
{
|
|
|
|
CELL c = (CELL)(ae->NextOfAE);
|
|
|
|
c |= AtomMarkedBit;
|
|
|
|
ae->NextOfAE = (Atom)c;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline int
|
|
|
|
AtomResetMark(AtomEntry *ae)
|
|
|
|
{
|
|
|
|
CELL c = (CELL)(ae->NextOfAE);
|
|
|
|
if (c & AtomMarkedBit) {
|
|
|
|
c &= ~AtomMarkedBit;
|
|
|
|
ae->NextOfAE = (Atom)c;
|
2007-02-18 00:26:36 +00:00
|
|
|
return TRUE;
|
2002-06-04 19:21:55 +01:00
|
|
|
}
|
2007-02-18 00:26:36 +00:00
|
|
|
return FALSE;
|
2002-06-04 19:21:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline Atom
|
|
|
|
CleanAtomMarkedBit(Atom a)
|
|
|
|
{
|
|
|
|
CELL c = (CELL)a;
|
|
|
|
c &= ~AtomMarkedBit;
|
2007-02-18 00:26:36 +00:00
|
|
|
return (Atom)c;
|
2002-06-04 19:21:55 +01:00
|
|
|
}
|
|
|
|
|
2010-12-12 16:45:39 +00:00
|
|
|
|
2002-06-04 19:21:55 +01:00
|
|
|
static inline Functor
|
|
|
|
FuncAdjust(Functor f)
|
|
|
|
{
|
2005-05-30 04:26:37 +01:00
|
|
|
if (!IsExtensionFunctor(f)) {
|
|
|
|
AtomEntry *ae = RepAtom(NameOfFunctor(f));
|
|
|
|
MarkAtomEntry(ae);
|
|
|
|
}
|
2002-06-04 19:21:55 +01:00
|
|
|
return(f);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static inline Term
|
|
|
|
AtomTermAdjust(Term t)
|
|
|
|
{
|
|
|
|
AtomEntry *ae = RepAtom(AtomOfTerm(t));
|
|
|
|
MarkAtomEntry(ae);
|
|
|
|
return(t);
|
|
|
|
}
|
|
|
|
|
2010-03-21 22:12:42 +00:00
|
|
|
static inline Term
|
|
|
|
TermToGlobalOrAtomAdjust(Term t)
|
|
|
|
{
|
|
|
|
if (t && IsAtomTerm(t))
|
|
|
|
return AtomTermAdjust(t);
|
|
|
|
return(t);
|
|
|
|
}
|
|
|
|
|
2002-06-04 19:21:55 +01:00
|
|
|
static inline Atom
|
|
|
|
AtomAdjust(Atom a)
|
|
|
|
{
|
|
|
|
AtomEntry *ae;
|
|
|
|
if (a == NIL) return(a);
|
|
|
|
ae = RepAtom(a);
|
|
|
|
MarkAtomEntry(ae);
|
|
|
|
return(a);
|
|
|
|
}
|
|
|
|
|
|
|
|
#define IsOldCode(P) FALSE
|
|
|
|
#define IsOldCodeCellPtr(P) FALSE
|
|
|
|
#define IsOldDelay(P) FALSE
|
|
|
|
#define IsOldDelayPtr(P) FALSE
|
|
|
|
#define IsOldLocalInTR(P) FALSE
|
|
|
|
#define IsOldLocalInTRPtr(P) FALSE
|
|
|
|
#define IsOldGlobal(P) FALSE
|
|
|
|
#define IsOldGlobalPtr(P) FALSE
|
|
|
|
#define IsOldTrail(P) FALSE
|
|
|
|
#define IsOldTrailPtr(P) FALSE
|
|
|
|
|
|
|
|
#define CharP(X) ((char *)(X))
|
|
|
|
|
2009-10-28 13:11:35 +00:00
|
|
|
#define REINIT_LOCK(P)
|
|
|
|
#define REINIT_RWLOCK(P)
|
2011-03-08 00:22:32 +00:00
|
|
|
#define BlobTypeAdjust(P) (P)
|
2010-10-26 10:04:36 +01:00
|
|
|
#define NoAGCAtomAdjust(P) (P)
|
2008-09-05 05:22:19 +01:00
|
|
|
#define OrArgAdjust(P)
|
|
|
|
#define TabEntryAdjust(P)
|
2008-08-29 17:27:11 +01:00
|
|
|
#define IntegerAdjust(D) (D)
|
2002-06-04 19:21:55 +01:00
|
|
|
#define AddrAdjust(P) (P)
|
2008-04-04 10:10:02 +01:00
|
|
|
#define MFileAdjust(P) (P)
|
2008-08-29 17:27:11 +01:00
|
|
|
#define CodeVarAdjust(P) (P)
|
|
|
|
#define ConstantAdjust(P) (P)
|
|
|
|
#define ArityAdjust(P) (P)
|
|
|
|
#define DoubleInCodeAdjust(P)
|
|
|
|
#define IntegerInCodeAdjust(P)
|
|
|
|
#define OpcodeAdjust(P) (P)
|
|
|
|
#define ModuleAdjust(P) (P)
|
|
|
|
#define ExternalFunctionAdjust(P) (P)
|
2011-01-03 03:16:29 +00:00
|
|
|
#define DBRecordAdjust(P) (P)
|
2007-09-29 00:18:17 +01:00
|
|
|
#define PredEntryAdjust(P) (P)
|
2009-10-28 13:11:35 +00:00
|
|
|
#define ModEntryPtrAdjust(P) (P)
|
2002-06-04 19:21:55 +01:00
|
|
|
#define AtomEntryAdjust(P) (P)
|
2007-01-08 08:27:19 +00:00
|
|
|
#define GlobalEntryAdjust(P) (P)
|
2010-12-16 20:39:53 +00:00
|
|
|
#define BlobTermInCodeAdjust(P) (P)
|
2002-06-04 19:21:55 +01:00
|
|
|
#define CellPtoHeapAdjust(P) (P)
|
2008-09-18 17:59:16 +01:00
|
|
|
#define PtoAtomHashEntryAdjust(P) (P)
|
2002-06-04 19:21:55 +01:00
|
|
|
#define CellPtoHeapCellAdjust(P) (P)
|
|
|
|
#define CellPtoTRAdjust(P) (P)
|
|
|
|
#define CodeAddrAdjust(P) (P)
|
|
|
|
#define ConsultObjAdjust(P) (P)
|
|
|
|
#define DelayAddrAdjust(P) (P)
|
2006-08-22 17:12:46 +01:00
|
|
|
#define DelayAdjust(P) (P)
|
|
|
|
#define GlobalAdjust(P) (P)
|
2012-06-12 14:50:36 +01:00
|
|
|
#define DBRefAdjust(P,REF) (P)
|
2003-01-21 16:14:52 +00:00
|
|
|
#define DBRefPAdjust(P) (P)
|
2004-02-06 02:26:23 +00:00
|
|
|
#define DBTermAdjust(P) (P)
|
|
|
|
#define LUIndexAdjust(P) (P)
|
|
|
|
#define SIndexAdjust(P) (P)
|
2002-06-04 19:21:55 +01:00
|
|
|
#define LocalAddrAdjust(P) (P)
|
|
|
|
#define GlobalAddrAdjust(P) (P)
|
2009-10-30 23:59:00 +00:00
|
|
|
#define OpListAdjust(P) (P)
|
2004-02-06 02:26:23 +00:00
|
|
|
#define PtoLUCAdjust(P) (P)
|
|
|
|
#define PtoStCAdjust(P) (P)
|
2002-06-04 19:21:55 +01:00
|
|
|
#define PtoArrayEAdjust(P) (P)
|
2005-10-28 18:38:50 +01:00
|
|
|
#define PtoArraySAdjust(P) (P)
|
2006-08-22 17:12:46 +01:00
|
|
|
#define PtoGlobalEAdjust(P) (P)
|
2002-06-04 19:21:55 +01:00
|
|
|
#define PtoDelayAdjust(P) (P)
|
|
|
|
#define PtoGloAdjust(P) (P)
|
|
|
|
#define PtoLocAdjust(P) (P)
|
|
|
|
#define PtoHeapCellAdjust(P) (P)
|
2010-03-21 22:12:42 +00:00
|
|
|
#define TermToGlobalAdjust(P) (P)
|
2002-06-04 19:21:55 +01:00
|
|
|
#define PtoOpAdjust(P) (P)
|
2006-10-10 15:08:17 +01:00
|
|
|
#define PtoLUClauseAdjust(P) (P)
|
2006-11-27 17:42:03 +00:00
|
|
|
#define PtoLUIndexAdjust(P) (P)
|
2007-11-06 17:02:13 +00:00
|
|
|
#define PtoDBTLAdjust(P) (P)
|
2002-06-04 19:21:55 +01:00
|
|
|
#define PtoPredAdjust(P) (P)
|
2009-10-28 13:11:35 +00:00
|
|
|
#define PtoPtoPredAdjust(P) (P)
|
|
|
|
#define OpRTableAdjust(P) (P)
|
2010-03-01 17:52:42 +00:00
|
|
|
#define OpEntryAdjust(P) (P)
|
2002-06-04 19:21:55 +01:00
|
|
|
#define PropAdjust(P) (P)
|
|
|
|
#define TrailAddrAdjust(P) (P)
|
|
|
|
#define XAdjust(P) (P)
|
|
|
|
#define YAdjust(P) (P)
|
2007-12-05 12:17:25 +00:00
|
|
|
#define HoldEntryAdjust(P) (P)
|
2009-10-30 23:59:00 +00:00
|
|
|
#define CodeCharPAdjust(P) (P)
|
2014-12-14 11:56:20 +00:00
|
|
|
#define CodeConstCharPAdjust(P) (P)
|
2009-10-30 23:59:00 +00:00
|
|
|
#define CodeVoidPAdjust(P) (P)
|
2010-09-24 14:00:53 +01:00
|
|
|
#define HaltHookAdjust(P) (P)
|
2002-06-04 19:21:55 +01:00
|
|
|
|
2008-03-25 22:03:14 +00:00
|
|
|
#define recompute_mask(dbr)
|
2002-06-04 19:21:55 +01:00
|
|
|
|
2008-03-25 22:03:14 +00:00
|
|
|
#define rehash(oldcode, NOfE, KindOfEntries)
|
2002-06-04 19:21:55 +01:00
|
|
|
|
2010-05-03 14:26:56 +01:00
|
|
|
#define RestoreSWIHash()
|
|
|
|
|
2015-08-07 22:57:53 +01:00
|
|
|
static void
|
|
|
|
AdjustTermFlag(flag_term *tarr, UInt i)
|
|
|
|
{
|
|
|
|
CACHE_REGS
|
|
|
|
if (IsVarTerm(tarr[i].at)) {
|
2016-02-28 19:30:46 +00:00
|
|
|
RestoreDBTerm( tarr[i].DBT, false, 0 PASS_REGS );
|
2015-08-07 22:57:53 +01:00
|
|
|
} else if (IsAtomTerm( tarr[i].at ) )
|
|
|
|
tarr[i].at = AtomTermAdjust(tarr[i].at);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void RestoreFlags( UInt NFlags )
|
|
|
|
{
|
|
|
|
CACHE_REGS
|
|
|
|
size_t i;
|
|
|
|
flag_term *tarr = GLOBAL_Flags;
|
|
|
|
|
|
|
|
if (worker_id == 0)
|
|
|
|
for (i=0; i<GLOBAL_flagCount; i++) {
|
|
|
|
AdjustTermFlag( tarr, i);
|
|
|
|
}
|
|
|
|
tarr = LOCAL_Flags;
|
|
|
|
for (i=0; i<LOCAL_flagCount; i++) {
|
|
|
|
AdjustTermFlag( tarr, i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-06-04 19:21:55 +01:00
|
|
|
#include "rheap.h"
|
|
|
|
|
2010-04-09 11:46:59 +01:00
|
|
|
static void
|
2011-03-07 16:02:55 +00:00
|
|
|
RestoreHashPreds( USES_REGS1 )
|
2010-04-09 11:46:59 +01:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-03-07 16:02:55 +00:00
|
|
|
static void init_reg_copies(USES_REGS1)
|
2007-02-18 00:26:36 +00:00
|
|
|
{
|
2011-05-04 10:11:41 +01:00
|
|
|
LOCAL_OldASP = ASP;
|
|
|
|
LOCAL_OldLCL0 = LCL0;
|
|
|
|
LOCAL_OldTR = TR;
|
2011-05-23 16:19:47 +01:00
|
|
|
LOCAL_OldGlobalBase = (CELL *)LOCAL_GlobalBase;
|
2014-01-19 21:15:05 +00:00
|
|
|
LOCAL_OldH = HR;
|
2011-05-04 10:11:41 +01:00
|
|
|
LOCAL_OldH0 = H0;
|
2011-05-23 16:19:47 +01:00
|
|
|
LOCAL_OldTrailBase = LOCAL_TrailBase;
|
|
|
|
LOCAL_OldTrailTop = LOCAL_TrailTop;
|
2011-05-04 10:11:41 +01:00
|
|
|
LOCAL_OldHeapBase = Yap_HeapBase;
|
|
|
|
LOCAL_OldHeapTop = HeapTop;
|
2007-02-18 00:26:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-11-27 17:42:03 +00:00
|
|
|
static void
|
2011-03-07 16:02:55 +00:00
|
|
|
RestoreAtomList(Atom atm USES_REGS)
|
2006-11-27 17:42:03 +00:00
|
|
|
{
|
2009-10-30 23:59:00 +00:00
|
|
|
AtomEntry *at;
|
|
|
|
|
|
|
|
at = RepAtom(atm);
|
|
|
|
if (EndOfPAEntr(at))
|
|
|
|
return;
|
|
|
|
do {
|
2011-03-07 16:02:55 +00:00
|
|
|
RestoreAtom(atm PASS_REGS);
|
2009-10-30 23:59:00 +00:00
|
|
|
atm = CleanAtomMarkedBit(at->NextOfAE);
|
|
|
|
at = RepAtom(atm);
|
|
|
|
} while (!EndOfPAEntr(at));
|
2007-09-29 00:18:17 +01:00
|
|
|
}
|
|
|
|
|
2002-06-04 19:21:55 +01:00
|
|
|
static void
|
2011-03-07 16:02:55 +00:00
|
|
|
mark_trail(USES_REGS1)
|
2002-06-04 19:21:55 +01:00
|
|
|
{
|
2007-03-18 23:09:12 +00:00
|
|
|
register tr_fr_ptr pt;
|
2002-06-04 19:21:55 +01:00
|
|
|
|
2007-03-18 23:09:12 +00:00
|
|
|
pt = TR;
|
2002-06-04 19:21:55 +01:00
|
|
|
/* moving the trail is simple */
|
2011-05-23 16:19:47 +01:00
|
|
|
while (pt != (tr_fr_ptr)LOCAL_TrailBase) {
|
2007-03-18 23:09:12 +00:00
|
|
|
CELL reg = TrailTerm(pt-1);
|
|
|
|
|
2002-06-04 19:21:55 +01:00
|
|
|
if (!IsVarTerm(reg)) {
|
|
|
|
if (IsAtomTerm(reg)) {
|
|
|
|
MarkAtomEntry(RepAtom(AtomOfTerm(reg)));
|
|
|
|
}
|
|
|
|
}
|
2007-03-18 23:09:12 +00:00
|
|
|
|
|
|
|
pt--;
|
2002-06-04 19:21:55 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-02-27 12:56:27 +00:00
|
|
|
static void
|
2011-03-07 16:02:55 +00:00
|
|
|
mark_registers(USES_REGS1)
|
2009-02-27 12:56:27 +00:00
|
|
|
{
|
|
|
|
CELL *pt;
|
|
|
|
|
|
|
|
pt = XREGS;
|
|
|
|
/* moving the trail is simple */
|
|
|
|
while (pt != XREGS+MaxTemps) {
|
|
|
|
CELL reg = *pt++;
|
|
|
|
|
|
|
|
if (!IsVarTerm(reg)) {
|
|
|
|
if (IsAtomTerm(reg)) {
|
|
|
|
MarkAtomEntry(RepAtom(AtomOfTerm(reg)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-06-04 19:21:55 +01:00
|
|
|
static void
|
2011-03-07 16:02:55 +00:00
|
|
|
mark_local(USES_REGS1)
|
2002-06-04 19:21:55 +01:00
|
|
|
{
|
2008-01-23 17:57:56 +00:00
|
|
|
CELL *pt;
|
2002-06-04 19:21:55 +01:00
|
|
|
|
|
|
|
/* Adjusting the local */
|
|
|
|
pt = LCL0;
|
|
|
|
/* moving the trail is simple */
|
|
|
|
while (pt > ASP) {
|
|
|
|
CELL reg = *--pt;
|
|
|
|
|
|
|
|
if (!IsVarTerm(reg)) {
|
2007-03-18 23:09:12 +00:00
|
|
|
if (IsAtomTerm(reg)
|
2008-03-25 22:03:14 +00:00
|
|
|
#ifdef TABLING
|
2007-03-18 23:09:12 +00:00
|
|
|
/* assume we cannot have atoms on first page,
|
|
|
|
so this must be an arity
|
|
|
|
*/
|
|
|
|
&& reg > Yap_page_size
|
|
|
|
#endif
|
|
|
|
) {
|
2002-06-04 19:21:55 +01:00
|
|
|
MarkAtomEntry(RepAtom(AtomOfTerm(reg)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-05-27 22:44:00 +01:00
|
|
|
static CELL *
|
|
|
|
mark_global_cell(CELL *pt)
|
|
|
|
{
|
|
|
|
CELL reg = *pt;
|
|
|
|
|
|
|
|
if (IsVarTerm(reg)) {
|
|
|
|
/* skip bitmaps */
|
|
|
|
switch(reg) {
|
|
|
|
case (CELL)FunctorDouble:
|
2014-01-19 21:15:05 +00:00
|
|
|
#if SIZEOF_DOUBLE == 2*SIZEOF_INT_P
|
2005-05-27 22:44:00 +01:00
|
|
|
return pt + 4;
|
|
|
|
#else
|
|
|
|
return pt + 3;
|
|
|
|
#endif
|
2013-12-02 14:49:41 +00:00
|
|
|
case (CELL)FunctorString:
|
|
|
|
return pt + 3 + pt[1];
|
2005-05-27 22:44:00 +01:00
|
|
|
case (CELL)FunctorBigInt:
|
|
|
|
{
|
2008-11-28 15:54:46 +00:00
|
|
|
Int sz = 3 +
|
2007-02-18 00:26:36 +00:00
|
|
|
(sizeof(MP_INT)+
|
2008-11-28 15:54:46 +00:00
|
|
|
(((MP_INT *)(pt+2))->_mp_alloc*sizeof(mp_limb_t)))/sizeof(CELL);
|
2017-07-30 21:53:07 +01:00
|
|
|
YAP_Opaque_CallOnGCMark f;
|
|
|
|
YAP_Opaque_CallOnGCRelocate f2;
|
2011-12-13 12:16:42 +00:00
|
|
|
Term t = AbsAppl(pt);
|
2011-12-13 10:41:05 +00:00
|
|
|
|
2011-12-13 12:16:42 +00:00
|
|
|
if ( (f = Yap_blob_gc_mark_handler(t)) ) {
|
2011-12-13 10:41:05 +00:00
|
|
|
CELL ar[256];
|
2011-12-13 12:16:42 +00:00
|
|
|
Int i,n = (f)(Yap_BlobTag(t), Yap_BlobInfo(t), ar, 256);
|
2011-12-13 10:41:05 +00:00
|
|
|
if (n < 0) {
|
2015-09-25 10:57:26 +01:00
|
|
|
Yap_Error(RESOURCE_ERROR_HEAP,TermNil,"not enough space for slot internal variables in agc");
|
2011-12-13 10:41:05 +00:00
|
|
|
}
|
|
|
|
for (i = 0; i< n; i++) {
|
|
|
|
CELL *pt = ar+i;
|
|
|
|
CELL reg = *pt;
|
|
|
|
if (!IsVarTerm(reg) && IsAtomTerm(reg)) {
|
|
|
|
*pt = AtomTermAdjust(reg);
|
|
|
|
}
|
|
|
|
}
|
2011-12-13 18:14:33 +00:00
|
|
|
if ( (f2 = Yap_blob_gc_relocate_handler(t)) < 0 ) {
|
2011-12-13 12:16:42 +00:00
|
|
|
int out = (f2)(Yap_BlobTag(t), Yap_BlobInfo(t), ar, n);
|
2011-12-13 10:41:05 +00:00
|
|
|
if (out < 0)
|
2015-09-25 10:57:26 +01:00
|
|
|
Yap_Error(RESOURCE_ERROR_HEAP,TermNil,"bad restore of slot internal variables in agc");
|
2011-12-13 10:41:05 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-02-18 00:26:36 +00:00
|
|
|
return pt + sz;
|
2005-05-27 22:44:00 +01:00
|
|
|
}
|
|
|
|
case (CELL)FunctorLongInt:
|
2007-02-18 00:26:36 +00:00
|
|
|
return pt + 3;
|
2005-05-27 22:44:00 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else if (IsAtomTerm(reg)) {
|
|
|
|
MarkAtomEntry(RepAtom(AtomOfTerm(reg)));
|
|
|
|
return pt+1;
|
|
|
|
}
|
|
|
|
return pt+1;
|
|
|
|
}
|
|
|
|
|
2002-06-04 19:21:55 +01:00
|
|
|
static void
|
2011-03-07 16:02:55 +00:00
|
|
|
mark_global(USES_REGS1)
|
2002-06-04 19:21:55 +01:00
|
|
|
{
|
2005-05-27 22:44:00 +01:00
|
|
|
CELL *pt;
|
2002-06-04 19:21:55 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* to clean the global now that functors are just variables pointing to
|
|
|
|
* the code
|
|
|
|
*/
|
2005-05-27 22:44:00 +01:00
|
|
|
pt = H0;
|
2014-01-19 21:15:05 +00:00
|
|
|
while (pt < HR) {
|
2005-05-27 22:44:00 +01:00
|
|
|
pt = mark_global_cell(pt);
|
2002-06-04 19:21:55 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2011-03-07 16:02:55 +00:00
|
|
|
mark_stacks(USES_REGS1)
|
2002-06-04 19:21:55 +01:00
|
|
|
{
|
2011-03-07 16:02:55 +00:00
|
|
|
mark_registers(PASS_REGS1);
|
|
|
|
mark_trail(PASS_REGS1);
|
|
|
|
mark_local(PASS_REGS1);
|
|
|
|
mark_global(PASS_REGS1);
|
2002-06-04 19:21:55 +01:00
|
|
|
}
|
|
|
|
|
2007-02-18 00:26:36 +00:00
|
|
|
static void
|
|
|
|
clean_atom_list(AtomHashEntry *HashPtr)
|
2006-11-27 17:42:03 +00:00
|
|
|
{
|
|
|
|
Atom atm = HashPtr->Entry;
|
|
|
|
Atom *patm = &(HashPtr->Entry);
|
|
|
|
while (atm != NIL) {
|
2007-02-18 00:26:36 +00:00
|
|
|
AtomEntry *at = RepAtom(atm);
|
|
|
|
if (AtomResetMark(at) ||
|
2011-12-22 10:27:56 +00:00
|
|
|
( at->PropsOfAE != NIL && !IsBlob(at) ) ||
|
2011-05-10 10:06:51 +01:00
|
|
|
(GLOBAL_AGCHook != NULL && !GLOBAL_AGCHook(atm))) {
|
2006-11-27 17:42:03 +00:00
|
|
|
patm = &(at->NextOfAE);
|
|
|
|
atm = at->NextOfAE;
|
|
|
|
} else {
|
2007-02-18 00:26:36 +00:00
|
|
|
NOfAtoms--;
|
2011-12-22 10:27:56 +00:00
|
|
|
if (IsBlob(atm)) {
|
2015-10-22 00:33:38 +01:00
|
|
|
YAP_BlobPropEntry *b = RepBlobProp(at->PropsOfAE);
|
2011-12-22 10:27:56 +00:00
|
|
|
if (b->NextOfPE != NIL) {
|
|
|
|
patm = &(at->NextOfAE);
|
|
|
|
atm = at->NextOfAE;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
NOfAtoms++;
|
|
|
|
NOfBlobs--;
|
|
|
|
Yap_FreeCodeSpace((char *)b);
|
2015-10-22 00:33:38 +01:00
|
|
|
GLOBAL_agc_collected += sizeof(YAP_BlobPropEntry);
|
2011-12-22 10:27:56 +00:00
|
|
|
GLOBAL_agc_collected += sizeof(AtomEntry)+sizeof(size_t)+at->rep.blob->length;
|
2016-11-02 05:16:36 +00:00
|
|
|
} else {
|
2006-12-13 16:10:26 +00:00
|
|
|
#ifdef DEBUG_RESTORE3
|
2007-02-18 00:26:36 +00:00
|
|
|
fprintf(stderr, "Purged %p:%s patm=%p %p\n", at, at->StrOfAE, patm, at->NextOfAE);
|
2006-12-13 16:10:26 +00:00
|
|
|
#endif
|
2015-09-21 23:05:36 +01:00
|
|
|
GLOBAL_agc_collected += sizeof(AtomEntry)+strlen((const char *)at->StrOfAE);
|
2006-12-13 16:10:26 +00:00
|
|
|
}
|
2007-02-18 00:26:36 +00:00
|
|
|
*patm = atm = at->NextOfAE;
|
2006-11-27 17:42:03 +00:00
|
|
|
Yap_FreeCodeSpace((char *)at);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-06-04 19:21:55 +01:00
|
|
|
/*
|
|
|
|
* This is the really tough part, to restore the whole of the heap
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
clean_atoms(void)
|
|
|
|
{
|
|
|
|
AtomHashEntry *HashPtr = HashChain;
|
|
|
|
register int i;
|
|
|
|
|
2007-02-18 00:26:36 +00:00
|
|
|
AtomResetMark(AtomFoundVar);
|
|
|
|
AtomResetMark(AtomFreeTerm);
|
2003-10-28 01:16:03 +00:00
|
|
|
for (i = 0; i < AtomHashTableSize; ++i) {
|
2007-02-18 00:26:36 +00:00
|
|
|
clean_atom_list(HashPtr);
|
2006-11-27 17:42:03 +00:00
|
|
|
HashPtr++;
|
|
|
|
}
|
2007-02-18 00:26:36 +00:00
|
|
|
clean_atom_list(&INVISIBLECHAIN);
|
2011-03-19 15:26:11 +00:00
|
|
|
{
|
|
|
|
AtomHashEntry list;
|
2015-06-18 00:12:59 +01:00
|
|
|
list.Entry = Blobs;
|
2011-03-19 15:26:11 +00:00
|
|
|
clean_atom_list(&list);
|
|
|
|
}
|
2002-06-04 19:21:55 +01:00
|
|
|
}
|
|
|
|
|
2002-11-11 17:38:10 +00:00
|
|
|
static void
|
2011-03-07 16:02:55 +00:00
|
|
|
atom_gc(USES_REGS1)
|
2002-06-04 19:21:55 +01:00
|
|
|
{
|
2016-07-31 04:36:40 +01:00
|
|
|
bool gc_verbose = Yap_is_gc_verbose();
|
|
|
|
bool gc_trace = false;
|
2002-06-05 04:59:50 +01:00
|
|
|
|
|
|
|
|
2004-03-02 16:44:58 +00:00
|
|
|
UInt time_start, agc_time;
|
2008-01-23 17:57:56 +00:00
|
|
|
#if defined(YAPOR) || defined(THREADS)
|
2007-03-21 18:32:50 +00:00
|
|
|
return;
|
2008-01-23 17:57:56 +00:00
|
|
|
#endif
|
2016-07-31 04:36:40 +01:00
|
|
|
|
2002-11-18 18:18:05 +00:00
|
|
|
if (Yap_GetValue(AtomGcTrace) != TermNil)
|
2016-07-31 04:36:40 +01:00
|
|
|
gc_trace = true;
|
2008-01-23 17:57:56 +00:00
|
|
|
|
2011-05-25 16:40:36 +01:00
|
|
|
GLOBAL_agc_calls++;
|
|
|
|
GLOBAL_agc_collected = 0;
|
2007-02-18 00:26:36 +00:00
|
|
|
|
2002-06-05 04:59:50 +01:00
|
|
|
if (gc_trace) {
|
2014-03-06 02:09:48 +00:00
|
|
|
fprintf(stderr, "%% agc:\n");
|
2002-06-05 04:59:50 +01:00
|
|
|
} else if (gc_verbose) {
|
2014-03-06 02:09:48 +00:00
|
|
|
fprintf(stderr, "%% Start of atom garbage collection %d:\n", GLOBAL_agc_calls);
|
2002-06-05 04:59:50 +01:00
|
|
|
}
|
2002-11-18 18:18:05 +00:00
|
|
|
time_start = Yap_cputime();
|
2002-06-05 04:59:50 +01:00
|
|
|
/* get the number of active registers */
|
|
|
|
YAPEnterCriticalSection();
|
2011-03-07 16:02:55 +00:00
|
|
|
init_reg_copies(PASS_REGS1);
|
|
|
|
mark_stacks(PASS_REGS1);
|
2009-10-30 23:59:00 +00:00
|
|
|
restore_codes();
|
2002-06-04 19:21:55 +01:00
|
|
|
clean_atoms();
|
2011-12-22 10:27:56 +00:00
|
|
|
NOfBlobsMax = NOfBlobs+(NOfBlobs/2+256< 1024 ? NOfBlobs/2+256 : 1024);
|
2002-06-05 04:59:50 +01:00
|
|
|
YAPLeaveCriticalSection();
|
2002-11-18 18:18:05 +00:00
|
|
|
agc_time = Yap_cputime()-time_start;
|
2011-05-25 16:40:36 +01:00
|
|
|
GLOBAL_tot_agc_time += agc_time;
|
|
|
|
GLOBAL_tot_agc_recovered += GLOBAL_agc_collected;
|
2002-06-05 04:59:50 +01:00
|
|
|
if (gc_verbose) {
|
2010-02-10 09:03:03 +00:00
|
|
|
#ifdef _WIN32
|
2014-03-06 02:09:48 +00:00
|
|
|
fprintf(stderr, "%% Collected %I64d bytes.\n", GLOBAL_agc_collected);
|
2010-02-10 09:03:03 +00:00
|
|
|
#else
|
2014-03-06 02:09:48 +00:00
|
|
|
fprintf(stderr, "%% Collected %lld bytes.\n", GLOBAL_agc_collected);
|
2010-02-10 09:03:03 +00:00
|
|
|
#endif
|
2014-03-06 02:09:48 +00:00
|
|
|
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);
|
2002-06-05 04:59:50 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-11-11 17:38:10 +00:00
|
|
|
void
|
2011-03-07 16:02:55 +00:00
|
|
|
Yap_atom_gc(USES_REGS1)
|
2002-11-11 17:38:10 +00:00
|
|
|
{
|
2011-03-07 16:02:55 +00:00
|
|
|
atom_gc(PASS_REGS1);
|
2002-11-11 17:38:10 +00:00
|
|
|
}
|
|
|
|
|
2002-06-05 04:59:50 +01:00
|
|
|
static Int
|
2011-03-07 16:02:55 +00:00
|
|
|
p_atom_gc(USES_REGS1)
|
2002-06-05 04:59:50 +01:00
|
|
|
{
|
|
|
|
#ifndef FIXED_STACKS
|
2011-03-07 16:02:55 +00:00
|
|
|
atom_gc(PASS_REGS1);
|
2002-06-05 04:59:50 +01:00
|
|
|
#endif /* FIXED_STACKS */
|
2005-05-31 20:42:28 +01:00
|
|
|
return TRUE;
|
2002-06-05 04:59:50 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static Int
|
2011-03-07 16:02:55 +00:00
|
|
|
p_inform_agc(USES_REGS1)
|
2002-06-05 04:59:50 +01:00
|
|
|
{
|
2011-05-25 16:40:36 +01:00
|
|
|
Term tn = MkIntegerTerm(GLOBAL_tot_agc_time);
|
|
|
|
Term tt = MkIntegerTerm(GLOBAL_agc_calls);
|
|
|
|
Term ts = MkIntegerTerm(GLOBAL_tot_agc_recovered);
|
2002-06-05 04:59:50 +01:00
|
|
|
|
2010-03-22 14:47:53 +00:00
|
|
|
return
|
|
|
|
Yap_unify(tn, ARG2) &&
|
|
|
|
Yap_unify(tt, ARG1) &&
|
|
|
|
Yap_unify(ts, ARG3);
|
2002-06-05 04:59:50 +01:00
|
|
|
}
|
|
|
|
|
2007-02-18 00:26:36 +00:00
|
|
|
|
2002-06-05 04:59:50 +01:00
|
|
|
void
|
2002-11-18 18:18:05 +00:00
|
|
|
Yap_init_agc(void)
|
2002-06-05 04:59:50 +01:00
|
|
|
{
|
2012-10-19 18:10:48 +01:00
|
|
|
Yap_InitCPred("$atom_gc", 0, p_atom_gc, 0);
|
|
|
|
Yap_InitCPred("$inform_agc", 3, p_inform_agc, 0);
|
2002-06-04 19:21:55 +01:00
|
|
|
}
|