-
Notifications
You must be signed in to change notification settings - Fork 71
JIT Compiler
Pharo's interpreter implements for many of its bytecodes static type predictions. Static typre predictions inline the common case in the bytecode with type checks, for example for integer arithmetic, and falls back to user-defined methods if not suitable. This is the case for example of the add bytecode illustrated below.
Interpreter >> bytecodePrimAdd
| rcvr arg result |
rcvr := self internalStackValue: 1.
arg := self internalStackValue: 0.
(objectMemory areIntegers: rcvr and: arg) ifTrue: [
result := (objectMemory integerValueOf: rcvr) + ( objectMemory integerValueOf: arg).
"Check for overflow"
(objectMemory isIntegerValue: result) ifTrue: [
self
internalPop: 2
thenPush: (objectMemory integerObjectOf: result). ^ self fetchNextBytecode "success"]].
"Slow path, message send"
self normalSend
Such instruction pops two elements from the operand stack, checks if they are both small integers and, if they are, it adds them up. If the result does not overflow, arguments are popped, the result is pushed to the operand stack, and execution continues with the next byte-code. If none of the conditions above hold, the instruction takes a slow path and performs a message send.
Many primitives are statically inlined in the interpreter but not in the compiled code of RegisterAllocatingCogit
and StackToRegisterMappingCogit
.
This is for example the case of the following bytecodes that directly perform message sends in compiled code:
- bytecodePrimMultiply
- bytecodePrimDiv
- bytecodePrimDivide
- bytecodePrimBitShift
In addition, SimpleStackBasedCogit
does not inline the following
- bytecodePrimBitAnd
- bytecodePrimBitOr
- bytecodePrimAdd
- bytecodePrimSubtract