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 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
264 | 264 |
265 | 265 |
266 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadFalse() { | 266 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadFalse() { |
267 Output(Bytecode::kLdaFalse); | 267 Output(Bytecode::kLdaFalse); |
268 return *this; | 268 return *this; |
269 } | 269 } |
270 | 270 |
271 | 271 |
272 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadAccumulatorWithRegister( | 272 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadAccumulatorWithRegister( |
273 Register reg) { | 273 Register reg) { |
274 // TODO(oth): Avoid loading the accumulator with the register if the | 274 if (!IsRegisterInAccumulator(reg)) { |
275 // previous bytecode stored the accumulator with the same register. | 275 Output(Bytecode::kLdar, reg.ToOperand()); |
276 Output(Bytecode::kLdar, reg.ToOperand()); | 276 } |
277 return *this; | 277 return *this; |
278 } | 278 } |
279 | 279 |
280 | 280 |
281 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreAccumulatorInRegister( | 281 BytecodeArrayBuilder& BytecodeArrayBuilder::StoreAccumulatorInRegister( |
282 Register reg) { | 282 Register reg) { |
283 // TODO(oth): Avoid storing the accumulator in the register if the | 283 if (!IsRegisterInAccumulator(reg)) { |
284 // previous bytecode loaded the accumulator with the same register. | 284 Output(Bytecode::kStar, reg.ToOperand()); |
285 Output(Bytecode::kStar, reg.ToOperand()); | 285 } |
286 return *this; | 286 return *this; |
287 } | 287 } |
288 | 288 |
289 | 289 |
290 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadGlobal( | 290 BytecodeArrayBuilder& BytecodeArrayBuilder::LoadGlobal( |
291 size_t name_index, int feedback_slot, LanguageMode language_mode, | 291 size_t name_index, int feedback_slot, LanguageMode language_mode, |
292 TypeofMode typeof_mode) { | 292 TypeofMode typeof_mode) { |
293 // TODO(rmcilroy): Potentially store language and typeof information in an | 293 // TODO(rmcilroy): Potentially store language and typeof information in an |
294 // operand rather than having extra bytecodes. | 294 // operand rather than having extra bytecodes. |
295 Bytecode bytecode = BytecodeForLoadGlobal(language_mode, typeof_mode); | 295 Bytecode bytecode = BytecodeForLoadGlobal(language_mode, typeof_mode); |
(...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
945 return true; | 945 return true; |
946 } else { | 946 } else { |
947 return TemporaryRegisterIsLive(reg); | 947 return TemporaryRegisterIsLive(reg); |
948 } | 948 } |
949 } | 949 } |
950 } | 950 } |
951 UNREACHABLE(); | 951 UNREACHABLE(); |
952 return false; | 952 return false; |
953 } | 953 } |
954 | 954 |
| 955 |
955 bool BytecodeArrayBuilder::LastBytecodeInSameBlock() const { | 956 bool BytecodeArrayBuilder::LastBytecodeInSameBlock() const { |
956 return last_bytecode_start_ < bytecodes()->size() && | 957 return last_bytecode_start_ < bytecodes()->size() && |
957 last_bytecode_start_ >= last_block_end_; | 958 last_bytecode_start_ >= last_block_end_; |
958 } | 959 } |
959 | 960 |
960 | 961 |
| 962 bool BytecodeArrayBuilder::IsRegisterInAccumulator(Register reg) { |
| 963 if (!LastBytecodeInSameBlock()) return false; |
| 964 Bytecode previous_bytecode = |
| 965 Bytecodes::FromByte(bytecodes()->at(last_bytecode_start_)); |
| 966 if (previous_bytecode == Bytecode::kLdar || |
| 967 previous_bytecode == Bytecode::kStar) { |
| 968 size_t operand_offset = last_bytecode_start_ + |
| 969 Bytecodes::GetOperandOffset(previous_bytecode, 0); |
| 970 if (reg == Register::FromOperand(bytecodes()->at(operand_offset))) { |
| 971 return true; |
| 972 } |
| 973 } |
| 974 return false; |
| 975 } |
| 976 |
| 977 |
961 // static | 978 // static |
962 Bytecode BytecodeArrayBuilder::BytecodeForBinaryOperation(Token::Value op) { | 979 Bytecode BytecodeArrayBuilder::BytecodeForBinaryOperation(Token::Value op) { |
963 switch (op) { | 980 switch (op) { |
964 case Token::Value::ADD: | 981 case Token::Value::ADD: |
965 return Bytecode::kAdd; | 982 return Bytecode::kAdd; |
966 case Token::Value::SUB: | 983 case Token::Value::SUB: |
967 return Bytecode::kSub; | 984 return Bytecode::kSub; |
968 case Token::Value::MUL: | 985 case Token::Value::MUL: |
969 return Bytecode::kMul; | 986 return Bytecode::kMul; |
970 case Token::Value::DIV: | 987 case Token::Value::DIV: |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1282 DCHECK_GT(next_consecutive_count_, 0); | 1299 DCHECK_GT(next_consecutive_count_, 0); |
1283 builder_->BorrowConsecutiveTemporaryRegister(next_consecutive_register_); | 1300 builder_->BorrowConsecutiveTemporaryRegister(next_consecutive_register_); |
1284 allocated_.push_back(next_consecutive_register_); | 1301 allocated_.push_back(next_consecutive_register_); |
1285 next_consecutive_count_--; | 1302 next_consecutive_count_--; |
1286 return Register(next_consecutive_register_++); | 1303 return Register(next_consecutive_register_++); |
1287 } | 1304 } |
1288 | 1305 |
1289 } // namespace interpreter | 1306 } // namespace interpreter |
1290 } // namespace internal | 1307 } // namespace internal |
1291 } // namespace v8 | 1308 } // namespace v8 |
OLD | NEW |