[Vm-dev] [64 bits] Object pointers in jitted code

Eliot Miranda eliot.miranda at gmail.com
Wed Feb 28 18:00:55 UTC 2018

Hi Javier,

On Wed, Feb 28, 2018 at 7:36 AM, Javier Pimás <elpochodelagente at gmail.com>

> On Wed, Feb 28, 2018 at 11:13 AM, Clément Bera <bera.clement at gmail.com>
> wrote:
>> On Wed, Feb 28, 2018 at 2:16 PM, Javier Pimás <elpochodelagente at gmail.com
>> > wrote:
>>> Hi! This time I'm investigating how cog jit handles pointers to objects
>>> in native code. In x86-32 its easier because you have immediates of the
>>> size of a pointer, but in x64 the immediates are restricted to 32bits (and
>>> I think less in arm). So I wonder how people works around that, if using a
>>> movabs instruction every time you need a pointer or if doing something
>>> else. I found a mail in the list dated from 2011 (titled "questions about
>>> cog internals") where you (Eliot) said that pointers were inlined in jit
>>> code, but I don't know if that's still the case. Looking at the slang code
>>> I found CogOutOfLineLiteralsX64Compiler, but it seems it is not used
>>> (yet?).
>> Just generate & disassemble any method with literals from the Squeak
>> image (in-image compilation workspace scripts) with different ISA and look
>> at the disassembled code, it takes 1 second and you'll see by yourself how
>> pointer size constants (literals) are dealt with.
>> The ARM JIT dumps pointer size constants somewhere unreachable by
>> machine code execution but near by (in-between jumps for example) and
>> access it with PC-relative instructions, that's one good way to work
>> around it.
> The arm jit also seems to support the two approaches
> (CogInLineLiteralsARMCompiler, CogOutOfLineLiteralsARMCompiler), how do
> you do gc with inline literals there?

With suitably layered abstractions.  The method map is traversed using
Cogit>>#mapFor:performUntil:arg:.  mapObjectReferencesInMachineCode: is the
entry point for GC and become.  e.g. a scavenge
applies remapIfObjectRef:pc:hasYoung: via mapFor:performUntil:arg: to every
method in the youngReferrers list (which drastically reduces the amount of
machine code scanned in each scavenge; most methods don't have any
references to young objects),
whereas mapObjectReferencesInMachineCodeForFullGC
applies #remapIfObjectRef:pc:hasYoung: via mapFor:performUntil:arg: to
every machine code method, and to any object references in the generated

remapIfObjectRef:pc:hasYoung: has the following signature:

remapIfObjectRef: annotation pc: mcpc hasYoung: hasYoungPtr

If annotation is IsObjectReference then the literalsManager is asked to
fetch and store literal referenced at pc
via fetchLiteralAtAnnotatedAddress:using:
and storeLiteral:atAnnotatedAddress:using:.  These in turn defer to the
backEnd (an instance of the current CogCompilerClass, such as
CogInLineLiteralsX64Compiler) to extract the address or literal from the
machine code and store it back.  With in-line literals the address
following the instruction is added to the map.  With out-of-line literals
the address of the literal is added to the map.

Then once all relevant methods haver been processed the instruction cache
is flushed and execution proceeds.

>> Cheers!
>>> Pocho
>>> --
>>> Javier Pimás
>>> Ciudad de Buenos Aires
>> --
>> Clément Béra
>> Pharo consortium engineer
>> https://clementbera.wordpress.com/
>> Bâtiment B 40, avenue Halley 59650 Villeneuve d'Ascq
> --
> Javier Pimás
> Ciudad de Buenos Aires

best, Eliot
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20180228/652cbc5b/attachment.html>

More information about the Vm-dev mailing list