1/* 2 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#include "config.h" 27#include "DFGTierUpCheckInjectionPhase.h" 28 29#if ENABLE(DFG_JIT) 30 31#include "DFGGraph.h" 32#include "DFGInsertionSet.h" 33#include "DFGPhase.h" 34#include "FTLCapabilities.h" 35#include "JSCInlines.h" 36 37namespace JSC { namespace DFG { 38 39class TierUpCheckInjectionPhase : public Phase { 40public: 41 TierUpCheckInjectionPhase(Graph& graph) 42 : Phase(graph, "tier-up check injection") 43 { 44 } 45 46 bool run() 47 { 48 RELEASE_ASSERT(m_graph.m_plan.mode == DFGMode); 49 50 if (!Options::useFTLJIT()) 51 return false; 52 53 if (m_graph.m_profiledBlock->m_didFailFTLCompilation) 54 return false; 55 56#if ENABLE(FTL_JIT) 57 FTL::CapabilityLevel level = FTL::canCompile(m_graph); 58 if (level == FTL::CannotCompile) 59 return false; 60 61 if (!Options::enableOSREntryToFTL()) 62 level = FTL::CanCompile; 63 64 InsertionSet insertionSet(m_graph); 65 for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) { 66 BasicBlock* block = m_graph.block(blockIndex); 67 if (!block) 68 continue; 69 70 for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) { 71 Node* node = block->at(nodeIndex); 72 if (node->op() != LoopHint) 73 continue; 74 75 // We only put OSR checks for the first LoopHint in the block. Note that 76 // more than one LoopHint could happen in cases where we did a lot of CFG 77 // simplification in the bytecode parser, but it should be very rare. 78 79 NodeOrigin origin = node->origin; 80 81 if (level != FTL::CanCompileAndOSREnter || origin.semantic.inlineCallFrame) { 82 insertionSet.insertNode( 83 nodeIndex + 1, SpecNone, CheckTierUpInLoop, origin); 84 break; 85 } 86 87 bool isAtTop = true; 88 for (unsigned subNodeIndex = nodeIndex; subNodeIndex--;) { 89 if (!block->at(subNodeIndex)->isSemanticallySkippable()) { 90 isAtTop = false; 91 break; 92 } 93 } 94 95 if (!isAtTop) { 96 insertionSet.insertNode( 97 nodeIndex + 1, SpecNone, CheckTierUpInLoop, origin); 98 break; 99 } 100 101 insertionSet.insertNode( 102 nodeIndex + 1, SpecNone, CheckTierUpAndOSREnter, origin); 103 break; 104 } 105 106 if (block->last()->op() == Return) { 107 insertionSet.insertNode( 108 block->size() - 1, SpecNone, CheckTierUpAtReturn, block->last()->origin); 109 } 110 111 insertionSet.execute(block); 112 } 113 114 m_graph.m_plan.willTryToTierUp = true; 115 return true; 116#else // ENABLE(FTL_JIT) 117 RELEASE_ASSERT_NOT_REACHED(); 118 return false; 119#endif // ENABLE(FTL_JIT) 120 } 121}; 122 123bool performTierUpCheckInjection(Graph& graph) 124{ 125 SamplingRegion samplingRegion("DFG Tier-up Check Injection"); 126 return runPhase<TierUpCheckInjectionPhase>(graph); 127} 128 129} } // namespace JSC::DFG 130 131#endif // ENABLE(DFG_JIT) 132 133 134