ClementBera uploaded a new version of VMMaker to project VM Maker: http://source.squeak.org/VMMaker/VMMaker.oscog-cb.1954.mcz
==================== Summary ====================
Name: VMMaker.oscog-cb.1954 Author: cb Time: 29 September 2016, 12:09:23.749488 pm UUID: 34c89fe5-922b-4d01-b2cc-14bd416b3673 Ancestors: VMMaker.oscog-eem.1953
Fixed a bug in the SistaCogit mustBeboolean handling which confused the mcpc to bcpc mapping, forbidding counters to trip correctly.
=============== Diff against VMMaker.oscog-eem.1953 ===============
Item was changed: ----- Method: SistaCogit>>genJumpIf:to: (in category 'bytecode generator support') ----- genJumpIf: boolean to: targetBytecodePC "The heart of performance counting in Sista. Conditional branches are 6 times less frequent than sends and can provide basic block frequencies (send counters can't). Each conditional has a 32-bit counter split into an upper 16 bits counting executions and a lower half counting untaken executions of the branch. Executing the branch decrements the upper half, tripping if the count goes negative. Not taking the branch decrements the lower half. N.B. We *do not* eliminate dead branches (true ifTrue:/true ifFalse:) so that scanning for send and branch data is simplified and that branch data is correct." <inline: false> | ok counterAddress countTripped retry nextPC nextDescriptor desc | <var: #ok type: #'AbstractInstruction *'> <var: #desc type: #'CogSimStackEntry *'> <var: #retry type: #'AbstractInstruction *'> <var: #countTripped type: #'AbstractInstruction *'> <var: #nextDescriptor type: #'BytecodeDescriptor *'>
"In optimized code we don't generate counters to improve performance" (coInterpreter isOptimizedMethod: methodObj) ifTrue: [ ^ super genJumpIf: boolean to: targetBytecodePC ]. "If the branch is reached only for the counter trip trampoline (typically, var1 == var2 ifTrue: falls through to the branch only for the trampoline) we generate a specific path to drastically reduce the number of machine instructions" branchReachedOnlyForCounterTrip ifTrue: [ branchReachedOnlyForCounterTrip := false. ^ self genCounterTripOnlyJumpIf: boolean to: targetBytecodePC ]. "We detect and: / or:, if found, we don't generate the counters to avoid pathological counter slow down" boolean == objectMemory falseObject ifTrue: [ nextPC := bytecodePC + (self generatorAt: byte0) numBytes. nextDescriptor := self generatorAt: (objectMemory fetchByte: nextPC ofObject: methodObj) + bytecodeSetOffset. nextDescriptor generator == #genPushConstantTrueBytecode ifTrue: [ ^ super genJumpIf: boolean to: targetBytecodePC ]. nextDescriptor := self generatorAt: (objectMemory fetchByte: targetBytecodePC ofObject: methodObj) + bytecodeSetOffset. nextDescriptor generator == #genPushConstantFalseBytecode ifTrue: [ ^ super genJumpIf: boolean to: targetBytecodePC ]. ].
extA := 0. "We ignore the noMustBeBoolean flag. It should not be present in methods with counters, and if it is we don't care."
"We don't generate counters on branches on true/false, the basicblock usage can be inferred" desc := self ssTop. (desc type == SSConstant and: [desc constant = objectMemory trueObject or: [desc constant = objectMemory falseObject]]) ifTrue: [ ^ super genJumpIf: boolean to: targetBytecodePC ]. self ssFlushTo: simStackPtr - 1. desc popToReg: TempReg. self ssPop: 1.
"We need SendNumArgsReg because of the mustBeBooleanTrampoline" self ssAllocateRequiredReg: SendNumArgsReg.
retry := self Label. self genExecutionCountLogicInto: [ :cAddress :countTripBranch | counterAddress := cAddress. countTripped := countTripBranch ] counterReg: SendNumArgsReg. counterIndex := counterIndex + 1.
"Cunning trick by LPD. If true and false are contiguous subtract the smaller. Correct result is either 0 or the distance between them. If result is not 0 or their distance send mustBeBoolean." self assert: (objectMemory objectAfter: objectMemory falseObject) = objectMemory trueObject. self genSubConstant: boolean R: TempReg. self JumpZero: (self ensureFixupAt: targetBytecodePC - initialPC).
self genFallsThroughCountLogicCounterReg: SendNumArgsReg counterAddress: counterAddress.
self CmpCq: (boolean == objectMemory falseObject ifTrue: [objectMemory trueObject - objectMemory falseObject] ifFalse: [objectMemory falseObject - objectMemory trueObject]) R: TempReg. ok := self JumpZero: 0. self MoveCq: 0 R: SendNumArgsReg. "if counterReg is 0 this is a mustBeBoolean, not a counter trip." countTripped jmpTarget: (self CallRT: (boolean == objectMemory falseObject ifTrue: [ceSendMustBeBooleanAddFalseTrampoline] ifFalse: [ceSendMustBeBooleanAddTrueTrampoline])). "If we're in an image which hasn't got the Sista code loaded then the ceCounterTripped: trampoline will return directly to machine code, returning the boolean. So the code should jump back to the retry point. The trampoline makes sure that TempReg has been reloaded." + self annotateBytecode: self Label. "For some reason if I write self annotateBytecode: (self Jump: retry) the annotation is not at the correct place." + self Jump: retry. - self annotateBytecode: (self Jump: retry). ok jmpTarget: self Label. ^0!
vm-dev@lists.squeakfoundation.org