<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">2014-05-19 20:50 GMT+02:00  <span dir="ltr">&lt;<a href="mailto:commits@source.squeak.org" target="_blank">commits@source.squeak.org</a>&gt;</span>:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Eliot Miranda uploaded a new version of Kernel to project The Trunk:<br>
<a href="http://source.squeak.org/trunk/Kernel-eem.852.mcz" target="_blank">http://source.squeak.org/trunk/Kernel-eem.852.mcz</a><br>
<br>
==================== Summary ====================<br>
<br>
Name: Kernel-eem.852<br>
Author: eem<br>
Time: 19 May 2014, 11:49:49.951 am<br>
UUID: 6d0add2f-b4ae-4e90-9b0d-7c938c4f4c1c<br>
Ancestors: Kernel-eem.851<br>
<br>
Change scanning methods in InstructionStream and<br>
CompiledMethod to double-dispatch through<br>
CompiledMethod&gt;&gt;#encoderClass to provide pluggable<br>
multiple bytecode set support.  The sign of a method&#39;s<br>
header chooses which of two bytecode sets are in effect,<br>
choosing between PrimaryBytecodeSetEncoderClass<br>
(header &gt;= 0), and SecondaryBytecodeSetEncoderClass<br>
(header &lt;= 0).<br>
<br>
=============== Diff against Kernel-eem.851 ===============<br>
<br>
Item was changed:<br>
  ----- Method: CompiledMethod class&gt;&gt;newBytes:trailerBytes:nArgs:nTemps:nStack:nLits:primitive: (in category &#39;instance creation&#39;) -----<br>
  newBytes: numberOfBytes trailerBytes: trailer nArgs: nArgs nTemps: nTemps nStack: stackSize nLits: nLits primitive: primitiveIndex<br>
        &quot;Answer an instance of me. The header is specified by the message<br>
+        arguments. The remaining parts are not as yet determined.&quot;<br>
-       arguments. The remaining parts are not as yet determined.&quot;<br>
        | largeBit primBits |<br>
        nTemps &gt; 63 ifTrue:<br>
                [^ self error: &#39;Cannot compile -- too many temporary variables&#39;].<br>
        nLits &gt; 255 ifTrue:<br>
+               [^ self error: &#39;Cannot compile -- too many literals&#39;].<br>
-               [^ self error: &#39;Cannot compile -- too many literals variables&#39;].<br>
        largeBit := (nTemps + stackSize) &gt; SmallFrame ifTrue: [1] ifFalse: [0].<br>
        primBits := primitiveIndex &lt;= 16r1FF<br>
                ifTrue: [primitiveIndex]<br>
                ifFalse: [&quot;For now the high bit of primitive no. is in the 29th bit of header&quot;<br>
                                primitiveIndex &gt; 16r3FF ifTrue: [self error: &#39;prim num too large&#39;].<br>
                                (primitiveIndex bitAnd: 16r1FF) + ((primitiveIndex bitAnd: 16r200) bitShift: 19)].<br>
<br>
        ^trailer<br>
                createMethod: numberOfBytes<br>
                class: self<br>
                header: (nArgs bitShift: 24) +<br>
                                (nTemps bitShift: 18) +<br>
                                (largeBit bitShift: 17) +<br>
                                (nLits bitShift: 9) +<br>
                                primBits!<br>
<br>
Item was changed:<br>
  ----- Method: CompiledMethod class&gt;&gt;newBytes:trailerBytes:nArgs:nTemps:nStack:nLits:primitive:flag: (in category &#39;instance creation&#39;) -----<br>
  newBytes: numberOfBytes trailerBytes: trailer nArgs: nArgs nTemps: nTemps nStack: stackSize nLits: nLits primitive: primitiveIndex flag: flag<br>
        &quot;Answer an instance of me. The header is specified by the message<br>
+        arguments. The remaining parts are not as yet determined.&quot;<br>
-       arguments. The remaining parts are not as yet determined.&quot;<br>
        | largeBit primBits flagBit |<br>
        nTemps &gt; 63 ifTrue:<br>
                [^ self error: &#39;Cannot compile -- too many temporary variables&#39;].<br>
        nLits &gt; 255 ifTrue:<br>
+               [^ self error: &#39;Cannot compile -- too many literals&#39;].<br>
-               [^ self error: &#39;Cannot compile -- too many literals variables&#39;].<br>
        largeBit := (nTemps + stackSize) &gt; SmallFrame ifTrue: [1] ifFalse: [0].<br>
<br>
        &quot;For now the high bit of the primitive no. is in a high bit of the header&quot;<br>
        primBits := (primitiveIndex bitAnd: 16r1FF) + ((primitiveIndex bitAnd: 16r200) bitShift: 19).<br>
<br>
        flagBit := flag ifTrue: [ 1 ] ifFalse: [ 0 ].<br>
<br>
-       &quot;Copy the source code trailer to the end&quot;<br>
        ^trailer<br>
                createMethod: numberOfBytes<br>
                class: self<br>
                header: (nArgs bitShift: 24) +<br>
                                (nTemps bitShift: 18) +<br>
                                (largeBit bitShift: 17) +<br>
                                (nLits bitShift: 9) +<br>
                                primBits +<br>
                                (flagBit bitShift: 29)!<br>
<br>
Item was changed:<br>
  ----- Method: CompiledMethod&gt;&gt;containsBlockClosures (in category &#39;closures&#39;) -----<br>
  containsBlockClosures<br>
+       ^self scanner scanFor: self encoderClass createClosureScanBlock!<br>
-       ^ self scanner scanFor: [ :bc | bc = 143 &quot;push closure bytecode&quot; ]!<br>
<br>
Item was changed:<br>
  ----- Method: CompiledMethod&gt;&gt;header (in category &#39;literals&#39;) -----<br>
  header<br>
        &quot;Answer the word containing the information about the form of the<br>
+        receiver and the form of the context needed to run the receiver.<br>
+        There are two different formats, selected by the sign bit.  These are<br>
-       receiver and the form of the context needed to run the receiver.&quot;<br>
<br>
+        Original Squeak V3:<br>
+               30:sign:0 29:flag 28:prim (high bit) 27-24:numArgs 23-18:numTemps 17:largeFrameFlag 16-9:numLits 8-0:prim (low 9 bits)<br>
+<br>
+        Alternate Bytecode Set<br>
+               30:sign:1 29-28:accessModifier 27-24:numArgs 23-18:numTemps 17:largeFrameFlag 16:hasPrimitive 15-0:numLits<br>
+<br>
+        i.e. the Alternate Bytecode Set expands the number of literals to 65535 by assuming a CallPrimitive bytecode.&quot;<br>
+<br>
        ^self objectAt: 1!<br>
<br>
Item was changed:<br>
  ----- Method: CompiledMethod&gt;&gt;isBlueBookCompiled (in category &#39;testing&#39;) -----<br>
  isBlueBookCompiled<br>
+       &quot;Answer whether the receiver was compiled using the old Smalltalk-80 blocks<br>
+        compiler.  This is used to help DebuggerMethodMap choose which mechanisms<br>
+        to use to inspect (debug) activations of the receiver.&quot;<br>
-       &quot;Answer whether the receiver was compiled using the closure compiler.<br>
-        This is used to help DebuggerMethodMap choose which mechanisms to<br>
-        use to inspect activations of the receiver.<br>
-        This method answers false negatives in that it only identifies methods<br>
-        that create old BlockClosures or use the new BlockClosure bytecodes.<br>
-        It cannot tell if a method which uses neither the old nor the new block<br>
-        bytecodes is compiled with the blue-book compiler or the new compiler.<br>
-        But since methods that don&#39;t create blocks have essentially the same<br>
-        code when compiled with either compiler this makes little difference.&quot;<br>
<br>
+       ^self encoderClass supportsClosures not!<br>
-       ^((InstructionStream on: self) scanFor:<br>
-               [:instr |<br>
-               (instr &gt;= 138 and: [instr &lt;= 143]) ifTrue: [^false].<br>
-               instr = 200])<br>
-          or: [(self hasLiteral: #blockCopy:)<br>
-                  and: [self messages includes: #blockCopy:]]!<br>
<br>
Item was changed:<br>
  ----- Method: CompiledMethod&gt;&gt;isClosureCompiled (in category &#39;testing&#39;) -----<br>
  isClosureCompiled<br>
        &quot;Answer whether the receiver was compiled using the closure compiler.<br>
         This is used to help DebuggerMethodMap choose which mechanisms to<br>
+        use to inspect (debug) activations of the receiver.&quot;<br>
-        use to inspect activations of the receiver.<br>
-        This method answers false negatives in that it only identifies methods<br>
-        that create new BlockClosures or use the new BlockClosure bytecodes.<br>
-        But since methods that don&#39;t create blocks have essentially the same<br>
-        code when compiled with either compiler this makes little difference.&quot;<br>
<br>
+       ^self encoderClass supportsClosures!<br>
-       ^((InstructionStream on: self) scanFor: [:instr | instr &gt;= 138 and: [instr &lt;= 143]])<br>
-          or: [(self hasLiteral: #closureCopy:copiedValues:)<br>
-                  and: [self messages includes: #closureCopy:copiedValues:]]!<br>
<br></blockquote><div><br><div>Note that this change makes ClosureCompilerTest&gt;&gt;#testSourceRangeAccessForBlueBookInjectInto fail<br></div><div>But the test itself is for pre-closure byteCodes (using EncoderForV3, or so called Blue Book blocks with blockCopy byteCode)<br>

</div><div></div><div><br>In my image, I have no blue book CompiledMethod, if I believe this snippet:<br><br>CompiledMethod allInstances count: [:e |<br>    ((InstructionStream on: e) scanFor: [:instr | instr = 200])<br>

           or: [(e hasLiteral: #blockCopy:)<br>                   and: [e messages includes: #blockCopy:]]].<br><br></div><div>Do we really want to support this old thing?<br>Or shall we remove this test and support of previous bytecode set (EncoderForV3)?</div>
Or is there a danger that some old ImageSegment bring some zombies back? <br></div></div>Or are these things still usefull for some boostrap voodoo?<br><br>Currently, debugging such compiled method fails with sticky debuggers...<br>
Some bytes are rotting, we lack tests, a single person is active/fluent on this part, so dropping support is a reasonnable option.<br></div></div>