Eliot Miranda uploaded a new version of VMMaker to project VM Maker: http://source.squeak.org/VMMaker/VMMaker.oscog-eem.2642.mcz ==================== Summary ==================== Name: VMMaker.oscog-eem.2642 Author: eem Time: 28 December 2019, 1:07:48.41918 pm UUID: 9a197bc5-dc28-4df3-9518-9ddd8be37d03 Ancestors: VMMaker.oscog-eem.2641 Cogit: Small simpliofication to context creation. =============== Diff against VMMaker.oscog-eem.2641 =============== Item was changed: ----- Method: CogObjectRepresentationForSpur>>genGetActiveContextLarge:inBlock: (in category 'initialization') ----- genGetActiveContextLarge: isLarge inBlock: isInBlock "Create a trampoline to answer the active context that will answer it if a frame is already married, and create it otherwise. Assume numArgs is in SendNumArgsReg and ClassReg is free." | header slotSize jumpSingle loopHead jumpNeedScavenge continuation exit | <var: #jumpNeedScavenge type: #'AbstractInstruction *'> <var: #continuation type: #'AbstractInstruction *'> <var: #jumpSingle type: #'AbstractInstruction *'> <var: #loopHead type: #'AbstractInstruction *'> <var: #exit type: #'AbstractInstruction *'> + cogit - cogit "load the flag; stash it in both TempReg & ClassReg; do the compare (a prime candidated for use of AndCq:R:R:)" MoveMw: FoxMethod r: FPReg R: ClassReg; + TstCq: MFMethodFlagHasContextFlag R: ClassReg. - AndCq: MFMethodFlagHasContextFlag R: ClassReg R: TempReg. jumpSingle := cogit JumpZero: 0. "jump if flag bit not set" cogit "since the flag bit was set, get the context in the receiver reg and return" MoveMw: FoxThisContext r: FPReg R: ReceiverResultReg; RetN: 0. jumpSingle jmpTarget: cogit Label. "OK, it doesn't exist; instantiate and initialize it" "set the hasContext flag; See CoInterpreter class>>initializeFrameIndices" cogit OrCq: MFMethodFlagHasContextFlag R: ClassReg; MoveR: ClassReg Mw: FoxMethod r: FPReg. "now get the home CogMethod into ClassReg and save for post-instantiation." isInBlock caseOf: { [InFullBlock] -> [cogit SubCq: 3 R: ClassReg]. "-3 is -(hasContext+isBlock) flags" [InVanillaBlock] -> [cogit SubCq: 3 R: ClassReg; "-3 is -(hasContext+isBlock) flags" MoveM16: 0 r: ClassReg R: TempReg; SubR: TempReg R: ClassReg]. [0] -> [cogit SubCq: 1 R: ClassReg]. "-1 is hasContext flag" }. "instantiate the context..." slotSize := isLarge ifTrue: [LargeContextSlots] ifFalse: [SmallContextSlots]. header := objectMemory headerForSlots: slotSize format: objectMemory indexablePointersFormat classIndex: ClassMethodContextCompactIndex. self flag: #endianness. cogit MoveAw: objectMemory freeStartAddress R: ReceiverResultReg. self genStoreHeader: header intoNewInstance: ReceiverResultReg using: TempReg. cogit MoveR: ReceiverResultReg R: TempReg; AddCq: (objectMemory smallObjectBytesForSlots: slotSize) R: TempReg; MoveR: TempReg Aw: objectMemory freeStartAddress; CmpCq: objectMemory getScavengeThreshold R: TempReg. jumpNeedScavenge := cogit JumpAboveOrEqual: 0. "Now initialize the fields of the context. See CoInterpreter>>marryFrame:SP:copyTemps:" "sender gets frame pointer as a SmallInteger" continuation := cogit MoveR: FPReg R: TempReg. self genSetSmallIntegerTagsIn: TempReg. cogit MoveR: TempReg Mw: objectMemory baseHeaderSize + (SenderIndex * objectMemory bytesPerOop) r: ReceiverResultReg. "pc gets frame caller as a SmallInteger" cogit MoveMw: FoxSavedFP r: FPReg R: TempReg. self genSetSmallIntegerTagsIn: TempReg. cogit MoveR: TempReg Mw: objectMemory baseHeaderSize + (InstructionPointerIndex * objectMemory bytesPerOop) r: ReceiverResultReg. "Set the method field, freeing up ClassReg again, and frame's context field," cogit MoveMw: (cogit offset: CogMethod of: #methodObject) r: ClassReg R: TempReg; MoveR: TempReg Mw: objectMemory baseHeaderSize + (MethodIndex * objectMemory wordSize) r: ReceiverResultReg; MoveR: ReceiverResultReg Mw: FoxThisContext r: FPReg. "Now compute stack pointer; this is stackPointer (- 1 for return pc if a CISC) - framePointer - wordSize (1 each for saved pc, method, context, receiver) + 1 (1-relative) + numArgs" "TPR note - the code here is actually doing context stackPointer := ((((fp - sp) / wordSize) - [3|4]) + num args) asSmallInteger" cogit SubR: SPReg R: FPReg R: TempReg; "TempReg := FPReg - SPReg" LogicalShiftRightCq: self log2BytesPerWord R: TempReg; SubCq: (cogit backEnd hasLinkRegister ifTrue: [3] ifFalse: [4]) R: TempReg; AddR: SendNumArgsReg R: TempReg. self genConvertIntegerToSmallIntegerInReg: TempReg. cogit MoveR: TempReg Mw: objectMemory baseHeaderSize + (StackPointerIndex * objectMemory bytesPerOop) r: ReceiverResultReg. "Set closureOrNil to either the stacked receiver or nil" isInBlock > 0 ifTrue: [cogit MoveR: SendNumArgsReg R: TempReg; AddCq: 2 R: TempReg; "+2 for saved fp and saved pc" MoveXwr: TempReg R: FPReg R: TempReg] ifFalse: [cogit genMoveNilR: TempReg]. cogit MoveR: TempReg Mw: objectMemory baseHeaderSize + (ClosureIndex * objectMemory bytesPerOop) r: ReceiverResultReg. "Set the receiver" cogit MoveMw: FoxMFReceiver r: FPReg R: TempReg; MoveR: TempReg Mw: objectMemory baseHeaderSize + (ReceiverIndex * objectMemory bytesPerOop) r: ReceiverResultReg. "Now copy the arguments. This is tricky because of the shortage of registers,. ClassReg ranges from 1 to numArgs (SendNumArgsReg), and from ReceiverIndex + 1 to ReceiverIndex + numArgs. 1 to: numArgs do: [:i| temp := longAt(FPReg + ((SendNumArgs - i + 2) * wordSize)). +2 for saved pc and savedfp longAtput(FPReg + FoxMFReceiver + (i * wordSize), temp)]" "TPR note: this is a prime candidate for passing off to the backend to do at least faintly optimal code" cogit MoveCq: 1 R: ClassReg. loopHead := cogit CmpR: SendNumArgsReg R: ClassReg. exit := cogit JumpGreater: 0. cogit MoveR: SendNumArgsReg R: TempReg; SubR: ClassReg R: TempReg; AddCq: 2 R: TempReg; "+2 for saved fp and saved pc" MoveXwr: TempReg R: FPReg R: TempReg; AddCq: ReceiverIndex + (objectMemory baseHeaderSize / objectMemory wordSize) R: ClassReg; "Now convert ClassReg from frame index to context index" MoveR: TempReg Xwr: ClassReg R: ReceiverResultReg; SubCq: ReceiverIndex + (objectMemory baseHeaderSize / objectMemory wordSize) - 1 R: ClassReg; "convert back adding 1 ;-)" Jump: loopHead. exit jmpTarget: cogit Label. "Finally nil or copy the non-argument temps. ClassReg := FPReg + FoxMFReceiver. SendNumArgsReg := SendNumArgsReg+ReceiverIndex. [ClassReg := ClassReg - wordSize. backEnd hasLinkRegister ifTrue: [ClassReg > SPReg] ifFalse: [ClassReg >= SPReg]] whileTrue: [receiver[SendNumArgsReg] := *ClassReg. SendNumArgsReg := SendNumArgsReg + 1]]" coInterpreter marryFrameCopiesTemps ifFalse: [cogit MoveCq: objectMemory nilObject R: TempReg]. cogit MoveR: FPReg R: ClassReg; AddCq: FoxMFReceiver R: ClassReg; AddCq: ReceiverIndex + 1 + (objectMemory baseHeaderSize / objectMemory wordSize) R: SendNumArgsReg. loopHead := cogit SubCq: objectMemory wordSize R: ClassReg. cogit CmpR: ClassReg R: SPReg. "If on a CISC there's a retpc for the trampoline call on top of stack; if on a RISC there isn't." exit := cogit backEnd hasLinkRegister ifTrue: [cogit JumpAboveOrEqual: 0] ifFalse: [cogit JumpBelow: 0]. coInterpreter marryFrameCopiesTemps ifTrue: [cogit MoveMw: 0 r: ClassReg R: TempReg]. cogit MoveR: TempReg Xwr: SendNumArgsReg R: ReceiverResultReg; AddCq: 1 R: SendNumArgsReg; Jump: loopHead. exit jmpTarget: cogit Label. cogit RetN: 0. jumpNeedScavenge jmpTarget: cogit Label. cogit backEnd saveAndRestoreLinkRegAround: [cogit CallRT: ceScheduleScavengeTrampoline registersToBeSavedMask: (cogit registerMaskFor: ReceiverResultReg and: SendNumArgsReg and: ClassReg)]. cogit Jump: continuation. ^0! |
Free forum by Nabble | Edit this page |