| 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 namespace v8 { | 7 namespace v8 { |
| 8 namespace internal { | 8 namespace internal { |
| 9 namespace interpreter { | 9 namespace interpreter { |
| 10 | 10 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 32 int register_count = local_register_count_ + temporary_register_count_; | 32 int register_count = local_register_count_ + temporary_register_count_; |
| 33 int frame_size = register_count * kPointerSize; | 33 int frame_size = register_count * kPointerSize; |
| 34 Handle<BytecodeArray> output = isolate_->factory()->NewBytecodeArray( | 34 Handle<BytecodeArray> output = isolate_->factory()->NewBytecodeArray( |
| 35 bytecode_size, &bytecodes_.front(), frame_size); | 35 bytecode_size, &bytecodes_.front(), frame_size); |
| 36 bytecode_generated_ = true; | 36 bytecode_generated_ = true; |
| 37 return output; | 37 return output; |
| 38 } | 38 } |
| 39 | 39 |
| 40 | 40 |
| 41 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value binop, | 41 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value binop, |
| 42 int reg) { | 42 Register reg) { |
| 43 Output(BytecodeForBinaryOperation(binop), reg); | 43 Output(BytecodeForBinaryOperation(binop), reg.ToOperand()); |
| 44 return *this; | 44 return *this; |
| 45 } | 45 } |
| 46 | 46 |
| 47 | 47 |
| 48 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral( | 48 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral( |
| 49 v8::internal::Smi* smi) { | 49 v8::internal::Smi* smi) { |
| 50 int32_t raw_smi = smi->value(); | 50 int32_t raw_smi = smi->value(); |
| 51 if (raw_smi == 0) { | 51 if (raw_smi == 0) { |
| 52 Output(Bytecode::kLdaZero); | 52 Output(Bytecode::kLdaZero); |
| 53 } else if (raw_smi > -128 && raw_smi <= 128) { | 53 } else if (raw_smi > -128 && raw_smi <= 128) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 84 } | 84 } |
| 85 | 85 |
| 86 | 86 |
| 87 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadFalse() { | 87 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadFalse() { |
| 88 Output(Bytecode::kLdaFalse); | 88 Output(Bytecode::kLdaFalse); |
| 89 return *this; | 89 return *this; |
| 90 } | 90 } |
| 91 | 91 |
| 92 | 92 |
| 93 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadAccumulatorWithRegister( | 93 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadAccumulatorWithRegister( |
| 94 int reg) { | 94 Register reg) { |
| 95 Output(Bytecode::kLdar, reg); | 95 Output(Bytecode::kLdar, reg.ToOperand()); |
| 96 return *this; | 96 return *this; |
| 97 } | 97 } |
| 98 | 98 |
| 99 | 99 |
| 100 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreAccumulatorInRegister( | 100 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreAccumulatorInRegister( |
| 101 int reg) { | 101 Register reg) { |
| 102 Output(Bytecode::kStar, reg); | 102 Output(Bytecode::kStar, reg.ToOperand()); |
| 103 return *this; | 103 return *this; |
| 104 } | 104 } |
| 105 | 105 |
| 106 | 106 |
| 107 BytecodeArrayBuilder& BytecodeArrayBuilder::Return() { | 107 BytecodeArrayBuilder& BytecodeArrayBuilder::Return() { |
| 108 Output(Bytecode::kReturn); | 108 Output(Bytecode::kReturn); |
| 109 return *this; | 109 return *this; |
| 110 } | 110 } |
| 111 | 111 |
| 112 | 112 |
| 113 int BytecodeArrayBuilder::BorrowTemporaryRegister() { | 113 int BytecodeArrayBuilder::BorrowTemporaryRegister() { |
| 114 DCHECK_GE(local_register_count_, 0); | 114 DCHECK_GE(local_register_count_, 0); |
| 115 int temporary_register = temporary_register_next_++; | 115 int temporary_reg_index = temporary_register_next_++; |
| 116 int count = temporary_register_next_ - local_register_count_; | 116 int count = temporary_register_next_ - local_register_count_; |
| 117 if (count > temporary_register_count_) { | 117 if (count > temporary_register_count_) { |
| 118 temporary_register_count_ = count; | 118 temporary_register_count_ = count; |
| 119 } | 119 } |
| 120 return temporary_register; | 120 return temporary_reg_index; |
| 121 } | 121 } |
| 122 | 122 |
| 123 | 123 |
| 124 void BytecodeArrayBuilder::ReturnTemporaryRegister(int reg) { | 124 void BytecodeArrayBuilder::ReturnTemporaryRegister(int reg_index) { |
| 125 DCHECK_EQ(reg, temporary_register_next_ - 1); | 125 DCHECK_EQ(reg_index, temporary_register_next_ - 1); |
| 126 temporary_register_next_ = reg; | 126 temporary_register_next_ = reg_index; |
| 127 } | 127 } |
| 128 | 128 |
| 129 | 129 |
| 130 bool BytecodeArrayBuilder::OperandIsValid(Bytecode bytecode, int operand_index, | 130 bool BytecodeArrayBuilder::OperandIsValid(Bytecode bytecode, int operand_index, |
| 131 uint8_t operand_value) const { | 131 uint8_t operand_value) const { |
| 132 OperandType operand_type = Bytecodes::GetOperandType(bytecode, operand_index); | 132 OperandType operand_type = Bytecodes::GetOperandType(bytecode, operand_index); |
| 133 switch (operand_type) { | 133 switch (operand_type) { |
| 134 case OperandType::kNone: | 134 case OperandType::kNone: |
| 135 return false; | 135 return false; |
| 136 case OperandType::kImm8: | 136 case OperandType::kImm8: |
| 137 return true; | 137 return true; |
| 138 case OperandType::kReg: | 138 case OperandType::kReg: |
| 139 return operand_value < temporary_register_next_; | 139 return Register::FromOperand(operand_value).index() < |
| 140 temporary_register_next_; |
| 140 } | 141 } |
| 141 UNREACHABLE(); | 142 UNREACHABLE(); |
| 142 return false; | 143 return false; |
| 143 } | 144 } |
| 144 | 145 |
| 145 | 146 |
| 146 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint8_t operand0, | 147 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint8_t operand0, |
| 147 uint8_t operand1, uint8_t operand2) { | 148 uint8_t operand1, uint8_t operand2) { |
| 148 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 3); | 149 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 3); |
| 149 DCHECK(OperandIsValid(bytecode, 0, operand0) && | 150 DCHECK(OperandIsValid(bytecode, 0, operand0) && |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 case Token::Value::DIV: | 194 case Token::Value::DIV: |
| 194 return Bytecode::kDiv; | 195 return Bytecode::kDiv; |
| 195 default: | 196 default: |
| 196 UNIMPLEMENTED(); | 197 UNIMPLEMENTED(); |
| 197 return static_cast<Bytecode>(-1); | 198 return static_cast<Bytecode>(-1); |
| 198 } | 199 } |
| 199 } | 200 } |
| 200 | 201 |
| 201 | 202 |
| 202 TemporaryRegisterScope::TemporaryRegisterScope(BytecodeArrayBuilder* builder) | 203 TemporaryRegisterScope::TemporaryRegisterScope(BytecodeArrayBuilder* builder) |
| 203 : builder_(builder), count_(0), register_(-1) {} | 204 : builder_(builder), count_(0), last_register_index_(-1) {} |
| 204 | 205 |
| 205 | 206 |
| 206 TemporaryRegisterScope::~TemporaryRegisterScope() { | 207 TemporaryRegisterScope::~TemporaryRegisterScope() { |
| 207 while (count_-- != 0) { | 208 while (count_-- != 0) { |
| 208 builder_->ReturnTemporaryRegister(register_--); | 209 builder_->ReturnTemporaryRegister(last_register_index_--); |
| 209 } | 210 } |
| 210 } | 211 } |
| 211 | 212 |
| 212 | 213 |
| 213 int TemporaryRegisterScope::NewRegister() { | 214 Register TemporaryRegisterScope::NewRegister() { |
| 214 count_++; | 215 count_++; |
| 215 register_ = builder_->BorrowTemporaryRegister(); | 216 last_register_index_ = builder_->BorrowTemporaryRegister(); |
| 216 return register_; | 217 return Register(last_register_index_); |
| 217 } | 218 } |
| 218 | 219 |
| 219 } // namespace interpreter | 220 } // namespace interpreter |
| 220 } // namespace internal | 221 } // namespace internal |
| 221 } // namespace v8 | 222 } // namespace v8 |
| OLD | NEW |