1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-04-30 20:00:19 +02:00
Commit graph

369 commits

Author SHA1 Message Date
Andy Wingo
8bcba78eda Fix unused local warning in vm-engine.c
* libguile/vm-engine.c (return-values): Remove needless frame_size=3
  local var.
2018-10-07 16:33:04 +02:00
Andy Wingo
4e8d27f0d1 Finish updating vm.texi
* doc/ref/compiler.texi (Bytecode): Update macro-assembler instructions,
  and move most of them to the instruction set reference.
* doc/ref/vm.texi (A Virtual Machine for Guile, VM Programs): Minor
  fixes.
(Instruction Set): Update for Guile 3 instruction set.
* libguile/vm-engine.c (vm_engine): Update a few instruction
  docstrings.
2018-09-30 16:08:40 +02:00
Andy Wingo
a74b4a45fa Update comments in vm-engine.c
* libguile/jit.c (compile_s64_numerically_equal): Remove as this
instruction was removed in previous refactoring.
(compile_atomic_scm_set_immediate), compile_atomic_scm_ref_immediate):
Adapt to change in C name of these instructions.
* libguile/vm-engine.c: Add comments for all instructions.
2018-09-22 18:42:27 +02:00
Andy Wingo
1e7c541b2f Fix case where running abort hook could trash registers
* libguile/vm-engine.c (abort): If the abort doesn't need to longjmp and
  the abort hook was enabled, cache registers first to avoid restoring
  a bad IP to the VM.
2018-09-22 17:33:58 +02:00
Andy Wingo
4060728e0a Renumber instructions and bump objcode version
* libguile/loader.h (SCM_OBJCODE_MINIMUM_MINOR_VERSION):
  (SCM_OBJCODE_MINOR_VERSION): Bump version.
* module/system/vm/assembler.scm (*bytecode-minor-version*): Bump.
* libguile/vm-engine.c: Rearrange opcodes to be contiguous and in a
  somewhat sensible order.
2018-09-20 11:22:15 +02:00
Andy Wingo
ce9169804e Fix --disable-jit compilation
* libguile/jit.c: Wrap the whole thing in ENABLE_JIT.
* libguile/threads.c (on_thread_exit):
* libguile/vm.c (scm_call_n):
* libguile/init.c (scm_i_init_guile):
* libguile/vm-engine.c (VM_NAME): Wrap calls into jit.c with ENABLE_JIT.
* configure.ac: Move up AC_CANONICAL_TARGET, as autoconf was complaining
  about it coming after AC_ARG_PROGRAM.
* acinclude.m4 (GUILE_ENABLE_JIT): Fix to honor --enable-jit arg.
2018-09-17 09:28:41 +02:00
Andy Wingo
09b8f8ec06 Deoptimize to VM when hooks are enabled
* libguile/vm.c (vm_clear_mcode_return_addresses): New helper.
(vm_recompute_disable_mcode): Force a thread to deoptimize if hooks
become enabled.
(scm_call_n): Don't enter mcode if it's disabled.  Also check the right
flag for when to run the abort hook (the abort_hook_enabled flag).
* libguile/vm-engine.c (instrument-entry, instrument-loop)
(return-values, abort, compose-continuation): Don't enter mcode if mcode
is disabled for this thread.
2018-09-14 15:16:33 +02:00
Andy Wingo
12b125f2ad Hook refactors
* libguile/vm.h (SCM_VM_NUM_HOOKS): Remove hook enumeration.
(struct scm_vm): Re-arrange members to be more dense and to use common
cache lines for commonly-used members.  Declare hooks and their enabled
flags by name.
* libguile/vm-engine.c (RUN_HOOK): Refer to hooks by name.
* libguile/vm.c (FOR_EACH_HOOK): New helper.
(vm_hook_compute_enabled, vm_recompute_disable_mcode): New routines to
recompute when hooks are enabled, and whether to disable mcode because
hooks are active.
(set_vm_trace_level): New helper.
(invoke_hook): Take hook to invoke by value.
(DEFINE_INVOKE_HOOK): Refactor to use named hooks.
(scm_i_vm_prepare_stack): Init named hooks.
(VM_ADD_HOOK, VM_REMOVE_HOOK): Refactor to use named hooks, and also
recompute global disable_mcode flag.
(scm_set_vm_trace_level_x, scm_c_set_vm_engine_x): Use internal helper.
2018-09-14 13:02:44 +02:00
Andy Wingo
0ccd2d0d9e Remove hook intrinsics: hooks are just for the VM
* libguile/intrinsics.h (SCM_FOR_ALL_VM_INTRINSICS): Remove VM hook
  intrinsics, now that we're going to rely on the interpreter for
  stepping and breakpoints.
* libguile/jit.c (struct scm_jit_state): Remove "hooks_enabled" member,
  now that we won't JIT.  Remove all code related to calling hooks.
* libguile/vm-engine.c (RUN_HOOK): Call hooks directly instead of
  through intrinsics.  Use precise per-hook enable flags.
* libguile/vm.c (DEFINE_INVOKE_HOOK): New helper.  Use to define the
  hook invokers.
2018-09-14 09:34:31 +02:00
Andy Wingo
bf31fe4cf6 VM manages hook sets itself
* libguile/vm.h (SCM_VM_ABORT_HOOK): Rename from
  SCM_VM_ABORT_CONTINUATION_HOOK.
* libguile/vm-engine.c (ABORT_HOOK):
* libguile/vm.c (invoke_abort_hook): Adapt to SCM_VM_ABORT_HOOK name
change.
(reset_vm_hook_enabled): New helper.
(VM_ADD_HOOK, VM_REMOVE_HOOK): New helper macros, replacing
VM_DEFINE_HOOK.
(scm_vm_add_abort_hook_x, scm_vm_remove_abort_hook_x)
(scm_vm_add_apply_hook_x, scm_vm_remove_apply_hook_x)
(scm_vm_add_return_hook_x, scm_vm_remove_return_hook_x)
(scm_vm_add_next_hook_x, scm_vm_remove_next_hook_x): New functions,
replacing direct access to the hooks.  Allows us to know in a more
fine-grained way when to enable hooks.
(scm_set_vm_trace_level_x): Use reset_vm_hook_enabled to update the
individual hook_enabled flags.
* module/statprof.scm:
* module/system/vm/coverage.scm:
* module/system/vm/traps.scm:
* module/system/vm/vm.scm: Adapt VM hook users to the new API.
2018-09-14 08:52:24 +02:00
Andy Wingo
076c3ad8d7 JIT counter tweaks
* libguile/vm-engine.c (instrument-entry, instrument-loop): Make the
  counter check >=, so that we can set the threshold to 0 and still get
  compilation.
* libguile/jit.h (enum scm_jit_counter_value): Make the increments
  event.
2018-09-02 11:00:24 +02:00
Andy Wingo
cc997293e2 JIT threshold controlled by environment variable
* libguile/jit.c (scm_jit_counter_threshold): Make a static variable
  instead of a compile-time constant.
  (scm_init_jit): Init scm_jit_counter_threshold from
  GUILE_JIT_COUNTER_THRESHOLD environment variable.  Default is -1
  indicating "never JIT".
* libguile/vm-engine.c (instrument-entry, instrument-loop): Adapt to new
  variable.
2018-08-31 11:28:38 +02:00
Andy Wingo
24d09b16b6 Maybe enter JIT when returning from interpreted functions
* libguile/jit.c (scm_jit_compute_mcode): Minor optimization.
* libguile/vm-engine.c (return-values): Maybe return to JIT code.
2018-08-29 17:54:19 +02:00
Andy Wingo
916c570557 Tweak to instrument-entry
* libguile/vm-engine.c (instrument-entry): Eagerly check if data->mcode
  is already set, and in that case just jump directly without checking
  the counter.
2018-08-20 12:45:07 +02:00
Andy Wingo
3827769aff 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.
2018-08-17 08:50:33 +02:00
Andy Wingo
e6304fb242 Define intrinsics for atomic ops
* libguile/intrinsics.h:
* libguile/intrinsics.c (atomic_ref_scm, atomic_set_scm):
  (atomic_swap_scm, atomic_compare_and_swap_scm): New intrinsics, given
  that lightning doesn't know atomics.
  (scm_bootstrap_intrinsics): Init new intrinsics.
* libguile/vm-engine.c (atomic-scm-ref/immediate)
  (atomic-scm-set!/immediate, atomic-scm-swap!/immediate)
  (atomic-scm-compare-and-swap!/immediate): Use intrinsics, to be like
  the JIT.
2018-08-13 22:00:19 +02:00
Andy Wingo
0188bd3816 64-bit intrinsic args and return values passed indirectly on 32-bit
* libguile/intrinsics.h (INDIRECT_INT64_INTRINSICS): New definition.  If
  true, int64 args and return values are passed by reference.  Here to
  make JIT easier.
* libguile/intrinsics.c (indirect_scm_to_int64, indirect_scm_to_uint64):
  (indirect_scm_to_uint64_truncate, indirect_scm_from_int64):
  (indirect_scm_from_uint64, indirect_lsh, indirect_rsh): New indirect
  variants.
  (scm_bootstrap_intrinsics): Use indirect variants as appropriate.
* libguile/vm-engine.c: Update to call indirect intrinsics if
  appropriate.
2018-08-13 22:00:15 +02:00
Andy Wingo
d4abe8bbed Avoid needless 64-bit args on 32-bit machines for some intrinsics
* libguile/intrinsics.h:
* libguile/intrinsics.c (string_set_x): Change to take size_t and u32 as
  args.
  (allocate_words): Change to take size_t as arg.
* libguile/vm.c (expand_apply_argument): Rename from rest_arg_length,
  and also handle the stack manipulation.
* libguile/vm-engine.c (expand-apply-argument): Update for intrinsic
  change.
  (call-scm-sz-u32): Rename from call-scm-u64-u64, as it matches its
  uses and will compile better on 32-bit systems.
* module/system/vm/assembler.scm (define-scm-sz-u32-intrinsic):
  (string-set!): Update for new instrinsic call inst.
* libguile/jit.c (compile_call_scm_sz_u32): Adapt.
2018-08-13 14:30:01 +02:00
Andy Wingo
11940f4c72 Update error-wrong-num-args intrinsic prototype
* libguile/intrinsics.h (SCM_FOR_ALL_VM_INTRINSICS):
* libguile/intrinsics.c (error_wrong_num_args): Take the thread as an
  arg, instead of the ostensible callee.
* libguile/vm-engine.c: Update callers of wrong-num-args intrinsic to
  pass a thread instead.
2018-08-13 10:59:09 +02:00
Andy Wingo
5df43b60a9 Adapt JIT calling convention; continuations take mra from stack
* libguile/intrinsics.h (SCM_FOR_ALL_VM_INTRINSICS): Update prototype of
  capture-continuation.
* libguile/jit.h:
* libguile/jit.c (scm_jit_enter_mcode): Return void, not the vra.
  Instead, we expect the code to set vp->ip for the vra.
* libguile/vm-engine.c (instrument-entry, instrument-loop)
  (return-values, abort): Adapt scm_jit_enter_mcode calling convention.
  (capture-continuation): No need to pass an mra; the intrinsic will
  read it from the stack.
* libguile/vm.c (capture_continuation): Remove mra arg, as we take mra
  from the continuation.
  (scm_call_n): Adapt to scm_jit_enter_mcode change.
2018-08-13 10:32:13 +02:00
Andy Wingo
a20feea43e Continuations capture machine code address
* libguile/continuations.c (scm_i_continuation_to_frame): Adapt to vra
  field renaming.
  (scm_i_reinstate_continuation, grow_stack, copy_stack_and_call)
  (scm_dynthrow): Take mra of continuation.  Set on the vp before the
  longjmp.
* libguile/continuations.h: Update scm_i_reinstate_continuation
  prototype.
* libguile/dynstack.h:
* libguile/control.c (scm_suspendable_continuation_p):
* libguile/dynstack.c (PROMPT_WORDS, PROMPT_VRA, PROMPT_MRA):
  (PROMPT_JMPBUF, scm_dynstack_push_prompt, scm_dynstack_find_prompt)
  (scm_dynstack_wind_prompt): Store both virtual and machine return
  addresses on the dynstack, for prompts.
* libguile/eval.c (eval): Pass NULL for mra.
* libguile/intrinsics.c (push_prompt): Add mra arg, and pass it to the
  dynstack.
* libguile/intrinsics.h: Update prototypes so that continuation-related
  intrinsics can save and restore the MRA.
* libguile/jit.h:
* libguile/jit.c: Return VRA when JIT code needs to tier down.
* libguile/stacks.c (find_prompt, scm_make_stack)
* libguile/throw.c (catch): Adapt find-prompt calls.
* libguile/vm-engine.c (instrument-entry, instrument-loop): Add logic to
  continue with vcode after the mcode finishes.
  (compose-continuation, capture-continuation, abort, prompt): Add logic
  to pass NULL as captured MRA, but continue with mcode from new
  continuations, if appropriate.
* libguile/vm.c (scm_i_vm_cont_to_frame, capture_stack)
  (scm_i_capture_current_stack, reinstate_continuation_x)
  (capture_continuation, compose_continuation_inner, compose_continuation)
  (capture_delimited_continuation, abort_to_prompt): Adapt to plumb
  around machine code continuations.
  (scm_call_n): Check "mra_after_abort" field for machine code
  continuation, if any.
* libguile/vm.h (struct scm_vm): Add "mra_after_abort" field.
  (struct scm_vm_cont): Rename "ra" field to "vra" and add "mra" field.
2018-08-12 15:57:53 +02:00
Andy Wingo
939b1ae23f Rework foreign-call trampoline
* libguile/foreign.c (scm_i_foreign_call): Rename back from
  foreign_call.  Need a new trampoline that's easier to call from JIT,
  until we actually rewrite the FFI in terms of the JIT.
  (scm_register_foreign): Remove foreign_call intrinsic init.
* libguile/intrinsics.h (SCM_FOR_ALL_VM_INTRINSICS): Foreign-call
  intrinsic sets return directly on stack.
* libguile/vm-engine.c (foreign-call): Adapt to new intrinsic behavior.
* libguile/vm.c (foreign_call, scm_bootstrap_vm): Add new intrinsic
  wrapper.
2018-08-11 14:25:07 +02:00
Andy Wingo
6027027724 Invoke VM hooks through intrinsics
* libguile/intrinsics.h (SCM_FOR_ALL_VM_INTRINSICS): Make intrinsics for
  the VM hooks.
* libguile/vm-engine.c (RUN_HOOK): Run hooks through the intrinsics
  table.
* libguile/vm.c (invoke_apply_hook, invoke_return_hook):
  (invoke_next_hook, invoke_abort_hook): Rename, remove NOINLINE
  attribute (as we call them through the intrinsics table).
  (scm_bootstrap_vm): Init new intrinsics.
2018-08-11 11:37:03 +02:00
Andy Wingo
ef4c1a5f55 Add unpack-values-object intrinsic
* libguile/intrinsics.h (SCM_FOR_ALL_VM_INTRINSICS): Add
  unpack-values-object.
* libguile/vm-engine.c (subr-call): If the object is a values object,
  call out to unpack-values-object.  This is to avoid reifying
  allocate-frame code in each jitted subr.
* libguile/vm.c (unpack_values_object, scm_bootstrap_vm): Define new
  intrinsic.
2018-08-11 11:36:58 +02:00
Andy Wingo
c3ff72cb81 Change call/cc inst to capture-continuation
* libguile/jit.c (compile_capture_continuation): Rename from call_cc now
  that the call is elsewhere.
* libguile/vm-engine.c (call, tail-call): Remove needless SYNC_IP before
  get-callee-vcode; the intrinsic can sync the ip if needed from the
  frame.
  (capture-continuation): Rename from call/cc, and leave the call itself
  to tail-call.
* libguile/vm.c (vm_builtin_call_with_current_continuation_code): Update
  to put the continuation in a local and then tail call.
  (get_callee_vcode): Sync vp->ip if we error.
2018-08-08 16:32:18 +02:00
Andy Wingo
926b72f5ac Rework program->ip mapping in VM to always call intrinsic
* libguile/intrinsics.h:
* libguile/vm.c (get_callee_vcode): Rename from apply_non_program, and
  instead return the IP for the callee of a frame.
  (scm_call_n, scm_bootstrap_vm): Adapt to get_callee_vcode change.
* libguile/vm-engine.c (call, tail-call, call/cc): Use
  get_callee_vcode unconditionally.  JIT will do this to avoid so much
  code generation for calls.
2018-08-08 15:22:28 +02:00
Andy Wingo
b7dbc7251f Minor optimization in RESET_FRAME
* libguile/vm-engine.c (RESET_FRAME): Remove update of sp_min_since_gc.
2018-08-08 14:48:32 +02:00
Andy Wingo
41100f7786 Merge branch 'master' into lightning
This includes a manual cherry-pick of relevant stable-2.2 commits up to
4c91de3e45.
2018-08-07 12:43:25 +02:00
Ludovic Courtès
8840ee5a3c vm: Fix stack-marking bug in multi-threaded programs.
Fixes <https://bugs.gnu.org/28211>.

* libguile/vm-engine.c (call, call_label, handle_interrupts): Add
'new_fp' variable; set the dynamic link and return address of the frame
at NEW_FP before setting 'vp->fp'.  This fixes a bug whereby, in a
multi-threaded context, the stack-marking code could run after vp->fp
has been set but before its dynamic link has been set, leading the
stack-walking code in 'scm_i_vm_mark_stack' to exit early on.
2018-08-07 12:31:11 +02:00
Andy Wingo
0a01963d07 VM hooks take no values
* libguile/vm-engine.c (RUN_HOOK0, RUN_HOOK1): Remove.
  (RUN_HOOK): Take hook name.
  (APPLY_HOOK, RETURN_HOOK, NEXT_HOOK, ABORT_CONTINUATION_HOOK): Use
  RUN_HOOK.
* libguile/vm.c (vm_dispatch_hook): Remove value count arg; hooks no
  longer receive values (e.g. the return hook now uses
  frame-return-values).
  (vm_dispatch_abort_hook): Remove value count, which was bogus because
  the active frame was the continuation which might contain other
  locals, potentially unboxed, not the implicit return-values frame.  In
  the future we could push on an implicit return-values frame instead.
* module/system/vm/traps.scm (trap-in-procedure, trap-frame-finish):
  (trap-in-dynamic-extent, trap-calls-to-procedure): Adapt abort hooks
  to not take values.  They weren't being used anyway!
2018-08-07 11:05:56 +02:00
Andy Wingo
f4c50447dd Remove push continuation hook; return hook runs before FP pop
* libguile/frames.c (scm_frame_return_values): New function, for use
  when a frame is at "return-values".
  (scm_init_frames_builtins): Register frame-return-values.
* libguile/vm-engine.c (RETURN_HOOK): Rename from POP_CONTINUATION_HOOK.
  (call, call-label): Remove PUSH_CONTINUATION_HOOK; it's unneeded, as
  you can always check the FP from an apply hook.
  (return-values): Run return hook before popping frame.
* libguile/vm.c (vm_dispatch_return_hook): Rename from
  vm_dispatch_pop_continuation_hook.  Remove push continuation hook.
  (scm_vm_return_hook):
* libguile/vm.h (SCM_VM_PUSH_CONTINUATION_HOOK): Remove.
  (SCM_VM_RETURN_HOOK): Rename from SCM_VM_POP_CONTINUATION_HOOK.
* module/system/vm/frame.scm (frame-return-values): Export.
* module/system/vm/trace.scm (print-return, trace-calls-to-procedure)
  (trace-calls-in-procedure): Adapt to not receiving values as
  arguments.
* module/system/vm/traps.scm (trap-in-procedure, trap-frame-finish):
  Adapt to return hook coming from returning frame.
  (program-sources-by-line): Update to use match instead of pmatch.
* module/system/vm/traps.scm (trap-in-dynamic-extent)
  (trap-calls-to-procedure): Adapt to return hook not receiving values.
* module/system/vm/vm.scm: Remove push continuation hook and rename
  return hook.
2018-08-06 17:00:45 +02:00
Andy Wingo
dedf73d370 Consolidate apply hook to instrument-entry instruction
* libguile/vm.c (scm_call_n):
* libguile/vm-engine.c: Move apply hook to "instrument-entry"
  instruction.
2018-08-06 15:07:26 +02:00
Andy Wingo
b8a9a666f1 Rewrite subr implementation
* libguile/gsubr.c: Reimplement to store subr names and procedures in a
  side table, and to allocate fresh vcode for each subr.  This allows
  JIT of subrs, moves to a uniform all-code-starts-with-instrument-entry
  regime, and also allows statprof to distinguish between subrs based on
  IP.
* libguile/gsubr.h (SCM_SUBRF, SCM_SUBR_NAME): Call out to functions,
  now that these are in a side table.
  (scm_subr_function, scm_subr_name): New exports.
  (scm_i_primitive_name): New internal function, for looking up a
  primitive name based on IP.
  (scm_apply_subr): Take the subr index.
* libguile/vm-engine.c (subr-call):
* libguile/jit.c (compile_subr_call): Adapt to take index as arg.
* module/statprof.scm (sample-stack-procs, count-call):
  (stack-samples->procedure-data): Update to always record IP in stack
  samples and call counts.
* module/system/vm/frame.scm (frame-procedure-name): Simplify.
  (frame-instruction-pointer-or-primitive-procedure-name): Removed.
* libguile/programs.h:
* libguile/programs.c (scm_primitive_code_name): New function.
* module/system/vm/program.scm (primitive-code-name): New export.
2018-07-29 15:47:07 +02:00
Andy Wingo
a6b5049aa8 Emit instrument-loop in loops.
* am/bootstrap.am (SOURCES):
* module/Makefile.am (SOURCES): Handle renamve of handle-interrupts.scm
  to loop-instrumentation.scm.
* libguile/jit.h (SCM_JIT_COUNTER_ENTRY_INCREMENT): Rename from
  SCM_JIT_COUNTER_CALL_INCREMENT.
* libguile/vm-engine.c (instrument-entry): Rename from instrument-call.
* module/language/cps/compile-bytecode.scm (compile-function): Add
  handle-interrupts code before calls and returns.  Compile the
  "instrument-loop" primcall to an "instrument-loop" instruction and a
  "handle-interrupts" instruction.
  (lower-cps): Adapt to add-loop-instrumentation name change.
* module/language/cps/loop-instrumentation.scm: Rename from
  handle-interrupts.scm and just add "instrument-loop" primcalls in
  loops.  The compiler will add handle-interrupts primcalls as
  appropriate.
* module/system/vm/assembler.scm (<jit-data>): New data type, for
  emitting embedded JIT data.
  (<meta>): Add field for current JIT data.
  (make-meta): Initialize current JIT data.
  (emit-instrument-entry*, emit-instrument-loop*): New instruction
  emitters that reference the current JIT data.
  (end-program): Now that all labels are known, arrange to serialize the
  JIT data.
  (link-data): Reserve space for JIT data, and add relocs to initialize
  the "start" / "end" fields.
2018-07-29 15:47:07 +02:00
Andy Wingo
87da1c8d20 Add instrument-call, instrument-loop VM instructions
* libguile/jit.h (struct scm_jit_function_data)
  (enum scm_jit_counter_value): New data types.
* libguile/jit.c (scm_jit_compute_mcode, scm_jit_enter_mcode): New
  function stubs.  Adapt label/offset compilers to take pointers.
* libguile/vm-engine.c (instrument-call, instrument-loop): New
  instructions.
* libguile/vm.c: Add jit.h include.
* module/system/vm/assembler.scm (emit-instrument-call)
  (emit-instrument-loop): New exports.
2018-07-29 15:47:03 +02:00
Andy Wingo
950a762dc2 Multiple-value returns now start from slot 0, not slot 1
This should reduce frame sizes.

* libguile/vm-engine.c (halt): Adapt to multiple-values change.  Also
  adapt to not having the boot closure on the stack.
  (receive, receive-values, subr-call, foreign-call): Adapt to expect
  values one slot down.
  (prompt): Capture one less word for the values return.
* libguile/vm.c (vm_dispatch_pop_continuation_hook):
  (vm_dispatch_abort_hook): Adapt for where to expect values.
  (vm_builtin_values_code): Add a call to shuffle-down before
  returning.  This is more overhead than what existed before, but the
  hope is that the savings elsewhere pay off.
  (vm_builtin_values_code): Adapt to different values location.
  (reinstate_continuation_x, compose_continuation): Adapt to place
  resume args at right position.
  (capture_delimited_continuation): Remove unused sp and ip arguments.
  (abort_to_prompt): Adapt to capture_delimited_continuation change.
  (scm_call_n): Adapt to not reserve space for the boot closure.
* module/language/cps/compile-bytecode.scm (compile-function): When
  returning values, adapt reset-frame call for return calling convention
  change.  Adapt truncating or rest returns to expect values in the
  right place.
* module/language/cps/slot-allocation.scm (compute-shuffles):
  (allocate-lazy-vars, allocate-slots): Allocate values from the "proc
  slot", not proc-slot + 1.
* module/system/vm/assembler.scm (emit-init-constants): Reset the frame
  before returning so that the return value is in the right place.
* test-suite/tests/rtl.test: Update for return convention change.
* libguile/foreign.c (get_foreign_stub_code): Update for return calling
  convention change.
2018-07-20 11:42:30 +02:00
Andy Wingo
9b70129504 Fix stale stack frame clearing for frame size change
* libguile/vm-engine.c (return-values): Clear all 3 stack slots.  Not
  sure this is necessary though!
2018-07-20 11:42:30 +02:00
Andy Wingo
c2a8224a63 Rework VM approach to shuffling unknown numbers of args
* libguile/vm-engine.c (shuffle-down, expand-apply-argument): New
  instructions.
  (tail-call, tail-call-label, return-values): Don't reset the frame.
  The compiler should reset the frame appropriately.
  (tail-call/shuffle, tail-apply): Remove unused instructions.
* libguile/vm.c (vm_builtin_apply_code): Use new shuffle-down and
  expand-apply-argument opcodes.
  (vm_builtin_call_with_values_code): Replace tail-call/shuffle with
  shuffle-down then tail-call.
* libguile/jit.c (compile_shuffle_down, compile_expand_apply_argument):
  Add compiler stubs
  (COMPILE_X8_F12_F12): New definition.
  (compile_tail_call_shuffle, compile_tail_apply): Remove unused
  compilers.
* module/language/cps/compile-bytecode.scm (compile-function): Emit
  reset-frame before tail calls and returns.
* module/system/vm/assembler.scm (system): Remove unbound "emit-return"
  export.
* module/system/vm/disassembler.scm (code-annotation)
  (instruction-has-fallthrough?, define-stack-effect-parser): Adapt for
  opcode changes.
2018-07-20 11:42:30 +02:00
Andy Wingo
043432fd57 Reserve frame word for machine return address
* libguile/frames.h: Add machine return address to diagram.
  (SCM_FRAME_MACHINE_RETURN_ADDRESS):
  (SCM_FRAME_SET_MACHINE_RETURN_ADDRESS): New macros.
  (SCM_FRAME_PREVIOUS_SP):
  (SCM_FRAME_DYNAMIC_LINK):
  (SCM_FRAME_SET_DYNAMIC_LINK): Adapt for new frame size.
* libguile/vm-engine.c (halt): Set frame size to 3.
  (call, call-label): Set mRA to 0.
* libguile/vm.c (push_interrupt_frame, reinstate_continuation_x):
  (scm_call_n): Set frame size to 3.  In push_interrupt_frame, init the
  mRA of the frame.
  (vm_builtin_call_with_values_code, vm_handle_interrupt_code): Allocate
  larger frames.
* module/language/cps/slot-allocation.scm (allocate-slots): Frame size
  is 3.
* module/system/vm/disassembler.scm (define-clobber-parser): Bump frame
  size.
2018-07-20 11:42:30 +02:00
Andy Wingo
b1705bd0f0 Prepare for frames having separate virtual and machine return addrs
* libguile/frames.c (scm_frame_return_address): Use
  SCM_FRAME_VIRTUAL_RETURN_ADDRESS.
  (scm_c_frame_previous): Likewise.
* libguile/frames.h: Update diagram for new names.
  (union scm_vm_stack_element): Rename "as_ip" to "as_vcode", and
  add "as_mcode" for machine code pointers.
  (SCM_FRAME_VIRTUAL_RETURN_ADDRESS)
  (SCM_FRAME_SET_VIRTUAL_RETURN_ADDRESS): Rename to these, from
  SCM_FRAME_RETURN_ADDRESS and SCM_FRAME_SET_RETURN_ADDRESS.
* libguile/vm-engine.c (halt, call, call-label, return-values)
  (return-from-interrupt): Adapt to renamings.  Make "halt" have frame
  size as a parameter.
* libguile/vm.c (scm_i_vm_mark_stack): Adapt to renaming.
  (push_interrupt_frame): Take mRA as additional argument.  In future we
  will set it as frame mRA.
  (capture_continuation): Adapt to renaming.
  (scm_call_n): Adapt to renaming and make frame size adjustable.
  (push_interrupt_frame, reinstate_continuation_x): Make frame size
  adjustable.
* module/language/cps/slot-allocation.scm (allocate-slots): Make frame
  size adjustable.
* libguile/intrinsics.h (scm_t_thread_mra_intrinsic): New type; use for
  push_interrupt_frame.
  (scm_t_thread_u8_scm_sp_vra_intrinsic): Rename from the same but was
  "ra" instead of "vra", and change type to uint32_t*.
* module/system/vm/disassembler.scm (define-clobber-parser):
  Parameterize clobber set for calls by frame size.
2018-07-20 11:42:30 +02:00
Andy Wingo
9fc5282ca5 Merge 'master' into 'lightning' 2018-07-20 11:41:54 +02:00
Andy Wingo
e6461cf1b2 Fix errors introduced when giving multiple-values objects a tc7
* libguile/values.c (scm_c_value_ref): Fix a case in which a request for
  the 0th value of a zero-valued object would return the object instead
  of erroring.
* libguile/vm-engine.c (halt): Fix construction of a multiple-valued
  return (off-by-one error).  Fixes a crash introduced in
  4a2d78b4d4.
2018-07-16 12:16:58 +02:00
Andy Wingo
a433620c38 Fix bad opcode in VM
* libguile/vm-engine.c (VM_NAME): Fix accidentally reused number 180.
  Both values were invalid opcodes though.
2018-07-03 13:30:32 +02:00
Andy Wingo
d6b8f6a658 Minor change to VM DSL
* libguile/instructions.c (DOP1, DOP2, DOP3, DOP4, DOP5): New parts of
  the DSL, equivalent to e.g. OP1(x) | OP_DST.  Will allow other
  definitions of OP* that use token pasting.
* libguile/vm-engine.c: Adapt to use new DOP descriptors.
2018-07-03 11:13:27 +02:00
Andy Wingo
b5dcdf2e25 Revert "Refactor hook dispatch in VM"
This reverts commit 593e2db1dd.  The goto
strategy works for hooks that run just before a "next"; it doesn't work
for ones that run at the beginning of opcodes.
2018-06-27 20:19:40 +02:00
Andy Wingo
593e2db1dd Refactor hook dispatch in VM
* libguile/vm-engine.c (GOTO_HOOK, HOOK_HANDLER): Split hooks that don't
  take args into a "goto" side and a "target" side.  The idea is to just
  reify the hook call at one place in the binary, since the VM
  continuation is fully in the registers.
  (APPLY_HOOK, PUSH_CONTINUATION_HOOK, NEXT_HOOK)
  (ABORT_CONTINUATION_HOOK): Reimplement in terms of goto hooks.
  (POP_CONTINUATION_HOOK): This one is still old-style.
  (CONTINUE): New helper definition.
  (call, call-label): Move the push-continuation hooks up a bit, so it's
  clear they don't depend on intermediate opcode state.
  (vm_engine): Reify hook handlers for apply, etc.
2018-06-27 19:56:55 +02:00
Andy Wingo
2a8d72f7e0 Microoptimizations to hook dispatch
* libguile/vm.c (vm_dispatch_hook): Add a check that we're in the debug
  engine and the trace level is positive.  Allows us to do cheaper
  checks for when to dispatch hooks.
  (scm_call_n): Just check if trace level is nonzero.
* libguile/vm-engine.c (RUN_HOOK): Likewise just check if trace level is
  nonzero.
2018-06-27 19:26:03 +02:00
Andy Wingo
19cff78bb5 Minor optimizations to debug hook dispatch
* libguile/vm.c (scm_call_n): Only call hooks if the engine supports
  it.
  (vm_dispatch_abort_hook, vm_dispatch_next_hook)
  (vm_dispatch_pop_continuation_hook, vm_dispatch_push_continuation_hook)
  (vm_dispatch_apply_hook, vm_dispatch_hook): Take a thread as arg
  instead of VM, because that will probably already be in a register in
  the VM.  Given that all values are taken relative to the SP, no
  need to pass that either.
* libguile/vm-engine.c (RUN_HOOK0, RUN_HOOK1): Update appropriately.
2018-06-27 19:16:38 +02:00
Andy Wingo
9c8c4060dd Remove "resume" arg from vm engine
* libguile/vm-engine.c (vm_engine): Remove "resume" argument; scm_call_n
  will handle the differences.
* libguile/vm.c (scm_call_n): Inline handling of what to do in normal
  and resume cases.  Remove resume argument to vm_engine.
2018-06-27 18:57:37 +02:00
Andy Wingo
64d114817a Intrinsics take registers from thread
* libguile/continuations.c (scm_i_make_continuation): Remove registers
  argument; instead get from thread.
* libguile/vm-engine.c (vm_engine): Adapt VM engine to not receive a
  registers argument, and thus to not pass it to intrinsics either.
* libguile/intrinsics.h:
* libguile/intrinsics.c (push_prompt):
* libguile/vm.c (capture_continuation, compose_continuation)
  (abort_to_prompt): Refactor these intrinsics to not take a registers
  argument; it's not necessary.
  (scm_call_n): Don't pass registers argument.
2018-06-27 18:42:21 +02:00