Include new instruction execute_cpred to perform tail optimisation for
builtins. Required changes: - be careful about creeping in deallocate: it may be followed by something that is not a cut nor a proceed. - include new instruction in absmi.c: it is a merge of execute and call_cpred. - change compiler to generate execute even for C builtins. - be careful with dexecute: it may not be done if execute_op is a C builtin. - if we are in execute_cpred, the garbage collector cannot trust P: instead it must look at CP to find out the size of the current environment. The macro gc_P receives that information. - We don't need to change CP if we do a meta-call from within execute_cpred (and we in fact cannot). Check places where we do meta-calls: exec, clause in cdmgr, and lu_recorded.
This commit is contained in:
16
C/exec.c
16
C/exec.c
@@ -69,7 +69,12 @@ CallPredicate(PredEntry *pen, choiceptr cut_pt, yamop *code) {
|
||||
} else if (pen->ModuleOfPred)
|
||||
DEPTH -= MkIntConstant(2);
|
||||
#endif /* DEPTH_LIMIT */
|
||||
CP = P;
|
||||
if (P->opc != Yap_opcode(_execute_cpred)) {
|
||||
CP = P;
|
||||
ENV = YENV;
|
||||
YENV = ASP;
|
||||
YENV[E_CB] = (CELL) cut_pt;
|
||||
}
|
||||
P = code;
|
||||
/* vsc: increment reduction counter at meta-call entry */
|
||||
if (pen->PredFlags & ProfiledPredFlag) {
|
||||
@@ -77,9 +82,6 @@ CallPredicate(PredEntry *pen, choiceptr cut_pt, yamop *code) {
|
||||
pen->StatisticsForPred.NOfEntries++;
|
||||
UNLOCK(pen->StatisticsForPred.lock);
|
||||
}
|
||||
ENV = YENV;
|
||||
YENV = ASP;
|
||||
YENV[E_CB] = (CELL) cut_pt;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -627,7 +629,7 @@ p_execute_clause(void)
|
||||
static Int
|
||||
p_execute_in_mod(void)
|
||||
{ /* '$execute'(Goal) */
|
||||
return(do_execute(Deref(ARG1), IntOfTerm(Deref(ARG2))));
|
||||
return(do_execute(Deref(ARG1), Deref(ARG2)));
|
||||
}
|
||||
|
||||
static Int
|
||||
@@ -1898,8 +1900,10 @@ JumpToEnv(Term t) {
|
||||
/* is it a continuation? */
|
||||
env = B->cp_env;
|
||||
while (env > ENV)
|
||||
ENV = (CELL *)ENV[E_E];
|
||||
ENV = ENV_Parent(ENV);
|
||||
/* yes, we found it ! */
|
||||
while (env < ENV)
|
||||
env = ENV_Parent(env);
|
||||
if (env == ENV) break;
|
||||
/* oops, try next */
|
||||
B = B->cp_b;
|
||||
|
Reference in New Issue
Block a user