From 551df1c70a65551e7f1a2a8e19883e7a65fa8806 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADtor=20Santos=20Costa?= Date: Thu, 22 Dec 2011 10:27:56 +0000 Subject: [PATCH] handle blob overflows. --- C/agc.c | 17 +++++++++++++++-- C/exec.c | 10 ++++------ C/grow.c | 15 +++++++++++---- H/dhstruct.h | 5 +++++ H/hstruct.h | 5 +++++ H/ihstruct.h | 5 +++++ H/rhstruct.h | 5 +++++ library/dialect/swi/fli/blobs.c | 31 ++++++++++++++++++++++++++++--- library/dialect/swi/fli/swi.c | 1 - misc/HEAPFIELDS | 5 +++++ 10 files changed, 83 insertions(+), 16 deletions(-) diff --git a/C/agc.c b/C/agc.c index a52e40b8b..990be69db 100644 --- a/C/agc.c +++ b/C/agc.c @@ -398,13 +398,25 @@ clean_atom_list(AtomHashEntry *HashPtr) while (atm != NIL) { AtomEntry *at = RepAtom(atm); if (AtomResetMark(at) || - at->PropsOfAE != NIL || + ( at->PropsOfAE != NIL && !IsBlob(at) ) || (GLOBAL_AGCHook != NULL && !GLOBAL_AGCHook(atm))) { patm = &(at->NextOfAE); atm = at->NextOfAE; } else { NOfAtoms--; - if (IsWideAtom(atm)) { + if (IsBlob(atm)) { + BlobPropEntry *b = RepBlobProp(at->PropsOfAE); + if (b->NextOfPE != NIL) { + patm = &(at->NextOfAE); + atm = at->NextOfAE; + continue; + } + NOfAtoms++; + NOfBlobs--; + Yap_FreeCodeSpace((char *)b); + GLOBAL_agc_collected += sizeof(BlobPropEntry); + GLOBAL_agc_collected += sizeof(AtomEntry)+sizeof(size_t)+at->rep.blob->length; + } else if (IsWideAtom(atm)) { #ifdef DEBUG_RESTORE3 fprintf(stderr, "Purged %p:%S\n", at, at->WStrOfAE); #endif @@ -478,6 +490,7 @@ atom_gc(USES_REGS1) mark_stacks(PASS_REGS1); restore_codes(); clean_atoms(); + NOfBlobsMax = NOfBlobs+(NOfBlobs/2+256< 1024 ? NOfBlobs/2+256 : 1024); YAPLeaveCriticalSection(); agc_time = Yap_cputime()-time_start; GLOBAL_tot_agc_time += agc_time; diff --git a/C/exec.c b/C/exec.c index 4a3f91cbb..a172bfa23 100644 --- a/C/exec.c +++ b/C/exec.c @@ -1120,20 +1120,20 @@ Yap_execute_goal(Term t, int nargs, Term mod) if (pe == NIL) { return(CallMetaCall(mod PASS_REGS)); } - PELOCK(81,ppe); + PELOCK(81,RepPredProp(pe)); if (IsAtomTerm(t)) { - CodeAdr = RepPredProp (pe)->CodeOfPred; + CodeAdr = ppe->CodeOfPred; UNLOCK(ppe->PELock); out = do_goal(t, CodeAdr, 0, pt, FALSE PASS_REGS); } else { Functor f = FunctorOfTerm(t); - CodeAdr = RepPredProp (pe)->CodeOfPred; + CodeAdr = ppe->CodeOfPred; UNLOCK(ppe->PELock); out = do_goal(t, CodeAdr, ArityOfFunctor(f), pt, FALSE PASS_REGS); } if (out == 1) { - choiceptr cut_B, old_B; + choiceptr cut_B; /* we succeeded, let's prune */ /* restore the old environment */ /* get to previous environment */ @@ -1162,8 +1162,6 @@ Yap_execute_goal(Term t, int nargs, Term mod) } #endif /* TABLING */ B = cut_B; - /* find out where we have the old arguments */ - old_B = ((choiceptr)(ENV-(EnvSizeInCells+nargs+1)))-1; CP = saved_cp; P = saved_p; ASP = ENV; diff --git a/C/grow.c b/C/grow.c index 3539a4b50..eed3d652e 100644 --- a/C/grow.c +++ b/C/grow.c @@ -1421,15 +1421,17 @@ Yap_growheap(int fix_code, UInt in_size, void *cip) { CACHE_REGS int res; + int blob_overflow = (NOfBlobs > NOfBlobsMax); - if (NOfAtoms > 2*AtomHashTableSize) { + if (NOfAtoms > 2*AtomHashTableSize || blob_overflow) { UInt n = NOfAtoms; if (GLOBAL_AGcThreshold) Yap_atom_gc( PASS_REGS1 ); /* check if we have a significant improvement from agc */ - if (n > NOfAtoms+ NOfAtoms/10 || - /* +1 = make sure we didn't lose the current atom */ - NOfAtoms+1 > 2*AtomHashTableSize) { + if (!blob_overflow && + (n > NOfAtoms+ NOfAtoms/10 || + /* +1 = make sure we didn't lose the current atom */ + NOfAtoms+1 > 2*AtomHashTableSize)) { res = growatomtable( PASS_REGS1 ); } else { LOCK(LOCAL_SignalLock); @@ -1444,7 +1446,12 @@ Yap_growheap(int fix_code, UInt in_size, void *cip) if (res) return res; } +#if USE_SYSTEM_MALLOC + P = Yap_Error(OUT_OF_HEAP_ERROR,TermNil,"malloc failed"); + res = -1; +#else res=do_growheap(fix_code, in_size, (struct intermediates *)cip, NULL, NULL, NULL PASS_REGS); +#endif LeaveGrowMode(GrowHeapMode); return res; } diff --git a/H/dhstruct.h b/H/dhstruct.h index 53b5a56e2..a993249fd 100644 --- a/H/dhstruct.h +++ b/H/dhstruct.h @@ -302,3 +302,8 @@ #define SWI_BlobTypes Yap_heap_regs->swi_blob_types #define SWI_Blobs Yap_heap_regs->swi_blobs +#define NOfBlobs Yap_heap_regs->nofblobs +#define NOfBlobsMax Yap_heap_regs->nofblobsmax +#if defined(YAPOR) || defined(THREADS) +#define SWI_Blobs_Lock Yap_heap_regs->swi_blobs_lock +#endif diff --git a/H/hstruct.h b/H/hstruct.h index d137ae7fe..07f01c48e 100644 --- a/H/hstruct.h +++ b/H/hstruct.h @@ -302,3 +302,8 @@ struct PL_blob_t *swi_blob_types; struct AtomEntryStruct *swi_blobs; + UInt nofblobs; + UInt nofblobsmax; +#if defined(YAPOR) || defined(THREADS) + lockvar swi_blobs_lock; +#endif diff --git a/H/ihstruct.h b/H/ihstruct.h index ee1f6366a..69f9c37ec 100644 --- a/H/ihstruct.h +++ b/H/ihstruct.h @@ -302,3 +302,8 @@ SWI_BlobTypes = NULL; SWI_Blobs = NULL; + NOfBlobs = 0; + NOfBlobsMax = 256; +#if defined(YAPOR) || defined(THREADS) + INIT_LOCK(SWI_Blobs_Lock); +#endif diff --git a/H/rhstruct.h b/H/rhstruct.h index e1a8af4a3..0668229ed 100644 --- a/H/rhstruct.h +++ b/H/rhstruct.h @@ -302,3 +302,8 @@ RestoreSWIBlobTypes(); RestoreSWIBlobs(); + + +#if defined(YAPOR) || defined(THREADS) + REINIT_LOCK(SWI_Blobs_Lock); +#endif diff --git a/library/dialect/swi/fli/blobs.c b/library/dialect/swi/fli/blobs.c index ef38a0041..2b8e688bd 100644 --- a/library/dialect/swi/fli/blobs.c +++ b/library/dialect/swi/fli/blobs.c @@ -51,11 +51,25 @@ PL_is_blob(term_t t, PL_blob_t **type) return TRUE; } +void check_chain(void); + +void check_chain(void) { + AtomEntry *ae, *old; + ae = SWI_Blobs; + old = NULL; + while (ae) { + old = ae; + ae = RepAtom(ae->NextOfAE); + } +} + static AtomEntry * lookupBlob(void *blob, size_t len, PL_blob_t *type) { BlobPropEntry *b; AtomEntry *ae; + + LOCK(SWI_Blobs_Lock); if (type->flags & PL_BLOB_UNIQUE) { /* just keep a linked chain for now */ ae = SWI_Blobs; @@ -63,26 +77,37 @@ lookupBlob(void *blob, size_t len, PL_blob_t *type) if (ae->PropsOfAE && RepBlobProp(ae->PropsOfAE)->blob_t == type && ae->rep.blob->length == len && - !memcmp(ae->rep.blob->data, blob, len)) + !memcmp(ae->rep.blob->data, blob, len)) { + UNLOCK(SWI_Blobs_Lock); return ae; + } ae = RepAtom(ae->NextOfAE); } } b = (BlobPropEntry *)Yap_AllocCodeSpace(sizeof(BlobPropEntry)); - if (!b) + if (!b) { + UNLOCK(SWI_Blobs_Lock); return NULL; + } b->NextOfPE = NIL; b->KindOfPE = BlobProperty; b->blob_t = type; ae = (AtomEntry *)Yap_AllocCodeSpace(sizeof(AtomEntry)+len+sizeof(size_t)); - if (!ae) + if (!ae) { + UNLOCK(SWI_Blobs_Lock); return NULL; + } + NOfBlobs++; INIT_RWLOCK(ae->ARWLock); ae->PropsOfAE = AbsBlobProp(b); ae->NextOfAE = AbsAtom(SWI_Blobs); ae->rep.blob->length = len; memcpy(ae->rep.blob->data, blob, len); SWI_Blobs = ae; + UNLOCK(SWI_Blobs_Lock); + if (NOfBlobs > NOfBlobsMax) { + Yap_signal(YAP_CDOVF_SIGNAL); + } return ae; } diff --git a/library/dialect/swi/fli/swi.c b/library/dialect/swi/fli/swi.c index f3f635f56..4afb4b381 100644 --- a/library/dialect/swi/fli/swi.c +++ b/library/dialect/swi/fli/swi.c @@ -2421,7 +2421,6 @@ X_API int PL_thread_attach_engine(const PL_thread_attr_t *attr) /* we do not have an engine */ if (attr) { YAP_thread_attr yapt; - int wid; yapt.ssize = attr->local_size; yapt.tsize = attr->global_size; diff --git a/misc/HEAPFIELDS b/misc/HEAPFIELDS index 5d7ab05d4..d463768e7 100644 --- a/misc/HEAPFIELDS +++ b/misc/HEAPFIELDS @@ -345,3 +345,8 @@ struct swi_reverse_hash swi_reverse_hash[N_SWI_HASH] SWI_ReverseHash void void /* SWI blobs */ struct PL_blob_t *swi_blob_types SWI_BlobTypes =NULL RestoreSWIBlobTypes() struct AtomEntryStruct *swi_blobs SWI_Blobs =NULL RestoreSWIBlobs() +UInt nofblobs NOfBlobs =0 +UInt nofblobsmax NOfBlobsMax =256 +#if defined(YAPOR) || defined(THREADS) +lockvar swi_blobs_lock SWI_Blobs_Lock MkLock +#endif