369 lines
9.2 KiB
C
369 lines
9.2 KiB
C
|
/************************************************************************\
|
|||
|
* Logical Updates *
|
|||
|
\************************************************************************/
|
|||
|
|
|||
|
#ifdef INDENT_CODE
|
|||
|
{
|
|||
|
{
|
|||
|
{
|
|||
|
#endif /* INDENT_CODE */
|
|||
|
|
|||
|
BOp(profiled_retry_logical, OtaLl);
|
|||
|
check_trail(TR);
|
|||
|
{
|
|||
|
UInt timestamp;
|
|||
|
CACHE_Y(B);
|
|||
|
|
|||
|
#if defined(YAPOR) || defined(THREADS)
|
|||
|
if (PP != PREG->y_u.OtaLl.d->ClPred) {
|
|||
|
if (PP) UNLOCKPE(15,PP);
|
|||
|
PP = PREG->y_u.OtaLl.d->ClPred;
|
|||
|
PELOCK(15,PP);
|
|||
|
}
|
|||
|
#endif
|
|||
|
timestamp = IntegerOfTerm(((CELL *)(B_YREG+1))[PREG->y_u.OtaLl.s]);
|
|||
|
if (!VALID_TIMESTAMP(timestamp, PREG->y_u.OtaLl.d)) {
|
|||
|
/* jump to next instruction */
|
|||
|
PREG=PREG->y_u.OtaLl.n;
|
|||
|
JMPNext();
|
|||
|
}
|
|||
|
restore_yaam_regs(PREG->y_u.OtaLl.n);
|
|||
|
restore_args(PREG->y_u.OtaLl.s);
|
|||
|
LOCK(PREG->y_u.OtaLl.d->ClPred->StatisticsForPred.lock);
|
|||
|
PREG->y_u.OtaLl.d->ClPred->StatisticsForPred.NOfRetries++;
|
|||
|
UNLOCK(PREG->y_u.OtaLl.d->ClPred->StatisticsForPred.lock);
|
|||
|
#ifdef THREADS
|
|||
|
PP = PREG->y_u.OtaLl.d->ClPred;
|
|||
|
#endif
|
|||
|
PREG = PREG->y_u.OtaLl.d->ClCode;
|
|||
|
#ifdef FROZEN_STACKS
|
|||
|
S_YREG = (CELL *) PROTECT_FROZEN_B(B_YREG);
|
|||
|
set_cut(S_YREG, B->cp_b);
|
|||
|
#else
|
|||
|
set_cut(S_YREG, B_YREG->cp_b);
|
|||
|
#endif /* FROZEN_STACKS */
|
|||
|
SET_BB(B_YREG);
|
|||
|
ENDCACHE_Y();
|
|||
|
}
|
|||
|
JMPNext();
|
|||
|
ENDBOp();
|
|||
|
|
|||
|
BOp(profiled_trust_logical, OtILl);
|
|||
|
CACHE_Y(B);
|
|||
|
{
|
|||
|
LogUpdIndex *cl = PREG->y_u.OtILl.block;
|
|||
|
PredEntry *ap = cl->ClPred;
|
|||
|
LogUpdClause *lcl = PREG->y_u.OtILl.d;
|
|||
|
UInt timestamp = IntegerOfTerm(((CELL *)(B_YREG+1))[ap->ArityOfPE]);
|
|||
|
|
|||
|
#if defined(YAPOR) || defined(THREADS)
|
|||
|
if (PP != ap) {
|
|||
|
if (PP) UNLOCKPE(16,PP);
|
|||
|
PP = ap;
|
|||
|
PELOCK(16,PP);
|
|||
|
}
|
|||
|
#endif
|
|||
|
if (!VALID_TIMESTAMP(timestamp, lcl)) {
|
|||
|
/* jump to next alternative */
|
|||
|
PREG = FAILCODE;
|
|||
|
} else {
|
|||
|
LOCK(ap->StatisticsForPred.lock);
|
|||
|
ap->StatisticsForPred.NOfRetries++;
|
|||
|
UNLOCK(ap->StatisticsForPred.lock);
|
|||
|
PREG = lcl->ClCode;
|
|||
|
}
|
|||
|
/* HEY, leave indexing block alone!! */
|
|||
|
/* check if we are the ones using this code */
|
|||
|
#if MULTIPLE_STACKS
|
|||
|
DEC_CLREF_COUNT(cl);
|
|||
|
/* clear the entry from the trail */
|
|||
|
B->cp_tr--;
|
|||
|
TR = B->cp_tr;
|
|||
|
/* actually get rid of the code */
|
|||
|
if (cl->ClRefCount == 0 && (cl->ClFlags & (ErasedMask|DirtyMask))) {
|
|||
|
if (PREG != FAILCODE) {
|
|||
|
/* I am the last one using this clause, hence I don't need a lock
|
|||
|
to dispose of it
|
|||
|
*/
|
|||
|
if (lcl->ClRefCount == 1) {
|
|||
|
/* make sure the clause isn't destroyed */
|
|||
|
/* always add an extra reference */
|
|||
|
INC_CLREF_COUNT(lcl);
|
|||
|
TRAIL_CLREF(lcl);
|
|||
|
}
|
|||
|
}
|
|||
|
if (cl->ClFlags & ErasedMask) {
|
|||
|
saveregs();
|
|||
|
Yap_ErLogUpdIndex(cl);
|
|||
|
setregs();
|
|||
|
} else {
|
|||
|
saveregs();
|
|||
|
Yap_CleanUpIndex(cl);
|
|||
|
setregs();
|
|||
|
}
|
|||
|
save_pc();
|
|||
|
}
|
|||
|
#else
|
|||
|
if (TrailTerm(B->cp_tr-1) == CLREF_TO_TRENTRY(cl) &&
|
|||
|
B->cp_tr != B->cp_b->cp_tr) {
|
|||
|
cl->ClFlags &= ~InUseMask;
|
|||
|
--B->cp_tr;
|
|||
|
#if FROZEN_STACKS
|
|||
|
if (B->cp_tr > TR_FZ)
|
|||
|
#endif
|
|||
|
{
|
|||
|
TR = B->cp_tr;
|
|||
|
}
|
|||
|
/* next, recover space for the indexing code if it was erased */
|
|||
|
if (cl->ClFlags & (ErasedMask|DirtyMask)) {
|
|||
|
if (PREG != FAILCODE) {
|
|||
|
/* make sure we don't erase the clause we are jumping to,
|
|||
|
notice that we can erase a number of refs in one go. */
|
|||
|
if (!(lcl->ClFlags & InUseMask)) {
|
|||
|
lcl->ClFlags |= InUseMask;
|
|||
|
TRAIL_CLREF(lcl);
|
|||
|
}
|
|||
|
}
|
|||
|
if (cl->ClFlags & ErasedMask) {
|
|||
|
saveregs();
|
|||
|
Yap_ErLogUpdIndex(cl);
|
|||
|
setregs();
|
|||
|
} else {
|
|||
|
saveregs();
|
|||
|
Yap_CleanUpIndex(cl);
|
|||
|
setregs();
|
|||
|
}
|
|||
|
save_pc();
|
|||
|
}
|
|||
|
}
|
|||
|
#endif
|
|||
|
#ifdef YAPOR
|
|||
|
if (SCH_top_shared_cp(B)) {
|
|||
|
SCH_last_alternative(PREG, B_YREG);
|
|||
|
restore_args(ap->ArityOfPE);
|
|||
|
#ifdef FROZEN_STACKS
|
|||
|
S_YREG = (CELL *) PROTECT_FROZEN_B(B_YREG);
|
|||
|
#else
|
|||
|
S_YREG++;
|
|||
|
#endif /* FROZEN_STACKS */
|
|||
|
set_cut(S_YREG, B->cp_b);
|
|||
|
} else
|
|||
|
#endif /* YAPOR */
|
|||
|
{
|
|||
|
pop_yaam_regs();
|
|||
|
pop_args(ap->ArityOfPE);
|
|||
|
S_YREG--;
|
|||
|
#ifdef FROZEN_STACKS
|
|||
|
S_YREG = (CELL *) PROTECT_FROZEN_B(B_YREG);
|
|||
|
#endif /* FROZEN_STACKS */
|
|||
|
set_cut(S_YREG, B);
|
|||
|
}
|
|||
|
SET_BB(B_YREG);
|
|||
|
ENDCACHE_Y();
|
|||
|
JMPNext();
|
|||
|
}
|
|||
|
ENDBOp();
|
|||
|
|
|||
|
S_YREG = (CELL *) PROTECT_FROZEN_B(B_YREG);
|
|||
|
#endif /* FROZEN_STACKS */
|
|||
|
set_cut(S_YREG, B);
|
|||
|
}
|
|||
|
SET_BB(B_YREG);
|
|||
|
ENDCACHE_Y();
|
|||
|
JMPNext();
|
|||
|
}
|
|||
|
ENDBOp();
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/*****************************************************************
|
|||
|
* enter a logical semantics dynamic predicate *
|
|||
|
*****************************************************************/
|
|||
|
|
|||
|
/* only meaningful with THREADS on! */
|
|||
|
/* lock logical updates predicate. */
|
|||
|
Op(lock_lu, p);
|
|||
|
#if PARALLEL_YAP
|
|||
|
if (PP) {
|
|||
|
GONext();
|
|||
|
}
|
|||
|
PP = PREG->y_u.p.p;
|
|||
|
PELOCK(3, PP);
|
|||
|
#endif
|
|||
|
PREG = NEXTOP(PREG, p);
|
|||
|
GONext();
|
|||
|
ENDOp();
|
|||
|
|
|||
|
/* only meaningful with THREADS on! */
|
|||
|
/* lock logical updates predicate. */
|
|||
|
Op(unlock_lu, e);
|
|||
|
#if defined(YAPOR) || defined(THREADS)
|
|||
|
if (PP) {
|
|||
|
UNLOCKPE(1,PP);
|
|||
|
PP = NULL;
|
|||
|
}
|
|||
|
#endif
|
|||
|
PREG = NEXTOP(PREG, e);
|
|||
|
GONext();
|
|||
|
ENDOp();
|
|||
|
|
|||
|
|
|||
|
/* enter logical pred */
|
|||
|
BOp(alloc_for_logical_pred, L);
|
|||
|
check_trail(TR);
|
|||
|
/* say that an environment is using this clause */
|
|||
|
/* we have our own copy for the clause */
|
|||
|
#if MULTIPLE_STACKS
|
|||
|
{
|
|||
|
LogUpdClause *cl = PREG->y_u.L.ClBase;
|
|||
|
#if PARALLEL_YAP
|
|||
|
PredEntry *ap = cl->ClPred;
|
|||
|
#endif
|
|||
|
|
|||
|
/* always add an extra reference */
|
|||
|
INC_CLREF_COUNT(cl);
|
|||
|
TRAIL_CLREF(cl);
|
|||
|
UNLOCKPE(2,ap);
|
|||
|
PP = NULL;
|
|||
|
}
|
|||
|
#else
|
|||
|
{
|
|||
|
LogUpdClause *cl = (LogUpdClause *)PREG->y_u.L.ClBase;
|
|||
|
if (!(cl->ClFlags & InUseMask)) {
|
|||
|
cl->ClFlags |= InUseMask;
|
|||
|
TRAIL_CLREF(cl);
|
|||
|
}
|
|||
|
}
|
|||
|
#endif
|
|||
|
PREG = NEXTOP(PREG, L);
|
|||
|
JMPNext();
|
|||
|
ENDBOp();
|
|||
|
|
|||
|
/* copy database term */
|
|||
|
BOp(copy_idb_term, e);
|
|||
|
{
|
|||
|
LogUpdClause *cl = ClauseCodeToLogUpdClause(PREG);
|
|||
|
Term t;
|
|||
|
|
|||
|
SET_ASP(YREG, E_CB*sizeof(CELL));
|
|||
|
saveregs();
|
|||
|
while ((t = Yap_FetchTermFromDB(cl->lusl.ClSource)) == 0L) {
|
|||
|
if (PP) UNLOCKPE(3,PP);
|
|||
|
#if defined(YAPOR) || defined(THREADS)
|
|||
|
PP = NULL;
|
|||
|
#endif
|
|||
|
if (LOCAL_Error_TYPE == OUT_OF_ATTVARS_ERROR) {
|
|||
|
LOCAL_Error_TYPE = YAP_NO_ERROR;
|
|||
|
if (!Yap_growglobal(NULL)) {
|
|||
|
Yap_NilError(OUT_OF_ATTVARS_ERROR, LOCAL_ErrorMessage);
|
|||
|
FAIL();
|
|||
|
}
|
|||
|
} else {
|
|||
|
LOCAL_Error_TYPE = YAP_NO_ERROR;
|
|||
|
if (!Yap_gc(3, ENV, CP)) {
|
|||
|
Yap_NilError(OUT_OF_STACK_ERROR, LOCAL_ErrorMessage);
|
|||
|
FAIL();
|
|||
|
}
|
|||
|
}
|
|||
|
#if defined(YAPOR) || defined(THREADS)
|
|||
|
PELOCK(5,ClauseCodeToLogUpdClause(PREG)->ClPred);
|
|||
|
PP = ClauseCodeToLogUpdClause(PREG)->ClPred;
|
|||
|
#endif
|
|||
|
}
|
|||
|
if (!Yap_IUnify(ARG2, t)) {
|
|||
|
setregs();
|
|||
|
#if defined(YAPOR) || defined(THREADS)
|
|||
|
if (PP) UNLOCKPE(6,PP);
|
|||
|
PP = NULL;
|
|||
|
#endif
|
|||
|
FAIL();
|
|||
|
}
|
|||
|
if (!Yap_IUnify(ARG3, MkDBRefTerm((DBRef)cl))) {
|
|||
|
setregs();
|
|||
|
#if defined(YAPOR) || defined(THREADS)
|
|||
|
if (PP) UNLOCKPE(5,PP);
|
|||
|
PP = NULL;
|
|||
|
#endif
|
|||
|
FAIL();
|
|||
|
}
|
|||
|
setregs();
|
|||
|
|
|||
|
#if MULTIPLE_STACKS
|
|||
|
/* always add an extra reference */
|
|||
|
INC_CLREF_COUNT(cl);
|
|||
|
TRAIL_CLREF(cl);
|
|||
|
if (PP) UNLOCKPE(7,PP);
|
|||
|
PP = NULL;
|
|||
|
#else
|
|||
|
if (!(cl->ClFlags & InUseMask)) {
|
|||
|
/* Clause *cl = (Clause *)PREG->y_u.EC.ClBase;
|
|||
|
|
|||
|
PREG->y_u.EC.ClTrail = TR-(tr_fr_ptr)LOCAL_TrailBase;
|
|||
|
PREG->y_u.EC.ClENV = LCL0-YREG;*/
|
|||
|
cl->ClFlags |= InUseMask;
|
|||
|
TRAIL_CLREF(cl);
|
|||
|
}
|
|||
|
#endif
|
|||
|
}
|
|||
|
PREG = CPREG;
|
|||
|
YREG = ENV;
|
|||
|
#ifdef DEPTH_LIMIT
|
|||
|
DEPTH = YREG[E_DEPTH];
|
|||
|
#endif
|
|||
|
JMPNext();
|
|||
|
ENDBOp();
|
|||
|
|
|||
|
|
|||
|
/* unify with database term */
|
|||
|
BOp(unify_idb_term, e);
|
|||
|
{
|
|||
|
LogUpdClause *cl = ClauseCodeToLogUpdClause(PREG);
|
|||
|
|
|||
|
saveregs();
|
|||
|
if (!Yap_IUnify(ARG2, cl->lusl.ClSource->Entry)) {
|
|||
|
setregs();
|
|||
|
UNLOCKPE(8,PP);
|
|||
|
#if defined(YAPOR) || defined(THREADS)
|
|||
|
PP = NULL;
|
|||
|
#endif
|
|||
|
FAIL();
|
|||
|
}
|
|||
|
if (!Yap_IUnify(ARG3, MkDBRefTerm((DBRef)cl))) {
|
|||
|
setregs();
|
|||
|
UNLOCKPE(9,PP);
|
|||
|
#if defined(YAPOR) || defined(THREADS)
|
|||
|
PP = NULL;
|
|||
|
#endif
|
|||
|
FAIL();
|
|||
|
}
|
|||
|
setregs();
|
|||
|
|
|||
|
/* say that an environment is using this clause */
|
|||
|
/* we have our own copy for the clause */
|
|||
|
#if MULTIPLE_STACKS
|
|||
|
/* always add an extra reference */
|
|||
|
INC_CLREF_COUNT(cl);
|
|||
|
TRAIL_CLREF(cl);
|
|||
|
UNLOCKPE(10,PP);
|
|||
|
PP = NULL;
|
|||
|
#else
|
|||
|
if (!(cl->ClFlags & InUseMask)) {
|
|||
|
/* Clause *cl = (Clause *)PREG->y_u.EC.ClBase;
|
|||
|
|
|||
|
PREG->y_u.EC.ClTrail = TR-(tr_fr_ptr)LOCAL_TrailBase;
|
|||
|
PREG->y_u.EC.ClENV = LCL0-YREG;*/
|
|||
|
cl->ClFlags |= InUseMask;
|
|||
|
TRAIL_CLREF(cl);
|
|||
|
}
|
|||
|
#endif
|
|||
|
}
|
|||
|
PREG = CPREG;
|
|||
|
YREG = ENV;
|
|||
|
#ifdef DEPTH_LIMIT
|
|||
|
DEPTH = YREG[E_DEPTH];
|
|||
|
#endif
|
|||
|
JMPNext();
|
|||
|
ENDBOp();
|
|||
|
|
|||
|
|