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 11 namespace v8 { 12 namespace internal { 13 namespace compiler { 14 15 // static HasContextInput(const Operator * op)16bool OperatorProperties::HasContextInput(const Operator* op) { 17 IrOpcode::Value opcode = static_cast<IrOpcode::Value>(op->opcode()); 18 return IrOpcode::IsJsOpcode(opcode); 19 } 20 21 22 // static GetFrameStateInputCount(const Operator * op)23int OperatorProperties::GetFrameStateInputCount(const Operator* op) { 24 switch (op->opcode()) { 25 case IrOpcode::kCheckpoint: 26 case IrOpcode::kFrameState: 27 return 1; 28 case IrOpcode::kJSCallRuntime: { 29 const CallRuntimeParameters& p = CallRuntimeParametersOf(op); 30 return Linkage::NeedsFrameStateInput(p.id()) ? 1 : 0; 31 } 32 33 // Strict equality cannot lazily deoptimize. 34 case IrOpcode::kJSStrictEqual: 35 case IrOpcode::kJSStrictNotEqual: 36 return 0; 37 38 // Compare operations 39 case IrOpcode::kJSEqual: 40 case IrOpcode::kJSNotEqual: 41 case IrOpcode::kJSHasProperty: 42 case IrOpcode::kJSInstanceOf: 43 44 // Object operations 45 case IrOpcode::kJSCreate: 46 case IrOpcode::kJSCreateArguments: 47 case IrOpcode::kJSCreateArray: 48 case IrOpcode::kJSCreateLiteralArray: 49 case IrOpcode::kJSCreateLiteralObject: 50 case IrOpcode::kJSCreateLiteralRegExp: 51 52 // Property access operations 53 case IrOpcode::kJSLoadNamed: 54 case IrOpcode::kJSStoreNamed: 55 case IrOpcode::kJSLoadProperty: 56 case IrOpcode::kJSStoreProperty: 57 case IrOpcode::kJSLoadGlobal: 58 case IrOpcode::kJSStoreGlobal: 59 case IrOpcode::kJSDeleteProperty: 60 61 // Context operations 62 case IrOpcode::kJSCreateScriptContext: 63 64 // Conversions 65 case IrOpcode::kJSToInteger: 66 case IrOpcode::kJSToLength: 67 case IrOpcode::kJSToName: 68 case IrOpcode::kJSToNumber: 69 case IrOpcode::kJSToObject: 70 case IrOpcode::kJSToString: 71 72 // Call operations 73 case IrOpcode::kJSCallConstruct: 74 case IrOpcode::kJSCallFunction: 75 76 // Misc operations 77 case IrOpcode::kJSConvertReceiver: 78 case IrOpcode::kJSForInNext: 79 case IrOpcode::kJSForInPrepare: 80 case IrOpcode::kJSStackCheck: 81 return 1; 82 83 // Binary operators that can deopt in the middle the operation (e.g., 84 // as a result of lazy deopt in ToNumber conversion) need a second frame 85 // state so that we can resume before the operation. 86 case IrOpcode::kJSMultiply: 87 case IrOpcode::kJSAdd: 88 case IrOpcode::kJSBitwiseAnd: 89 case IrOpcode::kJSBitwiseOr: 90 case IrOpcode::kJSBitwiseXor: 91 case IrOpcode::kJSDivide: 92 case IrOpcode::kJSModulus: 93 case IrOpcode::kJSShiftLeft: 94 case IrOpcode::kJSShiftRight: 95 case IrOpcode::kJSShiftRightLogical: 96 case IrOpcode::kJSSubtract: 97 return 2; 98 99 // Compare operators that can deopt in the middle the operation (e.g., 100 // as a result of lazy deopt in ToNumber conversion) need a second frame 101 // state so that we can resume before the operation. 102 case IrOpcode::kJSGreaterThan: 103 case IrOpcode::kJSGreaterThanOrEqual: 104 case IrOpcode::kJSLessThan: 105 case IrOpcode::kJSLessThanOrEqual: 106 return 2; 107 108 default: 109 return 0; 110 } 111 } 112 113 114 // static GetTotalInputCount(const Operator * op)115int OperatorProperties::GetTotalInputCount(const Operator* op) { 116 return op->ValueInputCount() + GetContextInputCount(op) + 117 GetFrameStateInputCount(op) + op->EffectInputCount() + 118 op->ControlInputCount(); 119 } 120 121 122 // static IsBasicBlockBegin(const Operator * op)123bool OperatorProperties::IsBasicBlockBegin(const Operator* op) { 124 Operator::Opcode const opcode = op->opcode(); 125 return opcode == IrOpcode::kStart || opcode == IrOpcode::kEnd || 126 opcode == IrOpcode::kDead || opcode == IrOpcode::kLoop || 127 opcode == IrOpcode::kMerge || opcode == IrOpcode::kIfTrue || 128 opcode == IrOpcode::kIfFalse || opcode == IrOpcode::kIfSuccess || 129 opcode == IrOpcode::kIfException || opcode == IrOpcode::kIfValue || 130 opcode == IrOpcode::kIfDefault; 131 } 132 133 } // namespace compiler 134 } // namespace internal 135 } // namespace v8 136