-
-
Save niner/f566f86fc525c151b904f392cbca20f9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/core/frame.c b/src/core/frame.c | |
index 129a24191..7e47bd199 100644 | |
--- a/src/core/frame.c | |
+++ b/src/core/frame.c | |
@@ -556,6 +556,14 @@ void MVM_frame_invoke(MVMThreadContext *tc, MVMStaticFrame *static_frame, | |
} | |
/* Dispatches execution to the specified code object with the specified args. */ | |
+void MVM_frame_dispatch_jit(MVMThreadContext *tc, MVMCode *code, MVMCallsite *callsite, MVMRegister *source, MVMuint16 *map, MVMint32 spesh_cand) { | |
+ MVMArgs args = { | |
+ .callsite = callsite, | |
+ .source = source, | |
+ .map = map | |
+ }; | |
+ MVM_frame_dispatch(tc, code, args, spesh_cand); | |
+} | |
void MVM_frame_dispatch(MVMThreadContext *tc, MVMCode *code, MVMArgs args, MVMint32 spesh_cand) { | |
MVMFrame *frame; | |
MVMuint8 *chosen_bytecode; | |
diff --git a/src/core/frame.h b/src/core/frame.h | |
index 433e4e37a..2650d79d0 100644 | |
--- a/src/core/frame.h | |
+++ b/src/core/frame.h | |
@@ -190,6 +190,7 @@ void MVM_frame_invoke(MVMThreadContext *tc, MVMStaticFrame *static_frame, | |
MVMCallsite *callsite, MVMRegister *args, | |
MVMFrame *outer, MVMObject *code_ref, MVMint32 spesh_cand); | |
void MVM_frame_dispatch(MVMThreadContext *tc, MVMCode *code, MVMArgs args, MVMint32 spesh_cand); | |
+void MVM_frame_dispatch_jit(MVMThreadContext *tc, MVMCode *code, MVMCallsite *callsite, MVMRegister *source, MVMuint16 *map, MVMint32 spesh_cand); | |
void MVM_frame_dispatch_zero_args(MVMThreadContext *tc, MVMCode *code); | |
MVMFrame * MVM_frame_create_context_only(MVMThreadContext *tc, MVMStaticFrame *static_frame, | |
MVMObject *code_ref); | |
diff --git a/src/jit/compile.c b/src/jit/compile.c | |
index f85e6fdb1..5d0cbdd30 100644 | |
--- a/src/jit/compile.c | |
+++ b/src/jit/compile.c | |
@@ -97,6 +97,9 @@ MVMJitCode * MVM_jit_compile_graph(MVMThreadContext *tc, MVMJitGraph *jg) { | |
case MVM_JIT_NODE_INVOKE: | |
MVM_jit_emit_invoke(tc, &cl, jg, &node->u.invoke); | |
break; | |
+ case MVM_JIT_NODE_RUNCODE: | |
+ MVM_jit_emit_runcode(tc, &cl, jg, &node->u.runcode); | |
+ break; | |
case MVM_JIT_NODE_JUMPLIST: | |
MVM_jit_emit_jumplist(tc, &cl, jg, &node->u.jumplist); | |
break; | |
diff --git a/src/jit/graph.c b/src/jit/graph.c | |
index c007062cf..5cb3b2019 100644 | |
--- a/src/jit/graph.c | |
+++ b/src/jit/graph.c | |
@@ -3709,6 +3709,27 @@ start: | |
jg_append_call_c(tc, jg, op_to_func(tc, op), 1, args, MVM_JIT_RV_PTR, dst); | |
break; | |
} | |
+ case MVM_OP_sp_runcfunc_i: { | |
+ MVMint16 dst = ins->operands[0].reg.orig; | |
+ MVMint16 code = ins->operands[1].reg.orig; | |
+ MVMCallsite *callsite = (MVMCallsite*)ins->operands[2].lit_ui64; | |
+ | |
+ /* get label /after/ current (invoke) ins, where we'll need to reenter the JIT */ | |
+ MVMint32 reentry_label = MVM_jit_label_after_ins(tc, jg, iter->bb, ins); | |
+ MVMJitNode *node = MVM_spesh_alloc(tc, jg->sg, sizeof(MVMJitNode)); | |
+ node->type = MVM_JIT_NODE_RUNCODE; | |
+ node->u.runcode.callsite = callsite; | |
+ node->u.runcode.return_type = MVM_RETURN_INT; | |
+ node->u.runcode.return_register = dst; | |
+ node->u.runcode.code_register = code; | |
+ node->u.runcode.map = &ins->operands[3]; | |
+ node->u.runcode.spesh_cand = -1; | |
+ node->u.runcode.reentry_label = reentry_label; | |
+ jg_append_node(jg, node); | |
+ /* append reentry label */ | |
+ jg_append_label(tc, jg, reentry_label); | |
+ break; | |
+ } | |
default: { | |
/* Check if it's an extop. */ | |
MVMint32 emitted_extop = 0; | |
diff --git a/src/jit/graph.h b/src/jit/graph.h | |
index 83f01ba51..ba322e0f3 100644 | |
--- a/src/jit/graph.h | |
+++ b/src/jit/graph.h | |
@@ -189,6 +189,16 @@ struct MVMJitInvoke { | |
MVMint32 reentry_label; | |
}; | |
+struct MVMJitRunCode { | |
+ MVMCallsite *callsite; | |
+ MVMReturnType return_type; | |
+ MVMint16 return_register; | |
+ MVMint16 code_register; | |
+ MVMint16 spesh_cand; | |
+ MVMSpeshOperand *map; | |
+ MVMint32 reentry_label; | |
+}; | |
+ | |
struct MVMJitJumpList { | |
MVMint64 num_labels; | |
MVMint16 reg; | |
@@ -221,6 +231,7 @@ typedef enum { | |
MVM_JIT_NODE_DATA, | |
MVM_JIT_NODE_EXPR_TREE, | |
MVM_JIT_NODE_DEOPT_CHECK, | |
+ MVM_JIT_NODE_RUNCODE, | |
} MVMJitNodeType; | |
struct MVMJitNode { | |
@@ -238,6 +249,7 @@ struct MVMJitNode { | |
MVMJitData data; | |
MVMJitExprTree *tree; | |
MVMJitStackSlot stack; | |
+ MVMJitRunCode runcode; | |
} u; | |
}; | |
diff --git a/src/jit/x64/emit.dasc b/src/jit/x64/emit.dasc | |
index 360c3f46b..e0d0a12bc 100644 | |
--- a/src/jit/x64/emit.dasc | |
+++ b/src/jit/x64/emit.dasc | |
@@ -121,6 +121,7 @@ | |
|.type MPINT, mp_int | |
|.type MVMDISPINLINECACHEENTRY, MVMDispInlineCacheEntry | |
|.type MVMDISPINLINECACHE, MVMDispInlineCache | |
+|.type CFUNCTION, MVMCFunction | |
/* Static allocation of relevant types to registers. I pick | |
* callee-save registers for efficiency. It is likely we'll be calling | |
@@ -228,7 +229,6 @@ const unsigned char * MVM_jit_actions(void) { | |
|.define RVb, al | |
|.define RVF, xmm0 | |
- | |
|.macro callp, funcptr | |
|.data | |
|5: | |
@@ -3024,6 +3024,59 @@ void MVM_jit_emit_guard(MVMThreadContext *tc, MVMJitCompiler *compiler, MVMJitGr | |
|2: | |
} | |
+void MVM_jit_emit_runcode(MVMThreadContext *tc, MVMJitCompiler *compiler, MVMJitGraph *jg, MVMJitRunCode *runcode) { | |
+ MVMint16 i; | |
+ MVMuint64 callsite = (MVMuint64)runcode->callsite; | |
+ fprintf(stderr, "emit_runcode for %s %p return type %d code %d map %p reentry_label %d\n", MVM_string_utf8_maybe_encode_C_string(tc, jg->sg->sf->body.name), runcode->callsite, runcode->return_type, runcode->code_register, runcode->map, runcode->reentry_label); | |
+ | |
+ |.data | |
+ |5: | |
+ for (i = 0; i < runcode->callsite->flag_count; i++) { | |
+ |.word (MVMuint16)runcode->map[i].lit_ui16; | |
+ } | |
+ |.code | |
+ | |
+ /* The return address for the interpreter */ | |
+ | get_cur_op TMP2; | |
+ | mov TMP5, TC->cur_frame; | |
+ | mov aword FRAME:TMP5->return_address, TMP2; | |
+ | |
+ /* Store callsite in tmp6, which we use at the end of invoke */ | |
+ | mov64 TMP6, callsite; | |
+ | |
+ /* Store callsite in the frame. I use TMP5 as it never conflicts | |
+ * with argument passing (like TMP6, but unlike other TMP regs) */ | |
+ | mov FRAME:TMP5->cur_args_callsite, TMP6; | |
+ | |
+ /* Setup the frame for returning to our current position */ | |
+ if (sizeof(MVMReturnType) == 1) { | |
+ | mov byte FRAME:TMP5->return_type, runcode->return_type; | |
+ } else { | |
+ MVM_panic(1, "JIT: MVMReturnType has unexpected size"); | |
+ } | |
+ | |
+ /* The register for our return value */ | |
+ if (runcode->return_type == MVM_RETURN_VOID) { | |
+ | mov aword FRAME:TMP5->return_value, NULL; | |
+ } else { | |
+ | lea TMP2, WORK[runcode->return_register]; | |
+ | mov aword FRAME:TMP5->return_value, TMP2; | |
+ } | |
+ | |
+ | mov ARG1, TC; | |
+ /* TMP6 initialized by loadp callsite above */ | |
+ emit_stack_arg(tc, compiler, jg, 8, 0); | |
+ | mov TMP6, TC->interp_reg_base; | |
+ | mov TMP6, [TMP6]; | |
+ emit_stack_arg(tc, compiler, jg, 8, 8); | |
+ | lea TMP6, [<5]; | |
+ emit_stack_arg(tc, compiler, jg, 8, 16); | |
+ | mov FUNCTION, qword WORK[runcode->code_register]; | |
+ | mov FUNCTION, CFUNCTION:FUNCTION->body.func; | |
+ | call FUNCTION | |
+ | mov WORK[runcode->return_register], RV | |
+} | |
+ | |
void MVM_jit_emit_invoke(MVMThreadContext *tc, MVMJitCompiler *compiler, MVMJitGraph *jg, MVMJitInvoke *invoke) { | |
MVMint16 i; | |
MVMuint16 callsite_idx = invoke->callsite_idx; | |
diff --git a/src/types.h b/src/types.h | |
index 03edfbcaf..268fa8fe1 100644 | |
--- a/src/types.h | |
+++ b/src/types.h | |
@@ -263,6 +263,7 @@ typedef struct MVMJitJumpList MVMJitJumpList; | |
typedef struct MVMJitControl MVMJitControl; | |
typedef struct MVMJitData MVMJitData; | |
typedef struct MVMJitStackSlot MVMJitStackSlot; | |
+typedef struct MVMJitRunCode MVMJitRunCode; | |
typedef struct MVMJitCode MVMJitCode; | |
typedef struct MVMJitCompiler MVMJitCompiler; | |
typedef struct MVMJitExprTree MVMJitExprTree; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment