]> git.saurik.com Git - apple/javascriptcore.git/blame - bytecode/CallLinkStatus.cpp
JavaScriptCore-1218.35.tar.gz
[apple/javascriptcore.git] / bytecode / CallLinkStatus.cpp
CommitLineData
b37bf2e1 1/*
93a37866 2 * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
b37bf2e1
A
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 *
9dae56ea 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
b37bf2e1
A
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
9dae56ea 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
b37bf2e1
A
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
4e4e5a6f 26#include "config.h"
6fe7ccc8
A
27#include "CallLinkStatus.h"
28
29#include "CodeBlock.h"
30#include "LLIntCallLinkInfo.h"
93a37866
A
31#include "Operations.h"
32#include <wtf/CommaPrinter.h>
b37bf2e1 33
9dae56ea 34namespace JSC {
9dae56ea 35
93a37866
A
36CallLinkStatus::CallLinkStatus(JSValue value)
37 : m_callTarget(value)
38 , m_executable(0)
39 , m_structure(0)
40 , m_couldTakeSlowPath(false)
41 , m_isProved(false)
42{
43 if (!value || !value.isCell())
44 return;
45
46 m_structure = value.asCell()->structure();
47
48 if (!value.asCell()->inherits(&JSFunction::s_info))
49 return;
50
51 m_executable = jsCast<JSFunction*>(value.asCell())->executable();
52}
53
54JSFunction* CallLinkStatus::function() const
55{
56 if (!m_callTarget || !m_callTarget.isCell())
57 return 0;
58
59 if (!m_callTarget.asCell()->inherits(&JSFunction::s_info))
60 return 0;
61
62 return jsCast<JSFunction*>(m_callTarget.asCell());
63}
64
65InternalFunction* CallLinkStatus::internalFunction() const
66{
67 if (!m_callTarget || !m_callTarget.isCell())
68 return 0;
69
70 if (!m_callTarget.asCell()->inherits(&InternalFunction::s_info))
71 return 0;
72
73 return jsCast<InternalFunction*>(m_callTarget.asCell());
74}
75
76Intrinsic CallLinkStatus::intrinsicFor(CodeSpecializationKind kind) const
77{
78 if (!m_executable)
79 return NoIntrinsic;
80
81 return m_executable->intrinsicFor(kind);
82}
83
6fe7ccc8 84CallLinkStatus CallLinkStatus::computeFromLLInt(CodeBlock* profiledBlock, unsigned bytecodeIndex)
4e4e5a6f 85{
6fe7ccc8
A
86 UNUSED_PARAM(profiledBlock);
87 UNUSED_PARAM(bytecodeIndex);
88#if ENABLE(LLINT)
89 Instruction* instruction = profiledBlock->instructions().begin() + bytecodeIndex;
90 LLIntCallLinkInfo* callLinkInfo = instruction[4].u.callLinkInfo;
91
93a37866 92 return CallLinkStatus(callLinkInfo->lastSeenCallee.get());
6fe7ccc8 93#else
93a37866 94 return CallLinkStatus();
6fe7ccc8 95#endif
4e4e5a6f 96}
9dae56ea 97
6fe7ccc8 98CallLinkStatus CallLinkStatus::computeFor(CodeBlock* profiledBlock, unsigned bytecodeIndex)
4e4e5a6f 99{
6fe7ccc8
A
100 UNUSED_PARAM(profiledBlock);
101 UNUSED_PARAM(bytecodeIndex);
102#if ENABLE(JIT) && ENABLE(VALUE_PROFILER)
103 if (!profiledBlock->numberOfCallLinkInfos())
104 return computeFromLLInt(profiledBlock, bytecodeIndex);
105
106 if (profiledBlock->couldTakeSlowCase(bytecodeIndex))
93a37866 107 return CallLinkStatus::takesSlowPath();
6fe7ccc8 108
93a37866
A
109 CallLinkInfo& callLinkInfo = profiledBlock->getCallLinkInfo(bytecodeIndex);
110 if (callLinkInfo.stub)
111 return CallLinkStatus(callLinkInfo.stub->executable(), callLinkInfo.stub->structure());
112
113 JSFunction* target = callLinkInfo.lastSeenCallee.get();
6fe7ccc8
A
114 if (!target)
115 return computeFromLLInt(profiledBlock, bytecodeIndex);
116
93a37866
A
117 if (callLinkInfo.hasSeenClosure)
118 return CallLinkStatus(target->executable(), target->structure());
119
120 return CallLinkStatus(target);
6fe7ccc8 121#else
93a37866 122 return CallLinkStatus();
6fe7ccc8 123#endif
4e4e5a6f 124}
9dae56ea 125
93a37866
A
126void CallLinkStatus::dump(PrintStream& out) const
127{
128 if (!isSet()) {
129 out.print("Not Set");
130 return;
131 }
132
133 CommaPrinter comma;
134
135 if (m_isProved)
136 out.print(comma, "Statically Proved");
137
138 if (m_couldTakeSlowPath)
139 out.print(comma, "Could Take Slow Path");
140
141 if (m_callTarget)
142 out.print(comma, "Known target: ", m_callTarget);
143
144 if (m_executable)
145 out.print(comma, "Executable/CallHash: ", RawPointer(m_executable), "/", m_executable->hashFor(CodeForCall));
146
147 if (m_structure)
148 out.print(comma, "Structure: ", RawPointer(m_structure));
149}
150
4e4e5a6f 151} // namespace JSC
6fe7ccc8 152