<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><meta content="text/html;charset=UTF-8" http-equiv="Content-Type"></head><body ><div style='font-size:10pt;font-family:Verdana,Arial,Helvetica,sans-serif;'>The notes at Eliot's blog here: http://www.squeakvm.org/svn/squeak/branches/Cog/image/Workspace.text<br>imply the difference is important when building a Cog Development Image.<br><br><pre>i.e.<br><blockquote style="border: 1px solid rgb(204, 204, 204); padding: 7px; background-color: rgb(245, 245, 245);"><div>N.B. do *not* load VMMaker or VMMaker-oscog. N.B. VMMaker.oscog packages may be listed with VMMaker packages depending on Monticello version.</div></blockquote> <br>I don't know the implied difference.<br><br><br>cheers<br><br>tty<br></pre><br><div id="1"><br>---- On Fri, 14 Feb 2014 08:03:00 -0800 <b>Levente Uzonyi<leves@elte.hu></b> wrote ---- <br></div><br><blockquote style="border-left: 1px solid #0000FF; padding-left: 6px; margin:0 0 0 5px"> <br>Is it intentional that this package and the previous one are prefixed with <br>dots? <br> <br> <br>Levente <br> <br>On Thu, 13 Feb 2014, <a subj="" mailid="commits%40source.squeak.org" href="mailto:commits@source.squeak.org" target="_blank">commits@source.squeak.org</a> wrote: <br> <br>> <br>> Eliot Miranda uploaded a new version of VMMaker to project VM Maker: <br>> <a href="http://source.squeak.org/VMMaker/..VMMaker.oscog-eem.618.mcz" target="_blank">http://source.squeak.org/VMMaker/..VMMaker.oscog-eem.618.mcz</a> <br>> <br>> ==================== Summary ==================== <br>> <br>> Name: ..VMMaker.oscog-eem.618 <br>> Author: eem <br>> Time: 13 February 2014, 11:51:10.104 am <br>> UUID: 3756532a-fdbf-4e96-8cc9-be0f35157864 <br>> Ancestors: ..VMMaker.oscog-eem.617 <br>> <br>> Some musings on Spur compaction. <br>> <br>> =============== Diff against ..VMMaker.oscog-eem.617 =============== <br>> <br>> Item was added: <br>> + ----- Method: SpurMemoryManager>>abstractCompaction (in category 'compaction - analysis') ----- <br>> + abstractCompaction <br>> + "This method answers a rough estimate of compactibility." <br>> + <doNotGenerate> <br>> + | lowestFree freeChunks used movable | <br>> + lowestFree := SmallInteger maxVal. <br>> + freeChunks := Set new. <br>> + used := Set new. <br>> + movable := Set new. <br>> + self allObjectsInFreeTreeDo: <br>> + [:f| <br>> + (self addressAfter: f) < endOfMemory ifTrue: <br>> + [freeChunks add: f. <br>> + f < lowestFree ifTrue: [lowestFree := f]]]. <br>> + self allOldSpaceObjectsFrom: lowestFree do: <br>> + [:o| | size delta best | <br>> + size := self bytesInObject: o. <br>> + delta := SmallInteger maxVal. <br>> + freeChunks do: [:f| | fs | <br>> + ((fs := self bytesInObject: f) >= size) ifTrue: <br>> + [delta > (fs - size) ifTrue: <br>> + [delta := fs - size. best := f]]]. <br>> + best ifNotNil: <br>> + [movable add: o. <br>> + used add: (freeChunks remove: best)]]. <br>> + ^{ totalFreeOldSpace. movable inject: 0 into: [:s :o| s + (self bytesInObject: o)]. used inject: 0 into: [:s :o| s + (self bytesInObject: o)] }! <br>> <br>> Item was added: <br>> + ----- Method: SpurMemoryManager>>abstractPigCompaction (in category 'compaction - analysis') ----- <br>> + abstractPigCompaction <br>> + "This method answers a rough estimate of compactibility using a pig (a large free chunk)." <br>> + <doNotGenerate> <br>> + | pig pork moved unmoved nmoved nunmoved | <br>> + pig := self findAPig. <br>> + pork := self bytesInObject: pig. <br>> + moved := unmoved := nmoved := nunmoved := 0. <br>> + self allOldSpaceObjectsFrom: pig do: <br>> + [:o| | bytes | <br>> + bytes := self bytesInObject: o. <br>> + bytes <= pork <br>> + ifTrue: <br>> + [moved := moved + bytes. <br>> + nmoved := nmoved + 1. <br>> + pork := pork - bytes] <br>> + ifFalse: <br>> + [unmoved := unmoved + bytes. <br>> + nunmoved := nunmoved + 1]]. <br>> + ^{ self bytesInObject: pig. pork. moved. nmoved. unmoved. nunmoved }! <br>> <br>> Item was added: <br>> + ----- Method: SpurMemoryManager>>biggies (in category 'compaction - analysis') ----- <br>> + biggies <br>> + "This method answers a sorted collection of the objects >= 1,000,000 bytes long, <br>> + above the lowest large free chunk, sandwiched between nilObj and the end of memory." <br>> + <doNotGenerate> <br>> + | lowestFree biggies | <br>> + lowestFree := SmallInteger maxVal. <br>> + self allObjectsInFreeTreeDo: <br>> + [:f| (self addressAfter: f) < endOfMemory ifTrue: [f < lowestFree ifTrue: [lowestFree := f]]]. <br>> + biggies := SortedCollection new. <br>> + self allOldSpaceObjectsFrom: lowestFree do: <br>> + [:f| <br>> + (self bytesInObject: f) >= 1000000 ifTrue: <br>> + [biggies add: f]]. <br>> + ^{{nilObj hex. #nil}}, (biggies collect: [:f| {f hex. self bytesInObject: f}]), {{endOfMemory hex. #endOfMemory}}! <br>> <br>> Item was added: <br>> + ----- Method: SpurMemoryManager>>compactionIssues (in category 'compaction - analysis') ----- <br>> + compactionIssues <br>> + <doNotGenerate> <br>> + "Compaction isn't working well. It rarely moves more than a few tens of kilobytes. Why? <br>> + Load an image and before you run it, or just before a GC, run these anaylsis routines. <br>> + e.g. <br>> + self abstractCompaction #(63230272 75456 63210648) <br>> + shows we can move 75456 bytes of objects, but that would use 63210648 of free space. <br>> + i.e. there are lots of big free chunks in play, not many small ones that fit the bill. <br>> + <br>> + self largeFreeChunkDistribution <br>> + #( #('16r31C788' #nil) <br>> + #('16r1423AC0' 2061864) <br>> + #('16r1B705E8' 1515200) <br>> + #('16r1D31D20' 2011152) <br>> + #('16r1F37818' 1491480) <br>> + #('16r2225968' 1450512) <br>> + #('16r24C92C8' 48575672) (16r24C92C8 + 48575672) hex '16r531C780' a free chunk <br>> + #('16r531C788' #endOfMemory)) <br>> + shows there's plenty of large free chunks. And the trailing 16-byte free chunk shows coallescing is not working properly. <br>> + <br>> + self biggies #(#('16r31C788' #nil) #('16r531C788' #endOfMemory)) <br>> + shows there are no large objects to be moved. <br>> + <br>> + So... looks like compaction should hold onto the lowest large chunk and preferentially move objects into that. <br>> + Let's call it a pig. Compaction needs to whittle away at the pig. <br>> + <br>> + e.g. <br>> + self abstractPigCompaction #(2061864 0 2061864 18759 2018224 34757) <br>> + shows we can move 18759 objects that will occupy 2018224 bytes into that <br>> + low pig of 2061864 bytes."! <br>> <br>> Item was added: <br>> + ----- Method: SpurMemoryManager>>findAPig (in category 'compaction - analysis') ----- <br>> + findAPig <br>> + "Answer a large low free chuink." <br>> + <doNotGenerate> <br>> + | pig | <br>> + self allObjectsInFreeTreeDo: <br>> + [:f| <br>> + (self bytesInObject: f) >= 1000000 ifTrue: <br>> + [(pig isNil or: [pig > f]) ifTrue: <br>> + [pig := f]]]. <br>> + ^pig! <br>> <br>> Item was added: <br>> + ----- Method: SpurMemoryManager>>largeFreeChunkDistribution (in category 'compaction - analysis') ----- <br>> + largeFreeChunkDistribution <br>> + "This method answers a sorted collection of the free chunks >= 1,000,000 bytes long, <br>> + sandwiched between nilObj and the end of memory (ignoring the large chunk often found at the end of the heap)." <br>> + <doNotGenerate> <br>> + | freeChunks | <br>> + freeChunks := SortedCollection new. <br>> + self allObjectsInFreeTreeDo: <br>> + [:f| <br>> + ((self addressAfter: f) < endOfMemory <br>> + and: [(self bytesInObject: f) >= 1000000]) ifTrue: <br>> + [freeChunks add: f]]. <br>> + ^{{nilObj hex. #nil}}, (freeChunks collect: [:f| {f hex. self bytesInObject: f}]), {{endOfMemory hex. #endOfMemory}}! <br>> <br>> <br></blockquote><br></div></body></html>