5 Replies - 740 Views - Last Post: 16 November 2010 - 09:07 PM

#1 ishkabible  Icon User is offline

  • spelling expret
  • member icon




Reputation: 1622
  • View blog
  • Posts: 5,709
  • Joined: 03-August 09

JIT compiling

Posted 14 November 2010 - 06:27 PM

ok so i had an idea as to how to right code at run time using function pointers. i tried and it kept crashing, turns out that my OS dose not like calling things off the stack. i found this witch got me a working program after i found out that i could not run anything on the stack. my issue is that it still seems like very undefined behavior. what i have always works but it just doesn't seem to me like it is 100%. i was wondering if any one knew a better way to do this. i know there are libs out there like gnu lightning that do this for us but im wondering how they do this safely.

here is the code i wrote, moves y to x using JIT compiling.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

typedef void(*func)(); //type def for a function pointer so we can call the genrated function

inline void GetMov(unsigned char** code,int* x,int* y) {
    *code = malloc(11);
    unsigned char temp[] = {0xA1,((unsigned int)y),((unsigned int)y)>>8,((unsigned int)y)>>16,((unsigned int)y)>>24, //MOV EAX,[y]
                            0xA3,((unsigned int)x),((unsigned int)x)>>8,((unsigned int)x)>>16,((unsigned int)x)>>24, //MOV [x],EAX
                            0xC3
                           };
    memcpy(*code,temp,11);
}

void Run() {
    unsigned char* code;
    int x,y=22;
    GetMov(&code,&x,&y);
    ((func)code)();
    printf("%i",x); //should print 22 to the console
}

int main() {
    //this code must assume that pointers are 4 bytes, int's are 4 bytes, and char's are 1 byte,
    assert(sizeof(unsigned char)==1);
    assert(sizeof(unsigned int)==4);
    assert(sizeof(unsigned char*)==4);
    assert(sizeof(int*)==4);
    Run();
}




Is This A Good Question/Topic? 0
  • +

Replies To: JIT compiling

#2 ishkabible  Icon User is offline

  • spelling expret
  • member icon




Reputation: 1622
  • View blog
  • Posts: 5,709
  • Joined: 03-August 09

Re: JIT compiling

Posted 14 November 2010 - 08:44 PM

i worked out how to add, subtract, multiply, divide (kinda, this one has some issues), mod and i figure i can do lots more. is this really how this stuff is done?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

typedef void(*func)(); //type def for a function pointer so we can call the genrated function

inline void GetMov(unsigned char** code,int* x,int* y) {
    *code = malloc(11);
    unsigned char temp[] = {0xA1,((unsigned int)y),((unsigned int)y)>>8,((unsigned int)y)>>16,((unsigned int)y)>>24, //MOV EAX,[y]
                            0xA3,((unsigned int)x),((unsigned int)x)>>8,((unsigned int)x)>>16,((unsigned int)x)>>24, //MOV [x],EAX
                            0xC3
                           };
    memcpy(*code,temp,11);
}

inline void GetAdd(unsigned char** code,int*x,int* y,int* z) {
    *code = malloc(17);
    unsigned char temp[] = {0xA1,((unsigned int)z),((unsigned int)z)>>8,((unsigned int)z)>>16,((unsigned int)z)>>24, //MOV EAX,[y]
							0x03,0x05,((unsigned int)y),((unsigned int)y)>>8,((unsigned int)y)>>16,((unsigned int)y)>>24,
                            0xA3,((unsigned int)x),((unsigned int)x)>>8,((unsigned int)x)>>16,((unsigned int)x)>>24, //MOV [x],EAX
                            0xC3
                           };
    memcpy(*code,temp,17);
}

inline void GetSub(unsigned char** code,int*x,int* y,int* z) {
    *code = malloc(17);
    //needs to be in right order for subtraction
    unsigned char temp[] = {0xA1,((unsigned int)y),((unsigned int)y)>>8,((unsigned int)y)>>16,((unsigned int)y)>>24, //MOV EAX,[y]
							0x2B,0x05,((unsigned int)z),((unsigned int)z)>>8,((unsigned int)z)>>16,((unsigned int)z)>>24,
                            0xA3,((unsigned int)x),((unsigned int)x)>>8,((unsigned int)x)>>16,((unsigned int)x)>>24, //MOV [x],EAX
                            0xC3
                           };
    memcpy(*code,temp,17);
}

//x=y*z
inline void GetMul(unsigned char** code,int*x,int* y,int* z) {
    *code = malloc(18);
    //multipcation, dosnt need to be in any pictuler order
    unsigned char temp[] = {0xA1,((unsigned int)y),((unsigned int)y)>>8,((unsigned int)y)>>16,((unsigned int)y)>>24,
							0x0F,0xAF,0x05,((unsigned int)z),((unsigned int)z)>>8,((unsigned int)z)>>16,((unsigned int)z)>>24,
                            0xA3,((unsigned int)x),((unsigned int)x)>>8,((unsigned int)x)>>16,((unsigned int)x)>>24,
                            0xC3
                           };
    memcpy(*code,temp,18);
}

inline void GetDiv(unsigned char** code,int*x,int* y,int* z) {
    *code = malloc(24);
    //multipcation, dosnt need to be in any pictuler order
    unsigned char temp[] = {0xBA,0x00,0x00,0x00,0x00,
							0xA1,((unsigned int)y),((unsigned int)y)>>8,((unsigned int)y)>>16,((unsigned int)y)>>24,
							0x8B,0x1D,((unsigned int)z),((unsigned int)z)>>8,((unsigned int)z)>>16,((unsigned int)z)>>24,
							0xF7,0xFB,
                            0xA3,((unsigned int)x),((unsigned int)x)>>8,((unsigned int)x)>>16,((unsigned int)x)>>24,
                            0xC3
                           };
    memcpy(*code,temp,24);
}

inline void GetMod(unsigned char** code,int*x,int* y,int* z) {
    *code = malloc(25);
    //multipcation, dosnt need to be in any pictuler order
    unsigned char temp[] = {0xBA,0x00,0x00,0x00,0x00,
							0xA1,((unsigned int)y),((unsigned int)y)>>8,((unsigned int)y)>>16,((unsigned int)y)>>24,
							0x8B,0x1D,((unsigned int)z),((unsigned int)z)>>8,((unsigned int)z)>>16,((unsigned int)z)>>24,
							0xF7,0xFB,
                            0x89,0x15,((unsigned int)x),((unsigned int)x)>>8,((unsigned int)x)>>16,((unsigned int)x)>>24,
                            0xC3
                           };
    memcpy(*code,temp,25);
}

void Run() {
    unsigned char* code;
    int x, y= 60,z=-15;
    GetDiv(&code,&x,&y,&z);
    ((func)code)();
    printf("%i",x);
}

int main() {
    //this code must assume that pointers are 4 bytes, int's are 4 bytes, and char's are 1 byte,
    assert(sizeof(unsigned char)==1);
    assert(sizeof(unsigned int)==4);
    assert(sizeof(unsigned char*)==4);
    assert(sizeof(int*)==4);
    Run();

}



Was This Post Helpful? 0
  • +
  • -

#3 Oler1s  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1395
  • View blog
  • Posts: 3,884
  • Joined: 04-June 09

Re: JIT compiling

Posted 15 November 2010 - 08:20 PM

You don't have a JITter quite yet. But you've got opcode emission going there. It's done a bit more cleanly, and there's a more formal mechanism for managing the code buffers, but that's pretty much it. Instead of writing opcodes to file, you write to dynamically allocated memory, and then call into that memory appropriately.
Was This Post Helpful? 0
  • +
  • -

#4 ishkabible  Icon User is offline

  • spelling expret
  • member icon




Reputation: 1622
  • View blog
  • Posts: 5,709
  • Joined: 03-August 09

Re: JIT compiling

Posted 16 November 2010 - 11:02 AM

lol i thought it was more way more complicated than this. i thought JITing required some type of loader. i cant believe it was so simple. i think im gona write a class in c++ to manage some basic instructions. you mentioned "more formal mechanism for managing the code buffers", what are they? i can definitely clean this up but im unaware of better data structures to handle this.

edit: would using a std::vector as a buffer be acceptable. i could execute it by converting the vector to a pointer by dereferencing then referencing an vector.begin(). could also reference the first element. this was my idea on how to do any ways.

This post has been edited by ishkabible: 16 November 2010 - 03:16 PM

Was This Post Helpful? 0
  • +
  • -

#5 Oler1s  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1395
  • View blog
  • Posts: 3,884
  • Joined: 04-June 09

Re: JIT compiling

Posted 16 November 2010 - 08:05 PM

Quote

lol i thought it was more way more complicated than this. i thought JITing required some type of loader
As I said, you haven't created a JITter. So don't brush it off as something simple.

A JITter is a compiler. Your frontend is simplified because you are lexing a bytecode. But you don't have a frontend at all here. You also don't have a proper backend. You throw in hardcoded instructions. Try creating a properly decoupled target backend. But a proper JITter, like a good compiler, also has to consider optimizations. That's where the heavy lifting is.

Quote

"more formal mechanism for managing the code buffers", what are they?
Look at what you wrote. Your code emitter also allocates memory to write into. It allocates numbers like 18, 24, 25, 17, 42, etc. for memory blocks. Really? You don't see a problem here?

More importantly, the point of a jitter is to do the compilation once, and then not do it again. Where's your caching strategy? Where do you check if you have a buffer filled with the appropriate code? You also need to free allocated memory, and in a caching strategy, recognize buffers of compiled instructions that are no longer necessary. Well, you can't tell if they won't ever be necessary, but you might have a cache algorithm to weed infrequently used blocks.

Quote

would using a std::vector as a buffer be acceptable
That could work. It's not related to JIT compiling, and it's simply about you engineering your code.
Was This Post Helpful? 1
  • +
  • -

#6 ishkabible  Icon User is offline

  • spelling expret
  • member icon




Reputation: 1622
  • View blog
  • Posts: 5,709
  • Joined: 03-August 09

Re: JIT compiling

Posted 16 November 2010 - 09:07 PM

ya ok i see what you mean about the blocks i allocated there. i thought you meant there was a specifically better data structure to use vs allocating space in char array. yes i was just doing this for testing. im not goint to make a very complicated front end if anything just some mnemonic values of what ever instructions i decide to create. i really like the GNU lighting instructions as the map well(logically) in my head. i guess i should change the topic to JIT assembler instead of JIT compiler, i got a little over exited with what i was doing i guess :blush: i did not intend for this to be a complete representation of what i was going to do. ill work on it if i need some advice ill come back thanks!! :)
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1