<div dir="ltr">Hi Ryan, Tim,<div><br></div><div>    in finishing the CPIC change use the following scripts to create a closed PIC for each platform.</div><div><br></div><div>StackToRegisterMappingCogit genAndDisPICoptions: #(ISA IA32 CogCompilerClass CogIA32Compiler ObjectMemory NewCoObjectMemory).<br></div><div><div>StackToRegisterMappingCogit genAndDisPICoptions: #(ISA IA32 CogCompilerClass CogIA32Compiler ObjectMemory Spur32BitCoMemoryManager).</div><div>StackToRegisterMappingCogit genAndDisPICoptions: #(ISA ARMv5 CogCompilerClass CogOutOfLineLiteralsARMCompiler ObjectMemory Spur32BitCoMemoryManager).</div><div>StackToRegisterMappingCogit genAndDisPICoptions: #(ISA ARMv5 CogCompilerClass CogInLineLiteralsARMCompiler ObjectMemory Spur32BitCoMemoryManager).</div><div>StackToRegisterMappingCogit genAndDisPICoptions: #(ISA MIPSEL CogCompilerClass CogMIPSELCompiler ObjectMemory Spur32BitCoMemoryManager).<br></div><div>StackToRegisterMappingCogit genAndDisPICoptions: #(ISA X64 CogCompilerClass CogInLineLiteralsX64Compiler ObjectMemory Spur64BitCoMemoryManager).</div><div>StackToRegisterMappingCogit genAndDisPICoptions: #(ISA X64 CogCompilerClass CogOutOfLineLiteralsX64Compiler ObjectMemory Spur64BitCoMemoryManager).</div></div><div><br></div><div><br></div><div>Only the first four (both x86 and both ARMv5) work.  Don&#39;t worry about x64; I&#39;m fixing that.</div><div><br></div><div>I hope to fix expectedClosedPICPrototype to include asserts to test rewriteCPIC:caseJumpTo: et al, but have dad duties so may not get to this until Monday/Tuesday.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Nov 22, 2015 at 9:33 AM,  <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: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.1528.mcz" rel="noreferrer" target="_blank">http://source.squeak.org/VMMaker/VMMaker.oscog-eem.1528.mcz</a><br>
<br>
==================== Summary ====================<br>
<br>
Name: VMMaker.oscog-eem.1528<br>
Author: eem<br>
Time: 22 November 2015, 9:33:01.294 am<br>
UUID: 3ed0e2f1-7f11-4ab0-be68-96373bf4612f<br>
Ancestors: VMMaker.oscog-eem.1527<br>
<br>
Reorder CPIC instructions to suit MIPSEL, i.e. put the load before the compare and jump.  Simplify and eliminate duplication, especially in thge literals managers, nuking almost all of their PIC support code.  It isn&#39;t needed since the code ends up being the same in each manager.<br>
<br>
There is still work to do:<br>
- the rewriteCPICFoo methods should all be implemented in Cogit and should use the same accessors as expectedClosedPICPrototype demonstrates.<br>
- those methods should be tested via extra asserts in expectedClosedPICPrototype<br>
<br>
Extend MIPS&#39; noteFollowingConditionalBranch: to include long conditional jumps.<br>
<br>
=============== Diff against VMMaker.oscog-eem.1527 ===============<br>
<br>
Item was added:<br>
+ ----- Method: CogARMCompiler&gt;&gt;instructionIsCMP: (in category &#39;testing&#39;) -----<br>
+ instructionIsCMP: instr<br>
+       &quot;is this an CMP instruction?&quot;<br>
+       ^(instr &gt;&gt; 21 bitAnd: 16r7F) = CmpOpcode!<br>
<br>
Item was added:<br>
+ ----- Method: CogARMCompiler&gt;&gt;instructionIsLDR: (in category &#39;testing&#39;) -----<br>
+ instructionIsLDR: instr<br>
+       &quot;is this any kind of LDR instruction? c.f. memMxr:reg:base:u:b:l:imm:&quot;<br>
+       ^instr &gt;&gt; 28 ~= 16rF &quot;the NEVER condition is used to encode non-load instructions&quot;<br>
+         and: [(instr &gt;&gt; 20 bitAnd: 16rC5) = 16r41] &quot;ldr r1, [r2, #+/-imm] or ldr r1, [r2, r3]&quot;!<br>
<br>
Item was changed:<br>
  ----- Method: CogARMCompiler&gt;&gt;instructionIsOR: (in category &#39;testing&#39;) -----<br>
  instructionIsOR: instr<br>
        &quot;is this an ORR instruction?&quot;<br>
+       ^(instr &gt;&gt; 21 bitAnd: 16r7F) = (16r10 bitOr: OrOpcode)!<br>
-       ^(instr &gt;&gt; 21 bitAnd: 16rF) = 16rC!<br>
<br>
Item was removed:<br>
- ----- Method: CogARMCompiler&gt;&gt;literalBeforeFollowingAddress: (in category &#39;inline cacheing&#39;) -----<br>
- literalBeforeFollowingAddress: followingAddress<br>
-       &quot;Answer the constant loaded by the instruction sequence just before this address:&quot;<br>
-       ^self subclassResponsibility!<br>
<br>
Item was added:<br>
+ ----- Method: CogAbstractInstruction&gt;&gt;cmpC32RTempByteSize (in category &#39;accessing&#39;) -----<br>
+ cmpC32RTempByteSize<br>
+       self subclassResponsibility!<br>
<br>
Item was added:<br>
+ ----- Method: CogAbstractInstruction&gt;&gt;literal32BeforeFollowingAddress: (in category &#39;inline cacheing&#39;) -----<br>
+ literal32BeforeFollowingAddress: followingAddress<br>
+       &quot;Answer the constant loaded by the instruction sequence just before this address:&quot;<br>
+       &lt;inline: true&gt;<br>
+       ^objectMemory wordSize = 8<br>
+               ifTrue: [self subclassResponsibility]<br>
+               ifFalse: [self literalBeforeFollowingAddress: followingAddress]!<br>
<br>
Item was added:<br>
+ ----- Method: CogAbstractInstruction&gt;&gt;literalBeforeFollowingAddress: (in category &#39;inline cacheing&#39;) -----<br>
+ literalBeforeFollowingAddress: followingAddress<br>
+       &quot;Answer the constant loaded by the instruction sequence just before this address:&quot;<br>
+       ^self subclassResponsibility!<br>
<br>
Item was changed:<br>
  ----- Method: CogAbstractInstruction&gt;&gt;rewriteCPICCaseAt:tag:objRef:target: (in category &#39;inline cacheing&#39;) -----<br>
  rewriteCPICCaseAt: followingAddress tag: newTag objRef: newObjRef target: newTarget<br>
+       &quot;Rewrite the three values involved in a CPIC case. Used by the initialize &amp; extend CPICs.&quot;<br>
-       &quot;rewrite the three values involved in a CPIC case. Used by the create &amp; extend cpcic methods&quot;<br>
        self subclassResponsibility<br>
        !<br>
<br>
Item was added:<br>
+ ----- Method: CogIA32Compiler&gt;&gt;cmpC32RTempByteSize (in category &#39;accessing&#39;) -----<br>
+ cmpC32RTempByteSize<br>
+       ^5!<br>
<br>
Item was changed:<br>
  ----- Method: CogIA32Compiler&gt;&gt;rewriteCPICCaseAt:tag:objRef:target: (in category &#39;inline cacheing&#39;) -----<br>
  rewriteCPICCaseAt: followingAddress tag: newTag objRef: newObjRef target: newTarget<br>
+       &quot;Rewrite the three values involved in a CPIC case. Used by the initialize &amp; extend CPICs.&quot;<br>
-       &quot;rewrite the three values involved in a CPIC case. Used by the create &amp; extend cpcic methods&quot;<br>
<br>
        &quot;IA32 CPIC cases are<br>
+        cmpl $0x newTag, %eax<br>
+        movl $0x newObjRef, %ebx<br>
+        jz .+0x newTarget (0x00010924)&quot;<br>
+<br>
-       cmpl $0x newTag, %eax<br>
-       movl $0x newObjRef, %ebx<br>
-       jz .+0x newTarget (0x00010924)<br>
- &quot;<br>
        &quot;rewite the tag via the first ldr&quot;<br>
        self storeLiteral: newTag beforeFollowingAddress: (followingAddress -11).<br>
<br>
        &quot;write the obj ref/operand via the second ldr&quot;<br>
        self storeLiteral: newObjRef beforeFollowingAddress: (followingAddress - 6).<br>
<br>
        &quot;write the jump address for the new target address&quot;<br>
        self rewriteJumpLongAt: followingAddress target: newTarget!<br>
<br>
Item was added:<br>
+ ----- Method: CogInLineLiteralsARMCompiler&gt;&gt;cmpC32RTempByteSize (in category &#39;accessing&#39;) -----<br>
+ cmpC32RTempByteSize<br>
+       ^20!<br>
<br>
Item was added:<br>
+ ----- Method: CogInLineLiteralsARMCompiler&gt;&gt;literal32BeforeFollowingAddress: (in category &#39;inline cacheing&#39;) -----<br>
+ literal32BeforeFollowingAddress: followingAddress<br>
+       &quot;Answer the 32-bit constant loaded by a MOV/ORR/ORR/ORR<br>
+        or MOV/ORR/ORR/ORR/PUSH, or MOV/ORR/ORR/ORR/CMP sequence, just before this address:&quot;<br>
+       ^(self instructionIsOR: (self instructionBeforeAddress: followingAddress))<br>
+               ifTrue: [self extract32BitOperandFrom4InstructionsPreceding: followingAddress]<br>
+               ifFalse: [self extract32BitOperandFrom4InstructionsPreceding: followingAddress - 4]!<br>
<br>
Item was added:<br>
+ ----- Method: CogInLineLiteralsX64Compiler&gt;&gt;literal32BeforeFollowingAddress: (in category &#39;inline cacheing&#39;) -----<br>
+ literal32BeforeFollowingAddress: followingAddress<br>
+       &quot;Answer the 32-bit literal embedded in the instruction immediately preceding followingAddress.&quot;<br>
+       ^  ((objectMemory byteAt: followingAddress - 1) &lt;&lt; 24)<br>
+       +  ((objectMemory byteAt: followingAddress - 2) &lt;&lt; 16)<br>
+       +  ((objectMemory byteAt: followingAddress - 3) &lt;&lt; 8)<br>
+       +   (objectMemory byteAt: followingAddress - 4)!<br>
<br>
Item was added:<br>
+ ----- Method: CogMIPSELCompiler&gt;&gt;cmpC32RTempByteSize (in category &#39;accessing&#39;) -----<br>
+ cmpC32RTempByteSize<br>
+       self flag: #todo. &quot;value - reg or reg - value?&quot;<br>
+       self flag: #inefficient. &quot;Cog RTL assumes we can do any kind of conditional branch after a Cmp.&quot;<br>
+       ^28!<br>
<br>
Item was changed:<br>
  ----- Method: CogMIPSELCompiler&gt;&gt;noteFollowingConditionalBranch: (in category &#39;abstract instructions&#39;) -----<br>
  noteFollowingConditionalBranch: branch<br>
        &quot;Support for processors without condition codes, such as the MIPS.<br>
         Answer the branch opcode.  Modify the receiver and the branch to<br>
         implement a suitable conditional branch that doesn&#39;t depend on<br>
         condition codes being set by the receiver.&quot;<br>
        &lt;var: #branch type: #&#39;AbstractInstruction *&#39;&gt;<br>
        branch opcode caseOf: {<br>
                [JumpOverflow]          -&gt; [opcode := opcode caseOf: {<br>
                                                                                [AddCqR]        -&gt; [AddCheckOverflowCqR].<br>
                                                                                [AddRR]         -&gt; [AddCheckOverflowRR].<br>
                                                                                [MulRR]         -&gt; [MulCheckOverflowRR].<br>
                                                                                [SubCqR]        -&gt; [SubCheckOverflowCqR].<br>
                                                                                [SubRR]         -&gt; [SubCheckOverflowRR].<br>
                                                                                }].<br>
                [JumpNoOverflow]        -&gt; [opcode := opcode caseOf: {<br>
                                                                                [AddCqR]        -&gt; [AddCheckOverflowCqR].<br>
                                                                                [AddRR]         -&gt; [AddCheckOverflowRR].<br>
                                                                                [MulRR]         -&gt; [MulCheckOverflowRR].<br>
                                                                                [SubCqR]        -&gt; [SubCheckOverflowCqR].<br>
                                                                                [SubRR]         -&gt; [SubCheckOverflowRR].<br>
                                                                                }].<br>
                &quot;Ryan, I&#39;m imagining that all the other cases go in here, such as collapsing CmpRR; JumpZero to Label; BrEqRR.<br>
                 This is obviously not nearly complete.&quot;<br>
                [JumpZero]                      -&gt; [opcode caseOf: {<br>
                                                                        [CmpRR] -&gt; [branch setOpcode: BrEqRR andOperandsFrom: self.<br>
+                                                                                                       branch operands at: 3 put: (operands at: 1).<br>
                                                                                                        opcode := Label].<br>
                                                                }].<br>
                [JumpNonZero]           -&gt; [opcode caseOf: {<br>
                                                                        [CmpRR] -&gt; [branch setOpcode: BrNeRR andOperandsFrom: self.<br>
+                                                                                                       branch operands at: 3 put: (operands at: 1).<br>
                                                                                                        opcode := Label].<br>
                                                                }].<br>
+               [JumpLongZero]          -&gt; [opcode caseOf: {<br>
+                                                                       [CmpRR] -&gt; [branch setOpcode: BrNeRR andOperandsFrom: self.<br>
+                                                                                                       &quot;skip the following long branch&quot;<br>
+                                                                                                       branch operands at: 3 put: self jumpLongByteSize.<br>
+                                                                                                       opcode := JumpLong].<br>
+                                                               }].<br>
+               [JumpLongNonZero]       -&gt; [opcode caseOf: {<br>
+                                                                       [CmpRR] -&gt; [branch setOpcode: BrEqRR andOperandsFrom: self.<br>
+                                                                                                       &quot;skip the following long branch&quot;<br>
+                                                                                                       branch operands at: 3 put: self jumpLongByteSize.<br>
+                                                                                                       opcode := JumpLong].<br>
+                                                               }].<br>
                }<br>
                &quot;No otherwise for now to catch all cases&quot;<br>
                &quot;otherwise: []&quot;.<br>
        ^branch!<br>
<br>
Item was added:<br>
+ ----- Method: CogObjectRepresentationFor32BitSpur&gt;&gt;markAndTraceCacheTagLiteral:in:atpc: (in category &#39;garbage collection&#39;) -----<br>
+ markAndTraceCacheTagLiteral: literal in: cogMethodOrNil atpc: address<br>
+       &quot;Mark and trace a literal in an inline cache preceding address in cogMethodOrNil.<br>
+        Answer if code was modified.&quot;<br>
+       &lt;var: #cogMethodOrNil type: #&#39;CogMethod *&#39;&gt;<br>
+       &lt;var: #address type: #usqInt&gt;<br>
+       | objOop |<br>
+       (self couldBeObject: literal) ifFalse:<br>
+               [^false].<br>
+       self assert: (objectMemory addressCouldBeObj: literal).<br>
+       (objectMemory isForwarded: literal) ifFalse:<br>
+               [objectMemory markAndTrace: literal.<br>
+                ^false].<br>
+       objOop := objectMemory followForwarded: literal.<br>
+       cogit backEnd rewriteInlineCacheTag: objOop at: address.<br>
+       self markAndTraceUpdatedLiteral: objOop in: cogMethodOrNil.<br>
+       ^true!<br>
<br>
Item was added:<br>
+ ----- Method: CogObjectRepresentationFor64BitSpur&gt;&gt;markAndTraceCacheTagLiteral:in:atpc: (in category &#39;garbage collection&#39;) -----<br>
+ markAndTraceCacheTagLiteral: literal in: cogMethodOrNil atpc: address<br>
+       &quot;Mark and trace a literal in an inline cache preceding address in cogMethodOrNil.<br>
+        Answer if code was modified.  In 64-bit Spur, cache tags are either selector<br>
+        indices or class indices and so this is a noop.&quot;<br>
+       &lt;var: #cogMethodOrNil type: #&#39;CogMethod *&#39;&gt;<br>
+       &lt;var: #address type: #usqInt&gt;<br>
+       &lt;inline: true&gt;<br>
+       ^false!<br>
<br>
Item was removed:<br>
- ----- Method: CogObjectRepresentationForSpur&gt;&gt;markAndTraceCacheTagLiteral:in:atpc: (in category &#39;garbage collection&#39;) -----<br>
- markAndTraceCacheTagLiteral: literal in: cogMethodOrNil atpc: address<br>
-       &quot;Mark and trace a literal in an inline cache preceding address in cogMethodOrNil.<br>
-        Answer if code was modified.&quot;<br>
-       &lt;var: #cogMethodOrNil type: #&#39;CogMethod *&#39;&gt;<br>
-       &lt;var: #address type: #usqInt&gt;<br>
-       | objOop |<br>
-       (self couldBeObject: literal) ifFalse:<br>
-               [^false].<br>
-       self assert: (objectMemory addressCouldBeObj: literal).<br>
-       (objectMemory isForwarded: literal) ifFalse:<br>
-               [objectMemory markAndTrace: literal.<br>
-                ^false].<br>
-       objOop := objectMemory followForwarded: literal.<br>
-       cogit backEnd rewriteInlineCacheTag: objOop at: address.<br>
-       self markAndTraceUpdatedLiteral: objOop in: cogMethodOrNil.<br>
-       ^true!<br>
<br>
Item was removed:<br>
- ----- Method: CogObjectRepresentationForSqueakV3&gt;&gt;remapCacheTag: (in category &#39;garbage collection&#39;) -----<br>
- remapCacheTag: cacheTag<br>
-       ^(self couldBeObject: cacheTag)<br>
-               ifTrue: [objectMemory remap: cacheTag]<br>
-               ifFalse: [cacheTag]!<br>
<br>
Item was added:<br>
+ ----- Method: CogOutOfLineLiteralsARMCompiler&gt;&gt;cmpC32RTempByteSize (in category &#39;accessing&#39;) -----<br>
+ cmpC32RTempByteSize<br>
+       ^8!<br>
<br>
Item was changed:<br>
  ----- Method: CogOutOfLineLiteralsARMCompiler&gt;&gt;literalBeforeFollowingAddress: (in category &#39;inline cacheing&#39;) -----<br>
  literalBeforeFollowingAddress: followingAddress<br>
        &quot;Return the literal referenced by the instruction immediately preceding followingAddress.&quot;<br>
+       ^objectMemory longAt: (self pcRelativeAddressAt:<br>
+               ((self instructionIsLDR: (self instructionBeforeAddress: followingAddress))<br>
+                       ifTrue: [self instructionAddressBefore: followingAddress]<br>
+                       ifFalse: [self instructionAddressBefore: followingAddress - 4]))!<br>
-       ^objectMemory longAt: (self pcRelativeAddressAt: (self instructionAddressBefore: followingAddress))!<br>
<br>
Item was changed:<br>
  ----- Method: CogOutOfLineLiteralsARMCompiler&gt;&gt;storeLiteral:beforeFollowingAddress: (in category &#39;inline cacheing&#39;) -----<br>
  storeLiteral: literal beforeFollowingAddress: followingAddress<br>
        &quot;Rewrite the literal in the instruction immediately preceding followingAddress.&quot;<br>
+       objectMemory<br>
+               longAt: (self pcRelativeAddressAt:<br>
+                                       ((self instructionIsLDR: (self instructionBeforeAddress: followingAddress))<br>
+                                               ifTrue: [self instructionAddressBefore: followingAddress]<br>
+                                               ifFalse: [self instructionAddressBefore: followingAddress - 4]))<br>
+               put: literal!<br>
-       objectMemory longAt: (self pcRelativeAddressAt: (self instructionAddressBefore: followingAddress )) put: literal!<br>
<br>
Item was added:<br>
+ ----- Method: CogX64Compiler&gt;&gt;cmpC32RTempByteSize (in category &#39;accessing&#39;) -----<br>
+ cmpC32RTempByteSize<br>
+       ^6!<br>
<br>
Item was changed:<br>
  ----- Method: Cogit&gt;&gt;cPICHasForwardedClass: (in category &#39;in-line cacheing&#39;) -----<br>
  cPICHasForwardedClass: cPIC<br>
        &quot;The first case in a CPIC doesn&#39;t have a class reference so we need only step over actually usd subsequent cases.&quot;<br>
        | pc |<br>
        &lt;var: #cPIC type: #&#39;CogMethod *&#39;&gt;<br>
        &quot;start by finding the address of the topmost case, the cPICNumCases&#39;th one&quot;<br>
        pc := (self addressOfEndOfCase: cPIC cPICNumCases inCPIC: cPIC)<br>
                                - backEnd jumpLongConditionalByteSize.<br>
        2 to: cPIC cPICNumCases do:<br>
                        [:i |  | classIndex |<br>
+                       classIndex := literalsManager backEnd literal32BeforeFollowingAddress: pc.<br>
-                       classIndex := literalsManager classRefInClosedPICAt: pc.<br>
                        (objectMemory isForwardedClassIndex: classIndex)<br>
                                ifTrue: [^ true].<br>
                        &quot;since we started at the top, we can just add the case size each time to move on to the next case&quot;<br>
                        pc := pc + cPICCaseSize].<br>
        ^ false!<br>
<br>
Item was changed:<br>
  ----- Method: Cogit&gt;&gt;checkValidObjectReferencesInClosedPIC: (in category &#39;garbage collection&#39;) -----<br>
  checkValidObjectReferencesInClosedPIC: cPIC<br>
        &lt;var: #cPIC type: #&#39;CogMethod *&#39;&gt;<br>
        | ok pc |<br>
        ok := true.<br>
        pc := cPIC asInteger + firstCPICCaseOffset.<br>
<br>
        &quot;first we check the obj ref at the beginning of the CPIC&quot;<br>
+       (self checkMaybeObjRefInClosedPIC: (backEnd literalBeforeFollowingAddress: pc - backEnd jumpLongByteSize)) ifFalse:<br>
-       (self checkMaybeObjRefInClosedPIC: (literalsManager objRefInClosedPICAt: pc - backEnd jumpLongByteSize)) ifFalse:<br>
                [self print: &#39;object leak in CPIC &#39;; printHex: cPIC asInteger;<br>
                        print: &#39; @ &#39;; printHex: pc - backEnd jumpLongByteSize; cr.<br>
                 ok := false].<br>
<br>
        &quot;Next we step over each case that is in use. We find the end address of the cPICNumCases&#39;th case and can then just step forward by the case size thereafter&quot;<br>
        pc := self addressOfEndOfCase: cPIC cPICNumCases inCPIC: cPIC.<br>
<br>
        &quot;For each case we check any object reference at the end address - sizeof(conditional instruction) and then increment the end address by case size&quot;<br>
        2 to: cPIC cPICNumCases do:<br>
                [:i|<br>
                objectRepresentation inlineCacheTagsMayBeObjects ifTrue:<br>
+                       [(self checkMaybeObjRefInClosedPIC: (literalsManager backEnd literal32BeforeFollowingAddress: pc - backEnd jumpLongConditionalByteSize)) ifFalse:<br>
-                       [(self checkMaybeObjRefInClosedPIC: (literalsManager classRefInClosedPICAt: pc - backEnd jumpLongConditionalByteSize)) ifFalse:<br>
                                [self print: &#39;object leak in CPIC &#39;; printHex: cPIC asInteger;<br>
                                        print: &#39; @ &#39;; printHex: pc - backEnd jumpLongConditionalByteSize - backEnd loadLiteralByteSize; cr.<br>
                                 ok := false]].<br>
+               (self checkMaybeObjRefInClosedPIC: (backEnd literalBeforeFollowingAddress: pc - backEnd jumpLongConditionalByteSize - backEnd cmpC32RTempByteSize)) ifFalse:<br>
-               (self checkMaybeObjRefInClosedPIC: (literalsManager objRefInClosedPICAt: pc - backEnd jumpLongConditionalByteSize)) ifFalse:<br>
                        [self print: &#39;object leak in CPIC &#39;; printHex: cPIC asInteger;<br>
                                print: &#39; @ &#39;; printHex: pc - backEnd jumpLongConditionalByteSize; cr.<br>
                         ok := false].<br>
                pc := pc + cPICCaseSize].<br>
        ^ok!<br>
<br>
Item was changed:<br>
  ----- Method: Cogit&gt;&gt;closedPICRefersToUnmarkedObject: (in category &#39;garbage collection&#39;) -----<br>
  closedPICRefersToUnmarkedObject: cPIC<br>
        &quot;Answer if the ClosedPIC refers to any unmarked objects or freed/freeable target methods,<br>
         applying markAndTraceOrFreeCogMethod:firstVisit: to those targets to determine if freed/freeable.&quot;<br>
        &lt;var: #cPIC type: #&#39;CogMethod *&#39;&gt;<br>
+       | pc object |<br>
+       ((objectMemory isImmediate: cPIC selector)<br>
+       or: [objectMemory isMarked: cPIC selector]) ifFalse:<br>
+               [^true].<br>
+<br>
-       | pc offsetToLiteral object entryPoint targetMethod |<br>
-       &lt;var: #targetMethod type: #&#39;CogMethod *&#39;&gt;<br>
-       (objectMemory isImmediate: cPIC selector) ifFalse:<br>
-               [(objectMemory isMarked: cPIC selector) ifFalse:<br>
-                       [^true]].<br>
        &quot;First jump is unconditional; subsequent ones are conditional.&quot;<br>
+       &quot;Check the potential method oop for the first case only.<br>
+        Inline cache tags for the 1st case are at the send site.&quot;<br>
+       pc := self addressOfEndOfCase: 1 inCPIC: cPIC.<br>
+       (objectRepresentation couldBeObject: (object := backEnd literalBeforeFollowingAddress: pc - backEnd jumpLongByteSize)) ifTrue:<br>
+               [(objectMemory isMarked: object) ifFalse:<br>
+                       [^true]].<br>
+<br>
+       &quot;Check the first target&quot;<br>
+       (self markAndTraceOrFreePICTarget: (backEnd jumpLongTargetBeforeFollowingAddress: pc) in: cPIC) ifTrue:<br>
+               [^true].<br>
+<br>
+       2 to: cPIC cPICNumCases do:<br>
-       offsetToLiteral := backEnd jumpLongByteSize.<br>
-       1 to: cPIC cPICNumCases do:<br>
                [:i|<br>
                pc := self addressOfEndOfCase: i inCPIC: cPIC.<br>
+               (objectRepresentation inlineCacheTagsMayBeObjects<br>
+               and: [objectRepresentation couldBeObject: (object := literalsManager backEnd literal32BeforeFollowingAddress: pc - backEnd jumpLongConditionalByteSize)]) ifTrue:<br>
+                       [(objectMemory isMarked: object) ifFalse:<br>
-               (objectRepresentation inlineCacheTagsMayBeObjects and: [i&gt;1] ) &quot;inline cache tags for the 0th case are at the send site&quot; ifTrue:<br>
-                       [object := literalsManager classRefInClosedPICAt: pc - offsetToLiteral.<br>
-                        ((objectRepresentation couldBeObject: object)<br>
-                         and: [(objectMemory isMarked: object) not]) ifTrue:<br>
                                [^true]].<br>
+               &quot;Check the potential method oop for subsequent cases.&quot;<br>
+               (objectRepresentation couldBeObject: (object := backEnd literalBeforeFollowingAddress: pc - backEnd jumpLongConditionalByteSize - backEnd cmpC32RTempByteSize)) ifTrue:<br>
+                       [(objectMemory isMarked: object) ifFalse:<br>
+                               [^true]].<br>
+               &quot;Check subsequent targets&quot;<br>
+               (self markAndTraceOrFreePICTarget: (backEnd jumpLongConditionalTargetBeforeFollowingAddress: pc) in: cPIC) ifTrue:<br>
+                       [^true]].<br>
+<br>
-               object := literalsManager objRefInClosedPICAt: pc - offsetToLiteral.<br>
-               ((objectRepresentation couldBeObject: object)<br>
-                and: [(objectMemory isMarked: object) not]) ifTrue:<br>
-                       [^true].<br>
-               offsetToLiteral := backEnd jumpLongConditionalByteSize.<br>
-               entryPoint := i = 1<br>
-                                               ifTrue: [backEnd jumpLongTargetBeforeFollowingAddress: pc]<br>
-                                               ifFalse: [backEnd jumpLongConditionalTargetBeforeFollowingAddress: pc].<br>
-               &quot;Find target from jump.  Ignore jumps to the interpret and MNU calls within this PIC&quot;<br>
-               self assert: (entryPoint &gt; methodZoneBase and: [entryPoint &lt; methodZone freeStart]).<br>
-               (cPIC containsAddress: entryPoint) ifFalse:<br>
-                       [targetMethod := self cCoerceSimple: entryPoint - cmNoCheckEntryOffset to: #&#39;CogMethod *&#39;.<br>
-                        self assert: (targetMethod cmType = CMMethod<br>
-                                               or: [targetMethod cmType = CMFree]).<br>
-                        (self markAndTraceOrFreeCogMethod: targetMethod<br>
-                                 firstVisit: targetMethod asUnsignedInteger &gt; pc asUnsignedInteger) ifTrue:<br>
-                               [^true]]].<br>
        ^false!<br>
<br>
Item was changed:<br>
  ----- Method: Cogit&gt;&gt;compileClosedPICPrototype (in category &#39;in-line cacheing&#39;) -----<br>
  compileClosedPICPrototype<br>
        &quot;Compile the abstract instructions for a full closed PIC, used to generate the chunk of code<br>
         which is copied to form each closed PIC.  A Closed Polymorphic Inline Cache is a small jump<br>
         table used to optimize sends with a limited degree of polymorphism (currently up to 6 cases).<br>
         We call it closed because it deals only with a finite number of cases, as opposed to an Open PIC.<br>
         When a monomorphic linked send (a send with a single case, linking direct to the checked entry<br>
         point of a CogMethod) fails a class check, the Cogit attempts to create a two-entry PIC that will<br>
         handle jumping to the original target for the original class and the relevant target for the new<br>
         class.  This jump table will be extended on subsequent failures up to a limit (6).<br>
<br>
         We avoid extending CPICs to Open PICs by linking the send site to an Open PIC if one already<br>
         exists with the send&#39;s selector, a good policy since measurements show that sends of mega-<br>
         morphic selectors usually become megamorphic at all send sites.  Hence the Open PIC list.<br>
<br>
         A CPIC also optimizes MNUs and interpret-only methods.  Each case can load SendNumArgs with<br>
         the oop of a method, or will load SendNumArgs with 0 if not.  MNUs are optimized by jumping to<br>
         the mnuAbort in the CPIC, which calls code that creates the Message, thereby avoiding looking up<br>
         the original message which will not be found, and either looks up doesNotUnderstand: or directly<br>
         activates the method loaded into SendNumArgs, hence avoiding looking up doesNotUnderstand:.<br>
         Interpret-only methods are handled by jumping to the picInterpretAbort, which enters the<br>
         interpreter activating the method loaded in SendNumArgs.<br>
<br>
         CPICs look like the following, where rClass is set at the original send site for the 1st case, and #Foo<br>
         is some constant, either an oop, a class tag or an instruction address.<br>
<br>
                rTemp := (rRecever bitAnd: TagMask) = 0 ifTrue: [rReceiver class] ifFalse: [rRecever bitAnd: TagMask].<br>
                rTemp = rClass ifFalse:<br>
                        [self goto: #Label].<br>
                rSendNumArgs := #MethodForCase1Or0.<br>
                self goto: #TargetForCase1.<br>
         #Label<br>
                rTemp = #ClassTagForCase6 ifTrue:<br>
                        [rSendNumArgs := #MethodForCase6Or0.<br>
                         self goto: #TargetForCase6].<br>
                ...cases 5, 4 &amp; 3<br>
                rTemp = #ClassTagForCase2 ifTrue:<br>
                        [rSendNumArgs := #MethodForCase2Or0.<br>
                         self goto: #TargetForCase2].<br>
                self goto: #CPICMissTrampoline<br>
                literals (if out-of-line literals)<br>
<br>
         where we short-cut as many cases as needed by making the self goto: #Label skip as many cases<br>
         as needed.&quot;<br>
        &lt;inline: true&gt;<br>
        | numArgs jumpNext |<br>
        &lt;var: #jumpNext type: #&#39;AbstractInstruction *&#39;&gt;<br>
        self compilePICAbort: (numArgs := 0). &quot;Will get rewritten to appropriate arity when configuring.&quot;<br>
        jumpNext := self compileCPICEntry.<br>
        &quot;At the end of the entry code we need to jump to the first case code, which is actually the last chunk.<br>
         On each entension we must update this jump to move back one case.&quot;<br>
        &quot;16r5EAF00D is the method oop, or 0, for the 1st case.&quot;<br>
        self MoveUniqueCw: 16r5EAF00D R: SendNumArgsReg.<br>
        self JumpLong: self cPICPrototypeCaseOffset + 16rCA5E10.<br>
        endCPICCase0 := self Label.<br>
        1 to: maxCPICCases - 1 do:<br>
                [:h|<br>
                h = (maxCPICCases - 1) ifTrue:<br>
                        [jumpNext jmpTarget: self Label]. &quot;this is where we jump to for the first case&quot;<br>
-               &quot;16rBABE1F15+h is the class tag for the Nth case&quot;<br>
-               self CmpC32: 16rBABE1F15+h R: TempReg.<br>
                &quot;16rBADA550+h is the method oop, or 0, for the Nth case.&quot;<br>
                self MoveUniqueCw: 16rBADA550 + h R: SendNumArgsReg.<br>
+               &quot;16rBABE1F15+h is the class tag for the Nth case&quot;<br>
+               self CmpC32: 16rBABE1F15+h R: TempReg.<br>
                self JumpLongZero: self cPICPrototypeCaseOffset + 16rCA5E10 + (h * 16).<br>
                h = 1 ifTrue:<br>
                        [endCPICCase1 := self Label]].<br>
        self MoveCw: methodLabel address R: ClassReg.<br>
        self JumpLong: (self cPICMissTrampolineFor: numArgs).   &quot;Will get rewritten to appropriate arity when configuring.&quot;<br>
        cPICEndOfCodeLabel := self Label.<br>
        literalsManager dumpLiterals: false.<br>
        ^0!<br>
<br>
Item was changed:<br>
  ----- Method: Cogit&gt;&gt;expectedClosedPICPrototype: (in category &#39;in-line cacheing&#39;) -----<br>
  expectedClosedPICPrototype: cPIC<br>
        &quot;Answer 0 if the ClosedPIC is as expected from compileClosedPICPrototype,<br>
         otherwise answer an error code identifying the first discrepancy found.&quot;<br>
        &quot;self disassembleFrom: methodZoneBase + (self sizeof: CogMethod) to: methodZoneBase + closedPICSize&quot;<br>
        &lt;var: #cPIC type: #&#39;CogMethod *&#39;&gt;<br>
+       | pc object entryPoint |<br>
+       pc := cPIC asUnsignedInteger + firstCPICCaseOffset.<br>
-       | pc offsetToLiteral object entryPoint |<br>
-       pc := cPIC asInteger + firstCPICCaseOffset.<br>
        &quot;First jump is unconditional; subsequent ones are conditional&quot;<br>
+       object := backEnd literalBeforeFollowingAddress: pc - backEnd jumpLongByteSize.<br>
+       self assert: object = 16r5EAF00D.<br>
-       offsetToLiteral := backEnd jumpLongByteSize.<br>
-<br>
-       object := literalsManager objRefInClosedPICAt: pc - offsetToLiteral.<br>
-       self assert: (object = 16r5EAF00D).<br>
<br>
        entryPoint := backEnd jumpLongTargetBeforeFollowingAddress: pc.<br>
+       self assert: entryPoint = (self cPICPrototypeCaseOffset + 16rCA5E10).<br>
-       self assert: (entryPoint = (self cPICPrototypeCaseOffset + 16rCA5E10)).<br>
<br>
        1 to: maxCPICCases - 1 do:<br>
+               [:i | | methodObjPC classTagPC |<br>
-               [:i |<br>
                pc := pc + cPICCaseSize.<br>
-               offsetToLiteral := backEnd jumpLongConditionalByteSize.<br>
<br>
+               methodObjPC := pc - backEnd jumpLongConditionalByteSize - backEnd cmpC32RTempByteSize.<br>
+               object := backEnd literalBeforeFollowingAddress: methodObjPC.<br>
-               object := literalsManager classRefInClosedPICAt: pc - offsetToLiteral.<br>
-               self assert: object = (16rBABE1F15 + i).<br>
-               literalsManager storeClassRef: (object bitXor: 16r5A5A5A5A) inClosedPICAt: pc - offsetToLiteral.<br>
-               object := literalsManager classRefInClosedPICAt: pc - offsetToLiteral.<br>
-               self assert: object = ((16rBABE1F15 + i bitXor: 16r5A5A5A5A)).<br>
-               literalsManager storeClassRef: (object bitXor: 16r5A5A5A5A) inClosedPICAt: pc - offsetToLiteral.<br>
-<br>
-               object := literalsManager objRefInClosedPICAt: pc - offsetToLiteral.<br>
                self assert: object = (16rBADA550 + i).<br>
+               backEnd storeLiteral: (object bitXor: 16rA5A5A5A5) beforeFollowingAddress: methodObjPC.<br>
+               object := backEnd literalBeforeFollowingAddress: methodObjPC.<br>
+               self assert: object = (16rBADA550 + i bitXor: 16rA5A5A5A5).<br>
+               backEnd storeLiteral: (object bitXor: 16rA5A5A5A5) beforeFollowingAddress: methodObjPC.<br>
-               literalsManager storeObjRef: (object bitXor: 16rA5A5A5A5) inClosedPICAt: pc - offsetToLiteral.<br>
-               object := literalsManager objRefInClosedPICAt: pc - offsetToLiteral.<br>
-               self assert: object = ((16rBADA550 + i) bitXor: 16rA5A5A5A5).<br>
-               literalsManager storeObjRef: (object bitXor: 16rA5A5A5A5) inClosedPICAt: pc - offsetToLiteral.<br>
<br>
+               classTagPC := pc - backEnd jumpLongConditionalByteSize.<br>
+               object := backEnd literal32BeforeFollowingAddress: classTagPC.<br>
+               self assert: object = (16rBABE1F15 + i).<br>
+               backEnd storeLiteral: (object bitXor: 16r5A5A5A5A) beforeFollowingAddress: classTagPC.<br>
+               object := backEnd literal32BeforeFollowingAddress: classTagPC.<br>
+               self assert: object = (16rBABE1F15 + i bitXor: 16r5A5A5A5A).<br>
+               backEnd storeLiteral: (object bitXor: 16r5A5A5A5A) beforeFollowingAddress: classTagPC.<br>
+<br>
                entryPoint := backEnd jumpLongConditionalTargetBeforeFollowingAddress: pc.<br>
                self assert: entryPoint = (self cPICPrototypeCaseOffset + 16rCA5E10 + (i * 16))].<br>
<br>
        entryPoint := backEnd jumpLongTargetBeforeFollowingAddress: pc + cPICEndSize - literalsManager endSizeOffset.<br>
+       self assert: entryPoint = (self cPICMissTrampolineFor: 0).<br>
-       self assert: (entryPoint = (self cPICMissTrampolineFor: 0)).<br>
<br>
        ^0!<br>
<br>
Item was changed:<br>
  ----- Method: Cogit&gt;&gt;followMaybeObjRefInClosedPICAt: (in category &#39;garbage collection&#39;) -----<br>
  followMaybeObjRefInClosedPICAt: mcpc<br>
        &quot;Follow a potential object reference from a closed PIC.<br>
         This may be a method reference or null.<br>
         Answer if the followed literal is young.<br>
        &#39;mcpc&#39; refers to the jump/branch instruction at the end of<br>
        each cpic case&quot;<br>
        | object subject |<br>
+       object := backEnd literalBeforeFollowingAddress: mcpc.<br>
-       object := literalsManager objRefInClosedPICAt: mcpc.<br>
        (objectRepresentation couldBeObject: object) ifFalse:<br>
                [^false].<br>
        (objectMemory isForwarded: object) ifFalse:<br>
                [^objectMemory isYoungObject: object].<br>
        subject := objectMemory followForwarded: object.<br>
+       backEnd storeLiteral: subject beforeFollowingAddress: mcpc.<br>
-       literalsManager storeObjRef: subject inClosedPICAt: mcpc.<br>
        codeModified := true.<br>
        ^objectMemory isYoungObject: subject!<br>
<br>
Item was changed:<br>
  ----- Method: Cogit&gt;&gt;followMethodReferencesInClosedPIC: (in category &#39;garbage collection&#39;) -----<br>
  followMethodReferencesInClosedPIC: cPIC<br>
        &quot;Remap all object references in the closed PIC.  Answer if any references are young.<br>
        Set codeModified if any modifications are made.&quot;<br>
        &lt;var: #cPIC type: #&#39;CogMethod *&#39;&gt;<br>
        | pc refersToYoung |<br>
        pc := self addressOfEndOfCase: 1 inCPIC: cPIC.<br>
<br>
+       &quot;first we check the potential method oop load at the beginning of the CPIC&quot;<br>
-       &quot;first we check the method obj ref at the beginning of the CPIC&quot;<br>
        refersToYoung := self followMaybeObjRefInClosedPICAt: pc - backEnd jumpLongByteSize.<br>
<br>
        &quot;We find the end address of the cPICNumCases&#39;th case and can then just step forward by the case size thereafter&quot;<br>
        pc := self addressOfEndOfCase:  cPIC cPICNumCases inCPIC: cPIC.<br>
<br>
+       &quot;Next we check the potential potential method oop load for each case.&quot;<br>
-       &quot;For each case we check any object reference at the end address - sizeof(conditional instruction) and then increment the end address by case size&quot;<br>
        2 to: cPIC cPICNumCases do:<br>
                [:i|<br>
+               (self followMaybeObjRefInClosedPICAt: pc - backEnd jumpLongConditionalByteSize - backEnd cmpC32RTempByteSize) ifTrue:<br>
-               (self followMaybeObjRefInClosedPICAt: pc - backEnd jumpLongConditionalByteSize) ifTrue:<br>
                        [refersToYoung := true].<br>
                pc := pc + cPICCaseSize].<br>
        ^refersToYoung!<br>
<br>
Item was changed:<br>
  ----- Method: Cogit&gt;&gt;mapObjectReferencesInClosedPIC: (in category &#39;garbage collection&#39;) -----<br>
  mapObjectReferencesInClosedPIC: cPIC<br>
        &quot;Remap all object references in the closed PIC.  Answer if any references are young.<br>
        Set codeModified if any modifications are made.&quot;<br>
        &lt;var: #cPIC type: #&#39;CogMethod *&#39;&gt;<br>
        | pc refersToYoung |<br>
        pc := self addressOfEndOfCase:1 inCPIC:cPIC.<br>
<br>
+       &quot;first we check the potential method oop load at the beginning of the CPIC&quot;<br>
+       refersToYoung := self remapMaybeObjRefInClosedPICAt: pc - backEnd jumpLongByteSize.<br>
-       &quot;first we check the obj ref at the beginning of the CPIC&quot;<br>
-       refersToYoung := self updateMaybeObjRefInClosedPICAt: pc - backEnd jumpLongByteSize.<br>
<br>
        &quot;We find the end address of the cPICNumCases&#39;th case and can then just step forward by the case size thereafter&quot;<br>
        pc := self addressOfEndOfCase: cPIC cPICNumCases inCPIC: cPIC.<br>
<br>
+       &quot;Next we check the potential class ref in the compare instruction, and the potential method oop load for each case.&quot;<br>
-       &quot;For each case we check any object reference at the end address - sizeof(conditional instruction) and then increment the end address by case size&quot;<br>
        2 to: cPIC cPICNumCases do:<br>
                [:i|<br>
                objectRepresentation inlineCacheTagsMayBeObjects ifTrue:<br>
+                       [(self remapMaybeObjRefInClosedPICAt: pc - backEnd jumpLongConditionalByteSize) ifTrue:<br>
-                       [(self updateMaybeClassRefInClosedPICAt: pc - backEnd jumpLongConditionalByteSize) ifTrue:<br>
                                [refersToYoung := true]].<br>
+               (self remapMaybeObjRefInClosedPICAt: pc - backEnd jumpLongConditionalByteSize - backEnd cmpC32RTempByteSize) ifTrue:<br>
-               (self updateMaybeObjRefInClosedPICAt: pc - backEnd jumpLongConditionalByteSize) ifTrue:<br>
                        [refersToYoung := true].<br>
                pc := pc + cPICCaseSize].<br>
        ^refersToYoung!<br>
<br>
Item was added:<br>
+ ----- Method: Cogit&gt;&gt;markAndTraceOrFreePICTarget:in: (in category &#39;garbage collection&#39;) -----<br>
+ markAndTraceOrFreePICTarget: entryPoint in: cPIC<br>
+       &quot;If entryPoint is that of some method, then mark and trace objects in it and free if it is appropriate.<br>
+        Answer if the method has been freed.&quot;<br>
+       &lt;var: #cPIC type: #&#39;CogMethod *&#39;&gt;<br>
+       | targetMethod |<br>
+       &lt;var: #targetMethod type: #&#39;CogMethod *&#39;&gt;<br>
+       self assert: (entryPoint &gt; methodZoneBase and: [entryPoint &lt; methodZone freeStart]).<br>
+       (cPIC containsAddress: entryPoint) ifTrue:<br>
+               [^false].<br>
+       targetMethod := self cCoerceSimple: entryPoint - cmNoCheckEntryOffset to: #&#39;CogMethod *&#39;.<br>
+       self assert: (targetMethod cmType = CMMethod or: [targetMethod cmType = CMFree]).<br>
+       ^self markAndTraceOrFreeCogMethod: targetMethod<br>
+                 firstVisit: targetMethod asUnsignedInteger &gt; cPIC asUnsignedInteger!<br>
<br>
Item was added:<br>
+ ----- Method: Cogit&gt;&gt;remapMaybeObjRefInClosedPICAt: (in category &#39;garbage collection&#39;) -----<br>
+ remapMaybeObjRefInClosedPICAt: mcpc<br>
+       &quot;Remap a potential object reference from a closed PIC.<br>
+        This may be an object reference, an inline cache tag or null.<br>
+        Answer if the updated literal is young.<br>
+        mcpc is the address of the next instruction following either<br>
+        the load of the method literal or the compare of the class tag.&quot;<br>
+       | object subject |<br>
+       object := backEnd literalBeforeFollowingAddress: mcpc.<br>
+       (objectRepresentation couldBeObject: object) ifFalse:<br>
+               [^false].<br>
+       subject := objectRepresentation remapOop: object.<br>
+       object ~= subject ifTrue:<br>
+               [backEnd storeLiteral: subject beforeFollowingAddress: mcpc.<br>
+                codeModified := true].<br>
+       ^objectMemory isYoungObject: subject!<br>
<br>
Item was added:<br>
+ ----- Method: Cogit&gt;&gt;storeClassRef:inClosedPICAt: (in category &#39;in-line cacheing&#39;) -----<br>
+ storeClassRef: classObj inClosedPICAt: address<br>
+       &lt;var: #address type: #usqInt&gt;<br>
+       &lt;inline: true&gt;<br>
+       &quot;If inline cache tags are not objects they will be 32-bit values.&quot;<br>
+       objectRepresentation inlineCacheTagsMayBeObjects<br>
+               ifTrue: [backEnd storeLiteral: classObj beforeFollowingAddress: address]<br>
+               ifFalse: [backEnd storeLiteral32: classObj beforeFollowingAddress: address]!<br>
<br>
Item was removed:<br>
- ----- Method: Cogit&gt;&gt;updateMaybeClassRefInClosedPICAt: (in category &#39;garbage collection&#39;) -----<br>
- updateMaybeClassRefInClosedPICAt: mcpc<br>
-       &quot;Update a potential object reference from a closed PIC.<br>
-        This may be an object reference, an inline cache tag or null.<br>
-        Answer if the updated literal is young.&quot;<br>
-       | object subject |<br>
-       object := literalsManager classRefInClosedPICAt: mcpc.<br>
-       (objectRepresentation couldBeObject: object) ifFalse:<br>
-               [^false].<br>
-       subject := objectRepresentation remapOop: object.<br>
-       object ~= subject ifTrue:<br>
-               [literalsManager storeClassRef: subject inClosedPICAt: mcpc.<br>
-                codeModified := true].<br>
-       ^objectMemory isYoungObject: subject!<br>
<br>
Item was removed:<br>
- ----- Method: Cogit&gt;&gt;updateMaybeObjRefInClosedPICAt: (in category &#39;garbage collection&#39;) -----<br>
- updateMaybeObjRefInClosedPICAt: mcpc<br>
-       &quot;Update a potential object reference from a closed PIC.<br>
-        This may be an object reference, an inline cache tag or null.<br>
-        Answer if the updated literal is young.<br>
-       &#39;mcpc&#39; refers to the jump/branch instruction at the end of<br>
-       each cpic case&quot;<br>
-       | object subject |<br>
-       object := literalsManager objRefInClosedPICAt: mcpc.<br>
-       (objectRepresentation couldBeObject: object) ifFalse:<br>
-               [^false].<br>
-       subject := objectRepresentation remapOop: object.<br>
-       object ~= subject ifTrue:<br>
-               [literalsManager storeObjRef: subject inClosedPICAt: mcpc.<br>
-                codeModified := true].<br>
-       ^objectMemory isYoungObject: subject!<br>
<br>
Item was changed:<br>
  VMClass subclass: #InLineLiteralsManager<br>
+       instanceVariableNames: &#39;cogit objectMemory objectRepresentation&#39;<br>
-       instanceVariableNames: &#39;cogit&#39;<br>
        classVariableNames: &#39;&#39;<br>
        poolDictionaries: &#39;&#39;<br>
        category: &#39;VMMaker-JIT&#39;!<br>
<br>
  !InLineLiteralsManager commentStamp: &#39;eem 6/7/2015 12:07&#39; prior: 0!<br>
  An InLineLiteralsManager is a dummy class that understands the OutOfLineLiteralsManager API but does nothing.  It is used to allow the Cogits to work with back-ends that generate either in-line or out-of-line literals.!<br>
<br>
Item was removed:<br>
- ----- Method: InLineLiteralsManager&gt;&gt;cPICCase:relocateJumpLongBefore:by: (in category &#39;closed PIC parsing&#39;) -----<br>
- cPICCase: caseIndex relocateJumpLongBefore: pc by: delta<br>
-       &lt;inline: true&gt;<br>
-       cogit backEnd<br>
-               relocateJumpLongBeforeFollowingAddress: pc<br>
-               by: delta!<br>
<br>
Item was removed:<br>
- ----- Method: InLineLiteralsManager&gt;&gt;classRefInClosedPICAt: (in category &#39;garbage collection&#39;) -----<br>
- classRefInClosedPICAt: mcpc<br>
-       &lt;inline: true&gt;<br>
-       ^cogit backEnd literalBeforeFollowingAddress: mcpc - cogit backEnd loadLiteralByteSize!<br>
<br>
Item was changed:<br>
  ----- Method: InLineLiteralsManager&gt;&gt;cogit: (in category &#39;initialization&#39;) -----<br>
  cogit: aCogit<br>
        &lt;doNotGenerate&gt;<br>
+       cogit := aCogit.<br>
+       objectMemory := aCogit objectMemory.<br>
+       objectRepresentation := aCogit objectRepresentation.!<br>
-       cogit := aCogit!<br>
<br>
Item was removed:<br>
- ----- Method: InLineLiteralsManager&gt;&gt;objRefInClosedPICAt: (in category &#39;garbage collection&#39;) -----<br>
- objRefInClosedPICAt: mcpc<br>
-       &quot;&#39;mcpc&#39; refers to the jump/branch instruction at the end of<br>
-       each cpic case. The method objRef is the method object referenced by the<br>
-       movI $0x0bada553, %ebx<br>
-       or<br>
-       ldr    r6, [pc, #64]    ; 0x000017d4 16rBADA553<br>
-       type instruction preceeding this&quot;<br>
-       &lt;inline: true&gt;<br>
-       ^cogit backEnd literalBeforeFollowingAddress: mcpc!<br>
<br>
Item was removed:<br>
- ----- Method: InLineLiteralsManager&gt;&gt;storeClassRef:inClosedPICAt: (in category &#39;garbage collection&#39;) -----<br>
- storeClassRef: classObj inClosedPICAt: address<br>
-       &lt;var: #address type: #usqInt&gt;<br>
-       &lt;inline: true&gt;<br>
-       cogit backEnd storeLiteral: classObj beforeFollowingAddress: address - cogit backEnd loadLiteralByteSize!<br>
<br>
Item was removed:<br>
- ----- Method: InLineLiteralsManager&gt;&gt;storeObjRef:inClosedPICAt: (in category &#39;garbage collection&#39;) -----<br>
- storeObjRef: literal inClosedPICAt: address<br>
-       &quot;&#39;mcpc&#39; refers to the jump/branch instruction at the end of<br>
-       each cpic case. The objRef is the literal referenced by the<br>
-       movI $0x0bada553, %ebx or<br>
-       ldr    r6, [pc, #64]    ; 0x000017d4 16rBADA553<br>
-       type instruction preceeding this&quot;<br>
-       &lt;var: #address type: #usqInt&gt;<br>
-       &lt;inline: true&gt;<br>
-       cogit backEnd storeLiteral: literal beforeFollowingAddress: address!<br>
<br>
Item was removed:<br>
- ----- Method: OutOfLineLiteralsManager&gt;&gt;cPICCase:relocateJumpLongBefore:by: (in category &#39;closed PIC parsing&#39;) -----<br>
- cPICCase: caseIndex relocateJumpLongBefore: pc by: delta<br>
-       &lt;inline: true&gt;<br>
-       cogit backEnd relocateJumpLongBeforeFollowingAddress: pc by: delta!<br>
<br>
Item was removed:<br>
- ----- Method: OutOfLineLiteralsManager&gt;&gt;classRefInClosedPICAt: (in category &#39;garbage collection&#39;) -----<br>
- classRefInClosedPICAt: address<br>
-       &lt;inline: true&gt;<br>
-       &quot;If inline cache tags are not objects they will be 32-bit values.&quot;<br>
-       &quot;Current ARM out-of-line literal CPICs use<br>
-       ldr ip, [pc relative address1]<br>
-       cmp r0, ip<br>
-       ldr r6, [pc relative address2<br>
-       beq code<br>
-       hence the large backwards stepping here - address is pointing at the beq&quot;<br>
-       ^objectRepresentation inlineCacheTagsMayBeObjects<br>
-               ifFalse: [cogit backEnd literalBeforeFollowingAddress:  address - 8 &quot;better to use 2 * instructionSize if we could, step back to the cmp so the literal is found properly&quot; ]<br>
-               ifTrue: [self break. &quot;not sure about this ? &quot;objectMemory longAt: address - objectMemory bytesPerOop]!<br>
<br>
Item was removed:<br>
- ----- Method: OutOfLineLiteralsManager&gt;&gt;objRefInClosedPICAt: (in category &#39;garbage collection&#39;) -----<br>
- objRefInClosedPICAt: address<br>
-       &quot;&#39;mcpc&#39; refers to the jump/branch instruction at the end of<br>
-       each cpic case. The objRef is the literal referenced by the<br>
-        ldr    r6, [pc, #88]   ; 16r5EAF00D type instruction preceeding this&quot;<br>
-       &lt;inline: true&gt;<br>
-       ^cogit backEnd literalBeforeFollowingAddress: address !<br>
<br>
Item was removed:<br>
- ----- Method: OutOfLineLiteralsManager&gt;&gt;storeClassRef:inClosedPICAt: (in category &#39;garbage collection&#39;) -----<br>
- storeClassRef: classObj inClosedPICAt: address<br>
-       &lt;var: #address type: #usqInt&gt;<br>
-       &lt;inline: true&gt;<br>
-       &quot;If inline cache tags are not objects they will be 32-bit values.&quot;<br>
-       &quot;Current ARM out-of-line literal CPICs use<br>
-       ldr ip, [pc relative address1]<br>
-       cmp r0, ip<br>
-       ldr r6, [pc relative address2<br>
-       beq code<br>
-       hence the large backwards stepping here&quot;<br>
-       objectRepresentation inlineCacheTagsMayBeObjects<br>
-               ifTrue: [self break. objectMemory long32At: address - 4 put: classObj]<br>
-               ifFalse: [cogit backEnd storeLiteral: classObj beforeFollowingAddress:  address - 8 &quot;better to use 2 * instructionSize if we could, step back to the cmp so the literal is found properly&quot;]!<br>
<br>
Item was removed:<br>
- ----- Method: OutOfLineLiteralsManager&gt;&gt;storeObjRef:inClosedPICAt: (in category &#39;garbage collection&#39;) -----<br>
- storeObjRef: literal inClosedPICAt: address<br>
-       &quot;&#39;mcpc&#39; refers to the jump/branch instruction at the end of<br>
-       each cpic case. The objRef is the literal referenced by the<br>
-        ldr    r6, [pc, #88]   ; 16r5EAF00D type instruction preceeding this&quot;<br>
-       &lt;var: #address type: #usqInt&gt;<br>
-       &lt;inline: true&gt;<br>
-       cogit backEnd storeLiteral: literal beforeFollowingAddress: address!<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>