Open marceltaeumel opened 11 months ago
I don't remember, there are many possible path, what if not Jitted ? Certainly a case for exercising VM Simulator skills, or learn them...
Note that the primitiveLessThan should fail: it only handle SmallInteger argument (and receiver).
It's bytecodePrimLessThan that eventually handle the automatic int -> float conversion.
Remember that we (the stack interpreter) short-circuit some message sends for some specialSelectors when we can recognize known operand types.
Would it be possible that the debugger fails to emulate the special send machinery?
It appears that the JIT does thing differently than the (stack) interpreter.
The interpreter will try things in this order when interpreting the send of a special selector for arithmetic or comparison - for example in bytecodePrimAdd
primitiveFloatAdd:toArg:
) that will eventually attempt a conversion sqInt -> double through loadFloatOrIntFrom:
In this scheme, if we add handling of conversions in SmallInteger primitives, we will just duplicate the work done in the 2nd stage of bytecodePrimAdd for no added value, but just a few more wasted cycles.
The JIT will only try to handle the case of both SmallIntegers
genSpecialSelectorArithmetic
which is invoked for some of the specialSelectors (+ - bitAnd: bitOr:)genSpecialSelectorComparison
(< > <= >= = ~=)Then it will fallback to a message send which goes through the primitives.
and the integer primitives effectively do not handle conversion as we saw above.
The other way around, Float op: Integer
, the float primitives do handle the conversion, and the JIT appears to be faster than Integer op: Float
. The irony is that Jitted Integer op: Float
is even slower than interpreted code.
I let Eliot explain while the second stage was skipped, but it might be that it consumes two many instructions: remember that the purpose is to inline the specialSelectors send, so we might end up with lot of instructions... If it doesn't pay statistically (except in micro benchmarks), then it's not worth it, because it will exhaust the space devoted to jitted code more rapidly (and remember, specialSelectors are sent from many places !).
We saw that adding conversions in integer primitives is not ideal, at least for the interpreted code.
So welcome to brighter ideas for having your cake and eat it too...
I played around with VM parameter 75. It does indeed show a change for the float-based primitives (i.e., 541, 542, ...) but not the integer-based primitives (i.e., 1, 2, 3, ...).
Is this expected behavior? In the VMMaker sources, it looks like it should work at least for comparisons (i.e., 3 to 8):
Is
genPrimitiveLessThan
not the one in charge here? Hm....So, debugging
3+4.0
shows that the primitive will fail, which it should not when mixed-arithmetic would work as expected.