<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Mar 31, 2016 at 2:27 PM,  <span dir="ltr">&lt;<a href="mailto:commits@source.squeak.org" target="_blank">commits@source.squeak.org</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"><br>
Eliot Miranda uploaded a new version of VMMaker to project VM Maker:<br>
<a href="http://source.squeak.org/VMMaker/VMMaker.oscog-eem.1755.mcz" rel="noreferrer" target="_blank">http://source.squeak.org/VMMaker/VMMaker.oscog-eem.1755.mcz</a><br>
<br>
==================== Summary ====================<br>
<br>
Name: VMMaker.oscog-eem.1755<br>
Author: eem<br>
Time: 1 January 1970, 2:26:33.237515 pm<br></blockquote><div><br></div><div>^^Ouch^^ !! That&#39;s what one gets for living on the bleeding edge :-/</div><div> </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">
UUID: adcfc67f-a856-48b8-aef2-71ff6275a903<br>
Ancestors: VMMaker.oscog-nice.1754<br>
<br>
Spur Cogit:<br>
Add a compile-time flag, CheckRememberedInTrampoline, that controls whether the remembered check is generated in-line or in the trampoline.  If checked in the trampoline and on 64-bits use one memory access to get the header and share the access between the IMMUTABILITY check and the rememberedBit check.  Factor out the rememberedBit check into its own method.<br>
<br>
The default leaves the code unchanged.  I doubt that the option will improve anything significantly; measuring the generated code in the simulator the option saves only 0.6% of generated code.  But it&#39;s so lovely being able to explore the question in a couple of hours instead of at least a day or two in C.<br>
<br>
Here&#39;s the data: CRIT=CheckRememberedInTrampoline; this methid is the last method generated in a listener image before it prompts the user:<br>
IMMTABILITY:    16r93F80 &lt;-&gt;    16r940E8: method:   16rC582F8 prim 117 selector:   16r6D12C8 primRead:into:startingAt:count:<br>
IMMTABILICRIT:  16r93250 &lt;-&gt;    16r933B8: method:   16rC582F8 prim 117 selector:   16r6D12C8 primRead:into:startingAt:count:<br>
VANILLA:                16r91C00 &lt;-&gt;    16r91D68: method:   16rC582F8 prim 117 selector:   16r6D12C8 primRead:into:startingAt:count:<br>
VANILLACRIT:    16r90D80 &lt;-&gt;    16r90EE8: method:   16rC582F8 prim 117 selector:   16r6D12C8 primRead:into:startingAt:count:<br>
16r93F80 - 16r93250 / 16r93250 * 100.0 0.5601422920704027<br>
16r91C00 - 16r90D80 / 16r90D80 * 100.0 0.6256742179072277<br>
<br>
And interestingly IMMUTABILITY adds only 1.5% to the code bulk; writes are rare.<br>
16r93F80 - 16r91C00 / 16r91C00 * 100.0 1.5222984562607205<br>
16r93250 - 16r90D80 / 16r90D80 * 100.0 1.5884573894282634<br>
<br>
=============== Diff against VMMaker.oscog-nice.1754 ===============<br>
<br>
Item was added:<br>
+ ----- Method: CogObjectRepresentation class&gt;&gt;initializeMiscConstants (in category &#39;initialization&#39;) -----<br>
+ initializeMiscConstants<br>
+       &quot;Override to avoid inheriting (and hence repeating) VMClass class&gt;&gt;initializeMiscConstants.<br>
+        Subclasses that have misc constants to initialize will override further.&quot;!<br>
<br>
Item was changed:<br>
  CogObjectRepresentation subclass: #CogObjectRepresentationForSpur<br>
        instanceVariableNames: &#39;ceScheduleScavengeTrampoline ceSmallActiveContextInMethodTrampoline ceSmallActiveContextInBlockTrampoline ceLargeActiveContextInMethodTrampoline ceLargeActiveContextInBlockTrampoline ceStoreCheckContextReceiverTrampoline ceStoreTrampolines&#39;<br>
+       classVariableNames: &#39;CheckRememberedInTrampoline NumStoreTrampolines&#39;<br>
-       classVariableNames: &#39;NumStoreTrampolines&#39;<br>
        poolDictionaries: &#39;VMBytecodeConstants VMSqueakClassIndices&#39;<br>
        category: &#39;VMMaker-JIT&#39;!<br>
<br>
Item was added:<br>
+ ----- Method: CogObjectRepresentationForSpur class&gt;&gt;initializeMiscConstants (in category &#39;initialization&#39;) -----<br>
+ initializeMiscConstants<br>
+       CheckRememberedInTrampoline := initializationOptions at: #CheckRememberedInTrampoline ifAbsent: [false]!<br>
<br>
Item was added:<br>
+ ----- Method: CogObjectRepresentationForSpur&gt;&gt;genCheckRememberedBitOf:scratch: (in category &#39;compile abstract instructions&#39;) -----<br>
+ genCheckRememberedBitOf: objReg scratch: scratchReg<br>
+       &quot;Check the remembered bit of the object in objReg; answer the jump taken if the bit is already set.<br>
+        Only need to fetch the byte containing it, which reduces the size of the mask constant.&quot;<br>
+       | rememberedBitByteOffset mask |<br>
+       rememberedBitByteOffset := cogit backEnd isBigEndian<br>
+                                                                       ifTrue: [objectMemory baseHeaderSize - 1 - (objectMemory rememberedBitShift // 8)]<br>
+                                                                       ifFalse:[objectMemory rememberedBitShift // 8].<br>
+       mask := 1 &lt;&lt; (objectMemory rememberedBitShift \\ 8).<br>
+       cogit MoveMb: rememberedBitByteOffset r: objReg R: scratchReg.<br>
+       cogit TstCq: mask R: scratchReg.<br>
+       ^cogit JumpNonZero: 0!<br>
<br>
Item was changed:<br>
  ----- Method: CogObjectRepresentationForSpur&gt;&gt;genStoreCheckReceiverReg:valueReg:scratchReg:inFrame: (in category &#39;compile abstract instructions&#39;) -----<br>
  genStoreCheckReceiverReg: destReg valueReg: valueReg scratchReg: scratchReg inFrame: inFrame<br>
        &quot;Generate the code for a store check of valueReg into destReg.&quot;<br>
+       | jmpImmediate jmpDestYoung jmpSourceOld jmpAlreadyRemembered |<br>
-       | jmpImmediate jmpDestYoung jmpSourceOld jmpAlreadyRemembered mask rememberedBitByteOffset |<br>
        &lt;var: #jmpImmediate type: #&#39;AbstractInstruction *&#39;&gt;<br>
        &lt;var: #jmpDestYoung type: #&#39;AbstractInstruction *&#39;&gt;<br>
        &lt;var: #jmpSourceOld type: #&#39;AbstractInstruction *&#39;&gt;<br>
        &lt;var: #jmpAlreadyRemembered type: #&#39;AbstractInstruction *&#39;&gt;<br>
        &quot;Is value stored an immediate?  If so we&#39;re done&quot;<br>
        jmpImmediate := self genJumpImmediate: valueReg.<br>
        &quot;Get the old/new boundary in scratchReg&quot;<br>
        cogit MoveCw: objectMemory storeCheckBoundary R: scratchReg.<br>
        &quot;Is target young?  If so we&#39;re done&quot;<br>
        cogit CmpR: scratchReg R: destReg. &quot;N.B. FLAGS := destReg - scratchReg&quot;<br>
        jmpDestYoung := cogit JumpBelow: 0.<br>
        &quot;Is value stored old?  If so we&#39;re done.&quot;<br>
        cogit CmpR: scratchReg R: valueReg. &quot;N.B. FLAGS := valueReg - scratchReg&quot;<br>
        jmpSourceOld := cogit JumpAboveOrEqual: 0.<br>
        &quot;value is young and target is old.<br>
+        Need to remember this only if the remembered bit is not already set.&quot;<br>
+       CheckRememberedInTrampoline ifFalse:<br>
+               [jmpAlreadyRemembered := self genCheckRememberedBitOf: destReg scratch: scratchReg].<br>
-        Need to remember this only if the remembered bit is not already set.<br>
-        Test the remembered bit.  Only need to fetch the byte containing it,<br>
-        which reduces the size of the mask constant.&quot;<br>
-       rememberedBitByteOffset := jmpSourceOld isBigEndian<br>
-                                                                       ifTrue: [objectMemory baseHeaderSize - 1 - (objectMemory rememberedBitShift // 8)]<br>
-                                                                       ifFalse:[objectMemory rememberedBitShift // 8].<br>
-       mask := 1 &lt;&lt; (objectMemory rememberedBitShift \\ 8).<br>
-       cogit MoveMb: rememberedBitByteOffset r: destReg R: scratchReg.<br>
-       cogit AndCq: mask R: scratchReg.<br>
-       jmpAlreadyRemembered := cogit JumpNonZero: 0.<br>
        &quot;Remembered bit is not set.  Call store check to insert dest into remembered table.&quot;<br>
        self assert: destReg = ReceiverResultReg.<br>
        cogit<br>
                evaluateTrampolineCallBlock: [cogit CallRT: ceStoreCheckTrampoline]<br>
                protectLinkRegIfNot: inFrame.<br>
        jmpImmediate jmpTarget:<br>
        (jmpDestYoung jmpTarget:<br>
        (jmpSourceOld jmpTarget:<br>
+               cogit Label)).<br>
+       CheckRememberedInTrampoline ifFalse:<br>
+               [jmpAlreadyRemembered jmpTarget: jmpSourceOld getJmpTarget].<br>
-       (jmpAlreadyRemembered jmpTarget:<br>
-               cogit Label))).<br>
        ^0!<br>
<br>
Item was added:<br>
+ ----- Method: CogObjectRepresentationForSpur&gt;&gt;genStoreCheckTrampoline (in category &#39;initialization&#39;) -----<br>
+ genStoreCheckTrampoline<br>
+       | jumpSC |<br>
+       &lt;var: #jumpSC type: #&#39;AbstractInstruction *&#39;&gt;<br>
+       &lt;inline: true&gt;<br>
+       CheckRememberedInTrampoline ifTrue:<br>
+               [cogit zeroOpcodeIndex.<br>
+                jumpSC := self genCheckRememberedBitOf: ReceiverResultReg scratch: cogit backEnd cResultRegister.<br>
+                self assert: jumpSC opcode = JumpNonZero.<br>
+                jumpSC opcode: JumpZero.<br>
+                cogit RetN: 0.<br>
+                jumpSC jmpTarget: cogit Label].<br>
+       ^cogit<br>
+               genTrampolineFor: #remember:<br>
+               called: &#39;ceStoreCheckTrampoline&#39;<br>
+               numArgs: 1<br>
+               arg: ReceiverResultReg<br>
+               arg: nil<br>
+               arg: nil<br>
+               arg: nil<br>
+               regsToSave: (cogit callerSavedRegMask bitClear: (cogit registerMaskFor: ReceiverResultReg))<br>
+               pushLinkReg: true<br>
+               resultReg: cogit returnRegForStoreCheck<br>
+               appendOpcodes: CheckRememberedInTrampoline!<br>
<br>
Item was changed:<br>
  ----- Method: CogObjectRepresentationForSpur&gt;&gt;genStoreTrampolineCalled:instVarIndex: (in category &#39;initialization&#39;) -----<br>
  genStoreTrampolineCalled: trampolineName instVarIndex: instVarIndex<br>
        &quot;Convention:<br>
        - RcvrResultReg holds the object mutated.<br>
        If immutability failure:<br>
        - TempReg holds the instance variable index mutated<br>
                if instVarIndex &gt; numDedicatedStoreTrampoline<br>
        - ClassReg holds the value to store<br>
        Registers are not lived across this trampoline as the<br>
        immutability failure may need new stack frames.&quot;<br>
<br>
+       | jumpSC jumpRC |<br>
-       | jumpSC |<br>
        &lt;option: #IMMUTABILITY&gt;<br>
        &lt;var: #trampolineName type: #&#39;char *&#39;&gt;<br>
        &lt;var: #jumpSC type: #&#39;AbstractInstruction *&#39;&gt;<br>
+       &lt;var: #jumpRC type: #&#39;AbstractInstruction *&#39;&gt;<br>
        &lt;inline: false&gt;<br>
        cogit zeroOpcodeIndex.<br>
        &quot;SendNumArgsReg is mutated but we don&#39;t care as register are not live across the trampoline.<br>
         There is no reason why registers cannot be saved over the remember: call, but since the<br>
         immutability check is a suspension point, registers cannot remain live.&quot;<br>
        jumpSC := self genJumpMutable: ReceiverResultReg scratchReg: SendNumArgsReg.<br>
        cogit<br>
                compileTrampolineFor: #ceCannotAssignTo:withIndex:valueToAssign:<br>
                numArgs: 3<br>
                arg: ReceiverResultReg<br>
                arg: (instVarIndex &lt; (NumStoreTrampolines - 1)<br>
                                ifTrue: [cogit trampolineArgConstant: instVarIndex]<br>
                                ifFalse: [TempReg])<br>
                arg: ClassReg<br>
                arg: nil<br>
                regsToSave: cogit emptyRegisterMask<br>
                pushLinkReg: true<br>
                resultReg: NoReg.<br>
<br>
        &quot;Store check&quot;<br>
        jumpSC jmpTarget: cogit Label.<br>
+       &quot;If on 64-bits and doing the remembered bit test here, we can combine the tests to fetch the header once.&quot;<br>
+       CheckRememberedInTrampoline ifTrue:<br>
+               [objectMemory wordSize = 8<br>
+                       ifTrue:<br>
+                               [cogit TstCq: 1 &lt;&lt; objectMemory rememberedBitShift R: SendNumArgsReg.<br>
+                                jumpRC := cogit JumpZero: 0.<br>
+                                cogit RetN: 0]<br>
+                       ifFalse:<br>
+                               [jumpRC := self genCheckRememberedBitOf: ReceiverResultReg scratch: SendNumArgsReg.<br>
+                                self assert: jumpRC opcode = JumpNonZero.<br>
+                                jumpRC opcode: JumpZero.<br>
+                                cogit RetN: 0].<br>
+                jumpRC jmpTarget: cogit Label].<br>
        ^ cogit genTrampolineFor: #remember:<br>
                called: trampolineName<br>
                numArgs: 1<br>
                arg: ReceiverResultReg<br>
                arg: nil<br>
                arg: nil<br>
                arg: nil<br>
                regsToSave: cogit emptyRegisterMask<br>
                pushLinkReg: true<br>
                resultReg: NoReg<br>
                appendOpcodes: true!<br>
<br>
Item was changed:<br>
  ----- Method: CogObjectRepresentationForSpur&gt;&gt;genStoreWithImmutabilityAndStoreCheckSourceReg:slotIndex:destReg:scratchReg:needRestoreRcvr: (in category &#39;compile abstract instructions&#39;) -----<br>
  genStoreWithImmutabilityAndStoreCheckSourceReg: sourceReg slotIndex: index destReg: destReg scratchReg: scratchReg needRestoreRcvr: needRestoreRcvr<br>
        &quot;Store check code is duplicated to use a single trampoline&quot;<br>
+       | immutableJump jmpImmediate jmpDestYoung jmpSourceOld jmpAlreadyRemembered |<br>
-       | immutableJump jmpImmediate jmpDestYoung jmpSourceOld rememberedBitByteOffset jmpAlreadyRemembered mask |<br>
        &lt;var: #immutableJump type: #&#39;AbstractInstruction *&#39;&gt;<br>
        &lt;var: #jmpImmediate type: #&#39;AbstractInstruction *&#39;&gt;<br>
        &lt;var: #jmpDestYoung type: #&#39;AbstractInstruction *&#39;&gt;<br>
        &lt;var: #jmpSourceOld type: #&#39;AbstractInstruction *&#39;&gt;<br>
        &lt;var: #jmpAlreadyRemembered type: #&#39;AbstractInstruction *&#39;&gt;<br>
<br>
        immutableJump := self genJumpImmutable: destReg scratchReg: scratchReg.<br>
<br>
        cogit genTraceStores.<br>
<br>
        &quot;do the store&quot;<br>
        cogit MoveR: sourceReg<br>
                   Mw: index * objectMemory wordSize + objectMemory baseHeaderSize<br>
                   r: destReg.<br>
<br>
        &quot;store check&quot;<br>
        jmpImmediate := self genJumpImmediate: sourceReg.<br>
        &quot;Get the old/new boundary in scratchReg&quot;<br>
        cogit MoveCw: objectMemory storeCheckBoundary R: scratchReg.<br>
        &quot;Is target young?  If so we&#39;re done&quot;<br>
        cogit CmpR: scratchReg R: destReg. &quot;N.B. FLAGS := destReg - scratchReg&quot;<br>
        jmpDestYoung := cogit JumpBelow: 0.<br>
        &quot;Is value stored old?  If so we&#39;re done.&quot;<br>
        cogit CmpR: scratchReg R: sourceReg. &quot;N.B. FLAGS := valueReg - scratchReg&quot;<br>
        jmpSourceOld := cogit JumpAboveOrEqual: 0.<br>
        &quot;value is young and target is old.<br>
+        Need to remember this only if the remembered bit is not already set.&quot;<br>
+       CheckRememberedInTrampoline ifFalse:<br>
+               [jmpAlreadyRemembered := self genCheckRememberedBitOf: destReg scratch: scratchReg].<br>
-        Need to remember this only if the remembered bit is not already set.<br>
-        Test the remembered bit.  Only need to fetch the byte containing it,<br>
-        which reduces the size of the mask constant.&quot;<br>
-       rememberedBitByteOffset := jmpSourceOld isBigEndian<br>
-                                                                       ifTrue: [objectMemory baseHeaderSize - 1 - (objectMemory rememberedBitShift // 8)]<br>
-                                                                       ifFalse:[objectMemory rememberedBitShift // 8].<br>
-       mask := 1 &lt;&lt; (objectMemory rememberedBitShift \\ 8).<br>
-       cogit MoveMb: rememberedBitByteOffset r: destReg R: scratchReg.<br>
-       cogit AndCq: mask R: scratchReg.<br>
-       jmpAlreadyRemembered := cogit JumpNonZero: 0.<br>
        &quot;Set the inst var index for the benefit of the immutability check. The trampoline will<br>
         repeat the check to choose between the immutbality violation and the store check.&quot;<br>
        immutableJump jmpTarget: cogit Label.<br>
        self genStoreTrampolineCall: index.<br>
        needRestoreRcvr ifTrue: [ cogit putSelfInReceiverResultReg ].<br>
<br>
        jmpImmediate jmpTarget:<br>
        (jmpDestYoung jmpTarget:<br>
        (jmpSourceOld jmpTarget:<br>
+               cogit Label)).<br>
+       CheckRememberedInTrampoline ifFalse:<br>
+               [jmpAlreadyRemembered jmpTarget: jmpSourceOld getJmpTarget].<br>
-       (jmpAlreadyRemembered jmpTarget:<br>
-               cogit Label))).<br>
-<br>
        ^ 0!<br>
<br>
Item was changed:<br>
  ----- Method: CogObjectRepresentationForSpur&gt;&gt;generateObjectRepresentationTrampolines (in category &#39;initialization&#39;) -----<br>
  generateObjectRepresentationTrampolines<br>
        &quot;Do the store check.  Answer the argument for the benefit of the code generator;<br>
         ReceiverResultReg may be caller-saved and hence smashed by this call.  Answering<br>
         it allows the code generator to reload ReceiverResultReg cheaply.<br>
         In Spur the only thing we leave to the run-time is adding the receiver to the<br>
         remembered set and setting its isRemembered bit.&quot;<br>
        self<br>
                cppIf: IMMUTABILITY<br>
                ifTrue:<br>
                        [self cCode: [] inSmalltalk:<br>
                                [ceStoreTrampolines := CArrayAccessor on: (Array new: NumStoreTrampolines)].<br>
                         0 to: NumStoreTrampolines - 1 do:<br>
                                [:instVarIndex |<br>
                                 ceStoreTrampolines<br>
                                        at: instVarIndex<br>
                                        put: (self<br>
                                                        genStoreTrampolineCalled: (cogit<br>
                                                                                                                        trampolineName: &#39;ceStoreTrampoline&#39;<br>
                                                                                                                        numArgs: instVarIndex<br>
                                                                                                                        limit: NumStoreTrampolines - 2)<br>
                                                        instVarIndex: instVarIndex)]].<br>
+       ceStoreCheckTrampoline := self genStoreCheckTrampoline.<br>
-       ceStoreCheckTrampoline := cogit<br>
-                                                                       genTrampolineFor: #remember:<br>
-                                                                       called: &#39;ceStoreCheckTrampoline&#39;<br>
-                                                                       arg: ReceiverResultReg<br>
-                                                                       regsToSave: (cogit callerSavedRegMask bitClear: (cogit registerMaskFor: ReceiverResultReg))<br>
-                                                                       result: cogit returnRegForStoreCheck.<br>
        ceStoreCheckContextReceiverTrampoline := self genStoreCheckContextReceiverTrampoline.<br>
        ceScheduleScavengeTrampoline := cogit<br>
                                                                                        genTrampolineFor: #ceScheduleScavenge<br>
                                                                                        called: &#39;ceScheduleScavengeTrampoline&#39;<br>
                                                                                        regsToSave: cogit callerSavedRegMask.<br>
        ceSmallActiveContextInMethodTrampoline := self genActiveContextTrampolineLarge: false inBlock: false called: &#39;ceSmallMethodContext&#39;.<br>
        ceSmallActiveContextInBlockTrampoline := self genActiveContextTrampolineLarge: false inBlock: true called: &#39;ceSmallBlockContext&#39;.<br>
        ceLargeActiveContextInMethodTrampoline := self genActiveContextTrampolineLarge: true inBlock: false called: &#39;ceLargeMethodContext&#39;.<br>
        ceLargeActiveContextInBlockTrampoline := self genActiveContextTrampolineLarge: true inBlock: true called: &#39;ceLargeBlockContext&#39;!<br>
<br>
Item was changed:<br>
  ----- Method: Cogit class&gt;&gt;initializeMiscConstants (in category &#39;class initialization&#39;) -----<br>
  initializeMiscConstants<br>
        super initializeMiscConstants.<br>
        Debug := initializationOptions at: #Debug ifAbsent: [false].<br>
        (initializationOptions includesKey: #EagerInstructionDecoration)<br>
                ifTrue:<br>
                        [EagerInstructionDecoration := initializationOptions at: #EagerInstructionDecoration]<br>
                ifFalse:<br>
                        [EagerInstructionDecoration ifNil:<br>
                                [EagerInstructionDecoration := false]]. &quot;speeds up single stepping but could lose fidelity&quot;<br>
<br>
        ProcessorClass := (initializationOptions at: #ISA ifAbsentPut: [self objectMemoryClass defaultISA]) caseOf: {<br>
                                                        [#X64]          -&gt;      [BochsX64Alien].<br>
                                                        [#IA32]         -&gt;      [BochsIA32Alien].<br>
                                                        [#ARMv5]        -&gt;      [GdbARMAlien].<br>
                                                        [#MIPSEL]       -&gt;      [MIPSELSimulator] }.<br>
        CogCompilerClass := self activeCompilerClass.<br>
        (CogCompilerClass withAllSuperclasses copyUpTo: CogAbstractInstruction) reverseDo:<br>
                [:compilerClass| compilerClass initialize; initializeAbstractRegisters].<br>
+       self objectMemoryClass objectRepresentationClass initializeMiscConstants.<br>
        &quot;Our criterion for which methods to JIT is literal count.  The default value is 60 literals or less.&quot;<br>
        MaxLiteralCountForCompile := initializationOptions at: #MaxLiteralCountForCompile ifAbsent: [60].<br>
        &quot;we special-case 0, 1 &amp; 2 argument sends, N is numArgs &gt;= 3&quot;<br>
        NumSendTrampolines := 4.<br>
        &quot;Currently not even the ceImplicitReceiverTrampoline contains object references.&quot;<br>
        NumObjRefsInRuntime := 0.<br>
<br>
        NSCSelectorIndex := (NSSendCache instVarNames indexOf: #selector) - 1.<br>
        NSCNumArgsIndex := (NSSendCache instVarNames indexOf: #numArgs) - 1.<br>
        NSCClassTagIndex := (NSSendCache instVarNames indexOf: #classTag) - 1.<br>
        NSCEnclosingObjectIndex := (NSSendCache instVarNames indexOf: #enclosingObject) - 1.<br>
        NSCTargetIndex := (NSSendCache instVarNames indexOf: #target) - 1.<br>
        NumOopsPerNSC := NSSendCache instVarNames size.<br>
<br>
        &quot;Max size to alloca when compiling.<br>
         Mac OS X 10.6.8 segfaults approaching 8Mb.<br>
         Linux 2.6.9 segfaults above 11Mb.<br>
         WIndows XP segfaults approaching 2Mb.&quot;<br>
        MaxStackAllocSize := 1024 * 1024 * 3 / 2 !<br>
<br>
Item was changed:<br>
  ----- Method: VMBasicConstants class&gt;&gt;namesDefinedAtCompileTime (in category &#39;C translation&#39;) -----<br>
  namesDefinedAtCompileTime<br>
        &quot;Answer the set of names for variables that should be defined at compile time.<br>
         Some of these get default values during simulation, and hence get defaulted in<br>
         the various initializeMiscConstants methods.  But that they have values should<br>
         /not/ cause the code generator to do dead code elimination based on their<br>
         default values.&quot;<br>
        ^#(     VMBIGENDIAN<br>
                IMMUTABILITY<br>
                STACKVM COGVM COGMTVM SPURVM<br>
+               PharoVM                                                         &quot;Pharo vs Squeak&quot;<br>
+               EnforceAccessControl                                    &quot;Newspeak&quot;<br>
+               CheckRememberedInTrampoline)            &quot;IMMUTABILITY&quot;!<br>
-               &quot;Pharo vs Squeak&quot; PharoVM<br>
-               &quot;Newspeak&quot; EnforceAccessControl)!<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>