* 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.
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.
* 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.
* 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.
* libguile/values.c (scm_c_value_ref): Fix a case in which a request for
the 0th value of a zero-valued object would return the object instead
of erroring.
* libguile/vm-engine.c (halt): Fix construction of a multiple-valued
return (off-by-one error). Fixes a crash introduced in
4a2d78b4d4.
* libguile/instructions.c (DOP1, DOP2, DOP3, DOP4, DOP5): New parts of
the DSL, equivalent to e.g. OP1(x) | OP_DST. Will allow other
definitions of OP* that use token pasting.
* libguile/vm-engine.c: Adapt to use new DOP descriptors.
This reverts commit 593e2db1dd. The goto
strategy works for hooks that run just before a "next"; it doesn't work
for ones that run at the beginning of opcodes.
* libguile/vm-engine.c (GOTO_HOOK, HOOK_HANDLER): Split hooks that don't
take args into a "goto" side and a "target" side. The idea is to just
reify the hook call at one place in the binary, since the VM
continuation is fully in the registers.
(APPLY_HOOK, PUSH_CONTINUATION_HOOK, NEXT_HOOK)
(ABORT_CONTINUATION_HOOK): Reimplement in terms of goto hooks.
(POP_CONTINUATION_HOOK): This one is still old-style.
(CONTINUE): New helper definition.
(call, call-label): Move the push-continuation hooks up a bit, so it's
clear they don't depend on intermediate opcode state.
(vm_engine): Reify hook handlers for apply, etc.
* 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.
* 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.
* 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.
* 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.
* libguile/vm-engine.c (CALL_INTRINSIC): New helper macro.
(ALLOC_FRAME, vm_engine): Use CALL_INTRINSIC when we need to call
intrinsics. GCC still doesn't allocate intrinsics to a register
though!
* 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.
* 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.
* 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.
* libguile/control.h:
* libguile/control.c (scm_i_make_composable_continuation): Rename from
make_partial_continuation and expose internally.
(scm_abort_to_prompt_star): Adapt to scm_i_vm_abort name change.
* libguile/intrinsics.h (SCM_FOR_ALL_VM_INTRINSICS): Define
abort_to_prompt intrinsic.
* libguile/throw.c (abort_to_prompt): Adapt to scm_i_vm_abort name
change.
* libguile/vm-engine.c (abort): Use abort_to_prompt intrinsic.
* libguile/vm.c (capture_delimited_continuation): Move here from
control.c where it was named reify_partial_continuation.
(scm_i_vm_abort): Move from control.c where it was named
scm_c_abort (and only exposed internally).
(abort_to_prompt): New intrinsic, replacing vm_abort.
* libguile/vm.h: Add setjmp include and scm_i_vm_abort decl.
* libguile/intrinsics.h:
* libguile/vm.c (rest_arg_length): New intrinsic.
(vm_error_apply_to_non_list): Remove now-unused error proc.
* libguile/vm-engine.c (tail-apply): Use new intrinsic.
* libguile/intrinsics.h (SCM_FOR_ALL_VM_INTRINSICS): Add
compose-continuation intrinsic.
* libguile/vm-engine.c (compose-continuation): Call compose-continuation
intrinsic.
* libguile/vm.c (compose_continuation_inner, compose_continuation): Move
down and rename from vm_reinstate_partial_continuation, and make into
a form that works as an intrinsic.
* libguile/continuations.h:
* libguile/continuations.c (scm_i_make_continuation): Refactor to expect
registers to already be captured.
* libguile/scm.h (scm_i_thread): Add forward decl.
* libguile/threads.h (struct scm_i_thread): Just fill in the struct
type.
* libguile/vm-engine.c (call/cc); Use the registers already captured
before entering the VM.
* libguile/continuations.h (scm_t_contregs): Remove "struct vm*" member;
unneeded.
* libguile/continuations.c (scm_i_make_continuation): No need to store
continuation->vp.
(scm_i_contregs): New internal function, replaces scm_i_contregs_vp
and scm_i_contregs_vm_cont.
(scm_i_check_continuation): Remove; moved to vm.c.
(scm_i_reinstate_continuation): Add an abort(), to satisfy
SCM_NORETURN.
* libguile/intrinsics.h: Add new "reinstate-continuation!" intrinsic.
* libguile/vm-engine.c (continuation-call): Use new
reinstate-continuation! intrinsic.
* libguile/vm.c (vm_return_to_continuation_inner): Move later in the
file.
(reinstate_continuation_x): New intrinsic.
(scm_bootstrap_vm): Init new intrinsic.
* libguile/Makefile.am (noinst_HEADERS, modinclude_HEADERS): Change to
not install intrinsics.h.
* libguile/intrinsics.h: Add an error if BUILDING_LIBGUILE isn't set, to
catch any stray bad inclusions. Add intrinsic for foreign-call.
* libguile/foreign.c (foreign_call): Rename from scm_i_foreign_call, and
set as the foreign-call intrinsic.
* libguile/vm-engine.c (foreign-call): Use the intrinsic. In the future
we'll want to totally revamp the FFI, if we know that a JIT is
available!
* libguile/scm.h (scm_tc7_values): New tc7. Never seen by Scheme, so we
don't need to update it anywhere else.
* libguile/values.h (scm_is_values): New public static inline function.
(scm_i_nvalues, scm_i_value_ref): New private static inline
functions.
(SCM_VALUESP): Use scm_is_value.
(scm_values_2, scm_values_3): New functions.
(scm_values_vtable): Remove; values objects are not structs any more.
* libguile/values.c (scm_i_extract_values_2): Adapt to new values
representation.
(print_values): Remove now-unused function.
(scm_c_nvalues): Use scm_i_nvalues.
(scm_c_value_ref): Use scm_i_value_ref.
(scm_values, scm_c_values): Make the new-style objects, which store
their values inline.
(scm_values_2, scm_values_3): New helpers, to avoid consing little
useless lists.
* libguile/vm-engine.c (halt, subr-call)
* libguile/eval.c (eval): Adapt to new values representation.
* libguile/i18n.c (scm_locale_string_to_integer)
(scm_locale_string_to_integer)
* libguile/numbers.c (scm_i_floor_divide, scm_i_ceiling_divide)
(scm_i_truncate_divide, scm_i_centered_divide, scm_i_round_divide)
(scm_i_exact_integer_sqrt)
* libguile/r6rs-ports.c (make_bytevector_output_port)
* libguile/srfi-1.c (scm_srfi1_partition, scm_srfi1_partition_x)
* libguile/srfi-14.c (scm_char_set_diff_plus_intersection)
(scm_char_set_diff_plus_intersection_x)
* libguile/posix.c (scm_getrlimit, scm_open_process): Adapt to use
scm_values_2 or scm_values_3.
* libguile/print.c (iprin1): Add printer for values objects.
* libguile/intrinsics.h (SCM_FOR_ALL_VM_INTRINSICS): Add
push-interrupt-frame.
* libguile/vm.c (push_interrupt_frame): New intrinsic. Goal is to
reduce the amount of inline code the JIT will generate for handling
interrupts.
* libguile/vm-engine.c (handle-interrupts): Call out to the
push_interrupt_frame intrinsic in the slow case.
* libguile/intrinsics.h (scm_t_thread_sp_intrinsic): Change to take
thread instead of vp.
(SCM_FOR_ALL_VM_INTRINSICS): Change expand_stack to expect thread, not
vp.
* libguile/vm-engine.c (ALLOC_FRAME): Call expand_stack with thread.
* libguile/vm.c (thread_expand_stack, scm_bootstrap_vm): Adapt.
* libguile/vm.c (scm_t_vm_engine, scm_call_n): Remove "vp" argument.
* libguile/vm-engine.c (VP): New macro, to get VP from thread. Replace
all uses of vp with this.
As the FSF advises, 'There is no legal significance to using the
three-character sequence “(C)”, but it does no harm.' It does take up
space though! For that reason, we remove it here from our C files.
* libguile/__scm.h (scm_i_jmp_buf): Remove definition, which was a shim
for ia64. Instead, always use setjmp/longjmp and jmp_buf.
* libguile/_scm.h (SCM_I_SETJMP, SCM_I_LONGJMP): Remove; instead use
setjmp and longjmp.
* libguile/continuations.c (capture_auxiliary_stack):
(restore_auxiliary_stack): New helpers.
(scm_i_make_continuation): Use capture_auxiliary_stack.
(copy_stack_and_call): Use restore_auxiliary_stack. No need to stash
the aux stack on the thread, either.
* libguile/continuations.h (scm_t_contregs): Use
SCM_HAVE_AUXILIARY_STACK to flag when to have an auxiliary_stack
member.
* libguile/control.h:
* libguile/control.c (reify_partial_continuation, scm_c_abort):
(scm_suspendable_continuation_p): Adapt to use setjmp/longjmp
directly.
* libguile/deprecated.h: Add deprecated scm_i_jmp_buf define.
* libguile/dynstack.h:
* libguile/dynstack.c (PROMPT_JMPBUF):
(scm_dynstack_push_prompt, scm_dynstack_find_prompt):
(scm_dynstack_wind_prompt): Adapt to jmp_buf type.
* libguile/eval.c (eval): Use jmp_buf and setjmp directly.
* libguile/gc-malloc.c: No need for ia64-specific things.
* libguile/gc.c: No need for ia64-specific things.
* libguile/gc.h: No need to declare scm_ia64_ar_bsp.
* libguile/init.c: Remove typedef of setjmp_type for Cray, unused.
* libguile/threads.c (guilify_self_1): No more pending_rbs_continuation
in scm_i_thread, and register_backing_store_base is handled by libgc.
(scm_ia64_ar_bsp): Remove definitions; inlined into continuations.c's
capture_auxiliary_stack.
* libguile/threads.h (scm_i_thread): jmpbuf member is plain jmp_buf.
* libguile/throw.c (catch): Just use jmp_buf and setjmp.
* libguile/vm-engine.c (VM_NAME): Adapt prototype to take jmp_buf
pointer.
* libguile/vm.c (vm_abort): Adapt jmp_buf types.
(scm_call_n): Use setjmp.