Eliot Miranda uploaded a new version of VMMaker to project VM Maker: http://source.squeak.org/VMMaker/VMMaker.oscog-eem.2142.mcz ==================== Summary ==================== Name: VMMaker.oscog-eem.2142 Author: eem Time: 2 March 2017, 8:36:14.812791 am UUID: a11f8834-2f47-4326-aac8-64dac840dec3 Ancestors: VMMaker.oscog-eem.2141 Fix accessing a nil methodClass on jitting. Nuke the unused CogBytecodeDescriptor isCallPrimitive inst var and add a replacement. =============== Diff against VMMaker.oscog-eem.2141 =============== Item was changed: VMStructType subclass: #CogBytecodeDescriptor + instanceVariableNames: 'generator spanFunction needsFrameFunction stackDelta opcode numBytes isBranchTrue isBranchFalse isReturn isBlockCreation isMapped isMappedInBlock isExtension isInstVarRef is1ByteInstVarStore hasIRC' - instanceVariableNames: 'generator spanFunction needsFrameFunction stackDelta opcode numBytes isBranchTrue isBranchFalse isReturn isBlockCreation isMapped isMappedInBlock isExtension isInstVarRef is1ByteInstVarStore hasIRC isCallPrimitive' classVariableNames: '' poolDictionaries: '' category: 'VMMaker-JIT'! !CogBytecodeDescriptor commentStamp: 'eem 11/18/2010 06:32' prior: 0! I am an entry in the Cogit's dispatch table for bytecodes. I hold the routine to call to generate code for the partcular bytecode I represent and the number of bytes the bytecode has. For eliminating temps in frameless blocks I maintain a stack delta for bytecodes that are valid in a frameless block. The order of my instance variables is chosen for compact struct packing.! Item was changed: ----- Method: CogBytecodeDescriptor>>isCallPrimitive (in category 'accessing') ----- isCallPrimitive - "Answer the value of isCallPrimitive" + ^generator == #genCallPrimitiveBytecode! - ^ isCallPrimitive! Item was removed: - ----- Method: CogBytecodeDescriptor>>isCallPrimitive: (in category 'accessing') ----- - isCallPrimitive: anObject - "Set the value of isCallPrimitive" - - ^isCallPrimitive := anObject! Item was changed: ----- Method: Cogit class>>generatorTableFrom: (in category 'class initialization') ----- generatorTableFrom: anArray | blockCreationBytecodeSize | generatorTable := CArrayAccessor on: (Array new: 256). anArray do: [:tuple| | descriptor | (descriptor := CogBytecodeDescriptor new) numBytes: tuple first; generator: tuple fourth; isReturn: (tuple includes: #return); isMapped: ((tuple includes: #isMappedIfImmutability) ifTrue: [self bindingOf: #IMMUTABILITY] ifFalse: [tuple includes: #isMapped]); isMappedInBlock: (tuple includes: #isMappedInBlock); isBlockCreation: (tuple includes: #block); spanFunction: (((tuple includes: #block) or: [(tuple includes: #branch)]) ifTrue: [tuple detect: [:thing| thing isSymbol and: [thing numArgs = 4]]]); isBranchTrue: (tuple includes: #isBranchTrue); isBranchFalse: (tuple includes: #isBranchFalse); isExtension: (tuple includes: #extension); isInstVarRef: (tuple includes: #isInstVarRef); "for Spur" is1ByteInstVarStore: (tuple includes: #is1ByteInstVarStore); "for Spur" - isCallPrimitive: (tuple includes: #callPrimitive); hasIRC: (tuple includes: #hasIRC); "for Newspeak" yourself. "As a hack to cut down on descriptor flags, use opcode to tag unusedBytecode for scanning. Currently descriptors are exactly 16 bytes with all 8 flag bits used (in Newspeak at least 17 bytes, 9 flag bits). As another hack to eliminate a test in scanMethod mark unknowns as extensions." descriptor generator == #unknownBytecode ifTrue: [descriptor opcode: Nop; isExtension: true]. descriptor isBlockCreation ifTrue: [blockCreationBytecodeSize ifNil: [blockCreationBytecodeSize := descriptor numBytes] ifNotNil: [self assert: blockCreationBytecodeSize = descriptor numBytes]]. tuple do: [:thing| thing isSymbol ifTrue: [(thing beginsWith: #needsFrame) ifTrue: [descriptor needsFrameFunction: thing]. (CogRTLOpcodes classPool at: thing ifAbsent: []) ifNotNil: [:opcode| descriptor opcode: opcode]]]. tuple last isInteger ifTrue: [descriptor stackDelta: tuple last] ifFalse: [descriptor needsFrameFunction ifNotNil: [self error: 'frameless block bytecodes must specify a stack delta']]. tuple second to: tuple third do: [:index| generatorTable at: index put: descriptor]]. BlockCreationBytecodeSize := blockCreationBytecodeSize. ^generatorTable! Item was changed: ----- Method: Spur32BitCoMemoryManager>>receiverTagBitsForMethod: (in category 'cog jit support') ----- receiverTagBitsForMethod: aMethodObj "Answer the tag bits for the receiver based on the method's methodClass, if any." <api> + | methodClassOrNil | + methodClassOrNil := coInterpreter methodClassOf: aMethodObj. + (methodClassOrNil = nilObj + or: [(self instSpecOfClass: methodClassOrNil) ~= self forwardedFormat]) ifTrue: - | methodClass | - methodClass := coInterpreter methodClassOf: aMethodObj. - (self instSpecOfClass: methodClass) ~= self forwardedFormat ifTrue: [^0]. + ^methodClassOrNil = (self fetchPointer: self smallIntegerTag ofObject: classTableFirstPage) - ^methodClass = (self fetchPointer: self smallIntegerTag ofObject: classTableFirstPage) ifTrue: [self smallIntegerTag] + ifFalse: [self assert: methodClassOrNil = (self fetchPointer: self characterTag ofObject: classTableFirstPage). - ifFalse: [self assert: methodClass = (self fetchPointer: self characterTag ofObject: classTableFirstPage). self characterTag]! Item was changed: ----- Method: Spur64BitCoMemoryManager>>receiverTagBitsForMethod: (in category 'cog jit support') ----- receiverTagBitsForMethod: aMethodObj "Answer the tag bits for the receiver based on the method's methodClass, if any." <api> + | methodClassOrNil | + methodClassOrNil := coInterpreter methodClassOf: aMethodObj. + (methodClassOrNil = nilObj + or: [(self instSpecOfClass: methodClassOrNil) ~= self forwardedFormat]) ifTrue: - | methodClass | - methodClass := coInterpreter methodClassOf: aMethodObj. - (self instSpecOfClass: methodClass) ~= self forwardedFormat ifTrue: [^0]. + methodClassOrNil = (self fetchPointer: self smallIntegerTag ofObject: classTableFirstPage) ifTrue: - methodClass = (self fetchPointer: self smallIntegerTag ofObject: classTableFirstPage) ifTrue: [^self smallIntegerTag]. + methodClassOrNil = (self fetchPointer: self characterTag ofObject: classTableFirstPage) ifTrue: - methodClass = (self fetchPointer: self characterTag ofObject: classTableFirstPage) ifTrue: [^self characterTag]. + self assert: methodClassOrNil = (self fetchPointer: self smallFloatTag ofObject: classTableFirstPage). - self assert: methodClass = (self fetchPointer: self smallFloatTag ofObject: classTableFirstPage). ^self smallFloatTag! Item was changed: ----- Method: StackInterpreter>>methodClassOf: (in category 'compiled methods') ----- methodClassOf: methodPointer <api> + "Answer the method class of a method which is the value of an Association in the last literal, + or answer nil if there isn't one. + Using a read barrier here simplifies the become implementation and costs very little - "Using a read barrier here simplifies the become implementation and costs very little because the class index and ValueIndex of the association almost certainly share a cache line." | literal | literal := self followLiteral: (objectMemory literalCountOf: methodPointer) - 1 ofMethod: methodPointer. + literal ~= objectMemory nilObject ifTrue: + [self assert: ((objectMemory isPointers: literal) and: [(objectMemory numSlotsOf: literal) > ValueIndex]). + literal := objectMemory followField: ValueIndex ofObject: literal]. - NewspeakVM - ifTrue: - [literal ~= objectMemory nilObject ifTrue: - [literal := objectMemory followField: ValueIndex ofObject: literal]] - ifFalse: - [self assert: ((objectMemory isPointers: literal) and: [(objectMemory numSlotsOf: literal) > ValueIndex]). - literal := objectMemory followField: ValueIndex ofObject: literal]. ^literal! |
Free forum by Nabble | Edit this page |