summaryrefslogtreecommitdiff
path: root/libguile/vm.c
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2018-08-17 08:15:04 +0200
committerAndy Wingo <wingo@pobox.com>2018-08-17 08:50:33 +0200
commit3827769aff190a5e155b29d37fe157dd6115ad04 (patch)
treecca82537cba9073fce356cd75575be82e98e466c /libguile/vm.c
parente6304fb2425475ddf441439ee3c510060f9464d4 (diff)
downloadguile-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.c135
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