From 76a448e26ffe7e69a72856cc57d7c7e2150d17fd Mon Sep 17 00:00:00 2001 From: "kr.angelov" Date: Thu, 16 Oct 2014 10:00:32 +0000 Subject: [PATCH] finally proper stack unwind in the evaluator --- src/compiler/GF/Compile/GenerateBC.hs | 12 +- src/compiler/GF/Compile/GrammarToPGF.hs | 11 +- src/runtime/c/pgf/data.h | 5 +- src/runtime/c/pgf/evaluator.c | 130 +++++++-------- src/runtime/c/pgf/evaluator.h | 9 +- src/runtime/c/pgf/jit.c | 207 +++++++++++------------- src/runtime/haskell/PGF/Binary.hs | 7 +- src/runtime/haskell/PGF/ByteCode.hs | 6 +- 8 files changed, 176 insertions(+), 211 deletions(-) diff --git a/src/compiler/GF/Compile/GenerateBC.hs b/src/compiler/GF/Compile/GenerateBC.hs index 1f1e81ab9..d90e78ee7 100644 --- a/src/compiler/GF/Compile/GenerateBC.hs +++ b/src/compiler/GF/Compile/GenerateBC.hs @@ -24,7 +24,7 @@ generateByteCode gr arity eqs = is = push_is (arity-1) arity [] compileEquations :: SourceGrammar -> Int -> Int -> [IVal] -> [([(Ident,IVal)],[Patt],Term)] -> Maybe (Int,CodeLabel) -> [[Instr]] -> ([[Instr]],[Instr]) -compileEquations gr arity st _ [] fl bs = (bs,[mkFail st fl]) +compileEquations gr arity st _ [] fl bs = (bs,mkFail arity st fl) compileEquations gr arity st [] ((vs,[],t):_) fl bs = compileBody gr arity st vs t bs compileEquations gr arity st (i:is) eqs fl bs = whilePP eqs Map.empty where @@ -32,7 +32,7 @@ compileEquations gr arity st (i:is) eqs fl bs = whilePP eqs Map.empty [] -> (bs,[FAIL]) (cn:cns) -> let (bs1,instrs1) = compileBranch0 fl bs cn bs2 = foldl (compileBranch fl) bs1 cns - bs3 = [mkFail st fl]:bs2 + bs3 = mkFail arity st fl : bs2 in (bs3,EVAL (shiftIVal st i) RecCall : instrs1) whilePP ((vs, PP c ps' : ps, t):eqs) cns = whilePP eqs (Map.insertWith (++) (Q c,length ps') [(vs,ps'++ps,t)] cns) whilePP ((vs, PInt n : ps, t):eqs) cns = whilePP eqs (Map.insertWith (++) (EInt n,0) [(vs,ps,t)] cns) @@ -75,8 +75,12 @@ compileEquations gr arity st (i:is) eqs fl bs = whilePP eqs Map.empty let (bs1,instrs) = compileEquations gr arity (st+n) (push_is (st+n-1) n is) eqs fl ((case_instr t n (length bs1) : instrs) : bs) in bs1 -mkFail st1 Nothing = FAIL -mkFail st1 (Just (st0,l)) = DROP (st1-st0) l +mkFail arity st1 Nothing + | arity+1 /= st1 = [DROP (st1-arity), FAIL] + | otherwise = [FAIL] +mkFail arity st1 (Just (st0,l)) + | st1 /= st0 = [DROP (st1-st0), JUMP l] + | otherwise = [JUMP l] compileBody gr arity st vs e bs = let (heap,bs1,is) = compileFun gr arity st vs e 0 bs [] diff --git a/src/compiler/GF/Compile/GrammarToPGF.hs b/src/compiler/GF/Compile/GrammarToPGF.hs index b8a79af52..d0b588d81 100644 --- a/src/compiler/GF/Compile/GrammarToPGF.hs +++ b/src/compiler/GF/Compile/GrammarToPGF.hs @@ -50,8 +50,8 @@ mkCanon2pgf opts gr am = do funs = Map.fromList [(i2i f, (mkType [] ty, arity, mkDef gr arity mdef, 0)) | ((m,f),AbsFun (Just (L _ ty)) ma mdef _) <- adefs, - let arity = mkArrity ma ty] - + let arity = mkArity ma mdef ty] + cats = Map.fromList [(i2i c, (snd (mkContext [] cont),catfuns c, 0)) | ((m,c),AbsCat (Just (L _ cont))) <- adefs] @@ -150,9 +150,10 @@ mkDef gr arity (Just eqs) = Just ([C.Equ ps' (mkExp scope' e) | L _ (ps,e) <- eq ) mkDef gr arity Nothing = Nothing -mkArrity (Just a) ty = a -mkArrity Nothing ty = let (ctxt, _, _) = GM.typeForm ty - in length ctxt +mkArity (Just a) _ ty = a -- known arity, i.e. defined function +mkArity Nothing (Just _) ty = 0 -- defined function with no arity - must be an axiom +mkArity Nothing _ ty = let (ctxt, _, _) = GM.typeForm ty -- constructor + in length ctxt genCncCats gr am cm cdefs = let (index,cats) = mkCncCats 0 cdefs diff --git a/src/runtime/c/pgf/data.h b/src/runtime/c/pgf/data.h index 8e2b726a7..2b11f24da 100644 --- a/src/runtime/c/pgf/data.h +++ b/src/runtime/c/pgf/data.h @@ -136,8 +136,9 @@ typedef enum { PGF_INSTR_PUSH = 9, PGF_INSTR_EVAL = 10, PGF_INSTR_DROP = 13, - PGF_INSTR_FAIL = 14, - PGF_INSTR_ADD = 15 + PGF_INSTR_JUMP = 14, + PGF_INSTR_FAIL = 15, + PGF_INSTR_ADD = 16 } PgfInstruction; typedef GuSeq PgfConcrs; diff --git a/src/runtime/c/pgf/evaluator.c b/src/runtime/c/pgf/evaluator.c index bc89026fc..62fe0bdd5 100644 --- a/src/runtime/c/pgf/evaluator.c +++ b/src/runtime/c/pgf/evaluator.c @@ -5,6 +5,23 @@ #define PGF_ARGS_DELTA 5 +static inline PgfClosure* +pgf_mk_pap(PgfEvalState* state, PgfClosure* fun, + size_t n_args, PgfClosure** args) +{ + if (n_args > 0) { + PgfValuePAP* val = gu_new_flex(state->pool, PgfValuePAP, args, n_args); + val->header.code = state->eval_gates->evaluate_value_pap; + val->fun = fun; + val->n_args = n_args*sizeof(PgfClosure*); + for (size_t i = 0; i < n_args; i++) { + val->args[i] = args[i]; + } + return &val->header; + } + return fun; +} + PgfClosure* pgf_evaluate_expr_thunk(PgfEvalState* state, PgfExprThunk* thunk) { @@ -64,15 +81,11 @@ repeat:; PgfExprMeta* emeta = ei.data; PgfValueMeta* val = - gu_new_flex(state->pool, PgfValueMeta, args, n_args); - val->header.code = state->eval_gates->evaluate_value_meta; - val->id = emeta->id; - val->n_args = n_args*sizeof(PgfClosure*); - for (size_t i = 0; i < n_args; i++) { - val->args[i] = args[n_args-i-1]; - } - - res = &val->header; + gu_new(PgfValueMeta, state->pool); + val->header.code = state->eval_gates->evaluate_meta; + val->env = env; + val->id = emeta->id; + res = pgf_mk_pap(state, &val->header, n_args, args); break; } case PGF_EXPR_FUN: { @@ -83,18 +96,7 @@ repeat:; gu_assert(absfun != NULL); if (absfun->closure.code != NULL) { - res = (PgfClosure*) &absfun->closure; - - if (n_args > 0) { - PgfValuePAP* val = gu_new_flex(state->pool, PgfValuePAP, args, n_args); - val->header.code = state->eval_gates->evaluate_value_pap; - val->fun = res; - val->n_args = n_args*sizeof(PgfClosure*); - for (size_t i = 0; i < n_args; i++) { - val->args[i] = args[i]; - } - res = &val->header; - } + res = pgf_mk_pap(state, (PgfClosure*) &absfun->closure, n_args, args); } else { size_t arity = absfun->arity; @@ -113,18 +115,7 @@ repeat:; PgfExprThunk* lambda = gu_new(PgfExprThunk, state->pool); lambda->header.code = state->eval_gates->evaluate_value_lambda; lambda->env = NULL; - res = &lambda->header; - - if (n_args > 0) { - PgfValuePAP* val = gu_new_flex(state->pool, PgfValuePAP, args, n_args); - val->header.code = state->eval_gates->evaluate_value_pap; - val->fun = &lambda->header; - val->n_args = n_args*sizeof(PgfClosure*); - for (size_t i = 0; i < n_args; i++) { - val->args[i] = args[i]; - } - res = &val->header; - } + res = pgf_mk_pap(state, &lambda->header, n_args, args); for (size_t i = 0; i < arity; i++) { PgfExpr new_expr, arg; @@ -180,18 +171,7 @@ repeat:; i--; } - res = tmp_env->closure; - - if (n_args > 0) { - PgfValuePAP* val = gu_new_flex(state->pool, PgfValuePAP, args, n_args); - val->header.code = state->eval_gates->evaluate_value_pap; - val->fun = res; - val->n_args = n_args*sizeof(PgfClosure*); - for (size_t i = 0; i < n_args; i++) { - val->args[i] = args[i]; - } - res = &val->header; - } + res = pgf_mk_pap(state, tmp_env->closure, n_args, args); break; } case PGF_EXPR_TYPED: { @@ -245,28 +225,6 @@ pgf_value2expr(PgfEvalState* state, int level, PgfClosure* clos, GuPool* pool) expr = absfun->ep.expr; n_args = absfun->arity; args = val->args; - } else if (clos->code == state->eval_gates->evaluate_value_gen) { - PgfValueGen* val = (PgfValueGen*) clos; - - PgfExprVar *evar = - gu_new_variant(PGF_EXPR_VAR, - PgfExprVar, - &expr, pool); - evar->var = level - val->level - 1; - - n_args = val->n_args/sizeof(PgfClosure*); - args = val->args; - } else if (clos->code == state->eval_gates->evaluate_value_meta) { - PgfValueMeta* val = (PgfValueMeta*) clos; - - PgfExprMeta *emeta = - gu_new_variant(PGF_EXPR_META, - PgfExprMeta, - &expr, pool); - emeta->id = val->id; - - n_args = val->n_args / sizeof(PgfClosure*); - args = val->args; } else if (clos->code == state->eval_gates->evaluate_value_lit) { PgfValueLit* val = (PgfValueLit*) clos; @@ -316,18 +274,18 @@ pgf_value2expr(PgfEvalState* state, int level, PgfClosure* clos, GuPool* pool) PgfValueGen* gen = gu_new(PgfValueGen, state->pool); - gen->header.code = state->eval_gates->evaluate_value_gen; + gen->header.code = state->eval_gates->evaluate_gen; gen->level = level; - gen->n_args = 0; - PgfValuePAP* new_pap = gu_new_flex(state->pool, PgfValuePAP, args, pap->n_args+1); + size_t n_args = pap->n_args/sizeof(PgfClosure*); + PgfValuePAP* new_pap = gu_new_flex(state->pool, PgfValuePAP, args, n_args+1); new_pap->header.code = state->eval_gates->evaluate_value_pap; new_pap->fun = pap->fun; new_pap->n_args = pap->n_args+sizeof(PgfClosure*); - for (size_t i = 0; i < pap->n_args/sizeof(PgfClosure*); i++) { - new_pap->args[i] = pap->args[i]; + new_pap->args[0] = &gen->header; + for (size_t i = 0; i < n_args; i++) { + new_pap->args[i+1] = pap->args[i]; } - new_pap->args[pap->n_args] = &gen->header; PgfExprAbs *eabs = gu_new_variant(PGF_EXPR_ABS, @@ -336,6 +294,32 @@ pgf_value2expr(PgfEvalState* state, int level, PgfClosure* clos, GuPool* pool) eabs->bind_type = PGF_BIND_TYPE_EXPLICIT; eabs->id = gu_format_string(pool, "v%d", level); eabs->body = pgf_value2expr(state, level+1, &new_pap->header, pool); + } else if (clos->code == state->eval_gates->evaluate_value_const) { + PgfValuePAP* val = (PgfValuePAP*) clos; + + if (val->fun->code == state->eval_gates->evaluate_meta) { + PgfValueMeta* fun = (PgfValueMeta*) val->fun; + + PgfExprMeta *emeta = + gu_new_variant(PGF_EXPR_META, + PgfExprMeta, + &expr, pool); + emeta->id = fun->id; + } else if (val->fun->code == state->eval_gates->evaluate_gen) { + PgfValueGen* fun = (PgfValueGen*) val->fun; + + PgfExprVar *evar = + gu_new_variant(PGF_EXPR_VAR, + PgfExprVar, + &expr, pool); + evar->var = level - fun->level - 1; + } else { + PgfAbsFun* absfun = gu_container(val->fun, PgfAbsFun, closure); + expr = absfun->ep.expr; + } + + n_args = val->n_args/sizeof(PgfClosure*); + args = val->args; } else { gu_impossible(); } diff --git a/src/runtime/c/pgf/evaluator.h b/src/runtime/c/pgf/evaluator.h index 09b0afb2a..1f56d61a9 100644 --- a/src/runtime/c/pgf/evaluator.h +++ b/src/runtime/c/pgf/evaluator.h @@ -40,16 +40,12 @@ typedef struct { typedef struct { PgfClosure header; int level; - size_t n_args; - PgfClosure* args[]; } PgfValueGen; typedef struct { PgfClosure header; PgfEnv* env; PgfMetaId id; - size_t n_args; - PgfClosure* args[]; } PgfValueMeta; typedef struct { @@ -68,11 +64,12 @@ struct PgfEvalGates { PgfFunction evaluate_expr_thunk; PgfFunction evaluate_indirection; PgfFunction evaluate_value; - PgfFunction evaluate_value_gen; - PgfFunction evaluate_value_meta; PgfFunction evaluate_value_lit; PgfFunction evaluate_value_pap; PgfFunction evaluate_value_lambda; + PgfFunction evaluate_value_const; + PgfFunction evaluate_meta; + PgfFunction evaluate_gen; PgfFunction evaluate_caf; PgfFunction update_closure; diff --git a/src/runtime/c/pgf/jit.c b/src/runtime/c/pgf/jit.c index 8cb2257d6..0b42cc91f 100644 --- a/src/runtime/c/pgf/jit.c +++ b/src/runtime/c/pgf/jit.c @@ -329,8 +329,7 @@ PgfEvalGates* pgf_jit_gates(PgfReader* rdr) { PgfEvalGates* gates = gu_new(PgfEvalGates, rdr->opool); - jit_insn* next; - jit_insn* ref, *ref2; + jit_insn *ref, *next, *ref2; pgf_jit_make_space(rdr, JIT_CODE_WINDOW); @@ -346,102 +345,6 @@ pgf_jit_gates(PgfReader* rdr) jit_ldxi_p(JIT_RET, JIT_VHEAP, offsetof(PgfValue, con)); jit_bare_ret(); - pgf_jit_make_space(rdr, JIT_CODE_WINDOW*2); - - gates->evaluate_value_gen = jit_get_ip().ptr; - jit_subr_p(JIT_R0, JIT_FP, JIT_SP); - jit_subi_p(JIT_R0, JIT_R0, sizeof(void*)); - ref = jit_bnei_i(jit_forward(), JIT_R0, 0); - jit_movr_p(JIT_VHEAP, JIT_VCLOS); - jit_bare_ret(); - jit_patch(ref); - jit_pushr_i(JIT_R0); - jit_prepare(2); - jit_addi_i(JIT_R0, JIT_R0, sizeof(PgfValueGen)); - jit_pusharg_ui(JIT_R0); - jit_ldxi_p(JIT_R0, JIT_VSTATE, offsetof(PgfEvalState,pool)); - jit_pusharg_p(JIT_R0); - jit_finish(gu_malloc); - jit_retval(JIT_VHEAP); - jit_popr_i(JIT_R0); - jit_movi_p(JIT_R1, gates->evaluate_value_gen); - jit_str_p(JIT_VHEAP, JIT_R1); - jit_ldxi_p(JIT_R1, JIT_VCLOS, offsetof(PgfValueGen,level)); - jit_stxi_p(offsetof(PgfValueGen,level), JIT_VHEAP, JIT_R1); - jit_ldxi_p(JIT_R1, JIT_VCLOS, offsetof(PgfValueGen,n_args)); - jit_addr_i(JIT_R1, JIT_R1, JIT_R0); - jit_stxi_p(offsetof(PgfValueGen,n_args), JIT_VHEAP, JIT_R1); - jit_movi_i(JIT_R1, offsetof(PgfValueGen,args)); - jit_ldxi_i(JIT_R2, JIT_VCLOS, offsetof(PgfValueGen,n_args)); - jit_addr_i(JIT_R2, JIT_R2, JIT_R1); - jit_pushr_i(JIT_R0); - next = jit_get_label(); - ref = jit_bger_i(jit_forward(), JIT_R1, JIT_R2); - jit_ldxr_i(JIT_R0, JIT_VCLOS, JIT_R1); - jit_stxr_p(JIT_R1, JIT_VHEAP, JIT_R0); - jit_addi_i(JIT_R1, JIT_R1, sizeof(void*)); - jit_jmpi(next); - jit_patch(ref); - jit_popr_i(JIT_R0); - jit_addr_i(JIT_R2, JIT_R2, JIT_R0); - jit_popr_p(JIT_VCLOS); - next = jit_get_label(); - ref = jit_bger_i(jit_forward(), JIT_R1, JIT_R2); - jit_popr_p(JIT_R0); - jit_stxr_p(JIT_R1, JIT_VHEAP, JIT_R0); - jit_addi_i(JIT_R1, JIT_R1, sizeof(void*)); - jit_jmpi(next); - jit_patch(ref); - jit_jmpr(JIT_VCLOS); - - pgf_jit_make_space(rdr, JIT_CODE_WINDOW*2); - - gates->evaluate_value_meta = jit_get_ip().ptr; - jit_subr_p(JIT_R0, JIT_FP, JIT_SP); - jit_subi_p(JIT_R0, JIT_R0, sizeof(void*)); - ref = jit_bnei_i(jit_forward(), JIT_R0, 0); - jit_movr_p(JIT_VHEAP, JIT_VCLOS); - jit_bare_ret(); - jit_patch(ref); - jit_pushr_i(JIT_R0); - jit_prepare(2); - jit_addi_i(JIT_R0, JIT_R0, sizeof(PgfValueMeta)); - jit_pusharg_ui(JIT_R0); - jit_ldxi_p(JIT_R0, JIT_VSTATE, offsetof(PgfEvalState,pool)); - jit_pusharg_p(JIT_R0); - jit_finish(gu_malloc); - jit_retval(JIT_VHEAP); - jit_popr_i(JIT_R0); - jit_movi_p(JIT_R1, gates->evaluate_value_meta); - jit_str_p(JIT_VHEAP, JIT_R1); - jit_ldxi_p(JIT_R1, JIT_VCLOS, offsetof(PgfValueMeta,id)); - jit_stxi_p(offsetof(PgfValueMeta,id), JIT_VHEAP, JIT_R1); - jit_ldxi_p(JIT_R1, JIT_VCLOS, offsetof(PgfValueMeta,n_args)); - jit_addr_i(JIT_R1, JIT_R1, JIT_R0); - jit_stxi_p(offsetof(PgfValueMeta,n_args), JIT_VHEAP, JIT_R1); - jit_movi_i(JIT_R1, offsetof(PgfValueMeta,args)); - jit_ldxi_i(JIT_R2, JIT_VCLOS, offsetof(PgfValueMeta,n_args)); - jit_addr_i(JIT_R2, JIT_R2, JIT_R1); - jit_pushr_i(JIT_R0); - next = jit_get_label(); - ref = jit_bger_i(jit_forward(), JIT_R1, JIT_R2); - jit_ldxr_i(JIT_R0, JIT_VCLOS, JIT_R1); - jit_stxr_p(JIT_R1, JIT_VHEAP, JIT_R0); - jit_addi_i(JIT_R1, JIT_R1, sizeof(PgfClosure*)); - jit_jmpi(next); - jit_patch(ref); - jit_popr_i(JIT_R0); - jit_addr_i(JIT_R2, JIT_R2, JIT_R0); - jit_popr_p(JIT_VCLOS); - next = jit_get_label(); - ref = jit_bger_i(jit_forward(), JIT_R1, JIT_R2); - jit_popr_p(JIT_R0); - jit_stxr_p(JIT_R1, JIT_VHEAP, JIT_R0); - jit_addi_i(JIT_R1, JIT_R1, sizeof(PgfClosure*)); - jit_jmpi(next); - jit_patch(ref); - jit_jmpr(JIT_VCLOS); - pgf_jit_make_space(rdr, JIT_CODE_WINDOW); gates->evaluate_value_lit = jit_get_ip().ptr; @@ -470,6 +373,7 @@ pgf_jit_gates(PgfReader* rdr) jit_getarg_p(JIT_VCLOS, closure_arg); jit_ldr_p(JIT_R0, JIT_VCLOS); jit_callr(JIT_R0); + jit_insn* enter_ret = (void*) jit_get_ip().ptr; jit_movr_p(JIT_RET, JIT_VHEAP); jit_ret(); @@ -571,6 +475,7 @@ pgf_jit_gates(PgfReader* rdr) ref = jit_beqr_p(jit_forward(), JIT_VCLOS, JIT_RET); jit_pushr_p(JIT_VCLOS); jit_pushr_p(JIT_FP); + jit_movr_p(JIT_FP, JIT_SP); jit_movi_p(JIT_R1, gates->update_closure); jit_pushr_p(JIT_R1); jit_retval(JIT_VCLOS); @@ -595,31 +500,96 @@ pgf_jit_gates(PgfReader* rdr) jit_ldr_p(JIT_R0, JIT_VCLOS); jit_jmpr(JIT_R0); + pgf_jit_make_space(rdr, JIT_CODE_WINDOW*2); + + gates->evaluate_value_const = jit_get_ip().ptr; + jit_jmpi(gates->evaluate_value); + + pgf_jit_make_space(rdr, JIT_CODE_WINDOW*2); + gates->mk_const = jit_get_ip().ptr; - jit_ldxi_p(JIT_R0, JIT_VCLOS, offsetof(PgfAbsFun,arity)-offsetof(PgfAbsFun,closure)); - jit_muli_i(JIT_R0, JIT_R0, sizeof(PgfClosure*)); + jit_popr_p(JIT_R0); + ref2 = jit_bnei_i(jit_forward(), JIT_R0, (int)gates->update_closure); + jit_subr_p(JIT_R0, JIT_FP, JIT_SP); jit_pushr_i(JIT_R0); jit_prepare(2); - jit_addi_i(JIT_R0, JIT_R0, sizeof(PgfValue)); + jit_addi_i(JIT_R0, JIT_R0, sizeof(PgfValuePAP)); jit_pusharg_ui(JIT_R0); jit_ldxi_p(JIT_R0, JIT_VSTATE, offsetof(PgfEvalState,pool)); jit_pusharg_p(JIT_R0); jit_finish(gu_malloc); - jit_movi_p(JIT_R1, gates->evaluate_value); - jit_str_p(JIT_RET, JIT_R1); - jit_stxi_p(offsetof(PgfValue,con), JIT_RET, JIT_VCLOS); - jit_movr_p(JIT_VHEAP, JIT_RET); jit_popr_i(JIT_R1); - jit_popr_p(JIT_VCLOS); + jit_movi_p(JIT_R2, gates->evaluate_value_const); + jit_str_p(JIT_RET, JIT_R2); + jit_stxi_p(offsetof(PgfValuePAP,fun), JIT_RET, JIT_VCLOS); + jit_stxi_p(offsetof(PgfValuePAP,n_args), JIT_RET, JIT_R1); + jit_ldxi_p(JIT_VHEAP, JIT_FP, sizeof(void*)); + jit_movi_p(JIT_R2, gates->evaluate_indirection); + jit_str_p(JIT_VHEAP, JIT_R2); + jit_stxi_p(offsetof(PgfIndirection, val), JIT_VHEAP, JIT_RET); + jit_ldr_p(JIT_R2, JIT_FP); + jit_pushr_p(JIT_R2); + jit_ldxi_p(JIT_R2, JIT_FP, 2*sizeof(void*)); + jit_pushr_p(JIT_R2); + jit_addi_p(JIT_RET, JIT_RET, offsetof(PgfValuePAP,args)-sizeof(PgfClosure*)); next = jit_get_label(); ref = jit_blei_i(jit_forward(), JIT_R1, 0); - jit_popr_p(JIT_R2); - jit_stxi_p(offsetof(PgfValue,args), JIT_RET, JIT_R2); - jit_addi_i(JIT_RET, JIT_RET, sizeof(void*)); + jit_ldxi_p(JIT_R2, JIT_FP, -sizeof(void*)); + jit_stxi_p(2*sizeof(void*), JIT_FP, JIT_R2); + jit_stxr_p(JIT_R1, JIT_RET, JIT_R2); + jit_subi_i(JIT_FP, JIT_FP, sizeof(void*)); jit_subi_i(JIT_R1, JIT_R1, sizeof(void*)); jit_jmpi(next); jit_patch(ref); - jit_jmpr(JIT_VCLOS); + jit_popr_p(JIT_R0); + jit_popr_p(JIT_FP); + jit_addi_p(JIT_SP, JIT_SP, 3*sizeof(void*)); + jit_pushr_p(JIT_R0); + jit_jmpi(gates->mk_const); + jit_patch(ref2); + ref2 = jit_bnei_i(jit_forward(), JIT_R0, (int)enter_ret); + jit_subr_p(JIT_R0, JIT_FP, JIT_SP); + jit_pushr_i(JIT_R0); + jit_prepare(2); + jit_addi_i(JIT_R0, JIT_R0, sizeof(PgfValuePAP)); + jit_pusharg_ui(JIT_R0); + jit_ldxi_p(JIT_R0, JIT_VSTATE, offsetof(PgfEvalState,pool)); + jit_pusharg_p(JIT_R0); + jit_finish(gu_malloc); + jit_popr_i(JIT_R1); + jit_movr_p(JIT_VHEAP, JIT_RET); + jit_movi_p(JIT_R2, gates->evaluate_value_const); + jit_str_p(JIT_VHEAP, JIT_R2); + jit_stxi_p(offsetof(PgfValuePAP,fun), JIT_VHEAP, JIT_VCLOS); + jit_stxi_p(offsetof(PgfValuePAP,n_args), JIT_VHEAP, JIT_R1); + next = jit_get_label(); + ref = jit_blei_i(jit_forward(), JIT_R1, 0); + jit_popr_p(JIT_R2); + jit_stxi_p(offsetof(PgfValuePAP,args), JIT_RET, JIT_R2); + jit_addi_p(JIT_RET, JIT_RET, sizeof(void*)); + jit_subi_i(JIT_R1, JIT_R1, sizeof(void*)); + jit_jmpi(next); + jit_patch(ref); + jit_jmpi(enter_ret); + jit_patch(ref2); + jit_ldxi_p(JIT_VCLOS, JIT_FP, sizeof(void*)); + jit_ldr_p(JIT_FP, JIT_FP); + jit_ldxi_i(JIT_R0, JIT_VCLOS, offsetof(PgfAbsFun,arity)-offsetof(PgfAbsFun,closure)); + jit_muli_i(JIT_R0, JIT_R0, sizeof(PgfClosure*)); + jit_addi_i(JIT_R0, JIT_R0, sizeof(void*)); + jit_subr_p(JIT_R0, JIT_FP, JIT_R0); // don't use jit_subr_p(JIT_SP, JIT_FP, JIT_R0) since it is dangerous on x86 + jit_movr_p(JIT_SP, JIT_R0); + jit_jmpi(gates->mk_const); + + pgf_jit_make_space(rdr, JIT_CODE_WINDOW*2); + + gates->evaluate_gen = jit_get_ip().ptr; + jit_jmpi(gates->mk_const); + + pgf_jit_make_space(rdr, JIT_CODE_WINDOW*2); + + gates->evaluate_meta = jit_get_ip().ptr; + jit_jmpi(gates->mk_const); gates->fin.fn = pgf_jit_finalize_cafs; gates->cafs = NULL; @@ -1134,15 +1104,21 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr, } case PGF_INSTR_DROP: { size_t n = pgf_read_int(rdr); + +#ifdef PGF_JIT_DEBUG + gu_printf(out, err, "DROP %d\n", n); +#endif + + jit_addi_p(JIT_SP, JIT_SP, n*sizeof(PgfClosure*)); + break; + } + case PGF_INSTR_JUMP: { size_t target = pgf_read_int(rdr); #ifdef PGF_JIT_DEBUG - gu_printf(out, err, "DROP %d %03d\n", n, target); + gu_printf(out, err, "JUMP %03d\n", target); #endif - - if (n > 0) - jit_addi_p(JIT_SP, JIT_SP, n*sizeof(PgfClosure*)); - + jit_insn *jump = jit_jmpi(jit_forward()); @@ -1151,7 +1127,6 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr, label_patch.ref = jump; label_patch.is_abs = false; gu_buf_push(rdr->jit_state->segment_patches, PgfSegmentPatch, label_patch); - break; } case PGF_INSTR_FAIL: diff --git a/src/runtime/haskell/PGF/Binary.hs b/src/runtime/haskell/PGF/Binary.hs index 9a74ac2f2..93214038c 100644 --- a/src/runtime/haskell/PGF/Binary.hs +++ b/src/runtime/haskell/PGF/Binary.hs @@ -168,9 +168,10 @@ instance Binary Instr where put (EVAL (ARG_VAR n) (UpdateCall b c)) = putWord8 49 >> put n >> put (b,c) put (EVAL (FREE_VAR n) (UpdateCall b c)) = putWord8 50 >> put n >> put (b,c) put (EVAL (GLOBAL id) (UpdateCall b c)) = putWord8 51 >> put id >> put (b,c) - put (DROP n l ) = putWord8 52 >> put (n,l) - put (FAIL ) = putWord8 56 - put (ADD ) = putWord8 60 + put (DROP n ) = putWord8 52 >> put n + put (JUMP l ) = putWord8 56 >> put l + put (FAIL ) = putWord8 60 + put (ADD ) = putWord8 64 instance Binary Type where put (DTyp hypos cat exps) = put (hypos,cat,exps) diff --git a/src/runtime/haskell/PGF/ByteCode.hs b/src/runtime/haskell/PGF/ByteCode.hs index ababdde0d..46f81cff9 100644 --- a/src/runtime/haskell/PGF/ByteCode.hs +++ b/src/runtime/haskell/PGF/ByteCode.hs @@ -26,7 +26,8 @@ data Instr | SET_PAD | PUSH IVal | EVAL IVal TailInfo - | DROP {-# UNPACK #-} !Int {-# UNPACK #-} !CodeLabel + | DROP {-# UNPACK #-} !Int + | JUMP {-# UNPACK #-} !CodeLabel | FAIL | ADD @@ -60,7 +61,8 @@ ppInstr (SET v) = text "SET " <+> ppIVal v ppInstr (SET_PAD ) = text "SET_PAD" ppInstr (PUSH v) = text "PUSH " <+> ppIVal v ppInstr (EVAL v ti) = text "EVAL " <+> ppIVal v <+> ppTailInfo ti -ppInstr (DROP n l ) = text "DROP " <+> int n <+> ppLabel l +ppInstr (DROP n ) = text "DROP " <+> int n +ppInstr (JUMP l ) = text "JUMP " <+> ppLabel l ppInstr (FAIL ) = text "FAIL" ppInstr (ADD ) = text "ADD"