Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef V8_COMPILER_OPERATOR_PROPERTIES_INL_H_ | 5 #ifndef V8_COMPILER_OPERATOR_PROPERTIES_INL_H_ |
| 6 #define V8_COMPILER_OPERATOR_PROPERTIES_INL_H_ | 6 #define V8_COMPILER_OPERATOR_PROPERTIES_INL_H_ |
| 7 | 7 |
| 8 #include "src/compiler/common-operator.h" | 8 #include "src/compiler/common-operator.h" |
| 9 #include "src/compiler/js-operator.h" | 9 #include "src/compiler/js-operator.h" |
| 10 #include "src/compiler/opcodes.h" | 10 #include "src/compiler/opcodes.h" |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 31 return OperatorProperties::GetControlInputCount(op) > 0; | 31 return OperatorProperties::GetControlInputCount(op) > 0; |
| 32 } | 32 } |
| 33 | 33 |
| 34 inline bool OperatorProperties::HasFrameStateInput(Operator* op) { | 34 inline bool OperatorProperties::HasFrameStateInput(Operator* op) { |
| 35 if (!FLAG_turbo_deoptimization) { | 35 if (!FLAG_turbo_deoptimization) { |
| 36 return false; | 36 return false; |
| 37 } | 37 } |
| 38 | 38 |
| 39 switch (op->opcode()) { | 39 switch (op->opcode()) { |
| 40 case IrOpcode::kJSCallFunction: | 40 case IrOpcode::kJSCallFunction: |
| 41 case IrOpcode::kJSCallConstruct: | |
| 41 return true; | 42 return true; |
| 42 case IrOpcode::kJSCallRuntime: { | 43 case IrOpcode::kJSCallRuntime: { |
| 43 Runtime::FunctionId function = | 44 Runtime::FunctionId function = |
| 44 reinterpret_cast<Operator1<Runtime::FunctionId>*>(op)->parameter(); | 45 reinterpret_cast<Operator1<Runtime::FunctionId>*>(op)->parameter(); |
| 45 // TODO(jarin) At the moment, we only add frame state for | 46 // TODO(jarin) At the moment, we only add frame state for |
| 46 // few chosen runtime functions. | 47 // few chosen runtime functions. |
| 47 switch (function) { | 48 switch (function) { |
| 48 case Runtime::kDebugBreak: | 49 case Runtime::kDebugBreak: |
| 49 case Runtime::kDeoptimizeFunction: | 50 case Runtime::kDeoptimizeFunction: |
| 50 case Runtime::kSetScriptBreakPoint: | 51 case Runtime::kSetScriptBreakPoint: |
| 51 case Runtime::kDebugGetLoadedScripts: | 52 case Runtime::kDebugGetLoadedScripts: |
| 52 case Runtime::kStackGuard: | 53 case Runtime::kStackGuard: |
| 53 return true; | 54 return true; |
| 54 default: | 55 default: |
| 55 return false; | 56 return false; |
| 56 } | 57 } |
| 57 UNREACHABLE(); | 58 UNREACHABLE(); |
| 58 } | 59 } |
| 59 | 60 |
| 61 // Binary operations | |
| 62 case IrOpcode::kJSBitwiseOr: | |
| 63 case IrOpcode::kJSBitwiseXor: | |
| 64 case IrOpcode::kJSBitwiseAnd: | |
| 65 case IrOpcode::kJSShiftLeft: | |
| 66 case IrOpcode::kJSShiftRight: | |
| 67 case IrOpcode::kJSShiftRightLogical: | |
| 68 case IrOpcode::kJSAdd: | |
| 69 case IrOpcode::kJSSubtract: | |
| 70 case IrOpcode::kJSMultiply: | |
| 71 case IrOpcode::kJSDivide: | |
| 72 case IrOpcode::kJSModulus: | |
| 73 case IrOpcode::kJSLoadProperty: | |
| 74 case IrOpcode::kJSStoreProperty: | |
| 75 case IrOpcode::kJSLoadNamed: | |
| 76 case IrOpcode::kJSStoreNamed: | |
| 77 return true; | |
| 78 | |
| 60 default: | 79 default: |
| 61 return false; | 80 return false; |
| 62 } | 81 } |
| 63 } | 82 } |
| 64 | 83 |
| 65 inline int OperatorProperties::GetValueInputCount(Operator* op) { | 84 inline int OperatorProperties::GetValueInputCount(Operator* op) { |
| 66 return op->InputCount(); | 85 return op->InputCount(); |
| 67 } | 86 } |
| 68 | 87 |
| 69 inline int OperatorProperties::GetContextInputCount(Operator* op) { | 88 inline int OperatorProperties::GetContextInputCount(Operator* op) { |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 88 switch (op->opcode()) { | 107 switch (op->opcode()) { |
| 89 case IrOpcode::kPhi: | 108 case IrOpcode::kPhi: |
| 90 case IrOpcode::kEffectPhi: | 109 case IrOpcode::kEffectPhi: |
| 91 case IrOpcode::kControlEffect: | 110 case IrOpcode::kControlEffect: |
| 92 return 1; | 111 return 1; |
| 93 #define OPCODE_CASE(x) case IrOpcode::k##x: | 112 #define OPCODE_CASE(x) case IrOpcode::k##x: |
| 94 CONTROL_OP_LIST(OPCODE_CASE) | 113 CONTROL_OP_LIST(OPCODE_CASE) |
| 95 #undef OPCODE_CASE | 114 #undef OPCODE_CASE |
| 96 return static_cast<ControlOperator*>(op)->ControlInputCount(); | 115 return static_cast<ControlOperator*>(op)->ControlInputCount(); |
| 97 default: | 116 default: |
| 98 // If a node can lazily deoptimize, it needs control dependency. | |
| 99 if (CanLazilyDeoptimize(op)) { | |
| 100 return 1; | |
| 101 } | |
| 102 // Operators that have write effects must have a control | 117 // Operators that have write effects must have a control |
| 103 // dependency. Effect dependencies only ensure the correct order of | 118 // dependency. Effect dependencies only ensure the correct order of |
| 104 // write/read operations without consideration of control flow. Without an | 119 // write/read operations without consideration of control flow. Without an |
| 105 // explicit control dependency writes can be float in the schedule too | 120 // explicit control dependency writes can be float in the schedule too |
| 106 // early along a path that shouldn't generate a side-effect. | 121 // early along a path that shouldn't generate a side-effect. |
| 107 return op->HasProperty(Operator::kNoWrite) ? 0 : 1; | 122 return op->HasProperty(Operator::kNoWrite) ? 0 : 1; |
| 108 } | 123 } |
| 109 return 0; | 124 return 0; |
| 110 } | 125 } |
| 111 | 126 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 124 | 139 |
| 125 inline bool OperatorProperties::HasEffectOutput(Operator* op) { | 140 inline bool OperatorProperties::HasEffectOutput(Operator* op) { |
| 126 return op->opcode() == IrOpcode::kStart || | 141 return op->opcode() == IrOpcode::kStart || |
| 127 op->opcode() == IrOpcode::kControlEffect || | 142 op->opcode() == IrOpcode::kControlEffect || |
| 128 op->opcode() == IrOpcode::kValueEffect || | 143 op->opcode() == IrOpcode::kValueEffect || |
| 129 (op->opcode() != IrOpcode::kFinish && GetEffectInputCount(op) > 0); | 144 (op->opcode() != IrOpcode::kFinish && GetEffectInputCount(op) > 0); |
| 130 } | 145 } |
| 131 | 146 |
| 132 inline bool OperatorProperties::HasControlOutput(Operator* op) { | 147 inline bool OperatorProperties::HasControlOutput(Operator* op) { |
| 133 IrOpcode::Value opcode = static_cast<IrOpcode::Value>(op->opcode()); | 148 IrOpcode::Value opcode = static_cast<IrOpcode::Value>(op->opcode()); |
| 134 return (opcode != IrOpcode::kEnd && IrOpcode::IsControlOpcode(opcode)) || | 149 return (opcode != IrOpcode::kEnd && IrOpcode::IsControlOpcode(opcode)); |
| 135 CanLazilyDeoptimize(op); | |
| 136 } | 150 } |
| 137 | 151 |
| 138 | 152 |
| 139 inline int OperatorProperties::GetValueOutputCount(Operator* op) { | 153 inline int OperatorProperties::GetValueOutputCount(Operator* op) { |
| 140 return op->OutputCount(); | 154 return op->OutputCount(); |
| 141 } | 155 } |
| 142 | 156 |
| 143 inline int OperatorProperties::GetEffectOutputCount(Operator* op) { | 157 inline int OperatorProperties::GetEffectOutputCount(Operator* op) { |
| 144 return HasEffectOutput(op) ? 1 : 0; | 158 return HasEffectOutput(op) ? 1 : 0; |
| 145 } | 159 } |
| 146 | 160 |
| 147 inline int OperatorProperties::GetControlOutputCount(Operator* node) { | 161 inline int OperatorProperties::GetControlOutputCount(Operator* node) { |
| 148 return node->opcode() == IrOpcode::kBranch ? 2 : HasControlOutput(node) ? 1 | 162 return node->opcode() == IrOpcode::kBranch ? 2 : HasControlOutput(node) ? 1 |
| 149 : 0; | 163 : 0; |
| 150 } | 164 } |
| 151 | 165 |
| 152 | 166 |
| 153 inline bool OperatorProperties::IsBasicBlockBegin(Operator* op) { | 167 inline bool OperatorProperties::IsBasicBlockBegin(Operator* op) { |
| 154 uint8_t opcode = op->opcode(); | 168 uint8_t opcode = op->opcode(); |
| 155 return opcode == IrOpcode::kStart || opcode == IrOpcode::kEnd || | 169 return opcode == IrOpcode::kStart || opcode == IrOpcode::kEnd || |
| 156 opcode == IrOpcode::kDead || opcode == IrOpcode::kLoop || | 170 opcode == IrOpcode::kDead || opcode == IrOpcode::kLoop || |
| 157 opcode == IrOpcode::kMerge || opcode == IrOpcode::kIfTrue || | 171 opcode == IrOpcode::kMerge || opcode == IrOpcode::kIfTrue || |
| 158 opcode == IrOpcode::kIfFalse; | 172 opcode == IrOpcode::kIfFalse; |
| 159 } | 173 } |
| 160 | 174 |
| 161 inline bool OperatorProperties::CanLazilyDeoptimize(Operator* op) { | 175 // inline bool OperatorProperties::CanLazilyDeoptimize(Operator* op) { |
|
Benedikt Meurer
2014/09/01 09:07:05
Why is this still here?
Jarin
2014/09/01 09:23:34
Removed.
| |
| 162 // TODO(jarin) This function allows turning on lazy deoptimization | 176 // // TODO(jarin) This function allows turning on lazy deoptimization |
| 163 // incrementally. It will change as we turn on lazy deopt for | 177 // // incrementally. It will change as we turn on lazy deopt for |
| 164 // more nodes. | 178 // // more nodes. |
| 165 | 179 // |
| 166 if (!FLAG_turbo_deoptimization) { | 180 // if (!FLAG_turbo_deoptimization) { |
| 167 return false; | 181 // return false; |
| 168 } | 182 // } |
| 169 | 183 // |
| 170 switch (op->opcode()) { | 184 // switch (op->opcode()) { |
| 171 case IrOpcode::kCall: { | 185 // case IrOpcode::kCall: { |
| 172 CallOperator* call_op = reinterpret_cast<CallOperator*>(op); | 186 // CallOperator* call_op = reinterpret_cast<CallOperator*>(op); |
| 173 CallDescriptor* descriptor = call_op->parameter(); | 187 // CallDescriptor* descriptor = call_op->parameter(); |
| 174 return descriptor->CanLazilyDeoptimize(); | 188 // return descriptor->CanLazilyDeoptimize(); |
| 175 } | 189 // } |
| 176 case IrOpcode::kJSCallRuntime: { | 190 // case IrOpcode::kJSCallRuntime: { |
| 177 Runtime::FunctionId function = | 191 // Runtime::FunctionId function = |
| 178 reinterpret_cast<Operator1<Runtime::FunctionId>*>(op)->parameter(); | 192 // reinterpret_cast<Operator1<Runtime::FunctionId>*>(op)->parameter(); |
| 179 // TODO(jarin) At the moment, we only support lazy deoptimization for | 193 // // TODO(jarin) At the moment, we only support lazy deoptimization for |
| 180 // a few chosen runtime functions. | 194 // // a few chosen runtime functions. |
| 181 switch (function) { | 195 // switch (function) { |
| 182 case Runtime::kDebugBreak: | 196 // case Runtime::kDebugBreak: |
| 183 case Runtime::kDeoptimizeFunction: | 197 // case Runtime::kDeoptimizeFunction: |
| 184 case Runtime::kSetScriptBreakPoint: | 198 // case Runtime::kSetScriptBreakPoint: |
| 185 case Runtime::kDebugGetLoadedScripts: | 199 // case Runtime::kDebugGetLoadedScripts: |
| 186 case Runtime::kStackGuard: | 200 // case Runtime::kStackGuard: |
| 187 return true; | 201 // return true; |
| 188 default: | 202 // default: |
| 189 return false; | 203 // return false; |
| 190 } | 204 // } |
| 191 UNREACHABLE(); | 205 // UNREACHABLE(); |
| 192 } | 206 // } |
| 193 | 207 // |
| 194 // JS function calls | 208 // // JS function calls |
| 195 case IrOpcode::kJSCallFunction: | 209 // case IrOpcode::kJSCallFunction: |
| 196 case IrOpcode::kJSCallConstruct: | 210 // case IrOpcode::kJSCallConstruct: |
| 197 | 211 // |
| 198 // Binary operations | 212 // // Binary operations |
| 199 case IrOpcode::kJSBitwiseOr: | 213 // case IrOpcode::kJSBitwiseOr: |
| 200 case IrOpcode::kJSBitwiseXor: | 214 // case IrOpcode::kJSBitwiseXor: |
| 201 case IrOpcode::kJSBitwiseAnd: | 215 // case IrOpcode::kJSBitwiseAnd: |
| 202 case IrOpcode::kJSShiftLeft: | 216 // case IrOpcode::kJSShiftLeft: |
| 203 case IrOpcode::kJSShiftRight: | 217 // case IrOpcode::kJSShiftRight: |
| 204 case IrOpcode::kJSShiftRightLogical: | 218 // case IrOpcode::kJSShiftRightLogical: |
| 205 case IrOpcode::kJSAdd: | 219 // case IrOpcode::kJSAdd: |
| 206 case IrOpcode::kJSSubtract: | 220 // case IrOpcode::kJSSubtract: |
| 207 case IrOpcode::kJSMultiply: | 221 // case IrOpcode::kJSMultiply: |
| 208 case IrOpcode::kJSDivide: | 222 // case IrOpcode::kJSDivide: |
| 209 case IrOpcode::kJSModulus: | 223 // case IrOpcode::kJSModulus: |
| 210 case IrOpcode::kJSLoadProperty: | 224 // case IrOpcode::kJSLoadProperty: |
| 211 case IrOpcode::kJSStoreProperty: | 225 // case IrOpcode::kJSStoreProperty: |
| 212 case IrOpcode::kJSLoadNamed: | 226 // case IrOpcode::kJSLoadNamed: |
| 213 case IrOpcode::kJSStoreNamed: | 227 // case IrOpcode::kJSStoreNamed: |
| 214 return true; | 228 // return true; |
| 215 | 229 // |
| 216 default: | 230 // default: |
| 217 return false; | 231 // return false; |
| 218 } | 232 // } |
| 219 return false; | 233 // return false; |
| 220 } | 234 // } |
| 221 } | 235 } |
| 222 } | 236 } |
| 223 } // namespace v8::internal::compiler | 237 } // namespace v8::internal::compiler |
| 224 | 238 |
| 225 #endif // V8_COMPILER_OPERATOR_PROPERTIES_INL_H_ | 239 #endif // V8_COMPILER_OPERATOR_PROPERTIES_INL_H_ |
| OLD | NEW |