/*
* 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
// ;