Spur takes its first steps in Alpha!
17 June, 2014
(baby steps and giant leaps!)
From Eliot Miranda:
it gives me great pleasure to let you know that a spur-format trunk
Squeak image is finally available at
http://www.mirandabanda.org/files/Cog/SpurImages/. Spur VMs are available
Spur is a new object representation and garbage collector for
The object representation is significantly simpler than the existing one,
and hence permits a lot of JIT optimizations, in particular allocating
objects in machine code. This speeds up new, new: et al, but also speeds
up blocks because contexts and closures are now allocated in machine code.
It also provides immediate characters, so for example accessing wide
strings is much faster in Spur, since characters do not have to be
instantiated to represent characters with codes greater than 255.
The garbage collector has a scavenger and a global scan-mark-compact
collector. The scavenger is significantly faster than the existing
pointer-reversal scan-mark-compact, hence GC performance is much improved.
The memory manager manages old space as a sequence of segments, as opposed
to the single contiguous space provided by the existing memory manager.
The memory manager grows the heap a segment at a time, and can and will
release empty segments back to the host OS after a full GC. Hence Spur is
able to grow the heap to the limit of available memory without one having
to specify the VM’s memory size at start-up.
The object representation uses “lazy forwarding” to implement become:,
creating copies of objects that are becommed, and forwarding the existing
objects to the copies. While Spur still scans the stack zone on become to
ensure no forwarding pointers to the receiver exist in stack frames (for
check-free push and store instance variable operations), it does not scan
the entire heap, catching sends to forwarded objects as part of the normal
message send class checks, hence following forwarding pointers lazily, and
eliminating forwarders during GC. The existing memory manager does a full
memory sweep and compact to implement become. Hence Spur provides the
performance advantages of direct pointers while providing a significantly
While Spur uses moving GC (scavenging and compaction on full GC), just like
the existing memory manager, Spur supports pinning, the ability to stop an
object from moving. Old space objects will not be moved if pinned.
Attempting to pin a new space object causes a become, forwarding the new
space object to a pinned copy in old space. This allows simpler
interfacing with foreign code through the FFI, since one can hand out
references to pinned objects in the knowledge that they will not be moved
by the GC.
Finally Spur supports ephemerons in a simple and direct way, providing
pre-mortem per-instance finalization. Although the image-level support
needs to be written, it should soon be possible to improve the finalization
of entities such as buffered files (ensuring they are flushed before being
Spur is as yet a work in progress. The 32-bit implementation is usable and
appears stable. The major missing component is an incremental scan-mark GC
that should eliminate long pauses due to the global scan-mark-compact GC
(which is still invoked at snapshot time). I hope to start on this soon.
But another key facet of Spur is that the object header format and the
sizes of objects are common between 32- and 64-bits. In 32-bit and 64-bit
Spur, object bodies are multiples of 8 bytes, so there may be an unused
slot at the end of a 32-bit object with an odd number of slots. Hence Spur
is close to providing a “true” 64-bit system, one with 61-bit
SmallIntegers, and 61-bit SmallFloats (objects with the same precision, but
less range that 64-bit Float, done by stealing bits from the exponent
field). I look forward to collaborating with Esteban Lorenzano on 64-bit
Spur and hope that it will be available early next year.
I am of course interested in reports of performance effects. Under
certain, hopefully rare circumstances, Spur may actually be slower (one is
when the number of processes involved in process switching exceeds the
number of stack pages in the stack zone). But my limited experience is
that Spur is significantly faster than the existing VM. Please post
experiences, both positive and negative.
Finally, caveat emptor! This is alpha code. Bugs may result in image
corruption. If you do use Spur, please try and back up your work just in
case. And if anything does go wrong please let me know, preferrably
providing a reproducible case.