| 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 #include "src/compiler.h" | 6 #include "src/compiler.h" |
| 7 | 7 |
| 8 namespace v8 { | 8 namespace v8 { |
| 9 namespace internal { | 9 namespace internal { |
| 10 namespace interpreter { | 10 namespace interpreter { |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray() { | 117 Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray() { |
| 118 DCHECK_EQ(bytecode_generated_, false); | 118 DCHECK_EQ(bytecode_generated_, false); |
| 119 DCHECK(exit_seen_in_block_); | 119 DCHECK(exit_seen_in_block_); |
| 120 | 120 |
| 121 int bytecode_size = static_cast<int>(bytecodes_.size()); | 121 int bytecode_size = static_cast<int>(bytecodes_.size()); |
| 122 int register_count = | 122 int register_count = |
| 123 fixed_and_temporary_register_count() + translation_register_count(); | 123 fixed_and_temporary_register_count() + translation_register_count(); |
| 124 int frame_size = register_count * kPointerSize; | 124 int frame_size = register_count * kPointerSize; |
| 125 Handle<FixedArray> constant_pool = constant_array_builder()->ToFixedArray(); | 125 Handle<FixedArray> constant_pool = constant_array_builder()->ToFixedArray(); |
| 126 Handle<FixedArray> handler_table = handler_table_builder()->ToHandlerTable(); | 126 Handle<FixedArray> handler_table = handler_table_builder()->ToHandlerTable(); |
| 127 Handle<FixedArray> source_position_table = | 127 Handle<ByteArray> source_position_table = |
| 128 source_position_table_builder()->ToFixedArray(); | 128 source_position_table_builder()->ToSourcePositionTable(); |
| 129 Handle<BytecodeArray> output = isolate_->factory()->NewBytecodeArray( | 129 Handle<BytecodeArray> output = isolate_->factory()->NewBytecodeArray( |
| 130 bytecode_size, &bytecodes_.front(), frame_size, parameter_count(), | 130 bytecode_size, &bytecodes_.front(), frame_size, parameter_count(), |
| 131 constant_pool); | 131 constant_pool); |
| 132 output->set_handler_table(*handler_table); | 132 output->set_handler_table(*handler_table); |
| 133 output->set_source_position_table(*source_position_table); | 133 output->set_source_position_table(*source_position_table); |
| 134 bytecode_generated_ = true; | 134 bytecode_generated_ = true; |
| 135 return output; | 135 return output; |
| 136 } | 136 } |
| 137 | 137 |
| 138 | 138 |
| 139 template <size_t N> | 139 template <size_t N> |
| 140 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t(&operands)[N]) { | 140 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t(&operands)[N]) { |
| 141 // Don't output dead code. | 141 // Don't output dead code. |
| 142 if (exit_seen_in_block_) { | 142 if (exit_seen_in_block_) return; |
| 143 source_position_table_builder_.RevertPosition(bytecodes()->size()); | |
| 144 return; | |
| 145 } | |
| 146 | 143 |
| 147 int operand_count = static_cast<int>(N); | 144 int operand_count = static_cast<int>(N); |
| 148 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count); | 145 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count); |
| 149 | 146 |
| 150 int register_operand_count = Bytecodes::NumberOfRegisterOperands(bytecode); | 147 int register_operand_count = Bytecodes::NumberOfRegisterOperands(bytecode); |
| 151 if (register_operand_count > 0) { | 148 if (register_operand_count > 0) { |
| 152 register_translator()->TranslateInputRegisters(bytecode, operands, | 149 register_translator()->TranslateInputRegisters(bytecode, operands, |
| 153 operand_count); | 150 operand_count); |
| 154 } | 151 } |
| 155 | 152 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 203 | 200 |
| 204 | 201 |
| 205 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0) { | 202 void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0) { |
| 206 uint32_t operands[] = {operand0}; | 203 uint32_t operands[] = {operand0}; |
| 207 Output(bytecode, operands); | 204 Output(bytecode, operands); |
| 208 } | 205 } |
| 209 | 206 |
| 210 | 207 |
| 211 void BytecodeArrayBuilder::Output(Bytecode bytecode) { | 208 void BytecodeArrayBuilder::Output(Bytecode bytecode) { |
| 212 // Don't output dead code. | 209 // Don't output dead code. |
| 213 if (exit_seen_in_block_) { | 210 if (exit_seen_in_block_) return; |
| 214 source_position_table_builder_.RevertPosition(bytecodes()->size()); | |
| 215 return; | |
| 216 } | |
| 217 | 211 |
| 218 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 0); | 212 DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 0); |
| 219 last_bytecode_start_ = bytecodes()->size(); | 213 last_bytecode_start_ = bytecodes()->size(); |
| 220 bytecodes()->push_back(Bytecodes::ToByte(bytecode)); | 214 bytecodes()->push_back(Bytecodes::ToByte(bytecode)); |
| 221 } | 215 } |
| 222 | 216 |
| 223 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op, | 217 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op, |
| 224 Register reg) { | 218 Register reg) { |
| 225 Output(BytecodeForBinaryOperation(op), reg.ToRawOperand()); | 219 Output(BytecodeForBinaryOperation(op), reg.ToRawOperand()); |
| 226 return *this; | 220 return *this; |
| (...skipping 626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 853 case OperandSize::kNone: | 847 case OperandSize::kNone: |
| 854 UNREACHABLE(); | 848 UNREACHABLE(); |
| 855 } | 849 } |
| 856 unbound_jumps_--; | 850 unbound_jumps_--; |
| 857 } | 851 } |
| 858 | 852 |
| 859 | 853 |
| 860 BytecodeArrayBuilder& BytecodeArrayBuilder::OutputJump(Bytecode jump_bytecode, | 854 BytecodeArrayBuilder& BytecodeArrayBuilder::OutputJump(Bytecode jump_bytecode, |
| 861 BytecodeLabel* label) { | 855 BytecodeLabel* label) { |
| 862 // Don't emit dead code. | 856 // Don't emit dead code. |
| 863 if (exit_seen_in_block_) { | 857 if (exit_seen_in_block_) return *this; |
| 864 source_position_table_builder_.RevertPosition(bytecodes()->size()); | |
| 865 return *this; | |
| 866 } | |
| 867 | 858 |
| 868 // Check if the value in accumulator is boolean, if not choose an | 859 // Check if the value in accumulator is boolean, if not choose an |
| 869 // appropriate JumpIfToBoolean bytecode. | 860 // appropriate JumpIfToBoolean bytecode. |
| 870 if (NeedToBooleanCast()) { | 861 if (NeedToBooleanCast()) { |
| 871 jump_bytecode = GetJumpWithToBoolean(jump_bytecode); | 862 jump_bytecode = GetJumpWithToBoolean(jump_bytecode); |
| 872 } | 863 } |
| 873 | 864 |
| 874 if (label->is_bound()) { | 865 if (label->is_bound()) { |
| 875 // Label has been bound already so this is a backwards jump. | 866 // Label has been bound already so this is a backwards jump. |
| 876 CHECK_GE(bytecodes()->size(), label->offset()); | 867 CHECK_GE(bytecodes()->size(), label->offset()); |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1050 last_block_end_ = bytecodes()->size(); | 1041 last_block_end_ = bytecodes()->size(); |
| 1051 exit_seen_in_block_ = false; | 1042 exit_seen_in_block_ = false; |
| 1052 } | 1043 } |
| 1053 | 1044 |
| 1054 void BytecodeArrayBuilder::EnsureReturn(FunctionLiteral* literal) { | 1045 void BytecodeArrayBuilder::EnsureReturn(FunctionLiteral* literal) { |
| 1055 if (!exit_seen_in_block_) { | 1046 if (!exit_seen_in_block_) { |
| 1056 LoadUndefined(); | 1047 LoadUndefined(); |
| 1057 SetReturnPosition(literal); | 1048 SetReturnPosition(literal); |
| 1058 Return(); | 1049 Return(); |
| 1059 } | 1050 } |
| 1051 DCHECK(exit_seen_in_block_); |
| 1060 } | 1052 } |
| 1061 | 1053 |
| 1062 BytecodeArrayBuilder& BytecodeArrayBuilder::CallIC( | 1054 BytecodeArrayBuilder& BytecodeArrayBuilder::CallIC( |
| 1063 Register callable, Register receiver_args, size_t receiver_args_count, | 1055 Register callable, Register receiver_args, size_t receiver_args_count, |
| 1064 int feedback_slot, TailCallMode tail_call_mode) { | 1056 int feedback_slot, TailCallMode tail_call_mode) { |
| 1065 Bytecode bytecode = BytecodeForCallIC(tail_call_mode); | 1057 Bytecode bytecode = BytecodeForCallIC(tail_call_mode); |
| 1066 if (FitsInReg8Operand(callable) && FitsInReg8Operand(receiver_args) && | 1058 if (FitsInReg8Operand(callable) && FitsInReg8Operand(receiver_args) && |
| 1067 FitsInIdx8Operand(receiver_args_count) && | 1059 FitsInIdx8Operand(receiver_args_count) && |
| 1068 FitsInIdx8Operand(feedback_slot)) { | 1060 FitsInIdx8Operand(feedback_slot)) { |
| 1069 Output(bytecode, callable.ToRawOperand(), receiver_args.ToRawOperand(), | 1061 Output(bytecode, callable.ToRawOperand(), receiver_args.ToRawOperand(), |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1196 Output(BytecodeForDelete(language_mode), object.ToRawOperand()); | 1188 Output(BytecodeForDelete(language_mode), object.ToRawOperand()); |
| 1197 return *this; | 1189 return *this; |
| 1198 } | 1190 } |
| 1199 | 1191 |
| 1200 | 1192 |
| 1201 size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) { | 1193 size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) { |
| 1202 return constant_array_builder()->Insert(object); | 1194 return constant_array_builder()->Insert(object); |
| 1203 } | 1195 } |
| 1204 | 1196 |
| 1205 void BytecodeArrayBuilder::SetReturnPosition(FunctionLiteral* fun) { | 1197 void BytecodeArrayBuilder::SetReturnPosition(FunctionLiteral* fun) { |
| 1198 // Don't emit dead code. |
| 1199 if (exit_seen_in_block_) return; |
| 1200 |
| 1206 int pos = std::max(fun->start_position(), fun->end_position() - 1); | 1201 int pos = std::max(fun->start_position(), fun->end_position() - 1); |
| 1207 source_position_table_builder_.AddStatementPosition(bytecodes_.size(), pos); | 1202 source_position_table_builder_.AddStatementPosition(bytecodes_.size(), pos); |
| 1208 } | 1203 } |
| 1209 | 1204 |
| 1210 void BytecodeArrayBuilder::SetStatementPosition(Statement* stmt) { | 1205 void BytecodeArrayBuilder::SetStatementPosition(Statement* stmt) { |
| 1211 if (stmt->position() == RelocInfo::kNoPosition) return; | 1206 if (stmt->position() == RelocInfo::kNoPosition) return; |
| 1207 if (exit_seen_in_block_) return; |
| 1212 source_position_table_builder_.AddStatementPosition(bytecodes_.size(), | 1208 source_position_table_builder_.AddStatementPosition(bytecodes_.size(), |
| 1213 stmt->position()); | 1209 stmt->position()); |
| 1214 } | 1210 } |
| 1215 | 1211 |
| 1216 void BytecodeArrayBuilder::SetExpressionPosition(Expression* expr) { | 1212 void BytecodeArrayBuilder::SetExpressionPosition(Expression* expr) { |
| 1217 if (expr->position() == RelocInfo::kNoPosition) return; | 1213 if (expr->position() == RelocInfo::kNoPosition) return; |
| 1214 if (exit_seen_in_block_) return; |
| 1218 source_position_table_builder_.AddExpressionPosition(bytecodes_.size(), | 1215 source_position_table_builder_.AddExpressionPosition(bytecodes_.size(), |
| 1219 expr->position()); | 1216 expr->position()); |
| 1220 } | 1217 } |
| 1221 | 1218 |
| 1222 bool BytecodeArrayBuilder::TemporaryRegisterIsLive(Register reg) const { | 1219 bool BytecodeArrayBuilder::TemporaryRegisterIsLive(Register reg) const { |
| 1223 return temporary_register_allocator()->RegisterIsLive(reg); | 1220 return temporary_register_allocator()->RegisterIsLive(reg); |
| 1224 } | 1221 } |
| 1225 | 1222 |
| 1226 bool BytecodeArrayBuilder::OperandIsValid(Bytecode bytecode, int operand_index, | 1223 bool BytecodeArrayBuilder::OperandIsValid(Bytecode bytecode, int operand_index, |
| 1227 uint32_t operand_value) const { | 1224 uint32_t operand_value) const { |
| (...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1664 } | 1661 } |
| 1665 | 1662 |
| 1666 // static | 1663 // static |
| 1667 bool BytecodeArrayBuilder::FitsInReg16OperandUntranslated(Register value) { | 1664 bool BytecodeArrayBuilder::FitsInReg16OperandUntranslated(Register value) { |
| 1668 return value.is_short_operand(); | 1665 return value.is_short_operand(); |
| 1669 } | 1666 } |
| 1670 | 1667 |
| 1671 } // namespace interpreter | 1668 } // namespace interpreter |
| 1672 } // namespace internal | 1669 } // namespace internal |
| 1673 } // namespace v8 | 1670 } // namespace v8 |
| OLD | NEW |