Hi Igor,<div><br></div><div>    this is simply because the inliner can only inline an expression in an expression context.  Since sizeBitsOf: is written as multiple statements it can only be inlined in a statement context.  Here&#39;s NewObjectMemory&gt;sizeBitsOf: with the statements numbered:</div>
<div><br></div><div><div>sizeBitsOf: oop</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>&quot;Answer the number of bytes in the given object, including its base header, rounded up to an integral number of words.&quot;</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>&quot;Note: byte indexable objects need to have low bits subtracted from this size.&quot;</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>&lt;inline: true&gt;</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>| header |</div><div>1.<span class="Apple-tab-span" style="white-space:pre">        </span>header := self baseHeader: oop.</div><div>2.<span class="Apple-tab-span" style="white-space:pre">        </span>^(header bitAnd: TypeMask) = HeaderTypeSizeAndClass</div>
<div><span class="Apple-tab-span" style="white-space:pre">                </span>ifTrue: [(self sizeHeader: oop) bitAnd: LongSizeMask]</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>ifFalse: [header bitAnd: SizeMask]</div>
<div><br></div><div>Here&#39;s StackInterpreter&gt;printNameOfClass:count:, with the occurrence of sizeBitsOf: in an expression context:</div><div><br></div><div><div>printNameOfClass: classOop count: cnt</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>&quot;Details: The count argument is used to avoid a possible infinite recursion if classOop is a corrupted object.&quot;</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>&lt;inline: false&gt;</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>(classOop = 0 or: [cnt &lt;= 0]) ifTrue: [^self print: &#39;bad class&#39;].</div>
<div>e:<span class="Apple-tab-span" style="white-space:pre">        </span>((objectMemory sizeBitsOf: classOop) = metaclassSizeBytes</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>  and: [metaclassSizeBytes &gt; (thisClassIndex * BytesPerWord)])<span class="Apple-tab-span" style="white-space:pre">        </span>&quot;(Metaclass instSize * 4)&quot;</div>
<div><span class="Apple-tab-span" style="white-space:pre">                </span>ifTrue: [self printNameOfClass: (objectMemory fetchPointer: thisClassIndex ofObject: classOop) count: cnt - 1.</div><div><span class="Apple-tab-span" style="white-space:pre">                                </span>self print: &#39; class&#39;]</div>
<div><span class="Apple-tab-span" style="white-space:pre">                </span>ifFalse: [self printStringOf: (objectMemory fetchPointer: classNameIndex ofObject: classOop)]</div></div><div><br></div>With sizeBitsOf: defined as above this translates to:</div>
<div><br></div><div><div>static void</div><div>printNameOfClasscount(sqInt classOop, sqInt cnt)</div><div>{</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>if ((classOop == 0)</div><div><span class="Apple-tab-span" style="white-space:pre">        </span> || (cnt &lt;= 0)) {</div>
<div><span class="Apple-tab-span" style="white-space:pre">                </span>print(&quot;bad class&quot;); return;</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>if (((sizeBitsOf(classOop)) == GIV(metaclassSizeBytes))</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span> &amp;&amp; (GIV(metaclassSizeBytes) &gt; (GIV(thisClassIndex) * BytesPerWord))) {</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>printNameOfClasscount(longAt((classOop + BaseHeaderSize) + (GIV(thisClassIndex) &lt;&lt; ShiftForWord)), cnt - 1);</div>
<div><span class="Apple-tab-span" style="white-space:pre">                </span>print(&quot; class&quot;);</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>else {</div>
<div><span class="Apple-tab-span" style="white-space:pre">                </span>printStringOf(longAt((classOop + BaseHeaderSize) + (GIV(classNameIndex) &lt;&lt; ShiftForWord)));</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>}</div>
<div>}</div><div><br></div><div>But if one changes the definition of sizeBitsOf: to an expression, necessitating two references through oop, to:</div><div><br></div><div><div>sizeBitsOf: oop</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>&quot;Answer the number of bytes in the given object, including its base header, rounded up to an integral number of words.&quot;</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>&quot;Note: byte indexable objects need to have low bits subtracted from this size.&quot;</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>&lt;inline: true&gt;</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>^((self baseHeader: oop) bitAnd: TypeMask) = HeaderTypeSizeAndClass</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>ifTrue: [(self sizeHeader: oop) bitAnd: LongSizeMask]</div>
<div><span class="Apple-tab-span" style="white-space:pre">                </span>ifFalse: [(self baseHeader: oop) bitAnd: SizeMask]</div></div><div><br></div><div>then StackInterpreter&gt;printNameOfClass:count: translates to</div><div>
<br></div><div><div>static void</div><div>printNameOfClasscount(sqInt classOop, sqInt cnt)</div><div>{</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>if ((classOop == 0)</div><div><span class="Apple-tab-span" style="white-space:pre">        </span> || (cnt &lt;= 0)) {</div>
<div><span class="Apple-tab-span" style="white-space:pre">                </span>print(&quot;bad class&quot;); return;</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>if ((((((longAt(classOop)) &amp; TypeMask) == HeaderTypeSizeAndClass</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>? (longAt(classOop - (BytesPerWord * 2))) &amp; LongSizeMask</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>: (longAt(classOop)) &amp; SizeMask)) == GIV(metaclassSizeBytes))</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span> &amp;&amp; (GIV(metaclassSizeBytes) &gt; (GIV(thisClassIndex) * BytesPerWord))) {</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>printNameOfClasscount(longAt((classOop + BaseHeaderSize) + (GIV(thisClassIndex) &lt;&lt; ShiftForWord)), cnt - 1);</div>
<div><span class="Apple-tab-span" style="white-space:pre">                </span>print(&quot; class&quot;);</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>else {</div>
<div><span class="Apple-tab-span" style="white-space:pre">                </span>printStringOf(longAt((classOop + BaseHeaderSize) + (GIV(classNameIndex) &lt;&lt; ShiftForWord)));</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>}</div>
<div>}</div></div><div><br></div><div><br></div><div>So (David) this isn&#39;t so much a bug as a limitation of the inliner.</div><div><br></div><div>Of course in an expression context it could be translated as</div><div>
<br></div><div><div>static void</div><div>printNameOfClasscount(sqInt classOop, sqInt cnt)</div><div>{</div><div><span class="Apple-tab-span" style="white-space: pre; ">        </span>| header |</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>if ((classOop == 0)</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span> || (cnt &lt;= 0)) {</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>print(&quot;bad class&quot;); return;</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>}</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>if (((header = longAt(classOop),</div><div><span class="Apple-tab-span" style="white-space:pre">        </span> ((header &amp; TypeMask) == HeaderTypeSizeAndClass</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>? (longAt(classOop - (BytesPerWord * 2))) &amp; LongSizeMask</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>: header &amp; SizeMask)) == GIV(metaclassSizeBytes))</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span> &amp;&amp; (GIV(metaclassSizeBytes) &gt; (GIV(thisClassIndex) * BytesPerWord))) {</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>printNameOfClasscount(longAt((classOop + BaseHeaderSize) + (GIV(thisClassIndex) &lt;&lt; ShiftForWord)), cnt - 1);</div>
<div><span class="Apple-tab-span" style="white-space:pre">                </span>print(&quot; class&quot;);</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>else {</div>
<div><span class="Apple-tab-span" style="white-space:pre">                </span>printStringOf(longAt((classOop + BaseHeaderSize) + (GIV(classNameIndex) &lt;&lt; ShiftForWord)));</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>}</div>
<div>}</div></div><div><br></div><div>and I think the changes I made recently to TStmtListNode&gt;emitCCodeAsArgumentOn:level:generator: are what&#39;s required.  You simply have to track down where in the inliner it makes the determination as to whether the expression can be inlined.</div>
<div><br></div><div><br></div><div>HTH</div><div>Eliot</div><div><br></div><div class="gmail_quote">On Sat, Jul 30, 2011 at 8:53 PM, Igor Stasenko <span dir="ltr">&lt;<a href="mailto:siguctua@gmail.com">siguctua@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;"><br>
if instead i do like that:<br>
<br>
size := self sizeBitsOf: op1.<br>
sz2 := self sizeBitsOf: op2.<br>
size = sz2 ifFalse: [   ^ false ].<br>
<br>
<br>
then it inlines both calls.<br>
<div><div></div><div class="h5"><br>
On 31 July 2011 05:49, Igor Stasenko &lt;<a href="mailto:siguctua@gmail.com">siguctua@gmail.com</a>&gt; wrote:<br>
&gt; Here the slang code:<br>
&gt;<br>
&gt;        size := self sizeBitsOf: op1.<br>
&gt;        size = (self sizeBitsOf: op2) ifFalse: [<br>
&gt;                ^ false ].<br>
&gt;<br>
&gt; And here translated code:<br>
&gt;<br>
&gt;        /* begin sizeBitsOf: */<br>
&gt;        header = longAt(op1);<br>
&gt;        size = ((header &amp; TypeMask) == HeaderTypeSizeAndClass<br>
&gt;                ? (longAt(op1 - (BytesPerWord * 2))) &amp; LongSizeMask<br>
&gt;                : header &amp; SizeMask);<br>
&gt;        if (!(size == (sizeBitsOf(op2)))) {<br>
&gt;                return 0;<br>
&gt;        }<br>
&gt;<br>
&gt; as you can see it inlining first, but refuses to inline second one.<br>
&gt;<br>
&gt;<br>
&gt; --<br>
&gt; Best regards,<br>
&gt; Igor Stasenko AKA sig.<br>
&gt;<br>
<br>
<br>
<br>
--<br>
Best regards,<br>
Igor Stasenko AKA sig.<br>
</div></div></blockquote></div><br><br clear="all"><br>-- <br>best,<div>Eliot</div><br>
</div>