+**Note:** this document does not have a proper introduction as to how
+to understand the basics. We should write some. If you happen to be here
+and you're missing context, feel free to pester us on IRC.
+The JIT is very good at making sure some objects are never allocated if they
+don't escape from the trace. Such objects are called ``virtuals``. However,
+if we're dealing with frames, virtuals are often not good enough. Frames
+can escape and they can also be allocated already at the moment we enter the
+JIT. In such cases we need some extra object that can still be optimized away,
+despite existing on heap.
+We introduce virtualizables. They're objects that exist on the heap, but their
+fields are not always in sync with whatever happens in the assembler. One
+example is that virtualizable fields can store virtual objects without
+forcing them. It's very useful for frames. The definition looks like this::
+ _virtualizable2_ = ['locals[*]', 'stackdepth']
+And we use them in ``JitDriver`` like this::
+ jitdriver = JitDriver(greens=, reds=['frame'], virtualizables=['frame'])
+This declaration means that ``stackdepth`` is a virtualizable **field**, while
+``locals`` is a virtualizable **array** (a list stored on a virtualizable).
+There are various rules about using virtualizables, especially using
+virtualizable arrays that can be very confusing. Those will usually end
+up with a compile-time error (as opposed to strange behavior). The rules are:
+* Each array access must be with a known positive index that cannot raise
+ an ``IndexError``. Using ``no = jit.hint(no, promote=True)`` might be useful
+ to get a constant-number access.
+* If you allocate a new virtualizable in the JIT, it has to be done like this
+ (for example if we're in ``Frame.__init__``)::
+ self = hint(self, access_directly=True, fresh_virtualizable=True)
+ that way you can populate the fields directly.
+* If you use virtualizable outside of the JIT - it's very expensive and
+ sometimes aborts tracing. Consider it carefully as to how do it only for
+ debugging purposes and not every time (e.g. ``sys._getframe`` call).
+* If you have something equivalent of a Python generator, where the
+ virtualizable survives for longer, you want to force it before returning.
+ It's better to do it that way than by an external call some time later.
+ It's done using ``jit.hint(frame, force_virtualizable=True)``