Eliot Miranda uploaded a new version of VMMaker to project VM Maker: http://source.squeak.org/VMMaker/VMMaker.oscog-eem.1333.mcz
==================== Summary ====================
Name: VMMaker.oscog-eem.1333 Author: eem Time: 3 June 2015, 8:51:47.115 am UUID: bc9001c2-8816-4b4e-bf91-8e11cad6ed6b Ancestors: VMMaker.oscog-eem.1332
Cogit: Fix assert-fails with absent receiver sends in Newspeak. Have the implicit and outer send lookup trampolines set the stacked receiver (when there is one) when setting the implciit receiver.
Streamline send trampoline creation by refactoring trampoline name generation so that the two limits, NumSendTrampolines - 2 and numRegArgs are treated separately, and numArgsOrSendNumArgsReg: answers the relevant numArgs argument. This should clear up confusion between numRegArgs (which can be 0, 1 & 2) and NumSendTrampolines - 2, which is always 2.
=============== Diff against VMMaker.oscog-eem.1332 ===============
Item was changed: ----- Method: Cogit>>genNSSendTrampolineFor:numArgs:called: (in category 'initialization') ----- genNSSendTrampolineFor: aRoutine numArgs: numArgs called: aString "ReceiverResultReg: method receiver SendNumArgsReg: the NSSendCache cache" <option: #NewspeakVM> <var: #aRoutine type: #'void *'> <var: #aString type: #'char *'> | jumpMiss jumpItsTheReceiverStupid | <var: #jumpMiss type: #'AbstractInstruction *'> <var: #jumpItsTheReceiverStupid type: #'AbstractInstruction *'> opcodeIndex := 0. objectRepresentation genGetInlineCacheClassTagFrom: ReceiverResultReg into: ClassReg forEntry: false. self MoveMw: NSCClassTagIndex * objectMemory wordSize r: SendNumArgsReg R: TempReg. self CmpR: ClassReg R: TempReg. jumpMiss := self JumpNonZero: 0. self MoveMw: NSCEnclosingObjectIndex * objectMemory wordSize r: SendNumArgsReg R: TempReg. self CmpCq: 0 R: TempReg. jumpItsTheReceiverStupid := self JumpZero: 0. self MoveR: TempReg R: ReceiverResultReg. + "Now set the stacked receiver, if needed. If there are reg args this is + not required; see genPushRegisterArgsForNumArgs:numArgs: below." + (self numRegArgs = 0 or: [numArgs > self numRegArgs]) ifTrue: + [numArgs >= (NumSendTrampolines - 1) + ifTrue: "arbitrary argument count" + [self MoveMw: NSCNumArgsIndex * objectMemory wordSize r: SendNumArgsReg R: TempReg. + backEnd hasLinkRegister ifFalse: + [self AddCq: 1 R: TempReg].. + self MoveR: ReceiverResultReg Xwr: TempReg R: SPReg] + ifFalse: "Known argument count" + [self MoveR: TempReg Mw: (backEnd hasLinkRegister ifTrue: [0] ifFalse: [1]) + numArgs * objectMemory wordSize r: SPReg]]. - "We don't patch stack(-numArgs). See comment in ceImplicitReceiverSend:receiver:" jumpItsTheReceiverStupid jmpTarget: self Label. self MoveMw: NSCTargetIndex * objectMemory wordSize r: SendNumArgsReg R: TempReg. self JumpR: TempReg.
jumpMiss jmpTarget: self Label. objectRepresentation genEnsureObjInRegNotForwarded: ReceiverResultReg scratchReg: TempReg updatingMw: FoxMFReceiver r: FPReg. self numRegArgs > 0 ifTrue: [backEnd genPushRegisterArgsForNumArgs: numArgs scratchReg: TempReg]. ^self genTrampolineFor: aRoutine called: aString numArgs: 2 arg: SendNumArgsReg "The NSSendCache" arg: ReceiverResultReg arg: nil arg: nil saveRegs: false pushLinkReg: true resultReg: ReceiverResultReg "Never happens?" appendOpcodes: true!
Item was changed: ----- Method: Cogit>>generateNewspeakSendTrampolines (in category 'initialization') ----- generateNewspeakSendTrampolines "Self send, dynamic super send, implicit receiver send, and outer send" <option: #NewspeakVM> + 0 to: NumSendTrampolines - 1 do: - 0 to: NumSendTrampolines - 2 do: [:numArgs| selfSendTrampolines at: numArgs put: (self genTrampolineFor: #ceSelfSend:to:numArgs: called: (self trampolineName: 'ceSelfSend' numArgs: numArgs) arg: ClassReg arg: ReceiverResultReg + arg: (self numArgsOrSendNumArgsReg: numArgs))]. - arg: numArgs)]. - selfSendTrampolines - at: NumSendTrampolines - 1 - put: (self genTrampolineFor: #ceSelfSend:to:numArgs: - called: (self trampolineName: 'ceSelfSend' numArgs: -1) - arg: ClassReg - arg: ReceiverResultReg - arg: SendNumArgsReg).
+ 0 to: NumSendTrampolines - 1 do: - 0 to: NumSendTrampolines - 2 do: [:numArgs| dynamicSuperSendTrampolines at: numArgs put: (self genTrampolineFor: #ceDynamicSuperSend:to:numArgs: called: (self trampolineName: 'ceDynSuperSend' numArgs: numArgs) arg: ClassReg arg: ReceiverResultReg + arg: (self numArgsOrSendNumArgsReg: numArgs))]. - arg: numArgs)]. - dynamicSuperSendTrampolines - at: NumSendTrampolines - 1 - put: (self genTrampolineFor: #ceDynamicSuperSend:to:numArgs: - called: (self trampolineName: 'ceDynSuperSend' numArgs: -1) - arg: ClassReg - arg: ReceiverResultReg - arg: SendNumArgsReg).
+ 0 to: NumSendTrampolines - 1 do: - 0 to: NumSendTrampolines - 2 do: [:numArgs| implicitReceiverSendTrampolines at: numArgs put: (self genNSSendTrampolineFor: #ceImplicitReceiverSend:receiver: numArgs: numArgs called: (self trampolineName: 'ceImplicitReceiverSend' numArgs: numArgs))]. - implicitReceiverSendTrampolines - at: NumSendTrampolines - 1 - put: (self - genNSSendTrampolineFor: #ceImplicitReceiverSend:receiver: - numArgs: self numRegArgs + 1 - called: (self trampolineName: 'ceImplicitReceiverSend' numArgs: -1)).
+ 0 to: NumSendTrampolines - 1 do: - 0 to: NumSendTrampolines - 2 do: [:numArgs| outerSendTrampolines at: numArgs put: (self genNSSendTrampolineFor: #ceOuterSend:receiver: numArgs: numArgs called: (self trampolineName: 'ceOuterSend' numArgs: numArgs))]. - outerSendTrampolines - at: NumSendTrampolines - 1 - put: (self - genNSSendTrampolineFor: #ceOuterSend:receiver: - numArgs: self numRegArgs + 1 - called: (self trampolineName: 'ceOuterSend' numArgs: -1)).
!
Item was changed: ----- Method: Cogit>>generateSendTrampolines (in category 'initialization') ----- generateSendTrampolines + 0 to: NumSendTrampolines - 1 do: - 0 to: NumSendTrampolines - 2 do: [:numArgs| ordinarySendTrampolines at: numArgs put: (self genTrampolineFor: #ceSend:super:to:numArgs: called: (self trampolineName: 'ceSend' numArgs: numArgs) arg: ClassReg arg: 0 arg: ReceiverResultReg + arg: (self numArgsOrSendNumArgsReg: numArgs))]. - arg: numArgs)]. - ordinarySendTrampolines - at: NumSendTrampolines - 1 - put: (self genTrampolineFor: #ceSend:super:to:numArgs: - called: (self trampolineName: 'ceSend' numArgs: -1) - arg: ClassReg - arg: 0 - arg: ReceiverResultReg - arg: SendNumArgsReg).
"Generate these in the middle so they are within [firstSend, lastSend]." self cppIf: NewspeakVM ifTrue: [self generateNewspeakSendTrampolines]. self cppIf: BytecodeSetHasDirectedSuperSend ifTrue: + [0 to: NumSendTrampolines - 1 do: - [0 to: NumSendTrampolines - 2 do: [:numArgs| directedSuperSendTrampolines at: numArgs put: (self genTrampolineFor: #ceSend:above:to:numArgs: called: (self trampolineName: 'ceDirectedSuperSend' numArgs: numArgs) arg: ClassReg arg: TempReg arg: ReceiverResultReg + arg: (self numArgsOrSendNumArgsReg: numArgs))]]. - arg: numArgs)]. - directedSuperSendTrampolines - at: NumSendTrampolines - 1 - put: (self genTrampolineFor: #ceSend:above:to:numArgs: - called: (self trampolineName: 'ceDirectedSuperSend' numArgs: -1) - arg: ClassReg - arg: TempReg - arg: ReceiverResultReg - arg: SendNumArgsReg)].
+ 0 to: NumSendTrampolines - 1 do: - 0 to: NumSendTrampolines - 2 do: [:numArgs| superSendTrampolines at: numArgs put: (self genTrampolineFor: #ceSend:super:to:numArgs: called: (self trampolineName: 'ceSuperSend' numArgs: numArgs) arg: ClassReg arg: 1 arg: ReceiverResultReg + arg: (self numArgsOrSendNumArgsReg: numArgs))]. - arg: numArgs)]. - superSendTrampolines - at: NumSendTrampolines - 1 - put: (self genTrampolineFor: #ceSend:super:to:numArgs: - called: (self trampolineName: 'ceSuperSend' numArgs: -1) - arg: ClassReg - arg: 1 - arg: ReceiverResultReg - arg: SendNumArgsReg). firstSend := ordinarySendTrampolines at: 0. lastSend := superSendTrampolines at: NumSendTrampolines - 1!
Item was added: + ----- Method: Cogit>>numArgsOrSendNumArgsReg: (in category 'initialization') ----- + numArgsOrSendNumArgsReg: numArgs + "The send trampolines have different versions for different arg counts, with special + cases for 0 through NumSendTrampolines - 2, and a general case for more, passing + the arg count in SendNumArgsReg. This computes the relevant argument." + <inline: true> + ^numArgs <= (NumSendTrampolines - 2) ifTrue: [numArgs] ifFalse: [SendNumArgsReg]!
Item was changed: ----- Method: Cogit>>trampolineName:numArgs: (in category 'initialization') ----- trampolineName: routinePrefix numArgs: numArgs + ^self trampolineName: routinePrefix numArgs: numArgs limit: NumSendTrampolines - 2! - "Malloc a string with the contents for the trampoline table" - <returnTypeC: #'char *'> - <var: #routinePrefix type: #'char *'> - | theString | - <var: #theString type: #'char *'> - self cCode: '' inSmalltalk: - [^routinePrefix, (numArgs >= 0 ifTrue: [numArgs printString] ifFalse: ['N']), 'Args']. - theString := self malloc: (self strlen: routinePrefix) + 6. - self s: theString pr: '%s%cArgs' in: routinePrefix tf: (numArgs >= 0 ifTrue: [$0 + numArgs] ifFalse: [$N]). - ^theString!
Item was added: + ----- Method: Cogit>>trampolineName:numArgs:limit: (in category 'initialization') ----- + trampolineName: routinePrefix numArgs: numArgs limit: argsLimit + "Malloc a string with the contents for the trampoline table" + <inline: true> + <returnTypeC: #'char *'> + <var: #routinePrefix type: #'char *'> + | theString | + <var: #theString type: #'char *'> + self cCode: '' inSmalltalk: + [^routinePrefix, (numArgs <= argsLimit ifTrue: [numArgs printString] ifFalse: ['N']), 'Args']. + theString := self malloc: (self strlen: routinePrefix) + 6. + self s: theString pr: '%s%cArgs' in: routinePrefix tf: (numArgs <= argsLimit ifTrue: [$0 + numArgs] ifFalse: [$N]). + ^theString!
Item was added: + ----- Method: Cogit>>trampolineName:numRegArgs: (in category 'initialization') ----- + trampolineName: routinePrefix numRegArgs: numArgs + ^self trampolineName: routinePrefix numArgs: numArgs limit: self numRegArgs!
Item was changed: ----- Method: SimpleStackBasedCogit>>genSendAbsentImplicitOrOuter:numArgs:depth:sendTable: (in category 'bytecode generators') ----- genSendAbsentImplicitOrOuter: selector numArgs: numArgs depth: depth sendTable: sendTable <var: #sendTable type: #'sqInt *'> | nsSendCache | (objectMemory isYoung: selector) ifTrue: [hasYoungReferent := true].
nsSendCache := theIRCs + (NumOopsPerNSC * objectMemory bytesPerOop * indexOfIRC). indexOfIRC := indexOfIRC + 1. self assert: (objectMemory isInOldSpace: nsSendCache). self initializeNSSendCache: nsSendCache selector: selector numArgs: numArgs depth: depth.
+ "This leaves the method receiver on the stack, which might not be the implicit receiver. + But the lookup trampoline will establish the on-stack receiver once it locates it." - "This leaves the method receiver on the stack, which might not be the implicit receiver. But we care - not: the callee will use ReceiverResultReg to build its frame, not the value beneath the arguments." self marshallAbsentReceiverSendArguments: numArgs.
"Load the cache last so it is a fixed distance from the call." self MoveCw: nsSendCache R: SendNumArgsReg. self CallNewspeakSend: (sendTable at: (numArgs min: NumSendTrampolines - 1)).
self PushR: ReceiverResultReg. ^0!
Item was changed: ----- Method: StackToRegisterMappingCogit>>genCallPICEnilopmartNumArgs: (in category 'initialization') ----- genCallPICEnilopmartNumArgs: numArgs "Generate special versions of the ceCallCogCodePopReceiverAndClassRegs enilopmart that also pop register args from the stack to undo the pushing of register args in the abort/miss trampolines." <returnTypeC: 'void (*genCallPICEnilopmartNumArgs(sqInt numArgs))(void)'> | size endAddress enilopmart | opcodeIndex := 0. backEnd maybeEstablishVarBase. "Must happen first; value may be used in genLoadStackPointers" backEnd genLoadStackPointers. self PopR: ClassReg. "cacheTag" self PopR: TempReg. "entry-point" self PopR: (backEnd hasLinkRegister ifTrue: [LinkReg] ifFalse: [SendNumArgsReg]). "retpc" numArgs > 0 ifTrue: [numArgs > 1 ifTrue: [self PopR: Arg1Reg. self assert: self numRegArgs = 2]. self PopR: Arg0Reg]. self PopR: ReceiverResultReg. backEnd hasLinkRegister ifFalse: [self PushR: SendNumArgsReg]. "retpc" self JumpR: TempReg. self computeMaximumSizes. size := self generateInstructionsAt: methodZoneBase. endAddress := self outputInstructionsAt: methodZoneBase. self assert: methodZoneBase + size = endAddress. enilopmart := methodZoneBase. methodZoneBase := self alignUptoRoutineBoundary: endAddress. backEnd nopsFrom: endAddress to: methodZoneBase - 1. + self recordGeneratedRunTime: (self trampolineName: 'ceCallPIC' numRegArgs: numArgs) address: enilopmart. - self recordGeneratedRunTime: (self trampolineName: 'ceCallPIC' numArgs: numArgs) address: enilopmart. ^self cCoerceSimple: enilopmart to: #'void (*)(void)'!
Item was changed: ----- Method: StackToRegisterMappingCogit>>genMethodAbortTrampolineFor: (in category 'initialization') ----- genMethodAbortTrampolineFor: numArgs "Generate the abort for a method. This abort performs either a call of ceSICMiss: to handle a single-in-line cache miss or a call of ceStackOverflow: to handle a stack overflow. It distinguishes the two by testing ResultReceiverReg. If the register is zero then this is a stack-overflow because a) the receiver has already been pushed and so can be set to zero before calling the abort, and b) the receiver must always contain an object (and hence be non-zero) on SIC miss." | jumpSICMiss | <var: #jumpSICMiss type: #'AbstractInstruction *'> opcodeIndex := 0. self CmpCq: 0 R: ReceiverResultReg. jumpSICMiss := self JumpNonZero: 0.
"The abort sequence has pushed the LinkReg a second time - because a stack overflow can only happen after building a frame, which pushes LinkReg anyway, and we still need to push LinkReg in case we get to this routine from a sendMissAbort. (On ARM there is a simpler way; use two separate abort calls since all instructions are 32-bits but on x86 the zero receiver reg, call methodAbort sequence is smaller; we may fix this one day). Overwrite that duplicate with the right one - the return address for the call to the abort trampoline. The only reason it matters is an assert in ceStackOverflow: uses it" backEnd hasLinkRegister ifTrue: [self MoveR: LinkReg Mw: 0 r: SPReg]. self compileTrampolineFor: #ceStackOverflow: numArgs: 1 arg: SendNumArgsReg arg: nil arg: nil arg: nil saveRegs: false pushLinkReg: false "The LinkReg has already been set above." resultReg: nil. jumpSICMiss jmpTarget: self Label. backEnd genPushRegisterArgsForAbortMissNumArgs: numArgs. ^self genTrampolineFor: #ceSICMiss: + called: (self trampolineName: 'ceMethodAbort' numRegArgs: numArgs) - called: (self trampolineName: 'ceMethodAbort' numArgs: (numArgs <= self numRegArgs ifTrue: [numArgs] ifFalse: [-1])) numArgs: 1 arg: ReceiverResultReg arg: nil arg: nil arg: nil saveRegs: false pushLinkReg: false "The LinkReg will have been pushed in genPushRegisterArgsForAbortMissNumArgs: above." resultReg: nil appendOpcodes: true!
Item was changed: ----- Method: StackToRegisterMappingCogit>>genPICAbortTrampolineFor: (in category 'initialization') ----- genPICAbortTrampolineFor: numArgs "Generate the abort for a PIC. This abort performs either a call of ceInterpretMethodFromPIC:receiver: to handle invoking an uncogged target or a call of ceMNUFromPICMNUMethod:receiver: to handle an MNU dispatch in a closed PIC. It distinguishes the two by testing ClassReg. If the register is zero then this is an MNU." opcodeIndex := 0. backEnd genPushRegisterArgsForAbortMissNumArgs: numArgs. + ^self genInnerPICAbortTrampoline: (self trampolineName: 'cePICAbort' numRegArgs: numArgs)! - ^self genInnerPICAbortTrampoline: (self trampolineName: 'cePICAbort' numArgs: (numArgs <= self numRegArgs ifTrue: [numArgs] ifFalse: [-1]))!
Item was changed: ----- Method: StackToRegisterMappingCogit>>genPICMissTrampolineFor: (in category 'initialization') ----- genPICMissTrampolineFor: numArgs <inline: false> | startAddress | startAddress := methodZoneBase. opcodeIndex := 0. "N.B. a closed PIC jumps to the miss routine, not calls it, so there is only one retpc on the stack." backEnd genPushRegisterArgsForNumArgs: numArgs scratchReg: SendNumArgsReg. self genTrampolineFor: #ceCPICMiss:receiver: + called: (self trampolineName: 'cePICMiss' numRegArgs: numArgs) - called: (self trampolineName: 'cePICMiss' numArgs: (numArgs <= self numRegArgs ifTrue: [numArgs] ifFalse: [-1])) numArgs: 2 arg: ClassReg arg: ReceiverResultReg arg: nil arg: nil saveRegs: false pushLinkReg: true resultReg: nil appendOpcodes: true. ^startAddress!
Item was changed: ----- Method: StackToRegisterMappingCogit>>genSendAbsentImplicitOrOuter:numArgs:depth:sendTable: (in category 'bytecode generators') ----- genSendAbsentImplicitOrOuter: selector numArgs: numArgs depth: depth sendTable: sendTable <var: #sendTable type: #'sqInt *'> | nsSendCache | (objectMemory isYoung: selector) ifTrue: [hasYoungReferent := true].
nsSendCache := theIRCs + (NumOopsPerNSC * objectMemory bytesPerOop * indexOfIRC). indexOfIRC := indexOfIRC + 1. self assert: (objectMemory isInOldSpace: nsSendCache). self initializeNSSendCache: nsSendCache selector: selector numArgs: numArgs depth: depth.
self ssAllocateCallReg: SendNumArgsReg.
+ "This may leave the method receiver on the stack, which might not be the implicit receiver. + But the lookup trampoline will establish an on-stack receiver once it locates it." - "This leaves the method receiver on the stack, which might not be the implicit receiver. But we care - not: the callee will use ReceiverResultReg to build its frame, not the value beneath the arguments." self marshallAbsentReceiverSendArguments: numArgs.
"Load the cache last so it is a fixed distance from the call." self MoveCw: nsSendCache R: SendNumArgsReg. self CallNewspeakSend: (sendTable at: (numArgs min: NumSendTrampolines - 1)).
optStatus isReceiverResultRegLive: false. self ssPushRegister: ReceiverResultReg. ^0!
Item was changed: ----- Method: StackToRegisterMappingCogit>>generateMissAbortTrampolines (in category 'initialization') ----- generateMissAbortTrampolines "Generate the run-time entries for the various method and PIC entry misses and aborts. Read the class-side method trampolines for documentation on the various trampolines" - - "Slang needs these apparently superfluous asSymbol sends." 0 to: self numRegArgs + 1 do: [:numArgs| methodAbortTrampolines at: numArgs put: (self genMethodAbortTrampolineFor: numArgs)]. 0 to: self numRegArgs + 1 do: [:numArgs| picAbortTrampolines at: numArgs put: (self genPICAbortTrampolineFor: numArgs)]. 0 to: self numRegArgs + 1 do: [:numArgs| picMissTrampolines at: numArgs put: (self genPICMissTrampolineFor: numArgs)]!
Item was changed: ----- Method: StackToRegisterMappingCogit>>generateNewspeakSendTrampolines (in category 'initialization') ----- generateNewspeakSendTrampolines + "Self send, dynamic super send, implicit receiver send, and outer send." - "Self send, dynamic super send, and implicit receiver send. TODO: outer send." "Override to generate code to push the register arg(s) for <= numRegArg arity sends." <option: #NewspeakVM> + 0 to: NumSendTrampolines - 1 do: - 0 to: NumSendTrampolines - 2 do: [:numArgs| selfSendTrampolines at: numArgs put: (self genSendTrampolineFor: #ceSelfSend:to:numArgs: numArgs: numArgs called: (self trampolineName: 'ceSelfSend' numArgs: numArgs) arg: ClassReg arg: ReceiverResultReg + arg: (self numArgsOrSendNumArgsReg: numArgs))]. - arg: numArgs)]. - selfSendTrampolines - at: NumSendTrampolines - 1 - put: (self genSendTrampolineFor: #ceSelfSend:to:numArgs: - numArgs: self numRegArgs + 1 - called: (self trampolineName: 'ceSelfSend' numArgs: -1) - arg: ClassReg - arg: ReceiverResultReg - arg: SendNumArgsReg).
+ 0 to: NumSendTrampolines - 1 do: - 0 to: NumSendTrampolines - 2 do: [:numArgs| dynamicSuperSendTrampolines at: numArgs put: (self genSendTrampolineFor: #ceDynamicSuperSend:to:numArgs: numArgs: numArgs called: (self trampolineName: 'ceDynSuperSend' numArgs: numArgs) arg: ClassReg arg: ReceiverResultReg + arg: (self numArgsOrSendNumArgsReg: numArgs))]. - arg: numArgs)]. - dynamicSuperSendTrampolines - at: NumSendTrampolines - 1 - put: (self genSendTrampolineFor: #ceDynamicSuperSend:to:numArgs: - numArgs: self numRegArgs + 1 - called: (self trampolineName: 'ceDynSuperSend' numArgs: -1) - arg: ClassReg - arg: ReceiverResultReg - arg: SendNumArgsReg).
+ 0 to: NumSendTrampolines - 1 do: - 0 to: NumSendTrampolines - 2 do: [:numArgs| implicitReceiverSendTrampolines at: numArgs put: (self genNSSendTrampolineFor: #ceImplicitReceiverSend:receiver: numArgs: numArgs called: (self trampolineName: 'ceImplicitReceiverSend' numArgs: numArgs))]. - implicitReceiverSendTrampolines - at: NumSendTrampolines - 1 - put: (self - genNSSendTrampolineFor: #ceImplicitReceiverSend:receiver: - numArgs: self numRegArgs + 1 - called: (self trampolineName: 'ceImplicitReceiverSend' numArgs: -1)).
+ 0 to: NumSendTrampolines - 1 do: - 0 to: NumSendTrampolines - 2 do: [:numArgs| outerSendTrampolines at: numArgs put: (self genNSSendTrampolineFor: #ceOuterSend:receiver: numArgs: numArgs + called: (self trampolineName: 'ceOuterSend' numArgs: numArgs))]! - called: (self trampolineName: 'ceOuterSend' numArgs: numArgs))]. - outerSendTrampolines - at: NumSendTrampolines - 1 - put: (self - genNSSendTrampolineFor: #ceOuterSend:receiver: - numArgs: self numRegArgs + 1 - called: (self trampolineName: 'ceOuterSend' numArgs: -1)).!
Item was changed: ----- Method: StackToRegisterMappingCogit>>generateSendTrampolines (in category 'initialization') ----- generateSendTrampolines "Override to generate code to push the register arg(s) for <= numRegArg arity sends." + 0 to: NumSendTrampolines - 1 do: - 0 to: NumSendTrampolines - 2 do: [:numArgs| ordinarySendTrampolines at: numArgs put: (self genSendTrampolineFor: #ceSend:super:to:numArgs: numArgs: numArgs called: (self trampolineName: 'ceSend' numArgs: numArgs) arg: ClassReg arg: 0 arg: ReceiverResultReg + arg: (self numArgsOrSendNumArgsReg: numArgs))]. - arg: numArgs)]. - ordinarySendTrampolines - at: NumSendTrampolines - 1 - put: (self genSendTrampolineFor: #ceSend:super:to:numArgs: - numArgs: self numRegArgs + 1 - called: (self trampolineName: 'ceSend' numArgs: -1) - arg: ClassReg - arg: 0 - arg: ReceiverResultReg - arg: SendNumArgsReg).
"Generate these in the middle so they are within [firstSend, lastSend]." self cppIf: NewspeakVM ifTrue: [self generateNewspeakSendTrampolines]. self cppIf: BytecodeSetHasDirectedSuperSend ifTrue: + [0 to: NumSendTrampolines - 1 do: - [0 to: NumSendTrampolines - 2 do: [:numArgs| directedSuperSendTrampolines at: numArgs put: (self genSendTrampolineFor: #ceSend:above:to:numArgs: numArgs: numArgs called: (self trampolineName: 'ceDirectedSuperSend' numArgs: numArgs) arg: ClassReg arg: TempReg arg: ReceiverResultReg + arg: (self numArgsOrSendNumArgsReg: numArgs))]]. - arg: numArgs)]. - directedSuperSendTrampolines - at: NumSendTrampolines - 1 - put: (self genSendTrampolineFor: #ceSend:above:to:numArgs: - numArgs: self numRegArgs + 1 - called: (self trampolineName: 'ceDirectedSuperSend' numArgs: -1) - arg: ClassReg - arg: TempReg - arg: ReceiverResultReg - arg: SendNumArgsReg)].
+ 0 to: NumSendTrampolines - 1 do: - 0 to: NumSendTrampolines - 2 do: [:numArgs| superSendTrampolines at: numArgs put: (self genSendTrampolineFor: #ceSend:super:to:numArgs: numArgs: numArgs called: (self trampolineName: 'ceSuperSend' numArgs: numArgs) arg: ClassReg arg: 1 arg: ReceiverResultReg + arg: (self numArgsOrSendNumArgsReg: numArgs))]. - arg: numArgs)]. - superSendTrampolines - at: NumSendTrampolines - 1 - put: (self genSendTrampolineFor: #ceSend:super:to:numArgs: - numArgs: self numRegArgs + 1 - called: (self trampolineName: 'ceSuperSend' numArgs: -1) - arg: ClassReg - arg: 1 - arg: ReceiverResultReg - arg: SendNumArgsReg). firstSend := ordinarySendTrampolines at: 0. lastSend := superSendTrampolines at: NumSendTrampolines - 1!
vm-dev@lists.squeakfoundation.org