aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2024-10-22 18:56:04 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2024-10-22 18:56:04 +0300
commit3e8bbb6bcbb3b36e9813344e2f4528bb830d6ff4 (patch)
treee57ed757cd9aeab0673cd33882a07989e52513b0 /src
parent7f7b22674ed8e9633cd0e47662508c3641e9f967 (diff)
downloadejit-3e8bbb6bcbb3b36e9813344e2f4528bb830d6ff4.tar.gz
ejit-3e8bbb6bcbb3b36e9813344e2f4528bb830d6ff4.zip
move interp into run_interp
+ This allows us to skip a potential extra function call
Diffstat (limited to 'src')
-rw-r--r--src/common.h22
-rw-r--r--src/ejit.c53
-rw-r--r--src/interp.inc (renamed from src/interp.c)41
-rw-r--r--src/vec.h2
4 files changed, 66 insertions, 52 deletions
diff --git a/src/common.h b/src/common.h
index eb91409..64ca250 100644
--- a/src/common.h
+++ b/src/common.h
@@ -261,27 +261,33 @@ struct ejit_func {
};
-union interp_ret {
- int64_t r;
- double d;
-};
-
struct interp_state {
struct gprs gprs;
struct fprs fprs;
struct args args;
};
-union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
+int64_t ejit_interp(struct ejit_func *f, size_t argc,
+ struct ejit_arg args[argc],
+ struct interp_state *state, bool run,
+ void ***labels_wb);
+
+double ejit_interp_f(struct ejit_func *f, size_t argc,
struct ejit_arg args[argc],
struct interp_state *state, bool run,
void ***labels_wb);
int64_t ejit_run_interp(struct ejit_func *f, size_t argc,
- struct ejit_arg args[static argc], struct interp_state *state);
+ struct ejit_arg args[argc],
+ struct interp_state *state,
+ bool run,
+ void ***labels_wb);
double ejit_run_interp_f(struct ejit_func *f, size_t argc,
- struct ejit_arg args[static argc], struct interp_state *state);
+ struct ejit_arg args[argc],
+ struct interp_state *state,
+ bool run,
+ void ***labels_wb);
bool ejit_compile(struct ejit_func *f, bool use_64);
diff --git a/src/ejit.c b/src/ejit.c
index 86329de..c202c7a 100644
--- a/src/ejit.c
+++ b/src/ejit.c
@@ -1,3 +1,4 @@
+#include <math.h>
#include <assert.h>
#include <sys/mman.h>
@@ -96,7 +97,11 @@ void ejit_select_compile_func(struct ejit_func *f, size_t gpr, size_t fpr,
void **labels;
/* just get labels, don't actually run anything yet */
- ejit_interp(f, 0, NULL, NULL, false, &labels);
+ if (ejit_float_type(f->rtype))
+ ejit_run_interp_f(f, 0, NULL, NULL, false, &labels);
+ else
+ ejit_run_interp(f, 0, NULL, NULL, false, &labels);
+
foreach_vec(ii, f->insns) {
struct ejit_insn i = *insns_at(&f->insns, ii);
void *addr = labels[i.op];
@@ -1251,26 +1256,40 @@ static void destroy_interp_state(struct interp_state state)
args_destroy(&state.args);
}
-long ejit_run_interp(struct ejit_func *f, size_t argc,
- struct ejit_arg args[argc], struct interp_state *state)
+int64_t ejit_run_interp(struct ejit_func *f, size_t argc,
+ struct ejit_arg args[argc],
+ struct interp_state *state,
+ bool run,
+ void ***labels_wb)
{
- assert(f->gpr && "trying to run a function that hasn't been compiled");
- assert(f->rtype == EJIT_VOID || ejit_int_type(f->rtype));
- if (f->arena)
- return ((ejit_escape_t)f->arena)(argc, args);
+ if (run) {
+ assert(f->gpr && "trying to run a function that hasn't been compiled");
+ assert(f->rtype == EJIT_VOID || ejit_int_type(f->rtype));
+ if (f->arena)
+ return ((ejit_escape_t)f->arena)(argc, args);
+ }
- return ejit_interp(f, argc, args, state, true, NULL).r;
+ int64_t retval = 0; double retval_f = 0.0;
+#include "interp.inc"
+ return retval;
}
double ejit_run_interp_f(struct ejit_func *f, size_t argc,
- struct ejit_arg args[argc], struct interp_state *state)
-{
- assert(f->gpr && "trying to run a function that hasn't been compiled");
- assert(f->rtype == EJIT_VOID || ejit_int_type(f->rtype));
- if (f->arena)
- return ((ejit_escape_f_t)f->arena)(argc, args);
+ struct ejit_arg args[argc],
+ struct interp_state *state,
+ bool run,
+ void ***labels_wb)
+{
+ if (run) {
+ assert(f->gpr && "trying to run a function that hasn't been compiled");
+ assert(f->rtype == EJIT_VOID || ejit_int_type(f->rtype));
+ if (f->arena)
+ return ((ejit_escape_f_t)f->arena)(argc, args);
+ }
- return ejit_interp(f, argc, args, state, true, NULL).d;
+ int64_t retval = 0; double retval_f = 0.0;
+#include "interp.inc"
+ return retval_f;
}
int64_t ejit_run_func(struct ejit_func *f, size_t argc,
@@ -1282,7 +1301,7 @@ int64_t ejit_run_func(struct ejit_func *f, size_t argc,
return (int64_t)((ejit_escape_t)f->arena)(argc, args);
struct interp_state state = create_interp_state();
- long r = ejit_interp(f, argc, args, &state, true, NULL).r;
+ long r = ejit_run_interp(f, argc, args, &state, true, NULL);
destroy_interp_state(state);
return r;
}
@@ -1296,7 +1315,7 @@ double ejit_run_func_f(struct ejit_func *f, size_t argc,
return ((ejit_escape_f_t)f->arena)(argc, args);
struct interp_state state = create_interp_state();
- double r = ejit_interp(f, argc, args, &state, true, NULL).d;
+ double r = ejit_run_interp_f(f, argc, args, &state, true, NULL);
destroy_interp_state(state);
return r;
}
diff --git a/src/interp.c b/src/interp.inc
index 01121e5..75e7ff2 100644
--- a/src/interp.c
+++ b/src/interp.inc
@@ -1,12 +1,6 @@
-#include <ejit/ejit.h>
-#include <math.h>
-
-#include "common.h"
-
-union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
- struct ejit_arg args[argc],
- struct interp_state *state, bool run,
- void ***labels_wb)
+/* this is the body of a given ejit_interp function, it assumes there's an
+ * external int64_t retval and double retval_f into which it places the value to
+ * be returned. Included from src/interp.c */
{
static void *labels[OPCODE_COUNT] = {
[MOVI] = &&MOVI,
@@ -216,7 +210,7 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
if (!run) {
*labels_wb = labels;
- return (union interp_ret){.r = 0};
+ goto zero_out;
}
size_t prev_gprs = gprs_len(&state->gprs);
@@ -238,7 +232,6 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
/* retval is kind of an unfortunate extra bit of state to keep track of,
* but having call and return value separated is pretty convenient for
* void calls so I guess I don't mind? */
- int64_t retval = 0; double retval_f = 0.;
size_t pc = 0;
#define DO(x) x : { struct ejit_insn i = insns[pc]; (void)i;
@@ -251,7 +244,7 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
DISPATCH();
DO(END);
- goto out_int;
+ goto out;
DISPATCH();
DO(MOVI);
@@ -998,7 +991,7 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
struct ejit_arg *args = ((struct ejit_arg *)state->args.buf) +
prev_argc;
- retval = ejit_run_interp(f, argc, args, state);
+ retval = ejit_run_interp(f, argc, args, state, true, NULL);
gpr = ((long *)state->gprs.buf) + prev_gprs;
fpr = ((union fpr *)state->fprs.buf) + prev_fprs;
@@ -1011,7 +1004,7 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
struct ejit_arg *args = ((struct ejit_arg *)state->args.buf) +
prev_argc;
- retval_f = ejit_run_interp_f(f, argc, args, state);
+ retval_f = ejit_run_interp_f(f, argc, args, state, true, NULL);
gpr = ((long *)state->gprs.buf) + prev_gprs;
fpr = ((union fpr *)state->fprs.buf) + prev_fprs;
@@ -1044,45 +1037,41 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
* symmetry */
DO(RETR);
retval = gpr[i.r0];
- goto out_int;
+ goto out;
DISPATCH();
DO(RETI);
retval = i.o;
- goto out_int;
+ goto out;
DISPATCH();
DO(RETR_F);
retval_f = fpr[i.r0].f;
- goto out_float;
+ goto out;
DISPATCH();
DO(RETR_D);
retval_f = fpr[i.r0].d;
- goto out_float;
+ goto out;
DISPATCH();
DO(RETI_F);
retval_f = i.f;
- goto out_float;
+ goto out;
DISPATCH();
DO(RETI_D);
retval_f = i.d;
- goto out_float;
+ goto out;
DISPATCH();
#undef DISPATCH
#undef JUMP
#undef DO
-out_int:
+out:
gprs_shrink(&state->gprs, prev_gprs);
fprs_shrink(&state->fprs, prev_fprs);
- return (union interp_ret){.r = retval};
-out_float:
- gprs_shrink(&state->gprs, prev_gprs);
- fprs_shrink(&state->fprs, prev_fprs);
- return (union interp_ret){.d = retval_f};
+zero_out:
}
diff --git a/src/vec.h b/src/vec.h
index 37f29f6..90558ac 100644
--- a/src/vec.h
+++ b/src/vec.h
@@ -107,7 +107,7 @@ static inline void VEC(reserve)(struct VEC_STRUCT *v, size_t n)
static inline void VEC(shrink)(struct VEC_STRUCT *v, size_t n)
{
- assert(v->n >= n);
+ /* assert(v->n >= n); */
v->n = n;
}