Line data Source code
1 : // Copyright 2014 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #include "src/compiler/operator-properties.h"
6 :
7 : #include "src/compiler/js-operator.h"
8 : #include "src/compiler/linkage.h"
9 : #include "src/compiler/opcodes.h"
10 : #include "src/runtime/runtime.h"
11 :
12 : namespace v8 {
13 : namespace internal {
14 : namespace compiler {
15 :
16 : // static
17 1280650528 : bool OperatorProperties::HasContextInput(const Operator* op) {
18 1280908942 : IrOpcode::Value opcode = static_cast<IrOpcode::Value>(op->opcode());
19 1280650528 : return IrOpcode::IsJsOpcode(opcode);
20 : }
21 :
22 : // static
23 5123814 : bool OperatorProperties::NeedsExactContext(const Operator* op) {
24 : DCHECK(HasContextInput(op));
25 : IrOpcode::Value const opcode = static_cast<IrOpcode::Value>(op->opcode());
26 5123814 : switch (opcode) {
27 : #define CASE(Name) case IrOpcode::k##Name:
28 : // Binary/unary operators, calls and constructor calls only
29 : // need the context to generate exceptions or lookup fields
30 : // on the native context, so passing any context is fine.
31 : JS_SIMPLE_BINOP_LIST(CASE)
32 : JS_CALL_OP_LIST(CASE)
33 : JS_CONSTRUCT_OP_LIST(CASE)
34 : JS_SIMPLE_UNOP_LIST(CASE)
35 : #undef CASE
36 : case IrOpcode::kJSCloneObject:
37 : case IrOpcode::kJSCreate:
38 : case IrOpcode::kJSCreateLiteralArray:
39 : case IrOpcode::kJSCreateEmptyLiteralArray:
40 : case IrOpcode::kJSCreateLiteralObject:
41 : case IrOpcode::kJSCreateEmptyLiteralObject:
42 : case IrOpcode::kJSCreateArrayFromIterable:
43 : case IrOpcode::kJSCreateLiteralRegExp:
44 : case IrOpcode::kJSForInEnumerate:
45 : case IrOpcode::kJSForInNext:
46 : case IrOpcode::kJSForInPrepare:
47 : case IrOpcode::kJSGeneratorRestoreContext:
48 : case IrOpcode::kJSGeneratorRestoreContinuation:
49 : case IrOpcode::kJSGeneratorRestoreInputOrDebugPos:
50 : case IrOpcode::kJSGeneratorRestoreRegister:
51 : case IrOpcode::kJSGetSuperConstructor:
52 : case IrOpcode::kJSLoadGlobal:
53 : case IrOpcode::kJSLoadMessage:
54 : case IrOpcode::kJSStackCheck:
55 : case IrOpcode::kJSStoreGlobal:
56 : case IrOpcode::kJSStoreMessage:
57 : return false;
58 :
59 : case IrOpcode::kJSCallRuntime:
60 376432 : return Runtime::NeedsExactContext(CallRuntimeParametersOf(op).id());
61 :
62 : case IrOpcode::kJSCreateArguments:
63 : // For mapped arguments we need to access slots of context-allocated
64 : // variables if there's aliasing with formal parameters.
65 19384 : return CreateArgumentsTypeOf(op) == CreateArgumentsType::kMappedArguments;
66 :
67 : case IrOpcode::kJSCreateBlockContext:
68 : case IrOpcode::kJSCreateClosure:
69 : case IrOpcode::kJSCreateFunctionContext:
70 : case IrOpcode::kJSCreateGeneratorObject:
71 : case IrOpcode::kJSCreateCatchContext:
72 : case IrOpcode::kJSCreateWithContext:
73 : case IrOpcode::kJSDebugger:
74 : case IrOpcode::kJSDeleteProperty:
75 : case IrOpcode::kJSGeneratorStore:
76 : case IrOpcode::kJSHasProperty:
77 : case IrOpcode::kJSLoadContext:
78 : case IrOpcode::kJSLoadModule:
79 : case IrOpcode::kJSLoadNamed:
80 : case IrOpcode::kJSLoadProperty:
81 : case IrOpcode::kJSStoreContext:
82 : case IrOpcode::kJSStoreDataPropertyInLiteral:
83 : case IrOpcode::kJSStoreInArrayLiteral:
84 : case IrOpcode::kJSStoreModule:
85 : case IrOpcode::kJSStoreNamed:
86 : case IrOpcode::kJSStoreNamedOwn:
87 : case IrOpcode::kJSStoreProperty:
88 2066650 : return true;
89 :
90 : case IrOpcode::kJSAsyncFunctionEnter:
91 : case IrOpcode::kJSAsyncFunctionReject:
92 : case IrOpcode::kJSAsyncFunctionResolve:
93 : case IrOpcode::kJSCreateArrayIterator:
94 : case IrOpcode::kJSCreateAsyncFunctionObject:
95 : case IrOpcode::kJSCreateBoundFunction:
96 : case IrOpcode::kJSCreateCollectionIterator:
97 : case IrOpcode::kJSCreateIterResultObject:
98 : case IrOpcode::kJSCreateStringIterator:
99 : case IrOpcode::kJSCreateKeyValueArray:
100 : case IrOpcode::kJSCreateObject:
101 : case IrOpcode::kJSCreatePromise:
102 : case IrOpcode::kJSCreateTypedArray:
103 : case IrOpcode::kJSCreateArray:
104 : case IrOpcode::kJSFulfillPromise:
105 : case IrOpcode::kJSObjectIsArray:
106 : case IrOpcode::kJSPerformPromiseThen:
107 : case IrOpcode::kJSPromiseResolve:
108 : case IrOpcode::kJSRegExpTest:
109 : case IrOpcode::kJSRejectPromise:
110 : case IrOpcode::kJSResolvePromise:
111 : // These operators aren't introduced by BytecodeGraphBuilder and
112 : // thus we don't bother checking them. If you ever introduce one
113 : // of these early in the BytecodeGraphBuilder make sure to check
114 : // whether they are context-sensitive.
115 : break;
116 :
117 : #define CASE(Name) case IrOpcode::k##Name:
118 : // Non-JavaScript operators don't have a notion of "context"
119 : COMMON_OP_LIST(CASE)
120 : CONTROL_OP_LIST(CASE)
121 : MACHINE_OP_LIST(CASE)
122 : MACHINE_SIMD_OP_LIST(CASE)
123 : SIMPLIFIED_OP_LIST(CASE)
124 : break;
125 : #undef CASE
126 : }
127 0 : UNREACHABLE();
128 : }
129 :
130 : // static
131 1258064671 : bool OperatorProperties::HasFrameStateInput(const Operator* op) {
132 1258064671 : switch (op->opcode()) {
133 : case IrOpcode::kCheckpoint:
134 : case IrOpcode::kFrameState:
135 : return true;
136 : case IrOpcode::kJSCallRuntime: {
137 11620236 : const CallRuntimeParameters& p = CallRuntimeParametersOf(op);
138 11620232 : return Linkage::NeedsFrameStateInput(p.id());
139 : }
140 :
141 : // Strict equality cannot lazily deoptimize.
142 : case IrOpcode::kJSStrictEqual:
143 4549158 : return false;
144 :
145 : // Generator creation cannot call back into arbitrary JavaScript.
146 : case IrOpcode::kJSCreateGeneratorObject:
147 25836 : return false;
148 :
149 : // Binary operations
150 : case IrOpcode::kJSAdd:
151 : case IrOpcode::kJSSubtract:
152 : case IrOpcode::kJSMultiply:
153 : case IrOpcode::kJSDivide:
154 : case IrOpcode::kJSModulus:
155 : case IrOpcode::kJSExponentiate:
156 :
157 : // Bitwise operations
158 : case IrOpcode::kJSBitwiseOr:
159 : case IrOpcode::kJSBitwiseXor:
160 : case IrOpcode::kJSBitwiseAnd:
161 :
162 : // Shift operations
163 : case IrOpcode::kJSShiftLeft:
164 : case IrOpcode::kJSShiftRight:
165 : case IrOpcode::kJSShiftRightLogical:
166 :
167 : // Compare operations
168 : case IrOpcode::kJSEqual:
169 : case IrOpcode::kJSGreaterThan:
170 : case IrOpcode::kJSGreaterThanOrEqual:
171 : case IrOpcode::kJSLessThan:
172 : case IrOpcode::kJSLessThanOrEqual:
173 : case IrOpcode::kJSHasProperty:
174 : case IrOpcode::kJSHasInPrototypeChain:
175 : case IrOpcode::kJSInstanceOf:
176 : case IrOpcode::kJSOrdinaryHasInstance:
177 :
178 : // Object operations
179 : case IrOpcode::kJSCreate:
180 : case IrOpcode::kJSCreateArguments:
181 : case IrOpcode::kJSCreateArray:
182 : case IrOpcode::kJSCreateTypedArray:
183 : case IrOpcode::kJSCreateLiteralArray:
184 : case IrOpcode::kJSCreateArrayFromIterable:
185 : case IrOpcode::kJSCreateLiteralObject:
186 : case IrOpcode::kJSCreateLiteralRegExp:
187 : case IrOpcode::kJSCreateObject:
188 : case IrOpcode::kJSCloneObject:
189 :
190 : // Property access operations
191 : case IrOpcode::kJSLoadNamed:
192 : case IrOpcode::kJSStoreNamed:
193 : case IrOpcode::kJSLoadProperty:
194 : case IrOpcode::kJSStoreProperty:
195 : case IrOpcode::kJSLoadGlobal:
196 : case IrOpcode::kJSStoreGlobal:
197 : case IrOpcode::kJSStoreNamedOwn:
198 : case IrOpcode::kJSStoreDataPropertyInLiteral:
199 : case IrOpcode::kJSDeleteProperty:
200 :
201 : // Conversions
202 : case IrOpcode::kJSToLength:
203 : case IrOpcode::kJSToName:
204 : case IrOpcode::kJSToNumber:
205 : case IrOpcode::kJSToNumberConvertBigInt:
206 : case IrOpcode::kJSToNumeric:
207 : case IrOpcode::kJSToObject:
208 : case IrOpcode::kJSToString:
209 : case IrOpcode::kJSParseInt:
210 :
211 : // Call operations
212 : case IrOpcode::kJSConstructForwardVarargs:
213 : case IrOpcode::kJSConstruct:
214 : case IrOpcode::kJSConstructWithArrayLike:
215 : case IrOpcode::kJSConstructWithSpread:
216 : case IrOpcode::kJSCallForwardVarargs:
217 : case IrOpcode::kJSCall:
218 : case IrOpcode::kJSCallWithArrayLike:
219 : case IrOpcode::kJSCallWithSpread:
220 :
221 : // Misc operations
222 : case IrOpcode::kJSAsyncFunctionEnter:
223 : case IrOpcode::kJSAsyncFunctionReject:
224 : case IrOpcode::kJSAsyncFunctionResolve:
225 : case IrOpcode::kJSForInEnumerate:
226 : case IrOpcode::kJSForInNext:
227 : case IrOpcode::kJSStackCheck:
228 : case IrOpcode::kJSDebugger:
229 : case IrOpcode::kJSGetSuperConstructor:
230 : case IrOpcode::kJSBitwiseNot:
231 : case IrOpcode::kJSDecrement:
232 : case IrOpcode::kJSIncrement:
233 : case IrOpcode::kJSNegate:
234 : case IrOpcode::kJSPromiseResolve:
235 : case IrOpcode::kJSRejectPromise:
236 : case IrOpcode::kJSResolvePromise:
237 : case IrOpcode::kJSPerformPromiseThen:
238 : case IrOpcode::kJSObjectIsArray:
239 : case IrOpcode::kJSRegExpTest:
240 : return true;
241 :
242 : default:
243 984927516 : return false;
244 : }
245 : }
246 :
247 :
248 : // static
249 258414 : int OperatorProperties::GetTotalInputCount(const Operator* op) {
250 516828 : return op->ValueInputCount() + GetContextInputCount(op) +
251 258414 : GetFrameStateInputCount(op) + op->EffectInputCount() +
252 258414 : op->ControlInputCount();
253 : }
254 :
255 :
256 : // static
257 44 : bool OperatorProperties::IsBasicBlockBegin(const Operator* op) {
258 : Operator::Opcode const opcode = op->opcode();
259 44 : return opcode == IrOpcode::kStart || opcode == IrOpcode::kEnd ||
260 44 : opcode == IrOpcode::kDead || opcode == IrOpcode::kLoop ||
261 44 : opcode == IrOpcode::kMerge || opcode == IrOpcode::kIfTrue ||
262 36 : opcode == IrOpcode::kIfFalse || opcode == IrOpcode::kIfSuccess ||
263 72 : opcode == IrOpcode::kIfException || opcode == IrOpcode::kIfValue ||
264 44 : opcode == IrOpcode::kIfDefault;
265 : }
266 :
267 : } // namespace compiler
268 : } // namespace internal
269 121996 : } // namespace v8
|