On Sat, Jan 6, 2018 at 6:30 AM, Denis Kudriashov <[hidden email]> wrote:
Hi.
I guess "quick" methods are compiled as special primitives. For example accessors are primitives too:
(Point >> #x) isPrimitive
There is another method #isRealPrimitive which checks for explicit primitive call.
That's right. The scheme is as follows:
Numbered primitives used to be 9 bits fields and primitive numbers 1 through 255 were for conventional primitives, and primitive numbers 256 through 512 were for quick primitives, such that 256 through 263 pushed specific constants and 264 through 512 pushed the inst vars, 263 pushing inst var 0, 264 pushing inst var 1, etc. Here's the relevant section of the VM's primitive table:
"Quick Push Const Methods"
(256 nil) "primitivePushSelf"
(257 nil) "primitivePushTrue"
(258 nil) "primitivePushFalse"
(259 nil) "primitivePushNil"
(260 nil) "primitivePushMinusOne"
(261 nil) "primitivePushZero"
(262 nil) "primitivePushOne"
(263 nil) "primitivePushTwo"
"Quick Push Inst Var Methods"
(264 519 nil) "primitiveLoadInstVar"
Now we have 16 bits of primitive index. The scheme up to 32767 is the same; 1 through 32767 are available for conventional primitives, with 256 through 512 reserved for quick primitives. Numbers 32768 through 65535 are reserved for use "inline primitives". We divide the 32k values from 32767 on up into four 8k groups. Sista has the first 8k. Lowcode has the second 8k, and the remaining two groups of 8k are unassigned, reserved for future use.
Now that SistaV1 and Spur support up to 64k inst vars one could argue that we should extend the range of numbers available to quick primitives. But in the JIT there's no difference between the code generated for a quick primitive and the code generated for a conventional pshInstVar:/pushConstant:, methodReturnTop. IQuicjk primitive serve to improve performance only in the interpreter. So given that we have no classes defining more than 210 inst vars (in my image) I don't think its a pressing need :-)