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 } |
205 } | |
203 | 206 |
204 if ((register_operand_bitmap >> i) & 1) { | 207 DCHECK_LE(buffer_limit, buffer + sizeof(buffer)); |
205 int count; | 208 bytecodes()->insert(bytecodes()->end(), buffer, buffer_limit); |
206 if (operand_types[i + 1] == OperandType::kRegCount) { | 209 |
207 count = static_cast<int>(operands[i + 1]); | 210 for (int i = 0; i < operand_count; ++i) { |
rmcilroy
2016/06/27 14:03:48
Could we keep doing this as part of the loop above
oth
2016/06/27 18:53:50
Done.
It makes no difference either way perf wise
| |
208 } else { | 211 int count = Bytecodes::GetNumberOfRegistersRepresentedBy(operand_types[i]); |
209 count = Bytecodes::GetNumberOfRegistersRepresentedBy(operand_type); | 212 if (count == 0) { |
210 } | 213 continue; |
211 Register reg = Register::FromOperand(static_cast<int32_t>(operands[i])); | |
212 max_register_count_ = std::max(max_register_count_, reg.index() + count); | |
213 } | 214 } |
215 uint32_t reg_operand = operands[i]; | |
216 if (operand_types[i + 1] == OperandType::kRegCount) { | |
rmcilroy
2016/06/27 14:03:48
I've been caught out again thinking this goes out-
oth
2016/06/27 18:53:50
Done. It's no more or less confusing than having a
| |
217 count = static_cast<int>(operands[++i]); | |
218 } | |
219 Register reg = Register::FromOperand(static_cast<int32_t>(reg_operand)); | |
220 max_register_count_ = std::max(max_register_count_, reg.index() + count); | |
rmcilroy
2016/06/27 14:03:48
Any idea how much performance this part of the loo
oth
2016/06/27 18:53:50
Three runs on my workstation suggest it is in the
| |
214 } | 221 } |
215 } | 222 } |
216 | 223 |
217 // static | 224 // static |
218 Bytecode GetJumpWithConstantOperand(Bytecode jump_bytecode) { | 225 Bytecode GetJumpWithConstantOperand(Bytecode jump_bytecode) { |
219 switch (jump_bytecode) { | 226 switch (jump_bytecode) { |
220 case Bytecode::kJump: | 227 case Bytecode::kJump: |
221 return Bytecode::kJumpConstant; | 228 return Bytecode::kJumpConstant; |
222 case Bytecode::kJumpIfTrue: | 229 case Bytecode::kJumpIfTrue: |
223 return Bytecode::kJumpIfTrueConstant; | 230 return Bytecode::kJumpIfTrueConstant; |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
381 node->set_bytecode(node->bytecode(), k32BitJumpPlaceholder); | 388 node->set_bytecode(node->bytecode(), k32BitJumpPlaceholder); |
382 break; | 389 break; |
383 } | 390 } |
384 } | 391 } |
385 EmitBytecode(node); | 392 EmitBytecode(node); |
386 } | 393 } |
387 | 394 |
388 } // namespace interpreter | 395 } // namespace interpreter |
389 } // namespace internal | 396 } // namespace internal |
390 } // namespace v8 | 397 } // namespace v8 |
OLD | NEW |