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 ) ;
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)
# 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()
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
{
UInt i ;
for ( i = 0 ; i < PredHashTableSize ; i + + ) {
PredEntry * p = PredHash [ i ] ;
if ( p )
p = PredEntryAdjust ( p ) ;
while ( p ) {
Prop nextp ;
if ( p - > NextOfPE )
p - > NextOfPE = PropAdjust ( p - > NextOfPE ) ;
nextp = p - > NextOfPE ;
2011-03-07 16:02:55 +00:00
CleanCode ( p PASS_REGS ) ;
2010-04-09 11:46:59 +01:00
p = RepPredProp ( nextp ) ;
}
}
}
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 ) ;
2011-12-13 10:41:05 +00:00
Opaque_CallOnGCMark f ;
2011-12-13 18:14:33 +00:00
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 ) {
Yap_Error ( OUT_OF_HEAP_ERROR , TermNil , " not enough space for slot internal variables in agc " ) ;
}
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 )
Yap_Error ( OUT_OF_HEAP_ERROR , TermNil , " bad restore of slot internal variables in agc " ) ;
}
}
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 ) ) {
BlobPropEntry * b = RepBlobProp ( at - > PropsOfAE ) ;
if ( b - > NextOfPE ! = NIL ) {
patm = & ( at - > NextOfAE ) ;
atm = at - > NextOfAE ;
continue ;
}
NOfAtoms + + ;
NOfBlobs - - ;
Yap_FreeCodeSpace ( ( char * ) b ) ;
GLOBAL_agc_collected + = sizeof ( BlobPropEntry ) ;
GLOBAL_agc_collected + = sizeof ( AtomEntry ) + sizeof ( size_t ) + at - > rep . blob - > length ;
} else if ( IsWideAtom ( atm ) ) {
2006-11-27 17:42:03 +00:00
# ifdef DEBUG_RESTORE3
2009-09-12 22:43:18 +01:00
fprintf ( stderr , " Purged %p:%S \n " , at , at - > WStrOfAE ) ;
2006-11-27 17:42:03 +00:00
# endif
2011-05-25 16:40:36 +01:00
GLOBAL_agc_collected + = sizeof ( AtomEntry ) + wcslen ( at - > WStrOfAE ) ;
2006-12-13 16:10:26 +00:00
} else {
# 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
2011-05-25 16:40:36 +01:00
GLOBAL_agc_collected + = sizeof ( AtomEntry ) + strlen ( 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
HashPtr = WideHashChain ;
2006-11-27 17:42:03 +00:00
for ( i = 0 ; i < WideAtomHashTableSize ; + + i ) {
2007-02-18 00:26:36 +00:00
clean_atom_list ( HashPtr ) ;
2002-06-04 19:21:55 +01:00
HashPtr + + ;
}
2007-02-18 00:26:36 +00:00
clean_atom_list ( & INVISIBLECHAIN ) ;
2011-03-19 15:26:11 +00:00
{
AtomHashEntry list ;
list . Entry = SWI_Blobs ;
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
{
2002-11-18 18:18:05 +00:00
int gc_verbose = Yap_is_gc_verbose ( ) ;
2002-06-05 04:59:50 +01:00
int gc_trace = 0 ;
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
2002-11-18 18:18:05 +00:00
if ( Yap_GetValue ( AtomGcTrace ) ! = TermNil )
2002-06-05 04:59:50 +01:00
gc_trace = 1 ;
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 ) {
2011-05-25 16:40:36 +01:00
fprintf ( GLOBAL_stderr , " %% agc: \n " ) ;
2002-06-05 04:59:50 +01:00
} else if ( gc_verbose ) {
2011-05-25 16:40:36 +01:00
fprintf ( GLOBAL_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
2011-05-25 16:40:36 +01:00
fprintf ( GLOBAL_stderr , " %% Collected %I64d bytes. \n " , GLOBAL_agc_collected ) ;
2010-02-10 09:03:03 +00:00
# else
2011-05-25 16:40:36 +01:00
fprintf ( GLOBAL_stderr , " %% Collected %lld bytes. \n " , GLOBAL_agc_collected ) ;
2010-02-10 09:03:03 +00:00
# endif
2011-05-25 16:40:36 +01:00
fprintf ( GLOBAL_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
static Int
2011-03-07 16:02:55 +00:00
p_agc_threshold ( USES_REGS1 )
2007-02-18 00:26:36 +00:00
{
Term t = Deref ( ARG1 ) ;
if ( IsVarTerm ( t ) ) {
2011-05-10 10:06:51 +01:00
return Yap_unify ( ARG1 , MkIntegerTerm ( GLOBAL_AGcThreshold ) ) ;
2007-02-18 00:26:36 +00:00
} else if ( ! IsIntegerTerm ( t ) ) {
Yap_Error ( TYPE_ERROR_INTEGER , t , " prolog_flag/2 agc_margin " ) ;
return FALSE ;
} else {
Int i = IntegerOfTerm ( t ) ;
if ( i < 0 ) {
Yap_Error ( DOMAIN_ERROR_NOT_LESS_THAN_ZERO , t , " prolog_flag/2 agc_margin " ) ;
return FALSE ;
} else {
2011-05-10 10:06:51 +01:00
GLOBAL_AGcThreshold = i ;
2007-02-18 00:26:36 +00:00
return TRUE ;
}
}
}
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 ) ;
Yap_InitCPred ( " $agc_threshold " , 1 , p_agc_threshold , SafePredFlag ) ;
2002-06-04 19:21:55 +01:00
}