YAP 7.1.0
stackinfo.c
1/*************************************************************************
2* *
3* YAP Prolog *
4* *
5* Yap Prolog was developed at NCCUP - Universidade do Porto *
6* *
7* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 *
8* *
9**************************************************************************
10* *
11* File: stack.c *
12* comments: Stack Introspection *
13* *
14* Last rev: $Date: 2008-07-22 23:34:44 $,$Author: vsc $ *
15* $Log: not supported by cvs2svn $ *
16* Revision 1.230 2008/06/02 17:20:28 vsc *
17* *
18* *
19*************************************************************************/
20
31#include "Yap.h"
32#include "clause.h"
33#include "yapio.h"
34#include "YapEval.h"
35#include "tracer.h"
36#ifdef YAPOR
37#include "or.macros.h"
38#endif /* YAPOR */
39#ifdef TABLING
40#include "tab.macros.h"
41#endif /* TABLING */
42#if HAVE_STRING_H
43#include <string.h>
44#endif
45#include <heapgc.h>
46
47static int static_in_use(PredEntry *, int);
48#if !defined(YAPOR) && !defined(THREADS)
49static Int search_for_static_predicate_in_use(PredEntry *, int);
50static void mark_pred(int, PredEntry *);
51static void do_toggle_static_predicates_in_use(int);
52#endif
53static Int in_use( USES_REGS1 );
54static Int toggle_static_predicates_in_use( USES_REGS1 );
55static Int PredForCode(yamop *, Atom *, arity_t *, Term *);
56
57static PredEntry *
58PredForChoicePt(yamop *p_code, op_numbers *opn) {
59 while (TRUE) {
60 op_numbers opnum;
61 if (!p_code)
62 return NULL;
63 opnum = Yap_op_from_opcode(p_code->opc);
64 if (opn)
65 *opn = opnum;
66 switch(opnum) {
67 case _Nstop:
68 return NULL;
69 case _jump:
70 p_code = p_code->y_u.l.l;
71 break;
72 case _retry_me:
73 case _trust_me:
74 return p_code->y_u.Otapl.p;
75 case _retry_exo:
76 case _retry_all_exo:
77 return p_code->y_u.lp.p;
78 case _try_logical:
79 case _retry_logical:
80 case _trust_logical:
81 case _count_retry_logical:
82 case _count_trust_logical:
83 case _profiled_retry_logical:
84 case _profiled_trust_logical:
85 return p_code->y_u.OtaLl.d->ClPred;
86#ifdef TABLING
87 case _trie_trust_var:
88 case _trie_retry_var:
89 case _trie_trust_var_in_pair:
90 case _trie_retry_var_in_pair:
91 case _trie_trust_val:
92 case _trie_retry_val:
93 case _trie_trust_val_in_pair:
94 case _trie_retry_val_in_pair:
95 case _trie_trust_atom:
96 case _trie_retry_atom:
97 case _trie_trust_atom_in_pair:
98 case _trie_retry_atom_in_pair:
99 case _trie_trust_null:
100 case _trie_retry_null:
101 case _trie_trust_null_in_pair:
102 case _trie_retry_null_in_pair:
103 case _trie_trust_pair:
104 case _trie_retry_pair:
105 case _trie_trust_appl:
106 case _trie_retry_appl:
107 case _trie_trust_appl_in_pair:
108 case _trie_retry_appl_in_pair:
109 case _trie_trust_extension:
110 case _trie_retry_extension:
111 case _trie_trust_double:
112 case _trie_retry_double:
113 case _trie_trust_longint:
114 case _trie_retry_longint:
115 case _trie_trust_gterm:
116 case _trie_retry_gterm:
117 return NULL;
118 case _table_load_answer:
119 case _table_try_answer:
120 case _table_answer_resolution:
121 case _table_completion:
122#ifdef THREADS_CONSUMER_SHARING
123 case _table_answer_resolution_completion:
124#endif /* THREADS_CONSUMER_SHARING */
125 return NULL; /* ricroc: is this OK? */
126 /* compile error --> return ENV_ToP(gc_B->cp_cp); */
127#endif /* TABLING */
128 case _or_else:
129 if (p_code == p_code->y_u.Osblp.l) {
130 /* repeat */
131 Atom at = AtomRepeatSpace;
132 return RepPredProp(PredPropByAtom(at, PROLOG_MODULE));
133 } else {
134 return p_code->y_u.Osblp.p0;
135 }
136 break;
137 case _or_last:
138#ifdef YAPOR
139 return p_code->y_u.Osblp.p0;
140#else
141 return p_code->y_u.p.p;
142#endif /* YAPOR */
143 break;
144 case _count_retry_me:
145 case _retry_profiled:
146 case _retry2:
147 case _retry3:
148 case _retry4:
149 p_code = NEXTOP(p_code,l);
150 break;
151 default:
152 return p_code->y_u.Otapl.p;
153 }
154 }
155 return NULL;
156}
157
169PredEntry *
170Yap_PredForChoicePt(choiceptr cp, op_numbers *op) {
171 if (cp == NULL)
172 return NULL;
173 return PredForChoicePt(cp->cp_ap, op);
174}
175
176#if !defined(YAPOR) && !defined(THREADS)
177static yamop *cur_clause(PredEntry *pe, yamop *codeptr)
178{
179 StaticClause *cl;
180
181 cl = ClauseCodeToStaticClause(pe->cs.p_code.FirstClause);
182 do {
183 if (IN_BLOCK(codeptr,cl,cl->ClSize)) {
184 return cl->ClCode;
185 }
186 if (cl->ClCode == pe->cs.p_code.LastClause)
187 break;
188 cl = cl->ClNext;
189 } while (TRUE);
190 Yap_Error(SYSTEM_ERROR_INTERNAL,TermNil,"could not find clause for indexing code");
191 return(NULL);
192}
193
194static yamop *cur_log_upd_clause(PredEntry *pe, yamop *codeptr)
195{
196 LogUpdClause *cl;
197 cl = ClauseCodeToLogUpdClause(pe->cs.p_code.FirstClause);
198 do {
199 if (IN_BLOCK(codeptr,cl->ClCode,cl->ClSize)) {
200 return((yamop *)cl->ClCode);
201 }
202 cl = cl->ClNext;
203 } while (cl != NULL);
204 Yap_Error(SYSTEM_ERROR_INTERNAL,TermNil,"could not find clause for indexing code");
205 return(NULL);
206}
207
208static Int
209search_for_static_predicate_in_use(PredEntry *p, int check_everything)
210{
211 choiceptr b_ptr = B;
212 CELL *env_ptr = ENV;
213
214 if (check_everything && P) {
215 PredEntry *pe = EnvPreg(P);
216 if (p == pe) return TRUE;
217 pe = EnvPreg(CP);
218 if (p == pe) return TRUE;
219 }
220 do {
221 PredEntry *pe;
222
223 /* check first environments that are younger than our latest choicepoint */
224 if (check_everything && env_ptr) {
225 /*
226 I do not need to check environments for asserts,
227 only for retracts
228 */
229 while (env_ptr && b_ptr > (choiceptr)env_ptr) {
230 yamop *cp = (yamop *)env_ptr[E_CP];
231 PredEntry *pe;
232
233 pe = EnvPreg(cp);
234 if (p == pe) return(TRUE);
235 if (env_ptr != NULL)
236 env_ptr = (CELL *)(env_ptr[E_E]);
237 }
238 }
239 /* now mark the choicepoint */
240
241 if (b_ptr)
242 pe = PredForChoicePt(b_ptr->cp_ap, NULL);
243 else
244 return FALSE;
245 if (pe == p) {
246 if (check_everything)
247 return TRUE;
248 PELOCK(38,p);
249 if (p->PredFlags & IndexedPredFlag) {
250 yamop *code_p = b_ptr->cp_ap;
251 yamop *code_beg = p->cs.p_code.TrueCodeOfPred;
252
253 /* FIX ME */
254
255 if (p->PredFlags & LogUpdatePredFlag) {
256 LogUpdIndex *cl = ClauseCodeToLogUpdIndex(code_beg);
257 if (find_owner_log_index(cl, code_p))
258 b_ptr->cp_ap = cur_log_upd_clause(pe, b_ptr->cp_ap->y_u.Otapl.d);
259 } else if (p->PredFlags & MegaClausePredFlag) {
260 StaticIndex *cl = ClauseCodeToStaticIndex(code_beg);
261 if (find_owner_static_index(cl, code_p))
262 b_ptr->cp_ap = cur_clause(pe, b_ptr->cp_ap->y_u.Otapl.d);
263 } else {
264 /* static clause */
265 StaticIndex *cl = ClauseCodeToStaticIndex(code_beg);
266 if (find_owner_static_index(cl, code_p)) {
267 b_ptr->cp_ap = cur_clause(pe, b_ptr->cp_ap->y_u.Otapl.d);
268 }
269 }
270 }
271 UNLOCKPE(63,pe);
272 }
273 env_ptr = b_ptr->cp_env;
274 b_ptr = b_ptr->cp_b;
275 } while (b_ptr != NULL);
276 return(FALSE);
277}
278
279static void
280mark_pred(int mark, PredEntry *pe)
281{
282 /* if the predicate is static mark it */
283 if (pe->ModuleOfPred) {
284 PELOCK(39,p);
285 if (mark) {
286 pe->PredFlags |= InUsePredFlag;
287 } else {
288 pe->PredFlags &= ~InUsePredFlag;
289 }
290 UNLOCK(pe->PELock);
291 }
292}
293
294/* go up the chain of choice_points and environments,
295 marking all static predicates that current execution is depending
296 upon */
297static void
298do_toggle_static_predicates_in_use(int mask)
299{
300 choiceptr b_ptr = B;
301 CELL *env_ptr = ENV;
302
303 if (b_ptr == NULL)
304 return;
305
306 do {
307 PredEntry *pe;
308
309 /* check first environments that are younger than our latest choicepoint */
310 while (b_ptr > (choiceptr)env_ptr) {
311 PredEntry *pe = EnvPreg((yamop *)env_ptr[E_CP]);
312
313 mark_pred(mask, pe);
314 env_ptr = (CELL *)(env_ptr[E_E]);
315 }
316 /* now mark the choicepoint */
317 if ((b_ptr)) {
318 if ((pe = PredForChoicePt(b_ptr->cp_ap, NULL))) {
319 mark_pred(mask, pe);
320 }
321 }
322 env_ptr = b_ptr->cp_env;
323 b_ptr = b_ptr->cp_b;
324 } while (b_ptr != NULL);
325 /* mark or unmark all predicates */
326 STATIC_PREDICATES_MARKED = mask;
327}
328
329#endif /* !defined(YAPOR) && !defined(THREADS) */
330
331 }
332 if (p == NULL) {
333 return 0;
334 }
335 clause_was_found(p, pat, parity);
336 if (p->ModuleOfPred == PROLOG_MODULE)
337 *pmodule = TermProlog;
338 else
339 *pmodule = p->ModuleOfPred;
340 return -1;
341}
342
343/* intruction blocks we found ourselves at */
344static PredEntry *
345walk_got_lu_block(LogUpdIndex *cl, CODEADDR *startp, CODEADDR *endp)
346{
347 PredEntry *pp = cl->ClPred;
348 *startp = (CODEADDR)cl;
349 *endp = (CODEADDR)cl+cl->ClSize;
350 return pp;
351}
352
353/* intruction blocks we found ourselves at */
354static PredEntry *
355walk_got_lu_clause(LogUpdClause *cl, CODEADDR *startp, CODEADDR *endp)
356{
357 *startp = (CODEADDR)cl;
358 *endp = (CODEADDR)cl+cl->ClSize;
359 return cl->ClPred;
360}
361
362/* we hit a meta-call, so we don't know what is happening */
363static PredEntry *
364found_meta_call(CODEADDR *startp, CODEADDR *endp)
365{
366 PredEntry *pp = PredMetaCall;
367 *startp = (CODEADDR)&(pp->OpcodeOfPred);
368 *endp = (CODEADDR)NEXTOP((yamop *)&(pp->OpcodeOfPred),e);
369 return pp;
370}
371
372/* intruction blocks we found ourselves at */
373static PredEntry *
374walk_found_c_pred(PredEntry *pp, CODEADDR *startp, CODEADDR *endp)
375{
376 StaticClause *cl = ClauseCodeToStaticClause(pp->CodeOfPred);
377 *startp = (CODEADDR)&(cl->ClCode);
378 *endp = (CODEADDR)&(cl->ClCode)+cl->ClSize;
379 return pp;
380}
381
382/* we hit a mega-clause, no point in going on */
383static PredEntry *
384found_mega_clause(PredEntry *pp, CODEADDR *startp, CODEADDR *endp)
385{
386 MegaClause *mcl = ClauseCodeToMegaClause(pp->cs.p_code.FirstClause);
387 *startp = (CODEADDR)mcl;
388 *endp = (CODEADDR)mcl+mcl->ClSize;
389 return pp;
390}
391
392/* we hit a mega-clause, no point in going on */
393static PredEntry *
394found_idb_clause(yamop *pc, CODEADDR *startp, CODEADDR *endp)
395{
396 LogUpdClause *cl = ClauseCodeToLogUpdClause(pc);
397
398 *startp = (CODEADDR)cl;
399 *endp = (CODEADDR)cl+cl->ClSize;
400 return cl->ClPred;
401}
402
403/* we hit a expand_index, no point in going on */
404static PredEntry *
405found_expand_index(yamop *pc, CODEADDR *startp, CODEADDR *endp, yamop *codeptr USES_REGS)
406{
407 PredEntry *pp = codeptr->y_u.sssllp.p;
408 if (pc == codeptr) {
409 *startp = (CODEADDR)codeptr;
410 *endp = (CODEADDR)NEXTOP(codeptr,sssllp);
411 }
412 return pp;
413}
414
415/* we hit a expand_index, no point in going on */
416static PredEntry *
417found_fail(yamop *pc, CODEADDR *startp, CODEADDR *endp USES_REGS)
418{
419 PredEntry *pp = RepPredProp(Yap_GetPredPropByAtom(AtomFail,CurrentModule));
420 *startp = *endp = (CODEADDR)FAILCODE;
421 return pp;
422}
423
424/* we hit a expand_index, no point in going on */
425static PredEntry *
426found_owner_op(yamop *pc, CODEADDR *startp, CODEADDR *endp USES_REGS)
427{
428 PredEntry *pp = ((PredEntry *)(Unsigned(pc)-(CELL)(&(((PredEntry *)NULL)->OpcodeOfPred))));
429 *startp = (CODEADDR)&(pp->OpcodeOfPred);
430 *endp = (CODEADDR)NEXTOP((yamop *)&(pp->OpcodeOfPred),e);
431 return pp;
432}
433
434/* we hit a expand_index, no point in going on */
435static PredEntry *
436found_expand(yamop *pc, CODEADDR *startp, CODEADDR *endp USES_REGS)
437{
438 PredEntry *pp = ((PredEntry *)(Unsigned(pc)-(CELL)(&(((PredEntry *)NULL)->cs.p_code.ExpandCode))));
439 *startp = (CODEADDR)&(pp->cs.p_code.ExpandCode);
440 *endp = (CODEADDR)NEXTOP((yamop *)&(pp->cs.p_code.ExpandCode),e);
441 return pp;
442}
443
444static PredEntry *
445found_ystop(yamop *pc, int clause_code, CODEADDR *startp, CODEADDR *endp, PredEntry *pp USES_REGS)
446{
447 if (pc == YESCODE) {
448 pp = RepPredProp(Yap_GetPredPropByAtom(AtomTrue,CurrentModule));
449 *startp = (CODEADDR)YESCODE;
450 *endp = (CODEADDR)YESCODE+(CELL)(NEXTOP((yamop *)NULL,e));
451 return pp;
452 }
453 if (!pp) {
454 /* must be an index */
455 PredEntry **pep = (PredEntry **)pc->y_u.l.l;
456 pp = pep[-1];
457 }
458 if (pp->PredFlags & LogUpdatePredFlag) {
459 if (clause_code) {
460 LogUpdClause *cl = ClauseCodeToLogUpdClause(pc->y_u.l.l);
461 *startp = (CODEADDR)cl;
462 *endp = (CODEADDR)cl+cl->ClSize;
463 } else {
464 LogUpdIndex *cl = ClauseCodeToLogUpdIndex(pc->y_u.l.l);
465 *startp = (CODEADDR)cl;
466 *endp = (CODEADDR)cl+cl->ClSize;
467 }
468 } else if (pp->PredFlags & DynamicPredFlag) {
469 DynamicClause *cl = ClauseCodeToDynamicClause(pc->y_u.l.l);
470 *startp = (CODEADDR)cl;
471 *endp = (CODEADDR)cl+cl->ClSize;
472 } else {
473 if (clause_code) {
474 StaticClause *cl = ClauseCodeToStaticClause(pc->y_u.l.l);
475 *startp = (CODEADDR)cl;
476 *endp = (CODEADDR)cl+cl->ClSize;
477 } else {
478 StaticIndex *cl = ClauseCodeToStaticIndex(pc->y_u.l.l);
479 *startp = (CODEADDR)cl;
480 *endp = (CODEADDR)cl+cl->ClSize;
481 }
482 }
483 return pp;
484}
485
486static PredEntry *
487ClauseInfoForCode(yamop *codeptr, CODEADDR *startp, CODEADDR *endp USES_REGS) {
488 yamop *pc;
489 PredEntry *pp = NULL;
490 int clause_code = FALSE;
491
492 if (codeptr >= COMMA_CODE &&
493 codeptr < FAILCODE) {
494 pp = RepPredProp(Yap_GetPredPropByFunc(FunctorComma,CurrentModule));
495 *startp = (CODEADDR)COMMA_CODE;
496 *endp = (CODEADDR)(FAILCODE-1);
497 return pp;
498 }
499 pc = codeptr;
500#include "walkclause.h"
501 return NULL;
502}
503
504PredEntry *
505Yap_PredEntryForCode(yamop *codeptr, find_pred_type where_from, CODEADDR *startp, CODEADDR *endp) {
506 CACHE_REGS
507 if (where_from == FIND_PRED_FROM_CP) {
508 PredEntry *pp = PredForChoicePt(codeptr, NULL);
509 if (cl_code_in_pred(pp, codeptr, startp, endp)) {
510 return pp;
511 }
512 } else if (where_from == FIND_PRED_FROM_ENV) {
513 PredEntry *pp = EnvPreg(codeptr);
514 if (cl_code_in_pred(pp, codeptr, startp, endp)) {
515 return pp;
516 }
517 } else {
518 return ClauseInfoForCode(codeptr, startp, endp PASS_REGS);
519 }
520 return NULL;
521}
522
531static Int
532p_in_use( USES_REGS1 )
533{ /* '$in_use'(+P,+Mod) */
534 PredEntry *pe;
535 Int out;
536
537 pe = get_pred(Deref(ARG1), Deref(ARG2), "$in_use");
538 if (EndOfPAEntr(pe))
539 return FALSE;
540 PELOCK(25,pe);
541 out = static_in_use(pe,TRUE);
542 UNLOCKPE(42,pe);
543 return(out);
544}
545
546
547static Int
548p_pred_for_code( USES_REGS1 ) {
549 yamop *codeptr;
550 Atom at;
551 arity_t arity;
552 Term tmodule = TermProlog;
553 Int cl;
554 Term t = Deref(ARG1);
555
556 if (IsVarTerm(t)) {
557 return FALSE;
558 } else if (IsApplTerm(t) && FunctorOfTerm(t) == FunctorStaticClause) {
559 codeptr = Yap_ClauseFromTerm(t)->ClCode;
560 } else if (IsIntegerTerm(t)) {
561 codeptr = (yamop *)IntegerOfTerm(t);
562 } else if (IsDBRefTerm(t)) {
563 codeptr = (yamop *)DBRefOfTerm(t);
564 } else {
565 return FALSE;
566 }
567 cl = PredForCode(codeptr, &at, &arity, &tmodule);
568 if (!tmodule) tmodule = TermProlog;
569 if (cl == 0) {
570 return Yap_unify(ARG5,MkIntTerm(0));
571 } else {
572 return(Yap_unify(ARG2,MkAtomTerm(at)) &&
573 Yap_unify(ARG3,MkIntegerTerm(arity)) &&
574 Yap_unify(ARG4,tmodule) &&
575 Yap_unify(ARG5,MkIntegerTerm(cl)));
576 }
577}
578
579#if LOW_PROF
580
581static void
582add_code_in_lu_index(LogUpdIndex *cl, PredEntry *pp)
583{
584 char *code_end = (char *)cl + cl->ClSize;
585 Yap_inform_profiler_of_clause(cl, code_end, pp, GPROF_LU_INDEX);
586 cl = cl->ChildIndex;
587 while (cl != NULL) {
588 add_code_in_lu_index(cl, pp);
589 cl = cl->SiblingIndex;
590 }
591}
592
593static void
594add_code_in_static_index(StaticIndex *cl, PredEntry *pp)
595{
596 char *code_end = (char *)cl + cl->ClSize;
597 Yap_inform_profiler_of_clause(cl, code_end, pp, GPROF_STATIC_INDEX);
598 cl = cl->ChildIndex;
599 while (cl != NULL) {
600 add_code_in_static_index(cl, pp);
601 cl = cl->SiblingIndex;
602 }
603}
604
605
606static void
607add_code_in_pred(PredEntry *pp) {
608 yamop *clcode;
609
610 PELOCK(49,pp);
611 /* check if the codeptr comes from the indexing code */
612
613 /* highly likely this is used for indexing */
614 Yap_inform_profiler_of_clause(&(pp->OpcodeOfPred), &(pp->OpcodeOfPred)+1, pp, GPROF_INIT_OPCODE);
615 if (pp->PredFlags & (CPredFlag|AsmPredFlag)) {
616 char *code_end;
617 StaticClause *cl;
618
619 clcode = pp->CodeOfPred;
620 cl = ClauseCodeToStaticClause(clcode);
621 code_end = (char *)cl + cl->ClSize;
622 Yap_inform_profiler_of_clause(cl, code_end, pp, GPROF_INIT_SYSTEM_CODE);
623 UNLOCK(pp->PELock);
624 return;
625 }
626 Yap_inform_profiler_of_clause(&(pp->cs.p_code.ExpandCode), &(pp->cs.p_code.ExpandCode)+1, pp, GPROF_INIT_EXPAND);
627 clcode = pp->cs.p_code.TrueCodeOfPred;
628 if (pp->PredFlags & IndexedPredFlag) {
629 if (pp->PredFlags & LogUpdatePredFlag) {
630 LogUpdIndex *cl = ClauseCodeToLogUpdIndex(clcode);
631 add_code_in_lu_index(cl, pp);
632 } else {
633 StaticIndex *cl = ClauseCodeToStaticIndex(clcode);
634 add_code_in_static_index(cl, pp);
635 }
636 }
637 clcode = pp->cs.p_code.FirstClause;
638 if (clcode != NULL) {
639 if (pp->PredFlags & LogUpdatePredFlag) {
640 LogUpdClause *cl = ClauseCodeToLogUpdClause(clcode);
641 do {
642 char *code_end;
643
644 code_end = (char *)cl + cl->ClSize;
645 Yap_inform_profiler_of_clause(cl, code_end, pp, GPROF_INIT_LOG_UPD_CLAUSE);
646 cl = cl->ClNext;
647 } while (cl != NULL);
648 } else if (pp->PredFlags & DynamicPredFlag) {
649 do {
650 DynamicClause *cl;
651 CODEADDR code_end;
652
653 cl = ClauseCodeToDynamicClause(clcode);
654 code_end = (CODEADDR)cl + cl->ClSize;
655 Yap_inform_profiler_of_clause(cl, code_end, pp, GPROF_INIT_DYNAMIC_CLAUSE);
656 if (clcode == pp->cs.p_code.LastClause)
657 break;
658 clcode = NextDynamicClause(clcode);
659 } while (TRUE);
660 } else {
661 StaticClause *cl = ClauseCodeToStaticClause(clcode);
662 do {
663 char *code_end;
664
665 code_end = (char *)cl + cl->ClSize;
666 Yap_inform_profiler_of_clause(cl, code_end, pp,GPROF_INIT_STATIC_CLAUSE);
667 if (cl->ClCode == pp->cs.p_code.LastClause)
668 break;
669 cl = cl->ClNext;
670 } while (TRUE);
671 }
672 }
673 UNLOCK(pp->PELock);
674}
675
676
677void
678Yap_dump_code_area_for_profiler(void) {
679 ModEntry *me = CurrentModules;
680
681 while (me) {
682 PredEntry *pp = me->PredForME;
683
684 while (pp != NULL) {
685 /* if (pp->ArityOfPE) {
686 fprintf(stderr,"%s/%d %p\n",
687 RepAtom(NameOfFunctor(pp->FunctorOfPred))->StrOfAE,
688 pp->ArityOfPE,
689 pp);
690 } else {
691 fprintf(stderr,"%s %p\n",
692 RepAtom((Atom)(pp->FunctorOfPred))->StrOfAE,
693 pp);
694 }*/
695 add_code_in_pred(pp);
696 pp = pp->NextPredOfModule;
697 }
698 me = me->NextME;
699 }
700 Yap_inform_profiler_of_clause(COMMA_CODE, FAILCODE, RepPredProp(Yap_GetPredPropByFunc(FunctorComma,0)), GPROF_INIT_COMMA);
701 Yap_inform_profiler_of_clause(FAILCODE, FAILCODE+1, RepPredProp(Yap_GetPredPropByAtom(AtomFail,0)), GPROF_INIT_FAIL);
702}
703
704#endif /* LOW_PROF */
705
706static UInt
707tree_index_ssz(StaticIndex *x)
708{
709 UInt sz = x->ClSize;
710 x = x->ChildIndex;
711 while (x != NULL) {
712 sz += tree_index_ssz(x);
713 x = x->SiblingIndex;
714 }
715 return sz;
716}
717
718static UInt
719index_ssz(StaticIndex *x, PredEntry *pe)
720{
721 UInt sz = 0;
722 yamop *ep = ExpandClausesFirst;
723 if (pe->PredFlags & MegaClausePredFlag) {
724 MegaClause *mcl = ClauseCodeToMegaClause(pe->cs.p_code.FirstClause);
725 if (mcl->ClFlags & ExoMask) {
726 struct index_t *i = ((struct index_t **)(pe->cs.p_code.FirstClause))[0];
727 sz = 0;
728
729 while (i) {
730 sz = i->size+sz;
731 i = i->next;
732 }
733 return sz;
734 }
735 }
736 /* expand clause blocks */
737 while (ep) {
738 if (ep->y_u.sssllp.p == pe)
739 sz += (UInt)NEXTOP((yamop *)NULL,sssllp)+ep->y_u.sssllp.s1*sizeof(yamop *);
740 ep = ep->y_u.sssllp.snext;
741 }
742 /* main indexing tree */
743 sz += tree_index_ssz(x);
744 return sz;
745}
746
747static Int
748static_statistics(PredEntry *pe)
749{
750 CACHE_REGS
751 UInt sz = sizeof(PredEntry), cls = 0, isz = 0;
752 StaticClause *cl = ClauseCodeToStaticClause(pe->cs.p_code.FirstClause);
753
754 if (pe->cs.p_code.NOfClauses > 1 &&
755 pe->cs.p_code.TrueCodeOfPred != pe->cs.p_code.FirstClause) {
756 isz = index_ssz(ClauseCodeToStaticIndex(pe->cs.p_code.TrueCodeOfPred), pe);
757 }
758 if (pe->PredFlags & MegaClausePredFlag) {
759 MegaClause *mcl = ClauseCodeToMegaClause(pe->cs.p_code.FirstClause);
760 return Yap_unify(ARG3, MkIntegerTerm(mcl->ClSize/mcl->ClItemSize)) &&
761 Yap_unify(ARG4, MkIntegerTerm(mcl->ClSize)) &&
762 Yap_unify(ARG5, MkIntegerTerm(isz));
763 }
764 if (pe->cs.p_code.NOfClauses) {
765 do {
766 cls++;
767 sz += cl->ClSize;
768 if (cl->ClCode == pe->cs.p_code.LastClause)
769 break;
770 cl = cl->ClNext;
771 } while (TRUE);
772 }
773 return Yap_unify(ARG3, MkIntegerTerm(cls)) &&
774 Yap_unify(ARG4, MkIntegerTerm(sz)) &&
775 Yap_unify(ARG5, MkIntegerTerm(isz));
776}
777
778static Int
779p_static_pred_statistics( USES_REGS1 )
780{
781 Int out;
782 PredEntry *pe;
783
784 pe = get_pred( Deref(ARG1), Deref(ARG2), "predicate_statistics");
785 if (pe == NIL)
786 return (FALSE);
787 PELOCK(50,pe);
788 if (pe->PredFlags & (DynamicPredFlag|LogUpdatePredFlag|UserCPredFlag|AsmPredFlag|CPredFlag|BinaryPredFlag)) {
789 /* should use '$recordedp' in this case */
790 UNLOCK(pe->PELock);
791 return FALSE;
792 }
793 out = static_statistics(pe);
794 UNLOCK(pe->PELock);
795 return out;
796}
797
798static Int
799p_predicate_erased_statistics( USES_REGS1 )
800{
801 UInt sz = 0, cls = 0;
802 UInt isz = 0, icls = 0;
803 PredEntry *pe;
804 LogUpdClause *cl = DBErasedList;
805 LogUpdIndex *icl = DBErasedIList;
806 Term tpred = ArgOfTerm(2,Deref(ARG1));
807 Term tmod = ArgOfTerm(1,Deref(ARG1));
808
809 if (EndOfPAEntr(pe=get_pred(tpred, tmod, "predicate_erased_statistics")))
810 return FALSE;
811 while (cl) {
812 if (cl->ClPred == pe) {
813 cls++;
814 sz += cl->ClSize;
815 }
816 cl = cl->ClNext;
817 }
818 while (icl) {
819 if (pe == icl->ClPred) {
820 icls++;
821 isz += icl->ClSize;
822 }
823 icl = icl->SiblingIndex;
824 }
825 return
826 Yap_unify(ARG2,MkIntegerTerm(cls)) &&
827 Yap_unify(ARG3,MkIntegerTerm(sz)) &&
828 Yap_unify(ARG4,MkIntegerTerm(icls)) &&
829 Yap_unify(ARG5,MkIntegerTerm(isz));
830}
831
832#ifdef DEBUG
833static Int
834p_predicate_lu_cps( USES_REGS1 )
835{
836 return Yap_unify(ARG1, MkIntegerTerm(Yap_LiveCps)) &&
837 Yap_unify(ARG2, MkIntegerTerm(Yap_FreedCps)) &&
838 Yap_unify(ARG3, MkIntegerTerm(Yap_DirtyCps)) &&
839 Yap_unify(ARG4, MkIntegerTerm(Yap_NewCps));
840}
841#endif
842
843static Int
844p_program_continuation( USES_REGS1 )
845{
846 PredEntry *pe = EnvPreg((yamop *)((ENV_Parent(ENV))[E_CP]));
847 if (pe->ModuleOfPred) {
848 if (!Yap_unify(ARG1,pe->ModuleOfPred))
849 return FALSE;
850 } else {
851 if (!Yap_unify(ARG1,TermProlog))
852 return FALSE;
853 }
854 if (pe->ArityOfPE) {
855 if (!Yap_unify(ARG2,MkAtomTerm(NameOfFunctor(pe->FunctorOfPred))))
856 return FALSE;
857 if (!Yap_unify(ARG3,MkIntegerTerm(ArityOfFunctor(pe->FunctorOfPred))))
858 return FALSE;
859 } else {
860 if (!Yap_unify(ARG2,MkAtomTerm((Atom)pe->FunctorOfPred)))
861 return FALSE;
862 if (!Yap_unify(ARG3,MkIntTerm(0)))
863 return FALSE;
864 }
865 return TRUE;
866}
867
868static Term
869BuildActivePred(PredEntry *ap, CELL *vect)
870{
871 CACHE_REGS
872 arity_t i;
873
874 if (!ap->ArityOfPE) {
875 return MkVarTerm();
876 }
877 for (i = 0; i < ap->ArityOfPE; i++) {
878 Term t = Deref(vect[i]);
879 if (IsVarTerm(t)) {
880 CELL *pt = VarOfTerm(t);
881 /* one stack */
882 if (pt > HR) {
883 Term nt = MkVarTerm();
884 Yap_unify(t, nt);
885 }
886 }
887 }
888 return Yap_MkApplTerm(ap->FunctorOfPred, ap->ArityOfPE, vect);
889}
890
891static int
892UnifyPredInfo(PredEntry *pe, int start_arg USES_REGS) {
893 arity_t arity = pe->ArityOfPE;
894 Term tmod, tname;
895
896 if (pe->ModuleOfPred != IDB_MODULE) {
897 if (pe->ModuleOfPred == PROLOG_MODULE) {
898 tmod = TermProlog;
899 } else {
900 tmod = pe->ModuleOfPred;
901 }
902 if (pe->ArityOfPE == 0) {
903 tname = MkAtomTerm((Atom)pe->FunctorOfPred);
904 } else {
905 Functor f = pe->FunctorOfPred;
906 tname = MkAtomTerm(NameOfFunctor(f));
907 }
908 } else {
909 tmod = pe->ModuleOfPred;
910 if (pe->PredFlags & NumberDBPredFlag) {
911 tname = MkIntegerTerm(pe->src.IndxId);
912 } else if (pe->PredFlags & AtomDBPredFlag) {
913 tname = MkAtomTerm((Atom)pe->FunctorOfPred);
914 } else {
915 Functor f = pe->FunctorOfPred;
916 tname = MkAtomTerm(NameOfFunctor(f));
917 }
918 }
919
920 return Yap_unify(XREGS[start_arg], tmod) &&
921 Yap_unify(XREGS[start_arg+1],tname) &&
922 Yap_unify(XREGS[start_arg+2],MkIntegerTerm(arity));
923}
924
925
926static Int
927ClauseId(yamop *ipc, PredEntry *pe)
928{
929 if (!ipc)
930 return 0;
931 return find_code_in_clause(pe, ipc, NULL, NULL);
932}
933
934static Int
935p_env_info( USES_REGS1 )
936{
937 CELL *env = LCL0-IntegerOfTerm(Deref(ARG1));
938 yamop *env_cp;
939 Term env_b, taddr;
940
941 if (!env)
942 return FALSE;
943 env_b = MkIntegerTerm((Int)(LCL0-(CELL *)env[E_CB]));
944 env_cp = (yamop *)env[E_CP];
945
946 /* pe = PREVOP(env_cp,Osbpp)->y_u.Osbpp.p0; */
947 taddr = MkIntegerTerm((Int)env);
948 return Yap_unify(ARG3,MkIntegerTerm((Int)env_cp)) &&
949 Yap_unify(ARG2, taddr) &&
950 Yap_unify(ARG4, env_b);
951}
952
953static Int
954p_cpc_info( USES_REGS1 )
955{
956 PredEntry *pe;
957 yamop *ipc = (yamop *)IntegerOfTerm(Deref(ARG1));
958
959 pe = PREVOP(ipc,Osbpp)->y_u.Osbpp.p0;
960 return UnifyPredInfo(pe, 2 PASS_REGS) &&
961 Yap_unify(ARG5,MkIntegerTerm(ClauseId(ipc,pe)));
962}
963
964static Int
965p_choicepoint_info( USES_REGS1 )
966{
967 choiceptr cptr = (choiceptr)(LCL0-IntegerOfTerm(Deref(ARG1)));
968 PredEntry *pe = NULL;
969 int go_on = TRUE;
970 yamop *ipc = cptr->cp_ap;
971 yamop *ncl = NULL;
972 Term t = TermNil, taddr;
973
974 taddr = MkIntegerTerm((Int)cptr);
975 while (go_on) {
976 op_numbers opnum = Yap_op_from_opcode(ipc->opc);
977 go_on = FALSE;
978 switch (opnum) {
979#ifdef TABLING
980 case _table_load_answer:
981#ifdef LOW_LEVEL_TRACER
982 pe = LOAD_CP(cptr)->cp_pred_entry;
983#else
984 pe = UndefCode;
985#endif
986 t = MkVarTerm();
987 break;
988 case _table_try_answer:
989 case _table_retry_me:
990 case _table_trust_me:
991 case _table_retry:
992 case _table_trust:
993 case _table_completion:
994#ifdef THREADS_CONSUMER_SHARING
995 case _table_answer_resolution_completion:
996#endif /* THREADS_CONSUMER_SHARING */
997#ifdef LOW_LEVEL_TRACER
998#ifdef DETERMINISTIC_TABLING
999 if (IS_DET_GEN_CP(cptr)) {
1000 pe = DET_GEN_CP(cptr)->cp_pred_entry;
1001 t = MkVarTerm();
1002 } else
1003#endif /* DETERMINISTIC_TABLING */
1004 {
1005 pe = GEN_CP(cptr)->cp_pred_entry;
1006 t = BuildActivePred(pe, (CELL *)(GEN_CP(B) + 1));
1007 }
1008#else
1009 pe = UndefCode;
1010 t = MkVarTerm();
1011#endif
1012 break;
1013 case _table_answer_resolution:
1014#ifdef LOW_LEVEL_TRACER
1015 pe = CONS_CP(cptr)->cp_pred_entry;
1016#else
1017 pe = UndefCode;
1018#endif
1019 t = MkVarTerm();
1020 break;
1021 case _trie_trust_var:
1022 case _trie_retry_var:
1023 case _trie_trust_var_in_pair:
1024 case _trie_retry_var_in_pair:
1025 case _trie_trust_val:
1026 case _trie_retry_val:
1027 case _trie_trust_val_in_pair:
1028 case _trie_retry_val_in_pair:
1029 case _trie_trust_atom:
1030 case _trie_retry_atom:
1031 case _trie_trust_atom_in_pair:
1032 case _trie_retry_atom_in_pair:
1033 case _trie_trust_null:
1034 case _trie_retry_null:
1035 case _trie_trust_null_in_pair:
1036 case _trie_retry_null_in_pair:
1037 case _trie_trust_pair:
1038 case _trie_retry_pair:
1039 case _trie_trust_appl:
1040 case _trie_retry_appl:
1041 case _trie_trust_appl_in_pair:
1042 case _trie_retry_appl_in_pair:
1043 case _trie_trust_extension:
1044 case _trie_retry_extension:
1045 case _trie_trust_double:
1046 case _trie_retry_double:
1047 case _trie_trust_longint:
1048 case _trie_retry_longint:
1049 case _trie_trust_gterm:
1050 case _trie_retry_gterm:
1051 pe = UndefCode;
1052 t = MkVarTerm();
1053 break;
1054#endif /* TABLING */
1055 case _try_logical:
1056 case _retry_logical:
1057 case _trust_logical:
1058 case _count_retry_logical:
1059 case _count_trust_logical:
1060 case _profiled_retry_logical:
1061 case _profiled_trust_logical:
1062 ncl = ipc->y_u.OtaLl.d->ClCode;
1063 pe = ipc->y_u.OtaLl.d->ClPred;
1064 t = BuildActivePred(pe, cptr->cp_args);
1065 break;
1066 case _or_else:
1067 pe = ipc->y_u.Osblp.p0;
1068 ncl = ipc;
1069 t = Yap_MkNewApplTerm(FunctorOr, 2);
1070 break;
1071
1072 case _or_last:
1073#ifdef YAPOR
1074 pe = ipc->y_u.Osblp.p0;
1075#else
1076 pe = ipc->y_u.p.p;
1077#endif
1078 ncl = ipc;
1079 t = Yap_MkNewApplTerm(FunctorOr, 2);
1080 break;
1081 case _retry2:
1082 case _retry3:
1083 case _retry4:
1084 pe = NULL;
1085 t = TermNil;
1086 ipc = NEXTOP(ipc,l);
1087 if (!ncl)
1088 ncl = ipc->y_u.Otapl.d;
1089 go_on = TRUE;
1090 break;
1091 case _jump:
1092 pe = NULL;
1093 t = TermNil;
1094 ipc = ipc->y_u.l.l;
1095 go_on = TRUE;
1096 break;
1097 case _retry_c:
1098 case _retry_userc:
1099 ncl = NEXTOP(ipc,OtapFs);
1100 pe = ipc->y_u.OtapFs.p;
1101 t = BuildActivePred(pe, cptr->cp_args);
1102 break;
1103 case _retry_profiled:
1104 case _count_retry:
1105 pe = NULL;
1106 t = TermNil;
1107 ncl = ipc->y_u.Otapl.d;
1108 ipc = NEXTOP(ipc,p);
1109 go_on = TRUE;
1110 break;
1111 case _retry_me:
1112 case _trust_me:
1113 case _count_retry_me:
1114 case _count_trust_me:
1115 case _profiled_retry_me:
1116 case _profiled_trust_me:
1117 case _retry_and_mark:
1118 case _profiled_retry_and_mark:
1119 case _retry:
1120 case _trust:
1121 if (!ncl)
1122 ncl = ipc->y_u.Otapl.d;
1123 pe = ipc->y_u.Otapl.p;
1124 t = BuildActivePred(pe, cptr->cp_args);
1125 break;
1126 case _retry_exo:
1127 case _retry_all_exo:
1128 ncl = NULL;
1129 pe = ipc->y_u.lp.p;
1130 t = BuildActivePred(pe, cptr->cp_args);
1131 break;
1132 case _Nstop:
1133 {
1134 Atom at = AtomLive;
1135 t = MkAtomTerm(at);
1136 pe = RepPredProp(PredPropByAtom(at, CurrentModule));
1137 }
1138 break;
1139 case _Ystop:
1140 default:
1141 return FALSE;
1142 }
1143 }
1144 return UnifyPredInfo(pe, 3 PASS_REGS) &&
1145 Yap_unify(ARG2, taddr) &&
1146 Yap_unify(ARG6,t) &&
1147 Yap_unify(ARG7,MkIntegerTerm(ClauseId(ncl,pe)));
1148}
1149
1150void
1151Yap_InitCdMgr(void)
1152{
1153 CACHE_REGS
1154 Term cm = CurrentModule;
1155
1156 Yap_InitCPred("in_use", 2, in_use, HiddenPredFlag|TestPredFlag | SafePredFlag|SyncPredFlag);
1157 Yap_InitCPred("toggle_static_predicates_in_use", 0, p_toggle_static_predicates_in_use, HiddenPredFlag|SafePredFlag|SyncPredFlag);
1158
1159}
Main definitions.
PredEntry * Yap_PredForChoicePt(choiceptr cp, op_numbers *op)
Yap_v<<ChoicePt(): find out the predicate who generated a CP.
Definition: stack.c:307
Module property: low-level data used to manage modes.
Definition: Yatom.h:209
struct mod_entry * NextME
Module local flags (from SWI compat)
Definition: Yatom.h:220
struct pred_entry * PredForME
kind of property
Definition: Yatom.h:212
Definition: Yatom.h:544
Definition: amidefs.h:264