Eliot Miranda uploaded a new version of VMMaker to project VM Maker: http://source.squeak.org/VMMaker/VMMaker.oscog-eem.1751.mcz
==================== Summary ====================
Name: VMMaker.oscog-eem.1751 Author: eem Time: 1 January 1970, 3:02:52.225589 pm UUID: 1ae8a7b7-5497-4eba-9511-198cc5aa7485 Ancestors: VMMaker.oscog-cb.1750
Revise the IMMUTABILITY store check to remove the need for the branch around the setting of TempReg with the inst var index. By having ceStoreTrampoline repeat the immutability test it doesn't care about the value of TempReg in the store check case and so we don't need to jump around the instruction that sets TempReg. This reduces the store check by a further 2 byte instruction. Clément, if you hate this we can back out of it, but I thought I'd commit it all the same.
Simulator: Fix casting in the JIT simulator for the recent integer conversion routine modifications.
=============== Diff against VMMaker.oscog-cb.1750 ===============
Item was changed: ----- Method: CogObjectRepresentationForSpur>>genStoreTrampolineCalled: (in category 'initialization') ----- genStoreTrampolineCalled: trampolineName "This can be entered in one of two states, depending on TempReg. TempReg = 0 => store check TempReg > 0 => immutability failure TempReg holds index + 1 in this case as the value 0 is reserved for store checks. In addition the 0 value is convenient to save one instruction for store checks." | jumpSC | <option: #IMMUTABILITY> <var: #trampolineName type: #'char *'> <var: #jumpSC type: #'AbstractInstruction *'> <inline: false> cogit zeroOpcodeIndex. + cogit PushR: SendNumArgsReg. + jumpSC := self genJumpMutable: ReceiverResultReg scratchReg: SendNumArgsReg. + cogit PopR: SendNumArgsReg. - cogit CmpCq: 0 R: TempReg. - jumpSC := cogit JumpZero: 0. - - "CannotAssignTo:, we restore the index." - cogit SubCq: 1 R: TempReg. cogit compileTrampolineFor: #ceCannotAssignTo:withIndex:valueToAssign: numArgs: 3 arg: ReceiverResultReg arg: TempReg arg: ClassReg arg: nil regsToSave: cogit emptyRegisterMask pushLinkReg: true resultReg: NoReg. "Store check" + jumpSC jmpTarget: (cogit PopR: SendNumArgsReg). - jumpSC jmpTarget: cogit Label. ^ cogit genTrampolineFor: #remember: called: trampolineName numArgs: 1 arg: ReceiverResultReg arg: nil arg: nil arg: nil regsToSave: cogit emptyRegisterMask pushLinkReg: true resultReg: NoReg appendOpcodes: true!
Item was changed: ----- Method: CogObjectRepresentationForSpur>>genStoreWithImmutabilityAndStoreCheckSourceReg:slotIndex:destReg:scratchReg:needRestoreRcvr: (in category 'compile abstract instructions') ----- genStoreWithImmutabilityAndStoreCheckSourceReg: sourceReg slotIndex: index destReg: destReg scratchReg: scratchReg needRestoreRcvr: needRestoreRcvr "Store check code is duplicated to use a single trampoline" + | immutableJump jmpImmediate jmpDestYoung jmpSourceOld rememberedBitByteOffset jmpAlreadyRemembered mask | <var: #immutableJump type: #'AbstractInstruction *'> - <var: #trampJump type: #'AbstractInstruction *'> <var: #jmpImmediate type: #'AbstractInstruction *'> <var: #jmpDestYoung type: #'AbstractInstruction *'> <var: #jmpSourceOld type: #'AbstractInstruction *'> <var: #jmpAlreadyRemembered type: #'AbstractInstruction *'> + - | immutableJump trampJump jmpImmediate jmpDestYoung jmpSourceOld rememberedBitByteOffset jmpAlreadyRemembered mask | - immutableJump := self genJumpImmutable: destReg scratchReg: scratchReg. cogit genTraceStores. "do the store" cogit MoveR: sourceReg Mw: index * objectMemory wordSize + objectMemory baseHeaderSize r: destReg. "store check" jmpImmediate := self genJumpImmediate: sourceReg. "Get the old/new boundary in scratchReg" cogit MoveCw: objectMemory storeCheckBoundary R: scratchReg. "Is target young? If so we're done" cogit CmpR: scratchReg R: destReg. "N.B. FLAGS := destReg - scratchReg" jmpDestYoung := cogit JumpBelow: 0. "Is value stored old? If so we're done." cogit CmpR: scratchReg R: sourceReg. "N.B. FLAGS := valueReg - scratchReg" jmpSourceOld := cogit JumpAboveOrEqual: 0. "value is young and target is old. Need to remember this only if the remembered bit is not already set. Test the remembered bit. Only need to fetch the byte containing it, which reduces the size of the mask constant." rememberedBitByteOffset := jmpSourceOld isBigEndian ifTrue: [objectMemory baseHeaderSize - 1 - (objectMemory rememberedBitShift // 8)] ifFalse:[objectMemory rememberedBitShift // 8]. mask := 1 << (objectMemory rememberedBitShift \ 8). cogit MoveMb: rememberedBitByteOffset r: destReg R: scratchReg. cogit AndCq: mask R: scratchReg. jmpAlreadyRemembered := cogit JumpNonZero: 0. + "Set the inst var index for the benefit of the immutability check. The trampoline will + repeat the check to choose between the immutbality violation and the store check." + immutableJump jmpTarget: (cogit MoveCq: index R: scratchReg). + cogit CallRT: ceStoreTrampoline. - "We know scratchReg now holds 0, this is convenient because the trampoline - convention expects 0 for store check in scratchReg. What a coincidence ;-)" - "Remembered bit is not set. Call store check to insert dest into remembered table." - trampJump := cogit Jump: 0. - "Here we reach the trampoline for Immutability failure" - immutableJump jmpTarget: (cogit MoveCq: index + 1 R: scratchReg). "index + 1 as 0 is reserved for store checks" - trampJump jmpTarget: (cogit CallRT: ceStoreTrampoline). cogit annotateBytecode: cogit Label. needRestoreRcvr ifTrue: [ cogit putSelfInReceiverResultReg ].
jmpImmediate jmpTarget: (jmpDestYoung jmpTarget: (jmpSourceOld jmpTarget: (jmpAlreadyRemembered jmpTarget: cogit Label))). ^ 0!
Item was changed: ----- Method: CogObjectRepresentationForSpur>>genStoreWithImmutabilityButNoStoreCheckSourceReg:slotIndex:destReg:scratchReg:needRestoreRcvr: (in category 'compile abstract instructions') ----- genStoreWithImmutabilityButNoStoreCheckSourceReg: sourceReg slotIndex: index destReg: destReg scratchReg: scratchReg needRestoreRcvr: needRestoreRcvr
<var: #mutableJump type: #'AbstractInstruction *'> <var: #immutabilityFailure type: #'AbstractInstruction *'> | immutabilityFailure mutableJump | "imm check has its own trampoline" mutableJump := self genJumpMutable: destReg scratchReg: scratchReg. + cogit MoveCq: index R: TempReg. - cogit MoveCq: index + 1 R: TempReg. "index + 1 as 0 is reserved for store checks" cogit CallRT: ceStoreTrampoline. cogit annotateBytecode: cogit Label. needRestoreRcvr ifTrue: [ cogit putSelfInReceiverResultReg ]. immutabilityFailure := cogit Jump: 0. mutableJump jmpTarget: cogit Label.
cogit genTraceStores. "do the store" cogit MoveR: sourceReg Mw: index * objectMemory wordSize + objectMemory baseHeaderSize r: destReg. immutabilityFailure jmpTarget: cogit Label.
^ 0!
Item was changed: ----- Method: CogVMSimulator>>cCoerceSimple:to: (in category 'translation support') ----- cCoerceSimple: value to: cTypeString "Type coercion for translation and simulation. For simulation answer a suitable surrogate for the struct types" + ^cTypeString + caseOf: + { [#'CogMethod *'] -> [cogit cogMethodSurrogateAt: value asUnsignedInteger]. + [#'CogBlockMethod *'] -> [cogit cogBlockMethodSurrogateAt: value asUnsignedInteger]. + [#'NSSendCache *'] -> [cogit nsSendCacheSurrogateAt: value asUnsignedInteger] } + otherwise: [value]! - ^cTypeString caseOf: - { [#'char *'] -> [value]. - [#'void *'] -> [value]. - [#sqInt] -> [value]. - [#'void (*)()'] -> [value]. - [#'void (*)(void)'] -> [value]. - [#'CogMethod *'] -> [cogit cogMethodSurrogateAt: value asUnsignedInteger]. - [#'CogBlockMethod *'] -> [cogit cogBlockMethodSurrogateAt: value asUnsignedInteger]. - [#'NSSendCache *'] -> [cogit nsSendCacheSurrogateAt: value asUnsignedInteger]. }!
vm-dev@lists.squeakfoundation.org