From cf669ee72bfa3b8fc55c88a8e9e370714635a6df Mon Sep 17 00:00:00 2001 From: vsc Date: Mon, 6 Mar 2006 14:04:57 +0000 Subject: [PATCH] fixes to garbage collector fixes to debugger git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@1558 b08c6af1-5177-4d33-ba66-4b1c6b8b522a --- C/cdmgr.c | 158 ++++++++++++++++++++++++++++++++++++++++++++++- C/exec.c | 2 + C/grow.c | 2 + C/heapgc.c | 25 ++++---- C/save.c | 8 +++ H/Heap.h | 9 ++- H/rheap.h | 10 ++- changes-5.1.html | 36 ++++++----- docs/yap.tex | 9 ++- pl/debug.yap | 73 +++++++++++++++++++--- 10 files changed, 290 insertions(+), 42 deletions(-) diff --git a/C/cdmgr.c b/C/cdmgr.c index 29cd5856e..cb9ffcab6 100644 --- a/C/cdmgr.c +++ b/C/cdmgr.c @@ -11,8 +11,11 @@ * File: cdmgr.c * * comments: Code manager * * * -* Last rev: $Date: 2006-02-01 13:28:56 $,$Author: vsc $ * +* Last rev: $Date: 2006-03-06 14:04:56 $,$Author: vsc $ * * $Log: not supported by cvs2svn $ +* Revision 1.176 2006/02/01 13:28:56 vsc +* bignum support fixes +* * Revision 1.175 2006/01/08 03:12:00 vsc * fix small bug in attvar handling. * @@ -3207,7 +3210,7 @@ all_cps(choiceptr b_ptr) bp = H; H += 2; /* notice that MkIntegerTerm may increase the Heap */ - bp[0] = MkIntegerTerm((Int)b_ptr->cp_ap); + bp[0] = MkIntegerTerm((Int)(LCL0-(CELL *)b_ptr)); if (H >= ASP) { bp[1] = TermNil; return tf; @@ -3243,6 +3246,12 @@ Yap_all_calls(void) return all_calls(); } +static Int +p_all_choicepoints(void) +{ + return Yap_unify(ARG1,all_cps(B)); +} + static Int p_current_stack(void) { @@ -5311,6 +5320,149 @@ p_program_continuation(void) return TRUE; } +static Term +BuildActivePred(PredEntry *ap, CELL *vect) +{ + if (!ap->ArityOfPE) { + return MkVarTerm(); + } + return Yap_MkApplTerm(ap->FunctorOfPred, ap->ArityOfPE, vect); +} + +static Int +p_choicepoint_info(void) +{ + choiceptr cptr = (choiceptr)(LCL0-IntegerOfTerm(Deref(ARG1))); + PredEntry *pe; + int go_on = TRUE; + yamop *ipc = cptr->cp_ap; + Term t, tname, tmod; + UInt arity; + + while (go_on) { + op_numbers opnum = Yap_op_from_opcode(ipc->opc); + + go_on = FALSE; + switch (opnum) { +#ifdef TABLING + case _table_load_answer: + pe = LOAD_CP(cptr)->cp_pred_entry; + t = MkVarTerm(); + break; + case _table_try_answer: + case _table_retry_me: + case _table_trust_me: + case _table_retry: + case _table_trust: + case _table_completion: + pe = GEN_CP(cptr)->cp_pred_entry; + t = BuildActivePred(pe, (CELL *)(GEN_CP(B) + 1)); + break; + case _table_answer_resolution: + pe = CONS_CP(cptr)->cp_pred_entry; + t = MkVarTerm(); + break; + case _trie_retry_null: + case _trie_trust_null: + case _trie_retry_var: + case _trie_trust_var: + case _trie_retry_val: + case _trie_trust_val: + case _trie_retry_atom: + case _trie_trust_atom: + case _trie_retry_list: + case _trie_trust_list: + case _trie_retry_struct: + case _trie_trust_struct: + case _trie_retry_extension: + case _trie_trust_extension: + case _trie_retry_float: + case _trie_trust_float: + case _trie_retry_long: + case _trie_trust_long: + pe = UndefCode; + t = MkVarTerm(); + break; +#endif /* TABLING */ + case _or_else: + pe = ipc->u.sla.p0; + t = Yap_MkNewApplTerm(FunctorOr, 2); + break; + case _or_last: + pe = ipc->u.p.p; + t = Yap_MkNewApplTerm(FunctorOr, 2); + break; + case _retry2: + case _retry3: + case _retry4: + case _trust_logical_pred: + ipc = NEXTOP(ipc,l); + go_on = TRUE; + break; + case _jump: + ipc = ipc->u.l.l; + go_on = TRUE; + break; + case _retry_c: + case _retry_userc: + pe = ipc->u.lds.p; + t = BuildActivePred(pe, cptr->cp_args); + break; + case _retry_profiled: + case _count_retry: + ipc = NEXTOP(ipc,p); + go_on = TRUE; + break; + case _retry_me: + case _trust_me: + case _count_retry_me: + case _count_trust_me: + case _profiled_retry_me: + case _profiled_trust_me: + case _retry_and_mark: + case _profiled_retry_and_mark: + case _retry: + case _trust: + pe = ipc->u.ld.p; + t = BuildActivePred(pe, cptr->cp_args); + break; + case _Nstop: + case _Ystop: + default: + pe = NULL; + return FALSE; + } + } + arity = pe->ArityOfPE; + if (pe->ModuleOfPred != IDB_MODULE) { + if (pe->ModuleOfPred == PROLOG_MODULE) { + tmod = TermProlog; + } else { + tmod = pe->ModuleOfPred; + } + if (pe->ArityOfPE == 0) { + tname = MkAtomTerm((Atom)pe->FunctorOfPred); + } else { + Functor f = pe->FunctorOfPred; + tname = MkAtomTerm(NameOfFunctor(f)); + } + } else { + tmod = pe->ModuleOfPred; + if (pe->PredFlags & NumberDBPredFlag) { + tname = MkIntegerTerm(pe->src.IndxId); + } else if (pe->PredFlags & AtomDBPredFlag) { + tname = MkAtomTerm((Atom)pe->FunctorOfPred); + } else { + Functor f = pe->FunctorOfPred; + tname = MkAtomTerm(NameOfFunctor(f)); + } + } + return Yap_unify(ARG2, tmod) && + Yap_unify(ARG3,tname) && + Yap_unify(ARG4,MkIntegerTerm(arity)) && + Yap_unify(ARG5,t); +} + void Yap_InitCdMgr(void) { @@ -5367,6 +5519,8 @@ Yap_InitCdMgr(void) Yap_InitCPred("$static_pred_statistics", 5, p_static_pred_statistics, SyncPredFlag|HiddenPredFlag); Yap_InitCPred("$p_nth_clause", 4, p_nth_clause, SyncPredFlag|HiddenPredFlag); Yap_InitCPred("$program_continuation", 3, p_program_continuation, SafePredFlag|SyncPredFlag|HiddenPredFlag); + Yap_InitCPred("$all_choicepoints", 1, p_all_choicepoints, HiddenPredFlag); + Yap_InitCPred("$choicepoint_info", 5, p_choicepoint_info, HiddenPredFlag); #ifdef DEBUG Yap_InitCPred("predicate_erased_statistics", 5, p_predicate_erased_statistics, SyncPredFlag); #endif diff --git a/C/exec.c b/C/exec.c index 7d519be6a..534c31649 100644 --- a/C/exec.c +++ b/C/exec.c @@ -1796,6 +1796,8 @@ Yap_InitYaamRegs(void) AttsMutableList = Yap_NewTimedVar(MkIntTerm(0)); #endif GcGeneration = Yap_NewTimedVar(MkIntTerm(0)); + GcCurrentPhase = 0L; + GcPhase = Yap_NewTimedVar(MkIntTerm(GcCurrentPhase)); #if defined(YAPOR) || defined(THREADS) PP = NULL; WPP = NULL; diff --git a/C/grow.c b/C/grow.c index 37d8d1023..e9042efc9 100644 --- a/C/grow.c +++ b/C/grow.c @@ -165,6 +165,7 @@ SetHeapRegs(void) WokenGoals = AbsAppl(PtoGloAdjust(RepAppl(WokenGoals))); #endif GcGeneration = AbsAppl(PtoGloAdjust(RepAppl(GcGeneration))); + GcPhase = AbsAppl(PtoGloAdjust(RepAppl(GcPhase))); } static void @@ -218,6 +219,7 @@ SetStackRegs(void) WokenGoals = AbsAppl(PtoGloAdjust(RepAppl(WokenGoals))); #endif GcGeneration = AbsAppl(PtoGloAdjust(RepAppl(GcGeneration))); + GcPhase = AbsAppl(PtoGloAdjust(RepAppl(GcPhase))); } static void diff --git a/C/heapgc.c b/C/heapgc.c index 048702633..f366abeee 100644 --- a/C/heapgc.c +++ b/C/heapgc.c @@ -433,6 +433,8 @@ push_registers(Int num_regs, yamop *nextop) } TrailTerm(TR) = GcGeneration; TR++; + TrailTerm(TR) = GcPhase; + TR++; #ifdef COROUTINING TrailTerm(TR) = WokenGoals; TrailTerm(TR+1) = AttsMutableList; @@ -495,6 +497,7 @@ pop_registers(Int num_regs, yamop *nextop) sal = sal->NextAE; } GcGeneration = TrailTerm(ptr++); + GcPhase = TrailTerm(ptr++); #ifdef COROUTINING #ifdef MULTI_ASSIGNMENT_VARIABLES WokenGoals = TrailTerm(ptr++); @@ -3495,6 +3498,7 @@ do_gc(Int predarity, CELL *current_env, yamop *nextop) CELL *max; Int effectiveness, tot; int gc_trace; + UInt gc_phase; heap_cells = H-H0; gc_verbose = is_gc_verbose(); @@ -3632,19 +3636,10 @@ do_gc(Int predarity, CELL *current_env, yamop *nextop) #endif /* get the number of active registers */ HGEN = H0+IntegerOfTerm(Yap_ReadTimedVar(GcGeneration)); + gc_phase = (UInt)IntegerOfTerm(Yap_ReadTimedVar(GcPhase)); /* old HGEN are not very reliable, but still may have data to recover */ - if (HGEN < HB) { - choiceptr b_ptr = B; - /* cannot trust the data between HGEN and its current choice-point */ - while (b_ptr) { - if (b_ptr->cp_h <= HGEN) { - HGEN = b_ptr->cp_h; - break; - } else { - b_ptr = b_ptr->cp_b; - } - } - if (!b_ptr) HGEN = H0; + if (gc_phase != GcCurrentPhase) { + HGEN = H0; } /* fprintf(stderr,"HGEN is %ld, %p, %p/%p\n", IntegerOfTerm(Yap_ReadTimedVar(GcGeneration)), HGEN, H,H0);*/ #if !GC_TAGS @@ -3657,7 +3652,10 @@ do_gc(Int predarity, CELL *current_env, yamop *nextop) total_marked -= total_oldies; tot = total_marked+(HGEN-H0); } else { - HGEN = H0; + if (HGEN != H0) { + HGEN = H0; + GcCurrentPhase++; + } tot = total_marked; } m_time = Yap_cputime(); @@ -3698,6 +3696,7 @@ do_gc(Int predarity, CELL *current_env, yamop *nextop) #endif /* fprintf(Yap_stderr,"NEW HGEN %ld (%ld)\n", H-H0, HGEN-H0);*/ Yap_UpdateTimedVar(GcGeneration, MkIntegerTerm(H-H0)); + Yap_UpdateTimedVar(GcPhase, MkIntegerTerm(GcCurrentPhase)); c_time = Yap_cputime(); if (gc_verbose) { fprintf(Yap_stderr, "%% Compress: took %g sec\n", (double)(c_time-time_start)/1000); diff --git a/C/save.c b/C/save.c index b95993cae..dfe076556 100644 --- a/C/save.c +++ b/C/save.c @@ -423,6 +423,8 @@ save_regs(int mode) putout(DEPTH); #endif putout(GcGeneration); + putout(GcPhase); + putout(GcCurrentPhase); } /* The operand base */ putcellptr(CellPtr(XREGS)); @@ -832,6 +834,12 @@ get_regs(int flag) GcGeneration = get_cell(); if (Yap_ErrorMessage) return -1; + GcPhase = get_cell(); + if (Yap_ErrorMessage) + return -1; + GcCurrentPhase = get_cell(); + if (Yap_ErrorMessage) + return -1; } /* Get the old bases */ OldXREGS = get_cellptr(); diff --git a/H/Heap.h b/H/Heap.h index 5e9bc6ee2..ad3935267 100644 --- a/H/Heap.h +++ b/H/Heap.h @@ -10,7 +10,7 @@ * File: Heap.h * * mods: * * comments: Heap Init Structure * -* version: $Id: Heap.h,v 1.91 2006-02-24 14:03:42 vsc Exp $ * +* version: $Id: Heap.h,v 1.92 2006-03-06 14:04:56 vsc Exp $ * *************************************************************************/ /* information that can be stored in Code Space */ @@ -98,6 +98,8 @@ typedef struct worker_local_struct { #endif /* gc_stuff */ Term gc_generation; /* global stack limit at last generation */ + Term gc_phase; /* gc phase to be sure we are on a valid compression */ + UInt gc_current_phase; /* gc currrent phase */ unsigned int gc_calls; /* number of times GC has been called */ Int tot_gc_time; /* total time spent in GC */ YAP_ULONG_LONG tot_gc_recovered; /* number of heap objects in all garbage collections */ @@ -785,7 +787,10 @@ struct various_codes *Yap_heap_regs; #define WokenGoals Yap_heap_regs->wl[worker_id].woken_goals #define AttsMutableList Yap_heap_regs->wl[worker_id].atts_mutable_list #endif +/* support for generations with backtracking */ #define GcGeneration Yap_heap_regs->wl[worker_id].gc_generation +#define GcPhase Yap_heap_regs->wl[worker_id].gc_phase +#define GcCurrentPhase Yap_heap_regs->wl[worker_id].gc_current_phase #define GcCalls Yap_heap_regs->wl[worker_id].gc_calls #define TotGcTime Yap_heap_regs->wl[worker_id].tot_gc_time #define TotGcRecovered Yap_heap_regs->wl[worker_id].tot_gc_recovered @@ -854,6 +859,8 @@ struct various_codes *Yap_heap_regs; #define AttsMutableList Yap_heap_regs->wl.atts_mutable_list #endif #define GcGeneration Yap_heap_regs->wl.gc_generation +#define GcPhase Yap_heap_regs->wl.gc_phase +#define GcCurrentPhase Yap_heap_regs->wl.gc_current_phase #define GcCalls Yap_heap_regs->wl.gc_calls #define TotGcTime Yap_heap_regs->wl.tot_gc_time #define TotGcRecovered Yap_heap_regs->wl.tot_gc_recovered diff --git a/H/rheap.h b/H/rheap.h index 4517f6548..17dd151ae 100644 --- a/H/rheap.h +++ b/H/rheap.h @@ -11,8 +11,11 @@ * File: rheap.h * * comments: walk through heap code * * * -* Last rev: $Date: 2006-02-24 14:03:42 $,$Author: vsc $ * +* Last rev: $Date: 2006-03-06 14:04:56 $,$Author: vsc $ * * $Log: not supported by cvs2svn $ +* 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. @@ -493,6 +496,11 @@ restore_codes(void) Yap_heap_regs->wl.scratchpad.ptr = (char *)AddrAdjust((ADDR)Yap_heap_regs->wl.scratchpad.ptr); } + Yap_heap_regs->wl.gc_generation = + AbsAppl(PtoGloAdjust(RepAppl(Yap_heap_regs->wl.gc_generation))); + Yap_heap_regs->wl.gc_phase = + AbsAppl(PtoGloAdjust(RepAppl(Yap_heap_regs->wl.gc_phase))); + /* current phase is an integer */ #endif #ifdef COROUTINING if (Yap_heap_regs->wake_up_code != NULL) diff --git a/changes-5.1.html b/changes-5.1.html index f263436c6..987dc4365 100644 --- a/changes-5.1.html +++ b/changes-5.1.html @@ -16,41 +16,49 @@

Yap-5.1.0: