<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Mar 9, 2016 at 3:08 AM, Stéphane Ducasse <span dir="ltr">&lt;<a href="mailto:stephane.ducasse@inria.fr" target="_blank">stephane.ducasse@inria.fr</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word">Hi eliot <div><br></div><div>Do not worry.<div>Now would it be possible to have a test or something like that that would help us</div><div>to </div><div><span style="white-space:pre-wrap">        </span>- document this part of the system</div><div><span style="white-space:pre-wrap">        </span>- check that the system is in a coherent state</div><div><br></div><div>Stef</div></div></div></blockquote><div><br></div><div>Yes, watch this space.  I should have the work done by tomorrow.  And the 64-bit system will be a tiny bit smaller and faster :-)</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div><div><div class="h5"><div><blockquote type="cite"><div>On 09 Mar 2016, at 10:26, Eliot Miranda &lt;<a href="mailto:eliot.miranda@gmail.com" target="_blank">eliot.miranda@gmail.com</a>&gt; wrote:</div><br><div><div dir="ltr">Um, under /no/ circumstances do what I&#39;m suggesting below.  It will screw up 320bit images completely.  I&#39;ve just turned odd SmallIntegers into SmallFloat54&#39;s in 32-bit Squeak.  I hope I won&#39;t destroy too many people&#39;s images.  This is perhaps my worst blunder.</div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Mar 8, 2016 at 10:38 AM, Eliot Miranda <span dir="ltr">&lt;<a href="mailto:eliot.miranda@gmail.com" target="_blank">eliot.miranda@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi Pavel,<div class="gmail_extra"><br><div class="gmail_quote"><span>On Tue, Mar 8, 2016 at 1:40 AM, Pavel Krivanek <span dir="ltr">&lt;<a href="mailto:pavel.krivanek@gmail.com" target="_blank">pavel.krivanek@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr">Hi, <div><br></div><div>there is a strange array of size 1024 in the Pharo image that is not eaten by garbage collector even if no object points to it. I guess it is related to Spur.</div><div><br></div><div><div>((Array allInstances select: [ :i | i size = 1024 ])</div><div> <span style="white-space:pre-wrap">        </span>select: [ :a | a second = SmallInteger  ]) pointersTo</div></div><div><br></div><div>What is it and is it accessible somehow?</div></div></blockquote><div><br></div></span><div>It is indeed the first class table page.  It looks like an old bug.  The oldest Spur image I can start up has the problem.   The way that class table pages are hidden is that they have a class index which is not that of Array.  Array is at index 52 in the class table (51 zero-relative, Array identityHash = 51), but it is also at index 17 (16 zero-relative).  Array allInstances looks for objects whose class index is 51, hence not seeing the class table pages, which all (but the first) have class index 16.</div><div><br></div><div>Luckily we can fix the problem easily, and we can fix another problem at the same time, which is that SmallFloat64 has the wrong hash.</div><div><br></div><div>The class table is two-level; a (hidden) array of Arrays.  Classes are in the class table at their identityHashes (so that to instantiate a class one copies the class&#39;s identity hash into the classIndex of the new instance instead of having to search the class table).  But when SmallFloat64 was created in the 32-bit image I forgot to give it the right hash and store it in the class table.  (there are no SmallFloat64 instances in a 32-bit image, only in 64-bits).</div><div><br></div><div>So we can first change SmallFloat64&#39;s hash to 3, which is what the Spur 64-bit VM and image require, and enter it into the first class table page, and then we can make the first class table page disappear.</div><div><br></div><div><div><br></div><div>| firstClassTablePage clone |</div><div>&quot;The first class table page is the first Array instance. Of course this is a bug.&quot;</div><div>firstClassTablePage := Array someInstance.</div><div><br></div><div>&quot;It should contain only nil and classes.&quot;</div><div>self assert: (firstClassTablePage allSatisfy: [:e| e == nil or: [e isBehavior]]).</div><div><br></div><div>&quot;And its first 17 elements should only be the immediate classes and Array, since Array is used as the class pun for class table pages, with index 17 (16 zero-relative)&quot;</div><div>self assert: (firstClassTablePage first: 17) asSet = {nil. SmallInteger. Character. Array} asSet.</div><div><br></div><div><div>&quot;It just so happens that the second Array is the specialSelectors&quot;</div><div>self assert: Array someInstance nextInstance == Smalltalk specialSelectors.</div></div><div><br></div><div>&quot;Store SmallFloat64 in the first class table page at index 4 (3 zero-relative).&quot;</div><div>firstClassTablePage at: 4 put: SmallFloat64.</div><div><br></div><div>&quot;Use the secret set identity hash primitive to set SmallFloat64&#39;s identityHash to 3.&quot;</div><div>SmallFloat64 tryPrimitive: 161 withArgs: #(3).</div><div><br></div><div>&quot;Now create an object that looks like Array class, but has identityHash 16.&quot;</div><div>&quot;Take a shallow copy of Array class.&quot;</div><div>clone := Array shallowCopy.</div><div>&quot;Change it into an Array.&quot;</div><div>Array adoptInstance: clone.</div><div>&quot;Set its identityHash to 16.&quot;</div><div>clone tryPrimitive: 161 withArgs: #(16).</div><div>&quot;Use the adoptInstance: primitive to ``set the class of the firstClassTablePage to the cone&#39;&#39;.</div><div> or, more accurately, to set the firstClassTablePage&#39;s class index to 16.&quot;</div><div>clone tryPrimitive: 160 withArgs: {firstClassTablePage}</div></div><div><br></div><div><br></div><div>With the above done, we can check that everything is ok.&quot;</div>self assert: SmallFloat64 identityHash = 3.<div>self assert: Array someInstance == Smalltalk specialSelectors.</div><div>&quot;A class table page is 1024 slots, contains only nil or behaviours, and contains at least one behaviour (is not all nils).  There shouldn&#39;t be any that we can find.&quot;</div><div>self assert: (self systemNavigation allObjects select: [:o| o isArray and: [o size = 1024 and: [(o allSatisfy: [:e| e == nil or: [e isBehavior]]) and: [o anySatisfy: [:e| e isBehavior]]]]]) size = 0</div><div><br></div><div><br></div><div>I recommend you create an update map.  Then create a version of kernel with a post-load action, written something like this:</div><div><br></div><div><div><br></div><div>(Array someInstance size = 1014</div><div> and: [(Array someInstance allSatisfy: [:e| e == nil or: [e isBehavior]])</div><div> and: [(firstClassTablePage first: 17) asSet = {nil. SmallInteger. Character. Array} asSet]]) ifTrue:</div><div><span style="white-space:pre-wrap">        </span>[| firstClassTablePage clone |</div><div><span style="white-space:pre-wrap">        </span>firstClassTablePage := Array someInstance.</div><div><span style="white-space:pre-wrap">        </span>self assert: (firstClassTablePage allSatisfy: [:e| e == nil or: [e isBehavior]]).</div><div><span style="white-space:pre-wrap">        </span>self assert: (firstClassTablePage first: 17) asSet = {nil. SmallInteger. Character. Array} asSet.</div><div><span style="white-space:pre-wrap">        </span>firstClassTablePage at: 4 put: SmallFloat64.</div><div><span style="white-space:pre-wrap">        </span>SmallFloat64 tryPrimitive: 161 withArgs: #(3).</div><div><span style="white-space:pre-wrap">        </span>clone := Array shallowCopy.</div><div><span style="white-space:pre-wrap">        </span>Array adoptInstance: clone.</div><div><span style="white-space:pre-wrap">        </span>clone tryPrimitive: 161 withArgs: #(16).</div><div><span style="white-space:pre-wrap">        </span>clone tryPrimitive: 160 withArgs: {Array someInstance}</div><div><span style="white-space:pre-wrap">        </span>self assert: SmallFloat64 identityHash = 3.</div><div><span style="white-space:pre-wrap">        </span>self assert: (Array someInstance first: 4) = {nil. SmallInteger. Character. SmallFloat64}]</div></div><div><br></div><div>Then create a second update map to ensure that that version of Kernel is loaded.</div><div><br></div><div>I will do this for Squeak immediately.</div><div><br></div><div><br></div><div>Apologies.</div><div><br></div><div>P.S. Interestingly enough, it shows what a horrible security hole the debugger primitives tryPrimitive:withArgs: and tryNamedPrimitive:withArgs: are.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div>Cheers,<br></div><div>-- Pavel</div></div>
</blockquote></div><div><br></div><div><div dir="ltr"><div><span style="font-size:small;border-collapse:separate"><div>_,,,^..^,,,_<br></div><div>best, Eliot</div></span></div></div></div>
</div></div>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div><div dir="ltr"><div><span style="font-size:small;border-collapse:separate"><div>_,,,^..^,,,_<br></div><div>best, Eliot</div></span></div></div></div>
</div>
</div></blockquote></div><br></div></div><div>
<div style="color:rgb(0,0,0);letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;word-wrap:break-word"><div style="color:rgb(0,0,0);letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;word-wrap:break-word"><div>--------------------------------------------</div><div>Stéphane Ducasse</div><div><a href="http://stephane.ducasse.free.fr" target="_blank">http://stephane.ducasse.free.fr</a></div><div><a href="http://www.synectique.eu" target="_blank">http://www.synectique.eu</a> / <a href="http://www.pharo.org" target="_blank">http://www.pharo.org</a> </div><div>03 59 35 87 52</div><div>Assistant: Julie Jonas </div><div>03 59 57 78 50</div><div>03 59 35 86 16</div><div><br></div><div>S. Ducasse - Inria</div><div>40, avenue Halley, </div><div>Parc Scientifique de la Haute Borne, Bât.A, Park Plaza</div><div><div>Villeneuve d&#39;Ascq 59650</div><div>France</div></div></div></div>
</div>
<br></div></div><br><br>
<br></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature"><div dir="ltr"><div><span style="font-size:small;border-collapse:separate"><div>_,,,^..^,,,_<br></div><div>best, Eliot</div></span></div></div></div>
</div></div>