Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When patching JITed code after become of a class, the class index can look like a negative number #873

Open
wants to merge 3 commits into
base: pharo-10
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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).
guillep marked this conversation as resolved.
Show resolved Hide resolved
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)
]