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)
|