2 * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
27 #include "CallLinkStatus.h"
29 #include "CodeBlock.h"
30 #include "LLIntCallLinkInfo.h"
31 #include "Operations.h"
32 #include <wtf/CommaPrinter.h>
36 CallLinkStatus::CallLinkStatus(JSValue value
)
40 , m_couldTakeSlowPath(false)
43 if (!value
|| !value
.isCell())
46 m_structure
= value
.asCell()->structure();
48 if (!value
.asCell()->inherits(&JSFunction::s_info
))
51 m_executable
= jsCast
<JSFunction
*>(value
.asCell())->executable();
54 JSFunction
* CallLinkStatus::function() const
56 if (!m_callTarget
|| !m_callTarget
.isCell())
59 if (!m_callTarget
.asCell()->inherits(&JSFunction::s_info
))
62 return jsCast
<JSFunction
*>(m_callTarget
.asCell());
65 InternalFunction
* CallLinkStatus::internalFunction() const
67 if (!m_callTarget
|| !m_callTarget
.isCell())
70 if (!m_callTarget
.asCell()->inherits(&InternalFunction::s_info
))
73 return jsCast
<InternalFunction
*>(m_callTarget
.asCell());
76 Intrinsic
CallLinkStatus::intrinsicFor(CodeSpecializationKind kind
) const
81 return m_executable
->intrinsicFor(kind
);
84 CallLinkStatus
CallLinkStatus::computeFromLLInt(CodeBlock
* profiledBlock
, unsigned bytecodeIndex
)
86 UNUSED_PARAM(profiledBlock
);
87 UNUSED_PARAM(bytecodeIndex
);
89 Instruction
* instruction
= profiledBlock
->instructions().begin() + bytecodeIndex
;
90 LLIntCallLinkInfo
* callLinkInfo
= instruction
[4].u
.callLinkInfo
;
92 return CallLinkStatus(callLinkInfo
->lastSeenCallee
.get());
94 return CallLinkStatus();
98 CallLinkStatus
CallLinkStatus::computeFor(CodeBlock
* profiledBlock
, unsigned bytecodeIndex
)
100 UNUSED_PARAM(profiledBlock
);
101 UNUSED_PARAM(bytecodeIndex
);
102 #if ENABLE(JIT) && ENABLE(VALUE_PROFILER)
103 if (!profiledBlock
->numberOfCallLinkInfos())
104 return computeFromLLInt(profiledBlock
, bytecodeIndex
);
106 if (profiledBlock
->couldTakeSlowCase(bytecodeIndex
))
107 return CallLinkStatus::takesSlowPath();
109 CallLinkInfo
& callLinkInfo
= profiledBlock
->getCallLinkInfo(bytecodeIndex
);
110 if (callLinkInfo
.stub
)
111 return CallLinkStatus(callLinkInfo
.stub
->executable(), callLinkInfo
.stub
->structure());
113 JSFunction
* target
= callLinkInfo
.lastSeenCallee
.get();
115 return computeFromLLInt(profiledBlock
, bytecodeIndex
);
117 if (callLinkInfo
.hasSeenClosure
)
118 return CallLinkStatus(target
->executable(), target
->structure());
120 return CallLinkStatus(target
);
122 return CallLinkStatus();
126 void CallLinkStatus::dump(PrintStream
& out
) const
129 out
.print("Not Set");
136 out
.print(comma
, "Statically Proved");
138 if (m_couldTakeSlowPath
)
139 out
.print(comma
, "Could Take Slow Path");
142 out
.print(comma
, "Known target: ", m_callTarget
);
145 out
.print(comma
, "Executable/CallHash: ", RawPointer(m_executable
), "/", m_executable
->hashFor(CodeForCall
));
148 out
.print(comma
, "Structure: ", RawPointer(m_structure
));