Skip to content

Commit

Permalink
Merge pull request #873 from tesonep/fix-large-classIndex-should-be-p…
Browse files Browse the repository at this point in the history
…ositive

When patching JITed code after become of a class, the class index can look like a negative number
  • Loading branch information
guillep authored Dec 3, 2024
2 parents cab16b3 + f572ef1 commit 26beb75
Show file tree
Hide file tree
Showing 9 changed files with 99 additions and 10 deletions.
2 changes: 1 addition & 1 deletion smalltalksrc/VMMaker/CogAbstractInstruction.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -1057,7 +1057,7 @@ CogAbstractInstruction >> getOperandsWithFormat: format [
ifTrue: [ (operand > 16 and: [ opcode ~= Label ])
ifTrue: [
(operand allMask: 16r80000000)
ifTrue: [ strOperands add: operand, '/', operand signedIntFromLong ].
ifTrue: [ strOperands add: operand printString, '/', operand signedIntFromLong printString ].
strOperands add: operand asString, '/', (operand hex)]
ifFalse: [
strOperands add: operand.
Expand Down
6 changes: 5 additions & 1 deletion smalltalksrc/VMMaker/CogIA32Compiler.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -3646,7 +3646,11 @@ CogIA32Compiler >> hasThreeAddressArithmetic [
{ #category : 'inline cacheing' }
CogIA32Compiler >> inlineCacheTagAt: callSiteReturnAddress [
"Answer the inline cache tag for the return address of a send."
^self literalBeforeFollowingAddress: callSiteReturnAddress - 5

<returnTypeC: #usqInt>

^ (self literalBeforeFollowingAddress: callSiteReturnAddress - 5)
bitAnd: 1 << objectMemory classIndexFieldWidth - 1
]

{ #category : 'disassembly' }
Expand Down
11 changes: 9 additions & 2 deletions smalltalksrc/VMMaker/CogInLineLiteralsARMCompiler.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,15 @@ CogInLineLiteralsARMCompiler >> getDefaultCogCodeSize [
{ #category : 'inline cacheing' }
CogInLineLiteralsARMCompiler >> inlineCacheTagAt: callSiteReturnAddress [
"Answer the inline cache tag for the return address of a send."
self assert: (self instructionIsBL: (self instructionBeforeAddress: callSiteReturnAddress)).
^self extract32BitOperandFrom4InstructionsPreceding: callSiteReturnAddress - 4

<returnTypeC: #usqInt>

self assert: (self instructionIsBL:
(self instructionBeforeAddress: callSiteReturnAddress)).

^ (self extract32BitOperandFrom4InstructionsPreceding:
callSiteReturnAddress - 4) bitAnd:
1 << objectMemory classIndexFieldWidth - 1
]

{ #category : 'testing' }
Expand Down
6 changes: 5 additions & 1 deletion smalltalksrc/VMMaker/CogInLineLiteralsX64Compiler.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,11 @@ CogInLineLiteralsX64Compiler >> getDefaultCogCodeSize [
{ #category : 'inline cacheing' }
CogInLineLiteralsX64Compiler >> inlineCacheTagAt: callSiteReturnAddress [
"Answer the inline cache tag for the return address of a send."
^self literal32BeforeFollowingAddress: callSiteReturnAddress - 5

<returnTypeC: #usqInt>

^ (self literal32BeforeFollowingAddress: callSiteReturnAddress - 5)
bitAnd: 1 << objectMemory classIndexFieldWidth - 1
]

{ #category : 'testing' }
Expand Down
5 changes: 4 additions & 1 deletion smalltalksrc/VMMaker/CogMIPSELCompiler.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -1908,6 +1908,8 @@ CogMIPSELCompiler >> inlineCacheTagAt: callSiteReturnAddress [
... <-- callSiteReturnAddress"

<var: #callSiteReturnAddress type: #usqInt>
<returnTypeC: #usqInt>

self assert: (self opcodeAtAddress: callSiteReturnAddress - 24) = LUI.
self assert: (self opcodeAtAddress: callSiteReturnAddress - 20) = ORI.
self assert: (self opcodeAtAddress: callSiteReturnAddress - 16) = LUI.
Expand All @@ -1916,7 +1918,8 @@ CogMIPSELCompiler >> inlineCacheTagAt: callSiteReturnAddress [
self assert: (self functionAtAddress: callSiteReturnAddress - 8) = JALR.
self assert: (objectMemory longAt: callSiteReturnAddress - 4) = self nop.

^self literalAtAddress: callSiteReturnAddress - 20
^(self literalAtAddress: callSiteReturnAddress - 20) bitAnd:
1 << objectMemory classIndexFieldWidth - 1
]

{ #category : 'disassembly' }
Expand Down
7 changes: 5 additions & 2 deletions smalltalksrc/VMMaker/CogOutOfLineLiteralsARMCompiler.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,11 @@ CogOutOfLineLiteralsARMCompiler >> getDefaultCogCodeSize [

{ #category : 'inline cacheing' }
CogOutOfLineLiteralsARMCompiler >> inlineCacheTagAt: callSiteReturnAddress [
<inline: true>
^objectMemory uint32AtPointer: (self pcRelativeAddressAt: (callSiteReturnAddress - 8) asUnsignedInteger)

<returnTypeC: #usqInt>

^(objectMemory uint32AtPointer: (self pcRelativeAddressAt: (callSiteReturnAddress - 8) asUnsignedInteger)) bitAnd:
1 << objectMemory classIndexFieldWidth - 1
]

{ #category : 'testing' }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,8 +207,12 @@ CogOutOfLineLiteralsARMv8Compiler >> getDefaultCogCodeSize [

{ #category : 'inline cacheing' }
CogOutOfLineLiteralsARMv8Compiler >> inlineCacheTagAt: callSiteReturnAddress [
<inline: true>
^objectMemory unsignedLongAt: (self pcRelativeAddressAt: (callSiteReturnAddress - 8) asUnsignedInteger)

<returnTypeC: #usqInt>

^ (objectMemory unsignedLongAt: (self pcRelativeAddressAt:
(callSiteReturnAddress - 8) asUnsignedInteger)) bitAnd:
1 << objectMemory classIndexFieldWidth - 1
]

{ #category : 'testing' }
Expand Down
2 changes: 2 additions & 0 deletions smalltalksrc/VMMaker/SpurMemoryManager.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -3697,6 +3697,7 @@ SpurMemoryManager >> classFormatFromInstFormat: instFormat [

{ #category : 'header format' }
SpurMemoryManager >> classIndexFieldWidth [
<api>
"22-bit class mask => ~ 4M classes"
^22
]
Expand Down Expand Up @@ -8166,6 +8167,7 @@ SpurMemoryManager >> isValidClassIndex: classIndex [
SpurMemoryManager >> isValidClassTag: classIndex [
<api>
| classOrNil |

self assert: (classIndex between: 0 and: 1 << self classIndexFieldWidth - 1).
classOrNil := self classOrNilAtIndex: classIndex.
^classOrNil ~= nilObj
Expand Down
62 changes: 62 additions & 0 deletions smalltalksrc/VMMakerTests/VMClassTagInlineReadTest.class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
Class {
#name : 'VMClassTagInlineReadTest',
#superclass : 'VMPrimitiveCallAbstractTest',
#pools : [
'CogRTLOpcodes'
],
#category : 'VMMakerTests-JitTests',
#package : 'VMMakerTests',
#tag : 'JitTests'
}

{ #category : 'tests' }
VMClassTagInlineReadTest >> testLinkingWithEntryOffset [

| sendingMethod targetMethod callSiteReturn |
sendingMethod := self
jitMethod: (self findMethod: #methodWithSend)
selector: memory nilObject.

targetMethod := self
jitMethod: (self findMethod: #yourself)
selector: memory trueObject.

callSiteReturn := sendingMethod address + 16r98.

cogit
linkSendAt: callSiteReturn
in: sendingMethod
to: targetMethod
offset: cogit entryOffset
receiver: memory falseObject.

self assert: (cogit backend inlineCacheTagAt: callSiteReturn) equals:(memory classIndexOf: memory falseObject)
]

{ #category : 'tests' }
VMClassTagInlineReadTest >> testLinkingWithEntryOffsetLargeClassIndex [

| sendingMethod targetMethod callSiteReturn |
sendingMethod := self
jitMethod: (self findMethod: #methodWithSend)
selector: memory nilObject.

targetMethod := self
jitMethod: (self findMethod: #yourself)
selector: memory trueObject.

callSiteReturn := sendingMethod address + 16r98.

obj := self newZeroSizedObject.
memory setClassIndexOf: obj to: (1 << memory classIndexFieldWidth - 5).

cogit
linkSendAt: callSiteReturn
in: sendingMethod
to: targetMethod
offset: cogit entryOffset
receiver: obj.


self assert: (cogit backend inlineCacheTagAt: callSiteReturn) equals: (1 << memory classIndexFieldWidth - 5)
]

0 comments on commit 26beb75

Please sign in to comment.