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

388 commits

Author SHA1 Message Date
Andy Wingo
4d834bdc12 Add logand/immediate, ulogand/immediate primcalls
* libguile/jit.c (compile_ulogand_immediate, compile_ulogand_immediate_slow)
* libguile/vm-engine.c (ulogand_immediate): New JIT and interpreter
support for ulogand/immediate.

* module/language/cps/guile-vm/lower-primcalls.scm (string-ref):
(vtable-vtable?):
(vtable-field-boxed?): Emit ulogand/immediate.
* module/language/cps/guile-vm/reify-primitives.scm (reify-primitives):
Remove logand/immediate.  Only emit ulogand/immediate if the immediate
is a u8.  Refactor mul/immediate.

* module/language/cps/specialize-numbers.scm (specialize-operations):
Produce ulogand/immediate if the result is a u64.

* module/language/cps/effects-analysis.scm:
* module/language/cps/types.scm (logand/immediate): Add effect and type
inference for logand/immediate, ulogand/immediate,

* module/language/cps/utils.scm (primcall-raw-representations):
ulogand/immediate makes a u64.

* module/language/tree-il/compile-cps.scm (convert): Generate
logand/immediate if possible.

* module/language/cps/compile-bytecode.scm (compile-function):
* module/system/vm/assembler.scm (system): Add ulogand/immediate
emitter.

* libguile/loader.h (SCM_OBJCODE_MINOR_VERSION): Bump.
2023-11-20 13:43:47 +01:00
Andy Wingo
c2cba86785 Better compilation of calls to raise-exception
Recognize `raise-exception` in the same way we recognize `throw`, though
it is a bit less optimized and the boot story is not as complicated.

* doc/ref/vm.texi (Non-Local Control Flow Instructions):
* libguile/jit.c (compile_unreachable):
(compile_unreachable_slow):
* libguile/vm-engine.c (VM_NAME):
* module/language/cps/compile-bytecode.scm (compile-function):
* module/system/vm/assembler.scm (emit-unreachable): Add new
"unreachable" instruction, inserted after a call to non-continuable
`raise-exception`.
* module/language/tree-il/compile-cps.scm (raise-exception):
* module/language/tree-il/primitives.scm
(*interesting-primitive-names*): Recognize raise-exception, and if it is
called with just one argument, prune that branch of the control-flow
graph.
2023-08-28 12:11:19 +02:00
Michael Gran
b9a40cdc18 Avoid inline assembly in VM when using Clang
Clang uses a different format for inline assembly.  Also, as noted
in the comment, this register usage is likely moot.

* libguile/vm-engine.c (JT_REG)[__GNUC__ && !__clang __]: define to empty
2023-07-17 18:30:12 -07:00
Andy Wingo
83023160b1 Simplify module variable lookup slow-path
* libguile/intrinsics.h:
* libguile/intrinsics.c (lookup_bound_public, lookup_bound_private): Two
new intrinsics.
(scm_bootstrap_intrinsics): Wire them up.
* libguile/jit.c (compile_call_scm_from_scmn_scmn):
(compile_call_scm_from_scmn_scmn_slow):
(COMPILE_X8_S24__N32__N32__C32): Add JIT support for new instruction
kind.
* libguile/vm-engine.c (call-scm<-scmn-scmn): New instruction, takes
arguments as non-immediate offsets, to avoid needless loads and register
pressure.
* module/language/cps/effects-analysis.scm: Add cases for new
primcalls.
* module/language/cps/compile-bytecode.scm (compile-function): Add new
primcalls.
* module/language/cps/reify-primitives.scm (cached-module-box): If the
variable is bound, call lookup-bound-public / lookup-bound-private as
appropriate instead of separately resolving the module, name, and doing
the bound check.
* module/language/tree-il/compile-bytecode.scm (emit-cached-module-box):
Use new instructions.
* module/system/vm/assembler.scm (define-scm<-scmn-scmn-intrinsic):
(lookup-bound-public, lookup-bound-private): Add assembler support.
2021-04-26 09:48:52 +02:00
Andy Wingo
8366634db7 Add eq-immediate? instruction
* libguile/jit.c (compile_eq_immediate, compile_eq_immediate_slow): Add
  JIT compiler.
* libguile/vm-engine.c (eq_immediate): New instruction.
* doc/ref/vm.texi (Comparison Instructions): Document.
* module/system/vm/assembler.scm (encode-X8_S8_ZI16!/shuffle): New
  shuffler.
* module/system/vm/disassembler.scm (code-annotation): Add eq-immediate?
  case.
2020-08-03 22:19:12 +02:00
Andy Wingo
172e5ccfc1 Add sign-extending make-immediate instruction
* doc/ref/vm.texi (Instruction Set, Constant Instructions): Document new
  instruction.
* libguile/instructions.c (FOR_EACH_INSTRUCTION_WORD_TYPE): New first
  word kind with zi16 operand.
* libguile/jit.c (compile_make_immediate, compile_make_immediate_slow):
  New compilers.
  (COMPILE_X8_S8_ZI16): New operand kind.
* libguile/vm-engine.c (make-immediate): New instruction.
* module/language/bytecode.scm:
* module/system/vm/assembler.scm (encode-X8_S8_ZI16<-/shuffle):
  (signed-bits, load-constant): Support the new instruction kind.
* module/system/vm/disassembler.scm (disassemblers)
  (sign-extended-immediate, code-annotation): Support for zi16
  operands.
2020-07-30 17:36:11 +02:00
Andy Wingo
bb7fa5bdc2 Add jtable instruction
* doc/ref/vm.texi (Instruction Set): Document new v32-x8-l24 instruction
  kind.
  (Branch Instructions): Document jtable.
* libguile/instructions.c (FOR_EACH_INSTRUCTION_WORD_TYPE): Add
  V32_X8_L24.
* libguile/jit.c (compile_jtable, compile_jtable_slow):
  (COMPILE_X8_S24__V32_X8_L24, analyze): Add stub JIT compiler
  implementation.
* libguile/vm-engine.c (jtable): New instruction.
* module/language/bytecode.scm (instruction-arity): Deprecate.
* module/system/vm/assembler.scm (encoder, assembler): Add V32_X8_L24
  case.
* module/system/vm/disassembler.scm (u32-ref, s32-ref): Move definitions
  to expansion-time only.
  (define-op-handlers): New definition, replacing visit-opcodes.
  (disassemblers, jump-parsers, stack-effect-parsers, clobber-parsers):
  Rework in terms of define-op-handlers.  Default case becomes #f, and
  add support for jtable.
  (disassemble-one, instruction-relative-jump-targets)
  (instruction-stack-size-after, instruction-slot-clobbers): Inline
  default case in the lookup procedure, not copied in the handler
  vector.
  (compute-labels): Add jtable case.
  (instruction-lengths-vector, instruction-length): Rework to allow
  variable-length instructions, and mark jtable as being
  variable-length.
  (instruction-has-fallthrough?): Add jtable to the no-fallthrough
  set.
2020-07-23 12:24:11 +02:00
Andy Wingo
d6b6daca37 Add intrinsics for a baseline compiler
Since there's no optimization in the baseline compiler, there's no sense
in instruction explosion.

* libguile/intrinsics.h:
* libguile/intrinsics.c ($car, $cdr, $set-car!, $set-cdr!,
  $variable-ref, $variable-set!, $vector-length, $vector-ref,
  $vector-set!, $vector-ref/immediate, $vector-set!, $allocate-struct,
  $struct-vtable, $struct-ref, $struct-set!  $struct-ref/immediate,
  $struct-set!): New intrinsics.
* libguile/jit.c (compile_call_scm_scm, compile_call_scm_scm_slow)
  (compile_call_scm_scm_scm, compile_call_scm_scm_scm_slow)
  (compile_call_scm_uimm_scm, compile_call_scm_uimm_scm_slow): New
  code generators.
* libguile/vm-engine.c (call-scm-scm, call-scm-scm-scm,
  call-scm-uimm-scm): New instructions.
* module/system/vm/assembler.scm (emit-null?, emit-false?, emit-nil?):
  Export these.  Also export emitters for the new intrinsics.
  (define-scm-scm-intrinsic, define-scm-uimm-scm-intrinsic)
  (define-scm-scm-scm-intrinsic): New helpers.
* doc/ref/vm.texi (Intrinsic Call Instructions): Add new instructions.
2020-04-29 21:47:37 +02: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
d1cf892880 Optimize fixnum or s64 -> f64 conversions
* libguile/intrinsics.c (scm_bootstrap_intrinsics):
* libguile/intrinsics.h (SCM_FOR_ALL_VM_INTRINSICS): Add "inexact"
  intrinsic.
* libguile/jit.c (compile_s64_to_f64): New compiler.
* libguile/vm-engine.c (s64->f64): New instruction.
* module/language/cps/effects-analysis.scm (heap-numbers-equal?):
* module/language/cps/reify-primitives.scm (compute-known-primitives):
* module/language/cps/slot-allocation.scm (compute-var-representations):
* module/language/cps/specialize-numbers.scm (fixnum->f64):
  (specialize-operations):
* module/language/cps/type-fold.scm (scm->f64, inexact):
* module/language/cps/types.scm (inexact, s64->f64):
* module/language/tree-il/cps-primitives.scm (exact->inexact):
* module/language/tree-il/primitives.scm (*interesting-primitive-names*):
  (*effect-free-primitives*):
* module/system/vm/assembler.scm: Recognize exact->inexact as a
  primitive, and optimize it.  Add compiler support for new "inexact"
  and "s64->f64" primcalls.
2019-09-01 20:46:04 +02:00
Andy Wingo
b02d1b08d7 Compiler allocates boxed flonums in unmarked space
This fixes a bug whereby the compiler would sometimes allocate floats in
marked space.

* libguile/gc-inline.h (scm_inline_gc_malloc_pointerless_words): New
  internal helper.
* libguile/intrinsics.h (SCM_FOR_ALL_VM_INTRINSICS):
* libguile/intrinsics.c (allocate_pointerless_words):
  (allocate_pointerless_words_with_freelist): New intrinsics.
* libguile/jit.c (compile_allocate_pointerless_words):
  (compile_allocate_pointerless_words_immediate): New compilers.
* libguile/vm-engine.c (allocate_pointerless_words)
  (allocate_pointerless_words_immediate): New opcodes.
* module/language/cps/compile-bytecode.scm (compile-function):
* module/language/cps/effects-analysis.scm (param):
* module/language/cps/reify-primitives.scm (reify-primitives):
* module/language/cps/specialize-primcalls.scm (specialize-primcalls):
* module/language/cps/types.scm (allocate-words):
(allocate-words/immediate):
* module/system/vm/assembler.scm (system): Add support for the new
  opcodes.
2019-08-26 10:19:24 +02:00
Andy Wingo
b1564df298 Unbox floor/ceiling and trigonometric functions where possible
* libguile/intrinsics.c (scm_atan1): New intrinsic, wrapping scm_atan.
  (scm_bootstrap_intrinsics): Add new intrinsics.
* libguile/intrinsics.h (scm_t_f64_from_f64_f64_intrinsic): New
  intrinsic type.
  (SCM_FOR_ALL_VM_INTRINSICS): Add intrinsics for floor, ceiling, sin,
  cos, tan, asin, acos, atan, and their unboxed counterparts.
* libguile/jit.c (sp_f64_operand): New helper.
  (compile_call_f64_from_f64, compile_call_f64_from_f64_f64): Call out
  to intrinsics.
* libguile/vm-engine.c (call-f64<-f64-f64): New opcode.
* module/language/cps/effects-analysis.scm: Add new intrinsics.
* module/language/cps/reify-primitives.scm (compute-known-primitives):
  Add new intrinsics.
* module/language/cps/slot-allocation.scm (compute-var-representations):
  Add 'f64 slot types for the new unboxed intrinsics.
* module/language/cps/specialize-numbers.scm (specialize-operations):
  Support unboxing the new intrinsics.
* module/language/cps/types.scm: Define type inferrers for the new
  intrinsics.
* module/language/tree-il/cps-primitives.scm: Define CPS translations
  for the new intrinsics.
* module/language/tree-il/primitives.scm (*interesting-primitive-names*):
  (*effect-free-primitives*, atan): Define primitive resolvers.
* module/system/vm/assembler.scm: Export assemblers for the new
  intrinsics.
  (define-f64<-f64-f64-intrinsic): New helper.
2019-08-24 11:56:18 +02:00
Andy Wingo
382cc5c246 Add support for optimized unboxed abs and sqrt
Some components of this have been wired up for a while; this commit
finishes the compiler, runtime, and JIT support.

* libguile/intrinsics.h (SCM_FOR_ALL_VM_INTRINSICS):
* libguile/intrinsics.c (scm_bootstrap_intrinsics): Declare the new
  intrinsics.
* libguile/jit.c (compile_call_f64_from_f64): Define code generators for
  the new intrinsics.
* libguile/vm-engine.c (call-f64<-f64): New instruction.
* module/language/cps/effects-analysis.scm:
* module/language/cps/reify-primitives.scm (compute-known-primitives):
* module/language/cps/slot-allocation.scm (compute-var-representations):
* module/language/cps/specialize-numbers.scm (specialize-operations):
* module/language/tree-il/cps-primitives.scm (abs):
* module/system/vm/assembler.scm (system, define-f64<-f64-intrinsic):
  (sqrt, abs, fsqrt, fabs):
* module/language/cps/types.scm (fsqrt, fabs): Add new f64<-f64
  primitives.
2019-08-04 21:54:51 +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
Andy Wingo
f07fadc72e VM does not initialize stack frames
* libguile/jit.c (compile_alloc_frame): Stop initializing locals.
  (compile_bind_rest): Use emit_alloc_frame.
* libguile/vm-engine.c (assert_nargs_ee_locals, allocate_frame): Don't
  initialize locals.
  (bind_rest): Don't initialize locals, and assert that the locals count
  has a minimum.
2019-06-06 17:39:53 +02:00
Andy Wingo
9fd978ed7e Add bind-optionals instruction
* doc/ref/vm.texi (Function Prologue Instructions): Document new
  instruction.
* libguile/jit.c (compile_bind_optionals): New compiler.
* libguile/vm-engine.c (VM_NAME): New interpreter.
* module/system/vm/assembler.scm (opt-prelude): Emit bind-optionals as
  appropriate.
* module/system/vm/disassembler.scm (define-stack-effect-parser)
  (code-annotation): Handle bind-optionals.
2019-06-06 16:36:32 +02:00
Andy Wingo
1fb39929f9 Reapply atomics inlining
This patch reapplies 230a555976 and
e8d34258be, but fixing a misplaced
comma (!).
2019-05-27 19:05:10 +02:00
Andy Wingo
2ba50e2fe6 Revert "Inline the atomic intrinsics"
This reverts commit 230a555976.
2019-05-27 18:40:42 +02:00
Andy Wingo
230a555976 Inline the atomic intrinsics
* libguile/intrinsics.h (SCM_FOR_ALL_VM_INTRINSICS):
* libguile/intrinsics.c (scm_bootstrap_intrinsics): Remove the atomic
  intrinsics, as the JIT no longer needs them.
* libguile/vm-engine.c (VM_NAME): Inline the intrinsics.
2019-05-27 12:01:38 +02:00
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