diff options
author | Andy Wingo <wingo@pobox.com> | 2018-09-02 11:51:45 +0200 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2018-09-02 11:54:12 +0200 |
commit | 54b23adc1384854264c62fe79f5af15927240c71 (patch) | |
tree | 74546d962f5ab359a951e16e302c68bfad86c8d4 /libguile/jit.c | |
parent | 076c3ad8d71f7d48374b79b04aa162802abb5e57 (diff) | |
download | guile-54b23adc1384854264c62fe79f5af15927240c71.tar.gz |
Add ability to tier up from within loops
* libguile/jit.c (struct scm_jit_state): Add entry and entry_label
members.
(analyze): Assert entry is jump target.
(compile): Record indirect entry label.
(compute_mcode): Record entry IP, and return entry mcode.
(scm_sys_jit_compile, scm_jit_compute_mcode): Adapt to compute_mcode
change. Support hot-loop transfer.
Diffstat (limited to 'libguile/jit.c')
-rw-r--r-- | libguile/jit.c | 69 |
1 files changed, 46 insertions, 23 deletions
diff --git a/libguile/jit.c b/libguile/jit.c index 069a765bb..351648cca 100644 --- a/libguile/jit.c +++ b/libguile/jit.c @@ -148,8 +148,6 @@ static void *exit_mcode; instruction, compiled as a stub on the side to reduce code size. */ static void *handle_interrupts_trampoline; -static void compute_mcode (scm_thread *, struct scm_jit_function_data *); - /* State of the JIT compiler for the current thread. */ struct scm_jit_state { jit_state_t *jit; @@ -158,6 +156,8 @@ struct scm_jit_state { uint32_t *ip; uint32_t *next_ip; const uint32_t *end; + uint32_t *entry; + jit_node_t *entry_label; uint8_t *op_attrs; jit_node_t **labels; int32_t frame_size; @@ -4377,6 +4377,9 @@ analyze (scm_jit_state *j) break; } } + + /* Even in loops, the entry should be a jump target. */ + ASSERT (j->op_attrs[j->entry - j->start] & OP_ATTR_BLOCK); } static void @@ -4408,6 +4411,8 @@ compile (scm_jit_state *j) j->register_state = state; jit_link (j->labels[offset]); } + if (j->ip == j->entry) + j->entry_label = jit_indirect (); compile1 (j); } } @@ -4437,10 +4442,12 @@ initialize_jit (void) j->jit = NULL; } -static void -compute_mcode (scm_thread *thread, struct scm_jit_function_data *data) +static uint8_t * +compute_mcode (scm_thread *thread, uint32_t *entry_ip, + struct scm_jit_function_data *data) { scm_jit_state *j = thread->jit_state; + uint8_t *entry_mcode; if (!j) { @@ -4458,27 +4465,34 @@ compute_mcode (scm_thread *thread, struct scm_jit_function_data *data) j->thread = thread; j->start = (const uint32_t *) (((char *)data) + data->start); j->end = (const uint32_t *) (((char *)data) + data->end); + j->entry = entry_ip; j->op_attrs = malloc ((j->end - j->start) * sizeof (*j->op_attrs)); ASSERT (j->op_attrs); j->labels = malloc ((j->end - j->start) * sizeof (*j->labels)); ASSERT (j->labels); ASSERT (j->start < j->end); + ASSERT (j->start <= j->entry); + ASSERT (j->entry < j->end); j->frame_size = -1; j->hooks_enabled = 0; /* ? */ j->jit = jit_new_state (); - INFO ("vcode: start=%p,+%zu\n", j->start, j->end - j->start); + INFO ("vcode: start=%p,+%zu entry=+%zu\n", j->start, j->end - j->start, + j->entry - j->start); compile (j); data->mcode = jit_emit (); + entry_mcode = jit_address (j->entry_label); + { jit_word_t size = 0; jit_get_code (&size); - DEBUG ("mcode: %p,+%zu\n", data->mcode, size); + DEBUG ("mcode: %p,+%zu entry=+%zu\n", data->mcode, size, + entry_mcode - data->mcode); } free (j->labels); @@ -4488,6 +4502,8 @@ compute_mcode (scm_thread *thread, struct scm_jit_function_data *data) j->start = j->end = j->ip = NULL; j->frame_size = -1; + + return entry_mcode; } /* This is a temporary function; just here while we're still kicking the @@ -4507,7 +4523,7 @@ scm_sys_jit_compile (SCM fn) data = (struct scm_jit_function_data *) (code + (int32_t)code[1]); - compute_mcode (SCM_I_CURRENT_THREAD, data); + compute_mcode (SCM_I_CURRENT_THREAD, code, data); return SCM_UNSPECIFIED; } @@ -4517,29 +4533,36 @@ scm_jit_compute_mcode (scm_thread *thread, struct scm_jit_function_data *data) { const uint32_t *vcode_start = (const uint32_t *) (((char *)data) + data->start); - if (vcode_start == thread->vm.ip) + if (data->mcode) { - if (!data->mcode) - { - compute_mcode (thread, data); + if (vcode_start == thread->vm.ip) + return data->mcode; + + /* FIXME: The function has mcode, compiled via some other + activation (possibly in another thread), but right now we're + currently in an interpreted loop (not at the beginning of the + function). We should re-compute the offset into the mcode. + For now though, just punt. */ + return NULL; + } + else + { + uint8_t *mcode = compute_mcode (thread, thread->vm.ip, data); - if (--jit_stop_after == 0) + if (--jit_stop_after == 0) + { + scm_jit_counter_threshold = -1; + fprintf (stderr, "stopping automatic JIT compilation, as requested\n"); + if (jit_pause_when_stopping) { - scm_jit_counter_threshold = -1; - fprintf (stderr, "stopping automatic JIT compilation, as requested\n"); - if (jit_pause_when_stopping) - { - fprintf (stderr, "sleeping for 30s; to debug:\n"); - fprintf (stderr, " gdb -p %d\n\n", getpid ()); - sleep (30); - } + fprintf (stderr, "sleeping for 30s; to debug:\n"); + fprintf (stderr, " gdb -p %d\n\n", getpid ()); + sleep (30); } } - return data->mcode; + return mcode; } - - return NULL; } void |