72#define HAS_CACHE_REGS 1
79#define DEBUG_INTERRUPTS()
82extern long long vsc_count;
83#define DEBUG_INTERRUPTS() \
84 { fprintf(stderr, "%d %lx %s %d B=%p E=%p ASP=%p\n", \
85 worker_id, LOCAL_Signals,\
86 __FUNCTION__, __LINE__, B, ENV, ASP);}
92TraceContext **curtrace;
94BlocksContext **globalcurblock;
95COUNT ineedredefinedest;
98NativeContext *NativeArea;
99IntermediatecodeContext *IntermediatecodeArea;
105Environment *Yap_ExpEnvP, Yap_ExpEnv;
107void **Yap_ABSMI_ControlLabels;
109static Int traced_absmi(
void) {
return Yap_traced_absmi(); }
117void **Yap_ABSMI_OPCODES;
124Term Yap_XREGS[MaxTemps];
135static Term save_goal(
PredEntry *pe USES_REGS) {
154 S_PT[0] = (CELL)FunctorModule;
155 S_PT[1] = (pe->ModuleOfPred ? pe->ModuleOfPred: TermProlog);
156 arity = pe->ArityOfPE;
158 S_PT[2] = MkAtomTerm((
Atom)pe->FunctorOfPred);
161 S_PT[2] = AbsAppl(HR);
163 S_PT[0] = (CELL)pe->FunctorOfPred;
167 for (a=1; a<= arity; a++) {
168 S_PT[a] = MkGlobal(XREGS[a]);
178static void put_goal(
PredEntry *pe, CELL *args USES_REGS) {
191 if (pe->ArityOfPE == 0)
194 for (i=0;i<pe->ArityOfPE;i++) {
195 XREGS[i+1] = *args++;
206 if (pco->opc != Yap_opcode(_skip) &&
207 pco->opc != Yap_opcode(_move_back))
208 return pe->ArityOfPE;
209 CELL *lab = (CELL *)(pco->y_u.l.l);
210 arity_t max = lab[0];
214 for (i = 0; i <= max; i++) {
216 if (i == 8 * CellSize) {
223 XREGS[i] = MkIntegerTerm(i);
232#if USE_THREADED_CODE && (defined(ANALYST) || defined(DEBUG))
234char *Yap_op_names[] = {
235#define OPCODE(OP, TYPE) #OP
236#include "YapOpcodes.h"
242static int check_alarm_fail_int(
int CONT USES_REGS) {
243#if defined(_MSC_VER) || defined(__MINGW32__)
246 if (LOCAL_PrologMode & (AbortMode | InterruptMode)) {
247 CalculateStackGap(PASS_REGS1);
250 if (Yap_get_signal(YAP_FAIL_SIGNAL)) {
251 return INT_HANDLER_FAIL;
254 return INT_HANDLER_GO_ON;
257static int stack_overflow(op_numbers op,
yamop *pc,
PredEntry **pt USES_REGS) {
259 if (Yap_get_signal(YAP_STOVF_SIGNAL) ||
260 Unsigned(YREG) - Unsigned(HR) < StackGap(PASS_REGS1)
262 PredEntry *pe = Yap_track_cpred( op, pc, 0, &info);
265 if (!Yap_gc(&info)) {
266 Yap_ThrowError(RESOURCE_ERROR_STACK, TermNil,
"stack overflow: gc failed");
268 return INT_HANDLER_RET_JMP;
270 return INT_HANDLER_GO_ON;
274static int code_overflow(CELL *yenv USES_REGS) {
275 if (Yap_get_signal(YAP_CDOVF_SIGNAL)) {
276 CELL cut_b = LCL0 - (CELL *)(yenv[E_CB]);
279 if (!Yap_locked_growheap(
false, 0, NULL)) {
280 Yap_ThrowError(RESOURCE_ERROR_HEAP, TermNil,
"YAP failed to grow heap: %s",
281 "malloc/mmap failed");
282 return INT_HANDLER_FAIL;
286 yenv[E_CB] = (CELL)(LCL0 - cut_b);
288 return INT_HANDLER_RET_JMP;
290 return INT_HANDLER_GO_ON;
300static Term save_xregs(
yamop *pco) {
302 CELL *lab = (CELL *)(pco->y_u.l.l), *start;
305 Term tp = MkIntegerTerm((Int)pco);
306 Term tcp = MkIntegerTerm((Int)CP);
307 Term tenv = MkIntegerTerm((Int)(LCL0 - ENV));
308 Term tyenv = MkIntegerTerm((Int)(LCL0 - YENV));
321 for (i = 0; i <= max; i++) {
323 if (i == 8 * CellSize) {
333 HR[0] = MkIntTerm(i);
335 tot+=2; deref_head(d1, mkglobal_unk);
336 RESET_VARIABLE(HR - 1);
342 deref_body(d1, pt0, mkglobal_unk, mkglobal_nonvar);
345 d1 = Unsigned(HR - 1);
355 *start = (CELL)Yap_MkFunctor(AtomTrue, tot);
356 return (AbsAppl(start));
360static Term addgs(Term g, Term tg)
363 if (g == TermTrue || g == 0) {
364 if (tg==0)
return TermTrue;
367 if (tg == TermTrue || tg == 0)
371 return Yap_MkApplTerm(FunctorComma,2,ts);
390 bool wk = Yap_get_signal(YAP_WAKEUP_SIGNAL);
391 bool creep = Yap_get_signal(YAP_CREEP_SIGNAL);
392 bool sig = Yap_has_a_signal();
395 Term td = Yap_ReadTimedVar(LOCAL_WokenGoals);
397 td= save_xregs(plab PASS_REGS);
398 td = Yap_MkApplTerm(FunctorRestoreRegs1, 1, &td);
404 Yap_UpdateTimedVar(LOCAL_WokenGoals, TermTrue);
407 tg=Yap_MkApplTerm(FunctorCreep, 1, &tg);
410 while ((td = Yap_next_signal(PASS_REGS1))) {
411 tg = addgs(Yap_MkApplTerm(FunctorSignalHandler, 1, &td),tg);
414 Yap_DebugPlWriteln(tg);
416 Term mod = CurrentModule;
418 tg = Yap_YapStripModule(tg, &mod);
420 Yap_ThrowError(INSTANTIATION_ERROR, tg,
"wake-up");
421 }
else if (IsPairTerm(tg)) {
422 XREGS[1] = HeadOfTerm(tg);
423 XREGS[2] = TailOfTerm(tg);
424 pe = RepPredProp(Yap_GetPredPropByFunc(FunctorCsult, mod));
425 }
else if (IsApplTerm(tg)) {
427 arity_t i, n = ArityOfFunctor(f);
428 CELL *p = RepAppl(tg) + 1;
429 for (i = 0; i < n; i++) {
432 pe = RepPredProp(Yap_GetPredPropByFunc(f, mod));
433 }
else if (IsAtomTerm(tg)) {
434 pe = RepPredProp(Yap_GetPredPropByAtom(AtomOfTerm(tg), mod));
436 Yap_ThrowError(TYPE_ERROR_CALLABLE, tg,
"wake-up");
446static bool interrupt_main(op_numbers op,
yamop *pc USES_REGS) {
447 bool late_creep =
false;
455Yap_track_cpred( op, pc, 0, &info);
458 SET_ASP(YENV,info.env_size);
459 if (LOCAL_PrologMode & InErrorMode) {
462 if ((v = code_overflow(YENV PASS_REGS)) != INT_HANDLER_GO_ON ) {
466 if ((v = stack_overflow(op, P, NULL PASS_REGS) !=
467 INT_HANDLER_GO_ON)) {
469 SET_ASP(info.env ,info.env_size);
478 PredEntry *newp = interrupt_wake_up( pe, NULL, TermTrue PASS_REGS);
480 Yap_signal(YAP_CREEP_SIGNAL);
483 size_t sz = ((size_t)NEXTOP(((
yamop*)NULL),Osbpp))/
sizeof(CELL)+1;
486 memcpy(buf, info.p, (
size_t)NEXTOP(NEXTOP(((
yamop*)NULL),Osbpp),l));
487 buf->y_u.Osbpp.p = newp;
488 yamop *next = NEXTOP(buf,Osbpp)
490 next->y_u.l.l = NEXTOP(info.p,Osbpp);
493 buf->opc = Yap_opcode(_execute);
494 buf->y_u.Osbpp.p = newp;
498 buf->opc = Yap_opcode(_call);
499 buf->y_u.Osbpp.p = newp;
503 buf->y_u.Osbpp.p = newp;
506 buf->y_u.Osbpp.p = newp;
509 buf->opc = Yap_opcode(_call);
510 buf->y_u.Osbpp.p = PredMetaCall;
515 next->opc = Yap_opcode(_jump);
516 next->y_u.l.l = info.p;
522 CalculateStackGap(PASS_REGS1);
528static bool interrupt_fail(USES_REGS1) {
530 if (LOCAL_PrologMode & InErrorMode) {
533 check_alarm_fail_int(
false PASS_REGS);
538 bool creep = Yap_get_signal(YAP_CREEP_SIGNAL);
540 PredEntry *newp = interrupt_wake_up( PredFail, NULL, TermTrue PASS_REGS);
541 if (creep) Yap_signal(YAP_CREEP_SIGNAL);
546 CalculateStackGap(PASS_REGS1);
547 if (newp) P = newp->CodeOfPred;
552static int interrupt_execute(USES_REGS1) {
555 return interrupt_main( _execute, P PASS_REGS);
558static int interrupt_executec(USES_REGS1) {
560 return interrupt_main(_execute_cpred, P PASS_REGS);
563static int interrupt_c_call(USES_REGS1) {
567 return interrupt_main( _call_cpred, P PASS_REGS);
570static int interrupt_user_call(USES_REGS1) {
574 return interrupt_main( _call_usercpred, P PASS_REGS);
578static bool interrupt_call(USES_REGS1) {
580 return interrupt_main( _call, P PASS_REGS) != INT_HANDLER_FAIL;
584static bool interrupt_dexecute(USES_REGS1) {
587 int rc = interrupt_main(_dexecute, P PASS_REGS);
588 return rc == INT_HANDLER_FAIL ? false :
true;
591static bool interrupt_pexecute(USES_REGS1) {
593 return interrupt_main(_p_execute, P PASS_REGS);
594 return INT_HANDLER_FAIL ? false :
true;
599static yamop* interrupt_prune(Term cut_t,
yamop *p USES_REGS) {
602 if (LOCAL_PrologMode & InErrorMode) {
604 PP = P->y_u.Osbpp.p0;
606 return PP->CodeOfPred;
608 if ((v = check_alarm_fail_int(
true PASS_REGS)) != INT_HANDLER_GO_ON) {
611 Term tcut = Yap_MkApplTerm(FunctorCutBy, 1, &cut_t);
612 p = NEXTOP(p, Osblp);
613 interrupt_wake_up( NULL, p, tcut PASS_REGS);
617static yamop * interrupt_cut(USES_REGS1) {
618 yamop *c = NEXTOP(NEXTOP(NEXTOP(P, s),Osbpp),l);
619 return interrupt_prune(MkIntTerm(LCL0-(CELL *)YENV[E_CB]), NEXTOP(P,s) PASS_REGS) == FAILCODE ?FAILCODE : c;
624static yamop * interrupt_cut_t(USES_REGS1) {
625 yamop *c = NEXTOP(NEXTOP(NEXTOP(P, s),Osbpp),l);
626 return interrupt_prune(MkIntTerm(LCL0-(CELL *)YENV[E_CB]), NEXTOP(P,s) PASS_REGS) == FAILCODE ? FAILCODE : c;
629static yamop * interrupt_cut_e(USES_REGS1) {
630 yamop *c = NEXTOP(NEXTOP(NEXTOP(P, s),Osbpp),l);
631 return interrupt_prune(MkIntTerm(LCL0-(CELL *)S[E_CB]), NEXTOP(P,s) PASS_REGS) == FAILCODE ? FAILCODE : c;
635static yamop * interrupt_commit_y(USES_REGS1) {
636 yamop *c = NEXTOP(NEXTOP(NEXTOP(P, yps),Osbpp),l);
637 return interrupt_prune(YENV[P->y_u.yps.y], NEXTOP(P,s) PASS_REGS) == FAILCODE ? FAILCODE : c;
641 static yamop * interrupt_commit_x(USES_REGS1) {
642 yamop *c = NEXTOP(NEXTOP(NEXTOP(P, xps),Osbpp),l);
643 return interrupt_prune(XREG(P->y_u.xps.x), NEXTOP(P,s) PASS_REGS) == FAILCODE ? FAILCODE : c;
646static yamop * interrupt_soft_cut_y(USES_REGS1) {
647 yamop *c = NEXTOP(NEXTOP(NEXTOP(P, yps),Osbpp),l);
648 return interrupt_prune(YENV[P->y_u.yps.y], NEXTOP(P,s) PASS_REGS) == FAILCODE ? FAILCODE : c;
652 static yamop * interrupt_soft_cut_x(USES_REGS1) {
653 yamop *c = NEXTOP(NEXTOP(NEXTOP(P, xps),Osbpp),l);
654 return interrupt_prune(XREG(P->y_u.xps.x), NEXTOP(P,s) PASS_REGS) == FAILCODE ? FAILCODE : c;
659static int interrupt_either(USES_REGS1) {
670 if (LOCAL_PrologMode & InErrorMode) {
674if ( (v=check_alarm_fail_int(
true PASS_REGS)) != INT_HANDLER_GO_ON) {
675 if ( v != INT_HANDLER_FAIL) { PP = PredFail;
return false; }
681 if (Yap_only_has_signal(YAP_CREEP_SIGNAL)) {
692 interrupt_wake_up( ap, NULL, TermTrue PASS_REGS);
693 if ( pe == PredTrue) { PP=ap;
return true; }
694 if ( pe == PredFail) { PP=PredFail;
return false; }
695 if (!pe || Yap_execute_pred(pe, NULL,
true ) ) {
705static void undef_goal(
PredEntry *pe USES_REGS) {
709 BACKUP_MACHINE_REGS();
711 if (pe->PredFlags & (DynamicPredFlag | LogUpdatePredFlag | MultiFileFlag) ) {
712 #if defined(YAPOR) || defined(THREADS)
718#if defined(YAPOR) || defined(THREADS)
722 CalculateStackGap(PASS_REGS1);
723 LOCAL_DoingUndefp =
false;
725 Term tg = save_goal(pe PASS_REGS);
728 UndefHook->OpcodeOfPred != UNDEF_OPCODE) {
732 }
else if (UndefHook0 &&
733 UndefHook0->OpcodeOfPred != UNDEF_OPCODE){
739 P = hook->CodeOfPred;
745#if defined(YAPOR) || defined(THREADS)
749 CalculateStackGap(PASS_REGS1);
750 RECOVER_MACHINE_REGS();
756static void spy_goal(USES_REGS1) {
759#if defined(YAPOR) || defined(THREADS)
765 if (!(pe->PredFlags & IndexedPredFlag) && pe->cs.p_code.NOfClauses > 1) {
768 Yap_IPred(pe, 0, CP);
770 if (P == PredFail->CodeOfPred) {
771#if defined(YAPOR) || defined(THREADS)
772 if (PP && !(PP->PredFlags & LogUpdatePredFlag)) {
781 if ((pe->PredFlags & CountPredFlag)) {
782 LOCK(pe->StatisticsForPred->lock);
783 pe->StatisticsForPred->NOfEntries++;
784 UNLOCK(pe->StatisticsForPred->lock);
785 LOCAL_ReductionsCounter--;
786 if (LOCAL_ReductionsCounter == 0 && LOCAL_ReductionsCounterOn) {
787#if defined(YAPOR) || defined(THREADS)
793 Yap_NilError(CALL_COUNTER_UNDERFLOW_EVENT,
"");
796 LOCAL_PredEntriesCounter--;
797 if (LOCAL_PredEntriesCounter == 0 && LOCAL_PredEntriesCounterOn) {
798#if defined(YAPOR) || defined(THREADS)
804 Yap_NilError(PRED_ENTRY_COUNTER_UNDERFLOW_EVENT,
"");
807 if ((pe->PredFlags & (CountPredFlag | ProfiledPredFlag | SpiedPredFlag)) ==
809#if defined(YAPOR) || defined(THREADS)
815 P = pe->cs.p_code.TrueCodeOfPred
821 if ((pe->PredFlags & ProfiledPredFlag)) {
822 if (!pe->StatisticsForPred)
823 Yap_initProfiler(pe);
824 LOCK(pe->StatisticsForPred->lock);
825 pe->StatisticsForPred->NOfEntries++;
826 UNLOCK(pe->StatisticsForPred->lock);
827 if (!(pe->PredFlags & SpiedPredFlag)) {
828 P = pe->cs.p_code.TrueCodeOfPred
830#if defined(YAPOR) || defined(THREADS)
839#if defined(YAPOR) || defined(THREADS)
845 ARG1 = save_goal(pe PASS_REGS);
850 LOCK(GLOBAL_ThreadHandlesLock);
857 UNLOCK(GLOBAL_ThreadHandlesLock);
859#ifdef LOW_LEVEL_TRACER
860 if (Yap_do_low_level_trace)
861 low_level_trace(enter_pred, pt0, XREGS + 1);
866Int Yap_absmi(
int inp) {
871 yamop *PCBACKUP = P1REG;
874#ifdef LONG_LIVED_REGISTERS
875 register CELL d0, d1;
876 register CELL *pt0, *pt1;
881 register yamop *PREG = P;
885 register yamop *CPREG = CP;
889 register CELL *HBREG = HB;
893 register CELL *YREG = Yap_REGS.YENV_;
897 register CELL *SREG = Yap_REGS.S_;
903#define I_R (XREGS[0])
906 Yap_ExpEnvP = &Yap_ExpEnv;
907 static void *control_labels[] = {
908 &&fail, &&NoStackCut, &&NoStackCommitY,
909 &&NoStackCutT, &&NoStackEithcer, &&NoStackExecute,
910 &&NoStackCall, &&NoStackDExecute, &&NoStackDeallocate,
911 &¬railleft, &&NoStackFail, &&NoStackCommitX};
914 globalcurblock = NULL;
915 ineedredefinedest = 0;
916 NativeArea = (NativeContext *)malloc(
sizeof(NativeContext));
917 NativeArea->area.p = NULL;
918 NativeArea->area.ok = NULL;
919 NativeArea->area.pc = NULL;
921 NativeArea->area.nrecomp = NULL;
922 NativeArea->area.compilation_time = NULL;
923 NativeArea->area.native_size_bytes = NULL;
924 NativeArea->area.trace_size_bytes = NULL;
925 NativeArea->success = NULL;
926 NativeArea->runs = NULL;
927 NativeArea->t_runs = NULL;
930 IntermediatecodeArea =
931 (IntermediatecodeContext *)malloc(
sizeof(IntermediatecodeContext));
932 IntermediatecodeArea->area.t = NULL;
933 IntermediatecodeArea->area.ok = NULL;
934 IntermediatecodeArea->area.isactive = NULL;
935 IntermediatecodeArea->area.lastblock = NULL;
937 IntermediatecodeArea->area.profiling_time = NULL;
939 IntermediatecodeArea->n = 0;
950 static void *OpAddress[] = {
951#define OPCODE(OP, TYPE) &&_##OP
952#include "YapOpcodes.h"
957 ExpEnv.config_struc.TOTAL_OF_OPCODES =
958 sizeof(OpAddress) / (2 *
sizeof(
void *));
974 register REGSTORE *regp = &Yap_REGS;
994 old_regs = &Yap_REGS;
995 init_absmi_regs(&absmi_regs);
997 regcache = Yap_regp LOCAL_PL_local_data_p->reg_cache = regcache;
999 Yap_regp = &absmi_regs;
1003 PREG = bpEntry->CodeOfPred;
1009#if USE_THREADED_CODE
1012 Yap_ABSMI_OPCODES = OpAddress;
1014 Yap_ABSMI_ControlLabels = control_labels;
1024 old_regs = &Yap_REGS;
1027 init_absmi_regs(&absmi_regs);
1031 pthread_setspecific(Yap_yaamregs_key, (
const void *)&absmi_regs);
1032 LOCAL_ThreadHandle.current_yaam_regs = &absmi_regs;
1033 regcache = &absmi_regs;
1036 Yap_regp = &absmi_regs;
1039#define Yap_REGS absmi_regs
1063#if USE_THREADED_CODE
1073 op_numbers opcode = _Ystop;
1076 unsigned long ops_done;
1084 opcode = PREG->y_u.o.opcw;
1095 GLOBAL_opcount[opcode]++;
1096 GLOBAL_2opcount[old_op][opcode]++;
1108#if !OS_HANDLES_TR_OVERFLOW
1121 SET_ASP(YREG, E_CB);
1122 cut_b = LCL0 - (CELL *)(ASP[E_CB]);
1124 if (!Yap_growtrail(0,
false)) {
1125 Yap_ThrowError(RESOURCE_ERROR_TRAIL,
1127 "YAP failed to reserve %ld bytes in growtrail",
1128 sizeof(CELL) * K16);
1137 SREG[E_CB] = (CELL)(LCL0 - cut_b);
1147 #include "absmi_insts.h"
1149#if !USE_THREADED_CODE
1152 Yap_Error(SYSTEM_ERROR_INTERNAL, MkIntegerTerm(opcode),
1153 "trying to execute invalid YAAM instruction %d", opcode);
1161 restore_absmi_regs(old_regs);
1174int Yap_absmiEND(
void) {
return 1; }