-
Notifications
You must be signed in to change notification settings - Fork 1.4k
/
DFGNodeFlags.h
200 lines (168 loc) · 8.11 KB
/
DFGNodeFlags.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
/*
* Copyright (C) 2012-2015 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#if ENABLE(DFG_JIT)
#include <wtf/PrintStream.h>
#include <wtf/StdLibExtras.h>
namespace JSC { namespace DFG {
// Entries in the NodeType enum (below) are composed of an id, a result type (possibly none)
// and some additional informative flags (must generate, is constant, etc).
#define NodeResultMask 0x0007
#define NodeResultJS 0x0001
#define NodeResultNumber 0x0002
#define NodeResultDouble 0x0003
#define NodeResultInt32 0x0004
#define NodeResultInt52 0x0005
#define NodeResultBoolean 0x0006
#define NodeResultStorage 0x0007
#define NodeMustGenerate 0x0008 // set on nodes that have side effects, and may not trivially be removed by DCE.
#define NodeHasVarArgs 0x0010
#define NodeMayHaveDoubleResult 0x00020
#define NodeMayOverflowInt52 0x00040
#define NodeMayOverflowInt32InBaseline 0x00080
#define NodeMayOverflowInt32InDFG 0x00100
#define NodeMayNegZeroInBaseline 0x00200
#define NodeMayNegZeroInDFG 0x00400
#define NodeMayHaveBigInt32Result 0x00800
#define NodeMayHaveHeapBigIntResult 0x01000
#define NodeMayHaveNonNumericResult 0x02000
#define NodeBehaviorMask (NodeMayHaveDoubleResult | NodeMayOverflowInt52 | NodeMayOverflowInt32InBaseline | NodeMayOverflowInt32InDFG | NodeMayNegZeroInBaseline | NodeMayNegZeroInDFG | NodeMayHaveBigInt32Result | NodeMayHaveHeapBigIntResult | NodeMayHaveNonNumericResult)
#define NodeMayHaveNonIntResult (NodeMayHaveDoubleResult | NodeMayHaveNonNumericResult | NodeMayHaveBigInt32Result | NodeMayHaveHeapBigIntResult)
#define NodeBytecodeUseBottom 0x00000
#define NodeBytecodeUsesAsNumber 0x04000 // The result of this computation may be used in a context that observes fractional, or bigger-than-int32, results.
#define NodeBytecodeNeedsNegZero 0x08000 // The result of this computation may be used in a context that observes -0.
#define NodeBytecodeNeedsNaNOrInfinity 0x10000 // The result of this computation may be used in a context that observes NaN or Infinity.
#define NodeBytecodeUsesAsOther 0x20000 // The result of this computation may be used in a context that distinguishes between NaN and other things (like undefined).
#define NodeBytecodeUsesAsInt 0x40000 // The result of this computation is known to be used in a context that prefers, but does not require, integer values.
#define NodeBytecodePrefersArrayIndex 0x80000 // The result of this computation is known to be used in a context that strongly prefers integer values, to the point that we should avoid using doubles if at all possible.
#define NodeBytecodeUsesAsArrayIndex (NodeBytecodeUsesAsNumber | NodeBytecodeNeedsNaNOrInfinity | NodeBytecodeUsesAsOther | NodeBytecodeUsesAsInt | NodeBytecodePrefersArrayIndex)
#define NodeBytecodeUsesAsValue (NodeBytecodeUsesAsNumber | NodeBytecodeNeedsNegZero | NodeBytecodeNeedsNaNOrInfinity | NodeBytecodeUsesAsOther)
#define NodeBytecodeBackPropMask (NodeBytecodeUsesAsNumber | NodeBytecodeNeedsNegZero | NodeBytecodeNeedsNaNOrInfinity | NodeBytecodeUsesAsOther | NodeBytecodeUsesAsInt | NodeBytecodePrefersArrayIndex)
#define NodeArithFlagsMask (NodeBehaviorMask | NodeBytecodeBackPropMask)
#define NodeIsFlushed 0x100000 // Computed by CPSRethreadingPhase, will tell you which local nodes are backwards-reachable from a Flush.
#define NodeMiscFlag1 0x200000
#define NodeMiscFlag2 0x400000
typedef uint32_t NodeFlags;
static inline bool bytecodeUsesAsNumber(NodeFlags flags)
{
return !!(flags & NodeBytecodeUsesAsNumber);
}
static inline bool bytecodeCanTruncateInteger(NodeFlags flags)
{
return !bytecodeUsesAsNumber(flags);
}
static inline bool bytecodeCanIgnoreNegativeZero(NodeFlags flags)
{
return !(flags & NodeBytecodeNeedsNegZero);
}
static inline bool bytecodeCanIgnoreNaNAndInfinity(NodeFlags flags)
{
return !(flags & NodeBytecodeNeedsNaNOrInfinity);
}
enum RareCaseProfilingSource {
BaselineRareCase, // Comes from slow case counting in the baseline JIT.
DFGRareCase, // Comes from OSR exit profiles.
AllRareCases
};
static inline bool nodeMayOverflowInt52(NodeFlags flags, RareCaseProfilingSource)
{
return !!(flags & NodeMayOverflowInt52);
}
static inline bool nodeMayOverflowInt32(NodeFlags flags, RareCaseProfilingSource source)
{
NodeFlags mask = 0;
switch (source) {
case BaselineRareCase:
mask = NodeMayOverflowInt32InBaseline;
break;
case DFGRareCase:
mask = NodeMayOverflowInt32InDFG;
break;
case AllRareCases:
mask = NodeMayOverflowInt32InBaseline | NodeMayOverflowInt32InDFG;
break;
}
return !!(flags & mask);
}
static inline bool nodeMayNegZero(NodeFlags flags, RareCaseProfilingSource source)
{
NodeFlags mask = 0;
switch (source) {
case BaselineRareCase:
mask = NodeMayNegZeroInBaseline;
break;
case DFGRareCase:
mask = NodeMayNegZeroInDFG;
break;
case AllRareCases:
mask = NodeMayNegZeroInBaseline | NodeMayNegZeroInDFG;
break;
}
return !!(flags & mask);
}
static inline bool nodeCanSpeculateInt32(NodeFlags flags, RareCaseProfilingSource source)
{
if (nodeMayOverflowInt32(flags, source))
return !bytecodeUsesAsNumber(flags);
if (nodeMayNegZero(flags, source))
return bytecodeCanIgnoreNegativeZero(flags);
return true;
}
static inline bool nodeCanSpeculateInt52(NodeFlags flags, RareCaseProfilingSource source)
{
if (nodeMayOverflowInt52(flags, source))
return false;
if (nodeMayNegZero(flags, source))
return bytecodeCanIgnoreNegativeZero(flags);
return true;
}
static inline bool nodeMayHaveHeapBigInt(NodeFlags flags, RareCaseProfilingSource)
{
return !!(flags & NodeMayHaveHeapBigIntResult);
}
static inline bool nodeCanSpeculateBigInt32(NodeFlags flags, RareCaseProfilingSource source)
{
// We always attempt to produce BigInt32 as much as possible. If we see HeapBigInt, we observed overflow.
// FIXME: Extend this information by tiered profiling (from Baseline, DFG etc.).
// https://bugs.webkit.org/show_bug.cgi?id=211039
return !nodeMayHaveHeapBigInt(flags, source);
}
// FIXME: Get rid of this.
// https://bugs.webkit.org/show_bug.cgi?id=131689
static inline NodeFlags canonicalResultRepresentation(NodeFlags flags)
{
switch (flags) {
case NodeResultDouble:
case NodeResultInt52:
case NodeResultStorage:
return flags;
default:
return NodeResultJS;
}
}
void dumpNodeFlags(PrintStream&, NodeFlags);
MAKE_PRINT_ADAPTOR(NodeFlagsDump, NodeFlags, dumpNodeFlags);
} } // namespace JSC::DFG
#endif // ENABLE(DFG_JIT)