support for space reservation (goal: call gc before trying to insert very large terms).

This commit is contained in:
Vitor Santos Costa 2010-08-02 13:04:30 +01:00
parent 212758d25e
commit 3d6e223dae
13 changed files with 88 additions and 16 deletions

View File

@ -1670,6 +1670,34 @@ Yap_absmi(int inp)
ENDBOp();
/*****************************************************************
* check for enough room *
*****************************************************************/
/* ensure_space */
BOp(ensure_space, ip);
{
Int sz = PREG->u.ip.i;
fprintf(stderr,"ensuring %ld\n", sz);
PREG = NEXTOP(PREG,ip);
if (Unsigned(H) + sz > Unsigned(YREG)-CreepFlag) {
ASP = YREG+E_CB;
if (ASP > (CELL *)PROTECT_FROZEN_B(B))
ASP = (CELL *)PROTECT_FROZEN_B(B);
saveregs();
if (!Yap_gcl(sz, 0, ENV, NEXTOP(PREG,ip))) {
PREG = NEXTOP(PREG,ip);
Yap_Error(OUT_OF_STACK_ERROR,TermNil,Yap_ErrorMessage);
setregs();
FAIL();
} else {
setregs();
}
}
}
JMPNext();
ENDBOp();
/*****************************************************************
* try and retry of dynamic predicates *
*****************************************************************/

View File

@ -509,6 +509,7 @@ a_cle(op_numbers opcode, yamop *code_p, int pass_no, struct intermediates *cip)
return code_p;
}
inline static yamop *
a_e(op_numbers opcode, yamop *code_p, int pass_no)
{
@ -1094,6 +1095,21 @@ a_blob(CELL rnd1, op_numbers opcode, int *clause_has_blobsp, yamop *code_p, int
return code_p;
}
static yamop *
a_ensure_space(op_numbers opcode, yamop *code_p, int pass_no, struct intermediates *cip, clause_info *clinfo)
{
if (cip->cpc->rnd1 > 4096 && FALSE) {
if (pass_no) {
code_p->opc = emit_op(opcode);
code_p->u.ip.i = sizeof(CELL) * cip->cpc->rnd1;
code_p->u.ip.p = clinfo->CurrentPred;
}
GONEXT(ip);
}
return code_p;
}
inline static yamop *
a_wdbt(CELL rnd1, op_numbers opcode, int *clause_has_dbtermp, yamop *code_p, int pass_no, struct intermediates *cip)
{
@ -3531,6 +3547,9 @@ do_pass(int pass_no, yamop **entry_codep, int assembling, int *clause_has_blobsp
/* reset dealloc_found in case there was a branch */
clinfo.dealloc_found = FALSE;
break;
case ensure_space_op:
code_p = a_ensure_space(_ensure_space, code_p, pass_no, cip, &clinfo);
break;
case pop_op:
if (cip->cpc->rnd1 == 1)
code_p = a_e(_pop, code_p, pass_no);

View File

@ -201,6 +201,8 @@ typedef struct compiler_struct_struct {
int onhead;
int onbranch;
int curbranch;
Int space_used;
PInstr *space_op;
Prop current_p0;
#ifdef TABLING_INNER_CUTS
PInstr *cut_mark;
@ -458,6 +460,7 @@ c_var(Term t, Int argno, unsigned int arity, unsigned int level, compiler_struct
} else
#endif
if (cglobs->onhead) {
cglobs->space_used ++;
if (level == 0)
Yap_emit((new ? (++cglobs->nvars, get_var_op) : get_val_op), t, argno, &cglobs->cint);
else
@ -725,6 +728,7 @@ c_arg(Int argno, Term t, unsigned int arity, unsigned int level, compiler_struct
: unify_num_op) :
write_num_op), (CELL) t, Zero, &cglobs->cint);
} else if (IsPairTerm(t)) {
cglobs->space_used += 2;
if (optimizer_on && level < 6) {
#if !defined(THREADS)
/* discard code sharing because we cannot write on shared stuff */
@ -792,6 +796,7 @@ c_arg(Int argno, Term t, unsigned int arity, unsigned int level, compiler_struct
return;
}
}
cglobs->space_used += 1+arity;
if (level == 0)
Yap_emit((cglobs->onhead ? get_struct_op : put_struct_op),
(CELL) FunctorOfTerm(t), argno, &cglobs->cint);
@ -2077,6 +2082,8 @@ c_head(Term t, compiler_struct *cglobs)
cglobs->onlast = FALSE;
cglobs->curbranch = cglobs->onbranch = 0;
cglobs->branch_pointer = cglobs->parent_branches;
cglobs->space_used = 0;
cglobs->space_op = NULL;
if (IsAtomTerm(t)) {
Yap_emit(name_op, (CELL) AtomOfTerm(t), Zero, &cglobs->cint);
#ifdef BEAM
@ -2086,6 +2093,8 @@ c_head(Term t, compiler_struct *cglobs)
#endif
return;
}
Yap_emit(ensure_space_op, Zero , Zero, &cglobs->cint);
cglobs->space_op = cglobs->cint.cpc;
f = FunctorOfTerm(t);
Yap_emit(name_op, (CELL) NameOfFunctor(f), ArityOfFunctor(f), &cglobs->cint);
#ifdef BEAM
@ -3516,6 +3525,9 @@ Yap_cclause(volatile Term inp_clause, Int NOfArgs, Term mod, volatile Term src)
c_body(body, mod, &cglobs);
/* Insert blobs at the very end */
if (cglobs.space_op)
cglobs.space_op->rnd1 = cglobs.space_used;
if (cglobs.cint.BlobsStart != NULL) {
cglobs.cint.cpc->nextInst = cglobs.cint.BlobsStart;
cglobs.cint.BlobsStart = NULL;

View File

@ -714,6 +714,7 @@ static char *opformat[] =
"unify_last_dbterm\t%w",
"unify_last_longint\t%w",
"unify_last_bigint\t%l",
"ensure_space",
"native_code",
"function_to_var\t%v,%B",
"function_to_val\t%v,%B",

View File

@ -24,6 +24,7 @@
OPCODE(alloc_for_logical_pred ,L),
OPCODE(copy_idb_term ,e),
OPCODE(unify_idb_term ,e),
OPCODE(ensure_space ,ip),
OPCODE(spy_or_trymark ,Otapl),
OPCODE(try_and_mark ,Otapl),
OPCODE(count_retry_and_mark ,Otapl),

View File

@ -477,6 +477,11 @@ typedef struct yami {
struct yami *l4;
CELL next;
} ollll;
struct {
Int i;
struct pred_entry *p;
CELL next;
} ip;
struct {
struct yami *l;
struct pred_entry *p;

View File

@ -77,6 +77,7 @@ typedef enum compiler_op {
unify_last_dbterm_op,
unify_last_longint_op,
unify_last_bigint_op,
ensure_space_op,
native_op,
f_var_op,
f_val_op,

View File

@ -289,6 +289,9 @@
case _write_longint:
cl = NEXTOP(cl,i);
break;
case _ensure_space:
cl = NEXTOP(cl,ip);
break;
case _unify_l_list:
cl = NEXTOP(cl,o);
break;
@ -646,9 +649,6 @@
case _write_x_loc:
cl = NEXTOP(cl,x);
break;
case _write_x_val:
cl = NEXTOP(cl,x);
break;
case _write_x_var:
if (!(nofregs = delete_regcopy(myregs, nofregs, cl->u.x.x))) {
clause->Tag = (CELL)NULL;

View File

@ -240,6 +240,12 @@ restore_opcodes(yamop *pc, yamop *max)
IntegerInCodeAdjust(pc->u.i.i);
pc = NEXTOP(pc,i);
break;
/* instructions type ip */
case _ensure_space:
IntegerInCodeAdjust(pc->u.ip.i);
pc->u.ip.p = PtoPredAdjust(pc->u.ip.p);
pc = NEXTOP(pc,ip);
break;
/* instructions type l */
case _Ystop:
case _jump:

View File

@ -184,6 +184,10 @@
case _write_longint:
pc = NEXTOP(pc,i);
break;
/* instructions type ip */
case _ensure_space:
pc = NEXTOP(pc,ip);
break;
/* instructions type l */
case _Ystop:
return found_ystop(pc, clause_code, startp, endp, pp);

View File

@ -822,7 +822,7 @@ opinfo("p_nonvar_x",[body,ifthenelse]).
opinfo("p_nonvar_y",[body,ifthenelse]).
opinfo("save_b_x",[body,new("x")]).
opinfo("save_b_y",[body,new("y")]).
opinfo("write_x_val",[body]).
opinfo("ensure_space",[body]).
opinfo("write_x_loc",[body]).
opinfo("write_x_var",[body,new("x")]).
opinfo("write_y_var",[body,new("y")]).

View File

@ -50,7 +50,7 @@ LD=@DO_SECOND_LD@ @SHLIB_LD@
LDFLAGS=@EXTRA_LIBS_FOR_SWIDLLS@
BINTARGET=$(DESTDIR)$(YAPLIBDIR)
PLTARGET=$(DESTDIR)$(SHAREDIR)/http
PLTARGET=$(DESTDIR)$(SHAREDIR)/semweb
FINAL_BINTARGET=$(YAPLIBDIR)
FINAL_PLTARGET=$(SHAREDIR)
@ -117,6 +117,7 @@ install: $(TARGETS) $(LIBPL)
for f in $(TARGETS); do \
$(INSTALL) -m 755 $$f $(BINTARGET); \
done
mkdir -p $(PLTARGET)
for f in $(DATA) $(LIBPL) $(srcdir)/README; do \
$(INSTALL_DATA) $$f $(PLTARGET); \
done

View File

@ -13,10 +13,6 @@
:- use_module(library(socket)).
:- use_module(library(debug)).
:- expects_dialect(swi).
:- assert(system:swi_io).
test_zlib :-
run_tests([ zlib
]).
@ -31,7 +27,7 @@ test(gunzip,
]) :-
gzopen('plunit-tmp.gz', read, ZIn),
call_cleanup(read_stream_to_codes(ZIn, Codes0), close(ZIn)),
myread_file_to_codes('test_zlib.pl', Codes1),
read_file_to_codes('test_zlib.pl', Codes1),
Codes0 == Codes1.
% gzip: Can gunzip read our compressed file
@ -39,11 +35,11 @@ test(gunzip,
test(gzip,
[ cleanup(delete_file('plunit-tmp.gz'))
]) :-
myread_file_to_codes('test_zlib.pl', Codes),
read_file_to_codes('test_zlib.pl', Codes),
gzopen('plunit-tmp.gz', write, ZOut),
format(ZOut, '~s', [Codes]),
close(ZOut),
myread_file_to_codes(pipe('gunzip < plunit-tmp.gz'), Codes1),
read_file_to_codes(pipe('gunzip < plunit-tmp.gz'), Codes1),
Codes == Codes1.
% deflate: test read/write of deflate format
@ -51,7 +47,7 @@ test(gzip,
test(deflate,
[ cleanup(delete_file('plunit-tmp.z'))
]) :-
myread_file_to_codes('test_zlib.pl', Codes),
read_file_to_codes('test_zlib.pl', Codes),
open('plunit-tmp.z', write, Out),
zopen(Out, ZOut, []),
format(ZOut, '~s', [Codes]),
@ -202,9 +198,7 @@ get_data(ZIn, N) :-
* UTIL *
*******************************/
myread_file_to_codes(File, Codes) :-
read_file_to_codes(File, Codes) :-
open(File, read, In),
call_cleanup(read_stream_to_codes(In, Codes), close(In)).
:- retract(system:swi_io).