772 lines
20 KiB
C
772 lines
20 KiB
C
/************************************************************************\
|
||
* Logical Updates *
|
||
\************************************************************************/
|
||
|
||
#ifdef INDENT_CODE
|
||
{
|
||
{
|
||
#endif /* INDENT_CODE */
|
||
|
||
/************************************************************************\
|
||
* Logical Updates *
|
||
\************************************************************************/
|
||
|
||
/* enter logical pred */
|
||
BOp(enter_lu_pred, Illss);
|
||
check_trail(TR);
|
||
/* mark the indexing code */
|
||
{
|
||
LogUpdIndex *cl = PREG->y_u.Illss.I;
|
||
PredEntry *ap = cl->ClPred;
|
||
|
||
if (!cl) { FAIL(); } /* in case the index is empty */
|
||
if (ap->LastCallOfPred != LUCALL_EXEC) {
|
||
/*
|
||
only increment time stamp if we are working on current time
|
||
stamp
|
||
*/
|
||
if (ap->TimeStampOfPred >= TIMESTAMP_RESET)
|
||
Yap_UpdateTimestamps(ap);
|
||
ap->TimeStampOfPred++;
|
||
ap->LastCallOfPred = LUCALL_EXEC;
|
||
/* fprintf(stderr,"R %x--%d--%ul\n",ap,ap->TimeStampOfPred,ap->ArityOfPE);*/
|
||
}
|
||
*--YREG = MkIntegerTerm(ap->TimeStampOfPred);
|
||
/* fprintf(stderr,"> %p/%p %d %d\n",cl,ap,ap->TimeStampOfPred,PREG->y_u.Illss.s);*/
|
||
PREG = PREG->y_u.Illss.l1;
|
||
/* indicate the indexing code is being used */
|
||
#if MULTIPLE_STACKS
|
||
/* just store a reference */
|
||
INC_CLREF_COUNT(cl);
|
||
TRAIL_CLREF(cl);
|
||
#else
|
||
if (!(cl->ClFlags & InUseMask)) {
|
||
cl->ClFlags |= InUseMask;
|
||
TRAIL_CLREF(cl);
|
||
}
|
||
#endif
|
||
}
|
||
JMPNext();
|
||
ENDBOp();
|
||
|
||
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();
|
||
|
||
BOp(try_logical, OtaLl);
|
||
check_trail(TR);
|
||
{
|
||
UInt timestamp;
|
||
|
||
CACHE_Y(YREG);
|
||
timestamp = IntegerOfTerm(S_YREG[0]);
|
||
/* fprintf(stderr,"+ %p/%p %d %d %d--%u\n",PREG,PREG->y_u.OtaLl.d->ClPred,timestamp,PREG->y_u.OtaLl.d->ClPred->TimeStampOfPred,PREG->y_u.OtaLl.d->ClTimeStart,PREG->y_u.OtaLl.d->ClTimeEnd);*/
|
||
/* Point AP to the code that follows this instruction */
|
||
/* always do this, even if we are not going to use it */
|
||
store_args(PREG->y_u.OtaLl.s);
|
||
store_yaam_regs(PREG->y_u.OtaLl.n, 0);
|
||
set_cut(S_YREG, B);
|
||
B = B_YREG;
|
||
#ifdef YAPOR
|
||
SCH_set_load(B_YREG);
|
||
#endif /* YAPOR */
|
||
#ifdef YAPOR
|
||
PP = PREG->y_u.OtaLl.d->ClPred;
|
||
#endif /* YAPOR */
|
||
if (!VALID_TIMESTAMP(timestamp, PREG->y_u.OtaLl.d)) {
|
||
/* jump to next alternative */
|
||
PREG=PREG->y_u.OtaLl.n;
|
||
} else {
|
||
PREG = PREG->y_u.OtaLl.d->ClCode;
|
||
}
|
||
SET_BB(B_YREG);
|
||
ENDCACHE_Y();
|
||
}
|
||
JMPNext();
|
||
ENDBOp();
|
||
|
||
BOp(count_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);
|
||
LOCAL_RetriesCounter--;
|
||
if (LOCAL_RetriesCounter == 0) {
|
||
saveregs();
|
||
Yap_NilError(RETRY_COUNTER_UNDERFLOW_EVENT,"");
|
||
setregs();
|
||
JMPNext();
|
||
}
|
||
LOCAL_PredEntriesCounter--;
|
||
if (LOCAL_PredEntriesCounter == 0) {
|
||
saveregs();
|
||
Yap_NilError(PRED_ENTRY_COUNTER_UNDERFLOW_EVENT,"");
|
||
setregs();
|
||
JMPNext();
|
||
}
|
||
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(count_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 {
|
||
LOCAL_RetriesCounter--;
|
||
if (LOCAL_RetriesCounter == 0) {
|
||
saveregs();
|
||
Yap_NilError(RETRY_COUNTER_UNDERFLOW_EVENT,"");
|
||
setregs();
|
||
JMPNext();
|
||
}
|
||
LOCAL_PredEntriesCounter--;
|
||
if (LOCAL_PredEntriesCounter == 0) {
|
||
saveregs();
|
||
Yap_NilError(PRED_ENTRY_COUNTER_UNDERFLOW_EVENT,"");
|
||
setregs();
|
||
JMPNext();
|
||
}
|
||
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
|
||
PELOCK(2, ap);
|
||
PP = ap;
|
||
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 too */
|
||
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();
|
||
|
||
|
||
|
||
BOp(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]);
|
||
/* fprintf(stderr,"^ %p/%p %d %d %d--%u\n",PREG,PREG->y_u.OtaLl.d->ClPred,timestamp,PREG->y_u.OtaLl.d->ClPred->TimeStampOfPred,PREG->y_u.OtaLl.d->ClTimeStart,PREG->y_u.OtaLl.d->ClTimeEnd);*/
|
||
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_at_least_one_arg(PREG->y_u.OtaLl.s);
|
||
#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(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]);
|
||
|
||
/* fprintf(stderr,"- %p/%p %d %d %p\n",PREG,ap,timestamp,ap->TimeStampOfPred,PREG->y_u.OtILl.d->ClCode);*/
|
||
#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 {
|
||
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) {
|
||
if (lcl->ClRefCount == 1) {
|
||
/* make sure the clause isn't destroyed */
|
||
/* always add an extra reference */
|
||
INC_CLREF_COUNT(lcl);
|
||
TRAIL_CLREF(lcl);
|
||
B->cp_tr = TR;
|
||
}
|
||
}
|
||
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 too */
|
||
if (!(lcl->ClFlags & InUseMask)) {
|
||
lcl->ClFlags |= InUseMask;
|
||
TRAIL_CLREF(lcl);
|
||
B->cp_tr = TR;
|
||
}
|
||
}
|
||
if (cl->ClFlags & ErasedMask) {
|
||
saveregs();
|
||
Yap_ErLogUpdIndex(cl);
|
||
setregs();
|
||
} else {
|
||
saveregs();
|
||
Yap_CleanUpIndex(cl);
|
||
setregs();
|
||
}
|
||
}
|
||
}
|
||
#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();
|
||
#if defined(YAPOR) || defined(THREADS)
|
||
if (PREG == FAILCODE) {
|
||
UNLOCKPE(26,PP);
|
||
PP = NULL;
|
||
}
|
||
#endif
|
||
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 == RESOURCE_ERROR_ATTRIBUTED_VARIABLES) {
|
||
LOCAL_Error_TYPE = YAP_NO_ERROR;
|
||
if (!Yap_growglobal(NULL)) {
|
||
Yap_NilError(RESOURCE_ERROR_ATTRIBUTED_VARIABLES, LOCAL_ErrorMessage);
|
||
FAIL();
|
||
}
|
||
} else {
|
||
LOCAL_Error_TYPE = YAP_NO_ERROR;
|
||
if (!Yap_gc(3, ENV, CP)) {
|
||
Yap_NilError(RESOURCE_ERROR_STACK, 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();
|