Opened 5 years ago

Closed 5 years ago

Last modified 5 years ago

#9008 closed enhancement (fixed)


Reported by: bdubbs@… Owned by: bdubbs@…
Priority: normal Milestone: 8.1
Component: BOOK Version: SVN
Severity: normal Keywords:


New minor version.

Change History (5)

comment:1 by bdubbs@…, 5 years ago

Owner: changed from blfs-book@… to bdubbs@…
Status: newassigned

comment:2 by bdubbs@…, 5 years ago

Changes in 2.2.0 (changes since the 2.0.x stable release series):

  • Notable changes


The biggest change in Guile 2.2 is a complete rewrite of its virtual machine and compiler internals. The result is faster startup time, better memory usage, and faster execution of user code. See the "Performance improvements" section below for more details.

Better thread-safety

This new release series takes the ABI-break opportunity to fix some interfaces that were difficult to use correctly from multiple threads. Notably, weak hash tables and ports are now transparently thread-safe. See "Scheduling" in the manual, for updated documentation on threads and communications primitives.

Better space-safety

It used to be the case that, when calling a Scheme procedure, the procedure and arguments were always preserved against garbage collection. This is no longer the case; Guile is free to collect the procedure and arguments if they become unreachable, or to re-use their slots for other local variables. Guile still offers good-quality backtraces by determining the procedure being called from the instruction pointer instead of from the value in slot 0 of an application frame, and by using a live variable map that allows the debugger to know which locals are live at all points in a frame.

Off-main-thread finalization

Following Guile 2.0.6's change to invoke finalizers via asyncs, Guile 2.2 takes the additional step of invoking finalizers from a dedicated finalizer thread, if threads are enabled. This avoids concurrency issues between finalizers and application code, and also speeds up finalization. If your application's finalizers are not robust to the presence of threads, see "Foreign Objects" in the manual for information on how to disable automatic finalization and instead run finalizers manually.

Better locale support in Guile scripts

When Guile is invoked directly, either from the command line or via a hash-bang line (e.g. "#!/usr/bin/guile"), it now installs the current locale via a call to `(setlocale LC_ALL "")'. For users with a unicode locale, this makes all ports unicode-capable by default, without the need to call `setlocale' in your program. This behavior may be controlled via the GUILE_INSTALL_LOCALE environment variable; see "Environment Variables" in the manual, for more.

Complete Emacs-compatible Elisp implementation

Thanks to the work of Robin Templeton, Guile's Elisp implementation is now fully Emacs-compatible, implementing all of Elisp's features and quirks in the same way as the editor we know and love.

Dynamically expandable stacks

Instead of allocating fixed stack sizes for running Scheme code, Guile now starts off each thread with only one page of stack, and expands and shrinks it dynamically as needed. Guile will throw an exception for stack overflows if growing the stack fails. It is also possible to impose a stack limit during the extent of a function call. See "Stack Overflow" in the manual, for more.

This change allows users to write programs that use the stack as a data structure for pending computations, as it was meant to be, without reifying that data out to the heap. Where you would previously make a loop that collect its results in reverse order only to re-reverse them at the end, now you can just recurse without worrying about stack overflows.

Using the stack also allows more code to be continuation-safe. For example, returning multiple times from a `map' procedure in Guile 2.0 would change the value of previously returned result lists, because map' built its result list in reverse order then used reverse!' to return the proper result. Now in Guile 2.2, `map' is implemented using straightforward recursion, which eliminates this bug while maintaining good performance as well as good space complexity.

Out-of-memory improvements

Instead of aborting, failures to allocate memory will now raise an unwind-only `out-of-memory' exception, and cause the corresponding `catch' expression to run garbage collection in order to free up memory.

GOOPS core reimplemented in Scheme

Guile's object orientation system, GOOPS, has been mostly reimplemented in Scheme. This decreases its maintenance burden on the rest of Guile, while also makes it possible to implement new features in the future, such as method combinations or `eqv?' specializers.


It used to be that Guile would stop at the first .go file it found in the GUILE_LOAD_COMPILED_PATH. If that file turned out to be out of date, then no .go file would be loaded. Now Guile will continue to search the path for a file which is both present and up-to-date, with respect to the .scm file.

C99 required

Following Emacs, you must use a C99-capable compiler when building Guile. In the future we also expect require C99 to use Guile's C interface, at least for `stdint' support.

Lightweight pre-emptive threading primitives

The compiler now inserts special "handle-interrupts" opcodes before each call, return, and backwards jump target. This allows the user to interrupt any computation and to accurately profile code using interrupts. It used to be that interrupts were run by calling a C function from the VM; now interrupt thunks are run directly from the VM. This allows interrupts to save a delimited continuation and, if the continuation was established from the same VM invocation (the usual restriction), that continuation can then be resumed. In this way users can implement lightweight pre-emptive threading facilities.

with-dynamic-state in VM

Similarly, `with-dynamic-state' no longer recurses out of the VM, allowing captured delimited continuations that include a `with-dynamic-state' invocation to be resumed. This is a precondition to allow lightweight threading libraries to establish a dynamic state per lightweight fiber.

  • Performance improvements

Faster programs via new virtual machine

Guile now compiles programs to instructions for a new virtual machine. The new virtual machine's instructions can address their source and destination operands by "name" (slot). This makes access to named temporary values much faster than in Guile 2.0, and removes a lot of value-shuffling that the old virtual machine had to do. The end result is that loop-heavy code can be two or three times as fast with Guile 2.2 as in 2.0. Your mileage may vary, of course; see "A Virtual Machine for Guile" in the manual for the nitties and the gritties.

Better startup time, memory usage with ELF object file format

Guile now uses the standard ELF format for its compiled code. (Guile has its own loader and linker, so this does not imply a dependency on any particular platform's ELF toolchain.) The benefit is that Guile is now able to statically allocate more data in the object files. ELF also enables more sharing of data between processes, and decreases startup time (about 40% faster than the already fast startup of the Guile 2.0 series). Guile also uses DWARF for some of its debugging information. Much of the debugging information can be stripped from the object files as well. See "Object File Format" in the manual, for full details.

Better optimizations via compiler rewrite

Guile's compiler now uses a Continuation-Passing Style (CPS) intermediate language, allowing it to reason easily about temporary values and control flow. Examples of optimizations that this permits are optimal contification, optimal common subexpression elimination, dead code elimination, loop-invariant code motion, loop peeling, loop inversion, parallel moves with at most one temporary, allocation of stack slots using precise liveness information, unboxing of 64-bit integers and floating point values, and closure optimization. For more, see "Continuation-Passing Style" in the manual.

Faster interpreter

Combined with a number of optimizations to the interpreter itself, simply compiling `eval.scm' with the new compiler yields an interpreter that is consistently two or three times faster than the one in Guile 2.0.

Allocation-free dynamic stack

Guile now implements the dynamic stack with an actual stack instead of a list of heap objects, avoiding most allocation. This speeds up prompts, the scm_dynwind_*' family of functions, fluids, and dynamic-wind'.

Optimized UTF-8 and Latin-1 ports, symbols, and strings

Guile 2.2 is faster at reading and writing UTF-8 and Latin-1 strings from ports, and at converting symbols and strings to and from these encodings.

Optimized hash functions

Guile 2.2 now uses Bob Jenkins' hashword2' (from his lookup3.c') for its string hash, and Thomas Wang's integer hash function for `hashq' and `hashv'. These functions produce much better hash values across all available fixnum bits.

Optimized generic array facility

Thanks to work by Daniel Llorens, the generic array facility is much faster now, as it is internally better able to dispatch on the type of the underlying backing store.

All ports are now buffered, can be targets of `setvbuf'

See "Buffering" in the manual, for more. A port with a buffer size of 1 is equivalent to an unbuffered port. Ports may set their default buffer sizes, and some ports (for example soft ports) are unbuffered by default for historical reasons.

Mutexes are now faster under contention

Guile implements its own mutexes, so that threads that are trying to acquire a mutex can be interrupted. These mutexes used to be quite inefficient when many threads were trying to acquire them, causing many spurious wakeups and contention. This has been fixed.

  • New interfaces

New cond-expand' feature: guile-2.2'

Use this feature if you need to check for Guile 2.2 from Scheme code.

New predicate: `nil?'

See "Nil" in the manual.

New compiler modules

Since the compiler was rewritten, there are new modules for the back-end of the compiler and the low-level loader and introspection interfaces. See the "Guile Implementation" chapter in the manual for all details.

Add "tree" display mode for statprof.

See the newly updated "Statprof" section of the manual, for more.

Support for non-blocking I/O

See "Non-Blocking I/O" in the manual, for more.

Implement R6RS custom binary input/output ports

See "Custom Ports" in the manual.

Implement R6RS output-buffer-mode Implement R6RS bytevector->string, string->bytevector

See "R6RS Transcoders" in the manual.

`accept' now takes optional flags argument

These flags can include SOCK_NONBLOCK' and SOCK_CLOEXEC', indicating options to apply to the returned socket, potentially removing the need for additional system calls to set these options. See "Network Sockets and Communication" in the manual, for more.

Thread-safe atomic boxes (references)

See "Atomics" in the manual.

Thread-local fluids

Guile now has support for fluids whose values are not captured by `current-dynamic-state' and not inheritied by child threads, and thus are local to the kernel thread they run on. See "Thread-Local Variables" in the manual, for more.


This predicate returns true if the delimited continuation captured by aborting to a prompt would be able to be resumed. See "Prompt Primitives" in the manual for more.

scm_c_prepare_to_wait_on_fd, scm_c_prepare_to_wait_on_cond, scm_c_wait_finished

See "Asyncs" in the manual for more.

File descriptor finalizers

See "Ports and File Descriptors" in the manual.

New inline functions: scm_new_smob', scm_new_double_smob'

These can replace many uses of SCM_NEWSMOB, SCM_RETURN_NEWSMOB2, and the like. See XXX in the manual, for more.

New low-level type accessors

For more on SCM_HAS_TYP7', SCM_HAS_TYP7S', `SCM_HAS_TYP16', see XXX.

SCM_HEAP_OBJECT_P' is now an alias for the inscrutable SCM_NIMP'.

SCM_UNPACK_POINTER' and SCM_PACK_POINTER' are better-named versions of the old SCM2PTR' and PTR2SCM'. Also, `SCM_UNPACK_POINTER' yields a void*.

TCP_NODELAY' and TCP_CORK' socket options, if provided by the system

scm_c_put_latin1_chars', scm_c_put_utf32_chars'

Use these instead of `scm_lfwrite'. See the new "Using Ports from C" section of the manual, for more.

<standard-vtable>, standard-vtable-fields

See "Structures" in the manual for more on these.

Convenience utilities for ports and strings.

See "Conversion to/from C" for more on `scm_from_port_string', scm_from_port_stringn', scm_to_port_string', and `scm_to_port_stringn'.

And More int he NEWS file.

comment:3 by bdubbs@…, 5 years ago

Resolution: fixed
Status: assignedclosed

Fixed at revision 18500.

comment:4 by bdubbs@…, 5 years ago

Milestone: 8.1m8.1

Milestone renamed

comment:5 by bdubbs@…, 5 years ago

Milestone: m8.18.1

Milestone renamed

Note: See TracTickets for help on using tickets.