Title: Spur, a new object representation for Cog
Speaker: Elliot Miranda
Wed, August 20, 9am – 10am
Video:
Part 1: https://www.youtube.com/watch?v=k0nBNS1aHZ4
Part 2: https://www.youtube.com/watch?v=sn3irBZE7g4
Part 3: https://www.youtube.com/watch?v=1Vg0iFeg_pA
Abstract: Spur is a new object representation and memory manager for the Cog VM. The object representation includes immediate characters and its simplicity allows Cog's JIT to implement many more operations, resulting in a faster VM. The object representation is designed to share the object header and the majority of the memory management code between 32-bit and 64-bit versions. Spur has two features new to Squeak/Pharo, the ability to grow and shrink memory via segments, and the ability to pin objects in memory. Spur has one altogether novel feature, a partial read barrier, which takes advantage of Smalltalk's message sending to provide lazy forwarding, which allows the system to implement become efficiently while retaining the speed advantages of direct pointers. This talk will explain these features with minimal manifestation of machine code on the slides and, for this author, plenty of pleasing pictures.
Bio: Eliot Miranda is a long-time Smalltalk systems programmer and virtual machine architect. He started his technical life developing holographic optics for bubble chamber physics, in so doing discovering a love of computing. His early work, started while a student at York University, produced the BrouHaHa series of virtual machines. These were Smalltalk-80 interpreters and threaded code JITs, written in C. While at Queen Mary College in the University of London he was involved in applying these implementations to prototyping what-you-see-is-what-i-see interfaces for IBM and to implementing the bulk of the software for the Active Book, a very early ARM-based tablet computer. He was virtual machine lead and then technical lead for VisualWorks for a decade at ParcPlace and its successors, before joining Cadence where he helped adapt Squeak to implement Newspeak. He then joined Qwaq, the company applying Croquet to business communications, where he implemented Cog. He is now back at Cadence in a team applying Cog and Newspeak to SoC design support. He is currently enjoying collaborating with a number of people on Cog-related projects, not least of which is an adaptive optimization system for Pharo/Squeak called Sista.
2)
7. oops
BS Direct Pointers
size...flags...hash
class
inst vars
...
refcount
HPS Object Table Indirection
size...flags...hash
class
indirection
inst vars
...
D-machine OTE
20-bit address
size
class
inst vars
...
Wednesday, 20 August 2014
8. oops! yeah, right...
size...flags...hash
class
indirection
inst vars
...
size...flags...inst size...hash...class index
indirection
inst vars
...
64-bit HPS 7
sparse
class
table
Wednesday, 20 August 2014
9. class indices/class tags
class index is index of class in class table
class’s identity hash is its index in class table
∴ its instances’ class tag
Behavior>>identityHash (& Behavior>>new)
use them in method caches; resolve to class
object on #class or full method lookup
constants, never moved by GC
cheap allocation of well-known objects
puns & special non-objects
#slots identityHash fmt class index
Wednesday, 20 August 2014
10. evolution
top-down selection pressure
(≈tests)
bottom-up refinement
(≈≈ pink plane)
exaptation
(≈ blue plane)
Wednesday, 20 August 2014
12. The VM System
heap
lcoaockhuep prims irnetteerrp gc &
alloc
Wednesday, 20 August 2014
13. The VM System
heap
lcoaockhuep zcoodnee sztoancek
prims irnetteerrp jit gc &
alloc
Wednesday, 20 August 2014
14. method lookup
findNewMethod
! "Find the compiled method to be run when the current
messageSelector is sent to the class lkupClass, setting
the values of newMethod and primitiveIndex."
! <inline: true>
! | ok |
! ok := self lookupInMethodCacheSel: messageSelector class: lkupClass.
! ok ifFalse: "entry was not found in the cache; look it up the hard way"
! ! [self lookupMethodInClass: lkupClass.
! ! self addNewMethodToCache]
Wednesday, 20 August 2014
15. Exapt
method cache probe
class tags
stack zone
primitives
Wednesday, 20 August 2014
16. Exaptation
become lazy
all objects can be forwarders
forwarded class tag fails method cache probe
follow on message lookup
stack zone scan avoids inst var access read barrier
Wednesday, 20 August 2014
17. become
size flags hash class index
inst var 0 inst var 1
.....
size flags hash class index
inst var 0 inst var 1
.....
Wednesday, 20 August 2014
18. become
size flags forwarded index
forwarding ptr
copy copy
size flags hash class index
inst var 0 inst var 1
.....
size flags forwarded index
forwarding ptr
size flags hash class index
inst var 0 inst var 1
.....
Wednesday, 20 August 2014
20. lazy forwarding issues
inst var access
(& method access in interpreter)
message sends
class hierarchy method lookup
global var access (including super sends)
primitives
Wednesday, 20 August 2014
21. lazy forwarding: inst vars
partial read barrier
size flags forwarded index
forwarding ptr
copy copy
size flags hash class index
inst var 0 inst var 1
.....
size flags forwarded index
forwarding ptr
size flags hash class index
inst var 0 inst var 1
.....
+ if became pointer or method object,
scan stack zone to follow forwarding pointers
Wednesday, 20 August 2014
23. lazy forwarding:
class hierarchy method lookup
after any pointer become could scan
every class in class table
every method on entry to stack zone
KISS
read barrier on access
superclassOf: classObj
! "Read barrier here costs very little because lookup is rare,
& class and superclass almost certainly share a cache line."
^objectMemory followField: SuperclassIndex ofObject: classObj
Wednesday, 20 August 2014
24. lazy forwarding:
global variable access
after any pointer or method become could scan
every method in stack & code zones
every method on entry to stack zone
KISS
read barrier on access
pushLiteralVariable: literalIndex
! | litVar |
! litVar := self literal: literalIndex.
! (heap isForwarded: litVar) ifTrue:
! ! [litVar := heap followForwarded: litVar].
! self push: (heap fetchPointer: ValueIndex ofObject: litVar)
Wednesday, 20 August 2014
25. lazy forwarding: primitives
bits
width
height
depth
offset
mask
x
y
bits
width
height
depth
offset
self validate
ifTrue: [self operate]
ifFalse: [self fail]
x
y
Wednesday, 20 August 2014
28. ephemerons
processEphemerons
! "There are ephemerons to be scavenged. Scavenge them and fire any whose keys are
! still in pastSpace and/or eden. The unscavenged ephemerons in this cycle can only be
! fired if all the unscavenged ephemerons in this cycle are firable, because references
! to ephemeron keys from unfired ephemerons should prevent the ephemerons with
! those keys from firing. So scavenge ephemerons with surviving keys, and only if none
! are found, fire ephemerons with unreferenced keys, and scavenge them. Read the
! class comment for a more in-depth description of the algorithm."
! | unfiredEphemeronsScavenged |
! unfiredEphemeronsScavenged := self scavengeUnfiredEphemeronsInRememberedSet.
! self scavengeUnfiredEphemeronsOnEphemeronList ifTrue:
! ! [unfiredEphemeronsScavenged := true].
! unfiredEphemeronsScavenged ifFalse:
! ! [self fireEphemeronsInRememberedSet.
! ! self fireEphemeronsOnEphemeronList]
Wednesday, 20 August 2014
29. object size/heap walk
8 22 5 22
<= 254 identityHash fmt class index
at least one slot
255 slot count
255 identityHash fmt class index
Wednesday, 20 August 2014