[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: |
Sun, 9 Mar 2014 14:43:33 -0300 |
2014-03-09 12:05 GMT-03:00 Bruno Loff <address@hidden>:
> Hello again :-)
Hi :-)
> As a way of being able to pause the execution of lightning-compiled code,
> and resume where it was, I programmed the following hack:
>
> Just before the main code, I add the following function:
>
> // void test(void )
> jit_prolog();
> jit_ldxi(JIT_R0, JIT_FP, 0x30);
> jit_ret();
> jit_epilog();
>
> The value 0x30 was chosen because when disassembling the generated code I
> noticed that lightning adds 0x30 bytes to the frame pointer immediately
> after it jumps to the function. This is probably a result of jit_prolog(),
> but I'm not sure.
It is jit_prolog. But the offset varies from port to port and is not
guaranteed
to stay constant.Also, several architectures have a dedicated return
address register (not available in the lightning api).
> Now, when I need to know the IP of some place, all I have to do is:
> 1: jit_prepare();
> 2: PUT_ADDRESS_OF_TEST_INTO_R0
JIT_R0 is not guaranteed to be the return value register. Even if
"jit_ldxi(JIT_R0, JIT_FP, 0x30);" to get the return address were valid,
you would need to write "jit_retr(JIT_R0);" instead of "jit_ret();".
> 3: jit_finishr(JIT_R0);
Here you should add "jit_retval(JIT_R0);", what is a noop in x86*, but
required on ports where the return register is not the same as JIT_R0.
> 4: ref = jit_beqi(JIT_R0, 0);
> 5: STORE_R0_SOMEWHERE_TO_BE_USED_LATER
> 6: jit_ret();
> 7: jit_patch(ref);
>
>
> and as soon as it returns, R0 has the address of (4), which is different
> than 0. Now I can store this address <somewhere>, leave the execution with
> jit_ret, and when I want to resume it all I need to do is set R0 to 0 and
> jump to the address I stored <somewhere>. When that happens the branch on
> (4) will jump into (7), and the code proceeds merrily onwards.
>
> This is a neat trick, the thing that annoys me is that I have to use this
> hack to get the address of 4. As far as I know, the value 0x30 for the
> prolog() could well change from one lightning version / platform to the
> next.
Yes, as described above it is not guaranteed to be constant.
> Is there any way to avoid that?
The proper way to write your example would be somewhat like:
1: ref = jit_movi(JIT_R0, 0); // 0 will be patched
2: jit_patch(ref); // create a label and put address of 3 in JIT_R0
3: ref = jit_beqi(JIT_R0, 0);
4: STORE_R0_SOMEWHERE_TO_BE_USED_LATER
5: jit_ret();
6: jit_patch(ref);
(2) is creating an implicit label, and patching the value to the movi, so
effectively puting the address of (3) in JIT_R0. This is *way* cheaper
than calling a function. But I see what you want, that is a way to
figure in runtime the return address of a jit function. Lightning does
not support it currently.
I do not know how your code works, but you probably would be better
using a controlling thread and mutexes or semaphores to temporarily
halt execution. e.g. in the C code:
pthread_mutex_lock(&jit_mutex); /* make jit stop in a checkpoint */
<<<do something>>>
pthread_mutex_unlock(&jit_mutex); /* let jit resume */
and in the jit code:
jit_prepare();
jit_pushargi((jit_word_t)&jit_mutex);
jit_finishi(pthread_mutex_lock);
<<<do something>>>
jit_prepare();
jit_pushargi((jit_word_t)&jit_mutex);
jit_finishi(pthread_mutex_unlock);
> Bruno
Thanks,
Paulo