[Vm-dev] VM Maker: VMMaker.oscog-cb.1807.mcz

commits at source.squeak.org commits at source.squeak.org
Fri Apr 15 18:41:37 UTC 2016


ClementBera uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-cb.1807.mcz

==================== Summary ====================

Name: VMMaker.oscog-cb.1807
Author: cb
Time: 15 April 2016, 11:40:00.409121 am
UUID: efdcf018-e896-4dce-b1a3-7b07f4248263
Ancestors: VMMaker.oscog-eem.1806

Added flags not to compile full block closure if not available.

=============== Diff against VMMaker.oscog-eem.1806 ===============

Item was changed:
  ----- Method: Cogit>>cogFullBlockMethod:numCopied: (in category 'jit - api') -----
  cogFullBlockMethod: aMethodObj numCopied: numCopied
  	"Attempt to produce a machine code method for the bytecode method
  	 object aMethodObj.  N.B. If there is no code memory available do *NOT*
  	 attempt to reclaim the method zone.  Certain clients (e.g. ceSICMiss:)
  	 depend on the zone remaining constant across method generation."
  	<api>
+ 	<option: #SistaV1BytecodeSet>
  	<returnTypeC: #'CogMethod *'>
  	| cogMethod |
  	<var: #cogMethod type: #'CogMethod *'>
  	self cCode: [] inSmalltalk: "for debugging, allow excluding methods based on selector or methodClass"
  		[self class initializationOptions
  			at: #DoNotJIT
  			ifPresent:
  				[:excluded| 
  				(excluded anySatisfy: [:exclude| aMethodObj = exclude]) ifTrue:
  					[coInterpreter transcript nextPutAll: 'EXCLUDING '; nextPutAll: aMethodObj; nextPutAll: ' (compiled block)'; cr; flush.
  					 ^nil]]].
  	self deny: (coInterpreter methodHasCogMethod: aMethodObj).
  	aMethodObj = breakMethod ifTrue: [self halt: 'Compilation of breakMethod'].
  	"If the generators for the alternate bytecode set are missing then interpret."
  	(coInterpreter methodUsesAlternateBytecodeSet: aMethodObj)
  		ifTrue:
  			[(self numElementsIn: generatorTable) <= 256 ifTrue:
  				[^nil].
  			 bytecodeSetOffset := 256]
  		ifFalse:
  			[bytecodeSetOffset := 0].
  	objectRepresentation ensureNoForwardedLiteralsIn: aMethodObj.
  	methodObj := aMethodObj.
  	methodHeader := objectMemory methodHeaderOf: aMethodObj.
  	cogMethod := self compileCogFullBlockMethod: numCopied.
  	(cogMethod asInteger between: MaxNegativeErrorCode and: -1) ifTrue:
  		[cogMethod asInteger = InsufficientCodeSpace ifTrue:
  			[coInterpreter callForCogCompiledCodeCompaction].
  		 self maybeFreeCounters.
  		 "Right now no errors should be reported, so nothing more to do."
  		 "self reportError: (self cCoerceSimple: cogMethod to: #sqInt)."
  		 ^nil].
  	"self cCode: ''
  		inSmalltalk:
  			[coInterpreter printCogMethod: cogMethod.
  			 ""coInterpreter symbolicMethod: aMethodObj.""
  			 self assertValidMethodMap: cogMethod."
  			 "self disassembleMethod: cogMethod."
  			 "printInstructions := clickConfirm := true""]."
  	^cogMethod!

Item was changed:
  ----- Method: Cogit>>compileCogFullBlockMethod: (in category 'compile abstract instructions') -----
  compileCogFullBlockMethod: numCopied
  	<returnTypeC: #'CogMethod *'>
+ 	<option: #SistaV1BytecodeSet>
  	| numBytecodes numBlocks numCleanBlocks result |
  	hasYoungReferent := (objectMemory isYoungObject: methodObj).
  	methodOrBlockNumArgs := coInterpreter argumentCountOf: methodObj.
  	inBlock := true.
  	postCompileHook := nil.
  	maxLitIndex := -1.
  	self assert: (coInterpreter primitiveIndexOf: methodObj) = 0.
  	initialPC := coInterpreter startPCOfMethod: methodObj.
  	"initial estimate.  Actual endPC is determined in scanMethod."
  	endPC := objectMemory numBytesOf: methodObj.
  	numBytecodes := endPC - initialPC + 1.
  	primitiveIndex := 0.
  	self allocateOpcodes: (numBytecodes + 10) * self estimateOfAbstractOpcodesPerBytecodes
  		bytecodes: numBytecodes
  		ifFail: [^coInterpreter cCoerceSimple: MethodTooBig to: #'CogMethod *'].
  	self flag: #TODO. "currently copiedValue access implies frameful method, this is suboptimal"
  	(numBlocks := self scanMethod) < 0 ifTrue:
  		[^coInterpreter cCoerceSimple: numBlocks to: #'CogMethod *'].
  	self assert: numBlocks = 0. "blocks in full blocks are full blocks, they are not inlined."
  	numCleanBlocks := self scanForCleanBlocks.
  	self assert: numCleanBlocks = 0. "blocks in full blocks are full blocks, they are not inlined."
  	self allocateBlockStarts: numBlocks + numCleanBlocks.
  	blockCount := 0.
  	numCleanBlocks > 0 ifTrue:
  		[self addCleanBlockStarts].
  	(self maybeAllocAndInitCounters
  	 and: [self maybeAllocAndInitIRCs]) ifFalse: "Inaccurate error code, but it'll do.  This will likely never fail."
  		[^coInterpreter cCoerceSimple: InsufficientCodeSpace to: #'CogMethod *'].
  
  	blockEntryLabel := nil.
  	methodLabel dependent: nil.
  	(result := self compileEntireFullBlockMethod: numCopied) < 0 ifTrue:
  		[^coInterpreter cCoerceSimple: result to: #'CogMethod *'].
  	^self generateCogFullBlock!

Item was changed:
  ----- Method: Cogit>>compileEntireFullBlockMethod: (in category 'compile abstract instructions') -----
  compileEntireFullBlockMethod: numCopied
  	"Compile the abstract instructions for the entire method, including blocks."
+ 	<option: #SistaV1BytecodeSet>
  	| result |
  	self preenMethodLabel.
  	self compileFullBlockEntry.
  
  	"Frame build"
  	self compileFullBlockMethodFrameBuild: numCopied.
  	"Method body"
  	(result := self compileMethodBody) < 0 ifTrue:
  		[^result].
  	self assert: blockCount = 0.
  	^0!

Item was changed:
  ----- Method: Cogit>>compileFullBlockEntry (in category 'compile abstract instructions') -----
  compileFullBlockEntry
+ 	<option: #SistaV1BytecodeSet>
  	"Compile the abstract instructions for the entire method, including blocks."
  	| jumpNoContextSwitch |
  
  	"Abort for stack overflow on full block activation (no inline cache miss possible).
  	 The flag is SendNumArgsReg."
  	stackOverflowCall := self MoveCq: 0 R: ReceiverResultReg.
  	backEnd hasLinkRegister ifTrue: [self PushR: LinkReg].
  	"Since the only case in which this is called is the
  	 stack overflow case we can reuse the trampoline."
  	self Call: (self methodAbortTrampolineFor: methodOrBlockNumArgs).
  
  	"Entries"
  	"No context switch entry"
  	fullBlockNoContextSwitchEntry := self MoveCq: 0 R: SendNumArgsReg.
  	jumpNoContextSwitch := self Jump: 0.
  
  	self AlignmentNops: (objectMemory wordSize max: 8).
  	"Context switch entry (use ReceiverResultReg as a non-zero value; it's shorter)."
  	fullBlockEntry := self MoveR: ReceiverResultReg R: SendNumArgsReg.
  	jumpNoContextSwitch jmpTarget: self Label.
  
  	^0!

Item was changed:
  ----- Method: Cogit>>generateCogFullBlock (in category 'compile abstract instructions') -----
  generateCogFullBlock
  	"We handle jump sizing simply.  First we make a pass that asks each
  	 instruction to compute its maximum size.  Then we make a pass that
  	 sizes jumps based on the maxmimum sizes.  Then we make a pass
  	 that fixes up jumps.  When fixing up a jump the jump is not allowed to
  	 choose a smaller offset but must stick to the size set in the second pass."
  	<returnTypeC: #'CogMethod *'>
+ 	<option: #SistaV1BytecodeSet>
  	| codeSize headerSize mapSize totalSize startAddress result method |
  	<var: #method type: #'CogMethod *'>
  	headerSize := self sizeof: CogMethod.
  	methodLabel address: methodZone freeStart.
  	self computeMaximumSizes.
  	methodLabel concretizeAt: methodZone freeStart.
  	codeSize := self generateInstructionsAt: methodLabel address + headerSize.
  	mapSize := self generateMapAt: nil start: methodLabel address + cbNoSwitchEntryOffset.
  .
  	totalSize := methodZone roundUpLength: headerSize + codeSize + mapSize.
  	totalSize > MaxMethodSize ifTrue:
  		[^self cCoerceSimple: MethodTooBig to: #'CogMethod *'].
  	startAddress := methodZone allocate: totalSize.
  	startAddress = 0 ifTrue:
  		[^self cCoerceSimple: InsufficientCodeSpace to: #'CogMethod *'].
  	self assert: startAddress + cbEntryOffset = fullBlockEntry address.
  	self assert: startAddress + cbNoSwitchEntryOffset = fullBlockNoContextSwitchEntry address.
  	result := self outputInstructionsAt: startAddress + headerSize.
  	self assert: startAddress + headerSize + codeSize = result.
  	backEnd padIfPossibleWithStopsFrom: result to: startAddress + totalSize - mapSize.
  	self generateMapAt: startAddress + totalSize - 1 start: startAddress + cbNoSwitchEntryOffset.
  	self flag: #TOCHECK. "It's not clear we want the same header than regular methods. 
  	It could be of the same size, but maybe the cmType could be different and the selector could be ignored." 
  	method := self fillInMethodHeader: (self cCoerceSimple: startAddress to: #'CogMethod *')
  					size: totalSize
  					selector: objectMemory nilObject.
  	method cpicHasMNUCaseOrCMIsFullBlock: true.
  	postCompileHook ifNotNil:
  		[self perform: postCompileHook with: method.
  		 postCompileHook := nil].
  	^method!

Item was changed:
  ----- Method: SistaStackToRegisterMappingCogit>>compileCogFullBlockMethod: (in category 'compile abstract instructions') -----
  compileCogFullBlockMethod: numCopied
+ 	<option: #SistaV1BytecodeSet>
  	counters := 0.
  	^super compileCogFullBlockMethod: numCopied!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>compileCogFullBlockMethod: (in category 'compile abstract instructions') -----
  compileCogFullBlockMethod: numCopied
+ 	<option: #SistaV1BytecodeSet>
  	methodOrBlockNumTemps := coInterpreter tempCountOf: methodObj.
  	self cCode: '' inSmalltalk:
  		[debugStackPointers := coInterpreter debugStackPointersFor: methodObj].
  	^super compileCogFullBlockMethod: numCopied!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>compileFullBlockMethodFrameBuild: (in category 'compile abstract instructions') -----
  compileFullBlockMethodFrameBuild: numCopied
+ 	<option: #SistaV1BytecodeSet>
  	needsFrame ifFalse:
  		[self initSimStackForFramelessMethod: initialPC.
  		 ^self].
  	super compileFullBlockMethodFrameBuild: numCopied.
  	self initSimStackForFramefulMethod: initialPC!



More information about the Vm-dev mailing list