[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