10.07.2015 Views

An ARM Backend for PyPyls Tracing JIT - STUPS Group

An ARM Backend for PyPyls Tracing JIT - STUPS Group

An ARM Backend for PyPyls Tracing JIT - STUPS Group

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

34 6 A BACKEND FOR PYPY’S <strong>JIT</strong>in frames. When <strong>for</strong>cing happens we can not continue with the execution of the optimizedloop and have to fall back to interpretation. Because of this, around calls that cantrigger such a frame <strong>for</strong>cing we need to check if <strong>for</strong>cing happened, in order to leave theoptimized loop in that case.To per<strong>for</strong>m the steps described above we make use of the <strong>for</strong>ce_index, mentionedbe<strong>for</strong>e when describing the frame layout. We use the slot of the <strong>for</strong>ce_index on thestack to store a value that is changed when we <strong>for</strong>ce the frame. Using this value wecan check if the frame was <strong>for</strong>ced and exit the loop if necessary. Additionally we makeuse of the address of the <strong>for</strong>ce_index, that is stored in the FP register, to restore thevariables used in the loop so the frontend can create the frame objects. We can restorethe variables using the address of the <strong>for</strong>ce_index, because the variables are stored ina known offset from this address.6.5 Guards and Leaving the LoopAs described in Section 3.2 traces correspond to only one possible path through the tracedloop. Operations called guards are inserted in the trace at all points where the executioncould take a different path than the one recorded during tracing. These operations checkthat the conditions valid during tracing are still valid during execution. Examples <strong>for</strong>such guards are guard_value, guard_class, guard_true, etc. which check the conditionindicated by their name to be true.Because a trace contains a large amount of guards and guards fail rarely we want toimplement guards in a way that the case where the guard does not fail is efficient. Theefficiency of the failure case is not as important.Guards are implemented by generating a comparison instruction on the input argumentof the guard and the provided condition. If the condition passes we jump over the blockof instructions generated <strong>for</strong> the guard and continue with the execution of the loop.In the case the check fails we enter the guard block. Within the guard block we first savethe locations of all variables, i.e. the registers they are associated with, and jump to aprocedure that takes care of all the steps needed to exit the loop. Each guard is associatedwith a list of variables that should be passed to the frontend to restore the state of theexecution in case the guard fails. When we generate the instructions <strong>for</strong> a guard, weadditionally allocate a small piece of memory which is associated with the guard. In thispiece of memory we store in an encoded way the in<strong>for</strong>mation about where each of thearguments associated with the guard is currently stored. Because of the large numberof guards generated we want to keep this encoding as compact as possible to reduce thememory footprint of the compiled loops. For each variable the encoding consists of upto 6 bytes: one byte <strong>for</strong> the type (int, pointer or float), one <strong>for</strong> the location (stack, registeror immediate) and four <strong>for</strong> the value itself, in the case of register locations we only storethe type and the register number, which on <strong>ARM</strong> fits into one byte.After a guard failure we jump to a pre-generated procedure that serves as a common exitpath <strong>for</strong> all compiled loops. This procedure takes care of saving all values that should bepassed to the frontend and then finally leaves the compiled loop by returning from thefunction that executes the trace. The saving of the values is done by reading the encoding

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!