diff options
author | Andy Wingo <wingo@pobox.com> | 2018-08-17 08:15:04 +0200 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2018-08-17 08:50:33 +0200 |
commit | 3827769aff190a5e155b29d37fe157dd6115ad04 (patch) | |
tree | cca82537cba9073fce356cd75575be82e98e466c /libguile/vm.c | |
parent | e6304fb2425475ddf441439ee3c510060f9464d4 (diff) | |
download | guile-3827769aff190a5e155b29d37fe157dd6115ad04.tar.gz |
Add instrumentation to VM builtins
* libguile/intrinsics.h: Add "intrinsic" for handle-interrupts code.
Unlike the other intrinsics, this one isn't a function.
* libguile/programs.c (try_parse_arity): Add cases for instructions used
in VM builtins.
(scm_primitive_call_ip): Return #f if call-ip not found.
* libguile/vm-engine.c (handle-interrupts): Get code from intrinsics.
* libguile/vm.c
* libguile/vm.c (instrumented_code, define_vm_builtins): Add
instrumentation to the builtins, so that they can be JIT-compiled.
(INIT_BUILTIN): Remove min-arity setting; the fallback min-arity
interpreter should figure it out.
(scm_bootstrap_vm): Call the new define_vm_builtins function.
* libguile/gsubr.c (primitive_call_ip): Return 0 if call IP not found.
(primitive_subr_idx): Interpret call ip == 0 as not-a-subr.
* module/system/vm/program.scm (program-arguments-alist): Allow a #f
call-ip.
Diffstat (limited to 'libguile/vm.c')
-rw-r--r-- | libguile/vm.c | 135 |
1 files changed, 77 insertions, 58 deletions
diff --git a/libguile/vm.c b/libguile/vm.c index ee22ad5c4..e14e5fe4a 100644 --- a/libguile/vm.c +++ b/libguile/vm.c @@ -300,60 +300,17 @@ vm_error_bad_instruction (uint32_t inst) static SCM vm_boot_continuation; -static SCM vm_builtin_apply; -static SCM vm_builtin_values; -static SCM vm_builtin_abort_to_prompt; -static SCM vm_builtin_call_with_values; -static SCM vm_builtin_call_with_current_continuation; + +#define DECLARE_BUILTIN(builtin, BUILTIN, req, opt, rest) \ + static SCM vm_builtin_##builtin; \ + static uint32_t *vm_builtin_##builtin##_code; +FOR_EACH_VM_BUILTIN (DECLARE_BUILTIN) +#undef DECLARE_BUILTIN static const uint32_t vm_boot_continuation_code[] = { SCM_PACK_OP_24 (halt, 0) }; -static const uint32_t vm_builtin_apply_code[] = { - SCM_PACK_OP_24 (assert_nargs_ge, 3), - SCM_PACK_OP_12_12 (shuffle_down, 1, 0), - SCM_PACK_OP_24 (expand_apply_argument, 0), - SCM_PACK_OP_24 (tail_call, 0), -}; - -static const uint32_t vm_builtin_values_code[] = { - SCM_PACK_OP_12_12 (shuffle_down, 1, 0), - SCM_PACK_OP_24 (return_values, 0) -}; - -static const uint32_t vm_builtin_abort_to_prompt_code[] = { - SCM_PACK_OP_24 (assert_nargs_ge, 2), - SCM_PACK_OP_24 (abort, 0), /* tag in r1, vals from r2 */ - /* FIXME: Partial continuation should capture caller regs. */ - SCM_PACK_OP_24 (return_values, 0) /* vals from r0 */ -}; - -static const uint32_t vm_builtin_call_with_values_code[] = { - SCM_PACK_OP_24 (assert_nargs_ee, 3), - SCM_PACK_OP_24 (alloc_frame, 8), - SCM_PACK_OP_12_12 (mov, 0, 6), - SCM_PACK_OP_24 (call, 7), SCM_PACK_OP_ARG_8_24 (0, 1), - SCM_PACK_OP_24 (long_fmov, 0), SCM_PACK_OP_ARG_8_24 (0, 2), - SCM_PACK_OP_12_12 (shuffle_down, 7, 1), - SCM_PACK_OP_24 (tail_call, 0) -}; - -static const uint32_t vm_builtin_call_with_current_continuation_code[] = { - SCM_PACK_OP_24 (assert_nargs_ee, 2), - SCM_PACK_OP_12_12 (mov, 1, 0), - SCM_PACK_OP_24 (capture_continuation, 0), - SCM_PACK_OP_24 (tail_call, 0) -}; - -static const uint32_t vm_handle_interrupt_code[] = { - SCM_PACK_OP_24 (alloc_frame, 4), - SCM_PACK_OP_12_12 (mov, 0, 3), - SCM_PACK_OP_24 (call, 3), SCM_PACK_OP_ARG_8_24 (0, 1), - SCM_PACK_OP_24 (return_from_interrupt, 0) -}; - - int scm_i_vm_is_boot_continuation_code (uint32_t *ip) { @@ -423,6 +380,75 @@ scm_init_vm_builtins (void) scm_vm_builtin_index_to_name); } +static uint32_t* +instrumented_code (const uint32_t *code, size_t byte_size) +{ + uint32_t *ret, *write; + ret = scm_i_alloc_primitive_code_with_instrumentation (byte_size / 4, &write); + memcpy (write, code, byte_size); + return ret; +} + +static void +define_vm_builtins (void) +{ + const uint32_t apply_code[] = { + SCM_PACK_OP_24 (assert_nargs_ge, 3), + SCM_PACK_OP_12_12 (shuffle_down, 1, 0), + SCM_PACK_OP_24 (expand_apply_argument, 0), + SCM_PACK_OP_24 (tail_call, 0), + }; + + const uint32_t values_code[] = { + SCM_PACK_OP_12_12 (shuffle_down, 1, 0), + SCM_PACK_OP_24 (return_values, 0) + }; + + const uint32_t abort_to_prompt_code[] = { + SCM_PACK_OP_24 (assert_nargs_ge, 2), + SCM_PACK_OP_24 (abort, 0), /* tag in r1, vals from r2 */ + /* FIXME: Partial continuation should capture caller regs. */ + SCM_PACK_OP_24 (return_values, 0) /* vals from r0 */ + }; + + const uint32_t call_with_values_code[] = { + SCM_PACK_OP_24 (assert_nargs_ee, 3), + SCM_PACK_OP_24 (alloc_frame, 8), + SCM_PACK_OP_12_12 (mov, 0, 6), + SCM_PACK_OP_24 (call, 7), SCM_PACK_OP_ARG_8_24 (0, 1), + SCM_PACK_OP_24 (long_fmov, 0), SCM_PACK_OP_ARG_8_24 (0, 2), + SCM_PACK_OP_12_12 (shuffle_down, 7, 1), + SCM_PACK_OP_24 (tail_call, 0) + }; + + const uint32_t call_with_current_continuation_code[] = { + SCM_PACK_OP_24 (assert_nargs_ee, 2), + SCM_PACK_OP_12_12 (mov, 1, 0), + SCM_PACK_OP_24 (capture_continuation, 0), + SCM_PACK_OP_24 (tail_call, 0) + }; + + /* This one isn't exactly a builtin but we still handle it here. */ + const uint32_t handle_interrupt_code[] = { + SCM_PACK_OP_24 (alloc_frame, 4), + SCM_PACK_OP_12_12 (mov, 0, 3), + SCM_PACK_OP_24 (call, 3), SCM_PACK_OP_ARG_8_24 (0, 1), + SCM_PACK_OP_24 (return_from_interrupt, 0) + }; + +#define DEFINE_BUILTIN(builtin, BUILTIN, req, opt, rest) \ + { \ + size_t sz = sizeof (builtin##_code); \ + vm_builtin_##builtin##_code = instrumented_code (builtin##_code, sz); \ + vm_builtin_##builtin = scm_i_make_program (vm_builtin_##builtin##_code); \ + } + FOR_EACH_VM_BUILTIN (DEFINE_BUILTIN); +#undef INDEX_TO_NAME + + scm_vm_intrinsics.handle_interrupt_code = + instrumented_code (handle_interrupt_code, sizeof (handle_interrupt_code)); +} + SCM scm_i_call_with_current_continuation (SCM proc) { @@ -1701,11 +1727,7 @@ scm_init_vm_builtin_properties (void) #define INIT_BUILTIN(builtin, BUILTIN, req, opt, rest) \ scm_set_procedure_property_x (vm_builtin_##builtin, scm_sym_name, \ - scm_sym_##builtin); \ - scm_set_procedure_minimum_arity_x (vm_builtin_##builtin, \ - SCM_I_MAKINUM (req), \ - SCM_I_MAKINUM (opt), \ - scm_from_bool (rest)); + scm_sym_##builtin); FOR_EACH_VM_BUILTIN (INIT_BUILTIN); #undef INIT_BUILTIN } @@ -1748,10 +1770,7 @@ scm_bootstrap_vm (void) (SCM_CELL_WORD_0 (vm_boot_continuation) | SCM_F_PROGRAM_IS_BOOT)); -#define DEFINE_BUILTIN(builtin, BUILTIN, req, opt, rest) \ - vm_builtin_##builtin = scm_i_make_program (vm_builtin_##builtin##_code); - FOR_EACH_VM_BUILTIN (DEFINE_BUILTIN); -#undef DEFINE_BUILTIN + define_vm_builtins (); } void |