OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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 #include "src/interpreter/bytecode-array-builder.h" | 5 #include "src/interpreter/bytecode-array-builder.h" |
6 | 6 |
7 #include "src/globals.h" | 7 #include "src/globals.h" |
8 #include "src/interpreter/bytecode-array-writer.h" | 8 #include "src/interpreter/bytecode-array-writer.h" |
9 #include "src/interpreter/bytecode-dead-code-optimizer.h" | 9 #include "src/interpreter/bytecode-dead-code-optimizer.h" |
10 #include "src/interpreter/bytecode-label.h" | 10 #include "src/interpreter/bytecode-label.h" |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
136 } | 136 } |
137 }; | 137 }; |
138 | 138 |
139 template <OperandType> | 139 template <OperandType> |
140 class OperandHelper {}; | 140 class OperandHelper {}; |
141 | 141 |
142 #define DEFINE_UNSIGNED_OPERAND_HELPER(Name, Type) \ | 142 #define DEFINE_UNSIGNED_OPERAND_HELPER(Name, Type) \ |
143 template <> \ | 143 template <> \ |
144 class OperandHelper<OperandType::k##Name> \ | 144 class OperandHelper<OperandType::k##Name> \ |
145 : public UnsignedOperandHelper<Type> {}; | 145 : public UnsignedOperandHelper<Type> {}; |
146 UNSIGNED_SCALAR_OPERAND_TYPE_LIST(DEFINE_UNSIGNED_OPERAND_HELPER) | 146 UNSIGNED_FIXED_SCALAR_OPERAND_TYPE_LIST(DEFINE_UNSIGNED_OPERAND_HELPER) |
| 147 UNSIGNED_SCALABLE_SCALAR_OPERAND_TYPE_LIST(DEFINE_UNSIGNED_OPERAND_HELPER) |
147 #undef DEFINE_UNSIGNED_OPERAND_HELPER | 148 #undef DEFINE_UNSIGNED_OPERAND_HELPER |
148 | 149 |
149 template <> | 150 template <> |
150 class OperandHelper<OperandType::kImm> { | 151 class OperandHelper<OperandType::kImm> { |
151 public: | 152 public: |
152 INLINE(static uint32_t Convert(BytecodeArrayBuilder* builder, int value)) { | 153 INLINE(static uint32_t Convert(BytecodeArrayBuilder* builder, int value)) { |
153 return static_cast<uint32_t>(value); | 154 return static_cast<uint32_t>(value); |
154 } | 155 } |
155 }; | 156 }; |
156 | 157 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
204 public: | 205 public: |
205 INLINE(static uint32_t Convert(BytecodeArrayBuilder* builder, | 206 INLINE(static uint32_t Convert(BytecodeArrayBuilder* builder, |
206 RegisterList reg_list)) { | 207 RegisterList reg_list)) { |
207 DCHECK_EQ(3, reg_list.register_count()); | 208 DCHECK_EQ(3, reg_list.register_count()); |
208 return builder->GetOutputRegisterListOperand(reg_list); | 209 return builder->GetOutputRegisterListOperand(reg_list); |
209 } | 210 } |
210 }; | 211 }; |
211 | 212 |
212 } // namespace | 213 } // namespace |
213 | 214 |
214 template <OperandType... operand_types> | 215 template <Bytecode bytecode, AccumulatorUse accumulator_use, |
| 216 OperandType... operand_types> |
215 class BytecodeNodeBuilder { | 217 class BytecodeNodeBuilder { |
216 public: | 218 public: |
217 template <typename... Operands> | 219 template <typename... Operands> |
218 INLINE(static BytecodeNode Make(BytecodeArrayBuilder* builder, | 220 INLINE(static BytecodeNode Make(BytecodeArrayBuilder* builder, |
219 BytecodeSourceInfo source_info, | 221 BytecodeSourceInfo source_info, |
220 Bytecode bytecode, Operands... operands)) { | 222 Operands... operands)) { |
221 builder->PrepareToOutputBytecode(bytecode); | 223 builder->PrepareToOutputBytecode<bytecode, accumulator_use>(); |
222 // The "OperandHelper<operand_types>::Convert(builder, operands)..." will | 224 // The "OperandHelper<operand_types>::Convert(builder, operands)..." will |
223 // expand both the OperandType... and Operands... parameter packs e.g. for: | 225 // expand both the OperandType... and Operands... parameter packs e.g. for: |
224 // BytecodeNodeBuilder<OperandType::kReg, OperandType::kImm>::Make< | 226 // BytecodeNodeBuilder<OperandType::kReg, OperandType::kImm>::Make< |
225 // Register, int>(..., Register reg, int immediate) | 227 // Register, int>(..., Register reg, int immediate) |
226 // the code will expand into: | 228 // the code will expand into: |
227 // OperandHelper<OperandType::kReg>::Convert(builder, reg), | 229 // OperandHelper<OperandType::kReg>::Convert(builder, reg), |
228 // OperandHelper<OperandType::kImm>::Convert(builder, immediate), | 230 // OperandHelper<OperandType::kImm>::Convert(builder, immediate), |
229 return BytecodeNode( | 231 return BytecodeNode::Create<bytecode, accumulator_use, operand_types...>( |
230 bytecode, OperandHelper<operand_types>::Convert(builder, operands)..., | 232 source_info, |
231 source_info); | 233 OperandHelper<operand_types>::Convert(builder, operands)...); |
232 } | 234 } |
233 }; | 235 }; |
234 | 236 |
235 #define DEFINE_BYTECODE_OUTPUT(name, accumulator_use, ...) \ | 237 #define DEFINE_BYTECODE_OUTPUT(name, ...) \ |
236 template <typename... Operands> \ | 238 template <typename... Operands> \ |
237 void BytecodeArrayBuilder::Output##name(Operands... operands) { \ | 239 void BytecodeArrayBuilder::Output##name(Operands... operands) { \ |
238 static_assert(sizeof...(Operands) <= Bytecodes::kMaxOperands, \ | 240 static_assert(sizeof...(Operands) <= Bytecodes::kMaxOperands, \ |
239 "too many operands for bytecode"); \ | 241 "too many operands for bytecode"); \ |
240 BytecodeNode node(BytecodeNodeBuilder<__VA_ARGS__>::Make<Operands...>( \ | 242 BytecodeNode node( \ |
241 this, CurrentSourcePosition(Bytecode::k##name), Bytecode::k##name, \ | 243 BytecodeNodeBuilder<Bytecode::k##name, __VA_ARGS__>::Make< \ |
242 operands...)); \ | 244 Operands...>(this, CurrentSourcePosition(Bytecode::k##name), \ |
243 pipeline()->Write(&node); \ | 245 operands...)); \ |
244 } \ | 246 pipeline()->Write(&node); \ |
245 \ | 247 } \ |
246 template <typename... Operands> \ | 248 \ |
247 void BytecodeArrayBuilder::Output##name(BytecodeLabel* label, \ | 249 template <typename... Operands> \ |
248 Operands... operands) { \ | 250 void BytecodeArrayBuilder::Output##name(BytecodeLabel* label, \ |
249 DCHECK(Bytecodes::IsJump(Bytecode::k##name)); \ | 251 Operands... operands) { \ |
250 BytecodeNode node(BytecodeNodeBuilder<__VA_ARGS__>::Make<Operands...>( \ | 252 DCHECK(Bytecodes::IsJump(Bytecode::k##name)); \ |
251 this, CurrentSourcePosition(Bytecode::k##name), Bytecode::k##name, \ | 253 BytecodeNode node( \ |
252 operands...)); \ | 254 BytecodeNodeBuilder<Bytecode::k##name, __VA_ARGS__>::Make< \ |
253 pipeline()->WriteJump(&node, label); \ | 255 Operands...>(this, CurrentSourcePosition(Bytecode::k##name), \ |
254 LeaveBasicBlock(); \ | 256 operands...)); \ |
| 257 pipeline()->WriteJump(&node, label); \ |
| 258 LeaveBasicBlock(); \ |
255 } | 259 } |
256 BYTECODE_LIST(DEFINE_BYTECODE_OUTPUT) | 260 BYTECODE_LIST(DEFINE_BYTECODE_OUTPUT) |
257 #undef DEFINE_BYTECODE_OUTPUT | 261 #undef DEFINE_BYTECODE_OUTPUT |
258 | 262 |
259 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op, | 263 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op, |
260 Register reg, | 264 Register reg, |
261 int feedback_slot) { | 265 int feedback_slot) { |
262 switch (op) { | 266 switch (op) { |
263 case Token::Value::ADD: | 267 case Token::Value::ADD: |
264 OutputAdd(reg, feedback_slot); | 268 OutputAdd(reg, feedback_slot); |
(...skipping 728 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
993 int first_reg_index = reg_list.first_register().index(); | 997 int first_reg_index = reg_list.first_register().index(); |
994 for (int i = 0; i < reg_list.register_count(); i++) { | 998 for (int i = 0; i < reg_list.register_count(); i++) { |
995 if (!RegisterIsValid(Register(first_reg_index + i))) { | 999 if (!RegisterIsValid(Register(first_reg_index + i))) { |
996 return false; | 1000 return false; |
997 } | 1001 } |
998 } | 1002 } |
999 return true; | 1003 return true; |
1000 } | 1004 } |
1001 } | 1005 } |
1002 | 1006 |
1003 void BytecodeArrayBuilder::PrepareToOutputBytecode(Bytecode bytecode) { | 1007 template <Bytecode bytecode, AccumulatorUse accumulator_use> |
1004 if (register_optimizer_) register_optimizer_->PrepareForBytecode(bytecode); | 1008 void BytecodeArrayBuilder::PrepareToOutputBytecode() { |
| 1009 if (register_optimizer_) |
| 1010 register_optimizer_->PrepareForBytecode<bytecode, accumulator_use>(); |
1005 } | 1011 } |
1006 | 1012 |
1007 uint32_t BytecodeArrayBuilder::GetInputRegisterOperand(Register reg) { | 1013 uint32_t BytecodeArrayBuilder::GetInputRegisterOperand(Register reg) { |
1008 DCHECK(RegisterIsValid(reg)); | 1014 DCHECK(RegisterIsValid(reg)); |
1009 if (register_optimizer_) reg = register_optimizer_->GetInputRegister(reg); | 1015 if (register_optimizer_) reg = register_optimizer_->GetInputRegister(reg); |
1010 return static_cast<uint32_t>(reg.ToOperand()); | 1016 return static_cast<uint32_t>(reg.ToOperand()); |
1011 } | 1017 } |
1012 | 1018 |
1013 uint32_t BytecodeArrayBuilder::GetOutputRegisterOperand(Register reg) { | 1019 uint32_t BytecodeArrayBuilder::GetOutputRegisterOperand(Register reg) { |
1014 DCHECK(RegisterIsValid(reg)); | 1020 DCHECK(RegisterIsValid(reg)); |
(...skipping 13 matching lines...) Expand all Loading... |
1028 RegisterList reg_list) { | 1034 RegisterList reg_list) { |
1029 DCHECK(RegisterListIsValid(reg_list)); | 1035 DCHECK(RegisterListIsValid(reg_list)); |
1030 if (register_optimizer_) | 1036 if (register_optimizer_) |
1031 register_optimizer_->PrepareOutputRegisterList(reg_list); | 1037 register_optimizer_->PrepareOutputRegisterList(reg_list); |
1032 return static_cast<uint32_t>(reg_list.first_register().ToOperand()); | 1038 return static_cast<uint32_t>(reg_list.first_register().ToOperand()); |
1033 } | 1039 } |
1034 | 1040 |
1035 } // namespace interpreter | 1041 } // namespace interpreter |
1036 } // namespace internal | 1042 } // namespace internal |
1037 } // namespace v8 | 1043 } // namespace v8 |
OLD | NEW |