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