blob: 1d1ff73dfdf938a5857aa3e9390b0c5e8c8ceb14 [file] [log] [blame]
oliver@apple.com2b2e1322013-07-25 04:02:28 +00001/*
jfbastien@apple.comd9f999e2017-10-20 02:23:29 +00002 * Copyright (C) 2013, 2015-2017 Apple Inc. All rights reserved.
oliver@apple.com2b2e1322013-07-25 04:02:28 +00003 *
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"
mark.lam@apple.comfa2a1422013-09-05 00:40:15 +000027#include "StackVisitor.h"
oliver@apple.com2b2e1322013-07-25 04:02:28 +000028
fpizlo@apple.comda834ae2015-03-26 04:28:43 +000029#include "ClonedArguments.h"
commit-queue@webkit.org1cb22272016-04-22 00:50:09 +000030#include "DebuggerPrimitives.h"
ggaren@apple.com21cd7022015-08-18 18:28:54 +000031#include "InlineCallFrame.h"
mark.lam@apple.comfd861642013-08-29 17:41:44 +000032#include "Interpreter.h"
fpizlo@apple.comfb7eff22014-02-11 01:45:50 +000033#include "JSCInlines.h"
sbarati@apple.com5db42f82017-04-04 22:23:37 +000034#include "WasmCallee.h"
jfbastien@apple.com381e3332017-05-10 18:15:17 +000035#include "WasmIndexOrName.h"
joepeck@webkit.org7e07f392016-09-22 18:59:47 +000036#include <wtf/text/StringBuilder.h>
oliver@apple.com2b2e1322013-07-25 04:02:28 +000037
38namespace JSC {
39
sbarati@apple.com5db42f82017-04-04 22:23:37 +000040StackVisitor::StackVisitor(CallFrame* startFrame, VM* vm)
oliver@apple.com2b2e1322013-07-25 04:02:28 +000041{
mark.lam@apple.comfa2a1422013-09-05 00:40:15 +000042 m_frame.m_index = 0;
sbarati@apple.com812da912016-12-12 03:11:18 +000043 m_frame.m_isWasmFrame = false;
msaboff@apple.com42984082014-08-20 20:28:24 +000044 CallFrame* topFrame;
45 if (startFrame) {
sbarati@apple.com5db42f82017-04-04 22:23:37 +000046 ASSERT(vm);
jfbastien@apple.comd9f999e2017-10-20 02:23:29 +000047 m_frame.m_entryFrame = vm->topEntryFrame;
sbarati@apple.com5db42f82017-04-04 22:23:37 +000048 topFrame = vm->topCallFrame;
fpizlo@apple.com75dcea92016-08-02 05:38:58 +000049
jfbastien@apple.comd9f999e2017-10-20 02:23:29 +000050 if (topFrame && static_cast<void*>(m_frame.m_entryFrame) == static_cast<void*>(topFrame)) {
51 topFrame = vmEntryRecord(m_frame.m_entryFrame)->m_prevTopCallFrame;
52 m_frame.m_entryFrame = vmEntryRecord(m_frame.m_entryFrame)->m_prevTopEntryFrame;
fpizlo@apple.com75dcea92016-08-02 05:38:58 +000053 }
msaboff@apple.com42984082014-08-20 20:28:24 +000054 } else {
jfbastien@apple.comd9f999e2017-10-20 02:23:29 +000055 m_frame.m_entryFrame = 0;
msaboff@apple.com42984082014-08-20 20:28:24 +000056 topFrame = 0;
57 }
jfbastien@apple.comd9f999e2017-10-20 02:23:29 +000058 m_frame.m_callerIsEntryFrame = false;
msaboff@apple.com42984082014-08-20 20:28:24 +000059 readFrame(topFrame);
60
61 // Find the frame the caller wants to start unwinding from.
62 while (m_frame.callFrame() && m_frame.callFrame() != startFrame)
63 gotoNextFrame();
mark.lam@apple.com304d5972013-08-08 16:57:07 +000064}
65
mark.lam@apple.comfa2a1422013-09-05 00:40:15 +000066void StackVisitor::gotoNextFrame()
oliver@apple.com2b2e1322013-07-25 04:02:28 +000067{
mark.lam@apple.com1cfbb242016-06-03 14:53:16 +000068 m_frame.m_index++;
mark.lam@apple.comfd861642013-08-29 17:41:44 +000069#if ENABLE(DFG_JIT)
70 if (m_frame.isInlinedFrame()) {
71 InlineCallFrame* inlineCallFrame = m_frame.inlineCallFrame();
msaboff@apple.comcde665e2015-11-03 20:02:02 +000072 CodeOrigin* callerCodeOrigin = inlineCallFrame->getCallerSkippingTailCalls();
msaboff@apple.coma3dc7532015-09-24 21:42:59 +000073 if (!callerCodeOrigin) {
74 while (inlineCallFrame) {
75 readInlinedFrame(m_frame.callFrame(), &inlineCallFrame->directCaller);
76 inlineCallFrame = m_frame.inlineCallFrame();
77 }
jfbastien@apple.comd9f999e2017-10-20 02:23:29 +000078 m_frame.m_entryFrame = m_frame.m_callerEntryFrame;
msaboff@apple.coma3dc7532015-09-24 21:42:59 +000079 readFrame(m_frame.callerFrame());
80 } else
81 readInlinedFrame(m_frame.callFrame(), callerCodeOrigin);
msaboff@apple.com0576b242014-08-22 19:54:30 +000082 return;
83 }
mark.lam@apple.comfd861642013-08-29 17:41:44 +000084#endif // ENABLE(DFG_JIT)
jfbastien@apple.comd9f999e2017-10-20 02:23:29 +000085 m_frame.m_entryFrame = m_frame.m_callerEntryFrame;
msaboff@apple.com0576b242014-08-22 19:54:30 +000086 readFrame(m_frame.callerFrame());
mark.lam@apple.comfd861642013-08-29 17:41:44 +000087}
88
sbarati@apple.com36c13402015-09-18 23:37:42 +000089void StackVisitor::unwindToMachineCodeBlockFrame()
90{
91#if ENABLE(DFG_JIT)
sbarati@apple.com36808c82016-07-06 05:25:06 +000092 if (m_frame.isInlinedFrame()) {
93 CodeOrigin codeOrigin = m_frame.inlineCallFrame()->directCaller;
94 while (codeOrigin.inlineCallFrame)
95 codeOrigin = codeOrigin.inlineCallFrame->directCaller;
96 readNonInlinedFrame(m_frame.callFrame(), &codeOrigin);
97 }
sbarati@apple.com36c13402015-09-18 23:37:42 +000098#endif
99}
100
mark.lam@apple.comfa2a1422013-09-05 00:40:15 +0000101void StackVisitor::readFrame(CallFrame* callFrame)
mark.lam@apple.comfd861642013-08-29 17:41:44 +0000102{
mark.lam@apple.comfd861642013-08-29 17:41:44 +0000103 if (!callFrame) {
104 m_frame.setToEnd();
105 return;
106 }
107
sbarati@apple.com5db42f82017-04-04 22:23:37 +0000108 if (callFrame->isAnyWasmCallee()) {
sbarati@apple.com812da912016-12-12 03:11:18 +0000109 readNonInlinedFrame(callFrame);
110 return;
111 }
112
mark.lam@apple.comfd861642013-08-29 17:41:44 +0000113#if !ENABLE(DFG_JIT)
114 readNonInlinedFrame(callFrame);
115
116#else // !ENABLE(DFG_JIT)
117 // If the frame doesn't have a code block, then it's not a DFG frame.
118 // Hence, we're not at an inlined frame.
119 CodeBlock* codeBlock = callFrame->codeBlock();
120 if (!codeBlock) {
121 readNonInlinedFrame(callFrame);
122 return;
123 }
124
125 // If the code block does not have any code origins, then there's no
126 // inlining. Hence, we're not at an inlined frame.
127 if (!codeBlock->hasCodeOrigins()) {
128 readNonInlinedFrame(callFrame);
129 return;
130 }
131
saambarati1@gmail.com9137c0b2015-08-25 19:40:46 +0000132 CallSiteIndex index = callFrame->callSiteIndex();
mark.lam@apple.comfd861642013-08-29 17:41:44 +0000133 ASSERT(codeBlock->canGetCodeOrigin(index));
134 if (!codeBlock->canGetCodeOrigin(index)) {
135 // See assertion above. In release builds, we try to protect ourselves
136 // from crashing even though stack walking will be goofed up.
137 m_frame.setToEnd();
138 return;
139 }
140
141 CodeOrigin codeOrigin = codeBlock->codeOrigin(index);
142 if (!codeOrigin.inlineCallFrame) {
143 readNonInlinedFrame(callFrame, &codeOrigin);
144 return;
145 }
146
147 readInlinedFrame(callFrame, &codeOrigin);
148#endif // !ENABLE(DFG_JIT)
149}
150
mark.lam@apple.comfa2a1422013-09-05 00:40:15 +0000151void StackVisitor::readNonInlinedFrame(CallFrame* callFrame, CodeOrigin* codeOrigin)
mark.lam@apple.comfd861642013-08-29 17:41:44 +0000152{
153 m_frame.m_callFrame = callFrame;
154 m_frame.m_argumentCountIncludingThis = callFrame->argumentCountIncludingThis();
jfbastien@apple.comd9f999e2017-10-20 02:23:29 +0000155 m_frame.m_callerEntryFrame = m_frame.m_entryFrame;
156 m_frame.m_callerFrame = callFrame->callerFrame(m_frame.m_callerEntryFrame);
157 m_frame.m_callerIsEntryFrame = m_frame.m_callerEntryFrame != m_frame.m_entryFrame;
sbarati@apple.com812da912016-12-12 03:11:18 +0000158 m_frame.m_isWasmFrame = false;
159
sbarati@apple.com5db42f82017-04-04 22:23:37 +0000160 CalleeBits callee = callFrame->callee();
sbarati@apple.com812da912016-12-12 03:11:18 +0000161 m_frame.m_callee = callee;
162
sbarati@apple.com5db42f82017-04-04 22:23:37 +0000163 if (callFrame->isAnyWasmCallee()) {
sbarati@apple.com812da912016-12-12 03:11:18 +0000164 m_frame.m_isWasmFrame = true;
165 m_frame.m_codeBlock = nullptr;
166 m_frame.m_bytecodeOffset = 0;
sbarati@apple.com58e60342017-04-27 03:38:12 +0000167#if ENABLE(WEBASSEMBLY)
168 CalleeBits bits = callFrame->callee();
169 if (bits.isWasm())
jfbastien@apple.com381e3332017-05-10 18:15:17 +0000170 m_frame.m_wasmFunctionIndexOrName = bits.asWasmCallee()->indexOrName();
sbarati@apple.com58e60342017-04-27 03:38:12 +0000171#endif
sbarati@apple.com812da912016-12-12 03:11:18 +0000172 } else {
173 m_frame.m_codeBlock = callFrame->codeBlock();
174 m_frame.m_bytecodeOffset = !m_frame.codeBlock() ? 0
175 : codeOrigin ? codeOrigin->bytecodeIndex
176 : callFrame->bytecodeOffset();
177
178 }
179
mark.lam@apple.comfd861642013-08-29 17:41:44 +0000180#if ENABLE(DFG_JIT)
181 m_frame.m_inlineCallFrame = 0;
182#endif
183}
184
185#if ENABLE(DFG_JIT)
msaboff@apple.comb70e41b2013-09-13 18:03:55 +0000186static int inlinedFrameOffset(CodeOrigin* codeOrigin)
mark.lam@apple.comfd861642013-08-29 17:41:44 +0000187{
188 InlineCallFrame* inlineCallFrame = codeOrigin->inlineCallFrame;
msaboff@apple.comb70e41b2013-09-13 18:03:55 +0000189 int frameOffset = inlineCallFrame ? inlineCallFrame->stackOffset : 0;
mark.lam@apple.comfd861642013-08-29 17:41:44 +0000190 return frameOffset;
191}
192
mark.lam@apple.comfa2a1422013-09-05 00:40:15 +0000193void StackVisitor::readInlinedFrame(CallFrame* callFrame, CodeOrigin* codeOrigin)
mark.lam@apple.comfd861642013-08-29 17:41:44 +0000194{
195 ASSERT(codeOrigin);
sbarati@apple.com812da912016-12-12 03:11:18 +0000196 m_frame.m_isWasmFrame = false;
mark.lam@apple.comfd861642013-08-29 17:41:44 +0000197
msaboff@apple.comb70e41b2013-09-13 18:03:55 +0000198 int frameOffset = inlinedFrameOffset(codeOrigin);
mark.lam@apple.comfd861642013-08-29 17:41:44 +0000199 bool isInlined = !!frameOffset;
200 if (isInlined) {
201 InlineCallFrame* inlineCallFrame = codeOrigin->inlineCallFrame;
202
203 m_frame.m_callFrame = callFrame;
204 m_frame.m_inlineCallFrame = inlineCallFrame;
fpizlo@apple.com8fefdd32015-02-18 19:55:47 +0000205 if (inlineCallFrame->argumentCountRegister.isValid())
206 m_frame.m_argumentCountIncludingThis = callFrame->r(inlineCallFrame->argumentCountRegister.offset()).unboxedInt32();
207 else
utatane.tea@gmail.com0c7cd0b2017-09-02 08:35:46 +0000208 m_frame.m_argumentCountIncludingThis = inlineCallFrame->argumentCountIncludingThis;
ggaren@apple.com81def5f2015-10-09 23:10:16 +0000209 m_frame.m_codeBlock = inlineCallFrame->baselineCodeBlock.get();
mark.lam@apple.comfd861642013-08-29 17:41:44 +0000210 m_frame.m_bytecodeOffset = codeOrigin->bytecodeIndex;
211
fpizlo@apple.coma62d4822013-10-06 04:22:43 +0000212 JSFunction* callee = inlineCallFrame->calleeForCallFrame(callFrame);
fpizlo@apple.coma62d4822013-10-06 04:22:43 +0000213 m_frame.m_callee = callee;
sbarati@apple.com5db42f82017-04-04 22:23:37 +0000214 ASSERT(!!m_frame.callee().rawPtr());
mark.lam@apple.comfd861642013-08-29 17:41:44 +0000215
216 // The callerFrame just needs to be non-null to indicate that we
217 // haven't reached the last frame yet. Setting it to the root
218 // frame (i.e. the callFrame that this inlined frame is called from)
219 // would work just fine.
220 m_frame.m_callerFrame = callFrame;
221 return;
222 }
223
224 readNonInlinedFrame(callFrame, codeOrigin);
225}
226#endif // ENABLE(DFG_JIT)
227
mark.lam@apple.comfa2a1422013-09-05 00:40:15 +0000228StackVisitor::Frame::CodeType StackVisitor::Frame::codeType() const
oliver@apple.com2b2e1322013-07-25 04:02:28 +0000229{
sbarati@apple.com812da912016-12-12 03:11:18 +0000230 if (isWasmFrame())
231 return CodeType::Wasm;
232
233 if (!codeBlock())
ossy@webkit.org0bf30c52013-09-12 15:28:14 +0000234 return CodeType::Native;
oliver@apple.com2b2e1322013-07-25 04:02:28 +0000235
236 switch (codeBlock()->codeType()) {
237 case EvalCode:
ossy@webkit.org0bf30c52013-09-12 15:28:14 +0000238 return CodeType::Eval;
utatane.tea@gmail.coma8309d92015-09-01 02:05:30 +0000239 case ModuleCode:
240 return CodeType::Module;
oliver@apple.com2b2e1322013-07-25 04:02:28 +0000241 case FunctionCode:
ossy@webkit.org0bf30c52013-09-12 15:28:14 +0000242 return CodeType::Function;
oliver@apple.com2b2e1322013-07-25 04:02:28 +0000243 case GlobalCode:
ossy@webkit.org0bf30c52013-09-12 15:28:14 +0000244 return CodeType::Global;
oliver@apple.com2b2e1322013-07-25 04:02:28 +0000245 }
246 RELEASE_ASSERT_NOT_REACHED();
ossy@webkit.org0bf30c52013-09-12 15:28:14 +0000247 return CodeType::Global;
oliver@apple.com2b2e1322013-07-25 04:02:28 +0000248}
249
sbarati@apple.com812da912016-12-12 03:11:18 +0000250RegisterAtOffsetList* StackVisitor::Frame::calleeSaveRegisters()
251{
252 if (isInlinedFrame())
253 return nullptr;
254
sbarati@apple.com02a8f692016-12-12 20:55:23 +0000255#if ENABLE(JIT) && NUMBER_OF_CALLEE_SAVES_REGISTERS > 0
256
sbarati@apple.com812da912016-12-12 03:11:18 +0000257#if ENABLE(WEBASSEMBLY)
258 if (isWasmFrame()) {
sbarati@apple.com5db42f82017-04-04 22:23:37 +0000259 if (callee().isCell()) {
260 RELEASE_ASSERT(isWebAssemblyToJSCallee(callee().asCell()));
261 return nullptr;
sbarati@apple.com812da912016-12-12 03:11:18 +0000262 }
sbarati@apple.com5db42f82017-04-04 22:23:37 +0000263 Wasm::Callee* wasmCallee = callee().asWasmCallee();
264 return wasmCallee->calleeSaveRegisters();
sbarati@apple.com812da912016-12-12 03:11:18 +0000265 }
sbarati@apple.com02a8f692016-12-12 20:55:23 +0000266#endif // ENABLE(WEBASSEMBLY)
sbarati@apple.com812da912016-12-12 03:11:18 +0000267
268 if (CodeBlock* codeBlock = this->codeBlock())
269 return codeBlock->calleeSaveRegisters();
270
sbarati@apple.com02a8f692016-12-12 20:55:23 +0000271#endif // ENABLE(JIT) && NUMBER_OF_CALLEE_SAVES_REGISTERS > 0
272
sbarati@apple.com812da912016-12-12 03:11:18 +0000273 return nullptr;
274}
275
mark.lam@apple.com1cfbb242016-06-03 14:53:16 +0000276String StackVisitor::Frame::functionName() const
oliver@apple.com2b2e1322013-07-25 04:02:28 +0000277{
278 String traceLine;
oliver@apple.com2b2e1322013-07-25 04:02:28 +0000279
280 switch (codeType()) {
sbarati@apple.com812da912016-12-12 03:11:18 +0000281 case CodeType::Wasm:
jfbastien@apple.comc1399852017-12-01 02:41:10 +0000282 traceLine = makeString(m_wasmFunctionIndexOrName);
sbarati@apple.com812da912016-12-12 03:11:18 +0000283 break;
ossy@webkit.org0bf30c52013-09-12 15:28:14 +0000284 case CodeType::Eval:
commit-queue@webkit.org29e710c2014-08-29 21:33:30 +0000285 traceLine = ASCIILiteral("eval code");
oliver@apple.com2b2e1322013-07-25 04:02:28 +0000286 break;
utatane.tea@gmail.coma8309d92015-09-01 02:05:30 +0000287 case CodeType::Module:
288 traceLine = ASCIILiteral("module code");
289 break;
sbarati@apple.com5db42f82017-04-04 22:23:37 +0000290 case CodeType::Native: {
291 JSCell* callee = this->callee().asCell();
oliver@apple.com2b2e1322013-07-25 04:02:28 +0000292 if (callee)
sbarati@apple.com812da912016-12-12 03:11:18 +0000293 traceLine = getCalculatedDisplayName(callFrame()->vm(), jsCast<JSObject*>(callee)).impl();
oliver@apple.com2b2e1322013-07-25 04:02:28 +0000294 break;
sbarati@apple.com5db42f82017-04-04 22:23:37 +0000295 }
296 case CodeType::Function:
297 traceLine = getCalculatedDisplayName(callFrame()->vm(), jsCast<JSObject*>(this->callee().asCell())).impl();
oliver@apple.com2b2e1322013-07-25 04:02:28 +0000298 break;
ossy@webkit.org0bf30c52013-09-12 15:28:14 +0000299 case CodeType::Global:
commit-queue@webkit.org29e710c2014-08-29 21:33:30 +0000300 traceLine = ASCIILiteral("global code");
oliver@apple.com2b2e1322013-07-25 04:02:28 +0000301 break;
302 }
303 return traceLine.isNull() ? emptyString() : traceLine;
304}
305
mark.lam@apple.com1cfbb242016-06-03 14:53:16 +0000306String StackVisitor::Frame::sourceURL() const
oliver@apple.com2b2e1322013-07-25 04:02:28 +0000307{
308 String traceLine;
309
310 switch (codeType()) {
ossy@webkit.org0bf30c52013-09-12 15:28:14 +0000311 case CodeType::Eval:
utatane.tea@gmail.coma8309d92015-09-01 02:05:30 +0000312 case CodeType::Module:
ossy@webkit.org0bf30c52013-09-12 15:28:14 +0000313 case CodeType::Function:
314 case CodeType::Global: {
commit-queue@webkit.orgfa196632015-08-28 21:07:22 +0000315 String sourceURL = codeBlock()->ownerScriptExecutable()->sourceURL();
oliver@apple.com2b2e1322013-07-25 04:02:28 +0000316 if (!sourceURL.isEmpty())
317 traceLine = sourceURL.impl();
318 break;
319 }
ossy@webkit.org0bf30c52013-09-12 15:28:14 +0000320 case CodeType::Native:
commit-queue@webkit.org29e710c2014-08-29 21:33:30 +0000321 traceLine = ASCIILiteral("[native code]");
oliver@apple.com2b2e1322013-07-25 04:02:28 +0000322 break;
sbarati@apple.com812da912016-12-12 03:11:18 +0000323 case CodeType::Wasm:
324 traceLine = ASCIILiteral("[wasm code]");
325 break;
oliver@apple.com2b2e1322013-07-25 04:02:28 +0000326 }
327 return traceLine.isNull() ? emptyString() : traceLine;
328}
329
mark.lam@apple.com1cfbb242016-06-03 14:53:16 +0000330String StackVisitor::Frame::toString() const
oliver@apple.com2b2e1322013-07-25 04:02:28 +0000331{
332 StringBuilder traceBuild;
333 String functionName = this->functionName();
334 String sourceURL = this->sourceURL();
335 traceBuild.append(functionName);
336 if (!sourceURL.isEmpty()) {
337 if (!functionName.isEmpty())
338 traceBuild.append('@');
339 traceBuild.append(sourceURL);
sbarati@apple.com812da912016-12-12 03:11:18 +0000340 if (hasLineAndColumnInfo()) {
oliver@apple.com2b2e1322013-07-25 04:02:28 +0000341 unsigned line = 0;
342 unsigned column = 0;
343 computeLineAndColumn(line, column);
344 traceBuild.append(':');
345 traceBuild.appendNumber(line);
346 traceBuild.append(':');
347 traceBuild.appendNumber(column);
348 }
349 }
350 return traceBuild.toString().impl();
351}
352
commit-queue@webkit.org1cb22272016-04-22 00:50:09 +0000353intptr_t StackVisitor::Frame::sourceID()
354{
355 if (CodeBlock* codeBlock = this->codeBlock())
356 return codeBlock->ownerScriptExecutable()->sourceID();
357 return noSourceID;
358}
359
fpizlo@apple.comda834ae2015-03-26 04:28:43 +0000360ClonedArguments* StackVisitor::Frame::createArguments()
oliver@apple.com2b2e1322013-07-25 04:02:28 +0000361{
mark.lam@apple.comfd861642013-08-29 17:41:44 +0000362 ASSERT(m_callFrame);
363 CallFrame* physicalFrame = m_callFrame;
fpizlo@apple.comda834ae2015-03-26 04:28:43 +0000364 ClonedArguments* arguments;
fpizlo@apple.com9bb773c2014-09-27 20:27:59 +0000365 ArgumentsMode mode;
mark.lam@apple.comee3c4102015-10-14 18:57:07 +0000366 if (Options::useFunctionDotArguments())
fpizlo@apple.comda834ae2015-03-26 04:28:43 +0000367 mode = ArgumentsMode::Cloned;
fpizlo@apple.com9bb773c2014-09-27 20:27:59 +0000368 else
fpizlo@apple.comda834ae2015-03-26 04:28:43 +0000369 mode = ArgumentsMode::FakeValues;
mark.lam@apple.comfd861642013-08-29 17:41:44 +0000370#if ENABLE(DFG_JIT)
371 if (isInlinedFrame()) {
372 ASSERT(m_inlineCallFrame);
fpizlo@apple.comda834ae2015-03-26 04:28:43 +0000373 arguments = ClonedArguments::createWithInlineFrame(physicalFrame, physicalFrame, m_inlineCallFrame, mode);
mark.lam@apple.comfd861642013-08-29 17:41:44 +0000374 } else
375#endif
fpizlo@apple.comda834ae2015-03-26 04:28:43 +0000376 arguments = ClonedArguments::createWithMachineFrame(physicalFrame, physicalFrame, mode);
oliver@apple.com2b2e1322013-07-25 04:02:28 +0000377 return arguments;
378}
379
sbarati@apple.com812da912016-12-12 03:11:18 +0000380bool StackVisitor::Frame::hasLineAndColumnInfo() const
381{
382 return !!codeBlock();
383}
384
mark.lam@apple.com1cfbb242016-06-03 14:53:16 +0000385void StackVisitor::Frame::computeLineAndColumn(unsigned& line, unsigned& column) const
oliver@apple.com2b2e1322013-07-25 04:02:28 +0000386{
387 CodeBlock* codeBlock = this->codeBlock();
388 if (!codeBlock) {
389 line = 0;
390 column = 0;
391 return;
392 }
393
394 int divot = 0;
395 int unusedStartOffset = 0;
396 int unusedEndOffset = 0;
397 unsigned divotLine = 0;
398 unsigned divotColumn = 0;
399 retrieveExpressionInfo(divot, unusedStartOffset, unusedEndOffset, divotLine, divotColumn);
400
commit-queue@webkit.orgfa196632015-08-28 21:07:22 +0000401 line = divotLine + codeBlock->ownerScriptExecutable()->firstLine();
oliver@apple.com2b2e1322013-07-25 04:02:28 +0000402 column = divotColumn + (divotLine ? 1 : codeBlock->firstLineColumnOffset());
ggaren@apple.com7a6a0f62015-03-26 23:12:39 +0000403
commit-queue@webkit.orgfa196632015-08-28 21:07:22 +0000404 if (codeBlock->ownerScriptExecutable()->hasOverrideLineNumber())
405 line = codeBlock->ownerScriptExecutable()->overrideLineNumber();
oliver@apple.com2b2e1322013-07-25 04:02:28 +0000406}
407
mark.lam@apple.com1cfbb242016-06-03 14:53:16 +0000408void StackVisitor::Frame::retrieveExpressionInfo(int& divot, int& startOffset, int& endOffset, unsigned& line, unsigned& column) const
oliver@apple.com2b2e1322013-07-25 04:02:28 +0000409{
410 CodeBlock* codeBlock = this->codeBlock();
411 codeBlock->unlinkedCodeBlock()->expressionRangeForBytecodeOffset(bytecodeOffset(), divot, startOffset, endOffset, line, column);
412 divot += codeBlock->sourceOffset();
413}
414
mark.lam@apple.comfa2a1422013-09-05 00:40:15 +0000415void StackVisitor::Frame::setToEnd()
oliver@apple.com2b2e1322013-07-25 04:02:28 +0000416{
mark.lam@apple.comfd861642013-08-29 17:41:44 +0000417 m_callFrame = 0;
418#if ENABLE(DFG_JIT)
419 m_inlineCallFrame = 0;
420#endif
sbarati@apple.com812da912016-12-12 03:11:18 +0000421 m_isWasmFrame = false;
oliver@apple.com2b2e1322013-07-25 04:02:28 +0000422}
423
mark.lam@apple.com1cfbb242016-06-03 14:53:16 +0000424void StackVisitor::Frame::dump(PrintStream& out, Indenter indent) const
oliver@apple.com2b2e1322013-07-25 04:02:28 +0000425{
mark.lam@apple.com1cfbb242016-06-03 14:53:16 +0000426 dump(out, indent, [] (PrintStream&) { });
oliver@apple.com2b2e1322013-07-25 04:02:28 +0000427}
428
mark.lam@apple.com1cfbb242016-06-03 14:53:16 +0000429void StackVisitor::Frame::dump(PrintStream& out, Indenter indent, std::function<void(PrintStream&)> prefix) const
oliver@apple.com2b2e1322013-07-25 04:02:28 +0000430{
mark.lam@apple.combce4c9b2013-09-04 00:26:57 +0000431 if (!this->callFrame()) {
mark.lam@apple.com1cfbb242016-06-03 14:53:16 +0000432 out.print(indent, "frame 0x0\n");
mark.lam@apple.combce4c9b2013-09-04 00:26:57 +0000433 return;
434 }
435
oliver@apple.com2b2e1322013-07-25 04:02:28 +0000436 CodeBlock* codeBlock = this->codeBlock();
mark.lam@apple.com1cfbb242016-06-03 14:53:16 +0000437 out.print(indent);
438 prefix(out);
439 out.print("frame ", RawPointer(this->callFrame()), " {\n");
oliver@apple.com2b2e1322013-07-25 04:02:28 +0000440
mark.lam@apple.com507b94e2015-04-17 00:25:14 +0000441 {
442 indent++;
oliver@apple.com2b2e1322013-07-25 04:02:28 +0000443
mark.lam@apple.com507b94e2015-04-17 00:25:14 +0000444 CallFrame* callFrame = m_callFrame;
445 CallFrame* callerFrame = this->callerFrame();
446 void* returnPC = callFrame->hasReturnPC() ? callFrame->returnPC().value() : nullptr;
447
mark.lam@apple.com1cfbb242016-06-03 14:53:16 +0000448 out.print(indent, "name: ", functionName(), "\n");
449 out.print(indent, "sourceURL: ", sourceURL(), "\n");
oliver@apple.com2b2e1322013-07-25 04:02:28 +0000450
mark.lam@apple.comb04e85d2015-04-17 01:03:55 +0000451 bool isInlined = false;
mark.lam@apple.comfd861642013-08-29 17:41:44 +0000452#if ENABLE(DFG_JIT)
mark.lam@apple.comb04e85d2015-04-17 01:03:55 +0000453 isInlined = isInlinedFrame();
mark.lam@apple.com1cfbb242016-06-03 14:53:16 +0000454 out.print(indent, "isInlinedFrame: ", isInlinedFrame(), "\n");
mark.lam@apple.com507b94e2015-04-17 00:25:14 +0000455 if (isInlinedFrame())
mark.lam@apple.com1cfbb242016-06-03 14:53:16 +0000456 out.print(indent, "InlineCallFrame: ", RawPointer(m_inlineCallFrame), "\n");
mark.lam@apple.comfd861642013-08-29 17:41:44 +0000457#endif
oliver@apple.com2b2e1322013-07-25 04:02:28 +0000458
sbarati@apple.com5db42f82017-04-04 22:23:37 +0000459 out.print(indent, "callee: ", RawPointer(callee().rawPtr()), "\n");
mark.lam@apple.com1cfbb242016-06-03 14:53:16 +0000460 out.print(indent, "returnPC: ", RawPointer(returnPC), "\n");
461 out.print(indent, "callerFrame: ", RawPointer(callerFrame), "\n");
commit-queue@webkit.org0cbf4f62018-01-31 04:47:43 +0000462 uintptr_t locationRawBits = callFrame->callSiteAsRawBits();
463 out.print(indent, "rawLocationBits: ", locationRawBits,
mark.lam@apple.com1cfbb242016-06-03 14:53:16 +0000464 " ", RawPointer(reinterpret_cast<void*>(locationRawBits)), "\n");
465 out.print(indent, "codeBlock: ", RawPointer(codeBlock));
mark.lam@apple.com507b94e2015-04-17 00:25:14 +0000466 if (codeBlock)
mark.lam@apple.come8499712016-11-10 21:42:33 +0000467 out.print(" ", *codeBlock);
mark.lam@apple.com1cfbb242016-06-03 14:53:16 +0000468 out.print("\n");
mark.lam@apple.comb04e85d2015-04-17 01:03:55 +0000469 if (codeBlock && !isInlined) {
mark.lam@apple.com507b94e2015-04-17 00:25:14 +0000470 indent++;
471
saambarati1@gmail.com9137c0b2015-08-25 19:40:46 +0000472 if (callFrame->callSiteBitsAreBytecodeOffset()) {
473 unsigned bytecodeOffset = callFrame->bytecodeOffset();
mark.lam@apple.com1cfbb242016-06-03 14:53:16 +0000474 out.print(indent, "bytecodeOffset: ", bytecodeOffset, " of ", codeBlock->instructions().size(), "\n");
oliver@apple.com0d587912013-07-25 04:04:39 +0000475#if ENABLE(DFG_JIT)
mark.lam@apple.com507b94e2015-04-17 00:25:14 +0000476 } else {
mark.lam@apple.com1cfbb242016-06-03 14:53:16 +0000477 out.print(indent, "hasCodeOrigins: ", codeBlock->hasCodeOrigins(), "\n");
mark.lam@apple.com507b94e2015-04-17 00:25:14 +0000478 if (codeBlock->hasCodeOrigins()) {
saambarati1@gmail.com9137c0b2015-08-25 19:40:46 +0000479 CallSiteIndex callSiteIndex = callFrame->callSiteIndex();
mark.lam@apple.com1cfbb242016-06-03 14:53:16 +0000480 out.print(indent, "callSiteIndex: ", callSiteIndex.bits(), " of ", codeBlock->codeOrigins().size(), "\n");
mark.lam@apple.com507b94e2015-04-17 00:25:14 +0000481
482 JITCode::JITType jitType = codeBlock->jitType();
483 if (jitType != JITCode::FTLJIT) {
484 JITCode* jitCode = codeBlock->jitCode().get();
mark.lam@apple.com1cfbb242016-06-03 14:53:16 +0000485 out.print(indent, "jitCode: ", RawPointer(jitCode),
486 " start ", RawPointer(jitCode->start()),
487 " end ", RawPointer(jitCode->end()), "\n");
mark.lam@apple.com507b94e2015-04-17 00:25:14 +0000488 }
489 }
oliver@apple.com0d587912013-07-25 04:04:39 +0000490#endif
mark.lam@apple.com507b94e2015-04-17 00:25:14 +0000491 }
492 unsigned line = 0;
493 unsigned column = 0;
494 computeLineAndColumn(line, column);
mark.lam@apple.com1cfbb242016-06-03 14:53:16 +0000495 out.print(indent, "line: ", line, "\n");
496 out.print(indent, "column: ", column, "\n");
mark.lam@apple.com507b94e2015-04-17 00:25:14 +0000497
498 indent--;
oliver@apple.com2b2e1322013-07-25 04:02:28 +0000499 }
jfbastien@apple.comd9f999e2017-10-20 02:23:29 +0000500 out.print(indent, "EntryFrame: ", RawPointer(m_entryFrame), "\n");
mark.lam@apple.com507b94e2015-04-17 00:25:14 +0000501 indent--;
oliver@apple.com2b2e1322013-07-25 04:02:28 +0000502 }
mark.lam@apple.com1cfbb242016-06-03 14:53:16 +0000503 out.print(indent, "}\n");
oliver@apple.com2b2e1322013-07-25 04:02:28 +0000504}
505
oliver@apple.com2b2e1322013-07-25 04:02:28 +0000506} // namespace JSC