Skip to content

Commit

Permalink
Dynamically determine register for return value and type
Browse files Browse the repository at this point in the history
This replaces assumptions about which locals the high level code uses for
storing the return type and for expecting the return value by accessing the
register numbers stored in the byte code for nativecallinvokejit instructions.
You can now tell the JIT that the C function you want to call should take an
argument from WORK[cur_op + whatever] which is the equivalent of all those
GET_REG(cur_op, whatever) in interp.c.
Same for return values. When in interp.c you'd write GET_REG(cur_op, 0) = ...;
you tell the JIT: node->u.call.rv_mode = MVM_JIT_RV_DYNIDX;
box_rv_node->u.call.rv_idx = 0;
  • Loading branch information
niner committed Aug 31, 2017
1 parent aad9014 commit 59c737a
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 12 deletions.
17 changes: 6 additions & 11 deletions src/core/nativecall.c
Expand Up @@ -382,15 +382,15 @@ void init_c_call_node(MVMJitNode *node, void *func_ptr) {

void init_box_call_node(MVMJitNode *box_rv_node, void *func_ptr) {
MVMJitCallArg args[] = { { MVM_JIT_INTERP_VAR , { MVM_JIT_INTERP_TC } },
{ MVM_JIT_REG_VAL, { 0 } },
{ MVM_JIT_REG_DYNIDX, { 1 } },
{ MVM_JIT_SAVED_RV, { 0 } }};
init_c_call_node(box_rv_node, func_ptr);
box_rv_node->next = NULL;
box_rv_node->u.call.args = MVM_calloc(3, sizeof(MVMJitCallArg));
memcpy(box_rv_node->u.call.args, args, 3 * sizeof(MVMJitCallArg));
box_rv_node->u.call.num_args = 3;
box_rv_node->u.call.rv_mode = MVM_JIT_RV_PTR;
box_rv_node->u.call.rv_idx = 1;
box_rv_node->u.call.rv_mode = MVM_JIT_RV_DYNIDX;
box_rv_node->u.call.rv_idx = 0;
}

MVMJitCode *create_caller_code(MVMThreadContext *tc, MVMNativeCallBody *body) {
Expand Down Expand Up @@ -462,16 +462,16 @@ MVMJitCode *create_caller_code(MVMThreadContext *tc, MVMNativeCallBody *body) {
}
else if (body->ret_type == MVM_NATIVECALL_ARG_UTF8STR) {
MVMJitCallArg args[] = { { MVM_JIT_INTERP_VAR , { MVM_JIT_INTERP_TC } },
{ MVM_JIT_REG_VAL, { 0 } },
{ MVM_JIT_REG_DYNIDX, { 1 } },
{ MVM_JIT_LITERAL, { MVM_NATIVECALL_ARG_UTF8STR } },
{ MVM_JIT_SAVED_RV, { 0 } }};
init_c_call_node(&box_rv_node, &MVM_nativecall_make_str);
box_rv_node.next = NULL;
box_rv_node.u.call.args = MVM_calloc(4, sizeof(MVMJitCallArg));
memcpy(box_rv_node.u.call.args, args, 4 * sizeof(MVMJitCallArg));
box_rv_node.u.call.num_args = 4;
box_rv_node.u.call.rv_mode = MVM_JIT_RV_PTR;
box_rv_node.u.call.rv_idx = 1;
box_rv_node.u.call.rv_mode = MVM_JIT_RV_DYNIDX;
box_rv_node.u.call.rv_idx = 0;
}
else if (body->ret_type == MVM_NATIVECALL_ARG_VOID) {
call_node.next = &unblock_gc_node;
Expand All @@ -482,11 +482,6 @@ MVMJitCode *create_caller_code(MVMThreadContext *tc, MVMNativeCallBody *body) {
goto cleanup;
}

if (box_rv_node.u.call.args != NULL) {
box_rv_node.u.call.args[1].v.reg += body->num_args;
box_rv_node.u.call.rv_idx += body->num_args;
}

jg.num_labels = 1;
jitcode = MVM_jit_compile_graph(tc, &jg);

Expand Down
16 changes: 16 additions & 0 deletions src/jit/emit_x64.dasc
Expand Up @@ -1922,6 +1922,12 @@ static void load_call_arg(MVMThreadContext *tc, MVMJitGraph *jg,
| mov TMP6, qword WORK[arg.v.reg];
| lea TMP6, STOOGE:TMP6->data;
break;
case MVM_JIT_REG_DYNIDX:
| get_cur_op TMP5;
| xor TMP6, TMP6;
| mov TMP6w, word [TMP5 + arg.v.reg*2]
| mov TMP6, qword [WORK + TMP6*8];
break;
case MVM_JIT_DATA_LABEL:
| lea TMP6, [=>(arg.v.lit_i64)];
break;
Expand Down Expand Up @@ -2047,6 +2053,7 @@ static void emit_posix_callargs(MVMThreadContext *tc, MVMJitGraph *jg,
case MVM_JIT_REG_ADDR:
case MVM_JIT_REG_OBJBODY:
case MVM_JIT_REG_STABLE:
case MVM_JIT_REG_DYNIDX:
case MVM_JIT_STR_IDX:
case MVM_JIT_LITERAL:
case MVM_JIT_LITERAL_64:
Expand All @@ -2069,6 +2076,8 @@ static void emit_posix_callargs(MVMThreadContext *tc, MVMJitGraph *jg,
on_stack[num_stack++] = args[i];
}
break;
default:
MVM_oops(tc, "JIT: Unknown JIT argument type %d for emit_posix_callargs", args[i].type);
}
}
for (i = 0; i < num_gpr; i++) {
Expand Down Expand Up @@ -2145,6 +2154,13 @@ void MVM_jit_emit_call_c(MVMThreadContext *tc, MVMJitGraph *jg,
| mov TMP1, WORK[call_spec->rv_idx];
| mov [RV], TMP1;
break;
case MVM_JIT_RV_DYNIDX:
/* store in register relative to cur_op */
| get_cur_op TMP1;
| xor TMP2, TMP2;
| mov TMP2w, word [TMP1 + call_spec->rv_idx*2];
| mov aword [WORK + TMP2*8], RV;
break;
}
}

Expand Down
5 changes: 4 additions & 1 deletion src/jit/graph.h
Expand Up @@ -101,6 +101,7 @@ typedef enum {
MVM_JIT_LITERAL_PTR,
MVM_JIT_REG_STABLE,
MVM_JIT_REG_OBJBODY,
MVM_JIT_REG_DYNIDX,
MVM_JIT_DATA_LABEL,
MVM_JIT_SAVED_RV,
MVM_JIT_PARAM_I64,
Expand Down Expand Up @@ -130,7 +131,9 @@ typedef enum {
/* dereference and store */
MVM_JIT_RV_DEREF,
/* store local at address */
MVM_JIT_RV_ADDR
MVM_JIT_RV_ADDR,
/* store in register relative to cur_op */
MVM_JIT_RV_DYNIDX,
} MVMJitRVMode;


Expand Down

0 comments on commit 59c737a

Please sign in to comment.