Printings: June 2000
Last updated 29 September 2003
These errors appear in the June 2000 reprinting.
Page 23, Diagram 2.5, the new free list should be S, U, V, ... (i.e. the order is reversed) . Thus,
Diagram 2.5 After
Pages 33 and 34, in the left-hand diagrams, the arrow from A' to B' in Diagram 2.10 and from A' to C' in Diagram 2.11 should be removed: the pointers are not written until the recursive step is complete .
Page 47, Algorithm 3.4, the test
x>t is better written
gcd(x,y) = -- assert: x >= y >= 0 if y == 0 return x t = x - y if y > t return gcd(y,t) else return gcd(t,yyuasa)Algorithm 3.4 Greatest common divisor.
Page 124, Diagram 6.5, the caption should read
left(F') is updated with the forwarding address found in
Page 148, Diagram 7.3, in attempting to correct a minor labelling error in the earlier printings, Diagram 7.3 instead repeats Diagram 7.2 . It should of course be:
Diagram 7.3 Overwriting
Rcreates old-young pointers.
Page 194: The discussion of how Steele allocates cells omits an account of allocation during the sweep phase, although this is described in Algorithm 8.6 . In summary,
Page 195, Algorithm 8.7,
colour(X) = blackshould be
mark_bit(X) = true -colour(X) is now blackNote also the omitted (if obvious) definitions,
marked(X) == (mark_bit(X) == true) unmarked(X) == (mark_bit(X) == false)
Page 204, Algorithm 8.12, the final test on
B should be
New(n) = if B >= T - n - Flip phase if scan < B abort "Haven't finished scavenging" flip() for root R R = copy(R) repeat k times while scan < B - scavenge a bit for P in Children(scan) *P = copy(*P) scan = scan + size(scan) if B >= T abort "Heap full" T = T - n return T read(T) = T' = copy(T) return T'Algorithm 8.12 Baker's incremental copying algorithm.
Page 204, line 2: the reference should be to Diagram 8.8 on the previous page .
Page 242, second paragraph: the block's count of free slots should be decremented, not incremented, and the allocator decrements the number of free, rather than allocated, blocks .
Page 262, last paragraph, second sentence, should refer to
Printings: June 1996, February 1997, November 1997.
Last updated 4 January 1999
The errors below were corrected in the January 1999 reprinting.
Page 3, first paragraph, last sentence: occam does not use static allocation.
Page 21, Algorithm 2.2,
Update should increment the reference
count of the new target before deleting the pointer to the old target to
prevent incorrect reclamation in the case that both targets are one and the
same and that this is the only reference to it. Thus,
Update(R, S) = RC(S) = RC(S) + 1 delete(*R) *R = SAlgorithm 2.2 Updating pointer fields under reference counting
eMS = (1-r) / (br+c)Similarly, the y-intercept for the Mark-Sweep curve in the graph in Diagram 2.12 should be 1/c .
Page 46, Algorithm 3.2
Update(R,S) = - R and S are heap objects incrementRC(S) delete(*R) remove S from ZCT *R = SAlgorithm 3.2 Deferred Reference Counting: updating pointer values.
Update(R,S) = T = sticky(*S) if RC(*S) == unique *S = T delete(*R) *R = TAlgorithm 3.7 One-bit reference counting with tagged pointers.
Update(R,S) = T = *R gr = group_no(R) if gr != group_no(S) - external reference increment_groupRC(S) if gr != group_no(T) - external reference decrement_groupRC(T) if groupRC(T) == 0 reclaim_group(T) *R = SAlgorithm 3.9 Bobrow's algorithm.
Update(R,S) = WRC(S) = WRC(S) + 1 delete(*R) *R = S weaken(*R)Algorithm 3.11 Salkild's
Update(R,S) = RC(S) = RC(S) + 1 colour(R) = black - `remove' R,S from control set colour(S) = black delete(*R) *R = SAlgorithm 3.15 Cyclic reference counting
collect_white(S) = if colour(S) == white colour(S) = black for T in Children(S) collect_white(*T) free(S)Algorithm 3.20
collect_whitesweeps white cells into the free-list.
Updateshould paint cells black not purple.
Page 78, Algorithm 4.2: if this version of
mark is used,
mark_heap should not set mark bits
Page 80, second paragraph, the figures given are in milliseconds, not microseconds as stated. The reference should be to [Zorn, 1990a], not to [Zorn, 1990b] .
Page 81, last paragraph, fifth sentence should read :
"If none of the node's children are unmarked, that stack slot is deemed to be empty and is squeezed out by sliding up the next useful entry."
allocate() = while sweep < Heap_top -- continue sweep if mark_bit(sweep) == marked mark_bit(sweep) = unmarked sweep = sweep + size(sweep) else result = sweep sweep = sweep + size(sweep) return result mark_heap() -- heap is full sweep = Heap_bottom while sweep < Heap_top -- try again if mark_bit(sweep) == marked mark_bit(sweep) = unmarked sweep = sweep + size(sweep) else result = sweep sweep = sweep + size(sweep) return result abort "Memory exhausted"Algorithm 4.4 Lazy sweeping.
mark_bit(p) = return bitmap[p>>3]
subdoes not set the condition codes, and
loadare not standard SPARC assembly instructions. Furthermore, brackets were omitted from
stinstructions . The correct versions are:
-- is a collection needed? subcc %g_allocated, ConsSize, %g_allocated bg,a noCollect subcc %g_freeConsIndex, 4, %g_free_ConsIndex call Collect nop subcc %g_freeConsIndex, 4, %g_free_ConsIndex noCollect: -- need to sweep? bg,a done ld [%g_freeCons + %g_freeConsIndex], %result call lazySweep nop ld [%g_freeCons + %g_freeConsIndex], %result done: ...Algorithm 4.5 Zorn's allocation sequence for cons cells
lazySweep: ... -- %bitsLeft contains the remaining bits andcc %bitsLeft, 1, %thisBit bnz,a nextBit add %currentRef, ConsSize, %currentRef -- sweep the word into the cons free-list st %currentRef, [%g_freeCons + %g_freeConsIndex] add %g_freeConsIndex, 4, %g_free_ConsIndex add %currentRef, ConsSize, %currentRef nextBit: -- on to the next bit srl %bitsLeft, 1,%bitsLeftAlgorithm 4.6 The inner loop of Zorn's lazy-sweep allocator processes one bit of the bitmap.
Page 102, Algorithm 5.2 does not clear mark-bits .
relocate() = free=heap_bottom live=heap_top mark_bit(Heap[heap_top+1]) = unmarked - sentinel repeat while marked(free) - find the next hole mark_bit(Heap[free]) = unmarked free=free+1 while not marked(live) and live > free - find the previous live cell live=live-1 if live>free mark_bit(Heap[live]) = unmarked - unmark it move(live, free) Heap[live] = free - leave forwarding address free=free+1 live=live-1 until live <= freeAlgorithm 5.2 The first pass of the Two-Finger compaction algorithm
Page 104, Algorithm 5.5, the second line of
compute_addresses should read
P = Heap_bottom
Page 113, subsection Handling abnormal residencies should read: "Sansom has proposed..." .
Page 123, Algorithm 6.1 .
In order to fit with the procedure
New given in
Algorithm 2.7 on page 29 of Chapter 2 the flip should also
Cin the last two sentences should be replaced by references to
A. Thus: "The scan finds a pointer to
left(F'). This pointer is updated with the forwarding address
A(see diagram 6.5 on the next page)."
Page 125, Algorithm 6.3: the first line should be indented by one tab .subcc %g_allocated, ConsSize, %g_allocated bg,a noCollect
flip() = Fromspace, Tospace = Tospace, Fromspace top_of_space = Tospace + space_size scan, partial, free = TospaceAlgorithm 6.4 Moon's approximately depth-first algorithm.
for R in Roots R = copy(R)
while scan < free scan_partial() scan_all()
"Although they accepted Appel's general case, they found that heap allocation of procedure activation frames required an extra two instructions per call (to save the frame pointer and move the heap pointer) -- 18 percent more instructions than was needed for stack allocation."
Page 145: Apple's Smalltalk was never released.
Page 146, paragraph two should read :
"On the other hand, the strong generational hypothesis, that the older an object is the less likely it is to die, does not appear to hold generally."
"Third, the minor collection successfully reclaimed all short-lived cells in the graph."
Diagram 7.9 Immediately after a major collection, but before the old generation is compacted.
st %ptr, [%obj] -- store ptr into obj st %obj, [%ssb] -- add obj to SSB add %ssb, 4, %ssbAlgorithm 7.4 The write-barrier for a sequential store buffer.
"Notice that hashing prevents duplicate entries from being introduced from the SSB."
st, use of
srlfor division and
stbfor clearing bytes . Thus,
st %ptr, [%obj + offset] -- store ptr into obj's field add %obj, offset, %temp -- calculate address of updated word srl %temp, k, %temp -- divide by card size, 2^k stb %g0, [%byte_map + %temp] -- clear byte in byte_mapAlgorithm 7.5 Chamber's write-barrier. k is log_2(card size).
st %ptr, [%obj + offset] -- store ptr into obj's field srl %temp, k, %temp -- calculate approximate byte index stb %g0, [%byte_map + %temp] -- clear byte in byte_mapAlgorithm 7.6 Hölzle's write-barrier.
k3throughout the procedure
sweep. The algorithm is also clearer, and more consistent stylistically with Algorithm 8.3 if
free_countis explicitly incremented by
sweeprather than implicitly in
sweep(k3) = sweep k3 items i = 0 while i<k3 and sweeper <= Heap_top if mark_bit(sweeper) == unmarked free(sweeper) increment free_count else mark_bit(sweeper) = unmarked increment sweeper i = i+1Algorithm 8.2 Auxiliary procedures for Yuasa's algorithm.
There's also a stylistic inconsistency between Algorithms 8.2 and 8.3 on the
It would be better if
mark in Algorithm 8.3 also took
k1 as a parameter (rather than as a global variable).
"The conservatism ..."
finishedshould be set to
mark() = phase = mark_phase for R in Roots gcpush(R,mark_stack) mark1() for S in system_stack LOCK S, system_stack gcpush(S,mark_stack) mark1() LOCK gcstate finished = mark_stack==empty while not finished mark1() LOCK gcstate finished = mark_stack==emptyAlgorithm 8.7 Steele's concurrent marker.
Page 230, penultimate paragraph, penultimate sentence: for code read data .
Diagram 9.6 Space leaks in a cons-list are limited to the target of the false reference.
Diagram 9.9 Mostly Copying garbage collection.
"A drawback is that other objects in those blocks have also been retained (for example, object
Xin Diagram 9.9)."
Page 248, Algorithm 9.3: the first line should be indented by one tab .
Pages 260, 264 and 269, Algorithms 10.2 to 10.4: the first lines should be indented by one tab .
Page 289 says, "Goncalves and Appel confirm these predictions, using Appel's generational copying collector for SML/NJ." SML/NJ no longer uses the two-generation collector described in his 1989 paper Simple Generational Garbage Collection and Fast Allocation, but now uses a multigeneration collector implemented by John Reppy and described in A High-Performance Garbage Collector for Standard ML. It was this many-generation collector that the FPCA'95 paper measured .
|[ book ]||[ GC page ]||[ home ]|