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/bytecodes.h" | 5 #include "src/interpreter/bytecodes.h" |
6 | 6 |
7 #include "src/frames.h" | 7 #include "src/frames.h" |
8 #include "src/interpreter/bytecode-traits.h" | 8 #include "src/interpreter/bytecode-traits.h" |
9 | 9 |
10 namespace v8 { | 10 namespace v8 { |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
225 IsJumpConstantWide(bytecode); | 225 IsJumpConstantWide(bytecode); |
226 } | 226 } |
227 | 227 |
228 | 228 |
229 // static | 229 // static |
230 bool Bytecodes::IsJumpOrReturn(Bytecode bytecode) { | 230 bool Bytecodes::IsJumpOrReturn(Bytecode bytecode) { |
231 return bytecode == Bytecode::kReturn || IsJump(bytecode); | 231 return bytecode == Bytecode::kReturn || IsJump(bytecode); |
232 } | 232 } |
233 | 233 |
234 | 234 |
| 235 namespace { |
| 236 static Register DecodeRegister(const uint8_t* operand_start, |
| 237 OperandType operand_type) { |
| 238 switch (Bytecodes::SizeOfOperand(operand_type)) { |
| 239 case OperandSize::kByte: |
| 240 return Register::FromOperand(*operand_start); |
| 241 case OperandSize::kShort: |
| 242 return Register::FromWideOperand(ReadUnalignedUInt16(operand_start)); |
| 243 case OperandSize::kNone: { |
| 244 UNREACHABLE(); |
| 245 } |
| 246 } |
| 247 return Register(); |
| 248 } |
| 249 } // namespace |
| 250 |
| 251 |
235 // static | 252 // static |
236 std::ostream& Bytecodes::Decode(std::ostream& os, const uint8_t* bytecode_start, | 253 std::ostream& Bytecodes::Decode(std::ostream& os, const uint8_t* bytecode_start, |
237 int parameter_count) { | 254 int parameter_count) { |
238 Vector<char> buf = Vector<char>::New(50); | 255 Vector<char> buf = Vector<char>::New(50); |
239 | 256 |
240 Bytecode bytecode = Bytecodes::FromByte(bytecode_start[0]); | 257 Bytecode bytecode = Bytecodes::FromByte(bytecode_start[0]); |
241 int bytecode_size = Bytecodes::Size(bytecode); | 258 int bytecode_size = Bytecodes::Size(bytecode); |
242 | 259 |
243 for (int i = 0; i < bytecode_size; i++) { | 260 for (int i = 0; i < bytecode_size; i++) { |
244 SNPrintF(buf, "%02x ", bytecode_start[i]); | 261 SNPrintF(buf, "%02x ", bytecode_start[i]); |
245 os << buf.start(); | 262 os << buf.start(); |
246 } | 263 } |
247 const int kBytecodeColumnSize = 6; | 264 const int kBytecodeColumnSize = 6; |
248 for (int i = bytecode_size; i < kBytecodeColumnSize; i++) { | 265 for (int i = bytecode_size; i < kBytecodeColumnSize; i++) { |
249 os << " "; | 266 os << " "; |
250 } | 267 } |
251 | 268 |
252 os << bytecode << " "; | 269 os << bytecode << " "; |
253 | 270 |
254 int number_of_operands = NumberOfOperands(bytecode); | 271 int number_of_operands = NumberOfOperands(bytecode); |
255 for (int i = 0; i < number_of_operands; i++) { | 272 for (int i = 0; i < number_of_operands; i++) { |
256 OperandType op_type = GetOperandType(bytecode, i); | 273 OperandType op_type = GetOperandType(bytecode, i); |
257 const uint8_t* operand_start = | 274 const uint8_t* operand_start = |
258 &bytecode_start[GetOperandOffset(bytecode, i)]; | 275 &bytecode_start[GetOperandOffset(bytecode, i)]; |
259 switch (op_type) { | 276 switch (op_type) { |
260 case interpreter::OperandType::kCount8: | 277 case interpreter::OperandType::kRegCount8: |
261 os << "#" << static_cast<unsigned int>(*operand_start); | 278 os << "#" << static_cast<unsigned int>(*operand_start); |
262 break; | 279 break; |
263 case interpreter::OperandType::kCount16: | 280 case interpreter::OperandType::kRegCount16: |
264 os << '#' << ReadUnalignedUInt16(operand_start); | 281 os << '#' << ReadUnalignedUInt16(operand_start); |
265 break; | 282 break; |
266 case interpreter::OperandType::kIdx8: | 283 case interpreter::OperandType::kIdx8: |
267 os << "[" << static_cast<unsigned int>(*operand_start) << "]"; | 284 os << "[" << static_cast<unsigned int>(*operand_start) << "]"; |
268 break; | 285 break; |
269 case interpreter::OperandType::kIdx16: | 286 case interpreter::OperandType::kIdx16: |
270 os << "[" << ReadUnalignedUInt16(operand_start) << "]"; | 287 os << "[" << ReadUnalignedUInt16(operand_start) << "]"; |
271 break; | 288 break; |
272 case interpreter::OperandType::kImm8: | 289 case interpreter::OperandType::kImm8: |
273 os << "#" << static_cast<int>(static_cast<int8_t>(*operand_start)); | 290 os << "#" << static_cast<int>(static_cast<int8_t>(*operand_start)); |
274 break; | 291 break; |
| 292 case interpreter::OperandType::kMaybeReg8: |
| 293 case interpreter::OperandType::kMaybeReg16: |
275 case interpreter::OperandType::kReg8: | 294 case interpreter::OperandType::kReg8: |
276 case interpreter::OperandType::kMaybeReg8: { | 295 case interpreter::OperandType::kReg16: { |
277 Register reg = Register::FromOperand(*operand_start); | 296 Register reg = DecodeRegister(operand_start, op_type); |
278 if (reg.is_function_context()) { | 297 if (reg.is_function_context()) { |
279 os << "<context>"; | 298 os << "<context>"; |
280 } else if (reg.is_function_closure()) { | 299 } else if (reg.is_function_closure()) { |
281 os << "<closure>"; | 300 os << "<closure>"; |
282 } else if (reg.is_new_target()) { | 301 } else if (reg.is_new_target()) { |
283 os << "<new.target>"; | 302 os << "<new.target>"; |
284 } else if (reg.is_parameter()) { | 303 } else if (reg.is_parameter()) { |
285 int parameter_index = reg.ToParameterIndex(parameter_count); | 304 int parameter_index = reg.ToParameterIndex(parameter_count); |
286 if (parameter_index == 0) { | 305 if (parameter_index == 0) { |
287 os << "<this>"; | 306 os << "<this>"; |
288 } else { | 307 } else { |
289 os << "a" << parameter_index - 1; | 308 os << "a" << parameter_index - 1; |
290 } | 309 } |
291 } else { | 310 } else { |
292 os << "r" << reg.index(); | 311 os << "r" << reg.index(); |
293 } | 312 } |
294 break; | 313 break; |
295 } | 314 } |
296 case interpreter::OperandType::kRegPair8: | 315 case interpreter::OperandType::kRegPair8: |
297 case interpreter::OperandType::kRegTriple8: { | 316 case interpreter::OperandType::kRegTriple8: |
298 Register reg = Register::FromOperand(*operand_start); | 317 case interpreter::OperandType::kRegPair16: |
| 318 case interpreter::OperandType::kRegTriple16: { |
| 319 Register reg = DecodeRegister(operand_start, op_type); |
299 int range = op_type == interpreter::OperandType::kRegPair8 ? 1 : 2; | 320 int range = op_type == interpreter::OperandType::kRegPair8 ? 1 : 2; |
300 if (reg.is_parameter()) { | 321 if (reg.is_parameter()) { |
301 int parameter_index = reg.ToParameterIndex(parameter_count); | 322 int parameter_index = reg.ToParameterIndex(parameter_count); |
302 DCHECK_NE(parameter_index, 0); | 323 DCHECK_GT(parameter_index, 0); |
303 os << "a" << parameter_index - range << "-" << parameter_index; | 324 os << "a" << parameter_index - range << "-" << parameter_index; |
304 } else { | 325 } else { |
305 os << "r" << reg.index() << "-" << reg.index() + range; | 326 os << "r" << reg.index() << "-" << reg.index() + range; |
306 } | 327 } |
307 break; | 328 break; |
308 } | 329 } |
309 case interpreter::OperandType::kReg16: { | |
310 Register reg = | |
311 Register::FromWideOperand(ReadUnalignedUInt16(operand_start)); | |
312 if (reg.is_parameter()) { | |
313 int parameter_index = reg.ToParameterIndex(parameter_count); | |
314 DCHECK_NE(parameter_index, 0); | |
315 os << "a" << parameter_index - 1; | |
316 } else { | |
317 os << "r" << reg.index(); | |
318 } | |
319 break; | |
320 } | |
321 case interpreter::OperandType::kNone: | 330 case interpreter::OperandType::kNone: |
322 UNREACHABLE(); | 331 UNREACHABLE(); |
323 break; | 332 break; |
324 } | 333 } |
325 if (i != number_of_operands - 1) { | 334 if (i != number_of_operands - 1) { |
326 os << ", "; | 335 os << ", "; |
327 } | 336 } |
328 } | 337 } |
329 return os; | 338 return os; |
330 } | 339 } |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
426 DCHECK_LE(index_, kMaxInt16); | 435 DCHECK_LE(index_, kMaxInt16); |
427 return static_cast<uint16_t>(-index_); | 436 return static_cast<uint16_t>(-index_); |
428 } | 437 } |
429 | 438 |
430 | 439 |
431 Register Register::FromWideOperand(uint16_t operand) { | 440 Register Register::FromWideOperand(uint16_t operand) { |
432 return Register(-static_cast<int16_t>(operand)); | 441 return Register(-static_cast<int16_t>(operand)); |
433 } | 442 } |
434 | 443 |
435 | 444 |
| 445 uint32_t Register::ToRawOperand() const { |
| 446 return static_cast<uint32_t>(-index_); |
| 447 } |
| 448 |
| 449 |
| 450 Register Register::FromRawOperand(uint32_t operand) { |
| 451 return Register(-static_cast<int32_t>(operand)); |
| 452 } |
| 453 |
| 454 |
436 bool Register::AreContiguous(Register reg1, Register reg2, Register reg3, | 455 bool Register::AreContiguous(Register reg1, Register reg2, Register reg3, |
437 Register reg4, Register reg5) { | 456 Register reg4, Register reg5) { |
438 if (reg1.index() + 1 != reg2.index()) { | 457 if (reg1.index() + 1 != reg2.index()) { |
439 return false; | 458 return false; |
440 } | 459 } |
441 if (reg3.is_valid() && reg2.index() + 1 != reg3.index()) { | 460 if (reg3.is_valid() && reg2.index() + 1 != reg3.index()) { |
442 return false; | 461 return false; |
443 } | 462 } |
444 if (reg4.is_valid() && reg3.index() + 1 != reg4.index()) { | 463 if (reg4.is_valid() && reg3.index() + 1 != reg4.index()) { |
445 return false; | 464 return false; |
446 } | 465 } |
447 if (reg5.is_valid() && reg4.index() + 1 != reg5.index()) { | 466 if (reg5.is_valid() && reg4.index() + 1 != reg5.index()) { |
448 return false; | 467 return false; |
449 } | 468 } |
450 return true; | 469 return true; |
451 } | 470 } |
452 | 471 |
453 } // namespace interpreter | 472 } // namespace interpreter |
454 } // namespace internal | 473 } // namespace internal |
455 } // namespace v8 | 474 } // namespace v8 |
OLD | NEW |