1636 lines
43 KiB
C
1636 lines
43 KiB
C
/*************************************************************************
|
|
* *
|
|
* YAP Prolog *
|
|
* *
|
|
* Yap Prolog was developed at NCCUP - Universidade do Porto *
|
|
* *
|
|
* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 *
|
|
* *
|
|
**************************************************************************
|
|
* *
|
|
* File: rheap.h *
|
|
* comments: walk through heap code *
|
|
* *
|
|
* Last rev: $Date: 2008-08-07 20:51:23 $,$Author: vsc $ *
|
|
* $Log: not supported by cvs2svn $
|
|
* Revision 1.99 2008/07/22 23:34:49 vsc
|
|
* SWI and module fixes
|
|
*
|
|
* Revision 1.98 2008/05/12 22:31:37 vsc
|
|
* fix previous fixes
|
|
*
|
|
* Revision 1.97 2008/05/12 14:04:23 vsc
|
|
* updates to restore
|
|
*
|
|
* Revision 1.96 2008/04/11 16:58:17 ricroc
|
|
* yapor: seq_def initialization
|
|
*
|
|
* Revision 1.95 2008/04/06 12:06:48 vsc
|
|
* more small fixes
|
|
*
|
|
* Revision 1.94 2008/04/06 11:53:02 vsc
|
|
* fix some restore bugs
|
|
*
|
|
* Revision 1.93 2008/04/04 09:10:02 vsc
|
|
* restore was restoring twice
|
|
*
|
|
* Revision 1.92 2008/04/03 11:34:47 vsc
|
|
* fix restorebb in cases entry key is not an atom (obs from Nicos
|
|
* Angelopoulos)
|
|
*
|
|
* Revision 1.91 2008/04/01 15:31:43 vsc
|
|
* more saved state fixes
|
|
*
|
|
* Revision 1.90 2008/04/01 14:09:43 vsc
|
|
* improve restore
|
|
*
|
|
* Revision 1.89 2008/04/01 09:41:05 vsc
|
|
* more fixes to restore
|
|
*
|
|
* Revision 1.88 2008/04/01 08:42:46 vsc
|
|
* fix restore and small VISTA thingies
|
|
*
|
|
* Revision 1.87 2008/03/25 22:03:14 vsc
|
|
* fix some icc warnings
|
|
*
|
|
* Revision 1.86 2008/03/25 16:45:53 vsc
|
|
* make or-parallelism compile again
|
|
*
|
|
* Revision 1.85 2008/02/12 17:03:52 vsc
|
|
* SWI-portability changes
|
|
*
|
|
* Revision 1.84 2008/02/07 21:39:51 vsc
|
|
* fix case where predicate is for an integer (DBEntry).
|
|
*
|
|
* Revision 1.83 2008/01/23 17:57:55 vsc
|
|
* valgrind it!
|
|
* enable atom garbage collection.
|
|
*
|
|
* Revision 1.82 2007/12/05 12:17:23 vsc
|
|
* improve JT
|
|
* fix graph compatibility with SICStus
|
|
* re-export declaration.
|
|
*
|
|
* Revision 1.81 2007/11/26 23:43:09 vsc
|
|
* fixes to support threads and assert correctly, even if inefficiently.
|
|
*
|
|
* Revision 1.80 2007/11/07 09:35:53 vsc
|
|
* small fix
|
|
*
|
|
* Revision 1.79 2007/11/07 09:25:27 vsc
|
|
* speedup meta-calls
|
|
*
|
|
* Revision 1.78 2007/11/06 17:02:12 vsc
|
|
* compile ground terms away.
|
|
*
|
|
* Revision 1.77 2007/10/10 09:44:24 vsc
|
|
* some more fixes to make YAP swi compatible
|
|
* fix absolute_file_name (again)
|
|
* fix setarg
|
|
*
|
|
* Revision 1.76 2007/09/28 23:18:17 vsc
|
|
* handle learning from interpretations.
|
|
*
|
|
* Revision 1.75 2007/04/10 22:13:21 vsc
|
|
* fix max modules limitation
|
|
*
|
|
* Revision 1.74 2007/03/22 11:12:21 vsc
|
|
* make sure that YAP_Restart does not restart a failed goal.
|
|
*
|
|
* Revision 1.73 2007/02/18 00:26:36 vsc
|
|
* fix atom garbage collector (although it is still off by default)
|
|
* make valgrind feel better
|
|
*
|
|
* Revision 1.72 2007/01/08 08:27:19 vsc
|
|
* fix restore (Trevor)
|
|
* make indexing a bit faster on IDB
|
|
*
|
|
* Revision 1.71 2006/11/27 17:42:03 vsc
|
|
* support for UNICODE, and other bug fixes.
|
|
*
|
|
* Revision 1.70 2006/08/25 19:50:35 vsc
|
|
* global data structures
|
|
*
|
|
* Revision 1.69 2006/08/22 16:12:46 vsc
|
|
* global variables
|
|
*
|
|
* Revision 1.68 2006/08/02 18:18:30 vsc
|
|
* preliminary support for readutil library (SWI compatible).
|
|
*
|
|
* Revision 1.67 2006/05/17 18:38:11 vsc
|
|
* make system library use true file name
|
|
*
|
|
* Revision 1.66 2006/04/28 15:48:33 vsc
|
|
* do locking on streams
|
|
*
|
|
* Revision 1.65 2006/04/28 13:23:23 vsc
|
|
* fix number of overflow bugs affecting threaded version
|
|
* make current_op faster.
|
|
*
|
|
* Revision 1.64 2006/03/22 20:07:28 vsc
|
|
* take better care of zombies
|
|
*
|
|
* Revision 1.63 2006/03/06 14:04:56 vsc
|
|
* fixes to garbage collector
|
|
* fixes to debugger
|
|
*
|
|
* Revision 1.62 2006/02/24 14:03:42 vsc
|
|
* fix refs to old LogUpd implementation (pre 5).
|
|
*
|
|
* Revision 1.61 2006/01/02 02:16:18 vsc
|
|
* support new interface between YAP and GMP, so that we don't rely on our own
|
|
* allocation routines.
|
|
* Several big fixes.
|
|
*
|
|
* Revision 1.60 2005/12/17 03:25:39 vsc
|
|
* major changes to support online event-based profiling
|
|
* improve error discovery and restart on scanner.
|
|
*
|
|
* Revision 1.59 2005/12/05 17:16:11 vsc
|
|
* write_depth/3
|
|
* overflow handlings and garbage collection
|
|
* Several ipdates to CLPBN
|
|
* dif/2 could be broken in the presence of attributed variables.
|
|
*
|
|
* Revision 1.58 2005/11/23 03:01:33 vsc
|
|
* fix several bugs in save/restore.b
|
|
*
|
|
* Revision 1.57 2005/10/28 17:38:50 vsc
|
|
* sveral updates
|
|
*
|
|
* Revision 1.56 2005/10/21 16:09:03 vsc
|
|
* SWI compatible module only operators
|
|
*
|
|
* Revision 1.55 2005/10/19 19:00:48 vsc
|
|
* extend arrays with nb_terms so that we can implement nb_ builtins
|
|
* correctly.
|
|
*
|
|
* Revision 1.54 2005/09/09 17:24:39 vsc
|
|
* a new and hopefully much better implementation of atts.
|
|
*
|
|
* Revision 1.53 2005/08/01 15:40:38 ricroc
|
|
* TABLING NEW: better support for incomplete tabling
|
|
*
|
|
* Revision 1.52 2005/07/06 19:34:11 ricroc
|
|
* TABLING: answers for completed calls can now be obtained by loading (new option) or executing (default) them from the trie data structure.
|
|
*
|
|
* Revision 1.51 2005/07/06 15:10:15 vsc
|
|
* improvements to compiler: merged instructions and fixes for ->
|
|
*
|
|
* Revision 1.50 2005/06/01 13:53:46 vsc
|
|
* improve bb routines to use the DB efficiently
|
|
* change interface between DB and BB.
|
|
*
|
|
* Revision 1.49 2005/05/30 03:26:37 vsc
|
|
* add some atom gc fixes
|
|
*
|
|
* Revision 1.48 2005/01/04 02:50:21 vsc
|
|
* - allow MegaClauses with blobs
|
|
* - change Diffs to be thread specific
|
|
* - include Christian's updates
|
|
*
|
|
* Revision 1.47 2004/12/02 06:06:47 vsc
|
|
* fix threads so that they at least start
|
|
* allow error handling to work with threads
|
|
* replace heap_base by Yap_heap_base, according to Yap's convention for globals.
|
|
*
|
|
* Revision 1.46 2004/11/23 21:16:21 vsc
|
|
* A few extra fixes for saved states.
|
|
*
|
|
* Revision 1.45 2004/10/26 20:16:18 vsc
|
|
* More bug fixes for overflow handling
|
|
*
|
|
* Revision 1.44 2004/10/06 16:55:47 vsc
|
|
* change configure to support big mem configs
|
|
* get rid of extra globals
|
|
* fix trouble with multifile preds
|
|
*
|
|
* Revision 1.43 2004/09/27 20:45:04 vsc
|
|
* Mega clauses
|
|
* Fixes to sizeof(expand_clauses) which was being overestimated
|
|
* Fixes to profiling+indexing
|
|
* Fixes to reallocation of memory after restoring
|
|
* Make sure all clauses, even for C, end in _Ystop
|
|
* Don't reuse space for Streams
|
|
* Fix Stream_F on StreaNo+1
|
|
*
|
|
* Revision 1.42 2004/06/05 03:37:00 vsc
|
|
* coroutining is now a part of attvars.
|
|
* some more fixes.
|
|
*
|
|
* Revision 1.41 2004/04/29 03:45:50 vsc
|
|
* fix garbage collection in execute_tail
|
|
*
|
|
* Revision 1.40 2004/03/31 01:03:10 vsc
|
|
* support expand group of clauses
|
|
*
|
|
* Revision 1.39 2004/03/19 11:35:42 vsc
|
|
* trim_trail for default machine
|
|
* be more aggressive about try-retry-trust chains.
|
|
* - handle cases where block starts with a wait
|
|
* - don't use _killed instructions, just let the thing rot by itself.
|
|
* *
|
|
* *
|
|
*************************************************************************/
|
|
#ifdef SCCS
|
|
static char SccsId[] = "@(#)rheap.c 1.3 3/15/90";
|
|
#endif
|
|
|
|
#define Atomics 0
|
|
#define Funcs 1
|
|
|
|
#define ConstantTermAdjust(P) ConstantTermAdjust__(P PASS_REGS)
|
|
#define DBGroundTermAdjust(P) DBGroundTermAdjust__(P PASS_REGS)
|
|
#define AdjustDBTerm(P,A,B,C) AdjustDBTerm__(P,A,B,C PASS_REGS)
|
|
#define AdjustSwitchTable(op, table, i) AdjustSwitchTable__(op, table, i PASS_REGS)
|
|
#define RestoreOtaplInst(start, opc, pe) RestoreOtaplInst__(start, opc, pe PASS_REGS)
|
|
#define RestoreDBErasedMarker() RestoreDBErasedMarker__( PASS_REGS1 )
|
|
#define RestoreLogDBErasedMarker() RestoreLogDBErasedMarker__( PASS_REGS1 )
|
|
#define RestoreForeignCode() RestoreForeignCode__( PASS_REGS1 )
|
|
#define RestoreAtoms() RestoreAtoms__( PASS_REGS1 )
|
|
#define RestoreWideAtoms() RestoreWideAtoms__( PASS_REGS1 )
|
|
#define RestoreSWIBlobs() RestoreSWIBlobs__( PASS_REGS1 )
|
|
#define RestoreSWIBlobTypes() RestoreSWIBlobTypes__( PASS_REGS1 )
|
|
#define RestoreInvisibleAtoms() RestoreInvisibleAtoms__( PASS_REGS1 )
|
|
#define RestorePredHash() RestorePredHash__( PASS_REGS1 )
|
|
#define RestoreHiddenPredicates() RestoreHiddenPredicates__( PASS_REGS1 )
|
|
#define RestoreDBTermsList() RestoreDBTermsList__( PASS_REGS1 )
|
|
#define RestoreExpandList() RestoreExpandList__( PASS_REGS1 )
|
|
#define RestoreIntKeys() RestoreIntKeys__( PASS_REGS1 )
|
|
#define RestoreIntLUKeys() RestoreIntLUKeys__( PASS_REGS1 )
|
|
#define RestoreIntBBKeys() RestoreIntBBKeys__( PASS_REGS1 )
|
|
#define RestoreDeadStaticClauses() RestoreDeadStaticClauses__( PASS_REGS1 )
|
|
#define RestoreDeadMegaClauses() RestoreDeadMegaClauses__( PASS_REGS1 )
|
|
#define RestoreDeadStaticIndices() RestoreDeadStaticIndices__( PASS_REGS1 )
|
|
#define RestoreDBErasedList() RestoreDBErasedList__( PASS_REGS1 )
|
|
#define RestoreDBErasedIList() RestoreDBErasedIList__( PASS_REGS1 )
|
|
#define RestoreYapRecords() RestoreYapRecords__( PASS_REGS1 )
|
|
#define RestoreSWIAtoms() RestoreSWIAtoms__( PASS_REGS1 )
|
|
static Term
|
|
ConstantTermAdjust__ (Term t USES_REGS)
|
|
{
|
|
if (IsAtomTerm(t))
|
|
return AtomTermAdjust(t);
|
|
return t;
|
|
}
|
|
|
|
static Term
|
|
DBGroundTermAdjust__ (Term t USES_REGS)
|
|
{
|
|
/* The term itself is restored by dbtermlist */
|
|
if (IsPairTerm(t)) {
|
|
return AbsPair(PtoHeapCellAdjust(RepPair(t)));
|
|
} else {
|
|
return AbsAppl(PtoHeapCellAdjust(RepAppl(t)));
|
|
}
|
|
}
|
|
|
|
/* Now, everything on its place so you must adjust the pointers */
|
|
|
|
static void
|
|
do_clean_susp_clauses(yamop *ipc USES_REGS) {
|
|
COUNT i;
|
|
yamop **st = (yamop **)NEXTOP(ipc,sssllp);
|
|
|
|
ipc->opc = Yap_opcode(_expand_clauses);
|
|
ipc->u.sssllp.p = PtoPredAdjust(ipc->u.sssllp.p);
|
|
if (ipc->u.sssllp.sprev) {
|
|
ipc->u.sssllp.sprev = PtoOpAdjust(ipc->u.sssllp.sprev);
|
|
}
|
|
if (ipc->u.sssllp.snext) {
|
|
ipc->u.sssllp.snext = PtoOpAdjust(ipc->u.sssllp.snext);
|
|
}
|
|
for (i = 0; i < ipc->u.sssllp.s1; i++, st++) {
|
|
if (*st) {
|
|
*st = PtoOpAdjust(*st);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
AdjustSwitchTable__(op_numbers op, yamop *table, COUNT i USES_REGS)
|
|
{
|
|
CELL *startcode = (CELL *)table;
|
|
/* in case the table is already gone */
|
|
if (!table)
|
|
return;
|
|
switch (op) {
|
|
case _switch_on_func:
|
|
{
|
|
COUNT j;
|
|
CELL *oldcode;
|
|
|
|
oldcode = startcode;
|
|
for (j = 0; j < i; j++) {
|
|
Functor oldfunc = (Functor)(oldcode[0]);
|
|
CODEADDR oldjmp = (CODEADDR)(oldcode[1]);
|
|
if (oldfunc) {
|
|
oldcode[0] = (CELL)FuncAdjust(oldfunc);
|
|
}
|
|
oldcode[1] = (CELL)CodeAddrAdjust(oldjmp);
|
|
oldcode += 2;
|
|
}
|
|
rehash(startcode, i, Funcs PASS_REGS);
|
|
}
|
|
break;
|
|
case _switch_on_cons:
|
|
{
|
|
COUNT j;
|
|
CELL *oldcode;
|
|
|
|
#if !defined(USE_OFFSETS)
|
|
oldcode = startcode;
|
|
#endif
|
|
for (j = 0; j < i; j++) {
|
|
Term oldcons = oldcode[0];
|
|
CODEADDR oldjmp = (CODEADDR)(oldcode[1]);
|
|
if (oldcons != 0x0 && IsAtomTerm(oldcons)) {
|
|
oldcode[0] = AtomTermAdjust(oldcons);
|
|
}
|
|
oldcode[1] = (CELL)CodeAddrAdjust(oldjmp);
|
|
oldcode += 2;
|
|
}
|
|
#if !USE_OFFSETS
|
|
rehash(startcode, i, Atomics PASS_REGS);
|
|
#endif
|
|
}
|
|
break;
|
|
case _go_on_func:
|
|
{
|
|
Functor oldfunc = (Functor)(startcode[0]);
|
|
|
|
startcode[0] = (CELL)FuncAdjust(oldfunc);
|
|
startcode[1] = (CELL)CodeAddrAdjust((CODEADDR)startcode[1]);
|
|
startcode[3] = (CELL)CodeAddrAdjust((CODEADDR)startcode[3]);
|
|
}
|
|
break;
|
|
case _go_on_cons:
|
|
{
|
|
Term oldcons = startcode[0];
|
|
|
|
if (IsAtomTerm(oldcons)) {
|
|
startcode[0] = AtomTermAdjust(oldcons);
|
|
}
|
|
startcode[1] = (CELL)CodeAddrAdjust((CODEADDR)startcode[1]);
|
|
startcode[3] = (CELL)CodeAddrAdjust((CODEADDR)startcode[3]);
|
|
}
|
|
break;
|
|
case _if_func:
|
|
{
|
|
Int j;
|
|
|
|
for (j = 0; j < i; j++) {
|
|
Functor oldfunc = (Functor)(startcode[0]);
|
|
CODEADDR oldjmp = (CODEADDR)(startcode[1]);
|
|
startcode[0] = (CELL)FuncAdjust(oldfunc);
|
|
startcode[1] = (CELL)CodeAddrAdjust(oldjmp);
|
|
startcode += 2;
|
|
}
|
|
/* adjust fail code */
|
|
startcode[1] = (CELL)CodeAddrAdjust((CODEADDR)startcode[1]);
|
|
}
|
|
break;
|
|
case _if_cons:
|
|
{
|
|
Int j;
|
|
|
|
for (j = 0; j < i; j++) {
|
|
Term oldcons = startcode[0];
|
|
CODEADDR oldjmp = (CODEADDR)(startcode[1]);
|
|
if (IsAtomTerm(oldcons)) {
|
|
startcode[0] = (CELL)AtomTermAdjust(oldcons);
|
|
}
|
|
startcode[1] = (CELL)CodeAddrAdjust(oldjmp);
|
|
startcode += 2;
|
|
}
|
|
/* adjust fail code */
|
|
startcode[1] = (CELL)CodeAddrAdjust((CODEADDR)startcode[1]);
|
|
}
|
|
break;
|
|
default:
|
|
Yap_Error(INTERNAL_ERROR,0L,"Opcode Not Implemented in AdjustSwitchTable");
|
|
}
|
|
}
|
|
|
|
STATIC_PROTO(void RestoreAtomList, (Atom CACHE_TYPE));
|
|
STATIC_PROTO(void RestoreAtom, (AtomEntry * CACHE_TYPE));
|
|
STATIC_PROTO(void RestoreHashPreds, ( CACHE_TYPE1 ));
|
|
|
|
static void
|
|
RestoreAtoms__( USES_REGS1 )
|
|
{
|
|
AtomHashEntry *HashPtr;
|
|
register int i;
|
|
|
|
Yap_heap_regs->hash_chain =
|
|
PtoAtomHashEntryAdjust(Yap_heap_regs->hash_chain);
|
|
HashPtr = HashChain;
|
|
for (i = 0; i < AtomHashTableSize; ++i) {
|
|
HashPtr->Entry = NoAGCAtomAdjust(HashPtr->Entry);
|
|
RestoreAtomList(HashPtr->Entry PASS_REGS);
|
|
HashPtr++;
|
|
}
|
|
}
|
|
|
|
static void
|
|
RestoreWideAtoms__( USES_REGS1 )
|
|
{
|
|
AtomHashEntry *HashPtr;
|
|
register int i;
|
|
|
|
Yap_heap_regs->wide_hash_chain =
|
|
PtoAtomHashEntryAdjust(Yap_heap_regs->wide_hash_chain);
|
|
HashPtr = WideHashChain;
|
|
for (i = 0; i < WideAtomHashTableSize; ++i) {
|
|
HashPtr->Entry = AtomAdjust(HashPtr->Entry);
|
|
RestoreAtomList(HashPtr->Entry PASS_REGS);
|
|
HashPtr++;
|
|
}
|
|
}
|
|
|
|
static void
|
|
RestoreInvisibleAtoms__( USES_REGS1 )
|
|
{
|
|
INVISIBLECHAIN.Entry = AtomAdjust(INVISIBLECHAIN.Entry);
|
|
RestoreAtomList(INVISIBLECHAIN.Entry PASS_REGS);
|
|
RestoreAtom(RepAtom(AtomFoundVar) PASS_REGS);
|
|
RestoreAtom(RepAtom(AtomFreeTerm) PASS_REGS);
|
|
}
|
|
|
|
#include "rclause.h"
|
|
|
|
/* adjusts terms stored in the data base, when they have no variables */
|
|
static Term
|
|
AdjustDBTerm__(Term trm, Term *p_base, Term *p_lim, Term *p_max USES_REGS)
|
|
{
|
|
if (IsVarTerm(trm))
|
|
return CodeVarAdjust(trm);
|
|
if (IsAtomTerm(trm))
|
|
return AtomTermAdjust(trm);
|
|
if (IsPairTerm(trm)) {
|
|
Term *p;
|
|
Term out;
|
|
|
|
p = PtoHeapCellAdjust(RepPair(trm));
|
|
out = AbsPair(p);
|
|
loop:
|
|
if (p >= p_base || p < p_lim) {
|
|
p[0] = AdjustDBTerm(p[0], p, p_lim, p_max);
|
|
if (IsPairTerm(p[1])) {
|
|
/* avoid term recursion with very deep lists */
|
|
Term *newp = PtoHeapCellAdjust(RepPair(p[1]));
|
|
p[1] = AbsPair(newp);
|
|
p_base = p;
|
|
p = newp;
|
|
goto loop;
|
|
} else {
|
|
p[1] = AdjustDBTerm(p[1], p, p_lim, p_max);
|
|
}
|
|
}
|
|
return out;
|
|
}
|
|
if (IsApplTerm(trm)) {
|
|
Term *p;
|
|
Functor f;
|
|
Term *p0 = p = PtoHeapCellAdjust(RepAppl(trm));
|
|
/* if it is before the current position, then we are looking
|
|
at old code */
|
|
if (p >= p_base || p < p_lim) {
|
|
if (p >= p_max || p < p_lim) {
|
|
if (DBRefOfTerm(trm)!=DBRefAdjust(DBRefOfTerm(trm),FALSE))
|
|
/* external term pointer, has to be a DBRef */
|
|
return MkDBRefTerm(DBRefAdjust(DBRefOfTerm(trm),FALSE));
|
|
}
|
|
f = (Functor)p[0];
|
|
if (!IsExtensionFunctor(f)) {
|
|
UInt Arity, i;
|
|
|
|
f = FuncAdjust(f);
|
|
*p++ = (Term)f;
|
|
Arity = ArityOfFunctor(f);
|
|
for (i = 0; i < Arity; ++i) {
|
|
*p = AdjustDBTerm(*p, p0, p_lim, p_max);
|
|
p++;
|
|
}
|
|
} else if (f == FunctorDBRef) {
|
|
}
|
|
}
|
|
return AbsAppl(p0);
|
|
}
|
|
return trm;
|
|
}
|
|
|
|
static void
|
|
RestoreDBTerm(DBTerm *dbr, int attachments USES_REGS)
|
|
{
|
|
if (attachments) {
|
|
#ifdef COROUTINING
|
|
if (dbr->ag.attachments)
|
|
dbr->ag.attachments = AdjustDBTerm(dbr->ag.attachments, dbr->Contents, dbr->Contents, dbr->Contents+dbr->NOfCells);
|
|
#endif
|
|
} else {
|
|
if (dbr->ag.NextDBT)
|
|
dbr->ag.NextDBT = DBTermAdjust(dbr->ag.NextDBT);
|
|
}
|
|
if (dbr->DBRefs) {
|
|
DBRef *cp;
|
|
DBRef tm;
|
|
|
|
dbr->DBRefs = DBRefPAdjust(dbr->DBRefs);
|
|
cp = dbr->DBRefs;
|
|
while ((tm = *--cp) != 0) {
|
|
*cp = DBRefAdjust(tm,TRUE);
|
|
}
|
|
}
|
|
dbr->Entry = AdjustDBTerm(dbr->Entry, dbr->Contents, dbr->Contents, dbr->Contents+dbr->NOfCells);
|
|
}
|
|
|
|
/* Restoring the heap */
|
|
|
|
/* Restores a prolog clause, in its compiled form */
|
|
static void
|
|
RestoreStaticClause(StaticClause *cl USES_REGS)
|
|
/*
|
|
* Cl points to the start of the code, IsolFlag tells if we have a single
|
|
* clause for this predicate or not
|
|
*/
|
|
{
|
|
if (cl->usc.ClSource) {
|
|
char *x = (char *)DBTermAdjust(cl->usc.ClSource);
|
|
char *base = (char *)cl;
|
|
|
|
if (x < base || x >= base+cl->ClSize) {
|
|
cl->usc.ClPred = PtoPredAdjust(cl->usc.ClPred);
|
|
} else {
|
|
cl->usc.ClSource = DBTermAdjust(cl->usc.ClSource);
|
|
RestoreDBTerm(cl->usc.ClSource, TRUE PASS_REGS);
|
|
}
|
|
}
|
|
if (cl->ClNext) {
|
|
cl->ClNext = PtoStCAdjust(cl->ClNext);
|
|
}
|
|
restore_opcodes(cl->ClCode, NULL PASS_REGS);
|
|
}
|
|
|
|
/* Restores a prolog clause, in its compiled form */
|
|
static void
|
|
RestoreMegaClause(MegaClause *cl USES_REGS)
|
|
/*
|
|
* Cl points to the start of the code, IsolFlag tells if we have a single
|
|
* clause for this predicate or not
|
|
*/
|
|
{
|
|
yamop *ptr, *max, *nextptr;
|
|
|
|
cl->ClPred = PtoPredAdjust(cl->ClPred);
|
|
if (cl->ClNext) {
|
|
cl->ClNext = (MegaClause *)AddrAdjust((ADDR)(cl->ClNext));
|
|
}
|
|
max = (yamop *)((CODEADDR)cl+cl->ClSize);
|
|
|
|
for (ptr = cl->ClCode; ptr < max; ) {
|
|
nextptr = (yamop *)((char *)ptr + cl->ClItemSize);
|
|
restore_opcodes(ptr, nextptr PASS_REGS);
|
|
ptr = nextptr;
|
|
}
|
|
}
|
|
|
|
/* Restores a prolog clause, in its compiled form */
|
|
static void
|
|
RestoreDynamicClause(DynamicClause *cl, PredEntry *pp USES_REGS)
|
|
/*
|
|
* Cl points to the start of the code, IsolFlag tells if we have a single
|
|
* clause for this predicate or not
|
|
*/
|
|
{
|
|
if (cl->ClPrevious != NULL) {
|
|
cl->ClPrevious = PtoOpAdjust(cl->ClPrevious);
|
|
}
|
|
INIT_LOCK(cl->ClLock);
|
|
restore_opcodes(cl->ClCode, NULL PASS_REGS);
|
|
}
|
|
|
|
/* Restores a prolog clause, in its compiled form */
|
|
static void
|
|
RestoreLUClause(LogUpdClause *cl, PredEntry *pp USES_REGS)
|
|
/*
|
|
* Cl points to the start of the code, IsolFlag tells if we have a single
|
|
* clause for this predicate or not
|
|
*/
|
|
{
|
|
// INIT_LOCK(cl->ClLock);
|
|
if (cl->ClFlags & LogUpdRuleMask) {
|
|
cl->ClExt = PtoOpAdjust(cl->ClExt);
|
|
}
|
|
if (cl->ClSource) {
|
|
cl->ClSource = DBTermAdjust(cl->ClSource);
|
|
RestoreDBTerm(cl->ClSource, TRUE PASS_REGS);
|
|
}
|
|
if (cl->ClPrev) {
|
|
cl->ClPrev = PtoLUCAdjust(cl->ClPrev);
|
|
}
|
|
if (cl->ClNext) {
|
|
cl->ClNext = PtoLUCAdjust(cl->ClNext);
|
|
}
|
|
cl->ClPred = PtoPredAdjust(cl->ClPred);
|
|
restore_opcodes(cl->ClCode, NULL PASS_REGS);
|
|
}
|
|
|
|
static void
|
|
RestoreDBTermEntry(struct dbterm_list *dbl USES_REGS) {
|
|
DBTerm *dbt;
|
|
|
|
if (dbl->dbterms)
|
|
dbt = dbl->dbterms = DBTermAdjust(dbl->dbterms);
|
|
else
|
|
return;
|
|
dbl->clause_code = PtoOpAdjust(dbl->clause_code);
|
|
if (dbl->next_dbl)
|
|
dbl->next_dbl = PtoDBTLAdjust(dbl->next_dbl);
|
|
dbl->p = PredEntryAdjust(dbl->p);
|
|
while (dbt) {
|
|
RestoreDBTerm(dbt, FALSE PASS_REGS);
|
|
dbt = dbt->ag.NextDBT;
|
|
}
|
|
}
|
|
|
|
static void
|
|
CleanLUIndex(LogUpdIndex *idx, int recurse USES_REGS)
|
|
{
|
|
// INIT_LOCK(idx->ClLock);
|
|
idx->ClPred = PtoPredAdjust(idx->ClPred);
|
|
if (idx->ParentIndex)
|
|
idx->ParentIndex = LUIndexAdjust(idx->ParentIndex);
|
|
if (idx->PrevSiblingIndex) {
|
|
idx->PrevSiblingIndex = LUIndexAdjust(idx->PrevSiblingIndex);
|
|
}
|
|
if (idx->SiblingIndex) {
|
|
idx->SiblingIndex = LUIndexAdjust(idx->SiblingIndex);
|
|
if (recurse)
|
|
CleanLUIndex(idx->SiblingIndex, TRUE PASS_REGS);
|
|
}
|
|
if (idx->ChildIndex) {
|
|
idx->ChildIndex = LUIndexAdjust(idx->ChildIndex);
|
|
if (recurse)
|
|
CleanLUIndex(idx->ChildIndex, TRUE PASS_REGS);
|
|
}
|
|
if (!(idx->ClFlags & SwitchTableMask)) {
|
|
restore_opcodes(idx->ClCode, NULL PASS_REGS);
|
|
}
|
|
}
|
|
|
|
static void
|
|
CleanSIndex(StaticIndex *idx, int recurse USES_REGS)
|
|
{
|
|
beginning:
|
|
if (!(idx->ClFlags & SwitchTableMask)) {
|
|
restore_opcodes(idx->ClCode, NULL PASS_REGS);
|
|
}
|
|
idx->ClPred = PtoPredAdjust(idx->ClPred);
|
|
if (idx->ChildIndex) {
|
|
idx->ChildIndex = SIndexAdjust(idx->ChildIndex);
|
|
if (recurse)
|
|
CleanSIndex(idx->ChildIndex, TRUE PASS_REGS);
|
|
}
|
|
if (idx->SiblingIndex) {
|
|
idx->SiblingIndex = SIndexAdjust(idx->SiblingIndex);
|
|
/* use loop to avoid recursion with very complex indices */
|
|
if (recurse) {
|
|
idx = idx->SiblingIndex;
|
|
goto beginning;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
RestoreSWIAtoms__( USES_REGS1 )
|
|
{
|
|
int i, j;
|
|
for (i=0; i < N_SWI_ATOMS; i++) {
|
|
SWI_Atoms[i] = AtomAdjust(SWI_Atoms[i]);
|
|
}
|
|
for (j=0; j < N_SWI_FUNCTORS; j++) {
|
|
SWI_Functors[j] = FuncAdjust(SWI_Functors[j]);
|
|
}
|
|
RestoreSWIHash();
|
|
}
|
|
|
|
static void
|
|
RestoreSWIBlobTypes__( USES_REGS1 )
|
|
{
|
|
}
|
|
|
|
static void
|
|
RestoreSWIBlobs__( USES_REGS1 )
|
|
{
|
|
SWI_Blobs = AtomAdjust(SWI_Blobs);
|
|
RestoreAtomList(SWI_Blobs PASS_REGS);
|
|
}
|
|
|
|
static void
|
|
RestoreHiddenPredicates__( USES_REGS1 )
|
|
{
|
|
HIDDEN_PREDICATES = PropAdjust(HIDDEN_PREDICATES);
|
|
RestoreEntries(HIDDEN_PREDICATES, TRUE PASS_REGS);
|
|
}
|
|
|
|
|
|
static void
|
|
RestorePredHash__( USES_REGS1 )
|
|
{
|
|
PredHash = PtoPtoPredAdjust(PredHash);
|
|
if (PredHash == NULL) {
|
|
Yap_Error(FATAL_ERROR,MkIntTerm(0),"restore should find predicate hash table");
|
|
}
|
|
REINIT_RWLOCK(PredHashRWLock);
|
|
RestoreHashPreds( PASS_REGS1 ); /* does most of the work */
|
|
}
|
|
|
|
static void
|
|
RestoreEnvInst(yamop start[2], yamop **instp, op_numbers opc, PredEntry *pred)
|
|
{
|
|
yamop *ipc = start;
|
|
|
|
ipc->opc = Yap_opcode(_call);
|
|
ipc->u.Osbpp.p = pred;
|
|
ipc->u.Osbpp.p0 = pred;
|
|
ipc = NEXTOP(ipc, Osbpp);
|
|
ipc->opc = Yap_opcode(opc);
|
|
*instp = ipc;
|
|
}
|
|
|
|
static void
|
|
RestoreOtaplInst__(yamop start[1], OPCODE opc, PredEntry *pe USES_REGS)
|
|
{
|
|
yamop *ipc = start;
|
|
|
|
/* this is a place holder, it should not really be used */
|
|
ipc->opc = Yap_opcode(opc);
|
|
ipc->u.Otapl.s = 0;
|
|
ipc->u.Otapl.p = pe;
|
|
if (ipc->u.Otapl.d)
|
|
ipc->u.Otapl.d = PtoOpAdjust(ipc->u.Otapl.d);
|
|
#ifdef YAPOR
|
|
INIT_YAMOP_LTT(ipc, 1);
|
|
#endif /* YAPOR */
|
|
#ifdef TABLING
|
|
ipc->u.Otapl.te = NULL;
|
|
#endif /* TABLING */
|
|
}
|
|
|
|
static void
|
|
RestoreDBTermsList__( USES_REGS1 )
|
|
{
|
|
if (Yap_heap_regs->dbterms_list) {
|
|
struct dbterm_list *dbl = PtoDBTLAdjust(Yap_heap_regs->dbterms_list);
|
|
Yap_heap_regs->dbterms_list = dbl;
|
|
while (dbl) {
|
|
RestoreDBTermEntry(dbl PASS_REGS);
|
|
dbl = dbl->next_dbl;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
RestoreExpandList__( USES_REGS1 )
|
|
{
|
|
if (Yap_heap_regs->expand_clauses_first)
|
|
Yap_heap_regs->expand_clauses_first = PtoOpAdjust(Yap_heap_regs->expand_clauses_first);
|
|
if (Yap_heap_regs->expand_clauses_last)
|
|
Yap_heap_regs->expand_clauses_last = PtoOpAdjust(Yap_heap_regs->expand_clauses_last);
|
|
{
|
|
yamop *ptr = Yap_heap_regs->expand_clauses_first;
|
|
while (ptr) {
|
|
do_clean_susp_clauses(ptr PASS_REGS);
|
|
ptr = ptr->u.sssllp.snext;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
RestoreUdiControlBlocks(void)
|
|
{
|
|
if (Yap_heap_regs->udi_control_blocks) {
|
|
Yap_Error(SYSTEM_ERROR, TermNil,
|
|
"YAP cannot restore UDI entries!!\n");
|
|
}
|
|
}
|
|
|
|
static void
|
|
RestoreIntKeys__( USES_REGS1 )
|
|
{
|
|
if (Yap_heap_regs->IntKeys != NULL) {
|
|
Yap_heap_regs->IntKeys = (Prop *)AddrAdjust((ADDR)(Yap_heap_regs->IntKeys));
|
|
{
|
|
UInt i;
|
|
for (i = 0; i < Yap_heap_regs->int_keys_size; i++) {
|
|
if (Yap_heap_regs->IntKeys[i] != NIL) {
|
|
Prop p0 = Yap_heap_regs->IntKeys[i] = PropAdjust(Yap_heap_regs->IntKeys[i]);
|
|
RestoreEntries(RepProp(p0), TRUE PASS_REGS);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
RestoreIntLUKeys__( USES_REGS1 )
|
|
{
|
|
if (Yap_heap_regs->IntLUKeys != NULL) {
|
|
Yap_heap_regs->IntLUKeys = (Prop *)AddrAdjust((ADDR)(Yap_heap_regs->IntLUKeys));
|
|
{
|
|
Int i;
|
|
for (i = 0; i < INT_KEYS_SIZE; i++) {
|
|
Prop p0 = INT_LU_KEYS[i];
|
|
if (p0) {
|
|
p0 = PropAdjust(p0);
|
|
INT_LU_KEYS[i] = p0;
|
|
while (p0) {
|
|
PredEntry *pe = RepPredProp(p0);
|
|
pe->NextOfPE =
|
|
PropAdjust(pe->NextOfPE);
|
|
CleanCode(pe PASS_REGS);
|
|
p0 = RepProp(pe->NextOfPE);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
RestoreIntBBKeys__( USES_REGS1 )
|
|
{
|
|
if (Yap_heap_regs->IntBBKeys != NULL) {
|
|
Yap_heap_regs->IntBBKeys = (Prop *)AddrAdjust((ADDR)(Yap_heap_regs->IntBBKeys));
|
|
{
|
|
UInt i;
|
|
for (i = 0; i < Yap_heap_regs->int_bb_keys_size; i++) {
|
|
if (Yap_heap_regs->IntBBKeys[i] != NIL) {
|
|
Prop p0 = Yap_heap_regs->IntBBKeys[i] = PropAdjust(Yap_heap_regs->IntBBKeys[i]);
|
|
RestoreEntries(RepProp(p0), TRUE PASS_REGS);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
RestoreDBErasedMarker__( USES_REGS1 )
|
|
{
|
|
Yap_heap_regs->db_erased_marker =
|
|
DBRefAdjust(Yap_heap_regs->db_erased_marker,TRUE);
|
|
Yap_heap_regs->db_erased_marker->id = FunctorDBRef;
|
|
Yap_heap_regs->db_erased_marker->Flags = ErasedMask;
|
|
Yap_heap_regs->db_erased_marker->Code = NULL;
|
|
Yap_heap_regs->db_erased_marker->DBT.DBRefs = NULL;
|
|
Yap_heap_regs->db_erased_marker->Parent = NULL;
|
|
}
|
|
|
|
static void
|
|
RestoreLogDBErasedMarker__( USES_REGS1 )
|
|
{
|
|
Yap_heap_regs->logdb_erased_marker =
|
|
PtoLUCAdjust(Yap_heap_regs->logdb_erased_marker);
|
|
Yap_heap_regs->logdb_erased_marker->Id = FunctorDBRef;
|
|
Yap_heap_regs->logdb_erased_marker->ClFlags = ErasedMask|LogUpdMask;
|
|
Yap_heap_regs->logdb_erased_marker->ClSource = NULL;
|
|
Yap_heap_regs->logdb_erased_marker->ClRefCount = 0;
|
|
Yap_heap_regs->logdb_erased_marker->ClPred = PredLogUpdClause;
|
|
Yap_heap_regs->logdb_erased_marker->ClExt = NULL;
|
|
Yap_heap_regs->logdb_erased_marker->ClPrev = NULL;
|
|
Yap_heap_regs->logdb_erased_marker->ClNext = NULL;
|
|
Yap_heap_regs->logdb_erased_marker->ClSize = (UInt)NEXTOP(((LogUpdClause *)NULL)->ClCode,e);
|
|
Yap_heap_regs->logdb_erased_marker->ClCode->opc = Yap_opcode(_op_fail);
|
|
INIT_CLREF_COUNT(Yap_heap_regs->logdb_erased_marker);
|
|
}
|
|
|
|
static void
|
|
RestoreDeadStaticClauses__( USES_REGS1 )
|
|
{
|
|
if (Yap_heap_regs->dead_static_clauses) {
|
|
StaticClause *sc = PtoStCAdjust(Yap_heap_regs->dead_static_clauses);
|
|
Yap_heap_regs->dead_static_clauses = sc;
|
|
while (sc) {
|
|
RestoreStaticClause(sc PASS_REGS);
|
|
sc = sc->ClNext;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
RestoreDeadMegaClauses__( USES_REGS1 )
|
|
{
|
|
if (Yap_heap_regs->dead_mega_clauses) {
|
|
MegaClause *mc = (MegaClause *)AddrAdjust((ADDR)(Yap_heap_regs->dead_mega_clauses));
|
|
Yap_heap_regs->dead_mega_clauses = mc;
|
|
while (mc) {
|
|
RestoreMegaClause(mc PASS_REGS);
|
|
mc = mc->ClNext;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
RestoreDeadStaticIndices__( USES_REGS1 )
|
|
{
|
|
if (Yap_heap_regs->dead_static_indices) {
|
|
StaticIndex *si = (StaticIndex *)AddrAdjust((ADDR)(Yap_heap_regs->dead_static_indices));
|
|
Yap_heap_regs->dead_static_indices = si;
|
|
while (si) {
|
|
CleanSIndex(si, FALSE PASS_REGS);
|
|
si = si->SiblingIndex;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
RestoreDBErasedList__( USES_REGS1 )
|
|
{
|
|
if (Yap_heap_regs->db_erased_list) {
|
|
LogUpdClause *lcl = Yap_heap_regs->db_erased_list =
|
|
PtoLUCAdjust(Yap_heap_regs->db_erased_list);
|
|
while (lcl) {
|
|
RestoreLUClause(lcl, FALSE PASS_REGS);
|
|
lcl = lcl->ClNext;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
RestoreDBErasedIList__( USES_REGS1 )
|
|
{
|
|
if (Yap_heap_regs->db_erased_ilist) {
|
|
LogUpdIndex *icl = Yap_heap_regs->db_erased_ilist =
|
|
LUIndexAdjust(Yap_heap_regs->db_erased_ilist);
|
|
while (icl) {
|
|
CleanLUIndex(icl, FALSE PASS_REGS);
|
|
icl = icl->SiblingIndex;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
RestoreStreams(void)
|
|
{
|
|
}
|
|
|
|
static void
|
|
RestoreAliases(void)
|
|
{
|
|
}
|
|
|
|
static void
|
|
RestoreForeignCode__( USES_REGS1 )
|
|
{
|
|
ForeignObj *f_code;
|
|
|
|
if (!ForeignCodeLoaded)
|
|
return;
|
|
if (ForeignCodeLoaded != NULL)
|
|
ForeignCodeLoaded = (void *)AddrAdjust((ADDR)ForeignCodeLoaded);
|
|
f_code = ForeignCodeLoaded;
|
|
while (f_code != NULL) {
|
|
StringList objs, libs;
|
|
if (f_code->objs != NULL)
|
|
f_code->objs = (StringList)AddrAdjust((ADDR)f_code->objs);
|
|
objs = f_code->objs;
|
|
while (objs != NULL) {
|
|
if (objs->next != NULL)
|
|
objs->next = (StringList)AddrAdjust((ADDR)objs->next);
|
|
objs->name = AtomAdjust(objs->name);
|
|
objs = objs->next;
|
|
}
|
|
if (f_code->libs != NULL)
|
|
f_code->libs = (StringList)AddrAdjust((ADDR)f_code->libs);
|
|
libs = f_code->libs;
|
|
while (libs != NULL) {
|
|
if (libs->next != NULL)
|
|
libs->next = (StringList)AddrAdjust((ADDR)libs->next);
|
|
libs->name = AtomAdjust(libs->name);
|
|
libs = libs->next;
|
|
}
|
|
if (f_code->f != NULL) {
|
|
f_code->f = AtomAdjust(f_code->f);
|
|
}
|
|
if (f_code->next != NULL)
|
|
f_code->next = (ForeignObj *)AddrAdjust((ADDR)f_code->next);
|
|
f_code = f_code->next;
|
|
}
|
|
}
|
|
|
|
static void
|
|
RestoreYapRecords__( USES_REGS1 )
|
|
{
|
|
struct record_list *ptr;
|
|
|
|
Yap_Records = DBRecordAdjust(Yap_Records);
|
|
ptr = Yap_Records;
|
|
while (ptr) {
|
|
ptr->next_rec = DBRecordAdjust(ptr->next_rec);
|
|
ptr->prev_rec = DBRecordAdjust(ptr->prev_rec);
|
|
ptr->dbrecord = DBTermAdjust(ptr->dbrecord);
|
|
RestoreDBTerm(ptr->dbrecord, FALSE PASS_REGS);
|
|
}
|
|
}
|
|
|
|
static void
|
|
RestoreBallTerm(int wid)
|
|
{
|
|
CACHE_REGS
|
|
if (LOCAL_BallTerm) {
|
|
LOCAL_BallTerm = DBTermAdjust(LOCAL_BallTerm);
|
|
RestoreDBTerm(LOCAL_BallTerm, TRUE PASS_REGS);
|
|
}
|
|
}
|
|
|
|
#include "rglobals.h"
|
|
#include "rlocals.h"
|
|
|
|
/* restore the failcodes */
|
|
static void
|
|
restore_codes(void)
|
|
{
|
|
CACHE_REGS
|
|
Yap_heap_regs->heap_top = AddrAdjust(LOCAL_OldHeapTop);
|
|
#include "rhstruct.h"
|
|
RestoreGlobal();
|
|
#ifndef worker_id
|
|
#define worker_id 0
|
|
#endif
|
|
RestoreWorker(worker_id PASS_REGS);
|
|
}
|
|
|
|
|
|
static void
|
|
RestoreDBEntry(DBRef dbr USES_REGS)
|
|
{
|
|
#ifdef DEBUG_RESTORE
|
|
fprintf(stderr, "Restoring at %x", dbr);
|
|
if (dbr->Flags & DBAtomic)
|
|
fprintf(stderr, " an atomic term\n");
|
|
else if (dbr->Flags & DBNoVars)
|
|
fprintf(stderr, " with no vars\n");
|
|
else if (dbr->Flags & DBComplex)
|
|
fprintf(stderr, " complex term\n");
|
|
else if (dbr->Flags & DBIsRef)
|
|
fprintf(stderr, " a ref\n");
|
|
else
|
|
fprintf(stderr, " a var\n");
|
|
#endif
|
|
RestoreDBTerm(&(dbr->DBT), TRUE PASS_REGS);
|
|
if (dbr->Parent) {
|
|
dbr->Parent = (DBProp)AddrAdjust((ADDR)(dbr->Parent));
|
|
}
|
|
if (dbr->Code != NULL)
|
|
dbr->Code = PtoOpAdjust(dbr->Code);
|
|
if (dbr->Prev != NULL)
|
|
dbr->Prev = DBRefAdjust(dbr->Prev,TRUE);
|
|
if (dbr->Next != NULL)
|
|
dbr->Next = DBRefAdjust(dbr->Next,TRUE);
|
|
#ifdef DEBUG_RESTORE2
|
|
fprintf(stderr, "Recomputing masks\n");
|
|
#endif
|
|
recompute_mask(dbr);
|
|
}
|
|
|
|
/* Restores a DB structure, as it was saved in the heap */
|
|
static void
|
|
RestoreDB(DBEntry *pp USES_REGS)
|
|
{
|
|
register DBRef dbr;
|
|
|
|
if (pp->First != NULL)
|
|
pp->First = DBRefAdjust(pp->First,TRUE);
|
|
if (pp->Last != NULL)
|
|
pp->Last = DBRefAdjust(pp->Last, TRUE);
|
|
if (pp->ArityOfDB)
|
|
pp->FunctorOfDB = FuncAdjust(pp->FunctorOfDB);
|
|
else
|
|
pp->FunctorOfDB = (Functor) AtomAdjust((Atom)(pp->FunctorOfDB));
|
|
if (pp->F0 != NULL)
|
|
pp->F0 = DBRefAdjust(pp->F0, TRUE);
|
|
if (pp->L0 != NULL)
|
|
pp->L0 = DBRefAdjust(pp->L0, TRUE);
|
|
/* immediate update semantics */
|
|
dbr = pp->F0;
|
|
/* While we have something in the data base, even if erased, restore it */
|
|
while (dbr) {
|
|
RestoreDBEntry(dbr PASS_REGS);
|
|
if (dbr->n != NULL)
|
|
dbr->n = DBRefAdjust(dbr->n, TRUE);
|
|
if (dbr->p != NULL)
|
|
dbr->p = DBRefAdjust(dbr->p, TRUE);
|
|
dbr = dbr->n;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Restores a group of clauses for the same predicate, starting with First
|
|
* and ending with Last, First may be equal to Last
|
|
*/
|
|
static void
|
|
CleanClauses(yamop *First, yamop *Last, PredEntry *pp USES_REGS)
|
|
{
|
|
if (!First)
|
|
return;
|
|
if (pp->PredFlags & LogUpdatePredFlag) {
|
|
LogUpdClause *cl = ClauseCodeToLogUpdClause(First);
|
|
while (cl != NULL) {
|
|
RestoreLUClause(cl, pp PASS_REGS);
|
|
cl = cl->ClNext;
|
|
}
|
|
} else if (pp->PredFlags & MegaClausePredFlag) {
|
|
MegaClause *cl = ClauseCodeToMegaClause(First);
|
|
|
|
RestoreMegaClause(cl PASS_REGS);
|
|
} else if (pp->PredFlags & DynamicPredFlag) {
|
|
yamop *cl = First;
|
|
|
|
do {
|
|
RestoreDynamicClause(ClauseCodeToDynamicClause(cl), pp PASS_REGS);
|
|
if (cl == Last) return;
|
|
cl = NextDynamicClause(cl);
|
|
} while (TRUE);
|
|
} else {
|
|
StaticClause *cl = ClauseCodeToStaticClause(First);
|
|
|
|
do {
|
|
RestoreStaticClause(cl PASS_REGS);
|
|
if (cl->ClCode == Last) return;
|
|
cl = cl->ClNext;
|
|
} while (TRUE);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/* Restores a DB structure, as it was saved in the heap */
|
|
static void
|
|
RestoreBB(BlackBoardEntry *pp, int int_key USES_REGS)
|
|
{
|
|
Term t = pp->Element;
|
|
if (t) {
|
|
if (!IsVarTerm(t)) {
|
|
if (IsAtomicTerm(t)) {
|
|
if (IsAtomTerm(t)) {
|
|
pp->Element = AtomTermAdjust(t);
|
|
}
|
|
} else {
|
|
RestoreLUClause((LogUpdClause *)DBRefOfTerm(t),NULL PASS_REGS);
|
|
}
|
|
}
|
|
}
|
|
if (!int_key) {
|
|
pp->KeyOfBB = AtomAdjust(pp->KeyOfBB);
|
|
}
|
|
if (pp->ModuleOfBB) {
|
|
pp->ModuleOfBB = AtomTermAdjust(pp->ModuleOfBB);
|
|
}
|
|
}
|
|
|
|
static void
|
|
restore_static_array(StaticArrayEntry *ae USES_REGS)
|
|
{
|
|
Int sz = -ae->ArrayEArity;
|
|
switch (ae->ArrayType) {
|
|
case array_of_ints:
|
|
case array_of_doubles:
|
|
case array_of_chars:
|
|
case array_of_uchars:
|
|
return;
|
|
case array_of_ptrs:
|
|
{
|
|
AtomEntry **base = (AtomEntry **)AddrAdjust((ADDR)(ae->ValueOfVE.ptrs));
|
|
Int i;
|
|
ae->ValueOfVE.ptrs = base;
|
|
if (ae != NULL) {
|
|
for (i=0; i<sz; i++) {
|
|
AtomEntry *reg = *base;
|
|
if (reg == NULL) {
|
|
base++;
|
|
} else if (IsOldCode((CELL)reg)) {
|
|
*base++ = AtomEntryAdjust(reg);
|
|
} else if (IsOldLocalInTR((CELL)reg)) {
|
|
*base++ = (AtomEntry *)LocalAddrAdjust((ADDR)reg);
|
|
} else if (IsOldGlobal((CELL)reg)) {
|
|
*base++ = (AtomEntry *)GlobalAddrAdjust((ADDR)reg);
|
|
} else if (IsOldTrail((CELL)reg)) {
|
|
*base++ = (AtomEntry *)TrailAddrAdjust((ADDR)reg);
|
|
} else {
|
|
/* oops */
|
|
base++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return;
|
|
case array_of_atoms:
|
|
{
|
|
Term *base = (Term *)AddrAdjust((ADDR)(ae->ValueOfVE.atoms));
|
|
Int i;
|
|
ae->ValueOfVE.atoms = base;
|
|
if (ae != 0L) {
|
|
for (i=0; i<sz; i++) {
|
|
Term reg = *base;
|
|
if (reg == 0L) {
|
|
base++;
|
|
} else {
|
|
*base++ = AtomTermAdjust(reg);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return;
|
|
case array_of_dbrefs:
|
|
{
|
|
Term *base = (Term *)AddrAdjust((ADDR)(ae->ValueOfVE.dbrefs));
|
|
Int i;
|
|
|
|
ae->ValueOfVE.dbrefs = base;
|
|
if (ae != 0L) {
|
|
for (i=0; i<sz; i++) {
|
|
Term reg = *base;
|
|
if (reg == 0L) {
|
|
base++;
|
|
} else {
|
|
*base++ = AbsAppl(PtoHeapCellAdjust(RepAppl(reg)));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return;
|
|
case array_of_nb_terms:
|
|
{
|
|
live_term *base = (live_term *)AddrAdjust((ADDR)(ae->ValueOfVE.lterms));
|
|
Int i;
|
|
|
|
ae->ValueOfVE.lterms = base;
|
|
if (ae != 0L) {
|
|
for (i=0; i < sz; i++,base++) {
|
|
Term reg = base->tlive;
|
|
if (IsVarTerm(reg)) {
|
|
CELL *var = (CELL *)reg;
|
|
|
|
if (IsOldGlobalPtr(var)) {
|
|
base->tlive = (CELL)PtoGloAdjust(var);
|
|
} else {
|
|
base->tlive = (CELL)PtoHeapCellAdjust(var);
|
|
}
|
|
} else if (IsAtomTerm(reg)) {
|
|
base->tlive = AtomTermAdjust(reg);
|
|
} else if (IsApplTerm(reg)) {
|
|
CELL *db = RepAppl(reg);
|
|
db = PtoGloAdjust(db);
|
|
base->tlive = AbsAppl(db);
|
|
} else if (IsApplTerm(reg)) {
|
|
CELL *db = RepPair(reg);
|
|
db = PtoGloAdjust(db);
|
|
base->tlive = AbsPair(db);
|
|
}
|
|
|
|
reg = base->tstore;
|
|
if (IsVarTerm(reg)) {
|
|
base->tstore = (Term)GlobalAddrAdjust((ADDR)reg);
|
|
} else if (IsAtomTerm(reg)) {
|
|
base->tstore = AtomTermAdjust(reg);
|
|
} else {
|
|
DBTerm *db = (DBTerm *)RepAppl(reg);
|
|
db = DBTermAdjust(db);
|
|
RestoreDBTerm(db, TRUE PASS_REGS);
|
|
base->tstore = AbsAppl((CELL *)db);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
case array_of_terms:
|
|
{
|
|
DBTerm **base = (DBTerm **)AddrAdjust((ADDR)(ae->ValueOfVE.terms));
|
|
Int i;
|
|
|
|
ae->ValueOfVE.terms = base;
|
|
if (ae != 0L) {
|
|
for (i=0; i<sz; i++) {
|
|
DBTerm *reg = *base;
|
|
if (reg == NULL) {
|
|
base++;
|
|
} else {
|
|
*base++ = reg = DBTermAdjust(reg);
|
|
RestoreDBTerm(reg, TRUE PASS_REGS);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Clean all the code for a particular predicate, this can get a bit tricky,
|
|
* because of the indexing code
|
|
*/
|
|
static void
|
|
CleanCode(PredEntry *pp USES_REGS)
|
|
{
|
|
CELL flag;
|
|
|
|
|
|
/* Init takes care of the first 2 cases */
|
|
if (pp->ModuleOfPred) {
|
|
pp->ModuleOfPred = AtomTermAdjust(pp->ModuleOfPred);
|
|
}
|
|
if (pp->ArityOfPE) {
|
|
if (pp->ModuleOfPred == IDB_MODULE) {
|
|
if (pp->PredFlags & NumberDBPredFlag) {
|
|
/* it's an integer, do nothing */
|
|
} else if (pp->PredFlags & AtomDBPredFlag) {
|
|
pp->FunctorOfPred = (Functor)AtomAdjust((Atom)(pp->FunctorOfPred));
|
|
} else {
|
|
pp->FunctorOfPred = FuncAdjust(pp->FunctorOfPred);
|
|
}
|
|
} else {
|
|
pp->FunctorOfPred = FuncAdjust(pp->FunctorOfPred);
|
|
}
|
|
} else {
|
|
pp->FunctorOfPred = (Functor)AtomAdjust((Atom)(pp->FunctorOfPred));
|
|
}
|
|
if (!(pp->PredFlags & NumberDBPredFlag)) {
|
|
if (pp->src.OwnerFile) {
|
|
pp->src.OwnerFile = AtomAdjust(pp->src.OwnerFile);
|
|
}
|
|
}
|
|
pp->OpcodeOfPred = Yap_opcode(Yap_op_from_opcode(pp->OpcodeOfPred));
|
|
if (pp->NextPredOfModule) {
|
|
pp->NextPredOfModule = PtoPredAdjust(pp->NextPredOfModule);
|
|
}
|
|
if (pp->PredFlags & (AsmPredFlag|CPredFlag)) {
|
|
/* assembly */
|
|
if (pp->CodeOfPred) {
|
|
pp->CodeOfPred = PtoOpAdjust(pp->CodeOfPred);
|
|
CleanClauses(pp->CodeOfPred, pp->CodeOfPred, pp PASS_REGS);
|
|
}
|
|
} else {
|
|
yamop *FirstC, *LastC;
|
|
/* Prolog code */
|
|
if (pp->cs.p_code.FirstClause)
|
|
pp->cs.p_code.FirstClause = PtoOpAdjust(pp->cs.p_code.FirstClause);
|
|
if (pp->cs.p_code.LastClause)
|
|
pp->cs.p_code.LastClause = PtoOpAdjust(pp->cs.p_code.LastClause);
|
|
pp->CodeOfPred =PtoOpAdjust(pp->CodeOfPred);
|
|
pp->cs.p_code.TrueCodeOfPred = PtoOpAdjust(pp->cs.p_code.TrueCodeOfPred);
|
|
pp->cs.p_code.ExpandCode = Yap_opcode(_expand_index);
|
|
flag = pp->PredFlags;
|
|
FirstC = pp->cs.p_code.FirstClause;
|
|
LastC = pp->cs.p_code.LastClause;
|
|
/* We just have a fail here */
|
|
if (FirstC == NULL && LastC == NULL) {
|
|
return;
|
|
}
|
|
#ifdef DEBUG_RESTORE2
|
|
fprintf(stderr, "at %ux Correcting clauses from %p to %p\n", *(OPCODE *) FirstC, FirstC, LastC);
|
|
#endif
|
|
CleanClauses(FirstC, LastC, pp PASS_REGS);
|
|
if (flag & IndexedPredFlag) {
|
|
#ifdef DEBUG_RESTORE2
|
|
fprintf(stderr, "Correcting indexed code\n");
|
|
#endif
|
|
if (flag & LogUpdatePredFlag) {
|
|
CleanLUIndex(ClauseCodeToLogUpdIndex(pp->cs.p_code.TrueCodeOfPred), TRUE PASS_REGS);
|
|
} else {
|
|
CleanSIndex(ClauseCodeToStaticIndex(pp->cs.p_code.TrueCodeOfPred), TRUE PASS_REGS);
|
|
}
|
|
} else if (flag & DynamicPredFlag) {
|
|
#ifdef DEBUG_RESTORE2
|
|
fprintf(stderr, "Correcting dynamic code\n");
|
|
#endif
|
|
RestoreDynamicClause(ClauseCodeToDynamicClause(pp->cs.p_code.TrueCodeOfPred),pp PASS_REGS);
|
|
}
|
|
}
|
|
/* we are pointing at ourselves */
|
|
}
|
|
|
|
/*
|
|
* Restores all of the entries, for a particular atom, we only have problems
|
|
* if we find code or data bases
|
|
*/
|
|
static void
|
|
RestoreEntries(PropEntry *pp, int int_key USES_REGS)
|
|
{
|
|
while (!EndOfPAEntr(pp)) {
|
|
switch(pp->KindOfPE) {
|
|
case FunctorProperty:
|
|
{
|
|
FunctorEntry *fe = (FunctorEntry *)pp;
|
|
Prop p0;
|
|
fe->NextOfPE =
|
|
PropAdjust(fe->NextOfPE);
|
|
fe->NameOfFE =
|
|
AtomAdjust(fe->NameOfFE);
|
|
p0 = fe->PropsOfFE =
|
|
PropAdjust(fe->PropsOfFE);
|
|
if (!EndOfPAEntr(p0)) {
|
|
/* at most one property */
|
|
CleanCode(RepPredProp(p0) PASS_REGS);
|
|
RepPredProp(p0)->NextOfPE =
|
|
PropAdjust(RepPredProp(p0)->NextOfPE);
|
|
p0 = RepPredProp(p0)->NextOfPE;
|
|
}
|
|
}
|
|
break;
|
|
case ValProperty:
|
|
{
|
|
ValEntry *ve = (ValEntry *)pp;
|
|
Term tv = ve->ValueOfVE;
|
|
ve->NextOfPE =
|
|
PropAdjust(ve->NextOfPE);
|
|
if (IsAtomTerm(tv))
|
|
ve->ValueOfVE = AtomTermAdjust(tv);
|
|
}
|
|
break;
|
|
case HoldProperty:
|
|
{
|
|
HoldEntry *he = (HoldEntry *)pp;
|
|
he->NextOfPE =
|
|
PropAdjust(he->NextOfPE);
|
|
}
|
|
break;
|
|
case ArrayProperty:
|
|
{
|
|
ArrayEntry *ae = (ArrayEntry *)pp;
|
|
ae->NextOfPE =
|
|
PropAdjust(ae->NextOfPE);
|
|
if (ae->ArrayEArity < 0) {
|
|
/* static array entry */
|
|
StaticArrayEntry *sae = (StaticArrayEntry *)ae;
|
|
if (sae->NextAE)
|
|
sae->NextAE = PtoArraySAdjust(sae->NextAE);
|
|
restore_static_array(sae PASS_REGS);
|
|
} else {
|
|
if (ae->NextAE)
|
|
ae->NextAE = PtoArrayEAdjust(ae->NextAE);
|
|
if (IsVarTerm(ae->ValueOfVE))
|
|
RESET_VARIABLE(&(ae->ValueOfVE));
|
|
else {
|
|
CELL *ptr = RepAppl(ae->ValueOfVE);
|
|
/* in fact it should just be a pointer to the global,
|
|
but we'll be conservative.
|
|
Notice that the variable should have been reset in restore_program mode.
|
|
*/
|
|
if (IsOldGlobalPtr(ptr)) {
|
|
ae->ValueOfVE = AbsAppl(PtoGloAdjust(ptr));
|
|
} else if (IsOldCodeCellPtr(ptr)) {
|
|
ae->ValueOfVE = AbsAppl(PtoHeapCellAdjust(ptr));
|
|
} else if (IsOldLocalInTRPtr(ptr)) {
|
|
ae->ValueOfVE = AbsAppl(PtoLocAdjust(ptr));
|
|
} else if (IsOldTrailPtr(ptr)) {
|
|
ae->ValueOfVE = AbsAppl(CellPtoTRAdjust(ptr));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case PEProp:
|
|
{
|
|
PredEntry *pe = (PredEntry *) pp;
|
|
pe->NextOfPE =
|
|
PropAdjust(pe->NextOfPE);
|
|
CleanCode(pe PASS_REGS);
|
|
}
|
|
break;
|
|
case DBProperty:
|
|
case CodeDBProperty:
|
|
#ifdef DEBUG_RESTORE2
|
|
fprintf(stderr, "Correcting data base clause at %p\n", pp);
|
|
#endif
|
|
{
|
|
DBEntry *de = (DBEntry *) pp;
|
|
de->NextOfPE =
|
|
PropAdjust(de->NextOfPE);
|
|
RestoreDB(de PASS_REGS);
|
|
}
|
|
break;
|
|
case BBProperty:
|
|
{
|
|
BlackBoardEntry *bb = (BlackBoardEntry *) pp;
|
|
bb->NextOfPE =
|
|
PropAdjust(bb->NextOfPE);
|
|
RestoreBB(bb, int_key PASS_REGS);
|
|
}
|
|
break;
|
|
case GlobalProperty:
|
|
{
|
|
GlobalEntry *gb = (GlobalEntry *) pp;
|
|
Term gbt = gb->global;
|
|
|
|
gb->NextOfPE =
|
|
PropAdjust(gb->NextOfPE);
|
|
gb->AtomOfGE =
|
|
AtomEntryAdjust(gb->AtomOfGE);
|
|
if (gb->NextGE) {
|
|
gb->NextGE =
|
|
GlobalEntryAdjust(gb->NextGE);
|
|
}
|
|
if (IsVarTerm(gbt)) {
|
|
CELL *gbp = VarOfTerm(gbt);
|
|
if (IsOldGlobalPtr(gbp))
|
|
gbp = PtoGloAdjust(gbp);
|
|
else
|
|
gbp = CellPtoHeapAdjust(gbp);
|
|
gb->global = (CELL)gbp;
|
|
} else if (IsPairTerm(gbt)) {
|
|
gb->global = AbsPair(PtoGloAdjust(RepPair(gbt)));
|
|
} else if (IsApplTerm(gbt)) {
|
|
CELL *gbp = RepAppl(gbt);
|
|
if (IsOldGlobalPtr(gbp))
|
|
gbp = PtoGloAdjust(gbp);
|
|
else
|
|
gbp = CellPtoHeapAdjust(gbp);
|
|
gb->global = AbsAppl(gbp);
|
|
} else if (IsAtomTerm(gbt)) {
|
|
gb->global = AtomTermAdjust(gbt);
|
|
} /* numbers need no adjusting */
|
|
}
|
|
break;
|
|
case OpProperty:
|
|
{
|
|
OpEntry *opp = (OpEntry *)pp;
|
|
if (opp->NextOfPE) {
|
|
opp->NextOfPE =
|
|
PropAdjust(opp->NextOfPE);
|
|
}
|
|
opp->OpName =
|
|
AtomAdjust(opp->OpName);
|
|
if (opp->OpModule) {
|
|
opp->OpModule = AtomTermAdjust(opp->OpModule);
|
|
}
|
|
if (opp->OpNext) {
|
|
opp->OpNext = OpEntryAdjust(opp->OpNext);
|
|
}
|
|
}
|
|
break;
|
|
case ModProperty:
|
|
{
|
|
ModEntry *me = (ModEntry *)pp;
|
|
if (me->NextOfPE) {
|
|
me->NextOfPE =
|
|
PropAdjust(me->NextOfPE);
|
|
}
|
|
if (me->PredForME) {
|
|
me->PredForME =
|
|
PtoPredAdjust(me->PredForME);
|
|
}
|
|
me->AtomOfME =
|
|
AtomAdjust(me->AtomOfME);
|
|
if (me->NextME)
|
|
me->NextME = (struct mod_entry *)
|
|
AddrAdjust((ADDR)me->NextME);
|
|
}
|
|
break;
|
|
case ExpProperty:
|
|
pp->NextOfPE =
|
|
PropAdjust(pp->NextOfPE);
|
|
break;
|
|
case WideAtomProperty:
|
|
pp->NextOfPE =
|
|
PropAdjust(pp->NextOfPE);
|
|
break;
|
|
case BlobProperty:
|
|
pp->NextOfPE =
|
|
PropAdjust(pp->NextOfPE);
|
|
{
|
|
BlobPropEntry *bpe = (BlobPropEntry *)pp;
|
|
bpe->blob_t =
|
|
BlobTypeAdjust(bpe->blob_t);
|
|
}
|
|
break;
|
|
default:
|
|
/* OOPS */
|
|
Yap_Error(SYSTEM_ERROR, TermNil,
|
|
"Invalid Atom Property %d at %p", pp->KindOfPE, pp);
|
|
return;
|
|
}
|
|
pp = RepProp(pp->NextOfPE);
|
|
}
|
|
}
|
|
|
|
static void
|
|
RestoreAtom(AtomEntry *at USES_REGS)
|
|
{
|
|
AtomEntry *nat;
|
|
|
|
/* this should be done before testing for wide atoms */
|
|
at->PropsOfAE = PropAdjust(at->PropsOfAE);
|
|
#if DEBUG_RESTORE2 /* useful during debug */
|
|
if (IsWideAtom(AbsAtom(at)))
|
|
fprintf(errout, "Restoring %S\n", at->WStrOfAE);
|
|
else
|
|
fprintf(errout, "Restoring %s\n", at->StrOfAE);
|
|
#endif
|
|
RestoreEntries(RepProp(at->PropsOfAE), FALSE PASS_REGS);
|
|
/* cannot use AtomAdjust without breaking agc */
|
|
nat = RepAtom(at->NextOfAE);
|
|
if (nat)
|
|
at->NextOfAE = AbsAtom(AtomEntryAdjust(nat));
|
|
}
|
|
|