Hi Eliot,
once again I am very pleasantly surprised by your professional and detailed answer which was a joy to read!
send: selector to: rcvr with: arguments lookupIn: lookupClass
"Simulate the action of sending a message with selector and arguments to rcvr. The argument, lookupClass, is the class in which to lookup the message. This is the receiver's class for normal messages, but for super messages it will be some specific class related to the source method."
| meth primFailCode val ctxt |
(meth := lookupClass lookupSelector: selector) ifNil:
[selector == #doesNotUnderstand: ifTrue:
[self error: 'Recursive message not understood!' translated].
^self send: #doesNotUnderstand:
to: rcvr
with: {(Message selector: selector arguments: arguments) lookupClass: lookupClass}
lookupIn: lookupClass].
meth isCompiledMethod ifFalse:
["Object as Methods (OaM) protocol: 'The contract is that, when the VM encounters an ordinary object (rather than a compiled method) in the method dictionary during lookup, it sends it the special selector #run:with:in: providing the original selector, arguments, and receiver.'. DOI: 10.1145/2991041.2991062."
^self send: #run:with:in:
to: meth
with: {selector. arguments. rcvr}].
meth numArgs = arguments size ifFalse:
[^ self error: ('Wrong number of arguments in simulated message {1}' translated format: {selector})].
(primIndex := meth primitive) > 0 ifTrue:
- [val := self doPrimitive: primIndex method: meth receiver: rcvr args: arguments.+ [val := self doPrimitive: primIndex method: meth receiver: rcvr args: arguments ifFail:
- (self isPrimFailToken: val) ifFalse:
- [^val]].
+ [:code | primFailCode := code].+ primFailCode ifNil: [^ val]].
(selector == #doesNotUnderstand: and: [lookupClass == ProtoObject]) ifTrue:
[^self error: ('Simulated message {1} not understood' translated format: {arguments first selector})].
ctxt := Context sender: self receiver: rcvr method: meth arguments: arguments.
- (primIndex isInteger and: [primIndex > 0]) ifTrue:+ primFailCode ifNotNil:
- [ctxt failPrimitiveWith: val].
+ [ctxt failPrimitiveWith: primFailCode].
^ctxt
Hi all, hi Eliot,
new year, new simulation fun, and I have collected two new questions about the Context implementation which I'd love to get answered here:
First, I was confused by the following:
(BlockClosure >> #numArgs) primitive. "266"
(Context >> #pc) primitive. "0"
What makes Context so special that it cannot be compiled with quick accessor methods?
Second, Context >> #isPrimFailToken: attracted my attention multiple times when looking at different #timeProfile results of simulation sessions. In the expression [100000 factorial] it takes up more than 44% of the whole execution time!
I have no idea why it could be so slow, but this message is sent really often, which is at least 2 times per simulation of a special message send.
Would there be an easy change to resolve this bottleneck and speed up the simulation by 40% or more?
Would it be possible to provide a primitive for this method? Or do you see any other way to optimize it?
Best,
Christoph
Free forum by Nabble | Edit this page |