/* * Copyright (C) 2013 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef FTLOSRExit_h #define FTLOSRExit_h #include #if ENABLE(FTL_JIT) #include "CodeOrigin.h" #include "DFGExitProfile.h" #include "DFGOSRExitBase.h" #include "FTLAbbreviations.h" #include "FTLExitArgumentList.h" #include "FTLExitValue.h" #include "FTLFormattedValue.h" #include "MethodOfGettingAValueProfile.h" #include "Operands.h" #include "ValueProfile.h" #include "VirtualRegister.h" namespace JSC { namespace FTL { // Tracks one OSR exit site within the FTL JIT. OSR exit in FTL works by deconstructing // the crazy that is OSR down to simple SSA CFG primitives that any compiler backend // (including of course LLVM) can grok and do meaningful things to. Except for // watchpoint-based exits, which haven't yet been implemented (see webkit.org/b/113647), // an exit is just a conditional branch in the emitted code where one destination is the // continuation and the other is a basic block that performs a no-return tail-call to an // exit thunk. This thunk takes as its arguments the live non-constant // not-already-accounted-for bytecode state. To appreciate how this works consider the // following JavaScript program, and its lowering down to LLVM IR including the relevant // exits: // // function foo(o) { // var a = o.a; // predicted int // var b = o.b; // var c = o.c; // NB this is dead // a = a | 5; // our example OSR exit: need to check if a is an int // return a + b; // } // // Just consider the "a | 5". In the DFG IR, this looks like: // // BitOr(Check:Int32:@a, Int32:5) // // Where @a is the node for the GetLocal node that gets the value of the 'a' variable. // Conceptually, this node can be further broken down to the following (note that this // particular lowering never actually happens - we skip this step and go straight to // LLVM IR - but it's still useful to see this): // // exitIf(@a is not int32); // continuation; // // Where 'exitIf()' is a function that will exit if the argument is true, and // 'continuation' is the stuff that we will do after the exitIf() check. (Note that // FTL refers to 'exitIf()' as 'speculate()', which is in line with DFG terminology.) // This then gets broken down to the following LLVM IR, assuming that %0 is the LLVM // value corresponding to variable 'a', and %1 is the LLVM value for variable 'b': // // %2 = ... // the predictate corresponding to '@a is not int32' // br i1 %2, label %3, label %4 // ;