myjit-devel Mailing List for MyJIT
Status: Beta
Brought to you by:
pkrajca
You can subscribe to this list here.
2015 |
Jan
|
Feb
(1) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
---|---|---|---|---|---|---|---|---|---|---|---|---|
2016 |
Jan
|
Feb
(3) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(5) |
Oct
|
Nov
|
Dec
|
From: Adam C. <cim...@gm...> - 2016-09-25 22:27:21
|
My code now works! I also noticed that the function pointers are written by `jit_generate_code` and not by `jit_prolog` as I originally assumed, after changing my function signatures all is good. Thank you for your help, Adam > On 25 Sep 2016, at 16:32, Petr Krajča <pet...@up...> wrote: > > Hello Adam, > > On Sun, 25 Sep 2016 14:29:28 +0200, Adam Cimarosti <cim...@gm...> wrote: > >> This could very well be incorrect usage on my part. >> * Specifically, I am using the same `jit` object to generate two functions. It hasn't given me issues with different code, so I assume it's supported. > > It is perfectly correct to generate two function using single `jit` object. However, you must call jit_generate_code(p) only once. Hence, you have to move lines > > jit_check_code(p, JIT_WARN_ALL); > jit_generate_code(p); > > into the main-function. > > >> * I am also returning 0 for a function with void return type, I assume this is the correct thing to do (rather than skipping the return >altogether). > > Yes, it's correct, you have to return something. > > Best regards, > Petr |
From: Petr K. <pet...@up...> - 2016-09-25 15:52:25
|
Hello Adam, On Sun, 25 Sep 2016 14:29:28 +0200, Adam Cimarosti <cim...@gm...> wrote: > This could very well be incorrect usage on my part. > * Specifically, I am using the same `jit` object to generate two functions. It hasn't given me issues with different code, so I assume it's supported. It is perfectly correct to generate two function using single `jit` object. However, you must call jit_generate_code(p) only once. Hence, you have to move lines jit_check_code(p, JIT_WARN_ALL); jit_generate_code(p); into the main-function. > * I am also returning 0 for a function with void return type, I assume this is the correct thing to do (rather than skipping the return >altogether). Yes, it's correct, you have to return something. Best regards, Petr |
From: Adam C. <cim...@gm...> - 2016-09-25 12:29:34
|
Hello, While learning myjit I've encountered a case that causes `jit_free` to segfault - a possible double-free. This could very well be incorrect usage on my part. * Specifically, I am using the same `jit` object to generate two functions. It hasn't given me issues with different code, so I assume it's supported. * I am also returning 0 for a function with void return type, I assume this is the correct thing to do (rather than skipping the return altogether). My code: I've tried to summarise this to a semi-minimal piece of code that replicates this issue: #include <stdlib.h> #include <stdio.h> #include "myjit/jitlib.h" typedef int (*int_int_func_t)(int); typedef void (*void_void_func_t)(void); int_int_func_t bld_le_than(struct jit* p, int threshold) { // declare the function int_int_func_t func; jit_prolog(p, &func); // declare and get the first arg jit_declare_arg(p, JIT_SIGNED_NUM, sizeof(int)); jit_getarg(p, R(0), 0); // compare it against the threshold and return jit_lei(p, R(0), R(0), threshold); jit_retr(p, R(0)); // generate the function and return it jit_check_code(p, JIT_WARN_ALL); jit_generate_code(p); return func; } void_void_func_t bld_greet4(struct jit* p) { void_void_func_t func; jit_prolog(p, &func); // R(0) is an accumulator, starting with 1, incremented to 4 jit_movi(p, R(0), 1); jit_label* loop = jit_get_label(p); jit_op* end = jit_bgti(p, JIT_FORWARD, R(0), 4); jit_prepare(p); jit_putargi(p, "Hello %d of 4!\n"); jit_putargr(p, R(0)); jit_call(p, printf); // increment accumulator and loop jit_addi(p, R(0), R(0), 1); jit_jmpi(p, loop); // the end of the loop jit_patch(p, end); jit_reti(p, 0); jit_check_code(p, JIT_WARN_ALL); jit_generate_code(p); return func; } int main() { struct jit* p = jit_init(); int_int_func_t le10 = bld_le_than(p, 10); void_void_func_t greet4 = bld_greet4(p); (void)le10; // printf("le10(5) = %d\n", le10(5)); (void)greet4; // greet4(); puts("about to `jit_free` and segfault"); jit_free(p); return 0; } Building: I am building and running this on my MacBook (AMD64). I've added the code above as demo4.c in your Makefile. all: demo1 demo2 demo3 demo4 myjit-disassembler demo4: demo4.c jitlib-core.o $(CC) -O2 -c -g -Winline -Wall -std=c99 -pedantic -D_XOPEN_SOURCE=600 demo4.c $(CC) -O2 -o demo4 -g -Wall -std=c99 -pedantic demo4.o jitlib-core.o -ldl Running in debugger: $ lldb demo4 (lldb) target create "demo4" Current executable set to 'demo4' (x86_64). (lldb) run Process 81549 launched: '/Users/adam/github/myjit-maincode/demo4' (x86_64) about to `jit_free` and segfault Process 81549 stopped * thread #1: tid = 0x1a3899, 0x000000010002c2c0 demo4`jit_reg_allocator_free(a=0x000000000001bf48) + 16 at reg-allocator.h:625, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x1bf78) frame #0: 0x000000010002c2c0 demo4`jit_reg_allocator_free(a=0x000000000001bf48) + 16 at reg-allocator.h:625 622 623 void jit_reg_allocator_free(struct jit_reg_allocator * a) 624 { -> 625 if (a->fp_regs) JIT_FREE(a->fp_regs); 626 JIT_FREE(a->gp_regs); 627 if (a->fp_arg_regs) JIT_FREE(a->fp_arg_regs); 628 if (a->gp_arg_regs) JIT_FREE(a->gp_arg_regs); (lldb) bt * thread #1: tid = 0x1a3899, 0x000000010002c2c0 demo4`jit_reg_allocator_free(a=0x000000000001bf48) + 16 at reg-allocator.h:625, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x1bf78) * frame #0: 0x000000010002c2c0 demo4`jit_reg_allocator_free(a=0x000000000001bf48) + 16 at reg-allocator.h:625 frame #1: 0x000000010002d779 demo4`jit_free(jit=0x0000000100805000) + 25 at jitlib-core.c:509 frame #2: 0x00000001000016f9 demo4`main + 57 at demo4.c:76 frame #3: 0x00007fff9aaa15ad libdyld.dylib`start + 1 frame #4: 0x00007fff9aaa15ad libdyld.dylib`start + 1 (lldb) p a (jit_reg_allocator *) $0 = 0x000000000001bf48 (lldb) p *a error: Couldn't apply expression side effects : Couldn't dematerialize a result variable: couldn't read its memory (lldb) f 1 frame #1: 0x000000010002d779 demo4`jit_free(jit=0x0000000100805000) + 25 at jitlib-core.c:509 506 507 void jit_free(struct jit * jit) 508 { -> 509 jit_reg_allocator_free(jit->reg_al); 510 free_ops(jit_op_first(jit->ops)); 511 free_labels(jit->labels); 512 if (jit->buf) JIT_FREE(jit->buf); (lldb) p jit (jit *) $3 = 0x0000000100805000 (lldb) p *jit (jit) $4 = { buf = 0x480af88348c76348 <no value available> buf_capacity = 184 ip = 0x9090c3c09e0f4000 <no value available> ops = 0x9090909090909090 last_op = 0x10ec8348ec8b4855 reg_al = 0x000000000001bf48 current_func = 0x0f4804ff83480000 labels = 0x7d89480000002e8f prepared_args = { count = 1972062456 ready = -37795592 gp_args = 16778132 fp_args = 855638016 stack_size = 1421560256 op = 0x8b48d3ff4100007f args = 0xc7e901c78348f87d } push_count = 1224736767 optimizations = 184 } |
From: Petr K. <pk...@io...> - 2016-09-23 21:41:44
|
On Wed, 21 Sep 2016 23:20:22 +0200, Adam Cimarosti <cim...@gm...> wrote: > Wonderful project! > > Myjit is a breath of fresh air, and it is very easy to get started. Thank you for your appreciation. > > I have two questions: > * What is the lifetime of the generated code? > * My requirement is for ephemeral code, generated on the fly from user > requests and cleaned-up soon after. > * Will `jit_free` clean this up or is the use case unsupported? Yes. However, keep in mind that the code generation itself has some overhead. For your use case it will be wise to turn optimizations off. > * I will (eventually) have a need to generate AVX code, I've noticed the > `jit_data_*` class of functions to inject bytes, can you think of an > alternative? Well, this is going to be an issue since there's no native support for SIMD instructions. These instructions are too CPU/model-specific and we want to keep MyJIT as vendor and platform independent as possible. Furthermore, on i386 and AMD64 XMM* registers are dedicated for floating point arithmetics. Of course, you can directly insert code for AVX but this have to be done carefully. Code have to PIC and you have take care of XMM* registers, i.e., save/restore their values before entering/leaving AVX code. Best regards, Petr |
From: Adam C. <cim...@gm...> - 2016-09-21 21:20:31
|
Wonderful project! Myjit is a breath of fresh air, and it is very easy to get started. I have two questions: What is the lifetime of the generated code? My requirement is for ephemeral code, generated on the fly from user requests and cleaned-up soon after. Will `jit_free` clean this up or is the use case unsupported? I will (eventually) have a need to generate AVX code, I've noticed the `jit_data_*` class of functions to inject bytes, can you think of an alternative? Thanks, Adam |
From: Petr K. <pk...@io...> - 2016-02-05 10:49:39
|
Hi, it should be sufficient to copy out the code from the buffer in "struct jit", i.e., unsigned char *mem = ... int code_size = jit->ip - jit->buf; memcpy(mem, jit->buf, code_size); However, I'm not sure if the emitted code is fully PIC. Recently, I've made changes in this direction but any interaction with the world outside of MyJIT may be an issue. Best regards, Petr On Fri, 05 Feb 2016 02:07:40 +0100, mahdi <xem...@ya...> wrote: > Hi, > > How can I store the output generated code in a buffer to be saved to an > output file? > > > > Best Regards |
From: Petr K. <pk...@io...> - 2016-02-05 10:32:59
|
Hi, it should be sufficient to copy out the code from the buffer in "struct jit", i.e., unsigned char *mem = ... int code_size = jit->ip - jit->buf; memcpy(mem, jit->buf, code_size); However, I'm not sure if the emitted code is fully PIC. Recently, I've made changes in this direction but any interaction with the world outside of MyJIT may be an issue. Best regards, Petr On Fri, 05 Feb 2016 02:07:40 +0100, mahdi <xem...@ya...> wrote: > Hi, > > How can I store the output generated code in a buffer to be saved to an > output file? > > > > Best Regards |
From: mahdi <xem...@ya...> - 2016-02-05 01:08:09
|
Hi, How can I store the output generated code in a buffer to be saved to an output file? Best Regards |
From: Марк К. <soc...@gm...> - 2015-02-12 16:08:21
|
bosubi reg, reg, imm O2 -= O3, goto O1 on overflow Seems, first operand should be "imm", not "reg". Also, I have a question: How I can implemente jump table in myjit? Im mean effective implementation of switch-case operator when every action is jump to specific location. I mean that in terms of C: instead fo this: switch (i) { case 0: jump addr_1; case 1: jump addr_2; ... case 255: jump addr_3; } I want to implement in myjit as: void* arr[256] = { addr1, addr2,....addr256}; goto *arr[i]; And also note, that at time of emitting that array of labels, label values are not known (I should use patch statement to define that addresses). -- Segmentation fault |