Eliot Miranda uploaded a new version of VMMaker to project VM Maker: http://source.squeak.org/VMMaker/VMMaker.oscog-eem.3137.mcz
==================== Summary ====================
Name: VMMaker.oscog-eem.3137 Author: eem Time: 11 January 2022, 8:50:04.810202 pm UUID: bf7c9af8-02ad-4d4b-b0c9-95bb93d59019 Ancestors: VMMaker.oscog-mt.3136
In-image compilation: fix issues with converting method header formats and with accessing primitive property flags via functionPointerForCompiledMethod:primitiveIndex:primitivePropertyFlagsInto:. The fundamental fix is to have the facade's CoInterpreter's objectMemory set to the facade, hence indirecting through the facade to get to the actual obejctMemory.
=============== Diff against VMMaker.oscog-mt.3136 ===============
Item was changed: ----- Method: CurrentImageCoInterpreterFacade>>functionPointerForCompiledMethod:primitiveIndex:primitivePropertyFlagsInto: (in category 'accessing') ----- functionPointerForCompiledMethod: methodOop primitiveIndex: primIndex primitivePropertyFlagsInto: flagsPtr + primIndex = PrimNumberExternalCall ifTrue: + [flagsPtr + at: 0 + put: (coInterpreter + primitivePropertyFlagsFor: (self primitiveMethodForMethodContainingExternalPrimitive: methodOop) + primitiveIndex: primIndex). + ^self oopForObject: ((self objectForOop: methodOop) literalAt: 1) second]. + ^(coInterpreter functionPointerForCompiledMethod: methodOop primitiveIndex: primIndex primitivePropertyFlagsInto: flagsPtr) ifNotNil: + [:symbol| self addressForLabel: symbol]! - ^([coInterpreter - functionPointerForCompiledMethod: methodOop - primitiveIndex: primIndex - primitivePropertyFlagsInto: flagsPtr] - on: Error - do: [:ex| - #someExternalPrimitive]) ifNotNil: - [:symbol| - self addressForLabel: symbol]!
Item was changed: ----- Method: CurrentImageCoInterpreterFacade>>initialize (in category 'initialize-release') ----- initialize objectMemory := self class objectMemoryClass simulatorClass new. objectMemory allocateMemoryOfSize: 4*1024*1024. memory := objectMemory memory. objectMemory initializeFreeSpaceForFacadeFrom: self startOfMemory to: self variablesBase. coInterpreter := CoInterpreter new. coInterpreter instVarNamed: 'objectMemory' + put: (false ifTrue: [objectMemory] ifFalse: [self]); - put: objectMemory; instVarNamed: 'primitiveTable' put: (CArrayAccessor on: CoInterpreter primitiveTable copy). variables := Dictionary new!
Item was added: + ----- Method: CurrentImageCoInterpreterFacade>>isBytes: (in category 'testing') ----- + isBytes: anOop + ^(self objectForOop: anOop) class isBytes!
Item was added: + ----- Method: CurrentImageCoInterpreterFacade>>numBytesOfBytes: (in category 'accessing') ----- + numBytesOfBytes: objOop + ^self numBytesOf: objOop!
Item was changed: ----- Method: CurrentImageCoInterpreterFacade>>primitiveIndexOfMethod:header: (in category 'accessing') ----- primitiveIndexOfMethod: anOop header: header | method | method := self objectForOop: anOop. - self assert: (self objectForOop: header) = method header. ^method primitive!
Item was added: + ----- Method: CurrentImageCoInterpreterFacade>>primitiveMethodForMethodContainingExternalPrimitive: (in category 'cog jit support') ----- + primitiveMethodForMethodContainingExternalPrimitive: methodOop + "Look up a primitive in a method and answer that method." + | candidates literal method | + method := self objectForOop: methodOop. + self assert: method primitive = PrimNumberExternalCall. + literal := method literalAt: 1. + candidates := self sn + allImplementorsOf: literal second + localTo: (literal first basicSize = 0 + ifTrue: [InterpreterPrimitives] + ifFalse: [InterpreterPlugin allSubclasses + detect: [:pluginClass| pluginClass moduleName = literal first]]). + self assert: candidates size = 1. + ^candidates first compiledMethod!
Item was added: + ----- Method: CurrentImageCoInterpreterFacade>>primitivePropertyFlags:numArgs: (in category 'accessing') ----- + primitivePropertyFlags: primIndex numArgs: numArgs + ^coInterpreter primitivePropertyFlags: primIndex numArgs: numArgs!
Item was changed: ----- Method: CurrentImageCoInterpreterFacade>>rawHeaderOf: (in category 'accessing') ----- rawHeaderOf: aMethodOop + self subclassResponsibility! - | method header correctedHeader headerOop | - method := self objectForOop: aMethodOop. - header := method header. - - "(index 0) 15 bits: number of literals (#numLiterals) - (index 15) 1 bit: jit without counters - reserved for methods that have been optimized by Sista - (index 16) 1 bit: has primitive - (index 17) 1 bit: whether a large frame size is needed (#frameSize => either SmallFrame or LargeFrame) - (index 18) 6 bits: number of temporary variables (#numTemps) - (index 24) 4 bits: number of arguments to the method (#numArgs) - (index 28) 2 bits: reserved for an access modifier (00-unused, 01-private, 10-protected, 11-public), although accessors for bit 29 exist (see #flag). - sign bit: 1 bit: selects the instruction set, >= 0 Primary, < 0 Secondary (#signFlag)" - - correctedHeader := self wordSize = Smalltalk wordSize - ifTrue: [header] - ifFalse: - [(header bitAnd: (1 bitShift: 30) - 1) - - (header < 0 ifTrue: [2 raisedTo: self wordSize * 8] ifFalse: [0])]. - headerOop := objectMemory integerObjectOf: correctedHeader. - headerOop := headerOop bitAnd: (2 raisedTo: self wordSize * 8) - 1. - self assert: (objectMemory literalCountOfMethodHeader: headerOop) = method numLiterals. - self assert: (coInterpreter argumentCountOfMethodHeader: headerOop) = method numArgs. - self assert: (coInterpreter temporaryCountOfMethodHeader: headerOop) = method numTemps. - self assert: (objectMemory headerIndicatesAlternateBytecodeSet: headerOop) = method signFlag. - headerToMethodMap - at: headerOop - ifPresent: [:existing| self assert: existing == method] - ifAbsentPut: [method]. - ^headerOop!
Item was removed: - ----- Method: CurrentImageCoInterpreterFacadeForSpurObjectRepresentation>>functionPointerForCompiledMethod:primitiveIndex:primitivePropertyFlagsInto: (in category 'cog jit support') ----- - functionPointerForCompiledMethod: methodOop primitiveIndex: primIndex primitivePropertyFlagsInto: flagsPtr - primIndex = PrimNumberExternalCall ifTrue: - [flagsPtr - at: 0 - put: (coInterpreter - primitivePropertyFlagsFor: (self primitiveMethodForMethodContainingExternalPrimitive: methodOop) - primitiveIndex: primIndex). - ^self oopForObject: ((self objectForOop: methodOop) literalAt: 1) second]. - ^super functionPointerForCompiledMethod: methodOop primitiveIndex: primIndex primitivePropertyFlagsInto: flagsPtr!
Item was removed: - ----- Method: CurrentImageCoInterpreterFacadeForSpurObjectRepresentation>>primitiveMethodForMethodContainingExternalPrimitive: (in category 'cog jit support') ----- - primitiveMethodForMethodContainingExternalPrimitive: methodOop - "Look up a primitive in a method and answer that method." - | candidates literal method | - method := self objectForOop: methodOop. - self assert: method primitive = PrimNumberExternalCall. - literal := method literalAt: 1. - candidates := self sn - allImplementorsOf: literal second - localTo: (literal first basicSize = 0 - ifTrue: [InterpreterPrimitives] - ifFalse: [InterpreterPlugin allSubclasses - detect: [:pluginClass| pluginClass moduleName = literal first]]). - self assert: candidates size = 1. - ^candidates first compiledMethod!
Item was added: + ----- Method: CurrentImageCoInterpreterFacadeForSpurObjectRepresentation>>rawHeaderOf: (in category 'accessing') ----- + rawHeaderOf: aMethodOop + | method header correctedHeader headerOop | + method := aMethodOop isCompiledCode + ifTrue: [aMethodOop] + ifFalse: [self objectForOop: aMethodOop]. + header := method header. + + "(index 0) 15 bits: number of literals (#numLiterals) + (index 15) 1 bit: jit without counters - reserved for methods that have been optimized by Sista + (index 16) 1 bit: has primitive + (index 17) 1 bit: whether a large frame size is needed (#frameSize => either SmallFrame or LargeFrame) + (index 18) 6 bits: number of temporary variables (#numTemps) + (index 24) 4 bits: number of arguments to the method (#numArgs) + (index 28) 2 bits: reserved for an access modifier (00-unused, 01-private, 10-protected, 11-public), although accessors for bit 29 exist (see #flag). + sign bit: 1 bit: selects the instruction set, >= 0 Primary, < 0 Secondary (#signFlag)" + + correctedHeader := self wordSize = Smalltalk wordSize + ifTrue: [header] + ifFalse: [(header bitAnd: (1 bitShift: 30) - 1) + + (header < 0 + ifTrue: [1 bitShift: self wordSize * 8 - objectMemory numTagBits] + ifFalse: [0])]. + headerOop := objectMemory integerObjectOf: correctedHeader. + self assert: (objectMemory literalCountOfMethodHeader: headerOop) = method numLiterals. + self assert: (coInterpreter argumentCountOfMethodHeader: headerOop) = method numArgs. + self assert: (coInterpreter temporaryCountOfMethodHeader: headerOop) = method numTemps. + self assert: (objectMemory headerIndicatesAlternateBytecodeSet: headerOop) = method signFlag. + headerToMethodMap + at: headerOop + ifPresent: [:existing| self assert: existing == method] + ifAbsentPut: [method]. + ^headerOop!
Item was added: + ----- Method: CurrentImageCoInterpreterFacadeForSqueakV3ObjectRepresentation>>rawHeaderOf: (in category 'accessing') ----- + rawHeaderOf: aMethodOop + | method header correctedHeader headerOop | + method := aMethodOop isCompiledCode + ifTrue: [aMethodOop] + ifFalse: [self objectForOop: aMethodOop]. + header := method header. + "original (+ve header): + (index 0) 9 bits: main part of primitive number (#primitive) + (index 9) 8 bits: number of literals (#numLiterals) + (index 17) 1 bit: whether a large frame size is needed (#frameSize) + (index 18) 6 bits: number of temporary variables (#numTemps) + (index 24) 4 bits: number of arguments to the method (#numArgs) + (index 28) 1 bit: high-bit of primitive number (#primitive) + (index 29) 1 bit: flag bit, ignored by the VM (#flag)" + + "new: (-ve header) + (index 0) 15 bits: number of literals (#numLiterals) + (index 15) 1 bit: jit without counters - reserved for methods that have been optimized by Sista + (index 16) 1 bit: has primitive + (index 17) 1 bit: whether a large frame size is needed (#frameSize => either SmallFrame or LargeFrame) + (index 18) 6 bits: number of temporary variables (#numTemps) + (index 24) 4 bits: number of arguments to the method (#numArgs) + (index 28) 2 bits: reserved for an access modifier (00-unused, 01-private, 10-protected, 11-public), although accessors for bit 29 exist (see #flag). + sign bit: 1 bit: selects the instruction set, >= 0 Primary, < 0 Secondary (#signFlag)" + + "This could be smarter. If MULTIPLEBYTECODESETS is in effect we can switch hit. If not, we can map to the relevant format. + For now we just reinterpret the method itself, answering a header in the format its bytecode set dictates..." + correctedHeader := header >= 0 + ifTrue: + [method numLiterals > 255 ifTrue: [self error: 'cannot map method to the old header format']. + (method primitive bitAnd: 16r1FF) + + (method numLiterals bitShift: 9) + + (header bitAnd: 16r3FFFF bitInvert)] + ifFalse: + [self wordSize = Smalltalk wordSize + ifTrue: [header] + ifFalse: [(header bitAnd: (1 bitShift: 30) - 1) + (1 bitShift: 30)]]. + headerOop := objectMemory integerObjectOf: correctedHeader. + self assert: (objectMemory literalCountOfMethodHeader: headerOop) = method numLiterals. + self assert: (coInterpreter argumentCountOfMethodHeader: headerOop) = method numArgs. + self assert: (coInterpreter temporaryCountOfMethodHeader: headerOop) = method numTemps. + self assert: (objectMemory headerIndicatesAlternateBytecodeSet: headerOop) = method signFlag. + headerToMethodMap + at: headerOop + ifPresent: [:existing| self assert: existing == method] + ifAbsentPut: [method]. + ^headerOop!
vm-dev@lists.squeakfoundation.org