Likely this relates to a problem with LLVM and it playing more by the rules.<div><br></div><div>(a) lack of prototypes makes LLVM generate bad code. </div><div><br></div><div>Fix that then you can compile and run VM with -O0</div>
<div>And run a bit with -O2 -Os</div><div><br></div><div>> Earlier note sent to a few folks, but let's widen the audience. </div><div><br></div><div><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">Ok, I'm driven to compile an Old VM for IOS with LLVM, as you know</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">this broken, still I'm millions of bytecodes in now...</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)"><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">What I found is the lack of prototypes would cause LLVM on anything</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">but -O0 to throw an ARM exception </span><span class="il" style="background-color:rgb(255,255,204);color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px">at</span><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)"> the first longAtPointer</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">Once I added prototypes then well we run millions of bytecode. Right</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">up to the point we die attempting to print the friggen Time on the</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">Transcript.</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">As it's one in the morning I'll throw it out for clues and maybe</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">someone wants to fight with it, give clues, throw beer or heckle from</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">the sidelines...</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)"><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">I know that the commonAt: is given an invalid or zero index value,</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">so the digitValue: throws a failure of </span><span class="il" style="background-color:rgb(255,255,204);color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px">at</span><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">: not working... Er then in</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">my image we run off to print the crash report, with time stamp....</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">repeat until you run out of 20MB of memory.</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)"><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">PS other fun notes because the endian and mmap memory offset is the</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">same between my mac and my iOS device and the saved image then on</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">startup I don't have to</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">swizzle the bytes, or alter the offset, so the VM startup code isn't</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">given a chance to stomp on anything. On an iPhone 3G this cut many</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">seconds off the VM startup.</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)"><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">Add handy fprintf on failure to commonAt:</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">sqInt commonAt(sqInt stringy) {</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">register struct foo * foo = &fum;</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)"> sqInt atIx;</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)"> sqInt rcvr;</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)"> sqInt result;</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)"> sqInt index;</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)"> sqInt sp;</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)"> sqInt sp1;</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)"><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)"><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)"> /* Sets successFlag */</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)"><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)"> index = positive32BitValueOf(</span><span class="il" style="background-color:rgb(255,255,204);color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px">longAt</span><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">(</span><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">foo->stackPointer));</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)"> rcvr = </span><span class="il" style="background-color:rgb(255,255,204);color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px">longAt</span><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">(foo->stackPointer - (1 * BytesPerWord));</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)"> if (!(foo->successFlag && (!((rcvr & 1))))) {</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)"> /* begin primitiveFail */</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)"> foo->successFlag = 0;</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">>>>>> fprintf(stderr,"\n failure for %u given %i",rcvr,index); //Happy puppy when -O0 not happy with -O1 (or others)</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)"> return null;</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)"> }</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)"><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)"><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)"><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">so given</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)"><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">sqInt primitiveSecondsClock(void) {</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">register struct foo * foo = &fum;</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)"> sqInt oop;</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)"> sqInt sp;</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)"><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)"> /* begin pop:thenPush: */</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)"> oop = positive32BitIntegerFor(</span><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">ioSeconds());</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)"> longAtput(sp = foo->stackPointer - ((1 - 1) * BytesPerWord), oop);</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)"> foo->stackPointer = sp;</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">}</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)"><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">*seems to work as the positive32BitIntegerFor feeds back something I</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">push back to positive32BitValueOf and print all the little pieces...</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)"><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">sqInt ->D2F68C2F<- Bytes 2F 8C F6 D2 integer value 3539373103 value</span><br style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">
<span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">from ioSeconds going into positive 3539373103 push as 3539373103<></span><br><br><div class="gmail_quote">
On Fri, Mar 22, 2013 at 5:25 PM, Nicolas Cellier <span dir="ltr"><<a href="mailto:nicolas.cellier.aka.nice@gmail.com" target="_blank">nicolas.cellier.aka.nice@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
2013/3/22 Bert Freudenberg <<a href="mailto:bert@freudenbergs.de">bert@freudenbergs.de</a>>:<br>
<div class="im">><br>
> On 2013-03-22, at 05:43, David T. Lewis <<a href="mailto:lewis@mail.msen.com">lewis@mail.msen.com</a>> wrote:<br>
><br>
>> "It ain't what you don't know that gets you into trouble. It's what you know for sure that just ain't so."<br>
>> -- Mark Twain<br>
>><br>
>> An interpreter VM compiled with the normal C macros in sqMemoryAccess.h (for "performance"):<br>
>><br>
>> 0 tinyBenchmarks. '417277913 bytecodes/sec; 14395420 sends/sec'<br>
>> 0 tinyBenchmarks. '414239482 bytecodes/sec; 14646769 sends/sec'<br>
>> 0 tinyBenchmarks. '417277913 bytecodes/sec; 14406658 sends/sec'<br>
>><br>
>> The same interpreter VM with C macros replaced by Smalltalk slang (class MemoryAccess):<br>
>><br>
>> 0 tinyBenchmarks. '455111111 bytecodes/sec; 14217973 sends/sec'<br>
>> 0 tinyBenchmarks. '451897616 bytecodes/sec; 14485815 sends/sec'<br>
>> 0 tinyBenchmarks. '453900709 bytecodes/sec; 14497194 sends/sec'<br>
>><br>
>> Dave<br>
><br>
> That is ... unexpected :)<br>
><br>
<br>
</div>Well, that's almost the same code both in MemoryAcess and<br>
sqMemoryAccess.h right?<br>
Maybe a bit different if you define USE_INLINE_MEMORY_ACCESSORS:<br>
<br>
static inline sqInt byteAt(sqInt oop) { return<br>
byteAtPointer(pointerForOop(oop)); }<br>
static inline sqInt byteAtPointer(char *ptr) { return<br>
(sqInt)(*((unsigned char *)ptr)); }<br>
static inline char *pointerForOop(usqInt oop) { return sqMemoryBase + oop; }<br>
<br>
Though I do not well see why it would not inline such simple piece,<br>
gcc has a license to not honour the inline request.<br>
On the other side MemoryAccess will always inline as we asked the code<br>
generator to (self inline: true)<br>
It would be worth verifying if one of the static function is generated<br>
in the executable (with nm -a or something).<br>
<br>
But I also see other subtle differences like this:<br>
<br>
intAtPointer: ptr put: val<br>
self inline: true.<br>
self var: #ptr type: 'char *'.<br>
self var: #val type: 'unsigned int'.<br>
^ self cCoerce:<br>
((self cCoerce: ptr to: 'unsigned int *')<br>
at: 0<br>
put: val)<br>
to: 'sqInt'<br>
<br>
while the header tells<br>
static inline sqInt intAtPointerput(char *ptr, int val) { return<br>
(sqInt)(*((unsigned int *)ptr)= (int)val); }<br>
<br>
OK, you might think that casting int->unsigned int is no-op on<br>
2-complement machines.<br>
But it's a distraction, we must omit the intermediate (*(unsigned int<br>
*)) and just consider that the return value is assigned with the<br>
parameter val.<br>
So the header just copy an int->int, but MemoryAccess uses the<br>
opposite cast unsigned int->int<br>
It's also a no-op except that:<br>
- the cast can overflow, which would be UB.<br>
- gcc has a licence to presume you don't rely on UB and thus can<br>
further consider the returned int is always >= 0<br>
That assertion cannot be done in the case of sqMemoryAccess.h<br>
<br>
So all I see here has nothing to do with premature optimization.<br>
It has to do with lack of understanding of the modern C standards, and<br>
the absolute casualness attitude we take with signed and unsigned<br>
types.<br>
<span class="HOEnZb"><font color="#888888"><br>
Nicolas<br>
</font></span><div class="HOEnZb"><div class="h5"><br>
> But it again shows the importance of the 3rd rule of Optimization.<br>
> <a href="http://c2.com/cgi/wiki?RulesOfOptimization" target="_blank">http://c2.com/cgi/wiki?RulesOfOptimization</a><br>
><br>
> - Bert -<br>
><br>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br>===========================================================================<br>John M. McIntosh <<a href="mailto:johnmci@smalltalkconsulting.com" target="_blank">johnmci@smalltalkconsulting.com</a>><br>
Corporate Smalltalk Consulting Ltd. Twitter: squeaker68882<br>===========================================================================<br><br>
</div>