operator-properties.cc 8.88 KB
Newer Older
1
// Copyright 2014 the V8 project authors. All rights reserved.
2 3 4
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

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 13 14 15

namespace v8 {
namespace internal {
namespace compiler {

16 17
// static
bool OperatorProperties::HasContextInput(const Operator* op) {
18 19 20 21
  IrOpcode::Value opcode = static_cast<IrOpcode::Value>(op->opcode());
  return IrOpcode::IsJsOpcode(opcode);
}

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
// static
bool OperatorProperties::NeedsExactContext(const Operator* op) {
  DCHECK(HasContextInput(op));
  IrOpcode::Value const opcode = static_cast<IrOpcode::Value>(op->opcode());
  switch (opcode) {
#define CASE(Name) case IrOpcode::k##Name:
    // Binary/unary operators, calls and constructor calls only
    // need the context to generate exceptions or lookup fields
    // on the native context, so passing any context is fine.
    JS_SIMPLE_BINOP_LIST(CASE)
    JS_CALL_OP_LIST(CASE)
    JS_CONSTRUCT_OP_LIST(CASE)
    JS_SIMPLE_UNOP_LIST(CASE)
#undef CASE
    case IrOpcode::kJSCloneObject:
    case IrOpcode::kJSCreate:
    case IrOpcode::kJSCreateLiteralArray:
    case IrOpcode::kJSCreateEmptyLiteralArray:
    case IrOpcode::kJSCreateLiteralObject:
    case IrOpcode::kJSCreateEmptyLiteralObject:
    case IrOpcode::kJSCreateArrayFromIterable:
    case IrOpcode::kJSCreateLiteralRegExp:
    case IrOpcode::kJSForInEnumerate:
    case IrOpcode::kJSForInNext:
    case IrOpcode::kJSForInPrepare:
    case IrOpcode::kJSGeneratorRestoreContext:
    case IrOpcode::kJSGeneratorRestoreContinuation:
    case IrOpcode::kJSGeneratorRestoreInputOrDebugPos:
    case IrOpcode::kJSGeneratorRestoreRegister:
    case IrOpcode::kJSGetSuperConstructor:
    case IrOpcode::kJSLoadGlobal:
    case IrOpcode::kJSLoadMessage:
    case IrOpcode::kJSStackCheck:
    case IrOpcode::kJSStoreGlobal:
    case IrOpcode::kJSStoreMessage:
      return false;

    case IrOpcode::kJSCallRuntime:
      return Runtime::NeedsExactContext(CallRuntimeParametersOf(op).id());

    case IrOpcode::kJSCreateArguments:
      // For mapped arguments we need to access slots of context-allocated
      // variables if there's aliasing with formal parameters.
      return CreateArgumentsTypeOf(op) == CreateArgumentsType::kMappedArguments;

    case IrOpcode::kJSCreateBlockContext:
    case IrOpcode::kJSCreateClosure:
    case IrOpcode::kJSCreateFunctionContext:
    case IrOpcode::kJSCreateGeneratorObject:
    case IrOpcode::kJSCreateCatchContext:
    case IrOpcode::kJSCreateWithContext:
    case IrOpcode::kJSDebugger:
    case IrOpcode::kJSDeleteProperty:
    case IrOpcode::kJSGeneratorStore:
    case IrOpcode::kJSHasProperty:
    case IrOpcode::kJSLoadContext:
    case IrOpcode::kJSLoadModule:
    case IrOpcode::kJSLoadNamed:
    case IrOpcode::kJSLoadProperty:
    case IrOpcode::kJSStoreContext:
    case IrOpcode::kJSStoreDataPropertyInLiteral:
    case IrOpcode::kJSStoreInArrayLiteral:
    case IrOpcode::kJSStoreModule:
    case IrOpcode::kJSStoreNamed:
    case IrOpcode::kJSStoreNamedOwn:
    case IrOpcode::kJSStoreProperty:
      return true;

90 91 92
    case IrOpcode::kJSAsyncFunctionEnter:
    case IrOpcode::kJSAsyncFunctionReject:
    case IrOpcode::kJSAsyncFunctionResolve:
93
    case IrOpcode::kJSCreateArrayIterator:
94
    case IrOpcode::kJSCreateAsyncFunctionObject:
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
    case IrOpcode::kJSCreateBoundFunction:
    case IrOpcode::kJSCreateCollectionIterator:
    case IrOpcode::kJSCreateIterResultObject:
    case IrOpcode::kJSCreateStringIterator:
    case IrOpcode::kJSCreateKeyValueArray:
    case IrOpcode::kJSCreateObject:
    case IrOpcode::kJSCreatePromise:
    case IrOpcode::kJSCreateTypedArray:
    case IrOpcode::kJSCreateArray:
    case IrOpcode::kJSFulfillPromise:
    case IrOpcode::kJSObjectIsArray:
    case IrOpcode::kJSPerformPromiseThen:
    case IrOpcode::kJSPromiseResolve:
    case IrOpcode::kJSRegExpTest:
    case IrOpcode::kJSRejectPromise:
    case IrOpcode::kJSResolvePromise:
      // These operators aren't introduced by BytecodeGraphBuilder and
      // thus we don't bother checking them. If you ever introduce one
      // of these early in the BytecodeGraphBuilder make sure to check
      // whether they are context-sensitive.
      break;

#define CASE(Name) case IrOpcode::k##Name:
      // Non-JavaScript operators don't have a notion of "context"
      COMMON_OP_LIST(CASE)
      CONTROL_OP_LIST(CASE)
      MACHINE_OP_LIST(CASE)
      MACHINE_SIMD_OP_LIST(CASE)
      SIMPLIFIED_OP_LIST(CASE)
      break;
#undef CASE
  }
  UNREACHABLE();
}
129 130

// static
131
bool OperatorProperties::HasFrameStateInput(const Operator* op) {
132
  switch (op->opcode()) {
133
    case IrOpcode::kCheckpoint:
134
    case IrOpcode::kFrameState:
135
      return true;
136
    case IrOpcode::kJSCallRuntime: {
137
      const CallRuntimeParameters& p = CallRuntimeParametersOf(op);
138
      return Linkage::NeedsFrameStateInput(p.id());
139 140
    }

141 142
    // Strict equality cannot lazily deoptimize.
    case IrOpcode::kJSStrictEqual:
143
      return false;
144

145 146 147 148
    // Generator creation cannot call back into arbitrary JavaScript.
    case IrOpcode::kJSCreateGeneratorObject:
      return false;

149
    // Binary operations
150 151
    case IrOpcode::kJSAdd:
    case IrOpcode::kJSSubtract:
152
    case IrOpcode::kJSMultiply:
153 154
    case IrOpcode::kJSDivide:
    case IrOpcode::kJSModulus:
155
    case IrOpcode::kJSExponentiate:
156

157 158 159 160 161
    // Bitwise operations
    case IrOpcode::kJSBitwiseOr:
    case IrOpcode::kJSBitwiseXor:
    case IrOpcode::kJSBitwiseAnd:

162 163 164 165 166
    // Shift operations
    case IrOpcode::kJSShiftLeft:
    case IrOpcode::kJSShiftRight:
    case IrOpcode::kJSShiftRightLogical:

167 168
    // Compare operations
    case IrOpcode::kJSEqual:
169 170 171 172
    case IrOpcode::kJSGreaterThan:
    case IrOpcode::kJSGreaterThanOrEqual:
    case IrOpcode::kJSLessThan:
    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 191 192 193 194 195 196
    // Property access operations
    case IrOpcode::kJSLoadNamed:
    case IrOpcode::kJSStoreNamed:
    case IrOpcode::kJSLoadProperty:
    case IrOpcode::kJSStoreProperty:
    case IrOpcode::kJSLoadGlobal:
    case IrOpcode::kJSStoreGlobal:
197
    case IrOpcode::kJSStoreNamedOwn:
198
    case IrOpcode::kJSStoreDataPropertyInLiteral:
199 200
    case IrOpcode::kJSDeleteProperty:

201
    // Conversions
202
    case IrOpcode::kJSToLength:
203
    case IrOpcode::kJSToName:
204
    case IrOpcode::kJSToNumber:
205
    case IrOpcode::kJSToNumberConvertBigInt:
206
    case IrOpcode::kJSToNumeric:
207 208
    case IrOpcode::kJSToObject:
    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 223 224
    case IrOpcode::kJSAsyncFunctionEnter:
    case IrOpcode::kJSAsyncFunctionReject:
    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 232
    case IrOpcode::kJSDecrement:
    case IrOpcode::kJSIncrement:
233
    case IrOpcode::kJSNegate:
234
    case IrOpcode::kJSPromiseResolve:
235 236
    case IrOpcode::kJSRejectPromise:
    case IrOpcode::kJSResolvePromise:
237
    case IrOpcode::kJSPerformPromiseThen:
238
    case IrOpcode::kJSObjectIsArray:
239
    case IrOpcode::kJSRegExpTest:
240
      return true;
241

242
    default:
243
      return false;
244 245
  }
}
246

247

248 249
// static
int OperatorProperties::GetTotalInputCount(const Operator* op) {
250 251 252
  return op->ValueInputCount() + GetContextInputCount(op) +
         GetFrameStateInputCount(op) + op->EffectInputCount() +
         op->ControlInputCount();
253 254
}

255

256 257 258
// static
bool OperatorProperties::IsBasicBlockBegin(const Operator* op) {
  Operator::Opcode const opcode = op->opcode();
259
  return opcode == IrOpcode::kStart || opcode == IrOpcode::kEnd ||
260
         opcode == IrOpcode::kDead || opcode == IrOpcode::kLoop ||
261
         opcode == IrOpcode::kMerge || opcode == IrOpcode::kIfTrue ||
262 263
         opcode == IrOpcode::kIfFalse || opcode == IrOpcode::kIfSuccess ||
         opcode == IrOpcode::kIfException || opcode == IrOpcode::kIfValue ||
264
         opcode == IrOpcode::kIfDefault;
265 266
}

267 268 269
}  // namespace compiler
}  // namespace internal
}  // namespace v8