arvindm95 / unladen-swallow

Automatically exported from code.google.com/p/unladen-swallow
Other
0 stars 0 forks source link

Teach the JIT to recompile things #41

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
We currently use llvm::ExecutionEngine::getPointerToFunction(func) to
translate LLVM IR into machine code. getPointerToFunction caches the
returned machine code for each input function, and will not regenerate it
even if the function has changed. This means we can't re-optimize a
function after calling it through LLVM.

ExecutionEngine::recompileAndRelinkFunction(func) is available to force
LLVM to regenerate the machine code, but it overwrites the original machine
code with a jump to the new block, which means we can't use it while any
stack frame in any thread is still executing the code.

More information on fixing this is at
http://wiki.llvm.org/Provide_more_control_over_and_access_to_JIT%27s_output

Original issue reported on code.google.com by jyass...@gmail.com on 28 May 2009 at 10:47

GoogleCodeExporter commented 8 years ago

Original comment by collinw on 19 Jun 2009 at 7:17

GoogleCodeExporter commented 8 years ago
What's the status of this?  Right now we need to make sure we record very 
accurate
feedback because of this limitation.  We only get one shot at compiling the 
right
machine code, and if we get it wrong, we bail a lot.

Here's a strawman solution we can start improving:
- Before entering native code, we increment a counter for "number of threads in
native code" on the code object.
- Upon exit, we decrement it.
- If the count is zero and the code has lots of bails (ie we think it needs to 
be
recompiled), we can free the native code.
- The next time we enter the code object, we'll recompile it as normal.

Alternatively, we could start stealing tracing JIT ideas:
- Every bail site gets an entry in an array of side exit structs.
- One field is a function pointer which is tail called on bail.
- By default, it jumps to a handler that gets back into the interpreter.
- When the interpreter returns, it compiles a new function from the current 
opcode
forward based on the current feedback and updates the side exit function 
pointer.
- The next time we bail from that side exit, we use the new native code object.

Original comment by reid.kle...@gmail.com on 23 Jan 2010 at 8:27

GoogleCodeExporter commented 8 years ago
I implemented a refcounted object which holds the reference to the llvm 
function and
destroys the function when it is deallocated.

Frames also hold a reference to the native function object. This already enables
recompilations. There are still several obstacles:
- Fatal bails from FDO_GLOBAL are not recorded as such. We may want to disable 
that
optimization if globals change too often.
- Bails from cold branches do not record the changed feedback. Recompiling 
leads to
more bails
- If an optimized binary op bails from operation overflow this does not show up 
in
the feedback. If it's a common case, we can not disable the optimization for 
that
particular op. (Happens a lot in my fuzzer)

Original comment by joerg...@gmail.com on 11 Feb 2010 at 10:47