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

342 commits

Author SHA1 Message Date
Andy Wingo
6efc0b8159 call-with-values builtin doesn't leave garbage on the stack
Fixes https://debbugs.gnu.org/63279.  The issue was that if the producer
thunk caused a backtrace, pretty-printing the call-with-values frame
would segfault because there was an unininitialized slot on the stack.
For functions produced by the compiler this wouldn't be a problem
because there are stack maps, but primitives require that all slots on a
pending stack frame be packed (no uninitialized values) and tagged (all
SCM values, no unboxed values).

* test-suite/tests/error-handling.test: New test.
* test-suite/Makefile.am: Add new file.
* libguile/vm.c (define_vm_builtins): Fix call-with-values to have a
more compact stack.
2023-05-07 09:50:14 +02:00
Ludovic Courtès
e47a153317 Work around unwanted stack retention when using prompts.
Fixes <https://bugs.gnu.org/59021>.

Previously, the stack allocated in 'capture_stack' and stored in
'p->stack_bottom' could be retained, leading to heap growth.

* libguile/vm.c (capture_stack): Make a single 'scm_gc_malloc' call
instead of two.
2022-11-20 18:07:24 +01:00
Ludovic Courtès
89edd1bc2d Fix race condition between 'abort-to-prompt' and stack marking.
Fixes <https://bugs.gnu.org/28211>.

* libguile/vm.c (scm_i_vm_emergency_abort, abort_to_prompt): Move
'vp->fp' assignment above 'sp[nargs]' assignments.
2020-03-17 22:57:41 +01:00
Andy Wingo
cc30168878 Fix bug restoring a JIT continuation from the interpreter
* libguile/vm.c (push_interrupt_frame, compose_continuation): In places
  where we push on synthetic frames before possibly going back to mcode,
  make sure that the return mcode will trampoline back to the
  interpreter.  Fixes compose-continuation from the interpreter to
  partial continuations with mcode.
2020-02-19 16:53:44 +01:00
Andy Wingo
e3e3e691f8 Fix abort_to_prompt bug if dynwind leave thunk expands the stack
* libguile/vm.c (scm_i_vm_emergency_abort, abort_to_prompt): Unwinding
  the dynwind stack can run dynwind leave thunks, which may expand the
  stack, which may invalidate previously calculated SP / FP values.
  (Re)calculate SP/FP after unwinding, to avoid writing to unmapped
  memory.  Fixes compile errors seen on Ubuntu and some other ports.
2020-01-02 13:29:39 +01:00
Andy Wingo
4a6a7e15d6 Remove vm->sp_min_since_gc
* libguile/jit.c (emit_alloc_frame_for_sp):
* libguile/vm-engine.c (ALLOC_FRAME, RESET_FRAME):
* libguile/vm.c (vm_increase_sp, scm_i_vm_prepare_stack):
  (return_unused_stack_to_os, vm_expand_stack, alloc_frame):
  (scm_call_with_stack_overflow_handler):
* libguile/vm.h (struct scm_vm): Remove sp_min_since_gc handling.  It
  was a very minor optimization when it was centralized in vm.c, but now
  with JIT it's causing too much duplicate code generation.
2019-12-09 22:03:34 +01:00
Andy Wingo
9e3a5c9a10 Fix the jitless fix
* libguile/vm.c (capture_continuation): Use #if, not #ifdef, to test the
  condition.
2019-08-19 16:43:43 +02:00
Andy Wingo
9d78665539 Disable some JIT compilation code when JIT configured out
* libguile/vm.c (vm_recompute_disable_mcode, capture_continuation):
  Disable logic if JIT not configured.
2019-08-19 16:31:29 +02:00
Andy Wingo
af72d01de8 Speed up returns in JIT
This patch is a bit unfortunate, in the sense that it exposes some of
the JIT guts to the rest of the VM.  Code needs to treat "machine return
addresses" as valid if non-NULL (as before) and also not equal to a
tier-down trampoline.  This is because tier-down at a return needs the
old frame pointer to load the "virtual return address", and the way this
patch works is that it passes the vra in a well-known register.  It's a
custom calling convention for a certain kind of return.

* libguile/jit.h (scm_jit_return_to_interpreter_trampoline): New
  internal global.
* libguile/jit.c: (scm_jit_clear_mcode_return_addresses): Move here,
  from vm.c.  Instead of zeroing return addresses, set them to the
  return-to-interpreter trampoline.
* libguile/vm-engine.c (return-values): Don't enter mcode if the mra is
  scm_jit_return_to_interpreter_trampoline.
* libguile/vm.c (capture_continuation): Treat the tier-down trampoline
  as NULL.
2019-06-18 21:45:29 +02:00
Ludovic Courtès
abeeec74b2 Do not warn the user when 'madvise' returns ENOSYS.
* libguile/vm.c (return_unused_stack_to_os): Avoid 'perror' calls when
'madvise' returns ENOSYS.
2019-05-23 17:16:02 +02:00
Andy Wingo
4e5329676b Fix backtraces with call-with-values during bootstrap
* libguile/programs.c (scm_i_program_name): Use scm_i_primitive_name for
  primitives.  No functional change though.
* libguile/vm.c (DEFINE_BUILTIN): Mark builtins as primitives.
2019-04-26 11:15:49 +02:00
Andy Wingo
6cd9b3114f Fix use of uninstalled header by installed headers
* libguile/Makefile.am (libpath.h): Remove definition of
  SCM_EFFECTIVE_VERSION, which is defined in version.h.
* libguile/extensions.h: Remove libpath.h inclusion, as it's not
  installed.
* libguile/atomic.c:
* libguile/bytevectors.c:
* libguile/control.c:
* libguile/fdes-finalizers.c:
* libguile/foreign-object.c:
* libguile/foreign.c:
* libguile/fports.c:
* libguile/frames.c:
* libguile/goops.c:
* libguile/i18n.c:
* libguile/instructions.c:
* libguile/intrinsics.c:
* libguile/ioext.c:
* libguile/load.c:
* libguile/loader.c:
* libguile/poll.c:
* libguile/ports.c:
* libguile/posix.c:
* libguile/programs.c:
* libguile/r6rs-ports.c:
* libguile/srfi-1.c:
* libguile/srfi-60.c:
* libguile/threads.c:
* libguile/unicode.c:
* libguile/vm.c:
* libguile/weak-vector.c: Include version.h for the
  SCM_EFFECTIVE_VERSION definition.
2018-10-07 15:15:02 +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
883bdc7453 Fix emergency aborts to not expand the stack
* libguile/vm.c (scm_i_vm_emergency_abort): New helper: an abort that
  doesn't allocate, not even stack.
* libguile/throw.c (abort_to_prompt): Use scm_i_vm_emergency_abort.
* libguile/vm.h: Declare helper.
2018-09-15 10:41:35 +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
babd4118c2 Fix nonlocal abort to compiled continuation
* libguile/vm.c (scm_call_n): Fix failure to reset vm.registers after a
  nonlocal abort to a compiled continuation.
2018-09-03 18:31:41 +02:00
Andy Wingo
110310b3e7 Expose scm_vm_builtin_ref internally
* libguile/vm-builtins.h:
* libguile/vm.c (scm_vm_builtin_ref): Expose internally.
2018-08-19 17:38:59 +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
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
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
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
Ludovic Courtès
ffc1b9f3ac vm: Fix another typo.
Fix typo introduced in efc33cd149.

* libguile/vm.c (return_unused_stack_to_os): Remove extra 'while'.
2018-08-07 12:13:35 +02:00
Ludovic Courtès
4611ba2fcf vm: Fix typo when checking for 'madvise' error code.
* libguile/vm.c (return_unused_stack_to_os): Check for EAGAIN, not -EAGAIN.
2018-08-07 12:09:19 +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
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
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
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
Andy Wingo
18431e6e63 Refactor handling of active VM registers
* libguile/threads.h (scm_thread): Remove unused jmp_buf regs member.
* libguile/vm.h (struct scm_vm): Rename resumable_prompt_cookie to just
  "registers"; we know it's a jmp_buf pointer.
* libguile/vm.c (scm_call_n):
* libguile/throw.c (catch):
* libguile/eval.c (eval):
* libguile/control.c (scm_suspendable_continuation_p): Adapt to cookie
  renaming.
2018-06-27 18:21:04 +02:00
Andy Wingo
7883290d88 Inline handling of non-program apply
* libguile/vm.c (vm_apply_non_program_code): Remove, now unneeded.
* libguile/vm-engine.c (vm_engine, call, tail-call, tail-call/shuffle)
  (tail-apply, call/cc): Inline handling of non-programs, as will be the
  case with JIT code.
2018-06-27 13:54:45 +02:00
Andy Wingo
1735cc1fec Apply-non-program is an intrinsic
* libguile/intrinsics.h (SCM_FOR_ALL_VM_INTRINSICS): Add
  apply-non-program intrinsic.
* libguile/vm-engine.c (apply-non-program): Replace impl with call to
  intrinsic.
* libguile/vm.c (vm_error_wrong_type_apply): Inline into
  apply_non_program intrinsic.
  (apply_non_program): New intrinsic.
  (scm_bootstrap_vm): Wire it up.
2018-06-27 13:38:30 +02:00
Andy Wingo
6eb4735149 Add intrinsics for error conditions (wrong num args etc)
* libguile/intrinsics.c (error_wrong_num_args, error_no_values)
  (error_not_enough_values, error_wrong_number_of_values): New
  intrinsics.
* libguile/intrinsics.h: Add new intrinsics.
* libguile/vm-engine.c: Signal errors using the new intrinsics.
* libguile/vm.c (vm_error): Remove, now that it's unused.
  (vm_error_bad_instruction): Abort instead of throwing an exception.
  If we get a bad instruction, nothing good will ever happen!
  (compose_continuation): Use wrong-type-arg for unrewindable
  continuations.
  (scm_bootstrap_vm): No need to make "vm-run" or "vm-error" symbols.
2018-06-27 09:47:31 +02:00
Andy Wingo
0ce9a1f870 VM throw uses intrinsics
* libguile/intrinsics.h (SCM_FOR_ALL_VM_INTRINSICS): Add intrinsics for
  throw, throw/value, and throw/value+data.
* libguile/intrinsics.c (throw_, throw_with_value):
  (throw_with_value_and_data): And here they are.
* libguile/vm-engine.c (throw, throw/value, throw/value+data): Use
  intrinsics.
* libguile/vm.c: Remove vm_throw et al.
2018-06-26 20:45:26 +02:00