[Vm-dev] VM Maker: VMMaker.oscog-eem.2142.mcz
commits at source.squeak.org
commits at source.squeak.org
Thu Mar 2 16:37:15 UTC 2017
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!
More information about the Vm-dev
mailing list