lightning
[Top][All Lists]
Advanced

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

Re: [Lightning] Re: About using lightning on a dynamically typed lang


From: Paulo César Pereira de Andrade
Subject: Re: [Lightning] Re: About using lightning on a dynamically typed language
Date: Sat, 5 Jun 2010 04:24:42 -0300
User-agent: SquirrelMail/1.4.19

Paulo César Pereira de Andrade wrote:
> Paolo Bonzini wrote:
>>>  The idea is to create several small C functions, for most opcodes, so
>>> that I don't need to (or should not) bother with c99 complex numbers,
>>> tls variables, etc from the jit code, only from the small "callbacks".
>>
>> Makes sense, like a mixture of JIT and threaded code.
>
>   The initial code I am writing (almost 3k lines already, but not yet
> compiled, and mostly cut&paste of the current implementation), basically
> starts with a call to mmap() of 16Mb, and I believe calling mremap if it
> every needs more memory (or just to shrink it back later should work...)
> should do it without the need of some "massaging" to adjust offsets...
>
>   Basically it calls these callbacks, and have a few specialized ones,
> for constant values, like known types and offsets. Very simple opcodes
> like load of constants are being written directly in jit.

  Well, it took me over a week of very tough work on the interpreter
to actually have it working with lightning, but the results are
promising :-)

  I did an "incremental" conversion to a function of almost every body
of the threaded code, and changed the logic to have the "current value"
accessible from the global thread structure, some major cleanup and bug
fixes while at it, so that the same code can be shared by bytecode
interpreter, and now from jit.
"incremental" because I was testing it very frequently and ensuring
no bugs/typos were being added; nothing worse then having several
thousand lines of code with "bugs there somewhere"...

  The major issues, other then becoming used to lightning (what is
actually very easy, /me that is not much used to debug assembly :-)
were:

o Need to have siglongjmp to jump "somewhere", and from "threre",
  reenter jit. After some "headaches", I ended up opting to implement
  the sigsetjmp call directly in jit, so that, when a signal handler
  siglongjump's (only SIGFPE and SIGSEGV), or some code finds an
  error condition, they will land back in the jit code, that can
  dispatch the exception to the language handler, if any, and this
  way, no registers are clobbered, but really, only needs JIT_V1 not
  clobbered, as it points to the TLS thread_self global variable.
o Mixed with the above problem, was a crash in some "vector" functions,
  and the cause turned out to be stack misalignment. I was thinking
  it was caused by different attempts to "reenter" jit, but the solution
  was to call jit_allocai(12) to "pad" the stack at 16 bytes when summed
  to the ethread_t argument, so that sse instructions work if using a
  local variable as argument.

  Other then that, now it works, can run multiple threads, and everything
works identically with the bytecode vm, and the jit vm, but still only
tested on i686.

>   I am a bit unsure if I could figure out some logic for fast dispatching
> based on "current value type", as in the current vm, there are 11 dispatch
> tables (and could have more, like one for when the loaded value is a
> hash table, or some other special types), based on the type of the
> current value, so, for example, if it finds an "add" opcode, it only
> checks the value in the top of the stack, and doesn't need to check the
> current value type again, and if the operation is invalid, the entry in
> the dispatch table is a direct jump to the error handling.
>   A naive implementation could be to have 11+ versions of the jit code,
> jumping from one to another when the type changes, but that may become
> worse then checking the type, most times redundantly, in every "callback"
> in C code.

  In the current code, there are no dispatch tables based on the current
value type aymore. That, associated with converting all instructions to
function calls made the vm 3 times slower, but the initial jit code is 2
times slower then what the vm used to be, but there are plenty of
optimization options, and I believe it should become significantly
faster once a significant amount of the "vm callbacks" are converted
to jit (currently, even to take a branch it calls a vm function to
choose if it will jump or not...)

>   But I believe for code working on only dynamically typed objects, it
> should still be around twice as fast, where it should become really fast
> is in code handling statically typed variables.
>
>> BTW in the GNU Smalltalk JIT the superoperators are completely
>> separated at JIT time.  In the interpreter instead there is a program
>> to generate the "glued" code.  The glued code is more efficient
>> because it avoids writing temporary data to the stack.
>
>   I probably will still use a few superoperator like "callbacks", to
> avoid writing to the vm stack (the worst case is bignums, as they
> are handled by value, so, inplace operations or knowing if can call
> "mp*_swap" is very desirable), but in a peephole pass that will happen
> to be during generation of jit.
>
>> Paolo

  Sorry for the long email... If anybody have interest in looking at
the current code, a direct link to the current implementation is
http://code.google.com/p/exl/source/browse/trunk/lib/elightning.c

Thanks,
Paulo




reply via email to

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