summaryrefslogtreecommitdiff
path: root/libguile/vm-engine.c
Commit message (Collapse)AuthorAgeFilesLines
* Simplify module variable lookup slow-pathAndy Wingo2021-04-261-2/+42
| | | | | | | | | | | | | | | | | | | | | | | | | | * 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.
* Add eq-immediate? instructionAndy Wingo2020-08-031-1/+21
| | | | | | | | | | | * 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.
* Add sign-extending make-immediate instructionAndy Wingo2020-07-301-2/+16
| | | | | | | | | | | | | | | | | * 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.
* Add jtable instructionAndy Wingo2020-07-231-1/+25
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * 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.
* Add intrinsics for a baseline compilerAndy Wingo2020-04-291-3/+57
| | | | | | | | | | | | | | | | | | | | | | | 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.
* Remove vm->sp_min_since_gcAndy Wingo2019-12-091-15/+5
| | | | | | | | | | | * 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.
* Optimize fixnum or s64 -> f64 conversionsAndy Wingo2019-09-011-1/+15
| | | | | | | | | | | | | | | | | | | | | * 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.
* Compiler allocates boxed flonums in unmarked spaceAndy Wingo2019-08-261-2/+34
| | | | | | | | | | | | | | | | | | | | | | | 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.
* Unbox floor/ceiling and trigonometric functions where possibleAndy Wingo2019-08-241-1/+19
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | * 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.
* Add support for optimized unboxed abs and sqrtAndy Wingo2019-08-041-1/+19
| | | | | | | | | | | | | | | | | | | | | 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.
* Speed up returns in JITAndy Wingo2019-06-181-1/+1
| | | | | | | | | | | | | | | | | | | | 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.
* VM does not initialize stack framesAndy Wingo2019-06-061-19/+8
| | | | | | | | | * 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.
* Add bind-optionals instructionAndy Wingo2019-06-061-1/+22
| | | | | | | | | | | * 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.
* Reapply atomics inliningAndy Wingo2019-05-271-6/+6
| | | | | | This patch reapplies 230a5559764679d75e3e8941e97a268a2b2e6a53 and e8d34258beab2799951e16d21d547299d4659364, but fixing a misplaced comma (!).
* Revert "Inline the atomic intrinsics"Andy Wingo2019-05-271-6/+6
| | | | This reverts commit 230a5559764679d75e3e8941e97a268a2b2e6a53.
* Inline the atomic intrinsicsAndy Wingo2019-05-271-6/+6
| | | | | | | * 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.
* Fix unused local warning in vm-engine.cAndy Wingo2018-10-071-1/+0
| | | | | * libguile/vm-engine.c (return-values): Remove needless frame_size=3 local var.
* Finish updating vm.texiAndy Wingo2018-09-301-8/+8
| | | | | | | | | | * 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.
* Update comments in vm-engine.cAndy Wingo2018-09-221-41/+451
| | | | | | | | * 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.
* Fix case where running abort hook could trash registersAndy Wingo2018-09-221-2/+5
| | | | | | * 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.
* Renumber instructions and bump objcode versionv2.3.0Andy Wingo2018-09-201-1287/+1176
| | | | | | | | * 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.
* Fix --disable-jit compilationlightningAndy Wingo2018-09-171-0/+10
| | | | | | | | | | | * 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.
* Deoptimize to VM when hooks are enabledAndy Wingo2018-09-141-48/+55
| | | | | | | | | | | * 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.
* Hook refactorsAndy Wingo2018-09-141-7/+7
| | | | | | | | | | | | | | | | | | | * 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.
* Remove hook intrinsics: hooks are just for the VMAndy Wingo2018-09-141-13/+13
| | | | | | | | | | | | * 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.
* VM manages hook sets itselfAndy Wingo2018-09-141-3/+3
| | | | | | | | | | | | | | | | | | | | | | | * 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.
* JIT counter tweaksAndy Wingo2018-09-021-2/+2
| | | | | | | | * 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.
* JIT threshold controlled by environment variableAndy Wingo2018-08-311-2/+2
| | | | | | | | | | * 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.
* Maybe enter JIT when returning from interpreted functionsAndy Wingo2018-08-291-7/+14
| | | | | * libguile/jit.c (scm_jit_compute_mcode): Minor optimization. * libguile/vm-engine.c (return-values): Maybe return to JIT code.
* Tweak to instrument-entryAndy Wingo2018-08-201-0/+8
| | | | | | * 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.
* Add instrumentation to VM builtinsAndy Wingo2018-08-171-1/+1
| | | | | | | | | | | | | | | | | | | * 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.
* Define intrinsics for atomic opsAndy Wingo2018-08-131-7/+7
| | | | | | | | | | | | * 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.
* 64-bit intrinsic args and return values passed indirectly on 32-bitAndy Wingo2018-08-131-9/+40
| | | | | | | | | | | | | * 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.
* Avoid needless 64-bit args on 32-bit machines for some intrinsicsAndy Wingo2018-08-131-16/+4
| | | | | | | | | | | | | | | | * 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.
* Update error-wrong-num-args intrinsic prototypeAndy Wingo2018-08-131-4/+4
| | | | | | | | * 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.
* Adapt JIT calling convention; continuations take mra from stackAndy Wingo2018-08-131-18/+11
| | | | | | | | | | | | | | | * 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.
* Continuations capture machine code addressAndy Wingo2018-08-121-12/+38
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * 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.
* Rework foreign-call trampolineAndy Wingo2018-08-111-6/+2
| | | | | | | | | | | | * 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.
* Invoke VM hooks through intrinsicsAndy Wingo2018-08-111-1/+1
| | | | | | | | | | | * 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.
* Add unpack-values-object intrinsicAndy Wingo2018-08-111-6/+2
| | | | | | | | | | * 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.
* Change call/cc inst to capture-continuationAndy Wingo2018-08-081-18/+9
| | | | | | | | | | | | | * 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.
* Rework program->ip mapping in VM to always call intrinsicAndy Wingo2018-08-081-25/+8
| | | | | | | | | | * 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.
* Minor optimization in RESET_FRAMEAndy Wingo2018-08-081-3/+9
| | | | * libguile/vm-engine.c (RESET_FRAME): Remove update of sp_min_since_gc.
* Merge branch 'master' into lightningAndy Wingo2018-08-071-16/+22
|\ | | | | | | | | This includes a manual cherry-pick of relevant stable-2.2 commits up to 4c91de3e45e7c98d5b7c484509fe5c59bd70f9fd.
| * vm: Fix stack-marking bug in multi-threaded programs.Ludovic Courtès2018-08-071-14/+20
| | | | | | | | | | | | | | | | | | | | | | 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.
* | VM hooks take no valuesAndy Wingo2018-08-071-11/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * 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!
* | Remove push continuation hook; return hook runs before FP popAndy Wingo2018-08-061-10/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * 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.
* | Consolidate apply hook to instrument-entry instructionAndy Wingo2018-08-061-11/+3
| | | | | | | | | | | | * libguile/vm.c (scm_call_n): * libguile/vm-engine.c: Move apply hook to "instrument-entry" instruction.
* | Rewrite subr implementationAndy Wingo2018-07-291-3/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * 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.
* | Emit instrument-loop in loops.Andy Wingo2018-07-291-3/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * 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.