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 | 217 |
224 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op, | 218 BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op, |
225 Register reg, | 219 Register reg, |
226 Strength strength) { | 220 Strength strength) { |
(...skipping 646 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
873 case OperandSize::kNone: | 867 case OperandSize::kNone: |
874 UNREACHABLE(); | 868 UNREACHABLE(); |
875 } | 869 } |
876 unbound_jumps_--; | 870 unbound_jumps_--; |
877 } | 871 } |
878 | 872 |
879 | 873 |
880 BytecodeArrayBuilder& BytecodeArrayBuilder::OutputJump(Bytecode jump_bytecode, | 874 BytecodeArrayBuilder& BytecodeArrayBuilder::OutputJump(Bytecode jump_bytecode, |
881 BytecodeLabel* label) { | 875 BytecodeLabel* label) { |
882 // Don't emit dead code. | 876 // Don't emit dead code. |
883 if (exit_seen_in_block_) { | 877 if (exit_seen_in_block_) return *this; |
884 source_position_table_builder_.RevertPosition(bytecodes()->size()); | |
885 return *this; | |
886 } | |
887 | 878 |
888 // Check if the value in accumulator is boolean, if not choose an | 879 // Check if the value in accumulator is boolean, if not choose an |
889 // appropriate JumpIfToBoolean bytecode. | 880 // appropriate JumpIfToBoolean bytecode. |
890 if (NeedToBooleanCast()) { | 881 if (NeedToBooleanCast()) { |
891 jump_bytecode = GetJumpWithToBoolean(jump_bytecode); | 882 jump_bytecode = GetJumpWithToBoolean(jump_bytecode); |
892 } | 883 } |
893 | 884 |
894 if (label->is_bound()) { | 885 if (label->is_bound()) { |
895 // Label has been bound already so this is a backwards jump. | 886 // Label has been bound already so this is a backwards jump. |
896 CHECK_GE(bytecodes()->size(), label->offset()); | 887 CHECK_GE(bytecodes()->size(), label->offset()); |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1074 last_block_end_ = bytecodes()->size(); | 1065 last_block_end_ = bytecodes()->size(); |
1075 exit_seen_in_block_ = false; | 1066 exit_seen_in_block_ = false; |
1076 } | 1067 } |
1077 | 1068 |
1078 void BytecodeArrayBuilder::EnsureReturn(FunctionLiteral* literal) { | 1069 void BytecodeArrayBuilder::EnsureReturn(FunctionLiteral* literal) { |
1079 if (!exit_seen_in_block_) { | 1070 if (!exit_seen_in_block_) { |
1080 LoadUndefined(); | 1071 LoadUndefined(); |
1081 SetReturnPosition(literal); | 1072 SetReturnPosition(literal); |
1082 Return(); | 1073 Return(); |
1083 } | 1074 } |
| 1075 DCHECK(exit_seen_in_block_); |
1084 } | 1076 } |
1085 | 1077 |
1086 BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable, | 1078 BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable, |
1087 Register receiver_args, | 1079 Register receiver_args, |
1088 size_t receiver_args_count, | 1080 size_t receiver_args_count, |
1089 int feedback_slot) { | 1081 int feedback_slot) { |
1090 if (FitsInReg8Operand(callable) && FitsInReg8Operand(receiver_args) && | 1082 if (FitsInReg8Operand(callable) && FitsInReg8Operand(receiver_args) && |
1091 FitsInIdx8Operand(receiver_args_count) && | 1083 FitsInIdx8Operand(receiver_args_count) && |
1092 FitsInIdx8Operand(feedback_slot)) { | 1084 FitsInIdx8Operand(feedback_slot)) { |
1093 Output(Bytecode::kCall, callable.ToRawOperand(), | 1085 Output(Bytecode::kCall, callable.ToRawOperand(), |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1202 Output(BytecodeForDelete(language_mode), object.ToRawOperand()); | 1194 Output(BytecodeForDelete(language_mode), object.ToRawOperand()); |
1203 return *this; | 1195 return *this; |
1204 } | 1196 } |
1205 | 1197 |
1206 | 1198 |
1207 size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) { | 1199 size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) { |
1208 return constant_array_builder()->Insert(object); | 1200 return constant_array_builder()->Insert(object); |
1209 } | 1201 } |
1210 | 1202 |
1211 void BytecodeArrayBuilder::SetReturnPosition(FunctionLiteral* fun) { | 1203 void BytecodeArrayBuilder::SetReturnPosition(FunctionLiteral* fun) { |
| 1204 // Don't emit dead code. |
| 1205 if (exit_seen_in_block_) return; |
| 1206 |
1212 int pos = std::max(fun->start_position(), fun->end_position() - 1); | 1207 int pos = std::max(fun->start_position(), fun->end_position() - 1); |
1213 source_position_table_builder_.AddStatementPosition(bytecodes_.size(), pos); | 1208 source_position_table_builder_.AddStatementPosition(bytecodes_.size(), pos); |
1214 } | 1209 } |
1215 | 1210 |
1216 void BytecodeArrayBuilder::SetStatementPosition(Statement* stmt) { | 1211 void BytecodeArrayBuilder::SetStatementPosition(Statement* stmt) { |
1217 if (stmt->position() == RelocInfo::kNoPosition) return; | 1212 if (stmt->position() == RelocInfo::kNoPosition) return; |
| 1213 if (exit_seen_in_block_) return; |
1218 source_position_table_builder_.AddStatementPosition(bytecodes_.size(), | 1214 source_position_table_builder_.AddStatementPosition(bytecodes_.size(), |
1219 stmt->position()); | 1215 stmt->position()); |
1220 } | 1216 } |
1221 | 1217 |
1222 void BytecodeArrayBuilder::SetExpressionPosition(Expression* expr) { | 1218 void BytecodeArrayBuilder::SetExpressionPosition(Expression* expr) { |
1223 if (expr->position() == RelocInfo::kNoPosition) return; | 1219 if (expr->position() == RelocInfo::kNoPosition) return; |
| 1220 if (exit_seen_in_block_) return; |
1224 source_position_table_builder_.AddExpressionPosition(bytecodes_.size(), | 1221 source_position_table_builder_.AddExpressionPosition(bytecodes_.size(), |
1225 expr->position()); | 1222 expr->position()); |
1226 } | 1223 } |
1227 | 1224 |
1228 bool BytecodeArrayBuilder::TemporaryRegisterIsLive(Register reg) const { | 1225 bool BytecodeArrayBuilder::TemporaryRegisterIsLive(Register reg) const { |
1229 return temporary_register_allocator()->RegisterIsLive(reg); | 1226 return temporary_register_allocator()->RegisterIsLive(reg); |
1230 } | 1227 } |
1231 | 1228 |
1232 bool BytecodeArrayBuilder::OperandIsValid(Bytecode bytecode, int operand_index, | 1229 bool BytecodeArrayBuilder::OperandIsValid(Bytecode bytecode, int operand_index, |
1233 uint32_t operand_value) const { | 1230 uint32_t operand_value) const { |
(...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1692 } | 1689 } |
1693 | 1690 |
1694 // static | 1691 // static |
1695 bool BytecodeArrayBuilder::FitsInReg16OperandUntranslated(Register value) { | 1692 bool BytecodeArrayBuilder::FitsInReg16OperandUntranslated(Register value) { |
1696 return value.is_short_operand(); | 1693 return value.is_short_operand(); |
1697 } | 1694 } |
1698 | 1695 |
1699 } // namespace interpreter | 1696 } // namespace interpreter |
1700 } // namespace internal | 1697 } // namespace internal |
1701 } // namespace v8 | 1698 } // namespace v8 |
OLD | NEW |