<div dir="ltr">Eliot,<div><br></div><div>Recent commits are very exciting. Context and closure creations are now inlined in machine code :-)</div><div><br></div><div>Have you already done at:put: and stringAt:put: or is it your next step ?</div>

<div><br></div><div>Please tell us about the new bench results with these features.</div><div><br></div><div>Clément</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">2014-06-02 16:14 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:0 0 0 .8ex;border-left:1px #ccc 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.746.mcz" target="_blank">http://source.squeak.org/VMMaker/VMMaker.oscog-eem.746.mcz</a><br>
<br>
==================== Summary ====================<br>
<br>
Name: VMMaker.oscog-eem.746<br>
Author: eem<br>
Time: 1 June 2014, 6:05:30.694 pm<br>
UUID: cc4961d3-e629-4e28-b308-88eab314a8c9<br>
Ancestors: VMMaker.oscog-eem.745<br>
<br>
Implement a peephole in the Spur Cogit for an indirection<br>
vector initialized with a single value  Avoid initializing the<br>
slot in the array to nil and instead initialize it with the value.<br>
<br>
Refactor setting byte1, byte2 &amp; byte3 into<br>
loadSubsequentBytesForDescriptor:at: for the peephole<br>
tryCollapseTempVectorInitializationOfSize:.<br>
<br>
No loner inline CoInterpreter&gt;&gt;pre/postGCAction: for VM profiling.<br>
<br>
Increase the number of trampoline table slots.<br>
<br>
Simulator:<br>
Fix CurrentImageCoInterpreterFacade for the new Spur<br>
inline instantiation code.<br>
<br>
=============== Diff against VMMaker.oscog-eem.745 ===============<br>
<br>
Item was changed:<br>
  ----- Method: CoInterpreter&gt;&gt;postGCAction: (in category &#39;object memory support&#39;) -----<br>
  postGCAction: gcModeArg<br>
        &quot;Attempt to shrink free memory, signal the gc semaphore and let the Cogit do its post GC thang&quot;<br>
+       &lt;inline: false&gt;<br>
        self assert: gcModeArg = gcMode.<br>
        super postGCAction: gcModeArg.<br>
        cogit cogitPostGCAction: gcModeArg.<br>
        lastCoggableInterpretedBlockMethod := lastUncoggableInterpretedBlockMethod := nil.<br>
        gcMode := 0!<br>
<br>
Item was changed:<br>
  ----- Method: CoInterpreter&gt;&gt;preGCAction: (in category &#39;object memory support&#39;) -----<br>
  preGCAction: gcModeArg<br>
+       &lt;inline: false&gt;<br>
-       &lt;inline: true&gt;<br>
        &quot;Need to write back the frame pointers unless all pages are free (as in snapshot).<br>
         Need to set gcMode var (to avoid passing the flag through a lot of the updating code)&quot;<br>
        super preGCAction: gcModeArg.<br>
<br>
        gcMode := gcModeArg.<br>
<br>
        cogit recordEventTrace ifTrue:<br>
                [| traceType |<br>
                traceType := gcModeArg == GCModeFull ifTrue: [TraceFullGC] ifFalse: [TraceIncrementalGC].<br>
                self recordTrace: traceType thing: traceType source: 0].<br>
<br>
        cogit recordPrimTrace ifTrue:<br>
                [| traceType |<br>
                traceType := gcModeArg == GCModeFull ifTrue: [TraceFullGC] ifFalse: [TraceIncrementalGC].<br>
                self fastLogPrim: traceType]!<br>
<br>
Item was added:<br>
+ ----- Method: CogObjectRepresentation&gt;&gt;createsArraysInline (in category &#39;bytecode generator support&#39;) -----<br>
+ createsArraysInline<br>
+       &quot;Answer if the object representation allocates arrays inline.  By<br>
+        default answer false. Better code can be generated when creating<br>
+        arrays inline if values are /not/ flushed to the stack.&quot;<br>
+       ^false!<br>
<br>
Item was removed:<br>
- ----- Method: CogObjectRepresentationFor32BitSpur&gt;&gt;createsClosuresInline (in category &#39;bytecode generator support&#39;) -----<br>
- createsClosuresInline<br>
-       &quot;Answer if the object representation allocates closures inline.  By<br>
-        default answer false. Better code can be generated when creating<br>
-        closures inline if copied values are /not/ flushed to the stack.&quot;<br>
-       ^true!<br>
<br>
Item was added:<br>
+ ----- Method: CogObjectRepresentationForSpur&gt;&gt;createsArraysInline (in category &#39;bytecode generator support&#39;) -----<br>
+ createsArraysInline<br>
+       &quot;Answer if the object representation allocates arrays inline.  By<br>
+        default answer false. Better code can be generated when creating<br>
+        arrays inline if values are /not/ flushed to the stack.&quot;<br>
+       ^true!<br>
<br>
Item was added:<br>
+ ----- Method: CogObjectRepresentationForSpur&gt;&gt;createsClosuresInline (in category &#39;bytecode generator support&#39;) -----<br>
+ createsClosuresInline<br>
+       &quot;Answer if the object representation allocates closures inline.  By<br>
+        default answer false. Better code can be generated when creating<br>
+        closures inline if copied values are /not/ flushed to the stack.&quot;<br>
+       ^true!<br>
<br>
Item was changed:<br>
  ----- Method: Cogit&gt;&gt;compileAbstractInstructionsFrom:through: (in category &#39;compile abstract instructions&#39;) -----<br>
  compileAbstractInstructionsFrom: start through: end<br>
        &quot;Loop over bytecodes, dispatching to the generator for each bytecode, handling fixups in due course.&quot;<br>
        | nextOpcodeIndex descriptor fixup result nExts |<br>
        &lt;var: #descriptor type: #&#39;BytecodeDescriptor *&#39;&gt;<br>
        &lt;var: #fixup type: #&#39;BytecodeFixup *&#39;&gt;<br>
        bytecodePC := start.<br>
        nExts := 0.<br>
        [byte0 := (objectMemory fetchByte: bytecodePC ofObject: methodObj)  + bytecodeSetOffset.<br>
         descriptor := self generatorAt: byte0.<br>
+        self loadSubsequentBytesForDescriptor: descriptor at: bytecodePC.<br>
-        descriptor numBytes &gt; 1 ifTrue:<br>
-               [byte1 := objectMemory fetchByte: bytecodePC + 1 ofObject: methodObj.<br>
-                descriptor numBytes &gt; 2 ifTrue:<br>
-                       [byte2 := objectMemory fetchByte: bytecodePC + 2 ofObject: methodObj.<br>
-                        descriptor numBytes &gt; 3 ifTrue:<br>
-                               [byte3 := objectMemory fetchByte: bytecodePC + 3 ofObject: methodObj.<br>
-                                descriptor numBytes &gt; 4 ifTrue:<br>
-                                       [self notYetImplemented]]]].<br>
         nextOpcodeIndex := opcodeIndex.<br>
         result := self perform: descriptor generator.<br>
         descriptor isExtension ifFalse: &quot;extended bytecodes must consume their extensions&quot;<br>
                [self assert: (extA = 0 and: [extB = 0])].<br>
         fixup := self fixupAt: bytecodePC - initialPC.<br>
         fixup targetInstruction ~= 0 ifTrue:<br>
                [&quot;There is a fixup for this bytecode.  It must point to the first generated<br>
                   instruction for this bytecode.  If there isn&#39;t one we need to add a label.&quot;<br>
                 opcodeIndex = nextOpcodeIndex ifTrue:<br>
                        [self Label].<br>
                 fixup targetInstruction: (self abstractInstructionAt: nextOpcodeIndex)].<br>
         bytecodePC := self nextBytecodePCFor: descriptor at: bytecodePC exts: nExts in: methodObj.<br>
         result = 0 and: [bytecodePC &lt;= end]]<br>
                whileTrue:<br>
                        [nExts := descriptor isExtension ifTrue: [nExts + 1] ifFalse: [0]].<br>
        self checkEnoughOpcodes.<br>
        ^result!<br>
<br>
Item was added:<br>
+ ----- Method: Cogit&gt;&gt;loadSubsequentBytesForDescriptor:at: (in category &#39;compile abstract instructions&#39;) -----<br>
+ loadSubsequentBytesForDescriptor: descriptor at: pc<br>
+       &lt;var: #descriptor type: #&#39;BytecodeDescriptor *&#39;&gt;<br>
+       descriptor numBytes &gt; 1 ifTrue:<br>
+               [byte1 := objectMemory fetchByte: pc + 1 ofObject: methodObj.<br>
+                descriptor numBytes &gt; 2 ifTrue:<br>
+                       [byte2 := objectMemory fetchByte: pc + 2 ofObject: methodObj.<br>
+                        descriptor numBytes &gt; 3 ifTrue:<br>
+                               [byte3 := objectMemory fetchByte: pc + 3 ofObject: methodObj.<br>
+                                descriptor numBytes &gt; 4 ifTrue:<br>
+                                       [self notYetImplemented]]]]!<br>
<br>
Item was added:<br>
+ ----- Method: CurrentImageCoInterpreterFacade class&gt;&gt;objectMemoryClass (in category &#39;accessing&#39;) -----<br>
+ objectMemoryClass<br>
+       ^self subclassResponsibility!<br>
<br>
Item was changed:<br>
  ----- Method: CurrentImageCoInterpreterFacade&gt;&gt;cogit: (in category &#39;initialize-release&#39;) -----<br>
  cogit: aCogit<br>
        cogit := aCogit.<br>
        coInterpreter cogit: aCogit.<br>
+       (objectMemory respondsTo: #cogit:) ifTrue:<br>
+               [objectMemory cogit: aCogit]!<br>
-       objectMemory cogit: aCogit!<br>
<br>
Item was added:<br>
+ ----- Method: CurrentImageCoInterpreterFacade&gt;&gt;indexablePointersFormat (in category &#39;accessing&#39;) -----<br>
+ indexablePointersFormat<br>
+       ^objectMemory indexablePointersFormat!<br>
<br>
Item was changed:<br>
  ----- Method: CurrentImageCoInterpreterFacade&gt;&gt;initialize (in category &#39;initialize-release&#39;) -----<br>
  initialize<br>
        memory := ByteArray new: 262144.<br>
+       objectMemory := self class objectMemoryClass new.<br>
-       objectMemory := NewCoObjectMemory new.<br>
        coInterpreter := CoInterpreter new.<br>
        coInterpreter<br>
                instVarNamed: &#39;objectMemory&#39;<br>
                        put: objectMemory;<br>
                instVarNamed: &#39;primitiveTable&#39;<br>
                        put: (CArrayAccessor on: CoInterpreter primitiveTable copy).<br>
        variables := Dictionary new.<br>
        #(&#39;stackLimit&#39;) do:<br>
                [:l| self addressForLabel: l].<br>
        self initializeObjectMap!<br>
<br>
Item was added:<br>
+ ----- Method: CurrentImageCoInterpreterFacade&gt;&gt;methodNeedsLargeContext: (in category &#39;accessing&#39;) -----<br>
+ methodNeedsLargeContext: aMethodOop<br>
+       ^(self objectForOop: aMethodOop) frameSize &gt; CompiledMethod smallFrameSize!<br>
<br>
Item was added:<br>
+ ----- Method: CurrentImageCoInterpreterFacadeForSpurObjectRepresentation class&gt;&gt;objectMemoryClass (in category &#39;accessing&#39;) -----<br>
+ objectMemoryClass<br>
+       ^Spur32BitCoMemoryManager!<br>
<br>
Item was added:<br>
+ ----- Method: CurrentImageCoInterpreterFacadeForSpurObjectRepresentation&gt;&gt;arrayFormat (in category &#39;accessing&#39;) -----<br>
+ arrayFormat<br>
+       ^objectMemory arrayFormat!<br>
<br>
Item was added:<br>
+ ----- Method: CurrentImageCoInterpreterFacadeForSpurObjectRepresentation&gt;&gt;getScavengeThreshold (in category &#39;accessing&#39;) -----<br>
+ getScavengeThreshold<br>
+       ^objectMemory getScavengeThreshold ifNil: [16r24680]!<br>
<br>
Item was added:<br>
+ ----- Method: CurrentImageCoInterpreterFacadeForSpurObjectRepresentation&gt;&gt;headerForSlots:format:classIndex: (in category &#39;accessing&#39;) -----<br>
+ headerForSlots: numSlots format: formatField classIndex: classIndex<br>
+       ^objectMemory headerForSlots: numSlots format: formatField classIndex: classIndex!<br>
<br>
Item was added:<br>
+ ----- Method: CurrentImageCoInterpreterFacadeForSpurObjectRepresentation&gt;&gt;numSlotsMask (in category &#39;accessing&#39;) -----<br>
+ numSlotsMask<br>
+       ^objectMemory numSlotsMask!<br>
<br>
Item was added:<br>
+ ----- Method: CurrentImageCoInterpreterFacadeForSpurObjectRepresentation&gt;&gt;rememberedBitShift (in category &#39;accessing&#39;) -----<br>
+ rememberedBitShift<br>
+       ^objectMemory rememberedBitShift!<br>
<br>
Item was added:<br>
+ ----- Method: CurrentImageCoInterpreterFacadeForSpurObjectRepresentation&gt;&gt;smallObjectBytesForSlots: (in category &#39;accessing&#39;) -----<br>
+ smallObjectBytesForSlots: numSlots<br>
+       ^objectMemory smallObjectBytesForSlots: numSlots!<br>
<br>
Item was added:<br>
+ ----- Method: CurrentImageCoInterpreterFacadeForSpurObjectRepresentation&gt;&gt;storeCheckBoundary (in category &#39;accessing&#39;) -----<br>
+ storeCheckBoundary<br>
+       ^objectMemory storeCheckBoundary ifNil: [16r12345678]!<br>
<br>
Item was added:<br>
+ ----- Method: CurrentImageCoInterpreterFacadeForSqueakV3ObjectRepresentation class&gt;&gt;objectMemoryClass (in category &#39;accessing&#39;) -----<br>
+ objectMemoryClass<br>
+       ^NewObjectMemory!<br>
<br>
Item was changed:<br>
  ----- Method: SimpleStackBasedCogit class&gt;&gt;initializeMiscConstants (in category &#39;class initialization&#39;) -----<br>
  initializeMiscConstants<br>
        super initializeMiscConstants.<br>
        MaxLiteralCountForCompile := initializationOptions at: #MaxLiteralCountForCompile ifAbsent: [60].<br>
        NumTrampolines := NewspeakVM<br>
+                                                       ifTrue: [50]<br>
+                                                       ifFalse: [42]!<br>
-                                                       ifTrue: [46]<br>
-                                                       ifFalse: [38]!<br>
<br>
Item was changed:<br>
  ----- Method: StackToRegisterMappingCogit class&gt;&gt;initializeMiscConstants (in category &#39;class initialization&#39;) -----<br>
  initializeMiscConstants<br>
        super initializeMiscConstants.<br>
        NumTrampolines := NewspeakVM<br>
+                                                       ifTrue: [60]<br>
+                                                       ifFalse: [52]!<br>
-                                                       ifTrue: [58]<br>
-                                                       ifFalse: [50]!<br>
<br>
Item was changed:<br>
  ----- Method: StackToRegisterMappingCogit&gt;&gt;compileAbstractInstructionsFrom:through: (in category &#39;compile abstract instructions&#39;) -----<br>
  compileAbstractInstructionsFrom: start through: end<br>
        &quot;Loop over bytecodes, dispatching to the generator for each bytecode, handling fixups in due course.&quot;<br>
        | nextOpcodeIndex descriptor nExts fixup result |<br>
        &lt;var: #descriptor type: #&#39;BytecodeDescriptor *&#39;&gt;<br>
        &lt;var: #fixup type: #&#39;BytecodeFixup *&#39;&gt;<br>
        self traceSimStack.<br>
        bytecodePC := start.<br>
        nExts := 0.<br>
        descriptor := nil.<br>
        deadCode := false.<br>
        [self cCode: &#39;&#39; inSmalltalk:<br>
                [(debugBytecodePointers includes: bytecodePC) ifTrue: [self halt]].<br>
        fixup := self fixupAt: bytecodePC - initialPC.<br>
        fixup targetInstruction asUnsignedInteger &gt; 0<br>
                ifTrue:<br>
                        [deadCode := false.<br>
                         fixup targetInstruction asUnsignedInteger &gt;= 2 ifTrue:<br>
                                [self merge: fixup<br>
                                        afterContinuation: (descriptor notNil<br>
                                                                                and: [descriptor isUnconditionalBranch<br>
                                                                                        or: [descriptor isReturn]]) not]]<br>
                ifFalse: &quot;If there&#39;s no fixup following a return there&#39;s no jump to that code and it is dead.&quot;<br>
                        [(descriptor notNil and: [descriptor isReturn]) ifTrue:<br>
                                [deadCode := true]].<br>
         self cCode: &#39;&#39; inSmalltalk:<br>
                [deadCode ifFalse:<br>
                        [self assert: simStackPtr + (needsFrame ifTrue: [0] ifFalse: [1])<br>
                                                = (self debugStackPointerFor: bytecodePC)]].<br>
         byte0 := (objectMemory fetchByte: bytecodePC ofObject: methodObj) + bytecodeSetOffset.<br>
         descriptor := self generatorAt: byte0.<br>
+        self loadSubsequentBytesForDescriptor: descriptor at: bytecodePC.<br>
-        descriptor numBytes &gt; 1 ifTrue:<br>
-               [byte1 := objectMemory fetchByte: bytecodePC + 1 ofObject: methodObj.<br>
-                descriptor numBytes &gt; 2 ifTrue:<br>
-                       [byte2 := objectMemory fetchByte: bytecodePC + 2 ofObject: methodObj.<br>
-                        descriptor numBytes &gt; 3 ifTrue:<br>
-                               [byte3 := objectMemory fetchByte: bytecodePC + 3 ofObject: methodObj.<br>
-                                descriptor numBytes &gt; 4 ifTrue:<br>
-                                       [self notYetImplemented]]]].<br>
         nextOpcodeIndex := opcodeIndex.<br>
         result := deadCode<br>
                                ifTrue: &quot;insert nops for dead code that is mapped so that bc to mc mapping is not many to one&quot;<br>
                                        [(descriptor isMapped<br>
                                          or: [inBlock and: [descriptor isMappedInBlock]]) ifTrue:<br>
                                                [self annotateBytecode: self Nop].<br>
                                                0]<br>
                                ifFalse:<br>
                                        [self perform: descriptor generator].<br>
         descriptor isExtension ifFalse: &quot;extended bytecodes must consume their extensions&quot;<br>
                [self assert: (extA = 0 and: [extB = 0])].<br>
         self traceDescriptor: descriptor; traceSimStack.<br>
         (fixup targetInstruction asUnsignedInteger between: 1 and: 2) ifTrue:<br>
                [&quot;There is a fixup for this bytecode.  It must point to the first generated<br>
                   instruction for this bytecode.  If there isn&#39;t one we need to add a label.&quot;<br>
                 opcodeIndex = nextOpcodeIndex ifTrue:<br>
                        [self Label].<br>
                 fixup targetInstruction: (self abstractInstructionAt: nextOpcodeIndex)].<br>
         bytecodePC := self nextBytecodePCFor: descriptor at: bytecodePC exts: nExts in: methodObj.<br>
         result = 0 and: [bytecodePC &lt;= end]] whileTrue:<br>
                [nExts := descriptor isExtension ifTrue: [nExts + 1] ifFalse: [0]].<br>
        self checkEnoughOpcodes.<br>
        ^result!<br>
<br>
Item was added:<br>
+ ----- Method: StackToRegisterMappingCogit&gt;&gt;evaluate:at: (in category &#39;peephole optimizations&#39;) -----<br>
+ evaluate: descriptor at: pc<br>
+       &lt;var: #descriptor type: #&#39;BytecodeDescriptor *&#39;&gt;<br>
+       byte0 := objectMemory fetchByte: pc ofObject: methodObj.<br>
+       self assert: descriptor = (self generatorAt: bytecodeSetOffset + byte0).<br>
+       self loadSubsequentBytesForDescriptor: descriptor at: pc.<br>
+       self perform: descriptor generator!<br>
<br>
Item was changed:<br>
  ----- Method: StackToRegisterMappingCogit&gt;&gt;genPushNewArrayBytecode (in category &#39;bytecode generators&#39;) -----<br>
  genPushNewArrayBytecode<br>
        | size popValues |<br>
        self assert: needsFrame.<br>
        optStatus isReceiverResultRegLive: false.<br>
        (popValues := byte1 &gt; 127)<br>
                ifTrue: [self ssFlushTo: simStackPtr]<br>
                ifFalse: [self ssAllocateCallReg: SendNumArgsReg and: ReceiverResultReg].<br>
        size := byte1 bitAnd: 127.<br>
+       popValues ifFalse:<br>
+               [(self tryCollapseTempVectorInitializationOfSize: size) ifTrue:<br>
+                       [^0]].<br>
        objectRepresentation genNewArrayOfSize: size initialized: popValues not.<br>
        popValues ifTrue:<br>
                [size - 1 to: 0 by: -1 do:<br>
                        [:i|<br>
                        self PopR: TempReg.<br>
                        objectRepresentation<br>
                                genStoreSourceReg: TempReg<br>
                                slotIndex: i<br>
                                intoNewObjectInDestReg: ReceiverResultReg].<br>
                 self ssPop: size].<br>
        ^self ssPushRegister: ReceiverResultReg!<br>
<br>
Item was added:<br>
+ ----- Method: StackToRegisterMappingCogit&gt;&gt;tryCollapseTempVectorInitializationOfSize: (in category &#39;peephole optimizations&#39;) -----<br>
+ tryCollapseTempVectorInitializationOfSize: slots<br>
+       &quot;Try and collapse<br>
+               push: (Array new: 1)<br>
+               popIntoTemp: tempIndex<br>
+               pushConstant: const or pushTemp: n<br>
+               popIntoTemp: 0 inVectorAt: tempIndex<br>
+        into<br>
+               tempAt: tempIndex put: {const}.<br>
+        One might think that we should look for a sequence of more than<br>
+        one pushes and pops but this is extremely rare.&quot;<br>
+       | pushArrayDesc storeArrayDesc pushValueDesc storeValueDesc reg |<br>
+       &lt;var: #pushArrayDesc type: #&#39;BytecodeDescriptor *&#39;&gt;<br>
+       &lt;var: #pushValueDesc type: #&#39;BytecodeDescriptor *&#39;&gt;<br>
+       &lt;var: #storeArrayDesc type: #&#39;BytecodeDescriptor *&#39;&gt;<br>
+       &lt;var: #storeValueDesc type: #&#39;BytecodeDescriptor *&#39;&gt;<br>
+       slots ~= 1 ifTrue:<br>
+               [^false].<br>
+       pushArrayDesc := self generatorAt: bytecodeSetOffset<br>
+                                                                               + (objectMemory<br>
+                                                                                               fetchByte: bytecodePC<br>
+                                                                                               ofObject: methodObj).<br>
+       self assert: pushArrayDesc generator == #genPushNewArrayBytecode.<br>
+       storeArrayDesc := self generatorAt: bytecodeSetOffset<br>
+                                                                               + (objectMemory<br>
+                                                                                               fetchByte: bytecodePC<br>
+                                                                                                               + pushArrayDesc numBytes<br>
+                                                                                               ofObject: methodObj).<br>
+       storeArrayDesc generator ~~ #genStoreAndPopTemporaryVariableBytecode ifTrue:<br>
+               [^false].<br>
+       pushValueDesc := self generatorAt: bytecodeSetOffset<br>
+                                                                               + (objectMemory<br>
+                                                                                               fetchByte: bytecodePC<br>
+                                                                                                               + pushArrayDesc numBytes<br>
+                                                                                                               + storeArrayDesc numBytes<br>
+                                                                                               ofObject: methodObj).<br>
+       (pushValueDesc generator ~~ #genPushLiteralConstantBytecode<br>
+        and: [pushValueDesc generator ~~ #genPushQuickIntegerConstantBytecode<br>
+        and: [pushValueDesc generator ~~ #genPushTemporaryVariableBytecode]]) ifTrue:<br>
+               [^false].<br>
+       storeValueDesc := self generatorAt: bytecodeSetOffset<br>
+                                                                               + (objectMemory<br>
+                                                                                               fetchByte: bytecodePC<br>
+                                                                                                               + pushArrayDesc numBytes<br>
+                                                                                                               + storeArrayDesc numBytes<br>
+                                                                                                               + pushValueDesc numBytes<br>
+                                                                                               ofObject: methodObj).<br>
+       storeValueDesc generator ~~ #genStoreAndPopRemoteTempLongBytecode ifTrue:<br>
+               [^false].<br>
+<br>
+       objectRepresentation genNewArrayOfSize: 1 initialized: false.<br>
+       self evaluate: pushValueDesc at: bytecodePC + pushArrayDesc numBytes + storeArrayDesc numBytes.<br>
+       reg := self ssStorePop: true toPreferredReg: TempReg.<br>
+       objectRepresentation<br>
+               genStoreSourceReg: reg<br>
+               slotIndex: 0<br>
+               intoNewObjectInDestReg: ReceiverResultReg.<br>
+       self ssPushRegister: ReceiverResultReg.<br>
+       self evaluate: storeArrayDesc at: bytecodePC + pushArrayDesc numBytes.<br>
+       bytecodePC := bytecodePC<br>
+                                       &quot;+ pushArrayDesc numBytes this gets added by nextBytecodePCFor:at:exts:in:&quot;<br>
+                                       + storeArrayDesc numBytes<br>
+                                       + pushValueDesc numBytes<br>
+                                       + storeValueDesc numBytes.<br>
+       ^true!<br>
<br>
</blockquote></div><br></div>