lightning
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Lightning] How to get call address / instruction pointer without a


From: Paulo César Pereira de Andrade
Subject: Re: [Lightning] How to get call address / instruction pointer without a hack?
Date: Tue, 11 Mar 2014 12:18:34 -0300

2014-03-10 14:22 GMT-03:00 Bruno Loff <address@hidden>:

  I just pushed an "experimental" interface to instruct lightning to use an
alternate code buffer, see
http://git.savannah.gnu.org/cgit/lightning.git/commit/?id=79bc3d03dd1c76d8a37ed3c12becbd9b71c142be

> Actually, I can satisfy my requirements with lightning as it stands without
> hacks. My generated code _would_ become a bit faster if lightning had the
> following possibility:
>
> ref = jit_movi(REGISTER, 0)
> jit_relative_patch_at(ref, label1, label2, const)
>
> this would cause the movi instruction to be patched to jit_address(label2) -
> jit_address(label 1) + const. This would effectively allow me put in the
> register the address of label 2 relative to the address of label 1, and add
> a constant on top of that. Even without the constant that would already
> improve my code.

  This is not easy to implement because it would require a quite different
abstraction to keep track of the states and remember what was meant
up to when actually emitting code and patching after label1 and label2
are resolved.

> Currently I am simulating the above by doing the following:
> ref = jit_movi(REGISTER, 0)
> jit_subr(REGISTER, REGISTER, V1)
> jit_patch_at(ref, label2)

  You should not need to do this with the new jit_set_code interface.
  An alternative could be to jit_ldi(reg, addr) the value from a global
state, but having the value in a register should be faster.

> And the main function that is emitted accepts an argument which it
> immediately puts in V1. Then I call this function with that argument set to
> jit_address(label1) + const. This works because label1 is always the same on
> every instance where I want to apply the trick above (actually label1 =
> jit_address(first_line_of_code)).
>
> alternatively, some instruction like
> ref = jit_movi(REGISTER, 0)
> ...
> jit_emit()
> jit_repatch_abs(ref, abs_value)
>
> which would be called *after* jit_emit and would change the code of the movi
> instruction to have some absolute value instead of 0. I really do not know
> how the immediate of the movi instruction is stored (you told me it was in
> the code, not in the data buffer), but maybe this is not hard to change even
> after the code emission?

  To implement this, it would be required to patch with a bogus value,
to cause lightning to generate a "patchable" instruction sequence, then,
with the proper interface exported to call the backend patch_at it would
be easy to repatch. But I really do not like it, and with the new jit_set_code
interface you should not need it.

> It seems a bit over the top to implement all of the things you mentioned
> just to fix this small problem. I would suggest that you don't do that
> unless someone else also asks for it.

  I think jit_set_code, at first, and then a way to disable use of a data
buffer are required to make it easier for any complex code out there
that used lightning 1.x to be ported to lightning 2.x, so I will work on
those.

>>    jit_emit. As a side note, it is worth mentioning that jit_patch_abs
>> exists,
>>    and is usable for jit_movi and jit_jmpi, but only use cases I can
>> imagine
>>    are when using multiple jit_context_t and using addresses after one of
>>    the contexts has been emitted, as all other addresses are expected to
>>    be constant at runtime or can be resolved before actual jit emit, e.g.
>>    dlopen+dlsym.
>>
>>
>>   If you, Bruno, or anybody else have suggestions, please let me know.


  A brief description of how to use jit_set_code is:

1) After finishing the code, instead of jit_emit(), call the new jit_realize()
   function.
2) After calling jit_realize(), call jit_get_code() with the address of a
   jit_word_t variable as argument, and that variable will be set to the
   expected maximum amount of bytes required to emit the code.
3) Call jit_set_code(ptr, bytes) with the ptr argument as the address of
   the memory to emit the code, and bytes as size of the buffer.
4) Call jit_emit() and check the return value. If it is NULL, it means the
   buffer was not large enough. You can keep calling jit_set_code() with
   different input, and then jit_emit() until the generated code fits in "bytes"
   bytes and jit_emit() does not return NULL.
5) After jit_emit returns a non NULL value, calling jit_get_code will set
   the argument to the exact amount of bytes used.


  This is an intermediate state to what you described as your needs from
lightning. The other case is not "wasting" memory for data, what should
be implemented next, so that the entire code buffer would be self contained,
would be safe to call jit_destroy_state to completely release all memory,
and would require only one extra call before actually emitting code to
instruct lightning to not use a data buffer.

Thanks,
Paulo



reply via email to

[Prev in Thread] Current Thread [Next in Thread]