diff --git a/C/adtdefs.c b/C/adtdefs.c index 45a8de61c..0f9a35665 100644 --- a/C/adtdefs.c +++ b/C/adtdefs.c @@ -30,7 +30,6 @@ ADDR STD_PROTO(Yap_PreAllocCodeSpace, (void)); Prop STD_PROTO(PredPropByFunc,(Functor, Term)); Prop STD_PROTO(PredPropByAtom,(Atom, Term)); #include "Yatom.h" -#include "Heap.h" #include "yapio.h" #include #include @@ -486,31 +485,6 @@ Yap_GetPredPropByAtomInThisModule(Atom at, Term cur_mod) } -static inline Prop -GetPredPropByFuncHavingLock(Functor f, Term cur_mod) -/* get predicate entry for ap/arity; create it if neccessary. */ -{ - Prop p0; - FunctorEntry *fe = (FunctorEntry *)f; - - p0 = fe->PropsOfFE; - while (p0) { - PredEntry *p = RepPredProp(p0); - if (/* p->KindOfPE != 0 || only props */ - (p->ModuleOfPred == cur_mod || !(p->ModuleOfPred))) { -#if THREADS - /* Thread Local Predicates */ - if (p->PredFlags & ThreadLocalPredFlag) { - return AbsPredProp(Yap_GetThreadPred(p)); - } -#endif - return (p0); - } - p0 = p->NextOfPE; - } - return(NIL); -} - Prop Yap_GetPredPropByFunc(Functor f, Term cur_mod) /* get predicate entry for ap/arity; */ @@ -523,30 +497,6 @@ Yap_GetPredPropByFunc(Functor f, Term cur_mod) return (p0); } -static inline Prop -GetPredPropByFuncHavingLockInThisModule(Functor f, Term cur_mod) -/* get predicate entry for ap/arity; create it if neccessary. */ -{ - Prop p0; - FunctorEntry *fe = (FunctorEntry *)f; - - p0 = fe->PropsOfFE; - while (p0) { - PredEntry *p = RepPredProp(p0); - if (p->ModuleOfPred == cur_mod) { -#if THREADS - /* Thread Local Predicates */ - if (p->PredFlags & ThreadLocalPredFlag) { - return AbsPredProp(Yap_GetThreadPred(p)); - } -#endif - return (p0); - } - p0 = p->NextOfPE; - } - return(NIL); -} - Prop Yap_GetPredPropByFuncInThisModule(Functor f, Term cur_mod) /* get predicate entry for ap/arity; */ @@ -554,7 +504,7 @@ Yap_GetPredPropByFuncInThisModule(Functor f, Term cur_mod) Prop p0; READ_LOCK(f->FRWLock); - p0 = GetPredPropByFuncHavingLockInThisModule(f, cur_mod); + p0 = GetPredPropByFuncHavingLock(f, cur_mod); READ_UNLOCK(f->FRWLock); return (p0); } @@ -607,11 +557,40 @@ Yap_GetExpPropHavingLock(AtomEntry *ae, unsigned int arity) return (p0); } +static void +ExpandPredHash(void) +{ + UInt new_size = PredHashTableSize+PredHashIncrement; + PredEntry **oldp = PredHash; + PredEntry **np = (PredEntry **) Yap_AllocAtomSpace(sizeof(PredEntry **)*new_size); + UInt i; + + if (!np) { + Yap_Error(FATAL_ERROR,TermNil,"Could not allocate space for pred table"); + } + for (i = 0; i < new_size; i++) { + np[i] = NULL; + } + for (i = 0; i < PredHashTableSize; i++) { + PredEntry *p = PredHash[i]; + + while (p) { + Prop nextp = p->NextOfPE; + UInt hsh = PRED_HASH(p->FunctorOfPred, p->ModuleOfPred, new_size); + p->NextOfPE = AbsPredProp(np[hsh]); + np[hsh] = p; + p = RepPredProp(nextp); + } + } + PredHashTableSize = new_size; + PredHash = np; + Yap_FreeAtomSpace((ADDR)oldp); +} + /* fe is supposed to be locked */ Prop Yap_NewPredPropByFunctor(FunctorEntry *fe, Term cur_mod) { - Prop p0; PredEntry *p = (PredEntry *) Yap_AllocAtomSpace(sizeof(*p)); INIT_RWLOCK(p->PRWLock); @@ -643,15 +622,39 @@ Yap_NewPredPropByFunctor(FunctorEntry *fe, Term cur_mod) p->beamTable = NULL; #endif /* BEAM */ /* careful that they don't cross MkFunctor */ - p->NextOfPE = fe->PropsOfFE; if (PRED_GOAL_EXPANSION_FUNC) { if (fe->PropsOfFE && (RepPredProp(fe->PropsOfFE)->PredFlags & GoalExPredFlag)) { p->PredFlags |= GoalExPredFlag; } } - fe->PropsOfFE = p0 = AbsPredProp(p); - p->FunctorOfPred = (Functor)fe; + p->FunctorOfPred = fe; + if (fe->PropsOfFE) { + UInt hsh = PRED_HASH(fe, cur_mod, PredHashTableSize); + + WRITE_LOCK(PredHashRWLock); + if (p->ModuleOfPred == 0L) { + PredEntry *pe = RepPredProp(fe->PropsOfFE); + + hsh = PRED_HASH(fe, pe->ModuleOfPred, PredHashTableSize); + /* should be the first one */ + pe->NextOfPE = AbsPredProp(PredHash[hsh]); + PredHash[hsh] = pe; + fe->PropsOfFE = AbsPredProp(p); + } else { + p->NextOfPE = AbsPredProp(PredHash[hsh]); + PredHash[hsh] = p; + } + PredsInHashTable++; + if (10*PredsInHashTable > 6*PredHashTableSize) + ExpandPredHash(); + WRITE_UNLOCK(PredHashRWLock); + /* make sure that we have something here */ + RepPredProp(fe->PropsOfFE)->NextOfPE = fe->PropsOfFE; + } else { + fe->PropsOfFE = AbsPredProp(p); + p->NextOfPE = NIL; + } WRITE_UNLOCK(fe->FRWLock); #ifdef LOW_PROF if (ProfilerOn && @@ -662,7 +665,7 @@ Yap_NewPredPropByFunctor(FunctorEntry *fe, Term cur_mod) } } #endif /* LOW_PROF */ - return p0; + return AbsPredProp(p); } #if THREADS @@ -785,21 +788,32 @@ Prop Yap_PredPropByFunctorNonThreadLocal(Functor f, Term cur_mod) /* get predicate entry for ap/arity; create it if neccessary. */ { - Prop p0; - FunctorEntry *fe = (FunctorEntry *)f; + PredEntry *p; - WRITE_LOCK(fe->FRWLock); - p0 = fe->PropsOfFE; - while (p0) { - PredEntry *p = RepPredProp(p0); - if (/* p->KindOfPE != 0 || only props */ - (p->ModuleOfPred == cur_mod || !(p->ModuleOfPred))) { - WRITE_UNLOCK(fe->FRWLock); - return (p0); - } - p0 = p->NextOfPE; + WRITE_LOCK(f->FRWLock); + if (!(p = RepPredProp(f->PropsOfFE))) + return Yap_NewPredPropByFunctor(f,cur_mod); + + if ((p->ModuleOfPred == cur_mod || !(p->ModuleOfPred))) { + return AbsPredProp(p); } - return Yap_NewPredPropByFunctor(fe,cur_mod); + if (p->NextOfPE) { + UInt hash = PRED_HASH(f,cur_mod,PredHashTableSize); + READ_LOCK(PredHashRWLock); + p = PredHash[hash]; + + while (p) { + if (p->FunctorOfPred == f && + p->ModuleOfPred == cur_mod) + { + READ_UNLOCK(PredHashRWLock); + return AbsPredProp(p); + } + p = RepPredProp(p->NextOfPE); + } + READ_UNLOCK(PredHashRWLock); + } + return Yap_NewPredPropByFunctor(f,cur_mod); } Prop diff --git a/C/agc.c b/C/agc.c index c216b3d2f..b8b9c07dd 100644 --- a/C/agc.c +++ b/C/agc.c @@ -116,6 +116,7 @@ AtomAdjust(Atom a) #define CharP(X) ((char *)(X)) #define AddrAdjust(P) (P) +#define PredEntryAdjust(P) (P) #define AtomEntryAdjust(P) (P) #define GlobalEntryAdjust(P) (P) #define BlobTermAdjust(P) (P) @@ -202,6 +203,25 @@ mark_hash_entry(AtomHashEntry *HashPtr) } } + +static void +mark_hash_preds(void) +{ + UInt i; + + for (i = 0; i < PredHashTableSize; i++) { + PredEntry *p = PredHash[i]; + + while (p) { + Prop nextp = p->NextOfPE = PropAdjust(p->NextOfPE); + CleanCode(p); + p = RepPredProp(nextp); + } + } +} + + + /* * This is the really tough part, to restore the whole of the heap */ @@ -222,6 +242,7 @@ mark_atoms(void) HashPtr++; } mark_hash_entry(&INVISIBLECHAIN); + mark_hash_preds(); } static void diff --git a/C/init.c b/C/init.c index 0a0cd10bf..ce1e1277c 100644 --- a/C/init.c +++ b/C/init.c @@ -1382,8 +1382,17 @@ Yap_InitWorkspace(int Heap, int Stack, int Trail, int max_table_size, INIT_RWLOCK(WideHashChain[i].AERWLock); WideHashChain[i].Entry = NIL; } + PredHash = (PredEntry **)Yap_AllocAtomSpace(sizeof(PredEntry **) * PredHashInitialSize); + PredHashTableSize = PredHashInitialSize; + if (PredHash == NULL) { + Yap_Error(FATAL_ERROR,MkIntTerm(0),"allocating initial predicate hash table"); + } + for (i = 0; i < PredHashTableSize; ++i) { + PredHash[i] = NULL; + } NOfAtoms = 0; NOfWideAtoms = 0; + PredsInHashTable = 0; #if THREADS SF_STORE->AtFoundVar = Yap_LookupAtom("."); Yap_ReleaseAtom(AtomFoundVar); diff --git a/C/save.c b/C/save.c index 64ec3322f..92718a4c5 100644 --- a/C/save.c +++ b/C/save.c @@ -1281,6 +1281,41 @@ RestoreAtomList(Atom atm) } +static void +RestoreHashPreds(void) +{ + UInt new_size = PredHashTableSize; + PredEntry **oldp = (PredEntry **)AddrAdjust((ADDR)PredHash); + PredEntry **np = (PredEntry **) Yap_AllocAtomSpace(sizeof(PredEntry **)*new_size); + UInt i; + + if (!np) { + Yap_Error(FATAL_ERROR,TermNil,"Could not allocate space for pred table"); + } + for (i = 0; i < new_size; i++) { + np[i] = NULL; + } + for (i = 0; i < PredHashTableSize; i++) { + PredEntry *p = PredHash[i]; + + p = PredEntryAdjust(p); + while (p) { + Prop nextp = p->NextOfPE = PropAdjust(p->NextOfPE); + UInt hsh; + + CleanCode(p); + hsh = PRED_HASH(p->FunctorOfPred, p->ModuleOfPred, new_size); + p->NextOfPE = AbsPredProp(np[hsh]); + np[hsh] = p; + p = RepPredProp(nextp); + } + } + PredHashTableSize = new_size; + PredHash = np; + Yap_FreeAtomSpace((ADDR)oldp); +} + + /* * This is the really tough part, to restore the whole of the heap */ @@ -1302,6 +1337,7 @@ restore_heap(void) } INVISIBLECHAIN.Entry = AtomAdjust(INVISIBLECHAIN.Entry); RestoreAtomList(INVISIBLECHAIN.Entry); + RestoreHashPreds(); RestoreForeignCodeStructure(); RestoreIOStructures(); } diff --git a/H/Heap.h b/H/Heap.h index 8fab6873b..9a40e066f 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.116 2007-09-17 22:17:49 vsc Exp $ * +* version: $Id: Heap.h,v 1.117 2007-09-28 23:18:17 vsc Exp $ * *************************************************************************/ /* information that can be stored in Code Space */ @@ -527,6 +527,11 @@ typedef struct various_codes { ADDR foreign_code_base; ADDR foreign_code_top; ADDR foreign_code_max; + struct pred_entry **pred_hash; +#if defined(YAPOR) || defined(THREADS) + rwlock_t pred_hash_rw_lock; +#endif + UInt preds_in_hash_table, pred_hash_table_size; int parser_error_style; int compiler_profiling; int compiler_call_counting; @@ -929,6 +934,12 @@ struct various_codes *Yap_heap_regs; #define ForeignCodeTop Yap_heap_regs->foreign_code_top; #define ForeignCodeMax Yap_heap_regs->foreign_code_max; #define ForeignCodeLoaded Yap_heap_regs->foreign_code_loaded +#define PredHash Yap_heap_regs->pred_hash +#define PredHashRWLock Yap_heap_regs->pred_hash_rw_lock +#define PredsInHashTable Yap_heap_regs->preds_in_hash_table +#define PredHashTableSize Yap_heap_regs->pred_hash_table_size +#define PredHashInitialSize 1039L +#define PredHashIncrement 7919L #define ParserErrorStyle Yap_heap_regs->parser_error_style #define DeadStaticClauses Yap_heap_regs->dead_static_clauses #define DeadMegaClauses Yap_heap_regs->dead_mega_clauses diff --git a/H/Yatom.h b/H/Yatom.h index ecb0259aa..ea30f0e88 100644 --- a/H/Yatom.h +++ b/H/Yatom.h @@ -1295,34 +1295,82 @@ Prop STD_PROTO (Yap_GetAPropHavingLock, (AtomEntry *, PropFlags)); EXTERN inline PredEntry *STD_PROTO (Yap_GetThreadPred, (PredEntry *)); #endif -EXTERN inline Prop -PredPropByFunc (Functor f, Term cur_mod) -/* get predicate entry for ap/arity; create it if neccessary. */ +typedef enum { - Prop p0; - FunctorEntry *fe = (FunctorEntry *) f; + PROLOG_MODULE = 0, + USER_MODULE = 1, + IDB_MODULE = 2, + ATTRIBUTES_MODULE = 3, + CHARSIO_MODULE = 4, + TERMS_MODULE = 5 +} default_modules; - WRITE_LOCK (fe->FRWLock); - p0 = fe->PropsOfFE; - while (p0) - { - PredEntry *p = RepPredProp (p0); - if ( /* p->KindOfPE != 0 || only props */ - (p->ModuleOfPred == cur_mod || !(p->ModuleOfPred))) +#include "Heap.h" + +EXTERN inline UInt STD_PROTO(PRED_HASH, (FunctorEntry *, Term, UInt)); + +EXTERN inline UInt +PRED_HASH(FunctorEntry *fe, Term cur_mod, UInt size) +{ + return ((CELL)fe+cur_mod) % size; +} + +EXTERN inline Prop STD_PROTO(GetPredPropByFuncHavingLock, (FunctorEntry *, Term)); + +EXTERN inline Prop +GetPredPropByFuncHavingLock (FunctorEntry *fe, Term cur_mod) +{ + PredEntry *p; + + if (!(p = RepPredProp(fe->PropsOfFE))) + return NIL; + + if ((p->ModuleOfPred == cur_mod || !(p->ModuleOfPred))) { +#if THREADS + /* Thread Local Predicates */ + if (p->PredFlags & ThreadLocalPredFlag) { + return AbsPredProp (Yap_GetThreadPred (p)); + } +#endif + return AbsPredProp(p); + } + if (p->NextOfPE) { + UInt hash = PRED_HASH(fe,cur_mod,PredHashTableSize); + READ_LOCK(PredHashRWLock); + p = PredHash[hash]; + + while (p) { + if (p->FunctorOfPred == fe && + p->ModuleOfPred == cur_mod) { #if THREADS /* Thread Local Predicates */ - if (p->PredFlags & ThreadLocalPredFlag) - { - WRITE_UNLOCK (fe->FRWLock); - return AbsPredProp (Yap_GetThreadPred (p)); - } + if (p->PredFlags & ThreadLocalPredFlag) { + return AbsPredProp (Yap_GetThreadPred (p)); + } #endif - WRITE_UNLOCK (fe->FRWLock); - return (p0); + READ_UNLOCK(PredHashRWLock); + return AbsPredProp(p); } - p0 = p->NextOfPE; + p = RepPredProp(p->NextOfPE); } + READ_UNLOCK(PredHashRWLock); + } + return NIL; +} + +EXTERN inline Prop +PredPropByFunc (Functor fe, Term cur_mod) +/* get predicate entry for ap/arity; create it if neccessary. */ +{ + Prop p0; + + WRITE_LOCK (fe->FRWLock); + p0 = GetPredPropByFuncHavingLock(fe, cur_mod); + if (p0) { + WRITE_UNLOCK (fe->FRWLock); + return p0; + } return Yap_NewPredPropByFunctor (fe, cur_mod); } @@ -1357,12 +1405,3 @@ PredPropByAtom (Atom at, Term cur_mod) return Yap_NewPredPropByAtom (ae, cur_mod); } -typedef enum -{ - PROLOG_MODULE = 0, - USER_MODULE = 1, - IDB_MODULE = 2, - ATTRIBUTES_MODULE = 3, - CHARSIO_MODULE = 4, - TERMS_MODULE = 5 -} default_modules; diff --git a/H/rheap.h b/H/rheap.h index 8c93eb632..d2d3001e6 100644 --- a/H/rheap.h +++ b/H/rheap.h @@ -11,8 +11,11 @@ * File: rheap.h * * comments: walk through heap code * * * -* Last rev: $Date: 2007-04-10 22:13:21 $,$Author: vsc $ * +* Last rev: $Date: 2007-09-28 23:18:17 $,$Author: vsc $ * * $Log: not supported by cvs2svn $ +* Revision 1.75 2007/04/10 22:13:21 vsc +* fix max modules limitation +* * Revision 1.74 2007/03/22 11:12:21 vsc * make sure that YAP_Restart does not restart a failed goal. * @@ -1152,9 +1155,10 @@ RestoreEntries(PropEntry *pp) AtomAdjust(fe->NameOfFE); p0 = fe->PropsOfFE = PropAdjust(fe->PropsOfFE); - while (!EndOfPAEntr(p0)) { + if (!EndOfPAEntr(p0)) { + /* at most one property */ CleanCode(RepPredProp(p0)); - p0 = RepPredProp(p0)->NextOfPE = + RepPredProp(p0)->NextOfPE = PropAdjust(RepPredProp(p0)->NextOfPE); } } diff --git a/H/sshift.h b/H/sshift.h index ca58ccec7..ac5491ba0 100644 --- a/H/sshift.h +++ b/H/sshift.h @@ -299,6 +299,15 @@ PropAdjust (Prop p) #endif +inline EXTERN PredEntry *PredEntryAdjust (PredEntry *); + +inline EXTERN PredEntry * +PredEntryAdjust (PredEntry *p) +{ + return (PredEntry *) ((p == NULL ? (p) : (PredEntry *) (CharP (p) + HDiff))); +} + + inline EXTERN Term AtomTermAdjust (Term); inline EXTERN Term diff --git a/changes-5.1.html b/changes-5.1.html index 8b44246e1..b7095a660 100644 --- a/changes-5.1.html +++ b/changes-5.1.html @@ -17,6 +17,8 @@

Yap-5.1.3: