SlideShare a Scribd company logo
1 of 81
Download to read offline
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
Growing an Abstract Grammar
Teaching Language
EngineeringTheo D'Hondt
Software Languages Lab
Vrije Universiteit Brussel
soft.vub.ac.be
tjdhondt@vub.ac.be
Reasoning about
memory-critical algorithms
1
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
Abstract
We call algorithms memory-critical if their actual dependence on memory is such that their
implementation cannot use abstractions that indirectly require memory of their own. An
obvious example of such an abstraction is a recursion stack. An equally obvious example
of a memory-critical algorithm is a garbage collector.
Generally, memory-critical algorithms are designed as state machines that apply a clever
technique to embed a greatly resized version of the abstraction-related memory within the
actual memory. Typically these algorithms end up being very terse and hard to conceive or
comprehend, and when expressed as actual code they are equally hard to debug or
optimise.
Memory-critical algorithms have been the object of scientific publications, educational
material and actual software since the early 60ies. In order to present these algorithms,
techniques ranging from mathematical formalisms, graphical representations to
pseudocode have been proposed. Unfortunately, these all suffer from the pithy nature of
these algorithms and the lack of a uniform medium to reason about them. Hence their
notoriously bad reputation for instance with students of advanced algorithms courses.
This talk will report on an initiative to bind formalism, graphics and (executable) code in a
framework to reason about memory-critical algorithms. It started out as an accumulation
of convenient representations, and grew into something that has the hallmark of a
systematic approach. It will be introduced by applying it to two historical algorithms, and
subsequently two non-trivial experiments will be briefly described.
2
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
Smaltalkers: [ . ] vs. { ; }
Sista: a Metacircular Architecture for Runtime
Optimisation Persistence
ClΓ©ment BΓ©ra
Laboratoire d’Informatique Fondamentale de Lille
INRIA Lille - Nord Europe 2017
... As most of the Smalltalk community has
high skills in Smalltalk but little skills in low-
level programming, the design aims here to
allow the community to contribute to a
project in Smalltalk doing Smalltalk-specific
optimisations, improving performance while
staying away from low-level details and
machine-specific optimisations ...
3
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
Smaltalkers: [ . ] vs. { ; }
Sista: a Metacircular Architecture for Runtime
Optimisation Persistence
ClΓ©ment BΓ©ra
Laboratoire d’Informatique Fondamentale de Lille
INRIA Lille - Nord Europe 2017
... As most of the Smalltalk community has
high skills in Smalltalk but little skills in low-
level programming, the design aims here to
allow the community to contribute to a
project in Smalltalk doing Smalltalk-specific
optimisations, improving performance while
staying away from low-level details and
machine-specific optimisations ...
Slang
3
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
Cheney's algorithm
C. J. Cheney

A nonrecursive list compacting algorithm.
Comm. ACM 13, 11 (1970)
h coding. It
that are de-
ple, efficient,
s few probes
Comm. ACM 11, 1 (Jan. 1968), 38--44.
3. BELL, J. R. The quadratic quotient method: A hash code
eliminating secondary clustering. Comm. ACM 13, 2 (Feb.
1970), 107-109.
4. RADKE,E.E. The use of quadratic residue research. Comm.
ACM 13, 2 (Feb. 1970), 103-105.
acting
dge, England
g scheme or
and LISP-like
the need for
ilt up to keep
ollection, compacl
[2] have pre-
uctures. One
a list pointer,
he authors of
but complex
m of Deutsch,
ler algorithm
T to copy a
list area (the
copied with-
new list area
s found will
the structure
r from them,
ect the list in
"nonitems."
The structure is accessed via the pointer HEAD. This
structure has two lists, the first consisting of three atoms
A, B, C and a list pointer to the second list which consists
solely of a list pointer to the atom A of the first list. Lists
+o
(a)
HEAD I q/q
SCAN't NEXT~
(b)
:: i i .... :HEAD
,+AIBIΒ’I I/1
SCANT NEXTT
(c)
I ,..... '.---5....,_.,,I I I
, I , .~ Itl/l
I I I Is
I
I I I
+
HEAD dAiSlCi ~,iA i,i/, 1
TNEXT
SCAN
(d)
old
list
area
new
list
area
FIG. 1. Compacting a structure without looped lists: (a) initial
structure; (b) and (c) during processing; (d) final structure.
Communications of the ACM 677
are terminated by NIL cells. The algorithm with some
modification can be applied to LISP-type structures.
To compact the structure, the list pointed to by HEAD
is copied by COPYLIST into the new area--the contents
of each item (not nonitems) are placed in consecutive cells
in the new area, and the cells in the old area are changed
to nonitems pointing to their equivalent cells in the new
area. COPYLIST returns as a result the address of the
first cell of the list in the new area. This value is used to
update HEAD. A pointer NEXT is kept pointing to the
next free cell in the new area. This intermediate structure
is shown in Figure 1(b).
A further pointer SCAN now scans the new area from
the beginning. If SCAN points to a NIL or an atom, it is
moved on to the next cell. If SCAN points to a list pointer,
COPYLIST is entered with this list pointer as its param-
eter. The sublist is therefore copied, updating NEXT,
and the value returned is used to make the list pointer
pointed at by SCAN point to the copied list in the new
area. The structure resulting when SCAN has processed
the first list pointer is shown in Figure 1(c). Note that, in
copying, COPYLIST omits the nonitems of the original
structure.
SCAN continues its traverse of the new area and will
pass over the NIL to the second list to reach another list
pointer. COPYLIST is again applied, but this time it
finds the first item is already in the new area (e.g. by com-
paring core addresses), and the function returns with the
address of this cell in the new area, which is used to update
the list pointer, but without recopying the list.
The compact structure is complete when SCAN reaches
the cell pointed to by NEXT. The procedure is capable of
dealing with looped lists as COPYLIST will place a non-
item in the new area when necessary (see Figure 2).
(o)
o,0
HEAD listorgc]
i i
I i
i I fleW
A version has been written in assembly language in-
volving the execution of between 30 and 40 orders on an
Atlas computer for each item of the structure transferred
to the new area.
The algorithm is presented below in two parts--the
"main program" first, and then the function COPYLIST.
Step 1. Initialize the pointers SCAN and NEXT to point to the
beginning of the new list area.
Step 2. Apply the function COPYLIST--described below--to
the pointer that points to the whole structure and assign
the result of COPYLIST to that pointer.
Step 3. If SCAN points to a list-pointer, then apply COPYLIST
to that list pointer, the result of COPYLIST replaces the
contents of the cell pointed at by SCAN.
Step 4. Increment SCAN, unless SCAN now points to the same
cell pointed at by NEXT, go to step 3 above. Otherwise the
compacting is complete.
The function COPYLIST takes one parameter,
POINTER, called by value; the function does the follow-
ing:
Step 1. If POINTER points to a cell that is a nonitem, make
POINTER point to the cell pointed at by the nonitem. Re-
peat this step while POINTER points to a nonitem.
Step 2. If POINTER is pointing to a cell in the new area, return
with the value of POINTER as the result.
Step 3. Save the current value of NEXT in a variable V.
Step 4. If POINTER is pointing to a cell in the new area, make
the cell pointed at by NEXT into a nonitem pointing to the
cell that is pointed at by POINTER, and go to step 11 below.
Step 5. Copy the contents of the cell pointed at by POINTER to
the cell pointed at by NEXT.
Step 6. If POINTER is pointing to a NIL, then go to step 11 below.
Step 7. Make the cell pointed at by POINTER into a nonitem
that points to the cell pointed at by NEXT, i.e. the corre-
sponding cell in the new area.
Step 8. Increment NEXT, increment POINTER.
Step 9. If POINTER points to a nonitem, make POINTER point
to the cell pointed at by the nonitem, repeat this step while
POINTER is pointing to a nonitem.
Step 10. Go to step 4 of the function COPYLIST.
Step 11. Increment NEXT and return with the value of V as the
result.
Acknowledgments. The author is particularly grateful
for many discussions with N. E. Wiseman and for the4
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
begin-garbage-collection
(assign free (const 0))
(assign scan (const 0))
(assign old (reg root))
(assign relocate-continue (label reassign-root))
(goto (label relocate-old-result-in-new))
reassign-root
(assign root (reg new))
(goto (label gc-loop))
gc-loop
(test (op =) (reg scan) (reg free))
(branch (label gc-flip))
(assign old (op vector-ref) (reg new-cars) (reg scan))
(assign relocate-continue (label update-car))
(goto (label relocate-old-result-in-new))
update-car
(perform (op vector-set!) (reg new-cars) (reg scan) (reg new))
(assign old (op vector-ref) (reg new-cdrs) (reg scan))
(assign relocate-continue (label update-cdr))
(goto (label relocate-old-result-in-new))
update-cdr
(perform (op vector-set!) (reg new-cdrs) (reg scan) (reg new))
(assign scan (op +) (reg scan) (const 1))
(goto (label gc-loop))
relocate-old-result-in-new
(test (op pointer-to-pair?) (reg old))
(branch (label pair))
(assign new (reg old))
(goto (reg relocate-continue))
pair
(assign oldcr (op vector-ref) (reg the-cars) (reg old))
(test (op broken-heart?) (reg oldcr))
(branch (label already-moved))
(assign new (reg free)) ;new location for pair
;; update free pointer
(assign free (op +) (reg free) (const 1))
;; Copy the car and cdr to new memory.
(perform (op vector-set!) (reg new-cars) (reg new) (reg oldcr))
(assign oldcr (op vector-ref) (reg the-cdrs) (reg old))
(perform (op vector-set!) (reg new-cdrs) (reg new) (reg oldcr))
;; Construct the broken heart.
(perform (op vector-set!) (reg the-cars) (reg old) (const broken-heart))
(perform (op vector-set!) (reg the-cdrs) (reg old) (reg new))
(goto (reg relocate-continue))
already-moved
(assign new (op vector-ref) (reg the-cdrs) (reg old))
(goto (reg relocate-continue))
gc-flip
(assign temp (reg the-cdrs))
(assign the-cdrs (reg new-cdrs))
(assign new-cdrs (reg temp))
(assign temp (reg the-cars))
(assign the-cars (reg new-cars))
(assign new-cars (reg temp))
Cheney's algorithm
Hal Abelson, Jerry Sussman and
Julie Sussman

Structure and Interpretation of
Computer Programs 

MIT Press (1984)
5
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
Schorr-Waite algorithm*
H. Schorr and W. M. Waite

An efficient machine-independent procedure for
garbage collection in various list structures 

Comm. ACM 10, 8 (1967)
dex registers and the accumulator for temporary storage,
though in general any three storage locations could be used.
One contains the address of the previous list element ex-
amined, the second the address of the element currently
being examined and the third the address of the next ele-
ment on the list. This is necessary for the reversal of the
pointers during the forward scan and their restoration
during the reverse scan.
In order to evaluate the speed of the routine, a Wise
program was written which created five complete binary
trees of depth 12. The remaining registers were discarded
and the garbage collector called. Thus it was forced to
trace a list structure containing over 20,000 registers, half
of which were branch points. The elapsed time, according
to the system clock, was 1.85 seconds. This list structure
seems far more complex than any which would be en-
countered in practice, and therefore a normal garbage col-
lection should take far less time. The space occupied is also
Q
F
ENTRY
i
SETI TO Ii
FIRSTCELL
OF L ST
lNO
IMAKE'TIMINUS
1I REVERSEPOINTER
OFCELLI
YES
YES
W:l
scanned many times, and the program would fail by enter-
ing a loop when attempting to trace a circular list. When
run under the above conditions (5 binary trees of depth 12)
the routine required 2.75 seconds for a complete trace.
As a final comparison, a routine which stored branch
points was coded and run using the same list structure. The
program occupied 34 words, and an additional 48 words
were allotted as a storage area for the branch points. Any
given part of the list structure was only traversed once, so
that this routine could trace any list for which the number
of branch points it was required to store was less than 49.
Only .448 seconds were required to complete the trace of
the test structure.
EXIT
YES
RESTORE POINTER
OF CELL I
LI - ~ I
TO~~~iYES
REVERSE POINTERI
IN CAR OF I
SET BRANCH
PO NT FLAG
1SET 2: TO
FIRST CELL
OF BRANCH
NO
(
FIG. 3. Trace algorithm for a one-way list. Forward scan; reverse scan
RESTOREPOINTER
IN CAROFI.
CLEAR BRANCH
POINT FLAG.
504 Communications of the ACM Volume 10 / Number 8 / August, 1967
venience in drawing the flowchart, the list elements are
assumed to be numbered sequentially. Thus, list element
I + 1 follows list element I (i.e., list element I + 1 is pointed
to by the TAIL of list element I). The routine uses two in-
dex registers and the accumulator for temporary storage,
though in general any three storage locations could be used.
One contains the address of the previous list element ex-
amined, the second the address of the element currently
being examined and the third the address of the next ele-
ment on the list. This is necessary for the reversal of the
pointers during the forward scan and their restoration
during the reverse scan.
In order to evaluate the speed of the routine, a Wise
program was written which created five complete binary
trees of depth 12. The remaining registers were discarded
and the garbage collector called. Thus it was forced to
trace a list structure containing over 20,000 registers, half
of which were branch points. The elapsed time, according
to the system clock, was 1.85 seconds. This list structure
seems far more complex than any which would be en-
countered in practice, and therefore a normal garbage col-
lection should take far less time. The space occupied is also
Q
F
ENTRY
i
SETI TO Ii
FIRSTCELL
OF L ST
lNO
IMAKE'TIMINUS
1I REVERSEPOINTER
OFCELLI
YES
YES
W:l
For purposes of comparison, a trace routine proposed by
Wilkes was coded for the 7094. It required only two tempo-
rary storage locations, and occupied 35 words of memory.
This routine traversed a path from the head of a list to each
terminal register separately. Thus much of the list was
scanned many times, and the program would fail by enter-
ing a loop when attempting to trace a circular list. When
run under the above conditions (5 binary trees of depth 12)
the routine required 2.75 seconds for a complete trace.
As a final comparison, a routine which stored branch
points was coded and run using the same list structure. The
program occupied 34 words, and an additional 48 words
were allotted as a storage area for the branch points. Any
given part of the list structure was only traversed once, so
that this routine could trace any list for which the number
of branch points it was required to store was less than 49.
Only .448 seconds were required to complete the trace of
the test structure.
EXIT
YES
RESTORE POINTER
OF CELL I
LI - ~ I
TO~~~iYES
REVERSE POINTERI
IN CAR OF I
SET BRANCH
PO NT FLAG
1SET 2: TO
FIRST CELL
OF BRANCH
NO
(
FIG. 3. Trace algorithm for a one-way list. Forward scan; reverse scan
RESTOREPOINTER
IN CAROFI.
CLEAR BRANCH
POINT FLAG.
504 Communications of the ACM Volume 10 / Number 8 / August, 1967
*also attributed to Peter Deutsch
6
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
Schorr-Waite algorithm
Alfred V. Aho, John E. Hopcroft, and Jeffrey Ullman
Data Structures and Algorithms (1st ed.)
Addison-Wesley (1983)
type 

	 atomtype = { some appropriate type; preferably of the same size as pointers } 

	 patterns = (PP, PA, AP, AA); 

	 celltype = record 

mark: boolean;

case pattern: patterns of 

	 PP: (left: ↑ celltype; right: ↑ celltype); 

	 PA: (left: ↑ celltype; right: atomtype); 

	 AP: (left: atomtype; right: ↑ celltype); 

	 AA: (left: atomtype; right: atomtype); 

end; 

var 

	 source: ↑ celltype;

	 memory: array [1..memorysize ] of celltype; 

procedure rotate ( var p1, p2, p3: ↑ celltype ); 

var 

	 temp: ↑ celltype; 

begin 

	 temp := p1; p1 := p2; p2 := p3; p3 := temp 

end; { rotate }

function blockleft ( cell: celltype ): boolean; 

{ test if left field is atom or null pointer } 

begin 

	 with cell do

	 	 if (pattern = PP) or (pattern = PA) then 

	 	 	 if left <> nil then return (false); 

	 return (true) 

end; { blockleft }



function blockright ( cell : celltype ): boolean; 

{ test if right field is atom or null pointer } 

begin

	 with cell do 

	 	 if (pattern = PP) or (pattern = AP) then 

	 	 	 if right <> nil then return (false); 

	 return (true) 

end; { blockright } 

...

...

...
...
7
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
ISMM 2017
Albert Mingkun Yang and Tobias Wrigstad 

Type-assisted automatic garbage collection for
lock-free data structures
ACM SIGPLAN International Symposium on
Memory Management (ISMM 2017)
struct cds_t {
int global_epoch;
int max_entry;
int size;
per_thread_t *threads;
};
struct per_thread_t {
int in_critical;
int local_epoch;
int entry;
wrapper_t limbo_list[3];
};
Figure 7. Central data structures for EBR implementation.
1. At allocation sites of spine objects, which are statically known
from their types, one allocation call was replaced with calloc()
(because Encore assumes memory is zeroed).
2. At the release point, a call to free() was used instead of
the ORCA API. Freeing the spine object immediately is safe
because of its guaranteed isolation inside the hot object.
3. The ACQUIRE was removed as there is no need for opaque
roots when the underlying memory manager is not automatic.
Previously, this was an increase of the foreign reference count
for each object moved into the Isolde heap.
4.1 Implementation Details
The C library contains three main public APIs. The function cri-
tical_enter() should be called before loading any fields in the
concurrent data structure (e.g., top in the Treiber Stack example)
into a local variable. The function critical_exit() should be
called when all pointers-on-stack-frame will not be used until the
next call of critical_enter(). In our implementation, those two
functions are placed at the entrance and the exit point of every
method of a hot class. It is possible that using static analysis, one
could find more precise boundary of the critical region.
void critical_enter(cds_t *this) // entering critical region
void critical_exit(cds_t *this) // exiting critical region
void defer_dec(void *node) // safe version of rc decrement
Full code for these functions is found in Figure 8 and the main
data structures in Figure 7. Each concurrent data structure holds
a cds_t object at run-time; max_entry is used to control the
frequency of updating global epoch counter, as we discussed in
previous section. size is set to be the max number of threads that
could interact with concurrent data structure, which is used to iterate
along the array referenced by threads. per_thread_t holds the
info each thread maintains; determining if this thread is in critical
region, local epoch, the number entrance into critical region, and a
limbo list for each epoch. The thread local variable thread_index
is used to store and retrieve thread-local EBR meta data. The details
how it is initialized are provided later. In the implementation of
critical_enter, we can see entry and max_entry is used to
amortize the cost across multiple entrance into critical region. An
extra level of indirection, wrapper_t, is used around spine objects
in defer_dec because an object could be added into multiple limbo
lists and even the same list multiple times. Notably, the original
EBR scheme [11] does not need this because it requires developers
to manually decide the unlinking point.
Helper Functions The helper functions update_global(), try-
_lock() and clean_list() are used internally by the functions
in the public API. They are shown in Figure 9. The function
update_global() limits the use of writes to the global epoch
counter in critical sections. In our implementation, we implement
1 void critical_enter(cds_t *this) {
2 per_thread_t *thread = &this.threads[thread_index];
3 while (true) {
4 thread.in_critical = 1;
5 int global_epoch = this.global_epoch;
6
7 if (thread->local_epoch != global_epoch) {
8 clean_list(&thread->limbo_list[global_epoch]);
9 thread->local_epoch = global_epoch;
10 thread->entry = 0;
11 }
12
13 if (thread->entry++ < this->max_entry) {
14 return;
15 }
16
17 thread->in_critical = 0;
18 thread->entry = 0;
19 update_global(this);
20 }
21 }
22
23 void critical_exit(cds_t *this) {
24 this->threads[thread_index].in_critical = 0;
25 }
26
27 void defer_dec(so_gc_t *so_gc, void *p) {
28 wrapper_t *w = new_wrapper();
29 w->p = p;
30 per_thread_t *thread =
31 &so_gc->threads[so_thread_index];
32 w->next = thread->limbo_list[thread->local_epoch];
33 thread->limbo_list[thread->local_epoch] = w;
34 }
Figure 8. Functions.
The function clean_list() iterates over all objects in a limbo
list, decrementing their reference counts, and reclaiming the objects
whose RC reaches zero. In our implementation, this amounts to
telling the actor on whose heap the object is allocated that the object
is no longer needed externally, through an asynchronous message
send. This allows the actor to free this memory during the next
garbage collection cycle after receipt of this message.
The body of the if-statement on Line 23 marks the moment when
a spine object becomes β€œeffectively” unreachable, and its finaliser
is called before the calling release API provided by the underlying
memory manager. (In our implementation this amounts to calling
a compiler-generated finaliser.) Switching the underlying memory
manager requires a change to this code, for example, in the case of
using malloc() and free(), this is a call to free().
4.2 Limitations
An inherent limitation of the epoch-based management of stack
pointers requires that the maximum number threads that can in-
teract with a concurrent data structure must be known when the
program starts. In the case of the Encore, this limitation is unprob-
lematic as Encore uses a fixed set of threads for an entire program
run which are fixed at the start of the program. On thread cre-
1 hot Stack[t]
2 spec top : Node[t]
3
4 def push(element:t) : t
5 βˆ’βˆ’ signaling into critical region
6 CRITICAL_ENTER(this);
7 βˆ’βˆ’ element managed by H
8 var new_top = new Node()
9 βˆ’βˆ’ RC(new_top) = 0, new_top owned by current thread
10 new_top.element = move_in element
11 ACQUIRE(element); NULLIFY(element);
12 βˆ’βˆ’ element managed by S
13 do
14 val old_top = this.top
15 βˆ’βˆ’ RC(old_top) = 1
16 new_top.next = old_top
17 INC_RC(old_top); DEFER_DEC_RC(new_top.next);
18 βˆ’βˆ’ RC(old_top) = 2
19 until CAT(this.top, new_top.next, new_top)
20 βˆ’βˆ’ Added to limbo list for deferred decrement
21 DEFER_DEC_RC(new_top.next);
22 INC_RC(new_top); NULLIFY(new_top);
23 βˆ’βˆ’ RC(new_top) = 1, new_top owned by stack object
24 βˆ’βˆ’ leaving critical region
25 CRITICAL_EXIT(this);
26 end
27
28 def pop() : t
29 CRITICAL_ENTER(this);
30 do
31 val old_top = this.top
32 βˆ’βˆ’ RC(old_top) = 1, old_top owned by stack object
33 βˆ’βˆ’ old_top.element managed by S
34 until CAT(this.top, old_top, old_top.next)
35 βˆ’βˆ’ Added to limbo list for deferred decrement
36 DEFER_DEC_RC(old_top);
37 var tmp = move_out old_top.element
38 ACQUIRE(element); NULLIFY(old_top.element)
39 βˆ’βˆ’ tmp managed by H
40 CRITICAL_EXIT(this);
41 return tmp
42 end
43 end
Figure 5. Complete example with GC instructions elaborated in.
they may be in a cycle. The Recycler [1] implements trial deletio
in the presence of mutators running concurrently.
Having described reference counts for references on the hea
we now describe our version of Fraser’s epoch-based reclamatio
scheme [11] for dealing with stack-based references efficiently.
3. An Epoch-Based Reclamation Primer
Reference counting is an intuitive technique: an object is live if an
only if its reference count is positive. A naive implementation cou
use a write barrier that increments and decrements RCs around a
pointer writes, regardless of whether the destination is on the stac
or on the heap. While likely inefficient, such an implementatio
is correct in a sequential case. In a concurrent setting, howev
before INC_RC(A) happens on reading a reference with RC=1
one thread, DEC_RC(A) could be happening concurrently in anoth
thread, causing A to be prematurely collected. As a result, th
reference count increase would be a write to a invalid memory.
The root cause of this problem is the race between loadin
the reference and incrementing the RC. Valois [23] solves th
problem by assuming type persistence, i.e., once a block of memo
is allocated for a type of objects, it could only be used for th
particular type. A late increment may still write to invalid memo
but it is guaranteed to be a slot reserved for RC only, and th
effect could be reverted back if revalidation fails (the object h
been collected). Detlefs et al. [8] show that this constraint ca
be removed using a double CAS, which is able to operate on tw
independent memory locations atomically. Sadly, no current CP
supports such an atomic primitive. Neither type-persistence n
double CAS constitutes a viable option in an automatic memo
management solution, but, fortunately, the data race on counte
can be avoided by applying RC to pointers on heap only. This h
been used before (see e.g., Deutsch & Bobrow [9]), but as a wa
of reducing the amount of RC manipulation due to local variable
While our motivation differs, we can reap the benefit of reduce
RC manipulation. Because RC attributed from pointers-on-stack
discarded, RC becomes imprecise. Deutsch & Bobrow [9], place a
object with RC = 0 in a Zero Count Table, and use stack scannin
to either restore to correct RC for still reachable objects or reclai
those surely dead ones. In the contrast, we use a modified versio
of Fraser’s epoch-based [11] reclamation (EBR) scheme, whic
addresses pointers on stack in a non-intrusive fashion.
Due to its low synchronization, EBR compares favourably
hazard pointers and reference counting according to [10], but to th
best of our knowledge, it has never been used in automatic GC.
EBR maintains a global epoch counter and a local epoch count
8
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
new
old root
S
root
rootnew
old
free
!
start
9
{ βˆ—old , new , new + 1 } β†’ { βˆ—new , S , free }
Cheney revisited (step 1)
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
new
old root
S
root
rootnew
old
free
!cell
start
9
{ βˆ—old , new , new + 1 } β†’ { βˆ—new , S , free }
Cheney revisited (step 1)
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
new
old root
S
root
rootnew
old
free
!cell pointer into memory
start
9
{ βˆ—old , new , new + 1 } β†’ { βˆ—new , S , free }
Cheney revisited (step 1)
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
scan pointer
new
old root
S
root
rootnew
old
free
!cell pointer into memory
start
9
{ βˆ—old , new , new + 1 } β†’ { βˆ—new , S , free }
Cheney revisited (step 1)
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
scan pointer
new
old root
S
root
rootnew
old
free
!cell pointer into memory
start
9
{ βˆ—old , new , new + 1 } β†’ { βˆ—new , S , free }
Cheney revisited (step 1)
free pointer
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
scan pointer
co-assign
new
old root
S
root
rootnew
old
free
!cell pointer into memory
start
9
{ βˆ—old , new , new + 1 } β†’ { βˆ—new , S , free }
Cheney revisited (step 1)
free pointer
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
{ S + 1 } β†’ { S }
(S < free ) ∧ (S↓ = 𝒢)
Cheney revisited (step 2)
atom
10
S
A
S
A
free free
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
{ S + 1 } β†’ { S }
(S < free ) ∧ (S↓ = 𝒢)
Cheney revisited (step 2)
atom
10
pointers = β„•

types	 = { 𝒢(tom), 𝓅(ointer), 𝒷(roken heart) }

cells	 = pointers Γ— types

S
A
S
A
free free
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
{ S + 1 } β†’ { S }
(S < free ) ∧ (S↓ = 𝒢)
Cheney revisited (step 2)
atom
10
pointers = β„•

types	 = { 𝒢(tom), 𝓅(ointer), 𝒷(roken heart) }

cells	 = pointers Γ— types

βˆ—: pointers ⟷ cells : p ⟷ [πœ‹, 𝜏]

↑: pointers ⟢ pointers : p ⟼ pβ†‘β‰‘βˆ—p πœ‹

↓: pointers ⟢ types : p ⟼ pβ†“β‰‘βˆ—p 𝜏
S
A
S
A
free free
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
{ S + 1 } β†’ { S }
(S < free ) ∧ (S↓ = 𝒢)
Cheney revisited (step 2)
atomA
atom
10
pointers = β„•

types	 = { 𝒢(tom), 𝓅(ointer), 𝒷(roken heart) }

cells	 = pointers Γ— types

βˆ—: pointers ⟷ cells : p ⟷ [πœ‹, 𝜏]

↑: pointers ⟢ pointers : p ⟼ pβ†‘β‰‘βˆ—p πœ‹

↓: pointers ⟢ types : p ⟼ pβ†“β‰‘βˆ—p 𝜏
S
A
S
A
free free
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
predicate
{ S + 1 } β†’ { S }
(S < free ) ∧ (S↓ = 𝒢)
Cheney revisited (step 2)
atomA
atom
10
pointers = β„•

types	 = { 𝒢(tom), 𝓅(ointer), 𝒷(roken heart) }

cells	 = pointers Γ— types

βˆ—: pointers ⟷ cells : p ⟷ [πœ‹, 𝜏]

↑: pointers ⟢ pointers : p ⟼ pβ†‘β‰‘βˆ—p πœ‹

↓: pointers ⟢ types : p ⟼ pβ†“β‰‘βˆ—p 𝜏
S
A
S
A
free free
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
{ βˆ—S↑ , [ βˆ… , 𝒷 ] , βˆ—(S↑ + 1) , [ free , 𝓅 ] , free + 2 , S + 1 } β†’ { βˆ—free , βˆ—S↑ , βˆ—(free + 1) , βˆ—(S↑ + 1) , free , S }
Cheney revisited (step 3)
unvisited
11
(S < free ) ∧ (S↓ = 𝓅) ∧ (S↑↓ β‰  𝒷)
S
car cdr
S
car cdr
!
free free
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
{ βˆ—S↑ , [ βˆ… , 𝒷 ] , βˆ—(S↑ + 1) , [ free , 𝓅 ] , free + 2 , S + 1 } β†’ { βˆ—free , βˆ—S↑ , βˆ—(free + 1) , βˆ—(S↑ + 1) , free , S }
Cheney revisited (step 3)
broken heart!
unvisited
11
(S < free ) ∧ (S↓ = 𝓅) ∧ (S↑↓ β‰  𝒷)
S
car cdr
S
car cdr
!
free free
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
{ βˆ—S↑ , [ βˆ… , 𝒷 ] , βˆ—(S↑ + 1) , [ free , 𝓅 ] , free + 2 , S + 1 } β†’ { βˆ—free , βˆ—S↑ , βˆ—(free + 1) , βˆ—(S↑ + 1) , free , S }
Cheney revisited (step 3)
broken heart!
a car cellcar
a cdr cellcdr
unvisited
11
(S < free ) ∧ (S↓ = 𝓅) ∧ (S↑↓ β‰  𝒷)
S
car cdr
S
car cdr
!
free free
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
{ βˆ—(S↑ + 1) , S + 1 } β†’ { βˆ—S , S }
(S < free ) ∧ (S↓ = 𝓅) ∧ (S↑↓ = 𝒷)
Cheney revisited (step 4)
visited
12
S S
! !
free free
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
{ new + 1 , old , new } β†’ { free , new , old }
S = free
Cheney revisited (step 5)
stop
13
root new
old
new
old
free
S
root
free
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
Cheney revisited (graph)
S↑↓ β‰  𝒷
Pointer to a
pointer not to a
broken heart
S = some
pointer
Pointer to a
pointer to a
broken heartS↑↓ = 𝒷Pointer to
an atom
S↓ = 𝒢
S + 1 β†’ S
βˆ—S↑ β†’ βˆ—free
[ βˆ… , 𝒷 ] β†’ βˆ—S↑
(S↑ + 1)↑ β†’ βˆ—(free + 1)
[ free , 𝓅 ] β†’ βˆ—(S↑ + 1)
free + 2 β†’ free
S + 1 β†’ S
(S↑ + 1)↑ β†’ S↑
S + 1 β†’ S
Pointer to
a pointer
S↓ = 𝓅
!
βˆ—old β†’ βˆ—new
new β†’ S
new + 1 β†’ free
"
S = free
All cells
updated
old β†’ new
new β†’ old
Pointer to a
pointer
S < free
14
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
Cheney revisited (code)
typedef struct CEL * ptr;
typedef enum {a, p, b} typ;
typedef struct CEL { ptr P; typ T; } cel;
static ptr free, new, old;
static void Cheney(void)
{ ptr S, S_;
*new = *old; // *new <- *old
S = new; // S <- new
for (free = new + 1; // free <- new + 1
S < free; // S < free
S += 1) // S <- S + 1
if (S->T == p) // Sv = p
{ S_ = S->P; // S^
if (S_->T != b) // S^v β‰  b
{ *free = *S_; // *free <- *S^
*S_ = (cel){ 0, b }; // *S^ <- [βˆ…, b]
*(free + 1) = *(S_ + 1); // *(free + 1) <- *(S^ + 1)
*(S_ + 1) = (cel){ free, p };// *(S^ + 1) <- [free, p]
free += 2; } // free <- free + 2
else // S^v = b
*S = *(S_ + 1); } // *S <- *(S^ + 1)
else; // Sv = a
free = new + 1; // free <- new + 1
S = old; // old
old = new; // old <- new
new = S; } // new <- old
15
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
Schorr-Waite revisited (step 1)
P P
C
root
memorymemory
!
start
16
{ βˆ… , memory } β†’ { P , C }
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
Schorr-Waite revisited (step 1)
P P
C
root
memorymemory
!
types = { 𝒢(tom), 𝓅(ointer) }
marks = { 𝓂(arked), π“Š(nmarked) }
cells = pointers Γ— types Γ— marks
βˆ—: pointers ⟷ cells : p ⟷ [πœ‹, 𝜏, πœ‡]
↑: pointers ⟢ pointers : p ⟼ p↑ β‰‘βˆ—p πœ‹
↓: pointers ⟢ types :p ⟼ p β‰‘βˆ—p 𝜏
⇣: pointers ⟢ marks : p ⟼ p⇣ β‰‘βˆ—p πœ‡
start
16
{ βˆ… , memory } β†’ { P , C }
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
Schorr-Waite revisited (step 1)
P P
C
root
memorymemory
!
types = { 𝒢(tom), 𝓅(ointer) }
marks = { 𝓂(arked), π“Š(nmarked) }
cells = pointers Γ— types Γ— marks
βˆ—: pointers ⟷ cells : p ⟷ [πœ‹, 𝜏, πœ‡]
↑: pointers ⟢ pointers : p ⟼ p↑ β‰‘βˆ—p πœ‹
↓: pointers ⟢ types :p ⟼ p β‰‘βˆ—p 𝜏
⇣: pointers ⟢ marks : p ⟼ p⇣ β‰‘βˆ—p πœ‡
start
16
{ βˆ… , memory } β†’ { P , C }
current pointer
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
Schorr-Waite revisited (step 1)
P P
C
root
memorymemory
!
types = { 𝒢(tom), 𝓅(ointer) }
marks = { 𝓂(arked), π“Š(nmarked) }
cells = pointers Γ— types Γ— marks
βˆ—: pointers ⟷ cells : p ⟷ [πœ‹, 𝜏, πœ‡]
↑: pointers ⟢ pointers : p ⟼ p↑ β‰‘βˆ—p πœ‹
↓: pointers ⟢ types :p ⟼ p β‰‘βˆ—p 𝜏
⇣: pointers ⟢ marks : p ⟼ p⇣ β‰‘βˆ—p πœ‡
start
16
{ βˆ… , memory } β†’ { P , C }
current pointer
previous pointer
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
Schorr-Waite revisited (step 2)
C C
A A
P
unvisitedatom
17
{ [P , 𝓅 , 𝓂] , C , C↑ } β†’ { βˆ—C , P , C }
(C⇣ = π“Š) ∧ (C↓ = 𝒢)
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
C
C
P
P
Schorr-Waite revisited (step 3)
unvisitedptr
18
{ [P , 𝓅 , 𝓂] , C , C↑ } β†’ { βˆ—C , P , C }
(C⇣ = π“Š) ∧ (C↓ = 𝓅)
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
Schorr-Waite revisited (step 4)
C C
P
visitedcar
19
{ C + 1 } β†’ { C }
(C⇣ = 𝓂) ∧ (P β‰  βˆ…) ∧ even?(C)
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
Schorr-Waite revisited (step 4)
C C
P
even pointer into memory
pointer into memory
odd pointer into memory
visitedcar
19
{ C + 1 } β†’ { C }
(C⇣ = 𝓂) ∧ (P β‰  βˆ…) ∧ even?(C)
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
P
C
P
C
Schorr-Waite revisited (step 5)
visitedcdr
20
{ [C – 1 , 𝓅 , 𝓂] , P , P↑ } β†’ { βˆ—P , C , P }
(C⇣ = 𝓂) ∧ (P β‰  βˆ…) ∧ odd?(C)
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
Schorr-Waite revisited (step 6)
stop
21
{ } β†’ { }
(C⇣ = 𝓂) ∧ (P = βˆ…)
P
C
!root
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
Schorr-Waite revisited (graph)
C↓ = 𝒢
Pointer to an
unmarked
atom
C = some
pointer
Pointer to an
unmarked
pointer
C↓ = 𝓅
Pointer to a
marked cell
C⇣ = 𝓂
even?(C)odd?(C)
Odd pointer to
a non-terminal
marked cell
[P , 𝓅 , 𝓂] β†’ βˆ—C
C β†’ P
C↑ β†’ C
C + 1 β†’ C
Pointer to an
unmarked
cell
C⇣ = π“Š
!
βˆ… β†’ P
memory β†’ C
"
Even pointer to
a non-terminal
marked cell
P β‰  βˆ…
𝓂 β†’ C⇣
P = βˆ…
Stop Pointer to a
non-terminal
marked cell
[C – 1 , 𝓅 , 𝓂] β†’ βˆ—P
P β†’ C
P↑ β†’ P
22
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
Schorr-Waite revisited (code)
typedef struct CEL * ptr;
typedef enum {a, p} typ;
typedef enum {m, u} mrk;
typedef struct CEL { ptr P; typ T; mrk M; } cel;
static unsigned is_even(ptr);
static void mark(ptr);
static const ptr null = (ptr)0;
static ptr memory;
static void Schorr_Waite(void)
{ ptr C, C_, P, P_;
P = null; // P <- null
for (C = memory;; ) // C <- memory
if (C->M == u) // Cw = u
if (C->P == a) // Cv = a
mark(C); // Cw = m
else // Cv = p
{ C_ = C->P; // C^
*C = (cel){ P, p, m }; // *C = [P, p, m]
P = C; // P <- C
C = C_; } // C <- C^
else // Cw = m
if (P != null) // P β‰  null
if (is_even(C)) // even?(C)
C = C + 1; // C <- C + 1
else // odd?(C)
{ P_ = P->P; // P^
*P = (cel){ C - 1, p, m };// *P = [C - 1, p, m]
C = P; // C <- P
P = P_; } // P <- P^
else // P = null
break; } // stop
23
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
Compacting mark-sweep
0 1 6 2 3 1 12 6 1 2 6 1 0
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
free root
15 1
0 14 9 2 2 1 2 13 1 8 3 7 0
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
free root
15 1
0 1 2 2 3 0 6 2 1 2 2 0 0
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
free root
15 1
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
free root
9 0
1 2 3 0 6 6 2 2 0 6
➠
➠
➠
H. B. M. Jonkers

A fast garbage compaction algorithm
Information Processing Letters, 9(1):25–30, July 1979
24
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
Compacting mark-sweep
typedef struct CEL * ptr;
typedef enum {a, m, u} flg;
typedef struct CEL { ptr P; flg F; } cel;
static ptr memory;
static unsigned is_raw(ptr), size(ptr);
static void mark_sweep(ptr root)
{ ptr C, C_, C__;
for (C = memory;;) // C <- memory
if (C->F == a) // Cv = a
C -= 1; // C = C - 1
else // Cv β‰  a
{ C_ = C->P; // C^
if (C->F == m) // Cv = m
if (C_ == memory) // C^ = memory
break; // stop
else // C^ β‰  memory
C = C_ - 1; // C <- C^ - 1
else // Cv = u
{ C__ = C_->P; // C^^
if (C_->F == m) // C^v = m
{ *C = *C__; // *C <- *C^^
*C__ = (cel){ C, m }; // *C__ <- [C, m]
C -= 1; } // C <- C - 1
else // C^v = u
{ *C = *C_; // *C <- *C^
*C_ = (cel){ C, m }; // *C_ <- [C, m]
if (is_raw(C__)) // raw?(C^^)
C -= 1; // C <- C - 1
else // regular?(C^^)
C = C_ + size(C__); }}}} // C <- C^ + size(C^^)
25
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
CMS + Schorr-Waite
C↓ = 𝒢
Pointer to
an atom
C = some
pointer
C↓ = π“Š
Pointer to an
unmarked
pointer
regular?(C↑↑)
Pointer to an
unmarked pointer to
a marked pointer
C↑↓ = 𝓂
βˆ—C↑↑ β†’ βˆ—C
[C, 𝓂] β†’ βˆ—C↑↑
C - 1 β†’ C
C↓ = 𝓂
Pointer to a
marked cell
C - 1 β†’ C
C↑ - 1 β†’ C
Pointer to an unmarked
pointer to an unmarked
raw header
raw?(C↑↑)
βˆ—C↑ β†’ βˆ—C
[C, 𝓂] β†’ C↑
C - 1 β†’ C
Pointer to an unmarked
pointer to an unmarked
regular header
!
[root, π“Š] β†’ βˆ—memory
memory β†’ C
" C↑= memory
Pointer to an
unmarked pointer to
an unmarked header
C↑↓ = π“Š
βˆ—C↑ β†’ βˆ—C
[C, 𝓂] β†’ C↑
C↑ + size(C↑↑) β†’ C
Pointer to a
marked non-
terminal pointer
C↑≠ memory
pair?(C↑)
[C - 1, 𝓅 , 𝓂] β†’ βˆ—P
P β†’ C
P↑ β†’ P
[C - 1, p, π“Š] β†’ βˆ—P
P - 1 β†’ C
P↑ β†’ P
βˆ—C↑↑ β†’ βˆ—C
[C, 𝓅 , 𝓂] β†’ βˆ—C↑↑
C - 1 β†’ C
[C↑↑, 𝒽, 𝓂] β†’ βˆ—C
[C, 𝓅, 𝓂] β†’ βˆ—C↑
chunk?(C)
C↕ = 𝒢 Chunk pointer to an
unmarked atom
Pointer to an
unmarked atom
pair?(C)
Pair pointer to an
unmarked atom
Some pointer
chunk?(C↑)
Pointer to an
unmarked
chunk pointer
Pointer to an unmarked
chunk pointer to an
unmarked regular header
regular?(C↑↑)
Pointer to an unmarked
chunk pointer to a
marked cell
C↑↓ = 𝓂
Chunk pointer to an
unmarked chunk pointer
to a marked header
chunk?(C)
Pair pointer to an
unmarked chunk pointer
to a marked header
pair?(C)
Pointer to an
unmarked pair
pointer
Pointer to a
marked cell
C↓ = 𝓂
Pointer to a
marked chunk
chunk?(C)
Chunk pointer to a
marked chunk with a
chunk thread
chunk?(C↑)
Chunk pointer to a
marked chunk with
pair thread
pair?(C↑)
Even pair pointer
to a marked cell
even?(C)
Odd pair pointer
to a marked cellodd?(C)
Odd pair pointer to a
marked cell with
chunk thread
Odd pair pointer to
a marked cell with
pair thread
pair?(P)
chunk?(P)
Pointer to an
unmarked cell
C↓ = π“Š
C - 1 β†’ C
𝓂 β†’ C↓
Pointer to an unmarked
chunk pointer to an
unmarked raw header
raw?(C↑↑)
Pair pointer to an unmarked
chunk pointer to an
unmarked raw header
Chunk pointer to an
unmarked chunk pointer to
an unmarked raw header
chunk?(C)
[C↑↑, 𝒽, 𝓂] β†’ βˆ—C
[C, 𝓅, 𝓂] β†’ βˆ—C↑
C - 1 β†’ C
[[C↑↑, 𝒽, 𝓂] β†’ βˆ—C
[C, 𝓅, 𝓂] β†’ βˆ—C↑
C↑ + size(C↑↑) β†’ C
pair?(C)
βˆ—C↑↑ β†’ βˆ—C
[C, 𝓅 , 𝓂] β†’ βˆ—C↑↑
[P, 𝓅, 𝓂] β†’ βˆ—C
C β†’ P
C↑ β†’ C
C↑ - 1 β†’ C
C↑ β†’ C C + 1 β†’ C
βˆ… β†’ P
memory β†’ C
!
Pointer to an unmarked
chunk pointer to an
unmarked cell
C↑↓ = π“Š
C↑ = memory"
Pointer to a non-
terminal marked cell
C↑ β‰  memory Pair pointer to a
marked cell
pair?(C)
Pointer to an
unmarked pointer
C↕ = 𝓅
C↓ = 𝒢
Pointer to an
unmarked
atom
C = some
pointer
Pointer to an
unmarked
pointer
C↓ = 𝓅
Pointer to a
marked cell
C⇣ = 𝓂
even?(C)odd?(C)
Odd pointer to
a non-terminal
marked cell
[P , 𝓅 , 𝓂] β†’ βˆ—C
C β†’ P
C↑ β†’ C
C + 1 β†’ C
Pointer to an
unmarked
cell
C⇣ = π“Š
!
βˆ… β†’ P
memory β†’ C
"
Even pointer to
a non-terminal
marked cell
P β‰  βˆ…
𝓂 β†’ C⇣
P = βˆ…
Stop Pointer to a
non-terminal
marked cell
[C – 1 , 𝓅 , 𝓂] β†’ βˆ—P
P β†’ C
P↑ β†’ P
➠
➠
application#1
26
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
CMS + Schorr-Waite
C↓ = 𝒢
Pointer to
an atom
C = some
pointer
C↓ = π“Š
Pointer to an
unmarked
pointer
regular?(C↑↑)
Pointer to an
unmarked pointer to
a marked pointer
C↑↓ = 𝓂
βˆ—C↑↑ β†’ βˆ—C
[C, 𝓂] β†’ βˆ—C↑↑
C - 1 β†’ C
C↓ = 𝓂
Pointer to a
marked cell
C - 1 β†’ C
C↑ - 1 β†’ C
Pointer to an unmarked
pointer to an unmarked
raw header
raw?(C↑↑)
βˆ—C↑ β†’ βˆ—C
[C, 𝓂] β†’ C↑
C - 1 β†’ C
Pointer to an unmarked
pointer to an unmarked
regular header
!
[root, π“Š] β†’ βˆ—memory
memory β†’ C
" C↑= memory
Pointer to an
unmarked pointer to
an unmarked header
C↑↓ = π“Š
βˆ—C↑ β†’ βˆ—C
[C, 𝓂] β†’ C↑
C↑ + size(C↑↑) β†’ C
Pointer to a
marked non-
terminal pointer
C↑≠ memory
pair?(C↑)
[C - 1, 𝓅 , 𝓂] β†’ βˆ—P
P β†’ C
P↑ β†’ P
[C - 1, p, π“Š] β†’ βˆ—P
P - 1 β†’ C
P↑ β†’ P
βˆ—C↑↑ β†’ βˆ—C
[C, 𝓅 , 𝓂] β†’ βˆ—C↑↑
C - 1 β†’ C
[C↑↑, 𝒽, 𝓂] β†’ βˆ—C
[C, 𝓅, 𝓂] β†’ βˆ—C↑
chunk?(C)
C↕ = 𝒢 Chunk pointer to an
unmarked atom
Pointer to an
unmarked atom
pair?(C)
Pair pointer to an
unmarked atom
Some pointer
chunk?(C↑)
Pointer to an
unmarked
chunk pointer
Pointer to an unmarked
chunk pointer to an
unmarked regular header
regular?(C↑↑)
Pointer to an unmarked
chunk pointer to a
marked cell
C↑↓ = 𝓂
Chunk pointer to an
unmarked chunk pointer
to a marked header
chunk?(C)
Pair pointer to an
unmarked chunk pointer
to a marked header
pair?(C)
Pointer to an
unmarked pair
pointer
Pointer to a
marked cell
C↓ = 𝓂
Pointer to a
marked chunk
chunk?(C)
Chunk pointer to a
marked chunk with a
chunk thread
chunk?(C↑)
Chunk pointer to a
marked chunk with
pair thread
pair?(C↑)
Even pair pointer
to a marked cell
even?(C)
Odd pair pointer
to a marked cellodd?(C)
Odd pair pointer to a
marked cell with
chunk thread
Odd pair pointer to
a marked cell with
pair thread
pair?(P)
chunk?(P)
Pointer to an
unmarked cell
C↓ = π“Š
C - 1 β†’ C
𝓂 β†’ C↓
Pointer to an unmarked
chunk pointer to an
unmarked raw header
raw?(C↑↑)
Pair pointer to an unmarked
chunk pointer to an
unmarked raw header
Chunk pointer to an
unmarked chunk pointer to
an unmarked raw header
chunk?(C)
[C↑↑, 𝒽, 𝓂] β†’ βˆ—C
[C, 𝓅, 𝓂] β†’ βˆ—C↑
C - 1 β†’ C
[[C↑↑, 𝒽, 𝓂] β†’ βˆ—C
[C, 𝓅, 𝓂] β†’ βˆ—C↑
C↑ + size(C↑↑) β†’ C
pair?(C)
βˆ—C↑↑ β†’ βˆ—C
[C, 𝓅 , 𝓂] β†’ βˆ—C↑↑
[P, 𝓅, 𝓂] β†’ βˆ—C
C β†’ P
C↑ β†’ C
C↑ - 1 β†’ C
C↑ β†’ C C + 1 β†’ C
βˆ… β†’ P
memory β†’ C
!
Pointer to an unmarked
chunk pointer to an
unmarked cell
C↑↓ = π“Š
C↑ = memory"
Pointer to a non-
terminal marked cell
C↑ β‰  memory Pair pointer to a
marked cell
pair?(C)
Pointer to an
unmarked pointer
C↕ = 𝓅
C↓ = 𝒢
Pointer to an
unmarked
atom
C = some
pointer
Pointer to an
unmarked
pointer
C↓ = 𝓅
Pointer to a
marked cell
C⇣ = 𝓂
even?(C)odd?(C)
Odd pointer to
a non-terminal
marked cell
[P , 𝓅 , 𝓂] β†’ βˆ—C
C β†’ P
C↑ β†’ C
C + 1 β†’ C
Pointer to an
unmarked
cell
C⇣ = π“Š
!
βˆ… β†’ P
memory β†’ C
"
Even pointer to
a non-terminal
marked cell
P β‰  βˆ…
𝓂 β†’ C⇣
P = βˆ…
Stop Pointer to a
non-terminal
marked cell
[C – 1 , 𝓅 , 𝓂] β†’ βˆ—P
P β†’ C
P↑ β†’ P
➠
➠
Why?
application#1
26
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
CMS + Schorr-Waite
C↓ = 𝒢
Pointer to
an atom
C = some
pointer
C↓ = π“Š
Pointer to an
unmarked
pointer
regular?(C↑↑)
Pointer to an
unmarked pointer to
a marked pointer
C↑↓ = 𝓂
βˆ—C↑↑ β†’ βˆ—C
[C, 𝓂] β†’ βˆ—C↑↑
C - 1 β†’ C
C↓ = 𝓂
Pointer to a
marked cell
C - 1 β†’ C
C↑ - 1 β†’ C
Pointer to an unmarked
pointer to an unmarked
raw header
raw?(C↑↑)
βˆ—C↑ β†’ βˆ—C
[C, 𝓂] β†’ C↑
C - 1 β†’ C
Pointer to an unmarked
pointer to an unmarked
regular header
!
[root, π“Š] β†’ βˆ—memory
memory β†’ C
" C↑= memory
Pointer to an
unmarked pointer to
an unmarked header
C↑↓ = π“Š
βˆ—C↑ β†’ βˆ—C
[C, 𝓂] β†’ C↑
C↑ + size(C↑↑) β†’ C
Pointer to a
marked non-
terminal pointer
C↑≠ memory
pair?(C↑)
[C - 1, 𝓅 , 𝓂] β†’ βˆ—P
P β†’ C
P↑ β†’ P
[C - 1, p, π“Š] β†’ βˆ—P
P - 1 β†’ C
P↑ β†’ P
βˆ—C↑↑ β†’ βˆ—C
[C, 𝓅 , 𝓂] β†’ βˆ—C↑↑
C - 1 β†’ C
[C↑↑, 𝒽, 𝓂] β†’ βˆ—C
[C, 𝓅, 𝓂] β†’ βˆ—C↑
chunk?(C)
C↕ = 𝒢 Chunk pointer to an
unmarked atom
Pointer to an
unmarked atom
pair?(C)
Pair pointer to an
unmarked atom
Some pointer
chunk?(C↑)
Pointer to an
unmarked
chunk pointer
Pointer to an unmarked
chunk pointer to an
unmarked regular header
regular?(C↑↑)
Pointer to an unmarked
chunk pointer to a
marked cell
C↑↓ = 𝓂
Chunk pointer to an
unmarked chunk pointer
to a marked header
chunk?(C)
Pair pointer to an
unmarked chunk pointer
to a marked header
pair?(C)
Pointer to an
unmarked pair
pointer
Pointer to a
marked cell
C↓ = 𝓂
Pointer to a
marked chunk
chunk?(C)
Chunk pointer to a
marked chunk with a
chunk thread
chunk?(C↑)
Chunk pointer to a
marked chunk with
pair thread
pair?(C↑)
Even pair pointer
to a marked cell
even?(C)
Odd pair pointer
to a marked cellodd?(C)
Odd pair pointer to a
marked cell with
chunk thread
Odd pair pointer to
a marked cell with
pair thread
pair?(P)
chunk?(P)
Pointer to an
unmarked cell
C↓ = π“Š
C - 1 β†’ C
𝓂 β†’ C↓
Pointer to an unmarked
chunk pointer to an
unmarked raw header
raw?(C↑↑)
Pair pointer to an unmarked
chunk pointer to an
unmarked raw header
Chunk pointer to an
unmarked chunk pointer to
an unmarked raw header
chunk?(C)
[C↑↑, 𝒽, 𝓂] β†’ βˆ—C
[C, 𝓅, 𝓂] β†’ βˆ—C↑
C - 1 β†’ C
[[C↑↑, 𝒽, 𝓂] β†’ βˆ—C
[C, 𝓅, 𝓂] β†’ βˆ—C↑
C↑ + size(C↑↑) β†’ C
pair?(C)
βˆ—C↑↑ β†’ βˆ—C
[C, 𝓅 , 𝓂] β†’ βˆ—C↑↑
[P, 𝓅, 𝓂] β†’ βˆ—C
C β†’ P
C↑ β†’ C
C↑ - 1 β†’ C
C↑ β†’ C C + 1 β†’ C
βˆ… β†’ P
memory β†’ C
!
Pointer to an unmarked
chunk pointer to an
unmarked cell
C↑↓ = π“Š
C↑ = memory"
Pointer to a non-
terminal marked cell
C↑ β‰  memory Pair pointer to a
marked cell
pair?(C)
Pointer to an
unmarked pointer
C↕ = 𝓅
C↓ = 𝒢
Pointer to an
unmarked
atom
C = some
pointer
Pointer to an
unmarked
pointer
C↓ = 𝓅
Pointer to a
marked cell
C⇣ = 𝓂
even?(C)odd?(C)
Odd pointer to
a non-terminal
marked cell
[P , 𝓅 , 𝓂] β†’ βˆ—C
C β†’ P
C↑ β†’ C
C + 1 β†’ C
Pointer to an
unmarked
cell
C⇣ = π“Š
!
βˆ… β†’ P
memory β†’ C
"
Even pointer to
a non-terminal
marked cell
P β‰  βˆ…
𝓂 β†’ C⇣
P = βˆ…
Stop Pointer to a
non-terminal
marked cell
[C – 1 , 𝓅 , 𝓂] β†’ βˆ—P
P β†’ C
P↑ β†’ P
➠
➠
Why?
save storage on pairs
application#1
26
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
CMS + Schorr-Waite
C↓ = 𝒢
Pointer to
an atom
C = some
pointer
C↓ = π“Š
Pointer to an
unmarked
pointer
regular?(C↑↑)
Pointer to an
unmarked pointer to
a marked pointer
C↑↓ = 𝓂
βˆ—C↑↑ β†’ βˆ—C
[C, 𝓂] β†’ βˆ—C↑↑
C - 1 β†’ C
C↓ = 𝓂
Pointer to a
marked cell
C - 1 β†’ C
C↑ - 1 β†’ C
Pointer to an unmarked
pointer to an unmarked
raw header
raw?(C↑↑)
βˆ—C↑ β†’ βˆ—C
[C, 𝓂] β†’ C↑
C - 1 β†’ C
Pointer to an unmarked
pointer to an unmarked
regular header
!
[root, π“Š] β†’ βˆ—memory
memory β†’ C
" C↑= memory
Pointer to an
unmarked pointer to
an unmarked header
C↑↓ = π“Š
βˆ—C↑ β†’ βˆ—C
[C, 𝓂] β†’ C↑
C↑ + size(C↑↑) β†’ C
Pointer to a
marked non-
terminal pointer
C↑≠ memory
pair?(C↑)
[C - 1, 𝓅 , 𝓂] β†’ βˆ—P
P β†’ C
P↑ β†’ P
[C - 1, p, π“Š] β†’ βˆ—P
P - 1 β†’ C
P↑ β†’ P
βˆ—C↑↑ β†’ βˆ—C
[C, 𝓅 , 𝓂] β†’ βˆ—C↑↑
C - 1 β†’ C
[C↑↑, 𝒽, 𝓂] β†’ βˆ—C
[C, 𝓅, 𝓂] β†’ βˆ—C↑
chunk?(C)
C↕ = 𝒢 Chunk pointer to an
unmarked atom
Pointer to an
unmarked atom
pair?(C)
Pair pointer to an
unmarked atom
Some pointer
chunk?(C↑)
Pointer to an
unmarked
chunk pointer
Pointer to an unmarked
chunk pointer to an
unmarked regular header
regular?(C↑↑)
Pointer to an unmarked
chunk pointer to a
marked cell
C↑↓ = 𝓂
Chunk pointer to an
unmarked chunk pointer
to a marked header
chunk?(C)
Pair pointer to an
unmarked chunk pointer
to a marked header
pair?(C)
Pointer to an
unmarked pair
pointer
Pointer to a
marked cell
C↓ = 𝓂
Pointer to a
marked chunk
chunk?(C)
Chunk pointer to a
marked chunk with a
chunk thread
chunk?(C↑)
Chunk pointer to a
marked chunk with
pair thread
pair?(C↑)
Even pair pointer
to a marked cell
even?(C)
Odd pair pointer
to a marked cellodd?(C)
Odd pair pointer to a
marked cell with
chunk thread
Odd pair pointer to
a marked cell with
pair thread
pair?(P)
chunk?(P)
Pointer to an
unmarked cell
C↓ = π“Š
C - 1 β†’ C
𝓂 β†’ C↓
Pointer to an unmarked
chunk pointer to an
unmarked raw header
raw?(C↑↑)
Pair pointer to an unmarked
chunk pointer to an
unmarked raw header
Chunk pointer to an
unmarked chunk pointer to
an unmarked raw header
chunk?(C)
[C↑↑, 𝒽, 𝓂] β†’ βˆ—C
[C, 𝓅, 𝓂] β†’ βˆ—C↑
C - 1 β†’ C
[[C↑↑, 𝒽, 𝓂] β†’ βˆ—C
[C, 𝓅, 𝓂] β†’ βˆ—C↑
C↑ + size(C↑↑) β†’ C
pair?(C)
βˆ—C↑↑ β†’ βˆ—C
[C, 𝓅 , 𝓂] β†’ βˆ—C↑↑
[P, 𝓅, 𝓂] β†’ βˆ—C
C β†’ P
C↑ β†’ C
C↑ - 1 β†’ C
C↑ β†’ C C + 1 β†’ C
βˆ… β†’ P
memory β†’ C
!
Pointer to an unmarked
chunk pointer to an
unmarked cell
C↑↓ = π“Š
C↑ = memory"
Pointer to a non-
terminal marked cell
C↑ β‰  memory Pair pointer to a
marked cell
pair?(C)
Pointer to an
unmarked pointer
C↕ = 𝓅
C↓ = 𝒢
Pointer to an
unmarked
atom
C = some
pointer
Pointer to an
unmarked
pointer
C↓ = 𝓅
Pointer to a
marked cell
C⇣ = 𝓂
even?(C)odd?(C)
Odd pointer to
a non-terminal
marked cell
[P , 𝓅 , 𝓂] β†’ βˆ—C
C β†’ P
C↑ β†’ C
C + 1 β†’ C
Pointer to an
unmarked
cell
C⇣ = π“Š
!
βˆ… β†’ P
memory β†’ C
"
Even pointer to
a non-terminal
marked cell
P β‰  βˆ…
𝓂 β†’ C⇣
P = βˆ…
Stop Pointer to a
non-terminal
marked cell
[C – 1 , 𝓅 , 𝓂] β†’ βˆ—P
P β†’ C
P↑ β†’ P
➠
➠
Why?
save storage on pairs
fixed data
far references
application#1
26
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
C↓ = 𝒢
Pointer to
an atom
C = some
pointer
C↓ = π“Š
Pointer to an
unmarked
pointer
regular?(C↑↑)
Pointer to an
unmarked pointer to
a marked pointer
C↑↓ = 𝓂
βˆ—C↑↑ β†’ βˆ—C
[C, 𝓂] β†’ βˆ—C↑↑
C - 1 β†’ C
C↓ = 𝓂
Pointer to a
marked cell
C - 1 β†’ C
C↑ - 1 β†’ C
Pointer to an unmarked
pointer to an unmarked
raw header
raw?(C↑↑)
βˆ—C↑ β†’ βˆ—C
[C, 𝓂] β†’ C↑
C - 1 β†’ C
Pointer to an unmarked
pointer to an unmarked
regular header
!
[root, π“Š] β†’ βˆ—memory
memory β†’ C
" C↑= memory
Pointer to an
unmarked pointer to
an unmarked header
C↑↓ = π“Š
βˆ—C↑ β†’ βˆ—C
[C, 𝓂] β†’ C↑
C↑ + size(C↑↑) β†’ C
Pointer to a
marked non-
terminal pointer
C↑≠ memory
C↓ = 𝒢
Pointer to an
unmarked
atom
C = some
pointer
Pointer to an
unmarked
pointer
C↓ = 𝓅
Pointer to a
marked cell
C⇣ = 𝓂
even?(C)odd?(C)
Odd pointer to
a non-terminal
marked cell
[P , 𝓅 , 𝓂] β†’ βˆ—C
C β†’ P
C↑ β†’ C
C + 1 β†’ C
Pointer to an
unmarked
cell
C⇣ = π“Š
!
βˆ… β†’ P
memory β†’ C
"
Even pointer to
a non-terminal
marked cell
P β‰  βˆ…
𝓂 β†’ C⇣
P = βˆ…
Stop Pointer to a
non-terminal
marked cell
[C – 1 , 𝓅 , 𝓂] β†’ βˆ—P
P β†’ C
P↑ β†’ P
CMS + Schorr-Waite
pair?(C↑)
[C - 1, 𝓅 , 𝓂] β†’ βˆ—P
P β†’ C
P↑ β†’ P
[C - 1, p, π“Š] β†’ βˆ—P
P - 1 β†’ C
P↑ β†’ P
βˆ—C↑↑ β†’ βˆ—C
[C, 𝓅 , 𝓂] β†’ βˆ—C↑↑
C - 1 β†’ C
[C↑↑, 𝒽, 𝓂] β†’ βˆ—C
[C, 𝓅, 𝓂] β†’ βˆ—C↑
chunk?(C)
C↕ = 𝒢 Chunk pointer to an
unmarked atom
Pointer to an
unmarked atom
pair?(C)
Pair pointer to an
unmarked atom
Some pointer
chunk?(C↑)
Pointer to an
unmarked
chunk pointer
Pointer to an unmarked
chunk pointer to an
unmarked regular header
regular?(C↑↑)
Pointer to an unmarked
chunk pointer to a
marked cell
C↑↓ = 𝓂
Chunk pointer to an
unmarked chunk pointer
to a marked header
chunk?(C)
Pair pointer to an
unmarked chunk pointer
to a marked header
pair?(C)
Pointer to an
unmarked pair
pointer
Pointer to a
marked cell
C↓ = 𝓂
Pointer to a
marked chunk
chunk?(C)
Chunk pointer to a
marked chunk with a
chunk thread
chunk?(C↑)
Chunk pointer to a
marked chunk with
pair thread
pair?(C↑)
Even pair pointer
to a marked cell
even?(C)
Odd pair pointer
to a marked cellodd?(C)
Odd pair pointer to a
marked cell with
chunk thread
Odd pair pointer to
a marked cell with
pair thread
pair?(P)
chunk?(P)
Pointer to an
unmarked cell
C↓ = π“Š
C - 1 β†’ C
𝓂 β†’ C↓
Pointer to an unmarked
chunk pointer to an
unmarked raw header
raw?(C↑↑)
Pair pointer to an unmarked
chunk pointer to an
unmarked raw header
Chunk pointer to an
unmarked chunk pointer to
an unmarked raw header
chunk?(C)
[C↑↑, 𝒽, 𝓂] β†’ βˆ—C
[C, 𝓅, 𝓂] β†’ βˆ—C↑
C - 1 β†’ C
[[C↑↑, 𝒽, 𝓂] β†’ βˆ—C
[C, 𝓅, 𝓂] β†’ βˆ—C↑
C↑ + size(C↑↑) β†’ C
pair?(C)
βˆ—C↑↑ β†’ βˆ—C
[C, 𝓅 , 𝓂] β†’ βˆ—C↑↑
[P, 𝓅, 𝓂] β†’ βˆ—C
C β†’ P
C↑ β†’ C
C↑ - 1 β†’ C
C↑ β†’ C C + 1 β†’ C
βˆ… β†’ P
memory β†’ C
!
Pointer to an unmarked
chunk pointer to an
unmarked cell
C↑↓ = π“Š
C↑ = memory"
Pointer to a non-
terminal marked cell
C↑ β‰  memory Pair pointer to a
marked cell
pair?(C)
Pointer to an
unmarked pointer
C↕ = 𝓅
➠
➠
27
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
C↓ = 𝒢
Pointer to
an atom
C = some
pointer
C↓ = π“Š
Pointer to an
unmarked
pointer
regular?(C↑↑)
Pointer to an
unmarked pointer to
a marked pointer
C↑↓ = 𝓂
βˆ—C↑↑ β†’ βˆ—C
[C, 𝓂] β†’ βˆ—C↑↑
C - 1 β†’ C
C↓ = 𝓂
Pointer to a
marked cell
C - 1 β†’ C
C↑ - 1 β†’ C
Pointer to an unmarked
pointer to an unmarked
raw header
raw?(C↑↑)
βˆ—C↑ β†’ βˆ—C
[C, 𝓂] β†’ C↑
C - 1 β†’ C
Pointer to an unmarked
pointer to an unmarked
regular header
!
[root, π“Š] β†’ βˆ—memory
memory β†’ C
" C↑= memory
Pointer to an
unmarked pointer to
an unmarked header
C↑↓ = π“Š
βˆ—C↑ β†’ βˆ—C
[C, 𝓂] β†’ C↑
C↑ + size(C↑↑) β†’ C
Pointer to a
marked non-
terminal pointer
C↑≠ memory
C↓ = 𝒢
Pointer to an
unmarked
atom
C = some
pointer
Pointer to an
unmarked
pointer
C↓ = 𝓅
Pointer to a
marked cell
C⇣ = 𝓂
even?(C)odd?(C)
Odd pointer to
a non-terminal
marked cell
[P , 𝓅 , 𝓂] β†’ βˆ—C
C β†’ P
C↑ β†’ C
C + 1 β†’ C
Pointer to an
unmarked
cell
C⇣ = π“Š
!
βˆ… β†’ P
memory β†’ C
"
Even pointer to
a non-terminal
marked cell
P β‰  βˆ…
𝓂 β†’ C⇣
P = βˆ…
Stop Pointer to a
non-terminal
marked cell
[C – 1 , 𝓅 , 𝓂] β†’ βˆ—P
P β†’ C
P↑ β†’ P
CMS + Schorr-Waite
pair?(C↑)
[C - 1, 𝓅 , 𝓂] β†’ βˆ—P
P β†’ C
P↑ β†’ P
[C - 1, p, π“Š] β†’ βˆ—P
P - 1 β†’ C
P↑ β†’ P
βˆ—C↑↑ β†’ βˆ—C
[C, 𝓅 , 𝓂] β†’ βˆ—C↑↑
C - 1 β†’ C
[C↑↑, 𝒽, 𝓂] β†’ βˆ—C
[C, 𝓅, 𝓂] β†’ βˆ—C↑
chunk?(C)
C↕ = 𝒢 Chunk pointer to an
unmarked atom
Pointer to an
unmarked atom
pair?(C)
Pair pointer to an
unmarked atom
Some pointer
chunk?(C↑)
Pointer to an
unmarked
chunk pointer
Pointer to an unmarked
chunk pointer to an
unmarked regular header
regular?(C↑↑)
Pointer to an unmarked
chunk pointer to a
marked cell
C↑↓ = 𝓂
Chunk pointer to an
unmarked chunk pointer
to a marked header
chunk?(C)
Pair pointer to an
unmarked chunk pointer
to a marked header
pair?(C)
Pointer to an
unmarked pair
pointer
Pointer to a
marked cell
C↓ = 𝓂
Pointer to a
marked chunk
chunk?(C)
Chunk pointer to a
marked chunk with a
chunk thread
chunk?(C↑)
Chunk pointer to a
marked chunk with
pair thread
pair?(C↑)
Even pair pointer
to a marked cell
even?(C)
Odd pair pointer
to a marked cellodd?(C)
Odd pair pointer to a
marked cell with
chunk thread
Odd pair pointer to
a marked cell with
pair thread
pair?(P)
chunk?(P)
Pointer to an
unmarked cell
C↓ = π“Š
C - 1 β†’ C
𝓂 β†’ C↓
Pointer to an unmarked
chunk pointer to an
unmarked raw header
raw?(C↑↑)
Pair pointer to an unmarked
chunk pointer to an
unmarked raw header
Chunk pointer to an
unmarked chunk pointer to
an unmarked raw header
chunk?(C)
[C↑↑, 𝒽, 𝓂] β†’ βˆ—C
[C, 𝓅, 𝓂] β†’ βˆ—C↑
C - 1 β†’ C
[[C↑↑, 𝒽, 𝓂] β†’ βˆ—C
[C, 𝓅, 𝓂] β†’ βˆ—C↑
C↑ + size(C↑↑) β†’ C
pair?(C)
βˆ—C↑↑ β†’ βˆ—C
[C, 𝓅 , 𝓂] β†’ βˆ—C↑↑
[P, 𝓅, 𝓂] β†’ βˆ—C
C β†’ P
C↑ β†’ C
C↑ - 1 β†’ C
C↑ β†’ C C + 1 β†’ C
βˆ… β†’ P
memory β†’ C
!
Pointer to an unmarked
chunk pointer to an
unmarked cell
C↑↓ = π“Š
C↑ = memory"
Pointer to a non-
terminal marked cell
C↑ β‰  memory Pair pointer to a
marked cell
pair?(C)
Pointer to an
unmarked pointer
C↕ = 𝓅
➠
➠
7 transitions
27
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
C↓ = 𝒢
Pointer to
an atom
C = some
pointer
C↓ = π“Š
Pointer to an
unmarked
pointer
regular?(C↑↑)
Pointer to an
unmarked pointer to
a marked pointer
C↑↓ = 𝓂
βˆ—C↑↑ β†’ βˆ—C
[C, 𝓂] β†’ βˆ—C↑↑
C - 1 β†’ C
C↓ = 𝓂
Pointer to a
marked cell
C - 1 β†’ C
C↑ - 1 β†’ C
Pointer to an unmarked
pointer to an unmarked
raw header
raw?(C↑↑)
βˆ—C↑ β†’ βˆ—C
[C, 𝓂] β†’ C↑
C - 1 β†’ C
Pointer to an unmarked
pointer to an unmarked
regular header
!
[root, π“Š] β†’ βˆ—memory
memory β†’ C
" C↑= memory
Pointer to an
unmarked pointer to
an unmarked header
C↑↓ = π“Š
βˆ—C↑ β†’ βˆ—C
[C, 𝓂] β†’ C↑
C↑ + size(C↑↑) β†’ C
Pointer to a
marked non-
terminal pointer
C↑≠ memory
C↓ = 𝒢
Pointer to an
unmarked
atom
C = some
pointer
Pointer to an
unmarked
pointer
C↓ = 𝓅
Pointer to a
marked cell
C⇣ = 𝓂
even?(C)odd?(C)
Odd pointer to
a non-terminal
marked cell
[P , 𝓅 , 𝓂] β†’ βˆ—C
C β†’ P
C↑ β†’ C
C + 1 β†’ C
Pointer to an
unmarked
cell
C⇣ = π“Š
!
βˆ… β†’ P
memory β†’ C
"
Even pointer to
a non-terminal
marked cell
P β‰  βˆ…
𝓂 β†’ C⇣
P = βˆ…
Stop Pointer to a
non-terminal
marked cell
[C – 1 , 𝓅 , 𝓂] β†’ βˆ—P
P β†’ C
P↑ β†’ P
CMS + Schorr-Waite
pair?(C↑)
[C - 1, 𝓅 , 𝓂] β†’ βˆ—P
P β†’ C
P↑ β†’ P
[C - 1, p, π“Š] β†’ βˆ—P
P - 1 β†’ C
P↑ β†’ P
βˆ—C↑↑ β†’ βˆ—C
[C, 𝓅 , 𝓂] β†’ βˆ—C↑↑
C - 1 β†’ C
[C↑↑, 𝒽, 𝓂] β†’ βˆ—C
[C, 𝓅, 𝓂] β†’ βˆ—C↑
chunk?(C)
C↕ = 𝒢 Chunk pointer to an
unmarked atom
Pointer to an
unmarked atom
pair?(C)
Pair pointer to an
unmarked atom
Some pointer
chunk?(C↑)
Pointer to an
unmarked
chunk pointer
Pointer to an unmarked
chunk pointer to an
unmarked regular header
regular?(C↑↑)
Pointer to an unmarked
chunk pointer to a
marked cell
C↑↓ = 𝓂
Chunk pointer to an
unmarked chunk pointer
to a marked header
chunk?(C)
Pair pointer to an
unmarked chunk pointer
to a marked header
pair?(C)
Pointer to an
unmarked pair
pointer
Pointer to a
marked cell
C↓ = 𝓂
Pointer to a
marked chunk
chunk?(C)
Chunk pointer to a
marked chunk with a
chunk thread
chunk?(C↑)
Chunk pointer to a
marked chunk with
pair thread
pair?(C↑)
Even pair pointer
to a marked cell
even?(C)
Odd pair pointer
to a marked cellodd?(C)
Odd pair pointer to a
marked cell with
chunk thread
Odd pair pointer to
a marked cell with
pair thread
pair?(P)
chunk?(P)
Pointer to an
unmarked cell
C↓ = π“Š
C - 1 β†’ C
𝓂 β†’ C↓
Pointer to an unmarked
chunk pointer to an
unmarked raw header
raw?(C↑↑)
Pair pointer to an unmarked
chunk pointer to an
unmarked raw header
Chunk pointer to an
unmarked chunk pointer to
an unmarked raw header
chunk?(C)
[C↑↑, 𝒽, 𝓂] β†’ βˆ—C
[C, 𝓅, 𝓂] β†’ βˆ—C↑
C - 1 β†’ C
[[C↑↑, 𝒽, 𝓂] β†’ βˆ—C
[C, 𝓅, 𝓂] β†’ βˆ—C↑
C↑ + size(C↑↑) β†’ C
pair?(C)
βˆ—C↑↑ β†’ βˆ—C
[C, 𝓅 , 𝓂] β†’ βˆ—C↑↑
[P, 𝓅, 𝓂] β†’ βˆ—C
C β†’ P
C↑ β†’ C
C↑ - 1 β†’ C
C↑ β†’ C C + 1 β†’ C
βˆ… β†’ P
memory β†’ C
!
Pointer to an unmarked
chunk pointer to an
unmarked cell
C↑↓ = π“Š
C↑ = memory"
Pointer to a non-
terminal marked cell
C↑ β‰  memory Pair pointer to a
marked cell
pair?(C)
Pointer to an
unmarked pointer
C↕ = 𝓅
➠
➠
7 transitions 6 transitions
27
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
C↓ = 𝒢
Pointer to
an atom
C = some
pointer
C↓ = π“Š
Pointer to an
unmarked
pointer
regular?(C↑↑)
Pointer to an
unmarked pointer to
a marked pointer
C↑↓ = 𝓂
βˆ—C↑↑ β†’ βˆ—C
[C, 𝓂] β†’ βˆ—C↑↑
C - 1 β†’ C
C↓ = 𝓂
Pointer to a
marked cell
C - 1 β†’ C
C↑ - 1 β†’ C
Pointer to an unmarked
pointer to an unmarked
raw header
raw?(C↑↑)
βˆ—C↑ β†’ βˆ—C
[C, 𝓂] β†’ C↑
C - 1 β†’ C
Pointer to an unmarked
pointer to an unmarked
regular header
!
[root, π“Š] β†’ βˆ—memory
memory β†’ C
" C↑= memory
Pointer to an
unmarked pointer to
an unmarked header
C↑↓ = π“Š
βˆ—C↑ β†’ βˆ—C
[C, 𝓂] β†’ C↑
C↑ + size(C↑↑) β†’ C
Pointer to a
marked non-
terminal pointer
C↑≠ memory
C↓ = 𝒢
Pointer to an
unmarked
atom
C = some
pointer
Pointer to an
unmarked
pointer
C↓ = 𝓅
Pointer to a
marked cell
C⇣ = 𝓂
even?(C)odd?(C)
Odd pointer to
a non-terminal
marked cell
[P , 𝓅 , 𝓂] β†’ βˆ—C
C β†’ P
C↑ β†’ C
C + 1 β†’ C
Pointer to an
unmarked
cell
C⇣ = π“Š
!
βˆ… β†’ P
memory β†’ C
"
Even pointer to
a non-terminal
marked cell
P β‰  βˆ…
𝓂 β†’ C⇣
P = βˆ…
Stop Pointer to a
non-terminal
marked cell
[C – 1 , 𝓅 , 𝓂] β†’ βˆ—P
P β†’ C
P↑ β†’ P
CMS + Schorr-Waite
pair?(C↑)
[C - 1, 𝓅 , 𝓂] β†’ βˆ—P
P β†’ C
P↑ β†’ P
[C - 1, p, π“Š] β†’ βˆ—P
P - 1 β†’ C
P↑ β†’ P
βˆ—C↑↑ β†’ βˆ—C
[C, 𝓅 , 𝓂] β†’ βˆ—C↑↑
C - 1 β†’ C
[C↑↑, 𝒽, 𝓂] β†’ βˆ—C
[C, 𝓅, 𝓂] β†’ βˆ—C↑
chunk?(C)
C↕ = 𝒢 Chunk pointer to an
unmarked atom
Pointer to an
unmarked atom
pair?(C)
Pair pointer to an
unmarked atom
Some pointer
chunk?(C↑)
Pointer to an
unmarked
chunk pointer
Pointer to an unmarked
chunk pointer to an
unmarked regular header
regular?(C↑↑)
Pointer to an unmarked
chunk pointer to a
marked cell
C↑↓ = 𝓂
Chunk pointer to an
unmarked chunk pointer
to a marked header
chunk?(C)
Pair pointer to an
unmarked chunk pointer
to a marked header
pair?(C)
Pointer to an
unmarked pair
pointer
Pointer to a
marked cell
C↓ = 𝓂
Pointer to a
marked chunk
chunk?(C)
Chunk pointer to a
marked chunk with a
chunk thread
chunk?(C↑)
Chunk pointer to a
marked chunk with
pair thread
pair?(C↑)
Even pair pointer
to a marked cell
even?(C)
Odd pair pointer
to a marked cellodd?(C)
Odd pair pointer to a
marked cell with
chunk thread
Odd pair pointer to
a marked cell with
pair thread
pair?(P)
chunk?(P)
Pointer to an
unmarked cell
C↓ = π“Š
C - 1 β†’ C
𝓂 β†’ C↓
Pointer to an unmarked
chunk pointer to an
unmarked raw header
raw?(C↑↑)
Pair pointer to an unmarked
chunk pointer to an
unmarked raw header
Chunk pointer to an
unmarked chunk pointer to
an unmarked raw header
chunk?(C)
[C↑↑, 𝒽, 𝓂] β†’ βˆ—C
[C, 𝓅, 𝓂] β†’ βˆ—C↑
C - 1 β†’ C
[[C↑↑, 𝒽, 𝓂] β†’ βˆ—C
[C, 𝓅, 𝓂] β†’ βˆ—C↑
C↑ + size(C↑↑) β†’ C
pair?(C)
βˆ—C↑↑ β†’ βˆ—C
[C, 𝓅 , 𝓂] β†’ βˆ—C↑↑
[P, 𝓅, 𝓂] β†’ βˆ—C
C β†’ P
C↑ β†’ C
C↑ - 1 β†’ C
C↑ β†’ C C + 1 β†’ C
βˆ… β†’ P
memory β†’ C
!
Pointer to an unmarked
chunk pointer to an
unmarked cell
C↑↓ = π“Š
C↑ = memory"
Pointer to a non-
terminal marked cell
C↑ β‰  memory Pair pointer to a
marked cell
pair?(C)
Pointer to an
unmarked pointer
C↕ = 𝓅
➠
➠
7 transitions 6 transitions
15 transitions
27
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
CMS + Schorr-Waite
typedef struct CEL * ptr;
typedef enum { a, h = a, p } typ;
typedef enum { m, u } mrk;
typedef struct CEL { ptr P; typ T; mrk M; } cel;
static const ptr null = (ptr)0;
static const unsigned max;
static ptr free, memory;
static unsigned is_chunk(ptr), size(ptr);
static ptr hdr(unsigned);
static void jonkers_schorr_waite(void)
{ ptr A, D, S, S_;
unsigned C, L1;
A = null; // A <- null
*free = (cel){0, h, m }; // *free <- [0, h, m]
for (S = D = memory + 1;;) // S <- D <- memory + 1
{ S_ = S->P; // S^
if (A == null) // A = null
if (S->M == m) // Sv = m
if (S < free) // S < free
{ A = S; // A <- S
S = S_; // S <- S^
C = 0; } // C <- 0
else // S = free
break; // stop
else // Sv = u
{ A = S; // A <- S
C = size(S_) + 1; // C <- size(S^) + 1
S += C; } // S <- S + size(S^) + 1
else // A β‰  null
if (C == 0) // C = 0
if (S->T == h) // Sw = h
{ L1 = size(S_) + 1; // size(S^) + 1
*A = *S; // *A <- *S
if (is_chunk(S)) // chunk?(S)
*S = (cel){ D, p, u };// *S <- [D, p, u]
else // pair?(S)
*S = (cel){ D, p, m };// *S <- [D, p, m]
S = A + L1; // S <- A + size(S^) + 1
D += L1; // D <- D + size(S^) + 1
A = null; } // A <- null
else // Sw = p
{ if (is_chunk(S)) // chunk?(S)
*S = (cel){ D, p, u }; // *S <- [D, p, u]
else // pair?(S)
*S = (cel){ D, p, m }; // *S <- [D, p, m]
S = S_; } // S <- S^
else // C > 0
if (S->M == m) // Sv = m
{ *A = (cel){ hdr(C - 1), h, u }; // *A <- [hdr(C-1), h, u]
A = null; // A <- null
C = 0; } // C = 0
else // Sv = u
{ L1 = size(S_) + 1; // size(S^) + 1
if (C + L1 > max) // C + size(S^) β‰₯ max
{ *A = (cel){ hdr(C - 1), h, u };// *A <- [hdr(C-1), h, u]
A = null; // A <- null
C = 0; } // C = 0
else // C + size(S^) ≀ max
{ S += L1; // S <- S + size(S^) + 1
C += L1; }}}} // C <- C + size(S^) + 1
28
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
CMS + Schorr-Waite
29
typedef struct CEL * ptr;
typedef enum { a, h = a, p } typ;
typedef enum { m, u } mrk;
typedef struct CEL { ptr P; typ T; mrk M; } cel;
static const ptr null = (ptr)0;
static const unsigned max;
static ptr free, memory;
static unsigned is_chunk(ptr), size(ptr);
static ptr hdr(unsigned);
static void jonkers_schorr_waite(void)
{ ptr A, D, S, S_;
unsigned C, L1;
A = null; // A <- null
*free = (cel){0, h, m }; // *free <- [0, h, m]
for (S = D = memory + 1;;) // S <- D <- memory + 1
{ S_ = S->P; // S^
if (A == null) // A = null
if (S->M == m) // Sv = m
if (S < free) // S < free
{ A = S; // A <- S
S = S_; // S <- S^
C = 0; } // C <- 0
else // S = free
break; // stop
else // Sv = u
{ A = S; // A <- S
C = size(S_) + 1; // C <- size(S^) + 1
S += C; } // S <- S + size(S^) + 1
else // A β‰  null
if (C == 0) // C = 0
if (S->T == h) // Sw = h
{ L1 = size(S_) + 1; // size(S^) + 1
*A = *S; // *A <- *S
if (is_chunk(S)) // chunk?(S)
*S = (cel){ D, p, u };// *S <- [D, p, u]
else // pair?(S)
*S = (cel){ D, p, m };// *S <- [D, p, m]
S = A + L1; // S <- A + size(S^) + 1
D += L1; // D <- D + size(S^) + 1
A = null; } // A <- null
else // Sw = p
{ if (is_chunk(S)) // chunk?(S)
*S = (cel){ D, p, u }; // *S <- [D, p, u]
else // pair?(S)
*S = (cel){ D, p, m }; // *S <- [D, p, m]
S = S_; } // S <- S^
else // C > 0
if (S->M == m) // Sv = m
{ *A = (cel){ hdr(C - 1), h, u }; // *A <- [hdr(C-1), h, u]
A = null; // A <- null
C = 0; } // C = 0
else // Sv = u
{ L1 = size(S_) + 1; // size(S^) + 1
if (C + L1 > max) // C + size(S^) β‰₯ max
{ *A = (cel){ hdr(C - 1), h, u };// *A <- [hdr(C-1), h, u]
A = null; // A <- null
C = 0; } // C = 0
else // C + size(S^) ≀ max
{ S += L1; // S <- S + size(S^) + 1
C += L1; }}}} // C <- C + size(S^) + 1
50 lines of executable
specification
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
0 1 6 2 3 1 12 6 1 2 6 1 0
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
free root
15 1
0 14 9 2 2 1 2 13 1 8 3 7 0
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
free root
15 1
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
free root
9 0
1 2 3 0 6 6 2 2 0 6
Fixing CMS: the problem
application#2
0 1 2 2 3 0 6 2 1 2 2 0 0
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
free root
15 1
➠
➠
➠
30
30
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
0 1 6 2 3 1 12 6 1 2 6 1 0
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
free root
15 1
0 14 9 2 2 1 2 13 1 8 3 7 0
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
free root
15 1
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
free root
9 0
1 2 3 0 6 6 2 2 0 6
Fixing CMS: the problem
application#2
0 1 2 2 3 0 6 2 1 2 2 0 0
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
free root
15 1
➠
➠
➠
30
30
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
Fixing CMS: partial solution
31
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
Fixing CMS: partial solution
sequential scan of complete heap
31
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
Fixing CMS: partial solution
sequential scan of complete heap
compress mark bits in bitmap
31
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
Fixing CMS: partial solution
sequential scan of complete heap
compress mark bits in bitmap
but: in dynamical languages
this bitmap is sparse
31
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
Fixing CMS: testcase
(define (xTree-balance xTree)
(define root (cadr xTree))
(define size (caddr xTree))
(define (traverse root size required)
(if (pair? root)
(begin
(define lCount (car root))
(define lTree (cadr root))
(define rTree (caddr root))
(define rCount (- size required))
(if (> lCount required)
(begin
(define lTree (traverse lTree lCount required))
(define llTree (cadr lTree))
(define rlTree (caddr lTree))
(define rTree (list (- lCount required) rlTree rTree))
(define rrTree (traverse rTree rCount (quotient rCount 2)))
(list required llTree rrTree))
(if (< lCount required)
(begin
(define rTree (traverse rTree (- size lCount) (- required lCount)))
(define lrTree (cadr rTree))
(define rrTree (caddr rTree))
(define lTree (list lCount lTree lrTree))
(define llTree (traverse lTree required (quotient required 2)))
(list required llTree rrTree))
(begin
(define lTree (traverse lTree lCount (quotient lCount 2)))
(define rTree (traverse rTree rCount (quotient rCount 2)))
(list lCount lTree rTree)))))
(if (null? root)
'error
root)))
(traverse root size (quotient size 2)))
32
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
Fixing CMS: testcase
(define (xTree-balance xTree)
(define root (cadr xTree))
(define size (caddr xTree))
(define (traverse root size required)
(if (pair? root)
(begin
(define lCount (car root))
(define lTree (cadr root))
(define rTree (caddr root))
(define rCount (- size required))
(if (> lCount required)
(begin
(define lTree (traverse lTree lCount required))
(define llTree (cadr lTree))
(define rlTree (caddr lTree))
(define rTree (list (- lCount required) rlTree rTree))
(define rrTree (traverse rTree rCount (quotient rCount 2)))
(list required llTree rrTree))
(if (< lCount required)
(begin
(define rTree (traverse rTree (- size lCount) (- required lCount)))
(define lrTree (cadr rTree))
(define rrTree (caddr rTree))
(define lTree (list lCount lTree lrTree))
(define llTree (traverse lTree required (quotient required 2)))
(list required llTree rrTree))
(begin
(define lTree (traverse lTree lCount (quotient lCount 2)))
(define rTree (traverse rTree rCount (quotient rCount 2)))
(list lCount lTree rTree)))))
(if (null? root)
'error
root)))
(traverse root size (quotient size 2)))
nested scope lots of
interpreter garbage
32
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
Fixing CMS: testcase
(define (xTree-balance xTree)
(define root (cadr xTree))
(define size (caddr xTree))
(define (traverse root size required)
(if (pair? root)
(begin
(define lCount (car root))
(define lTree (cadr root))
(define rTree (caddr root))
(define rCount (- size required))
(if (> lCount required)
(begin
(define lTree (traverse lTree lCount required))
(define llTree (cadr lTree))
(define rlTree (caddr lTree))
(define rTree (list (- lCount required) rlTree rTree))
(define rrTree (traverse rTree rCount (quotient rCount 2)))
(list required llTree rrTree))
(if (< lCount required)
(begin
(define rTree (traverse rTree (- size lCount) (- required lCount)))
(define lrTree (cadr rTree))
(define rrTree (caddr rTree))
(define lTree (list lCount lTree lrTree))
(define llTree (traverse lTree required (quotient required 2)))
(list required llTree rrTree))
(begin
(define lTree (traverse lTree lCount (quotient lCount 2)))
(define rTree (traverse rTree rCount (quotient rCount 2)))
(list lCount lTree rTree)))))
(if (null? root)
'error
root)))
(traverse root size (quotient size 2)))
nested scope lots of
interpreter garbage
functional style lots of
application garbage
32
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
>(load "CODE/xTrees.slip")
left count = 1
left count = 2499
elapsed: 24.4990180000 sec
<unspecified>
>(collect)
Collecting garbage ...
mark-thread: 0.004518
unthread: 0.555821
compact-link: 0.133263
used chunk space before GC: 601131564(66.79%)
used chunk space after GC: 110831(00.01%)
used pair space before GC: 226478924(25.16%)
used pair space after GC: 30004(00.00%)
<unspecified>
>
Fixing CMS: straight
33
preliminary
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
>(load "CODE/xTrees.slip")
left count = 1
left count = 2499
elapsed: 24.4990180000 sec
<unspecified>
>(collect)
Collecting garbage ...
mark-thread: 0.004518
unthread: 0.555821
compact-link: 0.133263
used chunk space before GC: 601131564(66.79%)
used chunk space after GC: 110831(00.01%)
used pair space before GC: 226478924(25.16%)
used pair space after GC: 30004(00.00%)
<unspecified>
>
Fixing CMS: straight
32 bits
900Mcell
33
preliminary
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
>(load "CODE/xTrees.slip")
left count = 1
left count = 2499
elapsed: 24.1853520000 sec
<unspecified>
>(collect)
Collecting garbage ...
mark-thread: 0.007855
unthread: 0.047346
compact-link: 0.032718
used chunk space before GC: 601131564(66.79%)
used chunk space after GC: 110831(00.01%)
used pair space before GC: 226478924(25.16%)
used pair space after GC: 30002(00.00%)
<unspecified>
>
Fixing CMS: bitmap
34
preliminary
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
>(load "CODE/xTrees.slip")
left count = 1
left count = 2499
elapsed: 24.7884030000 sec
<unspecified>
>(collect)
Collecting garbage ...
mark-thread: 0.008640
unthread: 0.001088
compact-link: 0.001118
used chunk space before GC: 601131564(66.79%)
used chunk space after GC: 110831(00.01%)
used pair space before GC: 226478924(25.16%)
used pair space after GC: 30002(00.00%)
<unspecified>
>
Fixing CMS: bitheap
35
preliminary
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
36
Bitheaps
Name is taken ...
Implements a priority queue
Leaves are (all) memory cells
Are (static) heaps with arity 32*
Each node contains 32 bits
Each bit indicates whether the subtree
contains at least one bit = 1
*will scale up to 32Gby on a 64bit architecture
32 32
32 32 32
i = (a >> 27) + 1
a &= (1 << 27) - 1
i = 32*i + (a >> 22) + 1
a &= (1 << 22) - 1
i = 32*i + (a >> 17) + 1
a &= (1 << 17) - 1
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
36
Bitheaps
Name is taken ...
Implements a priority queue
Leaves are (all) memory cells
Are (static) heaps with arity 32*
Each node contains 32 bits
Each bit indicates whether the subtree
contains at least one bit = 1
*will scale up to 32Gby on a 64bit architecture
32 32
32 32 32
i = (a >> 27) + 1
a &= (1 << 27) - 1
i = 32*i + (a >> 22) + 1
a &= (1 << 22) - 1
i = 32*i + (a >> 17) + 1
a &= (1 << 17) - 1
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
36
Bitheaps
Name is taken ...
Implements a priority queue
Leaves are (all) memory cells
Are (static) heaps with arity 32*
Each node contains 32 bits
Each bit indicates whether the subtree
contains at least one bit = 1
*will scale up to 32Gby on a 64bit architecture
32 32
32 32 32
i = (a >> 27) + 1
a &= (1 << 27) - 1
i = 32*i + (a >> 22) + 1
a &= (1 << 22) - 1
i = 32*i + (a >> 17) + 1
a &= (1 << 17) - 1
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
36
Bitheaps
Name is taken ...
Implements a priority queue
Leaves are (all) memory cells
Are (static) heaps with arity 32*
Each node contains 32 bits
Each bit indicates whether the subtree
contains at least one bit = 1
*will scale up to 32Gby on a 64bit architecture
32 32
32 32 32
i = (a >> 27) + 1
a &= (1 << 27) - 1
i = 32*i + (a >> 22) + 1
a &= (1 << 22) - 1
i = 32*i + (a >> 17) + 1
a &= (1 << 17) - 1
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
36
Bitheaps
Name is taken ...
Implements a priority queue
Leaves are (all) memory cells
Are (static) heaps with arity 32*
Each node contains 32 bits
Each bit indicates whether the subtree
contains at least one bit = 1
*will scale up to 32Gby on a 64bit architecture
32 32
32 32 32
i = (a >> 27) + 1
a &= (1 << 27) - 1
i = 32*i + (a >> 22) + 1
a &= (1 << 22) - 1
i = 32*i + (a >> 17) + 1
a &= (1 << 17) - 1
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
36
Bitheaps
Name is taken ...
Implements a priority queue
Leaves are (all) memory cells
Are (static) heaps with arity 32*
Each node contains 32 bits
Each bit indicates whether the subtree
contains at least one bit = 1
*will scale up to 32Gby on a 64bit architecture
32 32
32 32 32
i = (a >> 27) + 1
a &= (1 << 27) - 1
i = 32*i + (a >> 22) + 1
a &= (1 << 22) - 1
i = 32*i + (a >> 17) + 1
a &= (1 << 17) - 1
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
36
Bitheaps
Name is taken ...
Implements a priority queue
Leaves are (all) memory cells
Are (static) heaps with arity 32*
Each node contains 32 bits
Each bit indicates whether the subtree
contains at least one bit = 1
*will scale up to 32Gby on a 64bit architecture
32 32
32 32 32
i = (a >> 27) + 1
a &= (1 << 27) - 1
i = 32*i + (a >> 22) + 1
a &= (1 << 22) - 1
i = 32*i + (a >> 17) + 1
a &= (1 << 17) - 1
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
static void set(unsigned a)
{ unsigned b, i = 0;
b = a >> 25; a &= (1 << 25) - 1; memory[i] |= 1 << b; i = 1 + (i << 5) + b;
b = a >> 20; a &= (1 << 20) - 1; memory[i] |= 1 << b; i = 1 + (i << 5) + b;
b = a >> 15; a &= (1 << 15) - 1; memory[i] |= 1 << b; i = 1 + (i << 5) + b;
b = a >> 10; a &= (1 << 10) - 1; memory[i] |= 1 << b; i = 1 + (i << 5) + b;
b = a >> 5; a &= (1 << 5) - 1; memory[i] |= 1 << b; i = 1 + (i << 5) + b;
memory[i] |= 1 << a; }
(Bitheaps)
static UNS_type Bitheap[34636833] = { 0x0 };
37
// Sigma i=0,5 32^i = (32^6 - 1)/(32 - 1)
static UNS_type Bitheap[34636833] = { 0x0 };
static void do_(void (* lambda)(unsigned))
{ unsigned i0 = 0;
unsigned w1 = memory[i0];
if (w1)
{ i0 = 1 + (i0 << 5);
for (unsigned b1 = 0; b1 < 32; b1 += 1)
if (w1 & (1 << b1))
{ unsigned i1 = i0 + b1;
unsigned w2 = memory[i1];
if (w2)
{ i1 = 1 + (i1 << 5);
for (unsigned b2 = 0; b2 < 32; b2 += 1)
{ unsigned i6 = i5 + b6;
lambda(i6 - memory_size); }}}}}}}}}}}}}
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
static void set(unsigned a)
{ unsigned b, i = 0;
b = a >> 25; a &= (1 << 25) - 1; memory[i] |= 1 << b; i = 1 + (i << 5) + b;
b = a >> 20; a &= (1 << 20) - 1; memory[i] |= 1 << b; i = 1 + (i << 5) + b;
b = a >> 15; a &= (1 << 15) - 1; memory[i] |= 1 << b; i = 1 + (i << 5) + b;
b = a >> 10; a &= (1 << 10) - 1; memory[i] |= 1 << b; i = 1 + (i << 5) + b;
b = a >> 5; a &= (1 << 5) - 1; memory[i] |= 1 << b; i = 1 + (i << 5) + b;
memory[i] |= 1 << a; }
(Bitheaps)
static UNS_type Bitheap[34636833] = { 0x0 };
32 bits
4Gby
37
// Sigma i=0,5 32^i = (32^6 - 1)/(32 - 1)
static UNS_type Bitheap[34636833] = { 0x0 };
static void do_(void (* lambda)(unsigned))
{ unsigned i0 = 0;
unsigned w1 = memory[i0];
if (w1)
{ i0 = 1 + (i0 << 5);
for (unsigned b1 = 0; b1 < 32; b1 += 1)
if (w1 & (1 << b1))
{ unsigned i1 = i0 + b1;
unsigned w2 = memory[i1];
if (w2)
{ i1 = 1 + (i1 << 5);
for (unsigned b2 = 0; b2 < 32; b2 += 1)
{ unsigned i6 = i5 + b6;
lambda(i6 - memory_size); }}}}}}}}}}}}}
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
Conclusion
Early days but promising
Scalability
Complexity
Formal support
Tool support
Non-gc algorithms
38
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
Conclusion
Early days but promising
Scalability
Complexity
Formal support
Tool support
Non-gc algorithms
38
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
Conclusion
Early days but promising
Scalability
Complexity
Formal support
Tool support
Non-gc algorithms
38
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
Conclusion
Early days but promising
Scalability
Complexity
Formal support
Tool support
Non-gc algorithms
38
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
Conclusion
Early days but promising
Scalability
Complexity
Formal support
Tool support
Non-gc algorithms
38
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
Conclusion
Early days but promising
Scalability
Complexity
Formal support
Tool support
Non-gc algorithms
38
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
Conclusion
Early days but promising
Scalability
Complexity
Formal support
Tool support
Non-gc algorithms
38
Buenos Aires, November 2017
Smalltalks 2017:
Reasoning about memory-
critical algorithms
Conclusion
Early days but promising
Scalability
Complexity
Formal support
Tool support
Non-gc algorithms
38
convenience
leads to
procedure

More Related Content

What's hot

Data structures and algorithms lab2
Data structures and algorithms lab2Data structures and algorithms lab2
Data structures and algorithms lab2
Bianca TeşilΔƒ
Β 
Introduction to data structures and Algorithm
Introduction to data structures and AlgorithmIntroduction to data structures and Algorithm
Introduction to data structures and Algorithm
Dhaval Kaneria
Β 
Prelim Project OOP
Prelim Project OOPPrelim Project OOP
Prelim Project OOP
Dwight Sabio
Β 

What's hot (19)

Collatz Conjecture Research
Collatz Conjecture ResearchCollatz Conjecture Research
Collatz Conjecture Research
Β 
1 Anne complains that defining functions to use in her programs is a lot of ...
1 Anne complains that defining functions to use in her programs is a lot of  ...1 Anne complains that defining functions to use in her programs is a lot of  ...
1 Anne complains that defining functions to use in her programs is a lot of ...
Β 
Insertion sort and shell sort
Insertion sort and shell sortInsertion sort and shell sort
Insertion sort and shell sort
Β 
Data structures and algorithms lab2
Data structures and algorithms lab2Data structures and algorithms lab2
Data structures and algorithms lab2
Β 
Quick and radix sort
Quick and radix sortQuick and radix sort
Quick and radix sort
Β 
Unit 4.5
Unit 4.5Unit 4.5
Unit 4.5
Β 
Sorting algorithms
Sorting algorithmsSorting algorithms
Sorting algorithms
Β 
Introduction to data structures and Algorithm
Introduction to data structures and AlgorithmIntroduction to data structures and Algorithm
Introduction to data structures and Algorithm
Β 
Data Structures - Searching & sorting
Data Structures - Searching & sortingData Structures - Searching & sorting
Data Structures - Searching & sorting
Β 
Applications of data structures
Applications of data structuresApplications of data structures
Applications of data structures
Β 
1. cs8451 daa anna univ question bank unit 1
1. cs8451 daa anna univ question bank unit 11. cs8451 daa anna univ question bank unit 1
1. cs8451 daa anna univ question bank unit 1
Β 
Summary of MATLAB Functions-Part1
Summary of MATLAB Functions-Part1Summary of MATLAB Functions-Part1
Summary of MATLAB Functions-Part1
Β 
Shellshort ppt
Shellshort pptShellshort ppt
Shellshort ppt
Β 
Data structures arrays
Data structures   arraysData structures   arrays
Data structures arrays
Β 
Model and Design
Model and Design Model and Design
Model and Design
Β 
Unit 4.7
Unit 4.7Unit 4.7
Unit 4.7
Β 
Prelim Project OOP
Prelim Project OOPPrelim Project OOP
Prelim Project OOP
Β 
Sorting Seminar Presentation by Ashin Guha Majumder
Sorting Seminar Presentation by Ashin Guha MajumderSorting Seminar Presentation by Ashin Guha Majumder
Sorting Seminar Presentation by Ashin Guha Majumder
Β 
procedures
proceduresprocedures
procedures
Β 

Similar to Reasoning about memory-critical algorithms by Theo D'Hondt

computer notes - Linked list inside computer memory
computer notes - Linked list inside computer memorycomputer notes - Linked list inside computer memory
computer notes - Linked list inside computer memory
ecomputernotes
Β 
computer notes - Stack
computer notes - Stackcomputer notes - Stack
computer notes - Stack
ecomputernotes
Β 
OverviewUsing the C-structΒ feature, design, implement and .docx
OverviewUsing the C-structΒ feature, design, implement and .docxOverviewUsing the C-structΒ feature, design, implement and .docx
OverviewUsing the C-structΒ feature, design, implement and .docx
alfred4lewis58146
Β 
Assg 05 QuicksortCOSC 2336 Data StructuresObjectives.docx
Assg 05 QuicksortCOSC 2336 Data StructuresObjectives.docxAssg 05 QuicksortCOSC 2336 Data StructuresObjectives.docx
Assg 05 QuicksortCOSC 2336 Data StructuresObjectives.docx
jane3dyson92312
Β 
Assg 05 QuicksortCOSC 2336 Data StructuresObjectives.docx
Assg 05 QuicksortCOSC 2336 Data StructuresObjectives.docxAssg 05 QuicksortCOSC 2336 Data StructuresObjectives.docx
Assg 05 QuicksortCOSC 2336 Data StructuresObjectives.docx
festockton
Β 
Basic Garbage Collection Techniques
Basic  Garbage  Collection  TechniquesBasic  Garbage  Collection  Techniques
Basic Garbage Collection Techniques
An Khuong
Β 
[Ris cy business]
[Ris cy business][Ris cy business]
[Ris cy business]
Dino, llc
Β 
Advance data structure
Advance data structureAdvance data structure
Advance data structure
ashok kumar
Β 

Similar to Reasoning about memory-critical algorithms by Theo D'Hondt (20)

computer notes - Linked list inside computer memory
computer notes - Linked list inside computer memorycomputer notes - Linked list inside computer memory
computer notes - Linked list inside computer memory
Β 
Data Structure.pdf
Data Structure.pdfData Structure.pdf
Data Structure.pdf
Β 
Fusing Transformations of Strict Scala Collections with Views
Fusing Transformations of Strict Scala Collections with ViewsFusing Transformations of Strict Scala Collections with Views
Fusing Transformations of Strict Scala Collections with Views
Β 
DSA Lab Manual C Scheme.pdf
DSA Lab Manual C Scheme.pdfDSA Lab Manual C Scheme.pdf
DSA Lab Manual C Scheme.pdf
Β 
computer notes - Stack
computer notes - Stackcomputer notes - Stack
computer notes - Stack
Β 
OverviewUsing the C-structΒ feature, design, implement and .docx
OverviewUsing the C-structΒ feature, design, implement and .docxOverviewUsing the C-structΒ feature, design, implement and .docx
OverviewUsing the C-structΒ feature, design, implement and .docx
Β 
‏‏Lecture 2.pdf
‏‏Lecture 2.pdf‏‏Lecture 2.pdf
‏‏Lecture 2.pdf
Β 
Database structure Structures Link list and trees and Recurison complete
Database structure Structures Link list and trees and Recurison complete  Database structure Structures Link list and trees and Recurison complete
Database structure Structures Link list and trees and Recurison complete
Β 
EXTENDED K-MAP FOR MINIMIZING MULTIPLE OUTPUT LOGIC CIRCUITS
EXTENDED K-MAP FOR MINIMIZING MULTIPLE OUTPUT LOGIC CIRCUITSEXTENDED K-MAP FOR MINIMIZING MULTIPLE OUTPUT LOGIC CIRCUITS
EXTENDED K-MAP FOR MINIMIZING MULTIPLE OUTPUT LOGIC CIRCUITS
Β 
Assg 05 QuicksortCOSC 2336 Data StructuresObjectives.docx
Assg 05 QuicksortCOSC 2336 Data StructuresObjectives.docxAssg 05 QuicksortCOSC 2336 Data StructuresObjectives.docx
Assg 05 QuicksortCOSC 2336 Data StructuresObjectives.docx
Β 
Assg 05 QuicksortCOSC 2336 Data StructuresObjectives.docx
Assg 05 QuicksortCOSC 2336 Data StructuresObjectives.docxAssg 05 QuicksortCOSC 2336 Data StructuresObjectives.docx
Assg 05 QuicksortCOSC 2336 Data StructuresObjectives.docx
Β 
1183 c-interview-questions-and-answers
1183 c-interview-questions-and-answers1183 c-interview-questions-and-answers
1183 c-interview-questions-and-answers
Β 
Basic Garbage Collection Techniques
Basic  Garbage  Collection  TechniquesBasic  Garbage  Collection  Techniques
Basic Garbage Collection Techniques
Β 
One More Comments on Programming with Big Number Library in Scientific Computing
One More Comments on Programming with Big Number Library in Scientific ComputingOne More Comments on Programming with Big Number Library in Scientific Computing
One More Comments on Programming with Big Number Library in Scientific Computing
Β 
Data Structures Design Notes.pdf
Data Structures Design Notes.pdfData Structures Design Notes.pdf
Data Structures Design Notes.pdf
Β 
[Ris cy business]
[Ris cy business][Ris cy business]
[Ris cy business]
Β 
graph2tab, a library to convert experimental workflow graphs into tabular for...
graph2tab, a library to convert experimental workflow graphs into tabular for...graph2tab, a library to convert experimental workflow graphs into tabular for...
graph2tab, a library to convert experimental workflow graphs into tabular for...
Β 
Advance data structure
Advance data structureAdvance data structure
Advance data structure
Β 
Ecet 370 Education Organization -- snaptutorial.com
Ecet 370   Education Organization -- snaptutorial.comEcet 370   Education Organization -- snaptutorial.com
Ecet 370 Education Organization -- snaptutorial.com
Β 
Robust Visual Tracking Based on Sparse PCA-L1
Robust Visual Tracking Based on Sparse PCA-L1Robust Visual Tracking Based on Sparse PCA-L1
Robust Visual Tracking Based on Sparse PCA-L1
Β 

More from FAST

Powerlang: a Vehicle for Lively Implementing Programming Languages
Powerlang: a Vehicle for Lively Implementing Programming LanguagesPowerlang: a Vehicle for Lively Implementing Programming Languages
Powerlang: a Vehicle for Lively Implementing Programming Languages
FAST
Β 
Constructing 3D scenes with Woden Engine
Constructing 3D scenes with Woden EngineConstructing 3D scenes with Woden Engine
Constructing 3D scenes with Woden Engine
FAST
Β 
Demystifying the creation of coding tools
Demystifying the creation of coding toolsDemystifying the creation of coding tools
Demystifying the creation of coding tools
FAST
Β 
Application Starter: the entry point for your application
Application Starter: the entry point for your applicationApplication Starter: the entry point for your application
Application Starter: the entry point for your application
FAST
Β 
Using 128 GPU cores, Tensorflow and VASmalltalk to detect Kolsh beers with ES...
Using 128 GPU cores, Tensorflow and VASmalltalk to detect Kolsh beers with ES...Using 128 GPU cores, Tensorflow and VASmalltalk to detect Kolsh beers with ES...
Using 128 GPU cores, Tensorflow and VASmalltalk to detect Kolsh beers with ES...
FAST
Β 
VASmalltalk and Raspberry Pi powering the largest MIDI instrument of the world
VASmalltalk and Raspberry Pi powering the largest MIDI instrument of the worldVASmalltalk and Raspberry Pi powering the largest MIDI instrument of the world
VASmalltalk and Raspberry Pi powering the largest MIDI instrument of the world
FAST
Β 
Hands-on Raspberry Pi and VA Smalltalk - Starting Workshop
Hands-on Raspberry Pi and VA Smalltalk - Starting WorkshopHands-on Raspberry Pi and VA Smalltalk - Starting Workshop
Hands-on Raspberry Pi and VA Smalltalk - Starting Workshop
FAST
Β 

More from FAST (20)

Threads, Critical Sections, and Termination
Threads, Critical Sections, and TerminationThreads, Critical Sections, and Termination
Threads, Critical Sections, and Termination
Β 
OOP with Smalltalk
OOP with SmalltalkOOP with Smalltalk
OOP with Smalltalk
Β 
Powerlang: a Vehicle for Lively Implementing Programming Languages
Powerlang: a Vehicle for Lively Implementing Programming LanguagesPowerlang: a Vehicle for Lively Implementing Programming Languages
Powerlang: a Vehicle for Lively Implementing Programming Languages
Β 
Constructing 3D scenes with Woden Engine
Constructing 3D scenes with Woden EngineConstructing 3D scenes with Woden Engine
Constructing 3D scenes with Woden Engine
Β 
Demystifying the creation of coding tools
Demystifying the creation of coding toolsDemystifying the creation of coding tools
Demystifying the creation of coding tools
Β 
Application Starter: the entry point for your application
Application Starter: the entry point for your applicationApplication Starter: the entry point for your application
Application Starter: the entry point for your application
Β 
Improving the Pharo VM
Improving the Pharo VMImproving the Pharo VM
Improving the Pharo VM
Β 
What is (not) Pharo 8?
What is (not) Pharo 8?What is (not) Pharo 8?
What is (not) Pharo 8?
Β 
Stargate: an interstellar journey to RESTful APIs
Stargate: an interstellar journey to RESTful APIsStargate: an interstellar journey to RESTful APIs
Stargate: an interstellar journey to RESTful APIs
Β 
Opening Smalltalks 2019
Opening Smalltalks 2019Opening Smalltalks 2019
Opening Smalltalks 2019
Β 
Smalltalk Computers, Past and Future by Jecel Mattos de Assumpção Jr
Smalltalk Computers, Past and Future by Jecel Mattos de Assumpção JrSmalltalk Computers, Past and Future by Jecel Mattos de Assumpção Jr
Smalltalk Computers, Past and Future by Jecel Mattos de Assumpção Jr
Β 
Adaptive Compilation by Jecel Mattos de Assumpção Jr
Adaptive Compilation by Jecel Mattos de Assumpção JrAdaptive Compilation by Jecel Mattos de Assumpção Jr
Adaptive Compilation by Jecel Mattos de Assumpção Jr
Β 
Choosing where to run our objects: the S8 Smalltalk approach by Description:F...
Choosing where to run our objects: the S8 Smalltalk approach by Description:F...Choosing where to run our objects: the S8 Smalltalk approach by Description:F...
Choosing where to run our objects: the S8 Smalltalk approach by Description:F...
Β 
Using 128 GPU cores, Tensorflow and VASmalltalk to detect Kolsh beers with ES...
Using 128 GPU cores, Tensorflow and VASmalltalk to detect Kolsh beers with ES...Using 128 GPU cores, Tensorflow and VASmalltalk to detect Kolsh beers with ES...
Using 128 GPU cores, Tensorflow and VASmalltalk to detect Kolsh beers with ES...
Β 
Improving VASmalltalk deployment, availability and scalability with Docker by...
Improving VASmalltalk deployment, availability and scalability with Docker by...Improving VASmalltalk deployment, availability and scalability with Docker by...
Improving VASmalltalk deployment, availability and scalability with Docker by...
Β 
VASmalltalk and Raspberry Pi powering the largest MIDI instrument of the world
VASmalltalk and Raspberry Pi powering the largest MIDI instrument of the worldVASmalltalk and Raspberry Pi powering the largest MIDI instrument of the world
VASmalltalk and Raspberry Pi powering the largest MIDI instrument of the world
Β 
Hands-on Raspberry Pi and VA Smalltalk - Starting Workshop
Hands-on Raspberry Pi and VA Smalltalk - Starting WorkshopHands-on Raspberry Pi and VA Smalltalk - Starting Workshop
Hands-on Raspberry Pi and VA Smalltalk - Starting Workshop
Β 
Live typing: Update and what's next by Hernan Wilkinson
Live typing: Update and what's next by Hernan WilkinsonLive typing: Update and what's next by Hernan Wilkinson
Live typing: Update and what's next by Hernan Wilkinson
Β 
Enhanced Email Protocol Framework for VAST by Seth Berman
Enhanced Email Protocol Framework for VAST by Seth BermanEnhanced Email Protocol Framework for VAST by Seth Berman
Enhanced Email Protocol Framework for VAST by Seth Berman
Β 
VA Smalltalk Product Update by Seth Berman
VA Smalltalk Product Update by Seth BermanVA Smalltalk Product Update by Seth Berman
VA Smalltalk Product Update by Seth Berman
Β 

Recently uploaded

Recently uploaded (20)

Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
Β 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Β 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
Β 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
Β 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
Β 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
Β 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
Β 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Β 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Β 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
Β 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Β 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
Β 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
Β 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Β 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
Β 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Β 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
Β 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
Β 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
Β 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Β 

Reasoning about memory-critical algorithms by Theo D'Hondt

  • 1. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms Growing an Abstract Grammar Teaching Language EngineeringTheo D'Hondt Software Languages Lab Vrije Universiteit Brussel soft.vub.ac.be tjdhondt@vub.ac.be Reasoning about memory-critical algorithms 1
  • 2. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms Abstract We call algorithms memory-critical if their actual dependence on memory is such that their implementation cannot use abstractions that indirectly require memory of their own. An obvious example of such an abstraction is a recursion stack. An equally obvious example of a memory-critical algorithm is a garbage collector. Generally, memory-critical algorithms are designed as state machines that apply a clever technique to embed a greatly resized version of the abstraction-related memory within the actual memory. Typically these algorithms end up being very terse and hard to conceive or comprehend, and when expressed as actual code they are equally hard to debug or optimise. Memory-critical algorithms have been the object of scientific publications, educational material and actual software since the early 60ies. In order to present these algorithms, techniques ranging from mathematical formalisms, graphical representations to pseudocode have been proposed. Unfortunately, these all suffer from the pithy nature of these algorithms and the lack of a uniform medium to reason about them. Hence their notoriously bad reputation for instance with students of advanced algorithms courses. This talk will report on an initiative to bind formalism, graphics and (executable) code in a framework to reason about memory-critical algorithms. It started out as an accumulation of convenient representations, and grew into something that has the hallmark of a systematic approach. It will be introduced by applying it to two historical algorithms, and subsequently two non-trivial experiments will be briefly described. 2
  • 3. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms Smaltalkers: [ . ] vs. { ; } Sista: a Metacircular Architecture for Runtime Optimisation Persistence ClΓ©ment BΓ©ra Laboratoire d’Informatique Fondamentale de Lille INRIA Lille - Nord Europe 2017 ... As most of the Smalltalk community has high skills in Smalltalk but little skills in low- level programming, the design aims here to allow the community to contribute to a project in Smalltalk doing Smalltalk-specific optimisations, improving performance while staying away from low-level details and machine-specific optimisations ... 3
  • 4. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms Smaltalkers: [ . ] vs. { ; } Sista: a Metacircular Architecture for Runtime Optimisation Persistence ClΓ©ment BΓ©ra Laboratoire d’Informatique Fondamentale de Lille INRIA Lille - Nord Europe 2017 ... As most of the Smalltalk community has high skills in Smalltalk but little skills in low- level programming, the design aims here to allow the community to contribute to a project in Smalltalk doing Smalltalk-specific optimisations, improving performance while staying away from low-level details and machine-specific optimisations ... Slang 3
  • 5. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms Cheney's algorithm C. J. Cheney A nonrecursive list compacting algorithm. Comm. ACM 13, 11 (1970) h coding. It that are de- ple, efficient, s few probes Comm. ACM 11, 1 (Jan. 1968), 38--44. 3. BELL, J. R. The quadratic quotient method: A hash code eliminating secondary clustering. Comm. ACM 13, 2 (Feb. 1970), 107-109. 4. RADKE,E.E. The use of quadratic residue research. Comm. ACM 13, 2 (Feb. 1970), 103-105. acting dge, England g scheme or and LISP-like the need for ilt up to keep ollection, compacl [2] have pre- uctures. One a list pointer, he authors of but complex m of Deutsch, ler algorithm T to copy a list area (the copied with- new list area s found will the structure r from them, ect the list in "nonitems." The structure is accessed via the pointer HEAD. This structure has two lists, the first consisting of three atoms A, B, C and a list pointer to the second list which consists solely of a list pointer to the atom A of the first list. Lists +o (a) HEAD I q/q SCAN't NEXT~ (b) :: i i .... :HEAD ,+AIBIΒ’I I/1 SCANT NEXTT (c) I ,..... '.---5....,_.,,I I I , I , .~ Itl/l I I I Is I I I I + HEAD dAiSlCi ~,iA i,i/, 1 TNEXT SCAN (d) old list area new list area FIG. 1. Compacting a structure without looped lists: (a) initial structure; (b) and (c) during processing; (d) final structure. Communications of the ACM 677 are terminated by NIL cells. The algorithm with some modification can be applied to LISP-type structures. To compact the structure, the list pointed to by HEAD is copied by COPYLIST into the new area--the contents of each item (not nonitems) are placed in consecutive cells in the new area, and the cells in the old area are changed to nonitems pointing to their equivalent cells in the new area. COPYLIST returns as a result the address of the first cell of the list in the new area. This value is used to update HEAD. A pointer NEXT is kept pointing to the next free cell in the new area. This intermediate structure is shown in Figure 1(b). A further pointer SCAN now scans the new area from the beginning. If SCAN points to a NIL or an atom, it is moved on to the next cell. If SCAN points to a list pointer, COPYLIST is entered with this list pointer as its param- eter. The sublist is therefore copied, updating NEXT, and the value returned is used to make the list pointer pointed at by SCAN point to the copied list in the new area. The structure resulting when SCAN has processed the first list pointer is shown in Figure 1(c). Note that, in copying, COPYLIST omits the nonitems of the original structure. SCAN continues its traverse of the new area and will pass over the NIL to the second list to reach another list pointer. COPYLIST is again applied, but this time it finds the first item is already in the new area (e.g. by com- paring core addresses), and the function returns with the address of this cell in the new area, which is used to update the list pointer, but without recopying the list. The compact structure is complete when SCAN reaches the cell pointed to by NEXT. The procedure is capable of dealing with looped lists as COPYLIST will place a non- item in the new area when necessary (see Figure 2). (o) o,0 HEAD listorgc] i i I i i I fleW A version has been written in assembly language in- volving the execution of between 30 and 40 orders on an Atlas computer for each item of the structure transferred to the new area. The algorithm is presented below in two parts--the "main program" first, and then the function COPYLIST. Step 1. Initialize the pointers SCAN and NEXT to point to the beginning of the new list area. Step 2. Apply the function COPYLIST--described below--to the pointer that points to the whole structure and assign the result of COPYLIST to that pointer. Step 3. If SCAN points to a list-pointer, then apply COPYLIST to that list pointer, the result of COPYLIST replaces the contents of the cell pointed at by SCAN. Step 4. Increment SCAN, unless SCAN now points to the same cell pointed at by NEXT, go to step 3 above. Otherwise the compacting is complete. The function COPYLIST takes one parameter, POINTER, called by value; the function does the follow- ing: Step 1. If POINTER points to a cell that is a nonitem, make POINTER point to the cell pointed at by the nonitem. Re- peat this step while POINTER points to a nonitem. Step 2. If POINTER is pointing to a cell in the new area, return with the value of POINTER as the result. Step 3. Save the current value of NEXT in a variable V. Step 4. If POINTER is pointing to a cell in the new area, make the cell pointed at by NEXT into a nonitem pointing to the cell that is pointed at by POINTER, and go to step 11 below. Step 5. Copy the contents of the cell pointed at by POINTER to the cell pointed at by NEXT. Step 6. If POINTER is pointing to a NIL, then go to step 11 below. Step 7. Make the cell pointed at by POINTER into a nonitem that points to the cell pointed at by NEXT, i.e. the corre- sponding cell in the new area. Step 8. Increment NEXT, increment POINTER. Step 9. If POINTER points to a nonitem, make POINTER point to the cell pointed at by the nonitem, repeat this step while POINTER is pointing to a nonitem. Step 10. Go to step 4 of the function COPYLIST. Step 11. Increment NEXT and return with the value of V as the result. Acknowledgments. The author is particularly grateful for many discussions with N. E. Wiseman and for the4
  • 6. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms begin-garbage-collection (assign free (const 0)) (assign scan (const 0)) (assign old (reg root)) (assign relocate-continue (label reassign-root)) (goto (label relocate-old-result-in-new)) reassign-root (assign root (reg new)) (goto (label gc-loop)) gc-loop (test (op =) (reg scan) (reg free)) (branch (label gc-flip)) (assign old (op vector-ref) (reg new-cars) (reg scan)) (assign relocate-continue (label update-car)) (goto (label relocate-old-result-in-new)) update-car (perform (op vector-set!) (reg new-cars) (reg scan) (reg new)) (assign old (op vector-ref) (reg new-cdrs) (reg scan)) (assign relocate-continue (label update-cdr)) (goto (label relocate-old-result-in-new)) update-cdr (perform (op vector-set!) (reg new-cdrs) (reg scan) (reg new)) (assign scan (op +) (reg scan) (const 1)) (goto (label gc-loop)) relocate-old-result-in-new (test (op pointer-to-pair?) (reg old)) (branch (label pair)) (assign new (reg old)) (goto (reg relocate-continue)) pair (assign oldcr (op vector-ref) (reg the-cars) (reg old)) (test (op broken-heart?) (reg oldcr)) (branch (label already-moved)) (assign new (reg free)) ;new location for pair ;; update free pointer (assign free (op +) (reg free) (const 1)) ;; Copy the car and cdr to new memory. (perform (op vector-set!) (reg new-cars) (reg new) (reg oldcr)) (assign oldcr (op vector-ref) (reg the-cdrs) (reg old)) (perform (op vector-set!) (reg new-cdrs) (reg new) (reg oldcr)) ;; Construct the broken heart. (perform (op vector-set!) (reg the-cars) (reg old) (const broken-heart)) (perform (op vector-set!) (reg the-cdrs) (reg old) (reg new)) (goto (reg relocate-continue)) already-moved (assign new (op vector-ref) (reg the-cdrs) (reg old)) (goto (reg relocate-continue)) gc-flip (assign temp (reg the-cdrs)) (assign the-cdrs (reg new-cdrs)) (assign new-cdrs (reg temp)) (assign temp (reg the-cars)) (assign the-cars (reg new-cars)) (assign new-cars (reg temp)) Cheney's algorithm Hal Abelson, Jerry Sussman and Julie Sussman Structure and Interpretation of Computer Programs MIT Press (1984) 5
  • 7. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms Schorr-Waite algorithm* H. Schorr and W. M. Waite An efficient machine-independent procedure for garbage collection in various list structures Comm. ACM 10, 8 (1967) dex registers and the accumulator for temporary storage, though in general any three storage locations could be used. One contains the address of the previous list element ex- amined, the second the address of the element currently being examined and the third the address of the next ele- ment on the list. This is necessary for the reversal of the pointers during the forward scan and their restoration during the reverse scan. In order to evaluate the speed of the routine, a Wise program was written which created five complete binary trees of depth 12. The remaining registers were discarded and the garbage collector called. Thus it was forced to trace a list structure containing over 20,000 registers, half of which were branch points. The elapsed time, according to the system clock, was 1.85 seconds. This list structure seems far more complex than any which would be en- countered in practice, and therefore a normal garbage col- lection should take far less time. The space occupied is also Q F ENTRY i SETI TO Ii FIRSTCELL OF L ST lNO IMAKE'TIMINUS 1I REVERSEPOINTER OFCELLI YES YES W:l scanned many times, and the program would fail by enter- ing a loop when attempting to trace a circular list. When run under the above conditions (5 binary trees of depth 12) the routine required 2.75 seconds for a complete trace. As a final comparison, a routine which stored branch points was coded and run using the same list structure. The program occupied 34 words, and an additional 48 words were allotted as a storage area for the branch points. Any given part of the list structure was only traversed once, so that this routine could trace any list for which the number of branch points it was required to store was less than 49. Only .448 seconds were required to complete the trace of the test structure. EXIT YES RESTORE POINTER OF CELL I LI - ~ I TO~~~iYES REVERSE POINTERI IN CAR OF I SET BRANCH PO NT FLAG 1SET 2: TO FIRST CELL OF BRANCH NO ( FIG. 3. Trace algorithm for a one-way list. Forward scan; reverse scan RESTOREPOINTER IN CAROFI. CLEAR BRANCH POINT FLAG. 504 Communications of the ACM Volume 10 / Number 8 / August, 1967 venience in drawing the flowchart, the list elements are assumed to be numbered sequentially. Thus, list element I + 1 follows list element I (i.e., list element I + 1 is pointed to by the TAIL of list element I). The routine uses two in- dex registers and the accumulator for temporary storage, though in general any three storage locations could be used. One contains the address of the previous list element ex- amined, the second the address of the element currently being examined and the third the address of the next ele- ment on the list. This is necessary for the reversal of the pointers during the forward scan and their restoration during the reverse scan. In order to evaluate the speed of the routine, a Wise program was written which created five complete binary trees of depth 12. The remaining registers were discarded and the garbage collector called. Thus it was forced to trace a list structure containing over 20,000 registers, half of which were branch points. The elapsed time, according to the system clock, was 1.85 seconds. This list structure seems far more complex than any which would be en- countered in practice, and therefore a normal garbage col- lection should take far less time. The space occupied is also Q F ENTRY i SETI TO Ii FIRSTCELL OF L ST lNO IMAKE'TIMINUS 1I REVERSEPOINTER OFCELLI YES YES W:l For purposes of comparison, a trace routine proposed by Wilkes was coded for the 7094. It required only two tempo- rary storage locations, and occupied 35 words of memory. This routine traversed a path from the head of a list to each terminal register separately. Thus much of the list was scanned many times, and the program would fail by enter- ing a loop when attempting to trace a circular list. When run under the above conditions (5 binary trees of depth 12) the routine required 2.75 seconds for a complete trace. As a final comparison, a routine which stored branch points was coded and run using the same list structure. The program occupied 34 words, and an additional 48 words were allotted as a storage area for the branch points. Any given part of the list structure was only traversed once, so that this routine could trace any list for which the number of branch points it was required to store was less than 49. Only .448 seconds were required to complete the trace of the test structure. EXIT YES RESTORE POINTER OF CELL I LI - ~ I TO~~~iYES REVERSE POINTERI IN CAR OF I SET BRANCH PO NT FLAG 1SET 2: TO FIRST CELL OF BRANCH NO ( FIG. 3. Trace algorithm for a one-way list. Forward scan; reverse scan RESTOREPOINTER IN CAROFI. CLEAR BRANCH POINT FLAG. 504 Communications of the ACM Volume 10 / Number 8 / August, 1967 *also attributed to Peter Deutsch 6
  • 8. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms Schorr-Waite algorithm Alfred V. Aho, John E. Hopcroft, and Jeffrey Ullman Data Structures and Algorithms (1st ed.) Addison-Wesley (1983) type atomtype = { some appropriate type; preferably of the same size as pointers } patterns = (PP, PA, AP, AA); celltype = record mark: boolean;
 case pattern: patterns of PP: (left: ↑ celltype; right: ↑ celltype); PA: (left: ↑ celltype; right: atomtype); AP: (left: atomtype; right: ↑ celltype); AA: (left: atomtype; right: atomtype); end; var source: ↑ celltype;
 memory: array [1..memorysize ] of celltype; procedure rotate ( var p1, p2, p3: ↑ celltype ); var temp: ↑ celltype; begin temp := p1; p1 := p2; p2 := p3; p3 := temp end; { rotate }
 function blockleft ( cell: celltype ): boolean; { test if left field is atom or null pointer } begin with cell do
 if (pattern = PP) or (pattern = PA) then if left <> nil then return (false); return (true) end; { blockleft } 
 function blockright ( cell : celltype ): boolean; { test if right field is atom or null pointer } begin
 with cell do if (pattern = PP) or (pattern = AP) then if right <> nil then return (false); return (true) end; { blockright } ... ... ... ... 7
  • 9. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms ISMM 2017 Albert Mingkun Yang and Tobias Wrigstad Type-assisted automatic garbage collection for lock-free data structures ACM SIGPLAN International Symposium on Memory Management (ISMM 2017) struct cds_t { int global_epoch; int max_entry; int size; per_thread_t *threads; }; struct per_thread_t { int in_critical; int local_epoch; int entry; wrapper_t limbo_list[3]; }; Figure 7. Central data structures for EBR implementation. 1. At allocation sites of spine objects, which are statically known from their types, one allocation call was replaced with calloc() (because Encore assumes memory is zeroed). 2. At the release point, a call to free() was used instead of the ORCA API. Freeing the spine object immediately is safe because of its guaranteed isolation inside the hot object. 3. The ACQUIRE was removed as there is no need for opaque roots when the underlying memory manager is not automatic. Previously, this was an increase of the foreign reference count for each object moved into the Isolde heap. 4.1 Implementation Details The C library contains three main public APIs. The function cri- tical_enter() should be called before loading any fields in the concurrent data structure (e.g., top in the Treiber Stack example) into a local variable. The function critical_exit() should be called when all pointers-on-stack-frame will not be used until the next call of critical_enter(). In our implementation, those two functions are placed at the entrance and the exit point of every method of a hot class. It is possible that using static analysis, one could find more precise boundary of the critical region. void critical_enter(cds_t *this) // entering critical region void critical_exit(cds_t *this) // exiting critical region void defer_dec(void *node) // safe version of rc decrement Full code for these functions is found in Figure 8 and the main data structures in Figure 7. Each concurrent data structure holds a cds_t object at run-time; max_entry is used to control the frequency of updating global epoch counter, as we discussed in previous section. size is set to be the max number of threads that could interact with concurrent data structure, which is used to iterate along the array referenced by threads. per_thread_t holds the info each thread maintains; determining if this thread is in critical region, local epoch, the number entrance into critical region, and a limbo list for each epoch. The thread local variable thread_index is used to store and retrieve thread-local EBR meta data. The details how it is initialized are provided later. In the implementation of critical_enter, we can see entry and max_entry is used to amortize the cost across multiple entrance into critical region. An extra level of indirection, wrapper_t, is used around spine objects in defer_dec because an object could be added into multiple limbo lists and even the same list multiple times. Notably, the original EBR scheme [11] does not need this because it requires developers to manually decide the unlinking point. Helper Functions The helper functions update_global(), try- _lock() and clean_list() are used internally by the functions in the public API. They are shown in Figure 9. The function update_global() limits the use of writes to the global epoch counter in critical sections. In our implementation, we implement 1 void critical_enter(cds_t *this) { 2 per_thread_t *thread = &this.threads[thread_index]; 3 while (true) { 4 thread.in_critical = 1; 5 int global_epoch = this.global_epoch; 6 7 if (thread->local_epoch != global_epoch) { 8 clean_list(&thread->limbo_list[global_epoch]); 9 thread->local_epoch = global_epoch; 10 thread->entry = 0; 11 } 12 13 if (thread->entry++ < this->max_entry) { 14 return; 15 } 16 17 thread->in_critical = 0; 18 thread->entry = 0; 19 update_global(this); 20 } 21 } 22 23 void critical_exit(cds_t *this) { 24 this->threads[thread_index].in_critical = 0; 25 } 26 27 void defer_dec(so_gc_t *so_gc, void *p) { 28 wrapper_t *w = new_wrapper(); 29 w->p = p; 30 per_thread_t *thread = 31 &so_gc->threads[so_thread_index]; 32 w->next = thread->limbo_list[thread->local_epoch]; 33 thread->limbo_list[thread->local_epoch] = w; 34 } Figure 8. Functions. The function clean_list() iterates over all objects in a limbo list, decrementing their reference counts, and reclaiming the objects whose RC reaches zero. In our implementation, this amounts to telling the actor on whose heap the object is allocated that the object is no longer needed externally, through an asynchronous message send. This allows the actor to free this memory during the next garbage collection cycle after receipt of this message. The body of the if-statement on Line 23 marks the moment when a spine object becomes β€œeffectively” unreachable, and its finaliser is called before the calling release API provided by the underlying memory manager. (In our implementation this amounts to calling a compiler-generated finaliser.) Switching the underlying memory manager requires a change to this code, for example, in the case of using malloc() and free(), this is a call to free(). 4.2 Limitations An inherent limitation of the epoch-based management of stack pointers requires that the maximum number threads that can in- teract with a concurrent data structure must be known when the program starts. In the case of the Encore, this limitation is unprob- lematic as Encore uses a fixed set of threads for an entire program run which are fixed at the start of the program. On thread cre- 1 hot Stack[t] 2 spec top : Node[t] 3 4 def push(element:t) : t 5 βˆ’βˆ’ signaling into critical region 6 CRITICAL_ENTER(this); 7 βˆ’βˆ’ element managed by H 8 var new_top = new Node() 9 βˆ’βˆ’ RC(new_top) = 0, new_top owned by current thread 10 new_top.element = move_in element 11 ACQUIRE(element); NULLIFY(element); 12 βˆ’βˆ’ element managed by S 13 do 14 val old_top = this.top 15 βˆ’βˆ’ RC(old_top) = 1 16 new_top.next = old_top 17 INC_RC(old_top); DEFER_DEC_RC(new_top.next); 18 βˆ’βˆ’ RC(old_top) = 2 19 until CAT(this.top, new_top.next, new_top) 20 βˆ’βˆ’ Added to limbo list for deferred decrement 21 DEFER_DEC_RC(new_top.next); 22 INC_RC(new_top); NULLIFY(new_top); 23 βˆ’βˆ’ RC(new_top) = 1, new_top owned by stack object 24 βˆ’βˆ’ leaving critical region 25 CRITICAL_EXIT(this); 26 end 27 28 def pop() : t 29 CRITICAL_ENTER(this); 30 do 31 val old_top = this.top 32 βˆ’βˆ’ RC(old_top) = 1, old_top owned by stack object 33 βˆ’βˆ’ old_top.element managed by S 34 until CAT(this.top, old_top, old_top.next) 35 βˆ’βˆ’ Added to limbo list for deferred decrement 36 DEFER_DEC_RC(old_top); 37 var tmp = move_out old_top.element 38 ACQUIRE(element); NULLIFY(old_top.element) 39 βˆ’βˆ’ tmp managed by H 40 CRITICAL_EXIT(this); 41 return tmp 42 end 43 end Figure 5. Complete example with GC instructions elaborated in. they may be in a cycle. The Recycler [1] implements trial deletio in the presence of mutators running concurrently. Having described reference counts for references on the hea we now describe our version of Fraser’s epoch-based reclamatio scheme [11] for dealing with stack-based references efficiently. 3. An Epoch-Based Reclamation Primer Reference counting is an intuitive technique: an object is live if an only if its reference count is positive. A naive implementation cou use a write barrier that increments and decrements RCs around a pointer writes, regardless of whether the destination is on the stac or on the heap. While likely inefficient, such an implementatio is correct in a sequential case. In a concurrent setting, howev before INC_RC(A) happens on reading a reference with RC=1 one thread, DEC_RC(A) could be happening concurrently in anoth thread, causing A to be prematurely collected. As a result, th reference count increase would be a write to a invalid memory. The root cause of this problem is the race between loadin the reference and incrementing the RC. Valois [23] solves th problem by assuming type persistence, i.e., once a block of memo is allocated for a type of objects, it could only be used for th particular type. A late increment may still write to invalid memo but it is guaranteed to be a slot reserved for RC only, and th effect could be reverted back if revalidation fails (the object h been collected). Detlefs et al. [8] show that this constraint ca be removed using a double CAS, which is able to operate on tw independent memory locations atomically. Sadly, no current CP supports such an atomic primitive. Neither type-persistence n double CAS constitutes a viable option in an automatic memo management solution, but, fortunately, the data race on counte can be avoided by applying RC to pointers on heap only. This h been used before (see e.g., Deutsch & Bobrow [9]), but as a wa of reducing the amount of RC manipulation due to local variable While our motivation differs, we can reap the benefit of reduce RC manipulation. Because RC attributed from pointers-on-stack discarded, RC becomes imprecise. Deutsch & Bobrow [9], place a object with RC = 0 in a Zero Count Table, and use stack scannin to either restore to correct RC for still reachable objects or reclai those surely dead ones. In the contrast, we use a modified versio of Fraser’s epoch-based [11] reclamation (EBR) scheme, whic addresses pointers on stack in a non-intrusive fashion. Due to its low synchronization, EBR compares favourably hazard pointers and reference counting according to [10], but to th best of our knowledge, it has never been used in automatic GC. EBR maintains a global epoch counter and a local epoch count 8
  • 10. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms new old root S root rootnew old free ! start 9 { βˆ—old , new , new + 1 } β†’ { βˆ—new , S , free } Cheney revisited (step 1)
  • 11. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms new old root S root rootnew old free !cell start 9 { βˆ—old , new , new + 1 } β†’ { βˆ—new , S , free } Cheney revisited (step 1)
  • 12. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms new old root S root rootnew old free !cell pointer into memory start 9 { βˆ—old , new , new + 1 } β†’ { βˆ—new , S , free } Cheney revisited (step 1)
  • 13. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms scan pointer new old root S root rootnew old free !cell pointer into memory start 9 { βˆ—old , new , new + 1 } β†’ { βˆ—new , S , free } Cheney revisited (step 1)
  • 14. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms scan pointer new old root S root rootnew old free !cell pointer into memory start 9 { βˆ—old , new , new + 1 } β†’ { βˆ—new , S , free } Cheney revisited (step 1) free pointer
  • 15. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms scan pointer co-assign new old root S root rootnew old free !cell pointer into memory start 9 { βˆ—old , new , new + 1 } β†’ { βˆ—new , S , free } Cheney revisited (step 1) free pointer
  • 16. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms { S + 1 } β†’ { S } (S < free ) ∧ (S↓ = 𝒢) Cheney revisited (step 2) atom 10 S A S A free free
  • 17. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms { S + 1 } β†’ { S } (S < free ) ∧ (S↓ = 𝒢) Cheney revisited (step 2) atom 10 pointers = β„• types = { 𝒢(tom), 𝓅(ointer), 𝒷(roken heart) } cells = pointers Γ— types S A S A free free
  • 18. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms { S + 1 } β†’ { S } (S < free ) ∧ (S↓ = 𝒢) Cheney revisited (step 2) atom 10 pointers = β„• types = { 𝒢(tom), 𝓅(ointer), 𝒷(roken heart) } cells = pointers Γ— types βˆ—: pointers ⟷ cells : p ⟷ [πœ‹, 𝜏] ↑: pointers ⟢ pointers : p ⟼ pβ†‘β‰‘βˆ—p πœ‹ ↓: pointers ⟢ types : p ⟼ pβ†“β‰‘βˆ—p 𝜏 S A S A free free
  • 19. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms { S + 1 } β†’ { S } (S < free ) ∧ (S↓ = 𝒢) Cheney revisited (step 2) atomA atom 10 pointers = β„• types = { 𝒢(tom), 𝓅(ointer), 𝒷(roken heart) } cells = pointers Γ— types βˆ—: pointers ⟷ cells : p ⟷ [πœ‹, 𝜏] ↑: pointers ⟢ pointers : p ⟼ pβ†‘β‰‘βˆ—p πœ‹ ↓: pointers ⟢ types : p ⟼ pβ†“β‰‘βˆ—p 𝜏 S A S A free free
  • 20. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms predicate { S + 1 } β†’ { S } (S < free ) ∧ (S↓ = 𝒢) Cheney revisited (step 2) atomA atom 10 pointers = β„• types = { 𝒢(tom), 𝓅(ointer), 𝒷(roken heart) } cells = pointers Γ— types βˆ—: pointers ⟷ cells : p ⟷ [πœ‹, 𝜏] ↑: pointers ⟢ pointers : p ⟼ pβ†‘β‰‘βˆ—p πœ‹ ↓: pointers ⟢ types : p ⟼ pβ†“β‰‘βˆ—p 𝜏 S A S A free free
  • 21. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms { βˆ—S↑ , [ βˆ… , 𝒷 ] , βˆ—(S↑ + 1) , [ free , 𝓅 ] , free + 2 , S + 1 } β†’ { βˆ—free , βˆ—S↑ , βˆ—(free + 1) , βˆ—(S↑ + 1) , free , S } Cheney revisited (step 3) unvisited 11 (S < free ) ∧ (S↓ = 𝓅) ∧ (S↑↓ β‰  𝒷) S car cdr S car cdr ! free free
  • 22. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms { βˆ—S↑ , [ βˆ… , 𝒷 ] , βˆ—(S↑ + 1) , [ free , 𝓅 ] , free + 2 , S + 1 } β†’ { βˆ—free , βˆ—S↑ , βˆ—(free + 1) , βˆ—(S↑ + 1) , free , S } Cheney revisited (step 3) broken heart! unvisited 11 (S < free ) ∧ (S↓ = 𝓅) ∧ (S↑↓ β‰  𝒷) S car cdr S car cdr ! free free
  • 23. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms { βˆ—S↑ , [ βˆ… , 𝒷 ] , βˆ—(S↑ + 1) , [ free , 𝓅 ] , free + 2 , S + 1 } β†’ { βˆ—free , βˆ—S↑ , βˆ—(free + 1) , βˆ—(S↑ + 1) , free , S } Cheney revisited (step 3) broken heart! a car cellcar a cdr cellcdr unvisited 11 (S < free ) ∧ (S↓ = 𝓅) ∧ (S↑↓ β‰  𝒷) S car cdr S car cdr ! free free
  • 24. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms { βˆ—(S↑ + 1) , S + 1 } β†’ { βˆ—S , S } (S < free ) ∧ (S↓ = 𝓅) ∧ (S↑↓ = 𝒷) Cheney revisited (step 4) visited 12 S S ! ! free free
  • 25. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms { new + 1 , old , new } β†’ { free , new , old } S = free Cheney revisited (step 5) stop 13 root new old new old free S root free
  • 26. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms Cheney revisited (graph) S↑↓ β‰  𝒷 Pointer to a pointer not to a broken heart S = some pointer Pointer to a pointer to a broken heartS↑↓ = 𝒷Pointer to an atom S↓ = 𝒢 S + 1 β†’ S βˆ—S↑ β†’ βˆ—free [ βˆ… , 𝒷 ] β†’ βˆ—S↑ (S↑ + 1)↑ β†’ βˆ—(free + 1) [ free , 𝓅 ] β†’ βˆ—(S↑ + 1) free + 2 β†’ free S + 1 β†’ S (S↑ + 1)↑ β†’ S↑ S + 1 β†’ S Pointer to a pointer S↓ = 𝓅 ! βˆ—old β†’ βˆ—new new β†’ S new + 1 β†’ free " S = free All cells updated old β†’ new new β†’ old Pointer to a pointer S < free 14
  • 27. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms Cheney revisited (code) typedef struct CEL * ptr; typedef enum {a, p, b} typ; typedef struct CEL { ptr P; typ T; } cel; static ptr free, new, old; static void Cheney(void) { ptr S, S_; *new = *old; // *new <- *old S = new; // S <- new for (free = new + 1; // free <- new + 1 S < free; // S < free S += 1) // S <- S + 1 if (S->T == p) // Sv = p { S_ = S->P; // S^ if (S_->T != b) // S^v β‰  b { *free = *S_; // *free <- *S^ *S_ = (cel){ 0, b }; // *S^ <- [βˆ…, b] *(free + 1) = *(S_ + 1); // *(free + 1) <- *(S^ + 1) *(S_ + 1) = (cel){ free, p };// *(S^ + 1) <- [free, p] free += 2; } // free <- free + 2 else // S^v = b *S = *(S_ + 1); } // *S <- *(S^ + 1) else; // Sv = a free = new + 1; // free <- new + 1 S = old; // old old = new; // old <- new new = S; } // new <- old 15
  • 28. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms Schorr-Waite revisited (step 1) P P C root memorymemory ! start 16 { βˆ… , memory } β†’ { P , C }
  • 29. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms Schorr-Waite revisited (step 1) P P C root memorymemory ! types = { 𝒢(tom), 𝓅(ointer) } marks = { 𝓂(arked), π“Š(nmarked) } cells = pointers Γ— types Γ— marks βˆ—: pointers ⟷ cells : p ⟷ [πœ‹, 𝜏, πœ‡] ↑: pointers ⟢ pointers : p ⟼ p↑ β‰‘βˆ—p πœ‹ ↓: pointers ⟢ types :p ⟼ p β‰‘βˆ—p 𝜏 ⇣: pointers ⟢ marks : p ⟼ p⇣ β‰‘βˆ—p πœ‡ start 16 { βˆ… , memory } β†’ { P , C }
  • 30. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms Schorr-Waite revisited (step 1) P P C root memorymemory ! types = { 𝒢(tom), 𝓅(ointer) } marks = { 𝓂(arked), π“Š(nmarked) } cells = pointers Γ— types Γ— marks βˆ—: pointers ⟷ cells : p ⟷ [πœ‹, 𝜏, πœ‡] ↑: pointers ⟢ pointers : p ⟼ p↑ β‰‘βˆ—p πœ‹ ↓: pointers ⟢ types :p ⟼ p β‰‘βˆ—p 𝜏 ⇣: pointers ⟢ marks : p ⟼ p⇣ β‰‘βˆ—p πœ‡ start 16 { βˆ… , memory } β†’ { P , C } current pointer
  • 31. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms Schorr-Waite revisited (step 1) P P C root memorymemory ! types = { 𝒢(tom), 𝓅(ointer) } marks = { 𝓂(arked), π“Š(nmarked) } cells = pointers Γ— types Γ— marks βˆ—: pointers ⟷ cells : p ⟷ [πœ‹, 𝜏, πœ‡] ↑: pointers ⟢ pointers : p ⟼ p↑ β‰‘βˆ—p πœ‹ ↓: pointers ⟢ types :p ⟼ p β‰‘βˆ—p 𝜏 ⇣: pointers ⟢ marks : p ⟼ p⇣ β‰‘βˆ—p πœ‡ start 16 { βˆ… , memory } β†’ { P , C } current pointer previous pointer
  • 32. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms Schorr-Waite revisited (step 2) C C A A P unvisitedatom 17 { [P , 𝓅 , 𝓂] , C , C↑ } β†’ { βˆ—C , P , C } (C⇣ = π“Š) ∧ (C↓ = 𝒢)
  • 33. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms C C P P Schorr-Waite revisited (step 3) unvisitedptr 18 { [P , 𝓅 , 𝓂] , C , C↑ } β†’ { βˆ—C , P , C } (C⇣ = π“Š) ∧ (C↓ = 𝓅)
  • 34. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms Schorr-Waite revisited (step 4) C C P visitedcar 19 { C + 1 } β†’ { C } (C⇣ = 𝓂) ∧ (P β‰  βˆ…) ∧ even?(C)
  • 35. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms Schorr-Waite revisited (step 4) C C P even pointer into memory pointer into memory odd pointer into memory visitedcar 19 { C + 1 } β†’ { C } (C⇣ = 𝓂) ∧ (P β‰  βˆ…) ∧ even?(C)
  • 36. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms P C P C Schorr-Waite revisited (step 5) visitedcdr 20 { [C – 1 , 𝓅 , 𝓂] , P , P↑ } β†’ { βˆ—P , C , P } (C⇣ = 𝓂) ∧ (P β‰  βˆ…) ∧ odd?(C)
  • 37. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms Schorr-Waite revisited (step 6) stop 21 { } β†’ { } (C⇣ = 𝓂) ∧ (P = βˆ…) P C !root
  • 38. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms Schorr-Waite revisited (graph) C↓ = 𝒢 Pointer to an unmarked atom C = some pointer Pointer to an unmarked pointer C↓ = 𝓅 Pointer to a marked cell C⇣ = 𝓂 even?(C)odd?(C) Odd pointer to a non-terminal marked cell [P , 𝓅 , 𝓂] β†’ βˆ—C C β†’ P C↑ β†’ C C + 1 β†’ C Pointer to an unmarked cell C⇣ = π“Š ! βˆ… β†’ P memory β†’ C " Even pointer to a non-terminal marked cell P β‰  βˆ… 𝓂 β†’ C⇣ P = βˆ… Stop Pointer to a non-terminal marked cell [C – 1 , 𝓅 , 𝓂] β†’ βˆ—P P β†’ C P↑ β†’ P 22
  • 39. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms Schorr-Waite revisited (code) typedef struct CEL * ptr; typedef enum {a, p} typ; typedef enum {m, u} mrk; typedef struct CEL { ptr P; typ T; mrk M; } cel; static unsigned is_even(ptr); static void mark(ptr); static const ptr null = (ptr)0; static ptr memory; static void Schorr_Waite(void) { ptr C, C_, P, P_; P = null; // P <- null for (C = memory;; ) // C <- memory if (C->M == u) // Cw = u if (C->P == a) // Cv = a mark(C); // Cw = m else // Cv = p { C_ = C->P; // C^ *C = (cel){ P, p, m }; // *C = [P, p, m] P = C; // P <- C C = C_; } // C <- C^ else // Cw = m if (P != null) // P β‰  null if (is_even(C)) // even?(C) C = C + 1; // C <- C + 1 else // odd?(C) { P_ = P->P; // P^ *P = (cel){ C - 1, p, m };// *P = [C - 1, p, m] C = P; // C <- P P = P_; } // P <- P^ else // P = null break; } // stop 23
  • 40. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms Compacting mark-sweep 0 1 6 2 3 1 12 6 1 2 6 1 0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 free root 15 1 0 14 9 2 2 1 2 13 1 8 3 7 0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 free root 15 1 0 1 2 2 3 0 6 2 1 2 2 0 0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 free root 15 1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 free root 9 0 1 2 3 0 6 6 2 2 0 6 ➠ ➠ ➠ H. B. M. Jonkers A fast garbage compaction algorithm Information Processing Letters, 9(1):25–30, July 1979 24
  • 41. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms Compacting mark-sweep typedef struct CEL * ptr; typedef enum {a, m, u} flg; typedef struct CEL { ptr P; flg F; } cel; static ptr memory; static unsigned is_raw(ptr), size(ptr); static void mark_sweep(ptr root) { ptr C, C_, C__; for (C = memory;;) // C <- memory if (C->F == a) // Cv = a C -= 1; // C = C - 1 else // Cv β‰  a { C_ = C->P; // C^ if (C->F == m) // Cv = m if (C_ == memory) // C^ = memory break; // stop else // C^ β‰  memory C = C_ - 1; // C <- C^ - 1 else // Cv = u { C__ = C_->P; // C^^ if (C_->F == m) // C^v = m { *C = *C__; // *C <- *C^^ *C__ = (cel){ C, m }; // *C__ <- [C, m] C -= 1; } // C <- C - 1 else // C^v = u { *C = *C_; // *C <- *C^ *C_ = (cel){ C, m }; // *C_ <- [C, m] if (is_raw(C__)) // raw?(C^^) C -= 1; // C <- C - 1 else // regular?(C^^) C = C_ + size(C__); }}}} // C <- C^ + size(C^^) 25
  • 42. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms CMS + Schorr-Waite C↓ = 𝒢 Pointer to an atom C = some pointer C↓ = π“Š Pointer to an unmarked pointer regular?(C↑↑) Pointer to an unmarked pointer to a marked pointer C↑↓ = 𝓂 βˆ—C↑↑ β†’ βˆ—C [C, 𝓂] β†’ βˆ—C↑↑ C - 1 β†’ C C↓ = 𝓂 Pointer to a marked cell C - 1 β†’ C C↑ - 1 β†’ C Pointer to an unmarked pointer to an unmarked raw header raw?(C↑↑) βˆ—C↑ β†’ βˆ—C [C, 𝓂] β†’ C↑ C - 1 β†’ C Pointer to an unmarked pointer to an unmarked regular header ! [root, π“Š] β†’ βˆ—memory memory β†’ C " C↑= memory Pointer to an unmarked pointer to an unmarked header C↑↓ = π“Š βˆ—C↑ β†’ βˆ—C [C, 𝓂] β†’ C↑ C↑ + size(C↑↑) β†’ C Pointer to a marked non- terminal pointer C↑≠ memory pair?(C↑) [C - 1, 𝓅 , 𝓂] β†’ βˆ—P P β†’ C P↑ β†’ P [C - 1, p, π“Š] β†’ βˆ—P P - 1 β†’ C P↑ β†’ P βˆ—C↑↑ β†’ βˆ—C [C, 𝓅 , 𝓂] β†’ βˆ—C↑↑ C - 1 β†’ C [C↑↑, 𝒽, 𝓂] β†’ βˆ—C [C, 𝓅, 𝓂] β†’ βˆ—C↑ chunk?(C) C↕ = 𝒢 Chunk pointer to an unmarked atom Pointer to an unmarked atom pair?(C) Pair pointer to an unmarked atom Some pointer chunk?(C↑) Pointer to an unmarked chunk pointer Pointer to an unmarked chunk pointer to an unmarked regular header regular?(C↑↑) Pointer to an unmarked chunk pointer to a marked cell C↑↓ = 𝓂 Chunk pointer to an unmarked chunk pointer to a marked header chunk?(C) Pair pointer to an unmarked chunk pointer to a marked header pair?(C) Pointer to an unmarked pair pointer Pointer to a marked cell C↓ = 𝓂 Pointer to a marked chunk chunk?(C) Chunk pointer to a marked chunk with a chunk thread chunk?(C↑) Chunk pointer to a marked chunk with pair thread pair?(C↑) Even pair pointer to a marked cell even?(C) Odd pair pointer to a marked cellodd?(C) Odd pair pointer to a marked cell with chunk thread Odd pair pointer to a marked cell with pair thread pair?(P) chunk?(P) Pointer to an unmarked cell C↓ = π“Š C - 1 β†’ C 𝓂 β†’ C↓ Pointer to an unmarked chunk pointer to an unmarked raw header raw?(C↑↑) Pair pointer to an unmarked chunk pointer to an unmarked raw header Chunk pointer to an unmarked chunk pointer to an unmarked raw header chunk?(C) [C↑↑, 𝒽, 𝓂] β†’ βˆ—C [C, 𝓅, 𝓂] β†’ βˆ—C↑ C - 1 β†’ C [[C↑↑, 𝒽, 𝓂] β†’ βˆ—C [C, 𝓅, 𝓂] β†’ βˆ—C↑ C↑ + size(C↑↑) β†’ C pair?(C) βˆ—C↑↑ β†’ βˆ—C [C, 𝓅 , 𝓂] β†’ βˆ—C↑↑ [P, 𝓅, 𝓂] β†’ βˆ—C C β†’ P C↑ β†’ C C↑ - 1 β†’ C C↑ β†’ C C + 1 β†’ C βˆ… β†’ P memory β†’ C ! Pointer to an unmarked chunk pointer to an unmarked cell C↑↓ = π“Š C↑ = memory" Pointer to a non- terminal marked cell C↑ β‰  memory Pair pointer to a marked cell pair?(C) Pointer to an unmarked pointer C↕ = 𝓅 C↓ = 𝒢 Pointer to an unmarked atom C = some pointer Pointer to an unmarked pointer C↓ = 𝓅 Pointer to a marked cell C⇣ = 𝓂 even?(C)odd?(C) Odd pointer to a non-terminal marked cell [P , 𝓅 , 𝓂] β†’ βˆ—C C β†’ P C↑ β†’ C C + 1 β†’ C Pointer to an unmarked cell C⇣ = π“Š ! βˆ… β†’ P memory β†’ C " Even pointer to a non-terminal marked cell P β‰  βˆ… 𝓂 β†’ C⇣ P = βˆ… Stop Pointer to a non-terminal marked cell [C – 1 , 𝓅 , 𝓂] β†’ βˆ—P P β†’ C P↑ β†’ P ➠ ➠ application#1 26
  • 43. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms CMS + Schorr-Waite C↓ = 𝒢 Pointer to an atom C = some pointer C↓ = π“Š Pointer to an unmarked pointer regular?(C↑↑) Pointer to an unmarked pointer to a marked pointer C↑↓ = 𝓂 βˆ—C↑↑ β†’ βˆ—C [C, 𝓂] β†’ βˆ—C↑↑ C - 1 β†’ C C↓ = 𝓂 Pointer to a marked cell C - 1 β†’ C C↑ - 1 β†’ C Pointer to an unmarked pointer to an unmarked raw header raw?(C↑↑) βˆ—C↑ β†’ βˆ—C [C, 𝓂] β†’ C↑ C - 1 β†’ C Pointer to an unmarked pointer to an unmarked regular header ! [root, π“Š] β†’ βˆ—memory memory β†’ C " C↑= memory Pointer to an unmarked pointer to an unmarked header C↑↓ = π“Š βˆ—C↑ β†’ βˆ—C [C, 𝓂] β†’ C↑ C↑ + size(C↑↑) β†’ C Pointer to a marked non- terminal pointer C↑≠ memory pair?(C↑) [C - 1, 𝓅 , 𝓂] β†’ βˆ—P P β†’ C P↑ β†’ P [C - 1, p, π“Š] β†’ βˆ—P P - 1 β†’ C P↑ β†’ P βˆ—C↑↑ β†’ βˆ—C [C, 𝓅 , 𝓂] β†’ βˆ—C↑↑ C - 1 β†’ C [C↑↑, 𝒽, 𝓂] β†’ βˆ—C [C, 𝓅, 𝓂] β†’ βˆ—C↑ chunk?(C) C↕ = 𝒢 Chunk pointer to an unmarked atom Pointer to an unmarked atom pair?(C) Pair pointer to an unmarked atom Some pointer chunk?(C↑) Pointer to an unmarked chunk pointer Pointer to an unmarked chunk pointer to an unmarked regular header regular?(C↑↑) Pointer to an unmarked chunk pointer to a marked cell C↑↓ = 𝓂 Chunk pointer to an unmarked chunk pointer to a marked header chunk?(C) Pair pointer to an unmarked chunk pointer to a marked header pair?(C) Pointer to an unmarked pair pointer Pointer to a marked cell C↓ = 𝓂 Pointer to a marked chunk chunk?(C) Chunk pointer to a marked chunk with a chunk thread chunk?(C↑) Chunk pointer to a marked chunk with pair thread pair?(C↑) Even pair pointer to a marked cell even?(C) Odd pair pointer to a marked cellodd?(C) Odd pair pointer to a marked cell with chunk thread Odd pair pointer to a marked cell with pair thread pair?(P) chunk?(P) Pointer to an unmarked cell C↓ = π“Š C - 1 β†’ C 𝓂 β†’ C↓ Pointer to an unmarked chunk pointer to an unmarked raw header raw?(C↑↑) Pair pointer to an unmarked chunk pointer to an unmarked raw header Chunk pointer to an unmarked chunk pointer to an unmarked raw header chunk?(C) [C↑↑, 𝒽, 𝓂] β†’ βˆ—C [C, 𝓅, 𝓂] β†’ βˆ—C↑ C - 1 β†’ C [[C↑↑, 𝒽, 𝓂] β†’ βˆ—C [C, 𝓅, 𝓂] β†’ βˆ—C↑ C↑ + size(C↑↑) β†’ C pair?(C) βˆ—C↑↑ β†’ βˆ—C [C, 𝓅 , 𝓂] β†’ βˆ—C↑↑ [P, 𝓅, 𝓂] β†’ βˆ—C C β†’ P C↑ β†’ C C↑ - 1 β†’ C C↑ β†’ C C + 1 β†’ C βˆ… β†’ P memory β†’ C ! Pointer to an unmarked chunk pointer to an unmarked cell C↑↓ = π“Š C↑ = memory" Pointer to a non- terminal marked cell C↑ β‰  memory Pair pointer to a marked cell pair?(C) Pointer to an unmarked pointer C↕ = 𝓅 C↓ = 𝒢 Pointer to an unmarked atom C = some pointer Pointer to an unmarked pointer C↓ = 𝓅 Pointer to a marked cell C⇣ = 𝓂 even?(C)odd?(C) Odd pointer to a non-terminal marked cell [P , 𝓅 , 𝓂] β†’ βˆ—C C β†’ P C↑ β†’ C C + 1 β†’ C Pointer to an unmarked cell C⇣ = π“Š ! βˆ… β†’ P memory β†’ C " Even pointer to a non-terminal marked cell P β‰  βˆ… 𝓂 β†’ C⇣ P = βˆ… Stop Pointer to a non-terminal marked cell [C – 1 , 𝓅 , 𝓂] β†’ βˆ—P P β†’ C P↑ β†’ P ➠ ➠ Why? application#1 26
  • 44. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms CMS + Schorr-Waite C↓ = 𝒢 Pointer to an atom C = some pointer C↓ = π“Š Pointer to an unmarked pointer regular?(C↑↑) Pointer to an unmarked pointer to a marked pointer C↑↓ = 𝓂 βˆ—C↑↑ β†’ βˆ—C [C, 𝓂] β†’ βˆ—C↑↑ C - 1 β†’ C C↓ = 𝓂 Pointer to a marked cell C - 1 β†’ C C↑ - 1 β†’ C Pointer to an unmarked pointer to an unmarked raw header raw?(C↑↑) βˆ—C↑ β†’ βˆ—C [C, 𝓂] β†’ C↑ C - 1 β†’ C Pointer to an unmarked pointer to an unmarked regular header ! [root, π“Š] β†’ βˆ—memory memory β†’ C " C↑= memory Pointer to an unmarked pointer to an unmarked header C↑↓ = π“Š βˆ—C↑ β†’ βˆ—C [C, 𝓂] β†’ C↑ C↑ + size(C↑↑) β†’ C Pointer to a marked non- terminal pointer C↑≠ memory pair?(C↑) [C - 1, 𝓅 , 𝓂] β†’ βˆ—P P β†’ C P↑ β†’ P [C - 1, p, π“Š] β†’ βˆ—P P - 1 β†’ C P↑ β†’ P βˆ—C↑↑ β†’ βˆ—C [C, 𝓅 , 𝓂] β†’ βˆ—C↑↑ C - 1 β†’ C [C↑↑, 𝒽, 𝓂] β†’ βˆ—C [C, 𝓅, 𝓂] β†’ βˆ—C↑ chunk?(C) C↕ = 𝒢 Chunk pointer to an unmarked atom Pointer to an unmarked atom pair?(C) Pair pointer to an unmarked atom Some pointer chunk?(C↑) Pointer to an unmarked chunk pointer Pointer to an unmarked chunk pointer to an unmarked regular header regular?(C↑↑) Pointer to an unmarked chunk pointer to a marked cell C↑↓ = 𝓂 Chunk pointer to an unmarked chunk pointer to a marked header chunk?(C) Pair pointer to an unmarked chunk pointer to a marked header pair?(C) Pointer to an unmarked pair pointer Pointer to a marked cell C↓ = 𝓂 Pointer to a marked chunk chunk?(C) Chunk pointer to a marked chunk with a chunk thread chunk?(C↑) Chunk pointer to a marked chunk with pair thread pair?(C↑) Even pair pointer to a marked cell even?(C) Odd pair pointer to a marked cellodd?(C) Odd pair pointer to a marked cell with chunk thread Odd pair pointer to a marked cell with pair thread pair?(P) chunk?(P) Pointer to an unmarked cell C↓ = π“Š C - 1 β†’ C 𝓂 β†’ C↓ Pointer to an unmarked chunk pointer to an unmarked raw header raw?(C↑↑) Pair pointer to an unmarked chunk pointer to an unmarked raw header Chunk pointer to an unmarked chunk pointer to an unmarked raw header chunk?(C) [C↑↑, 𝒽, 𝓂] β†’ βˆ—C [C, 𝓅, 𝓂] β†’ βˆ—C↑ C - 1 β†’ C [[C↑↑, 𝒽, 𝓂] β†’ βˆ—C [C, 𝓅, 𝓂] β†’ βˆ—C↑ C↑ + size(C↑↑) β†’ C pair?(C) βˆ—C↑↑ β†’ βˆ—C [C, 𝓅 , 𝓂] β†’ βˆ—C↑↑ [P, 𝓅, 𝓂] β†’ βˆ—C C β†’ P C↑ β†’ C C↑ - 1 β†’ C C↑ β†’ C C + 1 β†’ C βˆ… β†’ P memory β†’ C ! Pointer to an unmarked chunk pointer to an unmarked cell C↑↓ = π“Š C↑ = memory" Pointer to a non- terminal marked cell C↑ β‰  memory Pair pointer to a marked cell pair?(C) Pointer to an unmarked pointer C↕ = 𝓅 C↓ = 𝒢 Pointer to an unmarked atom C = some pointer Pointer to an unmarked pointer C↓ = 𝓅 Pointer to a marked cell C⇣ = 𝓂 even?(C)odd?(C) Odd pointer to a non-terminal marked cell [P , 𝓅 , 𝓂] β†’ βˆ—C C β†’ P C↑ β†’ C C + 1 β†’ C Pointer to an unmarked cell C⇣ = π“Š ! βˆ… β†’ P memory β†’ C " Even pointer to a non-terminal marked cell P β‰  βˆ… 𝓂 β†’ C⇣ P = βˆ… Stop Pointer to a non-terminal marked cell [C – 1 , 𝓅 , 𝓂] β†’ βˆ—P P β†’ C P↑ β†’ P ➠ ➠ Why? save storage on pairs application#1 26
  • 45. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms CMS + Schorr-Waite C↓ = 𝒢 Pointer to an atom C = some pointer C↓ = π“Š Pointer to an unmarked pointer regular?(C↑↑) Pointer to an unmarked pointer to a marked pointer C↑↓ = 𝓂 βˆ—C↑↑ β†’ βˆ—C [C, 𝓂] β†’ βˆ—C↑↑ C - 1 β†’ C C↓ = 𝓂 Pointer to a marked cell C - 1 β†’ C C↑ - 1 β†’ C Pointer to an unmarked pointer to an unmarked raw header raw?(C↑↑) βˆ—C↑ β†’ βˆ—C [C, 𝓂] β†’ C↑ C - 1 β†’ C Pointer to an unmarked pointer to an unmarked regular header ! [root, π“Š] β†’ βˆ—memory memory β†’ C " C↑= memory Pointer to an unmarked pointer to an unmarked header C↑↓ = π“Š βˆ—C↑ β†’ βˆ—C [C, 𝓂] β†’ C↑ C↑ + size(C↑↑) β†’ C Pointer to a marked non- terminal pointer C↑≠ memory pair?(C↑) [C - 1, 𝓅 , 𝓂] β†’ βˆ—P P β†’ C P↑ β†’ P [C - 1, p, π“Š] β†’ βˆ—P P - 1 β†’ C P↑ β†’ P βˆ—C↑↑ β†’ βˆ—C [C, 𝓅 , 𝓂] β†’ βˆ—C↑↑ C - 1 β†’ C [C↑↑, 𝒽, 𝓂] β†’ βˆ—C [C, 𝓅, 𝓂] β†’ βˆ—C↑ chunk?(C) C↕ = 𝒢 Chunk pointer to an unmarked atom Pointer to an unmarked atom pair?(C) Pair pointer to an unmarked atom Some pointer chunk?(C↑) Pointer to an unmarked chunk pointer Pointer to an unmarked chunk pointer to an unmarked regular header regular?(C↑↑) Pointer to an unmarked chunk pointer to a marked cell C↑↓ = 𝓂 Chunk pointer to an unmarked chunk pointer to a marked header chunk?(C) Pair pointer to an unmarked chunk pointer to a marked header pair?(C) Pointer to an unmarked pair pointer Pointer to a marked cell C↓ = 𝓂 Pointer to a marked chunk chunk?(C) Chunk pointer to a marked chunk with a chunk thread chunk?(C↑) Chunk pointer to a marked chunk with pair thread pair?(C↑) Even pair pointer to a marked cell even?(C) Odd pair pointer to a marked cellodd?(C) Odd pair pointer to a marked cell with chunk thread Odd pair pointer to a marked cell with pair thread pair?(P) chunk?(P) Pointer to an unmarked cell C↓ = π“Š C - 1 β†’ C 𝓂 β†’ C↓ Pointer to an unmarked chunk pointer to an unmarked raw header raw?(C↑↑) Pair pointer to an unmarked chunk pointer to an unmarked raw header Chunk pointer to an unmarked chunk pointer to an unmarked raw header chunk?(C) [C↑↑, 𝒽, 𝓂] β†’ βˆ—C [C, 𝓅, 𝓂] β†’ βˆ—C↑ C - 1 β†’ C [[C↑↑, 𝒽, 𝓂] β†’ βˆ—C [C, 𝓅, 𝓂] β†’ βˆ—C↑ C↑ + size(C↑↑) β†’ C pair?(C) βˆ—C↑↑ β†’ βˆ—C [C, 𝓅 , 𝓂] β†’ βˆ—C↑↑ [P, 𝓅, 𝓂] β†’ βˆ—C C β†’ P C↑ β†’ C C↑ - 1 β†’ C C↑ β†’ C C + 1 β†’ C βˆ… β†’ P memory β†’ C ! Pointer to an unmarked chunk pointer to an unmarked cell C↑↓ = π“Š C↑ = memory" Pointer to a non- terminal marked cell C↑ β‰  memory Pair pointer to a marked cell pair?(C) Pointer to an unmarked pointer C↕ = 𝓅 C↓ = 𝒢 Pointer to an unmarked atom C = some pointer Pointer to an unmarked pointer C↓ = 𝓅 Pointer to a marked cell C⇣ = 𝓂 even?(C)odd?(C) Odd pointer to a non-terminal marked cell [P , 𝓅 , 𝓂] β†’ βˆ—C C β†’ P C↑ β†’ C C + 1 β†’ C Pointer to an unmarked cell C⇣ = π“Š ! βˆ… β†’ P memory β†’ C " Even pointer to a non-terminal marked cell P β‰  βˆ… 𝓂 β†’ C⇣ P = βˆ… Stop Pointer to a non-terminal marked cell [C – 1 , 𝓅 , 𝓂] β†’ βˆ—P P β†’ C P↑ β†’ P ➠ ➠ Why? save storage on pairs fixed data far references application#1 26
  • 46. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms C↓ = 𝒢 Pointer to an atom C = some pointer C↓ = π“Š Pointer to an unmarked pointer regular?(C↑↑) Pointer to an unmarked pointer to a marked pointer C↑↓ = 𝓂 βˆ—C↑↑ β†’ βˆ—C [C, 𝓂] β†’ βˆ—C↑↑ C - 1 β†’ C C↓ = 𝓂 Pointer to a marked cell C - 1 β†’ C C↑ - 1 β†’ C Pointer to an unmarked pointer to an unmarked raw header raw?(C↑↑) βˆ—C↑ β†’ βˆ—C [C, 𝓂] β†’ C↑ C - 1 β†’ C Pointer to an unmarked pointer to an unmarked regular header ! [root, π“Š] β†’ βˆ—memory memory β†’ C " C↑= memory Pointer to an unmarked pointer to an unmarked header C↑↓ = π“Š βˆ—C↑ β†’ βˆ—C [C, 𝓂] β†’ C↑ C↑ + size(C↑↑) β†’ C Pointer to a marked non- terminal pointer C↑≠ memory C↓ = 𝒢 Pointer to an unmarked atom C = some pointer Pointer to an unmarked pointer C↓ = 𝓅 Pointer to a marked cell C⇣ = 𝓂 even?(C)odd?(C) Odd pointer to a non-terminal marked cell [P , 𝓅 , 𝓂] β†’ βˆ—C C β†’ P C↑ β†’ C C + 1 β†’ C Pointer to an unmarked cell C⇣ = π“Š ! βˆ… β†’ P memory β†’ C " Even pointer to a non-terminal marked cell P β‰  βˆ… 𝓂 β†’ C⇣ P = βˆ… Stop Pointer to a non-terminal marked cell [C – 1 , 𝓅 , 𝓂] β†’ βˆ—P P β†’ C P↑ β†’ P CMS + Schorr-Waite pair?(C↑) [C - 1, 𝓅 , 𝓂] β†’ βˆ—P P β†’ C P↑ β†’ P [C - 1, p, π“Š] β†’ βˆ—P P - 1 β†’ C P↑ β†’ P βˆ—C↑↑ β†’ βˆ—C [C, 𝓅 , 𝓂] β†’ βˆ—C↑↑ C - 1 β†’ C [C↑↑, 𝒽, 𝓂] β†’ βˆ—C [C, 𝓅, 𝓂] β†’ βˆ—C↑ chunk?(C) C↕ = 𝒢 Chunk pointer to an unmarked atom Pointer to an unmarked atom pair?(C) Pair pointer to an unmarked atom Some pointer chunk?(C↑) Pointer to an unmarked chunk pointer Pointer to an unmarked chunk pointer to an unmarked regular header regular?(C↑↑) Pointer to an unmarked chunk pointer to a marked cell C↑↓ = 𝓂 Chunk pointer to an unmarked chunk pointer to a marked header chunk?(C) Pair pointer to an unmarked chunk pointer to a marked header pair?(C) Pointer to an unmarked pair pointer Pointer to a marked cell C↓ = 𝓂 Pointer to a marked chunk chunk?(C) Chunk pointer to a marked chunk with a chunk thread chunk?(C↑) Chunk pointer to a marked chunk with pair thread pair?(C↑) Even pair pointer to a marked cell even?(C) Odd pair pointer to a marked cellodd?(C) Odd pair pointer to a marked cell with chunk thread Odd pair pointer to a marked cell with pair thread pair?(P) chunk?(P) Pointer to an unmarked cell C↓ = π“Š C - 1 β†’ C 𝓂 β†’ C↓ Pointer to an unmarked chunk pointer to an unmarked raw header raw?(C↑↑) Pair pointer to an unmarked chunk pointer to an unmarked raw header Chunk pointer to an unmarked chunk pointer to an unmarked raw header chunk?(C) [C↑↑, 𝒽, 𝓂] β†’ βˆ—C [C, 𝓅, 𝓂] β†’ βˆ—C↑ C - 1 β†’ C [[C↑↑, 𝒽, 𝓂] β†’ βˆ—C [C, 𝓅, 𝓂] β†’ βˆ—C↑ C↑ + size(C↑↑) β†’ C pair?(C) βˆ—C↑↑ β†’ βˆ—C [C, 𝓅 , 𝓂] β†’ βˆ—C↑↑ [P, 𝓅, 𝓂] β†’ βˆ—C C β†’ P C↑ β†’ C C↑ - 1 β†’ C C↑ β†’ C C + 1 β†’ C βˆ… β†’ P memory β†’ C ! Pointer to an unmarked chunk pointer to an unmarked cell C↑↓ = π“Š C↑ = memory" Pointer to a non- terminal marked cell C↑ β‰  memory Pair pointer to a marked cell pair?(C) Pointer to an unmarked pointer C↕ = 𝓅 ➠ ➠ 27
  • 47. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms C↓ = 𝒢 Pointer to an atom C = some pointer C↓ = π“Š Pointer to an unmarked pointer regular?(C↑↑) Pointer to an unmarked pointer to a marked pointer C↑↓ = 𝓂 βˆ—C↑↑ β†’ βˆ—C [C, 𝓂] β†’ βˆ—C↑↑ C - 1 β†’ C C↓ = 𝓂 Pointer to a marked cell C - 1 β†’ C C↑ - 1 β†’ C Pointer to an unmarked pointer to an unmarked raw header raw?(C↑↑) βˆ—C↑ β†’ βˆ—C [C, 𝓂] β†’ C↑ C - 1 β†’ C Pointer to an unmarked pointer to an unmarked regular header ! [root, π“Š] β†’ βˆ—memory memory β†’ C " C↑= memory Pointer to an unmarked pointer to an unmarked header C↑↓ = π“Š βˆ—C↑ β†’ βˆ—C [C, 𝓂] β†’ C↑ C↑ + size(C↑↑) β†’ C Pointer to a marked non- terminal pointer C↑≠ memory C↓ = 𝒢 Pointer to an unmarked atom C = some pointer Pointer to an unmarked pointer C↓ = 𝓅 Pointer to a marked cell C⇣ = 𝓂 even?(C)odd?(C) Odd pointer to a non-terminal marked cell [P , 𝓅 , 𝓂] β†’ βˆ—C C β†’ P C↑ β†’ C C + 1 β†’ C Pointer to an unmarked cell C⇣ = π“Š ! βˆ… β†’ P memory β†’ C " Even pointer to a non-terminal marked cell P β‰  βˆ… 𝓂 β†’ C⇣ P = βˆ… Stop Pointer to a non-terminal marked cell [C – 1 , 𝓅 , 𝓂] β†’ βˆ—P P β†’ C P↑ β†’ P CMS + Schorr-Waite pair?(C↑) [C - 1, 𝓅 , 𝓂] β†’ βˆ—P P β†’ C P↑ β†’ P [C - 1, p, π“Š] β†’ βˆ—P P - 1 β†’ C P↑ β†’ P βˆ—C↑↑ β†’ βˆ—C [C, 𝓅 , 𝓂] β†’ βˆ—C↑↑ C - 1 β†’ C [C↑↑, 𝒽, 𝓂] β†’ βˆ—C [C, 𝓅, 𝓂] β†’ βˆ—C↑ chunk?(C) C↕ = 𝒢 Chunk pointer to an unmarked atom Pointer to an unmarked atom pair?(C) Pair pointer to an unmarked atom Some pointer chunk?(C↑) Pointer to an unmarked chunk pointer Pointer to an unmarked chunk pointer to an unmarked regular header regular?(C↑↑) Pointer to an unmarked chunk pointer to a marked cell C↑↓ = 𝓂 Chunk pointer to an unmarked chunk pointer to a marked header chunk?(C) Pair pointer to an unmarked chunk pointer to a marked header pair?(C) Pointer to an unmarked pair pointer Pointer to a marked cell C↓ = 𝓂 Pointer to a marked chunk chunk?(C) Chunk pointer to a marked chunk with a chunk thread chunk?(C↑) Chunk pointer to a marked chunk with pair thread pair?(C↑) Even pair pointer to a marked cell even?(C) Odd pair pointer to a marked cellodd?(C) Odd pair pointer to a marked cell with chunk thread Odd pair pointer to a marked cell with pair thread pair?(P) chunk?(P) Pointer to an unmarked cell C↓ = π“Š C - 1 β†’ C 𝓂 β†’ C↓ Pointer to an unmarked chunk pointer to an unmarked raw header raw?(C↑↑) Pair pointer to an unmarked chunk pointer to an unmarked raw header Chunk pointer to an unmarked chunk pointer to an unmarked raw header chunk?(C) [C↑↑, 𝒽, 𝓂] β†’ βˆ—C [C, 𝓅, 𝓂] β†’ βˆ—C↑ C - 1 β†’ C [[C↑↑, 𝒽, 𝓂] β†’ βˆ—C [C, 𝓅, 𝓂] β†’ βˆ—C↑ C↑ + size(C↑↑) β†’ C pair?(C) βˆ—C↑↑ β†’ βˆ—C [C, 𝓅 , 𝓂] β†’ βˆ—C↑↑ [P, 𝓅, 𝓂] β†’ βˆ—C C β†’ P C↑ β†’ C C↑ - 1 β†’ C C↑ β†’ C C + 1 β†’ C βˆ… β†’ P memory β†’ C ! Pointer to an unmarked chunk pointer to an unmarked cell C↑↓ = π“Š C↑ = memory" Pointer to a non- terminal marked cell C↑ β‰  memory Pair pointer to a marked cell pair?(C) Pointer to an unmarked pointer C↕ = 𝓅 ➠ ➠ 7 transitions 27
  • 48. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms C↓ = 𝒢 Pointer to an atom C = some pointer C↓ = π“Š Pointer to an unmarked pointer regular?(C↑↑) Pointer to an unmarked pointer to a marked pointer C↑↓ = 𝓂 βˆ—C↑↑ β†’ βˆ—C [C, 𝓂] β†’ βˆ—C↑↑ C - 1 β†’ C C↓ = 𝓂 Pointer to a marked cell C - 1 β†’ C C↑ - 1 β†’ C Pointer to an unmarked pointer to an unmarked raw header raw?(C↑↑) βˆ—C↑ β†’ βˆ—C [C, 𝓂] β†’ C↑ C - 1 β†’ C Pointer to an unmarked pointer to an unmarked regular header ! [root, π“Š] β†’ βˆ—memory memory β†’ C " C↑= memory Pointer to an unmarked pointer to an unmarked header C↑↓ = π“Š βˆ—C↑ β†’ βˆ—C [C, 𝓂] β†’ C↑ C↑ + size(C↑↑) β†’ C Pointer to a marked non- terminal pointer C↑≠ memory C↓ = 𝒢 Pointer to an unmarked atom C = some pointer Pointer to an unmarked pointer C↓ = 𝓅 Pointer to a marked cell C⇣ = 𝓂 even?(C)odd?(C) Odd pointer to a non-terminal marked cell [P , 𝓅 , 𝓂] β†’ βˆ—C C β†’ P C↑ β†’ C C + 1 β†’ C Pointer to an unmarked cell C⇣ = π“Š ! βˆ… β†’ P memory β†’ C " Even pointer to a non-terminal marked cell P β‰  βˆ… 𝓂 β†’ C⇣ P = βˆ… Stop Pointer to a non-terminal marked cell [C – 1 , 𝓅 , 𝓂] β†’ βˆ—P P β†’ C P↑ β†’ P CMS + Schorr-Waite pair?(C↑) [C - 1, 𝓅 , 𝓂] β†’ βˆ—P P β†’ C P↑ β†’ P [C - 1, p, π“Š] β†’ βˆ—P P - 1 β†’ C P↑ β†’ P βˆ—C↑↑ β†’ βˆ—C [C, 𝓅 , 𝓂] β†’ βˆ—C↑↑ C - 1 β†’ C [C↑↑, 𝒽, 𝓂] β†’ βˆ—C [C, 𝓅, 𝓂] β†’ βˆ—C↑ chunk?(C) C↕ = 𝒢 Chunk pointer to an unmarked atom Pointer to an unmarked atom pair?(C) Pair pointer to an unmarked atom Some pointer chunk?(C↑) Pointer to an unmarked chunk pointer Pointer to an unmarked chunk pointer to an unmarked regular header regular?(C↑↑) Pointer to an unmarked chunk pointer to a marked cell C↑↓ = 𝓂 Chunk pointer to an unmarked chunk pointer to a marked header chunk?(C) Pair pointer to an unmarked chunk pointer to a marked header pair?(C) Pointer to an unmarked pair pointer Pointer to a marked cell C↓ = 𝓂 Pointer to a marked chunk chunk?(C) Chunk pointer to a marked chunk with a chunk thread chunk?(C↑) Chunk pointer to a marked chunk with pair thread pair?(C↑) Even pair pointer to a marked cell even?(C) Odd pair pointer to a marked cellodd?(C) Odd pair pointer to a marked cell with chunk thread Odd pair pointer to a marked cell with pair thread pair?(P) chunk?(P) Pointer to an unmarked cell C↓ = π“Š C - 1 β†’ C 𝓂 β†’ C↓ Pointer to an unmarked chunk pointer to an unmarked raw header raw?(C↑↑) Pair pointer to an unmarked chunk pointer to an unmarked raw header Chunk pointer to an unmarked chunk pointer to an unmarked raw header chunk?(C) [C↑↑, 𝒽, 𝓂] β†’ βˆ—C [C, 𝓅, 𝓂] β†’ βˆ—C↑ C - 1 β†’ C [[C↑↑, 𝒽, 𝓂] β†’ βˆ—C [C, 𝓅, 𝓂] β†’ βˆ—C↑ C↑ + size(C↑↑) β†’ C pair?(C) βˆ—C↑↑ β†’ βˆ—C [C, 𝓅 , 𝓂] β†’ βˆ—C↑↑ [P, 𝓅, 𝓂] β†’ βˆ—C C β†’ P C↑ β†’ C C↑ - 1 β†’ C C↑ β†’ C C + 1 β†’ C βˆ… β†’ P memory β†’ C ! Pointer to an unmarked chunk pointer to an unmarked cell C↑↓ = π“Š C↑ = memory" Pointer to a non- terminal marked cell C↑ β‰  memory Pair pointer to a marked cell pair?(C) Pointer to an unmarked pointer C↕ = 𝓅 ➠ ➠ 7 transitions 6 transitions 27
  • 49. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms C↓ = 𝒢 Pointer to an atom C = some pointer C↓ = π“Š Pointer to an unmarked pointer regular?(C↑↑) Pointer to an unmarked pointer to a marked pointer C↑↓ = 𝓂 βˆ—C↑↑ β†’ βˆ—C [C, 𝓂] β†’ βˆ—C↑↑ C - 1 β†’ C C↓ = 𝓂 Pointer to a marked cell C - 1 β†’ C C↑ - 1 β†’ C Pointer to an unmarked pointer to an unmarked raw header raw?(C↑↑) βˆ—C↑ β†’ βˆ—C [C, 𝓂] β†’ C↑ C - 1 β†’ C Pointer to an unmarked pointer to an unmarked regular header ! [root, π“Š] β†’ βˆ—memory memory β†’ C " C↑= memory Pointer to an unmarked pointer to an unmarked header C↑↓ = π“Š βˆ—C↑ β†’ βˆ—C [C, 𝓂] β†’ C↑ C↑ + size(C↑↑) β†’ C Pointer to a marked non- terminal pointer C↑≠ memory C↓ = 𝒢 Pointer to an unmarked atom C = some pointer Pointer to an unmarked pointer C↓ = 𝓅 Pointer to a marked cell C⇣ = 𝓂 even?(C)odd?(C) Odd pointer to a non-terminal marked cell [P , 𝓅 , 𝓂] β†’ βˆ—C C β†’ P C↑ β†’ C C + 1 β†’ C Pointer to an unmarked cell C⇣ = π“Š ! βˆ… β†’ P memory β†’ C " Even pointer to a non-terminal marked cell P β‰  βˆ… 𝓂 β†’ C⇣ P = βˆ… Stop Pointer to a non-terminal marked cell [C – 1 , 𝓅 , 𝓂] β†’ βˆ—P P β†’ C P↑ β†’ P CMS + Schorr-Waite pair?(C↑) [C - 1, 𝓅 , 𝓂] β†’ βˆ—P P β†’ C P↑ β†’ P [C - 1, p, π“Š] β†’ βˆ—P P - 1 β†’ C P↑ β†’ P βˆ—C↑↑ β†’ βˆ—C [C, 𝓅 , 𝓂] β†’ βˆ—C↑↑ C - 1 β†’ C [C↑↑, 𝒽, 𝓂] β†’ βˆ—C [C, 𝓅, 𝓂] β†’ βˆ—C↑ chunk?(C) C↕ = 𝒢 Chunk pointer to an unmarked atom Pointer to an unmarked atom pair?(C) Pair pointer to an unmarked atom Some pointer chunk?(C↑) Pointer to an unmarked chunk pointer Pointer to an unmarked chunk pointer to an unmarked regular header regular?(C↑↑) Pointer to an unmarked chunk pointer to a marked cell C↑↓ = 𝓂 Chunk pointer to an unmarked chunk pointer to a marked header chunk?(C) Pair pointer to an unmarked chunk pointer to a marked header pair?(C) Pointer to an unmarked pair pointer Pointer to a marked cell C↓ = 𝓂 Pointer to a marked chunk chunk?(C) Chunk pointer to a marked chunk with a chunk thread chunk?(C↑) Chunk pointer to a marked chunk with pair thread pair?(C↑) Even pair pointer to a marked cell even?(C) Odd pair pointer to a marked cellodd?(C) Odd pair pointer to a marked cell with chunk thread Odd pair pointer to a marked cell with pair thread pair?(P) chunk?(P) Pointer to an unmarked cell C↓ = π“Š C - 1 β†’ C 𝓂 β†’ C↓ Pointer to an unmarked chunk pointer to an unmarked raw header raw?(C↑↑) Pair pointer to an unmarked chunk pointer to an unmarked raw header Chunk pointer to an unmarked chunk pointer to an unmarked raw header chunk?(C) [C↑↑, 𝒽, 𝓂] β†’ βˆ—C [C, 𝓅, 𝓂] β†’ βˆ—C↑ C - 1 β†’ C [[C↑↑, 𝒽, 𝓂] β†’ βˆ—C [C, 𝓅, 𝓂] β†’ βˆ—C↑ C↑ + size(C↑↑) β†’ C pair?(C) βˆ—C↑↑ β†’ βˆ—C [C, 𝓅 , 𝓂] β†’ βˆ—C↑↑ [P, 𝓅, 𝓂] β†’ βˆ—C C β†’ P C↑ β†’ C C↑ - 1 β†’ C C↑ β†’ C C + 1 β†’ C βˆ… β†’ P memory β†’ C ! Pointer to an unmarked chunk pointer to an unmarked cell C↑↓ = π“Š C↑ = memory" Pointer to a non- terminal marked cell C↑ β‰  memory Pair pointer to a marked cell pair?(C) Pointer to an unmarked pointer C↕ = 𝓅 ➠ ➠ 7 transitions 6 transitions 15 transitions 27
  • 50. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms CMS + Schorr-Waite typedef struct CEL * ptr; typedef enum { a, h = a, p } typ; typedef enum { m, u } mrk; typedef struct CEL { ptr P; typ T; mrk M; } cel; static const ptr null = (ptr)0; static const unsigned max; static ptr free, memory; static unsigned is_chunk(ptr), size(ptr); static ptr hdr(unsigned); static void jonkers_schorr_waite(void) { ptr A, D, S, S_; unsigned C, L1; A = null; // A <- null *free = (cel){0, h, m }; // *free <- [0, h, m] for (S = D = memory + 1;;) // S <- D <- memory + 1 { S_ = S->P; // S^ if (A == null) // A = null if (S->M == m) // Sv = m if (S < free) // S < free { A = S; // A <- S S = S_; // S <- S^ C = 0; } // C <- 0 else // S = free break; // stop else // Sv = u { A = S; // A <- S C = size(S_) + 1; // C <- size(S^) + 1 S += C; } // S <- S + size(S^) + 1 else // A β‰  null if (C == 0) // C = 0 if (S->T == h) // Sw = h { L1 = size(S_) + 1; // size(S^) + 1 *A = *S; // *A <- *S if (is_chunk(S)) // chunk?(S) *S = (cel){ D, p, u };// *S <- [D, p, u] else // pair?(S) *S = (cel){ D, p, m };// *S <- [D, p, m] S = A + L1; // S <- A + size(S^) + 1 D += L1; // D <- D + size(S^) + 1 A = null; } // A <- null else // Sw = p { if (is_chunk(S)) // chunk?(S) *S = (cel){ D, p, u }; // *S <- [D, p, u] else // pair?(S) *S = (cel){ D, p, m }; // *S <- [D, p, m] S = S_; } // S <- S^ else // C > 0 if (S->M == m) // Sv = m { *A = (cel){ hdr(C - 1), h, u }; // *A <- [hdr(C-1), h, u] A = null; // A <- null C = 0; } // C = 0 else // Sv = u { L1 = size(S_) + 1; // size(S^) + 1 if (C + L1 > max) // C + size(S^) β‰₯ max { *A = (cel){ hdr(C - 1), h, u };// *A <- [hdr(C-1), h, u] A = null; // A <- null C = 0; } // C = 0 else // C + size(S^) ≀ max { S += L1; // S <- S + size(S^) + 1 C += L1; }}}} // C <- C + size(S^) + 1 28
  • 51. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms CMS + Schorr-Waite 29 typedef struct CEL * ptr; typedef enum { a, h = a, p } typ; typedef enum { m, u } mrk; typedef struct CEL { ptr P; typ T; mrk M; } cel; static const ptr null = (ptr)0; static const unsigned max; static ptr free, memory; static unsigned is_chunk(ptr), size(ptr); static ptr hdr(unsigned); static void jonkers_schorr_waite(void) { ptr A, D, S, S_; unsigned C, L1; A = null; // A <- null *free = (cel){0, h, m }; // *free <- [0, h, m] for (S = D = memory + 1;;) // S <- D <- memory + 1 { S_ = S->P; // S^ if (A == null) // A = null if (S->M == m) // Sv = m if (S < free) // S < free { A = S; // A <- S S = S_; // S <- S^ C = 0; } // C <- 0 else // S = free break; // stop else // Sv = u { A = S; // A <- S C = size(S_) + 1; // C <- size(S^) + 1 S += C; } // S <- S + size(S^) + 1 else // A β‰  null if (C == 0) // C = 0 if (S->T == h) // Sw = h { L1 = size(S_) + 1; // size(S^) + 1 *A = *S; // *A <- *S if (is_chunk(S)) // chunk?(S) *S = (cel){ D, p, u };// *S <- [D, p, u] else // pair?(S) *S = (cel){ D, p, m };// *S <- [D, p, m] S = A + L1; // S <- A + size(S^) + 1 D += L1; // D <- D + size(S^) + 1 A = null; } // A <- null else // Sw = p { if (is_chunk(S)) // chunk?(S) *S = (cel){ D, p, u }; // *S <- [D, p, u] else // pair?(S) *S = (cel){ D, p, m }; // *S <- [D, p, m] S = S_; } // S <- S^ else // C > 0 if (S->M == m) // Sv = m { *A = (cel){ hdr(C - 1), h, u }; // *A <- [hdr(C-1), h, u] A = null; // A <- null C = 0; } // C = 0 else // Sv = u { L1 = size(S_) + 1; // size(S^) + 1 if (C + L1 > max) // C + size(S^) β‰₯ max { *A = (cel){ hdr(C - 1), h, u };// *A <- [hdr(C-1), h, u] A = null; // A <- null C = 0; } // C = 0 else // C + size(S^) ≀ max { S += L1; // S <- S + size(S^) + 1 C += L1; }}}} // C <- C + size(S^) + 1 50 lines of executable specification
  • 52. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms 0 1 6 2 3 1 12 6 1 2 6 1 0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 free root 15 1 0 14 9 2 2 1 2 13 1 8 3 7 0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 free root 15 1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 free root 9 0 1 2 3 0 6 6 2 2 0 6 Fixing CMS: the problem application#2 0 1 2 2 3 0 6 2 1 2 2 0 0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 free root 15 1 ➠ ➠ ➠ 30 30
  • 53. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms 0 1 6 2 3 1 12 6 1 2 6 1 0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 free root 15 1 0 14 9 2 2 1 2 13 1 8 3 7 0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 free root 15 1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 free root 9 0 1 2 3 0 6 6 2 2 0 6 Fixing CMS: the problem application#2 0 1 2 2 3 0 6 2 1 2 2 0 0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 free root 15 1 ➠ ➠ ➠ 30 30
  • 54. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms Fixing CMS: partial solution 31
  • 55. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms Fixing CMS: partial solution sequential scan of complete heap 31
  • 56. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms Fixing CMS: partial solution sequential scan of complete heap compress mark bits in bitmap 31
  • 57. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms Fixing CMS: partial solution sequential scan of complete heap compress mark bits in bitmap but: in dynamical languages this bitmap is sparse 31
  • 58. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms Fixing CMS: testcase (define (xTree-balance xTree) (define root (cadr xTree)) (define size (caddr xTree)) (define (traverse root size required) (if (pair? root) (begin (define lCount (car root)) (define lTree (cadr root)) (define rTree (caddr root)) (define rCount (- size required)) (if (> lCount required) (begin (define lTree (traverse lTree lCount required)) (define llTree (cadr lTree)) (define rlTree (caddr lTree)) (define rTree (list (- lCount required) rlTree rTree)) (define rrTree (traverse rTree rCount (quotient rCount 2))) (list required llTree rrTree)) (if (< lCount required) (begin (define rTree (traverse rTree (- size lCount) (- required lCount))) (define lrTree (cadr rTree)) (define rrTree (caddr rTree)) (define lTree (list lCount lTree lrTree)) (define llTree (traverse lTree required (quotient required 2))) (list required llTree rrTree)) (begin (define lTree (traverse lTree lCount (quotient lCount 2))) (define rTree (traverse rTree rCount (quotient rCount 2))) (list lCount lTree rTree))))) (if (null? root) 'error root))) (traverse root size (quotient size 2))) 32
  • 59. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms Fixing CMS: testcase (define (xTree-balance xTree) (define root (cadr xTree)) (define size (caddr xTree)) (define (traverse root size required) (if (pair? root) (begin (define lCount (car root)) (define lTree (cadr root)) (define rTree (caddr root)) (define rCount (- size required)) (if (> lCount required) (begin (define lTree (traverse lTree lCount required)) (define llTree (cadr lTree)) (define rlTree (caddr lTree)) (define rTree (list (- lCount required) rlTree rTree)) (define rrTree (traverse rTree rCount (quotient rCount 2))) (list required llTree rrTree)) (if (< lCount required) (begin (define rTree (traverse rTree (- size lCount) (- required lCount))) (define lrTree (cadr rTree)) (define rrTree (caddr rTree)) (define lTree (list lCount lTree lrTree)) (define llTree (traverse lTree required (quotient required 2))) (list required llTree rrTree)) (begin (define lTree (traverse lTree lCount (quotient lCount 2))) (define rTree (traverse rTree rCount (quotient rCount 2))) (list lCount lTree rTree))))) (if (null? root) 'error root))) (traverse root size (quotient size 2))) nested scope lots of interpreter garbage 32
  • 60. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms Fixing CMS: testcase (define (xTree-balance xTree) (define root (cadr xTree)) (define size (caddr xTree)) (define (traverse root size required) (if (pair? root) (begin (define lCount (car root)) (define lTree (cadr root)) (define rTree (caddr root)) (define rCount (- size required)) (if (> lCount required) (begin (define lTree (traverse lTree lCount required)) (define llTree (cadr lTree)) (define rlTree (caddr lTree)) (define rTree (list (- lCount required) rlTree rTree)) (define rrTree (traverse rTree rCount (quotient rCount 2))) (list required llTree rrTree)) (if (< lCount required) (begin (define rTree (traverse rTree (- size lCount) (- required lCount))) (define lrTree (cadr rTree)) (define rrTree (caddr rTree)) (define lTree (list lCount lTree lrTree)) (define llTree (traverse lTree required (quotient required 2))) (list required llTree rrTree)) (begin (define lTree (traverse lTree lCount (quotient lCount 2))) (define rTree (traverse rTree rCount (quotient rCount 2))) (list lCount lTree rTree))))) (if (null? root) 'error root))) (traverse root size (quotient size 2))) nested scope lots of interpreter garbage functional style lots of application garbage 32
  • 61. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms >(load "CODE/xTrees.slip") left count = 1 left count = 2499 elapsed: 24.4990180000 sec <unspecified> >(collect) Collecting garbage ... mark-thread: 0.004518 unthread: 0.555821 compact-link: 0.133263 used chunk space before GC: 601131564(66.79%) used chunk space after GC: 110831(00.01%) used pair space before GC: 226478924(25.16%) used pair space after GC: 30004(00.00%) <unspecified> > Fixing CMS: straight 33 preliminary
  • 62. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms >(load "CODE/xTrees.slip") left count = 1 left count = 2499 elapsed: 24.4990180000 sec <unspecified> >(collect) Collecting garbage ... mark-thread: 0.004518 unthread: 0.555821 compact-link: 0.133263 used chunk space before GC: 601131564(66.79%) used chunk space after GC: 110831(00.01%) used pair space before GC: 226478924(25.16%) used pair space after GC: 30004(00.00%) <unspecified> > Fixing CMS: straight 32 bits 900Mcell 33 preliminary
  • 63. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms >(load "CODE/xTrees.slip") left count = 1 left count = 2499 elapsed: 24.1853520000 sec <unspecified> >(collect) Collecting garbage ... mark-thread: 0.007855 unthread: 0.047346 compact-link: 0.032718 used chunk space before GC: 601131564(66.79%) used chunk space after GC: 110831(00.01%) used pair space before GC: 226478924(25.16%) used pair space after GC: 30002(00.00%) <unspecified> > Fixing CMS: bitmap 34 preliminary
  • 64. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms >(load "CODE/xTrees.slip") left count = 1 left count = 2499 elapsed: 24.7884030000 sec <unspecified> >(collect) Collecting garbage ... mark-thread: 0.008640 unthread: 0.001088 compact-link: 0.001118 used chunk space before GC: 601131564(66.79%) used chunk space after GC: 110831(00.01%) used pair space before GC: 226478924(25.16%) used pair space after GC: 30002(00.00%) <unspecified> > Fixing CMS: bitheap 35 preliminary
  • 65. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms 36 Bitheaps Name is taken ... Implements a priority queue Leaves are (all) memory cells Are (static) heaps with arity 32* Each node contains 32 bits Each bit indicates whether the subtree contains at least one bit = 1 *will scale up to 32Gby on a 64bit architecture 32 32 32 32 32 i = (a >> 27) + 1 a &= (1 << 27) - 1 i = 32*i + (a >> 22) + 1 a &= (1 << 22) - 1 i = 32*i + (a >> 17) + 1 a &= (1 << 17) - 1
  • 66. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms 36 Bitheaps Name is taken ... Implements a priority queue Leaves are (all) memory cells Are (static) heaps with arity 32* Each node contains 32 bits Each bit indicates whether the subtree contains at least one bit = 1 *will scale up to 32Gby on a 64bit architecture 32 32 32 32 32 i = (a >> 27) + 1 a &= (1 << 27) - 1 i = 32*i + (a >> 22) + 1 a &= (1 << 22) - 1 i = 32*i + (a >> 17) + 1 a &= (1 << 17) - 1
  • 67. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms 36 Bitheaps Name is taken ... Implements a priority queue Leaves are (all) memory cells Are (static) heaps with arity 32* Each node contains 32 bits Each bit indicates whether the subtree contains at least one bit = 1 *will scale up to 32Gby on a 64bit architecture 32 32 32 32 32 i = (a >> 27) + 1 a &= (1 << 27) - 1 i = 32*i + (a >> 22) + 1 a &= (1 << 22) - 1 i = 32*i + (a >> 17) + 1 a &= (1 << 17) - 1
  • 68. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms 36 Bitheaps Name is taken ... Implements a priority queue Leaves are (all) memory cells Are (static) heaps with arity 32* Each node contains 32 bits Each bit indicates whether the subtree contains at least one bit = 1 *will scale up to 32Gby on a 64bit architecture 32 32 32 32 32 i = (a >> 27) + 1 a &= (1 << 27) - 1 i = 32*i + (a >> 22) + 1 a &= (1 << 22) - 1 i = 32*i + (a >> 17) + 1 a &= (1 << 17) - 1
  • 69. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms 36 Bitheaps Name is taken ... Implements a priority queue Leaves are (all) memory cells Are (static) heaps with arity 32* Each node contains 32 bits Each bit indicates whether the subtree contains at least one bit = 1 *will scale up to 32Gby on a 64bit architecture 32 32 32 32 32 i = (a >> 27) + 1 a &= (1 << 27) - 1 i = 32*i + (a >> 22) + 1 a &= (1 << 22) - 1 i = 32*i + (a >> 17) + 1 a &= (1 << 17) - 1
  • 70. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms 36 Bitheaps Name is taken ... Implements a priority queue Leaves are (all) memory cells Are (static) heaps with arity 32* Each node contains 32 bits Each bit indicates whether the subtree contains at least one bit = 1 *will scale up to 32Gby on a 64bit architecture 32 32 32 32 32 i = (a >> 27) + 1 a &= (1 << 27) - 1 i = 32*i + (a >> 22) + 1 a &= (1 << 22) - 1 i = 32*i + (a >> 17) + 1 a &= (1 << 17) - 1
  • 71. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms 36 Bitheaps Name is taken ... Implements a priority queue Leaves are (all) memory cells Are (static) heaps with arity 32* Each node contains 32 bits Each bit indicates whether the subtree contains at least one bit = 1 *will scale up to 32Gby on a 64bit architecture 32 32 32 32 32 i = (a >> 27) + 1 a &= (1 << 27) - 1 i = 32*i + (a >> 22) + 1 a &= (1 << 22) - 1 i = 32*i + (a >> 17) + 1 a &= (1 << 17) - 1
  • 72. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms static void set(unsigned a) { unsigned b, i = 0; b = a >> 25; a &= (1 << 25) - 1; memory[i] |= 1 << b; i = 1 + (i << 5) + b; b = a >> 20; a &= (1 << 20) - 1; memory[i] |= 1 << b; i = 1 + (i << 5) + b; b = a >> 15; a &= (1 << 15) - 1; memory[i] |= 1 << b; i = 1 + (i << 5) + b; b = a >> 10; a &= (1 << 10) - 1; memory[i] |= 1 << b; i = 1 + (i << 5) + b; b = a >> 5; a &= (1 << 5) - 1; memory[i] |= 1 << b; i = 1 + (i << 5) + b; memory[i] |= 1 << a; } (Bitheaps) static UNS_type Bitheap[34636833] = { 0x0 }; 37 // Sigma i=0,5 32^i = (32^6 - 1)/(32 - 1) static UNS_type Bitheap[34636833] = { 0x0 }; static void do_(void (* lambda)(unsigned)) { unsigned i0 = 0; unsigned w1 = memory[i0]; if (w1) { i0 = 1 + (i0 << 5); for (unsigned b1 = 0; b1 < 32; b1 += 1) if (w1 & (1 << b1)) { unsigned i1 = i0 + b1; unsigned w2 = memory[i1]; if (w2) { i1 = 1 + (i1 << 5); for (unsigned b2 = 0; b2 < 32; b2 += 1) { unsigned i6 = i5 + b6; lambda(i6 - memory_size); }}}}}}}}}}}}}
  • 73. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms static void set(unsigned a) { unsigned b, i = 0; b = a >> 25; a &= (1 << 25) - 1; memory[i] |= 1 << b; i = 1 + (i << 5) + b; b = a >> 20; a &= (1 << 20) - 1; memory[i] |= 1 << b; i = 1 + (i << 5) + b; b = a >> 15; a &= (1 << 15) - 1; memory[i] |= 1 << b; i = 1 + (i << 5) + b; b = a >> 10; a &= (1 << 10) - 1; memory[i] |= 1 << b; i = 1 + (i << 5) + b; b = a >> 5; a &= (1 << 5) - 1; memory[i] |= 1 << b; i = 1 + (i << 5) + b; memory[i] |= 1 << a; } (Bitheaps) static UNS_type Bitheap[34636833] = { 0x0 }; 32 bits 4Gby 37 // Sigma i=0,5 32^i = (32^6 - 1)/(32 - 1) static UNS_type Bitheap[34636833] = { 0x0 }; static void do_(void (* lambda)(unsigned)) { unsigned i0 = 0; unsigned w1 = memory[i0]; if (w1) { i0 = 1 + (i0 << 5); for (unsigned b1 = 0; b1 < 32; b1 += 1) if (w1 & (1 << b1)) { unsigned i1 = i0 + b1; unsigned w2 = memory[i1]; if (w2) { i1 = 1 + (i1 << 5); for (unsigned b2 = 0; b2 < 32; b2 += 1) { unsigned i6 = i5 + b6; lambda(i6 - memory_size); }}}}}}}}}}}}}
  • 74. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms Conclusion Early days but promising Scalability Complexity Formal support Tool support Non-gc algorithms 38
  • 75. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms Conclusion Early days but promising Scalability Complexity Formal support Tool support Non-gc algorithms 38
  • 76. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms Conclusion Early days but promising Scalability Complexity Formal support Tool support Non-gc algorithms 38
  • 77. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms Conclusion Early days but promising Scalability Complexity Formal support Tool support Non-gc algorithms 38
  • 78. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms Conclusion Early days but promising Scalability Complexity Formal support Tool support Non-gc algorithms 38
  • 79. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms Conclusion Early days but promising Scalability Complexity Formal support Tool support Non-gc algorithms 38
  • 80. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms Conclusion Early days but promising Scalability Complexity Formal support Tool support Non-gc algorithms 38
  • 81. Buenos Aires, November 2017 Smalltalks 2017: Reasoning about memory- critical algorithms Conclusion Early days but promising Scalability Complexity Formal support Tool support Non-gc algorithms 38 convenience leads to procedure