26 | 26 | '''DFG JIT''' kicks in for functions that are invoked at least 60 times, or that took a loop at least 1000 times. Again, these numbers are approximate and are subject to additional heuristics. The DFG performs aggressive type speculation based on profiling information collected by the lower tiers. This allows it to forward-propagate type information, eliding many type checks. Sometimes the DFG goes further and speculates on values themselves - for example it may speculate that a value loaded from the heap is always some known function in order to enable inlining. The DFG uses deoptimization (we call it "OSR exit") to handle cases where speculation fails. Deoptimization may be synchronous (for example, a branch that checks that the type of a value is that which was expected) or asynchronous (for example, the runtime may observe that the shape or value of some object or variable has changed in a way that contravenes assumptions made by the DFG). The latter is referred to as "watchpointing" in the DFG codebase. Altogether, the Baseline JIT and the DFG JIT share a two-way OSR relationship: the Baseline JIT may OSR into the DFG when a function gets hot, and the DFG may OSR to the Baseline JIT in the case of deoptimization. Repeated OSR exits from the DFG serve as an additional profiling hint: the DFG OSR exit machinery records the reason of the exit (including potentially the values that failed speculation) as well as the frequency with which it occurred; if an exit is taken often enough then reoptimization kicks in: execution is permanently shifted to the Baseline JIT for the affected function, more profiling is gathered, and then the DFG may be later reinvoked. Reoptimization uses exponential back-off to defend against pathological code. The DFG is in [http://trac.webkit.org/browser/trunk/Source/JavaScriptCore/dfg dfg/]. |