blob: 3b8f3fa7f4241c3df5b4078510c9c45ec97f909c [file] [log] [blame]
fpizlo@apple.com0bfcc382012-11-30 03:42:29 +00001/*
fpizlo@apple.comed2da802018-07-22 02:48:16 +00002 * Copyright (C) 2012-2018 Apple Inc. All rights reserved.
fpizlo@apple.com0bfcc382012-11-30 03:42:29 +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"
27#include "CodeOrigin.h"
28
fpizlo@apple.com4a81fa42012-12-05 01:26:13 +000029#include "CodeBlock.h"
ggaren@apple.com21cd7022015-08-18 18:28:54 +000030#include "InlineCallFrame.h"
fpizlo@apple.com0bfcc382012-11-30 03:42:29 +000031
32namespace JSC {
33
fpizlo@apple.com0bfcc382012-11-30 03:42:29 +000034unsigned CodeOrigin::inlineDepth() const
35{
rmorisset@apple.comb4811e72019-03-20 20:24:36 +000036 unsigned result = 1;
37 for (InlineCallFrame* current = inlineCallFrame(); current; current = current->directCaller.inlineCallFrame())
38 result++;
39 return result;
fpizlo@apple.com0bfcc382012-11-30 03:42:29 +000040}
msaboff@apple.com95894332014-01-29 19:18:54 +000041
fpizlo@apple.comed2da802018-07-22 02:48:16 +000042bool CodeOrigin::isApproximatelyEqualTo(const CodeOrigin& other, InlineCallFrame* terminal) const
msaboff@apple.com95894332014-01-29 19:18:54 +000043{
44 CodeOrigin a = *this;
45 CodeOrigin b = other;
46
47 if (!a.isSet())
48 return !b.isSet();
49 if (!b.isSet())
50 return false;
fpizlo@apple.com0bfcc382012-11-30 03:42:29 +000051
msaboff@apple.com95894332014-01-29 19:18:54 +000052 if (a.isHashTableDeletedValue())
53 return b.isHashTableDeletedValue();
54 if (b.isHashTableDeletedValue())
55 return false;
56
57 for (;;) {
58 ASSERT(a.isSet());
59 ASSERT(b.isSet());
60
rmorisset@apple.comb4811e72019-03-20 20:24:36 +000061 if (a.bytecodeIndex() != b.bytecodeIndex())
msaboff@apple.com95894332014-01-29 19:18:54 +000062 return false;
rmorisset@apple.comb4811e72019-03-20 20:24:36 +000063
64 auto* aInlineCallFrame = a.inlineCallFrame();
65 auto* bInlineCallFrame = b.inlineCallFrame();
66 bool aHasInlineCallFrame = !!aInlineCallFrame && aInlineCallFrame != terminal;
67 bool bHasInlineCallFrame = !!bInlineCallFrame;
fpizlo@apple.comed2da802018-07-22 02:48:16 +000068 if (aHasInlineCallFrame != bHasInlineCallFrame)
msaboff@apple.com95894332014-01-29 19:18:54 +000069 return false;
70
fpizlo@apple.comed2da802018-07-22 02:48:16 +000071 if (!aHasInlineCallFrame)
msaboff@apple.com95894332014-01-29 19:18:54 +000072 return true;
73
rmorisset@apple.comb4811e72019-03-20 20:24:36 +000074 if (aInlineCallFrame->baselineCodeBlock.get() != bInlineCallFrame->baselineCodeBlock.get())
msaboff@apple.com95894332014-01-29 19:18:54 +000075 return false;
76
rmorisset@apple.comb4811e72019-03-20 20:24:36 +000077 a = aInlineCallFrame->directCaller;
78 b = bInlineCallFrame->directCaller;
msaboff@apple.com95894332014-01-29 19:18:54 +000079 }
80}
81
fpizlo@apple.comed2da802018-07-22 02:48:16 +000082unsigned CodeOrigin::approximateHash(InlineCallFrame* terminal) const
msaboff@apple.com95894332014-01-29 19:18:54 +000083{
84 if (!isSet())
85 return 0;
86 if (isHashTableDeletedValue())
87 return 1;
88
89 unsigned result = 2;
90 CodeOrigin codeOrigin = *this;
91 for (;;) {
keith_miller@apple.com0f985ec2019-10-23 00:55:38 +000092 result += codeOrigin.bytecodeIndex().asBits();
rmorisset@apple.comb4811e72019-03-20 20:24:36 +000093
94 auto* inlineCallFrame = codeOrigin.inlineCallFrame();
95
96 if (!inlineCallFrame)
msaboff@apple.com95894332014-01-29 19:18:54 +000097 return result;
98
rmorisset@apple.comb4811e72019-03-20 20:24:36 +000099 if (inlineCallFrame == terminal)
fpizlo@apple.comed2da802018-07-22 02:48:16 +0000100 return result;
101
rmorisset@apple.comb4811e72019-03-20 20:24:36 +0000102 result += WTF::PtrHash<JSCell*>::hash(inlineCallFrame->baselineCodeBlock.get());
msaboff@apple.com95894332014-01-29 19:18:54 +0000103
rmorisset@apple.comb4811e72019-03-20 20:24:36 +0000104 codeOrigin = inlineCallFrame->directCaller;
msaboff@apple.com95894332014-01-29 19:18:54 +0000105 }
106}
107
fpizlo@apple.com0bfcc382012-11-30 03:42:29 +0000108Vector<CodeOrigin> CodeOrigin::inlineStack() const
109{
110 Vector<CodeOrigin> result(inlineDepth());
111 result.last() = *this;
112 unsigned index = result.size() - 2;
rmorisset@apple.comb4811e72019-03-20 20:24:36 +0000113 for (InlineCallFrame* current = inlineCallFrame(); current; current = current->directCaller.inlineCallFrame())
msaboff@apple.coma3dc7532015-09-24 21:42:59 +0000114 result[index--] = current->directCaller;
rmorisset@apple.comb4811e72019-03-20 20:24:36 +0000115 RELEASE_ASSERT(!result[0].inlineCallFrame());
fpizlo@apple.com0bfcc382012-11-30 03:42:29 +0000116 return result;
117}
118
ggaren@apple.com81def5f2015-10-09 23:10:16 +0000119CodeBlock* CodeOrigin::codeOriginOwner() const
ggaren@apple.com21cd7022015-08-18 18:28:54 +0000120{
rmorisset@apple.comb4811e72019-03-20 20:24:36 +0000121 auto* inlineCallFrame = this->inlineCallFrame();
ggaren@apple.com21cd7022015-08-18 18:28:54 +0000122 if (!inlineCallFrame)
rmorisset@apple.comb4811e72019-03-20 20:24:36 +0000123 return nullptr;
ggaren@apple.com81def5f2015-10-09 23:10:16 +0000124 return inlineCallFrame->baselineCodeBlock.get();
ggaren@apple.com21cd7022015-08-18 18:28:54 +0000125}
126
127int CodeOrigin::stackOffset() const
128{
rmorisset@apple.comb4811e72019-03-20 20:24:36 +0000129 auto* inlineCallFrame = this->inlineCallFrame();
ggaren@apple.com21cd7022015-08-18 18:28:54 +0000130 if (!inlineCallFrame)
131 return 0;
ggaren@apple.com21cd7022015-08-18 18:28:54 +0000132 return inlineCallFrame->stackOffset;
133}
134
fpizlo@apple.com20d46242012-11-30 21:56:24 +0000135void CodeOrigin::dump(PrintStream& out) const
136{
fpizlo@apple.com50f06282013-12-10 05:52:24 +0000137 if (!isSet()) {
138 out.print("<none>");
139 return;
140 }
141
fpizlo@apple.com20d46242012-11-30 21:56:24 +0000142 Vector<CodeOrigin> stack = inlineStack();
143 for (unsigned i = 0; i < stack.size(); ++i) {
144 if (i)
145 out.print(" --> ");
146
rmorisset@apple.comb4811e72019-03-20 20:24:36 +0000147 if (InlineCallFrame* frame = stack[i].inlineCallFrame()) {
ggaren@apple.com81def5f2015-10-09 23:10:16 +0000148 out.print(frame->briefFunctionInformation(), ":<", RawPointer(frame->baselineCodeBlock.get()), "> ");
fpizlo@apple.coma62d4822013-10-06 04:22:43 +0000149 if (frame->isClosureCall)
fpizlo@apple.com806b5822013-01-08 01:23:38 +0000150 out.print("(closure) ");
151 }
fpizlo@apple.com20d46242012-11-30 21:56:24 +0000152
keith_miller@apple.com0f985ec2019-10-23 00:55:38 +0000153 out.print(stack[i].bytecodeIndex());
fpizlo@apple.com20d46242012-11-30 21:56:24 +0000154 }
155}
156
oliver@apple.com237b1462013-07-25 04:05:36 +0000157void CodeOrigin::dumpInContext(PrintStream& out, DumpContext*) const
158{
159 dump(out);
160}
161
fpizlo@apple.com0bfcc382012-11-30 03:42:29 +0000162} // namespace JSC