32
edits
(Created page with "== Overview == On-Stack invalidation in IonMonkey is the mechanism by which the following situation is handled: # Ion JITcode is entered. # The JITcode calls a C++ function # T...") |
|||
| Line 32: | Line 32: | ||
=== InvalidateEpilogue === | === InvalidateEpilogue === | ||
Once the C++ code that caused the invalidation finishes execution and returns to Ion JITcode, it will immediately jump to the <tt>invalidateEpilogue</tt>. This epilogue needs to figure out the stack layout, re-create the proper JS interpreter stack corresponding to the JITcode, and | Once the C++ code that caused the invalidation finishes execution and returns to Ion JITcode, it will immediately jump to the <tt>invalidateEpilogue</tt>. This epilogue needs to figure out the stack layout, re-create the proper JS interpreter stack corresponding to the JITcode, then return to the caller of the invalidated JITcode. | ||
This procedure prevents the execution of any on-stack JITcode that has been invalidated. | |||
For every <tt>IonScript</tt> there exists a corresponding <tt>invalidateEpilogue</tt> that's generated when the IonScript is generated. The generation of this code is in <tt>generateInvalidateEpilogue</tt> in ''ion/shared/CodeGenerator-x86-shared.cpp'' (and the corresponding ARM code generator file). | |||
The per-script epilogue assembly code is a thin veneer that: | |||
# Pushes the relevant JSScript pointer onto the stack. | |||
# Calls a common invalidation thunk. | |||
The common invalidation thunk is generated by <tt>IonCompartment::getOrCreateInvalidationThunk</tt> in ''ion/IonCompartment.h'', which is a singleton-creation wrapper around <tt>IonCompartment::generateInvalidator</tt>, which is different for each architecture. The x86 implementation of this method is located in ''ion/x86/Trampoline-x86.cpp'' (see the other relevant trampoline files for the implementations for those architectures). | |||
The behaviour of this code (for x86) is described below: | |||
# pop off 1 word from the stack. - This is to eliminate the return pointer to the script-specific invalidation epilogue code, which got pushed on when the common invalidation chunk was called. | |||
# push all registers onto the stack, remember stack pointer - This is to construct an <tt>InvalidationBailout</tt> on stack. | |||
# reserve sizeof(size_t) on the stack, remember stack pointer - To reserve space for the size of the frame (calculated and returned by <tt>InvalidationBailout</tt> which is passed a pointer to this stack location). | |||
# call the C++ function <tt>InvalidationBailout</tt> in ''ion/Bailouts.cpp''. | |||
edits