1/* 2 * Copyright (C) 2012, 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#ifndef CallLinkStatus_h 27#define CallLinkStatus_h 28 29#include "CallLinkInfo.h" 30#include "CodeOrigin.h" 31#include "CodeSpecializationKind.h" 32#include "ConcurrentJITLock.h" 33#include "Intrinsic.h" 34#include "JSCJSValue.h" 35 36namespace JSC { 37 38class CodeBlock; 39class ExecutableBase; 40class InternalFunction; 41class JSFunction; 42class Structure; 43struct CallLinkInfo; 44 45class CallLinkStatus { 46public: 47 CallLinkStatus() 48 : m_executable(0) 49 , m_structure(0) 50 , m_couldTakeSlowPath(false) 51 , m_isProved(false) 52 { 53 } 54 55 static CallLinkStatus takesSlowPath() 56 { 57 CallLinkStatus result; 58 result.m_couldTakeSlowPath = true; 59 return result; 60 } 61 62 explicit CallLinkStatus(JSValue); 63 64 CallLinkStatus(ExecutableBase* executable, Structure* structure) 65 : m_executable(executable) 66 , m_structure(structure) 67 , m_couldTakeSlowPath(false) 68 , m_isProved(false) 69 { 70 ASSERT(!!executable == !!structure); 71 } 72 73 CallLinkStatus& setIsProved(bool isProved) 74 { 75 m_isProved = isProved; 76 return *this; 77 } 78 79 static CallLinkStatus computeFor( 80 CodeBlock*, unsigned bytecodeIndex, const CallLinkInfoMap&); 81 82#if ENABLE(JIT) 83 // Computes the status assuming that we never took slow path and never previously 84 // exited. 85 static CallLinkStatus computeFor(const ConcurrentJITLocker&, CallLinkInfo&); 86#endif 87 88 typedef HashMap<CodeOrigin, CallLinkStatus, CodeOriginApproximateHash> ContextMap; 89 90 // Computes all of the statuses of the DFG code block. Doesn't include statuses that had 91 // no information. Currently we use this when compiling FTL code, to enable polyvariant 92 // inlining. 93 static void computeDFGStatuses(CodeBlock* dfgCodeBlock, ContextMap&); 94 95 // Helper that first consults the ContextMap and then does computeFor(). 96 static CallLinkStatus computeFor( 97 CodeBlock*, CodeOrigin, const CallLinkInfoMap&, const ContextMap&); 98 99 bool isSet() const { return m_callTarget || m_executable || m_couldTakeSlowPath; } 100 101 bool operator!() const { return !isSet(); } 102 103 bool couldTakeSlowPath() const { return m_couldTakeSlowPath; } 104 bool isClosureCall() const { return m_executable && !m_callTarget; } 105 106 JSValue callTarget() const { return m_callTarget; } 107 JSFunction* function() const; 108 InternalFunction* internalFunction() const; 109 Intrinsic intrinsicFor(CodeSpecializationKind) const; 110 ExecutableBase* executable() const { return m_executable; } 111 Structure* structure() const { return m_structure; } 112 bool isProved() const { return m_isProved; } 113 bool canOptimize() const { return (m_callTarget || m_executable) && !m_couldTakeSlowPath; } 114 115 void dump(PrintStream&) const; 116 117private: 118 void makeClosureCall() 119 { 120 ASSERT(!m_isProved); 121 // Turn this into a closure call. 122 m_callTarget = JSValue(); 123 } 124 125 static CallLinkStatus computeFromLLInt(const ConcurrentJITLocker&, CodeBlock*, unsigned bytecodeIndex); 126 127 JSValue m_callTarget; 128 ExecutableBase* m_executable; 129 Structure* m_structure; 130 bool m_couldTakeSlowPath; 131 bool m_isProved; 132}; 133 134} // namespace JSC 135 136#endif // CallLinkStatus_h 137 138