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-writer.h" | 5 #include "src/interpreter/bytecode-array-writer.h" |
6 | 6 |
7 #include "src/api.h" | 7 #include "src/api.h" |
8 #include "src/interpreter/bytecode-label.h" | 8 #include "src/interpreter/bytecode-label.h" |
9 #include "src/interpreter/constant-array-builder.h" | 9 #include "src/interpreter/constant-array-builder.h" |
10 #include "src/log.h" | 10 #include "src/log.h" |
11 | 11 |
12 namespace v8 { | 12 namespace v8 { |
13 namespace internal { | 13 namespace internal { |
14 namespace interpreter { | 14 namespace interpreter { |
15 | 15 |
| 16 STATIC_CONST_MEMBER_DEFINITION const size_t |
| 17 BytecodeArrayWriter::kMaxSizeOfPackedBytecode; |
| 18 |
16 BytecodeArrayWriter::BytecodeArrayWriter( | 19 BytecodeArrayWriter::BytecodeArrayWriter( |
17 Isolate* isolate, Zone* zone, ConstantArrayBuilder* constant_array_builder) | 20 Isolate* isolate, Zone* zone, ConstantArrayBuilder* constant_array_builder) |
18 : isolate_(isolate), | 21 : isolate_(isolate), |
19 bytecodes_(zone), | 22 bytecodes_(zone), |
20 max_register_count_(0), | 23 max_register_count_(0), |
21 unbound_jumps_(0), | 24 unbound_jumps_(0), |
22 source_position_table_builder_(isolate, zone), | 25 source_position_table_builder_(isolate, zone), |
23 constant_array_builder_(constant_array_builder) { | 26 constant_array_builder_(constant_array_builder) { |
24 LOG_CODE_EVENT(isolate_, CodeStartLinePosInfoRecordEvent( | 27 LOG_CODE_EVENT(isolate_, CodeStartLinePosInfoRecordEvent( |
25 source_position_table_builder())); | 28 source_position_table_builder())); |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
125 | 128 |
126 OperandScale OperandScaleForScalableUnsignedByte(uint32_t operand_value) { | 129 OperandScale OperandScaleForScalableUnsignedByte(uint32_t operand_value) { |
127 OperandSize bytes_required = Bytecodes::SizeForUnsignedOperand(operand_value); | 130 OperandSize bytes_required = Bytecodes::SizeForUnsignedOperand(operand_value); |
128 return ScaleForScalableByteOperand(bytes_required); | 131 return ScaleForScalableByteOperand(bytes_required); |
129 } | 132 } |
130 | 133 |
131 OperandScale GetOperandScale(const BytecodeNode* const node) { | 134 OperandScale GetOperandScale(const BytecodeNode* const node) { |
132 const OperandTypeInfo* operand_type_infos = | 135 const OperandTypeInfo* operand_type_infos = |
133 Bytecodes::GetOperandTypeInfos(node->bytecode()); | 136 Bytecodes::GetOperandTypeInfos(node->bytecode()); |
134 OperandScale operand_scale = OperandScale::kSingle; | 137 OperandScale operand_scale = OperandScale::kSingle; |
135 for (int i = 0; i < node->operand_count(); ++i) { | 138 int operand_count = node->operand_count(); |
| 139 for (int i = 0; i < operand_count; ++i) { |
136 switch (operand_type_infos[i]) { | 140 switch (operand_type_infos[i]) { |
137 case OperandTypeInfo::kScalableSignedByte: { | 141 case OperandTypeInfo::kScalableSignedByte: { |
138 uint32_t operand = node->operand(i); | 142 uint32_t operand = node->operand(i); |
139 operand_scale = | 143 operand_scale = |
140 std::max(operand_scale, OperandScaleForScalableSignedByte(operand)); | 144 std::max(operand_scale, OperandScaleForScalableSignedByte(operand)); |
141 break; | 145 break; |
142 } | 146 } |
143 case OperandTypeInfo::kScalableUnsignedByte: { | 147 case OperandTypeInfo::kScalableUnsignedByte: { |
144 uint32_t operand = node->operand(i); | 148 uint32_t operand = node->operand(i); |
145 operand_scale = std::max(operand_scale, | 149 operand_scale = std::max(operand_scale, |
146 OperandScaleForScalableUnsignedByte(operand)); | 150 OperandScaleForScalableUnsignedByte(operand)); |
147 break; | 151 break; |
148 } | 152 } |
149 case OperandTypeInfo::kFixedUnsignedByte: | 153 case OperandTypeInfo::kFixedUnsignedByte: |
150 case OperandTypeInfo::kFixedUnsignedShort: | 154 case OperandTypeInfo::kFixedUnsignedShort: |
151 break; | 155 break; |
152 case OperandTypeInfo::kNone: | 156 case OperandTypeInfo::kNone: |
153 UNREACHABLE(); | 157 UNREACHABLE(); |
154 break; | 158 break; |
155 } | 159 } |
156 } | 160 } |
157 return operand_scale; | 161 return operand_scale; |
158 } | 162 } |
159 | 163 |
160 } // namespace | 164 } // namespace |
161 | 165 |
162 void BytecodeArrayWriter::EmitBytecode(const BytecodeNode* const node) { | 166 void BytecodeArrayWriter::EmitBytecode(const BytecodeNode* const node) { |
163 DCHECK_NE(node->bytecode(), Bytecode::kIllegal); | 167 DCHECK_NE(node->bytecode(), Bytecode::kIllegal); |
164 | 168 |
| 169 uint8_t buffer[kMaxSizeOfPackedBytecode]; |
| 170 uint8_t* buffer_limit = buffer; |
| 171 |
165 OperandScale operand_scale = GetOperandScale(node); | 172 OperandScale operand_scale = GetOperandScale(node); |
166 if (operand_scale != OperandScale::kSingle) { | 173 if (operand_scale != OperandScale::kSingle) { |
167 Bytecode prefix = Bytecodes::OperandScaleToPrefixBytecode(operand_scale); | 174 Bytecode prefix = Bytecodes::OperandScaleToPrefixBytecode(operand_scale); |
168 bytecodes()->push_back(Bytecodes::ToByte(prefix)); | 175 *buffer_limit++ = Bytecodes::ToByte(prefix); |
169 } | 176 } |
170 | 177 |
171 Bytecode bytecode = node->bytecode(); | 178 Bytecode bytecode = node->bytecode(); |
172 bytecodes()->push_back(Bytecodes::ToByte(bytecode)); | 179 *buffer_limit++ = Bytecodes::ToByte(bytecode); |
173 | 180 |
174 int register_operand_bitmap = Bytecodes::GetRegisterOperandBitmap(bytecode); | |
175 const uint32_t* const operands = node->operands(); | 181 const uint32_t* const operands = node->operands(); |
176 const OperandSize* operand_sizes = | |
177 Bytecodes::GetOperandSizes(bytecode, operand_scale); | |
178 const OperandType* operand_types = Bytecodes::GetOperandTypes(bytecode); | 182 const OperandType* operand_types = Bytecodes::GetOperandTypes(bytecode); |
179 for (int i = 0; operand_types[i] != OperandType::kNone; ++i) { | 183 const int operand_count = Bytecodes::NumberOfOperands(bytecode); |
180 OperandType operand_type = operand_types[i]; | 184 for (int i = 0; i < operand_count; ++i) { |
181 switch (operand_sizes[i]) { | 185 OperandSize operand_size = |
| 186 Bytecodes::SizeOfOperand(operand_types[i], operand_scale); |
| 187 switch (operand_size) { |
182 case OperandSize::kNone: | 188 case OperandSize::kNone: |
183 UNREACHABLE(); | 189 UNREACHABLE(); |
184 break; | 190 break; |
185 case OperandSize::kByte: | 191 case OperandSize::kByte: |
186 bytecodes()->push_back(static_cast<uint8_t>(operands[i])); | 192 *buffer_limit++ = static_cast<uint8_t>(operands[i]); |
187 break; | 193 break; |
188 case OperandSize::kShort: { | 194 case OperandSize::kShort: { |
189 uint8_t operand_bytes[2]; | 195 WriteUnalignedUInt16(buffer_limit, operands[i]); |
190 WriteUnalignedUInt16(operand_bytes, operands[i]); | 196 buffer_limit += 2; |
191 bytecodes()->insert(bytecodes()->end(), operand_bytes, | |
192 operand_bytes + 2); | |
193 break; | 197 break; |
194 } | 198 } |
195 case OperandSize::kQuad: { | 199 case OperandSize::kQuad: { |
196 uint8_t operand_bytes[4]; | 200 WriteUnalignedUInt32(buffer_limit, operands[i]); |
197 WriteUnalignedUInt32(operand_bytes, operands[i]); | 201 buffer_limit += 4; |
198 bytecodes()->insert(bytecodes()->end(), operand_bytes, | |
199 operand_bytes + 4); | |
200 break; | 202 break; |
201 } | 203 } |
202 } | 204 } |
203 | 205 |
204 if ((register_operand_bitmap >> i) & 1) { | 206 int count = Bytecodes::GetNumberOfRegistersRepresentedBy(operand_types[i]); |
205 int count; | 207 if (count == 0) { |
206 if (operand_types[i + 1] == OperandType::kRegCount) { | 208 continue; |
207 count = static_cast<int>(operands[i + 1]); | |
208 } else { | |
209 count = Bytecodes::GetNumberOfRegistersRepresentedBy(operand_type); | |
210 } | |
211 Register reg = Register::FromOperand(static_cast<int32_t>(operands[i])); | |
212 max_register_count_ = std::max(max_register_count_, reg.index() + count); | |
213 } | 209 } |
| 210 // NB operand_types is terminated by OperandType::kNone so |
| 211 // operand_types[i + 1] is valid whilst i < operand_count. |
| 212 if (operand_types[i + 1] == OperandType::kRegCount) { |
| 213 count = static_cast<int>(operands[i]); |
| 214 } |
| 215 Register reg = Register::FromOperand(static_cast<int32_t>(operands[i])); |
| 216 max_register_count_ = std::max(max_register_count_, reg.index() + count); |
214 } | 217 } |
| 218 |
| 219 DCHECK_LE(buffer_limit, buffer + sizeof(buffer)); |
| 220 bytecodes()->insert(bytecodes()->end(), buffer, buffer_limit); |
215 } | 221 } |
216 | 222 |
217 // static | 223 // static |
218 Bytecode GetJumpWithConstantOperand(Bytecode jump_bytecode) { | 224 Bytecode GetJumpWithConstantOperand(Bytecode jump_bytecode) { |
219 switch (jump_bytecode) { | 225 switch (jump_bytecode) { |
220 case Bytecode::kJump: | 226 case Bytecode::kJump: |
221 return Bytecode::kJumpConstant; | 227 return Bytecode::kJumpConstant; |
222 case Bytecode::kJumpIfTrue: | 228 case Bytecode::kJumpIfTrue: |
223 return Bytecode::kJumpIfTrueConstant; | 229 return Bytecode::kJumpIfTrueConstant; |
224 case Bytecode::kJumpIfFalse: | 230 case Bytecode::kJumpIfFalse: |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
381 node->set_bytecode(node->bytecode(), k32BitJumpPlaceholder); | 387 node->set_bytecode(node->bytecode(), k32BitJumpPlaceholder); |
382 break; | 388 break; |
383 } | 389 } |
384 } | 390 } |
385 EmitBytecode(node); | 391 EmitBytecode(node); |
386 } | 392 } |
387 | 393 |
388 } // namespace interpreter | 394 } // namespace interpreter |
389 } // namespace internal | 395 } // namespace internal |
390 } // namespace v8 | 396 } // namespace v8 |
OLD | NEW |