Permalink
Browse files

Inline args preparation into interpreter, JIT.

Shaves some more instructions off every invocation. The C compiler
may have got to the inline into interp.c anyway, but the JIT one will
certainly save a bunch of instructions per invocation.
  • Loading branch information...
1 parent e2e8e03 commit 494b4e44cfa5e1a82fc984460cfe8d430d441792 @jnthn jnthn committed May 27, 2016
Showing with 14 additions and 18 deletions.
  1. +0 −9 src/core/args.c
  2. +0 −1 src/core/args.h
  3. +6 −1 src/core/interp.c
  4. +8 −7 src/jit/emit_x64.dasc
View
@@ -122,15 +122,6 @@ MVMObject * MVM_args_save_capture(MVMThreadContext *tc, MVMFrame *frame) {
return cc_obj;
}
-MVMCallsite * MVM_args_prepare(MVMThreadContext *tc, MVMCompUnit *cu, MVMint16 callsite_idx) {
- /* Store callsite in the frame so that the GC knows how to mark any arguments.
- * Note that since none of the arg-setting ops can trigger GC, there's no way
- * the setup can be interupted, so we don't need to clear the args buffer. */
- MVMCallsite *cs = cu->body.callsites[callsite_idx];
- tc->cur_frame->cur_args_callsite = cs;
- return cs;
-}
-
static void flatten_args(MVMThreadContext *tc, MVMArgProcContext *ctx);
/* Checks that the passed arguments fall within the expected arity. */
View
@@ -60,7 +60,6 @@ void MVM_args_checkarity(MVMThreadContext *tc, MVMArgProcContext *ctx, MVMuint16
void MVM_args_checkarity_for_jit(MVMThreadContext *tc, MVMuint16 min, MVMuint16 max);
MVMCallsite * MVM_args_copy_callsite(MVMThreadContext *tc, MVMArgProcContext *ctx);
MVMCallsite * MVM_args_proc_to_callsite(MVMThreadContext *tc, MVMArgProcContext *ctx, MVMuint8 *owns_callsite);
-MVMCallsite * MVM_args_prepare(MVMThreadContext *tc, MVMCompUnit *cu, MVMint16 callsite_idx);
MVM_PUBLIC MVMObject * MVM_args_use_capture(MVMThreadContext *tc, MVMFrame *f);
MVM_PUBLIC MVMObject * MVM_args_save_capture(MVMThreadContext *tc, MVMFrame *f);
View
@@ -797,7 +797,12 @@ void MVM_interp_run(MVMThreadContext *tc, void (*initial_invoke)(MVMThreadContex
goto NEXT;
}
OP(prepargs):
- cur_callsite = MVM_args_prepare(tc, cu, GET_UI16(cur_op, 0));
+ /* Store callsite in the frame so that the GC knows how to mark
+ * any arguments. Note that since none of the arg-setting ops can
+ * trigger GC, there's no way the setup can be interupted, so we
+ * don't need to clear the args buffer before we start. */
+ cur_callsite = cu->body.callsites[GET_UI16(cur_op, 0)];
+ tc->cur_frame->cur_args_callsite = cur_callsite;
cur_op += 2;
goto NEXT;
OP(arg_i):
View
@@ -79,6 +79,7 @@
|.type REGISTER, MVMRegister
|.type FRAME, MVMFrame
|.type ARGCTX, MVMArgProcContext
+|.type CALLSITEPTR, MVMCallsite*
|.type CAPTURE, MVMCallCapture
|.type CAPTUREBODY, MVMCallCaptureBody
|.type ARGPROCCONTEXT, MVMArgProcContext
@@ -2274,16 +2275,16 @@ void MVM_jit_emit_guard(MVMThreadContext *tc, MVMJitGraph *jg,
void MVM_jit_emit_invoke(MVMThreadContext *tc, MVMJitGraph *jg, MVMJitInvoke *invoke,
dasm_State **Dst) {
MVMint16 i;
+ MVMuint16 callsite_idx = invoke->callsite_idx;
MVM_jit_log(tc, "Emit invoke (%d args)\n", invoke->arg_count);
- /* setup the callsite */
- | mov ARG1, TC;
- | mov ARG2, CU;
- | mov ARG3, invoke->callsite_idx;
- | callp &MVM_args_prepare;
- | mov TMP6, RV; // store callsite in tmp6, which we don't use until the end
- /* Store arguments in the buffer. I use TMP5 as it never conflicts
+ /* Store callsite in tmp6, which we use at the end of invoke */
+ | mov TMP6, CU->body.callsites;
+ | mov TMP6, CALLSITEPTR:TMP6[callsite_idx];
+
+ /* Store callsite in the frame. I use TMP5 as it never conflicts
* with argument passing (like TMP6, but unlike other TMP regs) */
| mov TMP5, TC->cur_frame;
+ | mov FRAME:TMP5->cur_args_callsite, TMP6;
/* Setup the frame for returning to our current position */
if (sizeof(MVMReturnType) == 4) {

0 comments on commit 494b4e4

Please sign in to comment.