1/* 2 * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved. 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 * 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#ifndef DFGNodeType_h 27#define DFGNodeType_h 28 29#if ENABLE(DFG_JIT) 30 31#include "DFGNodeFlags.h" 32 33namespace JSC { namespace DFG { 34 35// This macro defines a set of information about all known node types, used to populate NodeId, NodeType below. 36#define FOR_EACH_DFG_OP(macro) \ 37 /* A constant in the CodeBlock's constant pool. */\ 38 macro(JSConstant, NodeResultJS | NodeDoesNotExit) \ 39 \ 40 /* Constants with specific representations. */\ 41 macro(DoubleConstant, NodeResultDouble | NodeDoesNotExit) \ 42 macro(Int52Constant, NodeResultInt52 | NodeDoesNotExit) \ 43 \ 44 /* A constant not in the CodeBlock's constant pool. Uses get patched to jumps that exit the */\ 45 /* code block. */\ 46 macro(WeakJSConstant, NodeResultJS | NodeDoesNotExit) \ 47 \ 48 /* Marker to indicate that an operation was optimized entirely and all that is left */\ 49 /* is to make one node alias another. CSE will later usually eliminate this node, */\ 50 /* though it may choose not to if it would corrupt predictions (very rare). */\ 51 macro(Identity, NodeResultJS) \ 52 \ 53 /* Nodes for handling functions (both as call and as construct). */\ 54 macro(ToThis, NodeResultJS) \ 55 macro(CreateThis, NodeResultJS) /* Note this is not MustGenerate since we're returning it anyway. */ \ 56 macro(GetCallee, NodeResultJS) \ 57 \ 58 /* Nodes for local variable access. These nodes are linked together using Phi nodes. */\ 59 /* Any two nodes that are part of the same Phi graph will share the same */\ 60 /* VariableAccessData, and thus will share predictions. */\ 61 macro(GetLocal, NodeResultJS) \ 62 macro(SetLocal, 0) \ 63 macro(MovHint, NodeDoesNotExit) \ 64 macro(ZombieHint, NodeDoesNotExit) \ 65 macro(GetArgument, NodeResultJS | NodeMustGenerate) \ 66 macro(Phantom, NodeMustGenerate) \ 67 macro(HardPhantom, NodeMustGenerate) /* Like Phantom, but we never remove any of its children. */ \ 68 macro(Check, 0) /* Used if we want just a type check but not liveness. DCE eithers kills this or converts it to Phantom. */\ 69 macro(Upsilon, NodeDoesNotExit | NodeRelevantToOSR) \ 70 macro(Phi, NodeDoesNotExit | NodeRelevantToOSR) \ 71 macro(Flush, NodeMustGenerate | NodeDoesNotExit) \ 72 macro(PhantomLocal, NodeMustGenerate | NodeDoesNotExit) \ 73 \ 74 /* Hint that this is where bytecode thinks is a good place to OSR. Note that this */\ 75 /* will exist even in inlined loops. This has no execution semantics but it must */\ 76 /* survive all DCE. We treat this as being a can-exit because tier-up to FTL may */\ 77 /* want all state. */\ 78 macro(LoopHint, NodeMustGenerate) \ 79 \ 80 /* Special node for OSR entry into the FTL. Indicates that we're loading a local */\ 81 /* variable from the scratch buffer. */\ 82 macro(ExtractOSREntryLocal, NodeResultJS) \ 83 \ 84 /* Tier-up checks from the DFG to the FTL. */\ 85 macro(CheckTierUpInLoop, NodeMustGenerate) \ 86 macro(CheckTierUpAndOSREnter, NodeMustGenerate) \ 87 macro(CheckTierUpAtReturn, NodeMustGenerate) \ 88 \ 89 /* Get the value of a local variable, without linking into the VariableAccessData */\ 90 /* network. This is only valid for variable accesses whose predictions originated */\ 91 /* as something other than a local access, and thus had their own profiling. */\ 92 macro(GetLocalUnlinked, NodeResultJS) \ 93 \ 94 /* Marker for an argument being set at the prologue of a function. */\ 95 macro(SetArgument, NodeDoesNotExit) \ 96 \ 97 /* Marker of location in the IR where we may possibly perform jump replacement to */\ 98 /* invalidate this code block. */\ 99 macro(InvalidationPoint, NodeMustGenerate) \ 100 \ 101 /* Nodes for bitwise operations. */\ 102 macro(BitAnd, NodeResultInt32) \ 103 macro(BitOr, NodeResultInt32) \ 104 macro(BitXor, NodeResultInt32) \ 105 macro(BitLShift, NodeResultInt32) \ 106 macro(BitRShift, NodeResultInt32) \ 107 macro(BitURShift, NodeResultInt32) \ 108 /* Bitwise operators call ToInt32 on their operands. */\ 109 macro(ValueToInt32, NodeResultInt32) \ 110 /* Used to box the result of URShift nodes (result has range 0..2^32-1). */\ 111 macro(UInt32ToNumber, NodeResultNumber) \ 112 /* Converts booleans to numbers but passes everything else through. */\ 113 macro(BooleanToNumber, NodeResultJS) \ 114 \ 115 /* Attempt to truncate a double to int32; this will exit if it can't do it. */\ 116 macro(DoubleAsInt32, NodeResultInt32) \ 117 \ 118 /* Change the representation of a value. */\ 119 macro(DoubleRep, NodeResultDouble) \ 120 macro(Int52Rep, NodeResultInt52) \ 121 macro(ValueRep, NodeResultJS) \ 122 \ 123 /* Bogus type asserting node. Useful for testing, disappears during Fixup. */\ 124 macro(FiatInt52, NodeResultJS) \ 125 \ 126 /* Nodes for arithmetic operations. */\ 127 macro(ArithAdd, NodeResultNumber) \ 128 macro(ArithSub, NodeResultNumber) \ 129 macro(ArithNegate, NodeResultNumber) \ 130 macro(ArithMul, NodeResultNumber) \ 131 macro(ArithIMul, NodeResultInt32) \ 132 macro(ArithDiv, NodeResultNumber) \ 133 macro(ArithMod, NodeResultNumber) \ 134 macro(ArithAbs, NodeResultNumber) \ 135 macro(ArithMin, NodeResultNumber) \ 136 macro(ArithMax, NodeResultNumber) \ 137 macro(ArithFRound, NodeResultNumber) \ 138 macro(ArithSqrt, NodeResultNumber) \ 139 macro(ArithSin, NodeResultNumber) \ 140 macro(ArithCos, NodeResultNumber) \ 141 \ 142 /* Add of values may either be arithmetic, or result in string concatenation. */\ 143 macro(ValueAdd, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \ 144 \ 145 /* Property access. */\ 146 /* PutByValAlias indicates a 'put' aliases a prior write to the same property. */\ 147 /* Since a put to 'length' may invalidate optimizations here, */\ 148 /* this must be the directly subsequent property put. Note that PutByVal */\ 149 /* opcodes use VarArgs beause they may have up to 4 children. */\ 150 macro(GetByVal, NodeResultJS | NodeMustGenerate | NodeMightClobber) \ 151 macro(PutByValDirect, NodeMustGenerate | NodeHasVarArgs | NodeMightClobber) \ 152 macro(PutByVal, NodeMustGenerate | NodeHasVarArgs | NodeMightClobber) \ 153 macro(PutByValAlias, NodeMustGenerate | NodeHasVarArgs | NodeMightClobber) \ 154 macro(GetById, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \ 155 macro(GetByIdFlush, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \ 156 macro(PutById, NodeMustGenerate | NodeClobbersWorld) \ 157 macro(PutByIdFlush, NodeMustGenerate | NodeMustGenerate | NodeClobbersWorld) \ 158 macro(PutByIdDirect, NodeMustGenerate | NodeClobbersWorld) \ 159 macro(CheckStructure, NodeMustGenerate) \ 160 macro(CheckExecutable, NodeMustGenerate) \ 161 /* Transition watchpoints are a contract between the party setting the watchpoint */\ 162 /* and the runtime system, where the party promises that the child object once had */\ 163 /* the structure being watched, and the runtime system in turn promises that the */\ 164 /* watchpoint will be turned into an OSR exit if any object with that structure */\ 165 /* ever transitions to a different structure. Hence, the child object must have */\ 166 /* previously had a CheckStructure executed on it or we're dealing with an object */\ 167 /* constant (WeakJSConstant) and the object was known to have that structure at */\ 168 /* compile-time. In the latter case this means that no structure checks have to be */\ 169 /* performed for this object by JITted code. In the former case this means that*/\ 170 /* the object's structure does not need to be rechecked due to side-effecting */\ 171 /* (clobbering) operations. */\ 172 macro(StructureTransitionWatchpoint, NodeMustGenerate) \ 173 macro(PutStructure, NodeMustGenerate) \ 174 macro(PhantomPutStructure, NodeMustGenerate | NodeDoesNotExit) \ 175 macro(AllocatePropertyStorage, NodeMustGenerate | NodeDoesNotExit | NodeResultStorage) \ 176 macro(ReallocatePropertyStorage, NodeMustGenerate | NodeDoesNotExit | NodeResultStorage) \ 177 macro(GetButterfly, NodeResultStorage) \ 178 macro(CheckArray, NodeMustGenerate) \ 179 macro(Arrayify, NodeMustGenerate) \ 180 macro(ArrayifyToStructure, NodeMustGenerate) \ 181 macro(GetIndexedPropertyStorage, NodeResultStorage) \ 182 macro(ConstantStoragePointer, NodeResultStorage) \ 183 macro(TypedArrayWatchpoint, NodeMustGenerate) \ 184 macro(GetByOffset, NodeResultJS) \ 185 macro(MultiGetByOffset, NodeResultJS) \ 186 macro(PutByOffset, NodeMustGenerate) \ 187 macro(MultiPutByOffset, NodeMustGenerate) \ 188 macro(GetArrayLength, NodeResultInt32) \ 189 macro(GetTypedArrayByteOffset, NodeResultInt32) \ 190 macro(GetScope, NodeResultJS) \ 191 macro(GetMyScope, NodeResultJS) \ 192 macro(SkipTopScope, NodeResultJS) \ 193 macro(SkipScope, NodeResultJS) \ 194 macro(GetClosureRegisters, NodeResultStorage) \ 195 macro(GetClosureVar, NodeResultJS) \ 196 macro(PutClosureVar, NodeMustGenerate) \ 197 macro(GetGlobalVar, NodeResultJS) \ 198 macro(PutGlobalVar, NodeMustGenerate) \ 199 macro(NotifyWrite, NodeMustGenerate) \ 200 macro(VariableWatchpoint, NodeMustGenerate) \ 201 macro(VarInjectionWatchpoint, NodeMustGenerate) \ 202 macro(FunctionReentryWatchpoint, NodeMustGenerate) \ 203 macro(CheckFunction, NodeMustGenerate) \ 204 macro(AllocationProfileWatchpoint, NodeMustGenerate) \ 205 macro(CheckInBounds, NodeMustGenerate) \ 206 \ 207 /* Optimizations for array mutation. */\ 208 macro(ArrayPush, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \ 209 macro(ArrayPop, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \ 210 \ 211 /* Optimizations for regular expression matching. */\ 212 macro(RegExpExec, NodeResultJS | NodeMustGenerate) \ 213 macro(RegExpTest, NodeResultJS | NodeMustGenerate) \ 214 \ 215 /* Optimizations for string access */ \ 216 macro(StringCharCodeAt, NodeResultInt32) \ 217 macro(StringCharAt, NodeResultJS) \ 218 macro(StringFromCharCode, NodeResultJS) \ 219 \ 220 /* Nodes for comparison operations. */\ 221 macro(CompareLess, NodeResultBoolean | NodeMustGenerate | NodeClobbersWorld) \ 222 macro(CompareLessEq, NodeResultBoolean | NodeMustGenerate | NodeClobbersWorld) \ 223 macro(CompareGreater, NodeResultBoolean | NodeMustGenerate | NodeClobbersWorld) \ 224 macro(CompareGreaterEq, NodeResultBoolean | NodeMustGenerate | NodeClobbersWorld) \ 225 macro(CompareEq, NodeResultBoolean | NodeMustGenerate | NodeClobbersWorld) \ 226 macro(CompareEqConstant, NodeResultBoolean) \ 227 macro(CompareStrictEq, NodeResultBoolean) \ 228 \ 229 /* Calls. */\ 230 macro(Call, NodeResultJS | NodeMustGenerate | NodeHasVarArgs | NodeClobbersWorld) \ 231 macro(Construct, NodeResultJS | NodeMustGenerate | NodeHasVarArgs | NodeClobbersWorld) \ 232 \ 233 /* Allocations. */\ 234 macro(NewObject, NodeResultJS) \ 235 macro(NewArray, NodeResultJS | NodeHasVarArgs) \ 236 macro(NewArrayWithSize, NodeResultJS | NodeMustGenerate) \ 237 macro(NewArrayBuffer, NodeResultJS) \ 238 macro(NewTypedArray, NodeResultJS | NodeClobbersWorld | NodeMustGenerate) \ 239 macro(NewRegexp, NodeResultJS) \ 240 \ 241 /* Nodes for misc operations. */\ 242 macro(Breakpoint, NodeMustGenerate) \ 243 macro(ProfileWillCall, NodeMustGenerate) \ 244 macro(ProfileDidCall, NodeMustGenerate) \ 245 macro(CheckHasInstance, NodeMustGenerate) \ 246 macro(InstanceOf, NodeResultBoolean) \ 247 macro(IsUndefined, NodeResultBoolean) \ 248 macro(IsBoolean, NodeResultBoolean) \ 249 macro(IsNumber, NodeResultBoolean) \ 250 macro(IsString, NodeResultBoolean) \ 251 macro(IsObject, NodeResultBoolean) \ 252 macro(IsFunction, NodeResultBoolean) \ 253 macro(TypeOf, NodeResultJS) \ 254 macro(LogicalNot, NodeResultBoolean) \ 255 macro(ToPrimitive, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \ 256 macro(ToString, NodeResultJS | NodeMustGenerate | NodeMightClobber) \ 257 macro(NewStringObject, NodeResultJS) \ 258 macro(MakeRope, NodeResultJS) \ 259 macro(In, NodeResultBoolean | NodeMustGenerate | NodeClobbersWorld) \ 260 \ 261 /* Nodes used for activations. Activation support works by having it anchored at */\ 262 /* epilgoues via TearOffActivation, and all CreateActivation nodes kept alive by */\ 263 /* being threaded with each other. */\ 264 macro(CreateActivation, NodeResultJS) \ 265 macro(TearOffActivation, NodeMustGenerate) \ 266 \ 267 /* Nodes used for arguments. Similar to activation support, only it makes even less */\ 268 /* sense. */\ 269 macro(CreateArguments, NodeResultJS) \ 270 macro(PhantomArguments, NodeResultJS | NodeDoesNotExit) \ 271 macro(TearOffArguments, NodeMustGenerate) \ 272 macro(GetMyArgumentsLength, NodeResultJS | NodeMustGenerate) \ 273 macro(GetMyArgumentByVal, NodeResultJS | NodeMustGenerate) \ 274 macro(GetMyArgumentsLengthSafe, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \ 275 macro(GetMyArgumentByValSafe, NodeResultJS | NodeMustGenerate | NodeClobbersWorld) \ 276 macro(CheckArgumentsNotCreated, NodeMustGenerate) \ 277 \ 278 /* Nodes for creating functions. */\ 279 macro(NewFunctionNoCheck, NodeResultJS) \ 280 macro(NewFunction, NodeResultJS) \ 281 macro(NewFunctionExpression, NodeResultJS) \ 282 \ 283 /* These aren't terminals but always exit */ \ 284 macro(Throw, NodeMustGenerate) \ 285 macro(ThrowReferenceError, NodeMustGenerate) \ 286 \ 287 /* Block terminals. */\ 288 macro(Jump, NodeMustGenerate) \ 289 macro(Branch, NodeMustGenerate) \ 290 macro(Switch, NodeMustGenerate) \ 291 macro(Return, NodeMustGenerate) \ 292 macro(Unreachable, NodeMustGenerate) \ 293 \ 294 /* Count execution. */\ 295 macro(CountExecution, NodeMustGenerate) \ 296 \ 297 /* This is a pseudo-terminal. It means that execution should fall out of DFG at */\ 298 /* this point, but execution does continue in the basic block - just in a */\ 299 /* different compiler. */\ 300 macro(ForceOSRExit, NodeMustGenerate) \ 301 \ 302 /* Checks the watchdog timer. If the timer has fired, we OSR exit to the */ \ 303 /* baseline JIT to redo the watchdog timer check, and service the timer. */ \ 304 macro(CheckWatchdogTimer, NodeMustGenerate) \ 305 /* Write barriers ! */\ 306 macro(StoreBarrier, NodeMustGenerate) \ 307 macro(StoreBarrierWithNullCheck, NodeMustGenerate) \ 308 309// This enum generates a monotonically increasing id for all Node types, 310// and is used by the subsequent enum to fill out the id (as accessed via the NodeIdMask). 311enum NodeType { 312#define DFG_OP_ENUM(opcode, flags) opcode, 313 FOR_EACH_DFG_OP(DFG_OP_ENUM) 314#undef DFG_OP_ENUM 315 LastNodeType 316}; 317 318// Specifies the default flags for each node. 319inline NodeFlags defaultFlags(NodeType op) 320{ 321 switch (op) { 322#define DFG_OP_ENUM(opcode, flags) case opcode: return flags; 323 FOR_EACH_DFG_OP(DFG_OP_ENUM) 324#undef DFG_OP_ENUM 325 default: 326 RELEASE_ASSERT_NOT_REACHED(); 327 return 0; 328 } 329} 330 331} } // namespace JSC::DFG 332 333#endif // ENABLE(DFG_JIT) 334 335#endif // DFGNodeType_h 336 337