Chromium Code Reviews| 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 #ifndef V8_INTERPRETER_BYTECODES_H_ | 5 #ifndef V8_INTERPRETER_BYTECODES_H_ |
| 6 #define V8_INTERPRETER_BYTECODES_H_ | 6 #define V8_INTERPRETER_BYTECODES_H_ |
| 7 | 7 |
| 8 #include <cstdint> | 8 #include <cstdint> |
| 9 #include <iosfwd> | 9 #include <iosfwd> |
| 10 #include <string> | 10 #include <string> |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 206 OperandType::kIdx, OperandType::kIdx) \ | 206 OperandType::kIdx, OperandType::kIdx) \ |
| 207 V(CreateFunctionContext, AccumulatorUse::kWrite, OperandType::kUImm) \ | 207 V(CreateFunctionContext, AccumulatorUse::kWrite, OperandType::kUImm) \ |
| 208 V(CreateWithContext, AccumulatorUse::kReadWrite, OperandType::kReg, \ | 208 V(CreateWithContext, AccumulatorUse::kReadWrite, OperandType::kReg, \ |
| 209 OperandType::kIdx) \ | 209 OperandType::kIdx) \ |
| 210 \ | 210 \ |
| 211 /* Arguments allocation */ \ | 211 /* Arguments allocation */ \ |
| 212 V(CreateMappedArguments, AccumulatorUse::kWrite) \ | 212 V(CreateMappedArguments, AccumulatorUse::kWrite) \ |
| 213 V(CreateUnmappedArguments, AccumulatorUse::kWrite) \ | 213 V(CreateUnmappedArguments, AccumulatorUse::kWrite) \ |
| 214 V(CreateRestParameter, AccumulatorUse::kWrite) \ | 214 V(CreateRestParameter, AccumulatorUse::kWrite) \ |
| 215 \ | 215 \ |
| 216 /* Control Flow */ \ | 216 /* Control Flow -- carefully ordered for efficient checks */ \ |
| 217 /* - [Unconditional jumps] */ \ | |
| 218 V(JumpLoop, AccumulatorUse::kNone, OperandType::kImm, OperandType::kImm) \ | |
| 219 /* - [Forward jumps] */ \ | |
| 217 V(Jump, AccumulatorUse::kNone, OperandType::kImm) \ | 220 V(Jump, AccumulatorUse::kNone, OperandType::kImm) \ |
| 221 /* - [Start constant jumps] */ \ | |
| 218 V(JumpConstant, AccumulatorUse::kNone, OperandType::kIdx) \ | 222 V(JumpConstant, AccumulatorUse::kNone, OperandType::kIdx) \ |
| 223 /* - [Conditional jumps] */ \ | |
| 224 /* - [Conditional constant jumps] */ \ | |
| 225 V(JumpIfNullConstant, AccumulatorUse::kRead, OperandType::kIdx) \ | |
| 226 V(JumpIfUndefinedConstant, AccumulatorUse::kRead, OperandType::kIdx) \ | |
| 227 V(JumpIfTrueConstant, AccumulatorUse::kRead, OperandType::kIdx) \ | |
| 228 V(JumpIfFalseConstant, AccumulatorUse::kRead, OperandType::kIdx) \ | |
| 229 V(JumpIfNotHoleConstant, AccumulatorUse::kRead, OperandType::kIdx) \ | |
| 230 /* - [Start ToBoolean jumps] */ \ | |
| 231 V(JumpIfToBooleanTrueConstant, AccumulatorUse::kRead, OperandType::kIdx) \ | |
| 232 V(JumpIfToBooleanFalseConstant, AccumulatorUse::kRead, OperandType::kIdx) \ | |
| 233 /* - [End constant jumps] */ \ | |
| 234 /* - [Conditional immediate jumps] */ \ | |
| 235 V(JumpIfToBooleanTrue, AccumulatorUse::kRead, OperandType::kImm) \ | |
| 236 V(JumpIfToBooleanFalse, AccumulatorUse::kRead, OperandType::kImm) \ | |
| 237 /* - [End ToBoolean jumps] */ \ | |
| 219 V(JumpIfTrue, AccumulatorUse::kRead, OperandType::kImm) \ | 238 V(JumpIfTrue, AccumulatorUse::kRead, OperandType::kImm) \ |
| 220 V(JumpIfTrueConstant, AccumulatorUse::kRead, OperandType::kIdx) \ | |
| 221 V(JumpIfFalse, AccumulatorUse::kRead, OperandType::kImm) \ | 239 V(JumpIfFalse, AccumulatorUse::kRead, OperandType::kImm) \ |
| 222 V(JumpIfFalseConstant, AccumulatorUse::kRead, OperandType::kIdx) \ | |
| 223 V(JumpIfToBooleanTrue, AccumulatorUse::kRead, OperandType::kImm) \ | |
| 224 V(JumpIfToBooleanTrueConstant, AccumulatorUse::kRead, OperandType::kIdx) \ | |
| 225 V(JumpIfToBooleanFalse, AccumulatorUse::kRead, OperandType::kImm) \ | |
| 226 V(JumpIfToBooleanFalseConstant, AccumulatorUse::kRead, OperandType::kIdx) \ | |
| 227 V(JumpIfNull, AccumulatorUse::kRead, OperandType::kImm) \ | 240 V(JumpIfNull, AccumulatorUse::kRead, OperandType::kImm) \ |
| 228 V(JumpIfNullConstant, AccumulatorUse::kRead, OperandType::kIdx) \ | |
| 229 V(JumpIfUndefined, AccumulatorUse::kRead, OperandType::kImm) \ | 241 V(JumpIfUndefined, AccumulatorUse::kRead, OperandType::kImm) \ |
| 230 V(JumpIfUndefinedConstant, AccumulatorUse::kRead, OperandType::kIdx) \ | |
| 231 V(JumpIfNotHole, AccumulatorUse::kRead, OperandType::kImm) \ | 242 V(JumpIfNotHole, AccumulatorUse::kRead, OperandType::kImm) \ |
| 232 V(JumpIfNotHoleConstant, AccumulatorUse::kRead, OperandType::kIdx) \ | |
| 233 V(JumpLoop, AccumulatorUse::kNone, OperandType::kImm, OperandType::kImm) \ | |
| 234 \ | 243 \ |
| 235 /* Complex flow control For..in */ \ | 244 /* Complex flow control For..in */ \ |
| 236 V(ForInPrepare, AccumulatorUse::kNone, OperandType::kReg, \ | 245 V(ForInPrepare, AccumulatorUse::kNone, OperandType::kReg, \ |
| 237 OperandType::kRegOutTriple) \ | 246 OperandType::kRegOutTriple) \ |
| 238 V(ForInContinue, AccumulatorUse::kWrite, OperandType::kReg, \ | 247 V(ForInContinue, AccumulatorUse::kWrite, OperandType::kReg, \ |
| 239 OperandType::kReg) \ | 248 OperandType::kReg) \ |
| 240 V(ForInNext, AccumulatorUse::kWrite, OperandType::kReg, OperandType::kReg, \ | 249 V(ForInNext, AccumulatorUse::kWrite, OperandType::kReg, OperandType::kReg, \ |
| 241 OperandType::kRegPair, OperandType::kIdx) \ | 250 OperandType::kRegPair, OperandType::kIdx) \ |
| 242 V(ForInStep, AccumulatorUse::kWrite, OperandType::kReg) \ | 251 V(ForInStep, AccumulatorUse::kWrite, OperandType::kReg) \ |
| 243 \ | 252 \ |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 293 V(DebugBreak6) | 302 V(DebugBreak6) |
| 294 | 303 |
| 295 #define DEBUG_BREAK_PREFIX_BYTECODE_LIST(V) \ | 304 #define DEBUG_BREAK_PREFIX_BYTECODE_LIST(V) \ |
| 296 V(DebugBreakWide) \ | 305 V(DebugBreakWide) \ |
| 297 V(DebugBreakExtraWide) | 306 V(DebugBreakExtraWide) |
| 298 | 307 |
| 299 #define DEBUG_BREAK_BYTECODE_LIST(V) \ | 308 #define DEBUG_BREAK_BYTECODE_LIST(V) \ |
| 300 DEBUG_BREAK_PLAIN_BYTECODE_LIST(V) \ | 309 DEBUG_BREAK_PLAIN_BYTECODE_LIST(V) \ |
| 301 DEBUG_BREAK_PREFIX_BYTECODE_LIST(V) | 310 DEBUG_BREAK_PREFIX_BYTECODE_LIST(V) |
| 302 | 311 |
| 312 // List of jump bytecodes. | |
| 313 #define JUMP_FORWARD_BYTECODE_LIST(V) \ | |
| 314 V(Jump) \ | |
| 315 V(JumpConstant) \ | |
| 316 V(JumpIfNullConstant) \ | |
| 317 V(JumpIfUndefinedConstant) \ | |
| 318 V(JumpIfTrueConstant) \ | |
| 319 V(JumpIfFalseConstant) \ | |
| 320 V(JumpIfNotHoleConstant) \ | |
| 321 V(JumpIfToBooleanTrueConstant) \ | |
| 322 V(JumpIfToBooleanFalseConstant) \ | |
| 323 V(JumpIfToBooleanTrue) \ | |
| 324 V(JumpIfToBooleanFalse) \ | |
| 325 V(JumpIfTrue) \ | |
| 326 V(JumpIfFalse) \ | |
| 327 V(JumpIfNull) \ | |
| 328 V(JumpIfUndefined) \ | |
| 329 V(JumpIfNotHole) | |
| 330 | |
| 331 #define JUMP_CONSTANT_BYTECODE_LIST(V) \ | |
| 332 V(JumpConstant) \ | |
| 333 V(JumpIfNullConstant) \ | |
| 334 V(JumpIfUndefinedConstant) \ | |
| 335 V(JumpIfTrueConstant) \ | |
| 336 V(JumpIfFalseConstant) \ | |
| 337 V(JumpIfNotHoleConstant) \ | |
| 338 V(JumpIfToBooleanTrueConstant) \ | |
| 339 V(JumpIfToBooleanFalseConstant) | |
| 340 | |
| 341 #define JUMP_IMMEDIATE_BYTECODE_LIST(V) \ | |
| 342 V(JumpLoop) \ | |
| 343 V(Jump) \ | |
| 344 V(JumpIfToBooleanTrue) \ | |
| 345 V(JumpIfToBooleanFalse) \ | |
| 346 V(JumpIfTrue) \ | |
| 347 V(JumpIfFalse) \ | |
| 348 V(JumpIfNull) \ | |
| 349 V(JumpIfUndefined) \ | |
| 350 V(JumpIfNotHole) | |
| 351 | |
| 352 #define JUMP_TO_BOOLEAN_BYTECODE_LIST(V) \ | |
| 353 V(JumpIfToBooleanTrueConstant) \ | |
| 354 V(JumpIfToBooleanFalseConstant) \ | |
| 355 V(JumpIfToBooleanTrue) \ | |
| 356 V(JumpIfToBooleanFalse) | |
| 357 | |
| 358 #define JUMP_UNCONDITIONAL_BYTECODE_LIST(V) \ | |
| 359 V(JumpLoop) \ | |
| 360 V(Jump) \ | |
| 361 V(JumpConstant) | |
| 362 | |
| 363 #define JUMP_CONDITIONAL_BYTECODE_LIST(V) \ | |
| 364 V(JumpIfNullConstant) \ | |
| 365 V(JumpIfUndefinedConstant) \ | |
| 366 V(JumpIfTrueConstant) \ | |
| 367 V(JumpIfFalseConstant) \ | |
| 368 V(JumpIfNotHoleConstant) \ | |
| 369 V(JumpIfToBooleanTrueConstant) \ | |
| 370 V(JumpIfToBooleanFalseConstant) \ | |
| 371 V(JumpIfToBooleanTrue) \ | |
| 372 V(JumpIfToBooleanFalse) \ | |
| 373 V(JumpIfTrue) \ | |
| 374 V(JumpIfFalse) \ | |
| 375 V(JumpIfNull) \ | |
| 376 V(JumpIfUndefined) \ | |
| 377 V(JumpIfNotHole) | |
|
rmcilroy
2016/12/05 14:33:40
nit - could you build these up so there aren't rep
Leszek Swirski
2016/12/05 17:53:11
Done, except for some duplication in JumpForward c
| |
| 378 | |
| 379 #define JUMP_BYTECODE_LIST(V) \ | |
| 380 V(JumpLoop) \ | |
| 381 JUMP_FORWARD_BYTECODE_LIST(V) | |
| 382 | |
| 303 // Enumeration of interpreter bytecodes. | 383 // Enumeration of interpreter bytecodes. |
| 304 enum class Bytecode : uint8_t { | 384 enum class Bytecode : uint8_t { |
| 305 #define DECLARE_BYTECODE(Name, ...) k##Name, | 385 #define DECLARE_BYTECODE(Name, ...) k##Name, |
| 306 BYTECODE_LIST(DECLARE_BYTECODE) | 386 BYTECODE_LIST(DECLARE_BYTECODE) |
| 307 #undef DECLARE_BYTECODE | 387 #undef DECLARE_BYTECODE |
| 308 #define COUNT_BYTECODE(x, ...) +1 | 388 #define COUNT_BYTECODE(x, ...) +1 |
| 309 // The COUNT_BYTECODE macro will turn this into kLast = -1 +1 +1... which will | 389 // The COUNT_BYTECODE macro will turn this into kLast = -1 +1 +1... which will |
| 310 // evaluate to the same value as the last real bytecode. | 390 // evaluate to the same value as the last real bytecode. |
| 311 kLast = -1 BYTECODE_LIST(COUNT_BYTECODE) | 391 kLast = -1 BYTECODE_LIST(COUNT_BYTECODE) |
| 312 #undef COUNT_BYTECODE | 392 #undef COUNT_BYTECODE |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 436 // Return true if |bytecode| is a register load without effects, | 516 // Return true if |bytecode| is a register load without effects, |
| 437 // e.g. Mov, Star. | 517 // e.g. Mov, Star. |
| 438 static CONSTEXPR bool IsRegisterLoadWithoutEffects(Bytecode bytecode) { | 518 static CONSTEXPR bool IsRegisterLoadWithoutEffects(Bytecode bytecode) { |
| 439 return bytecode == Bytecode::kMov || bytecode == Bytecode::kPopContext || | 519 return bytecode == Bytecode::kMov || bytecode == Bytecode::kPopContext || |
| 440 bytecode == Bytecode::kPushContext || bytecode == Bytecode::kStar; | 520 bytecode == Bytecode::kPushContext || bytecode == Bytecode::kStar; |
| 441 } | 521 } |
| 442 | 522 |
| 443 // Returns true if the bytecode is a conditional jump taking | 523 // Returns true if the bytecode is a conditional jump taking |
| 444 // an immediate byte operand (OperandType::kImm). | 524 // an immediate byte operand (OperandType::kImm). |
| 445 static CONSTEXPR bool IsConditionalJumpImmediate(Bytecode bytecode) { | 525 static CONSTEXPR bool IsConditionalJumpImmediate(Bytecode bytecode) { |
| 446 return bytecode == Bytecode::kJumpIfTrue || | 526 return bytecode >= Bytecode::kJumpIfToBooleanTrue && |
| 447 bytecode == Bytecode::kJumpIfFalse || | 527 bytecode <= Bytecode::kJumpIfNotHole; |
| 448 bytecode == Bytecode::kJumpIfToBooleanTrue || | |
| 449 bytecode == Bytecode::kJumpIfToBooleanFalse || | |
| 450 bytecode == Bytecode::kJumpIfNotHole || | |
| 451 bytecode == Bytecode::kJumpIfNull || | |
| 452 bytecode == Bytecode::kJumpIfUndefined; | |
| 453 } | 528 } |
| 454 | 529 |
| 455 // Returns true if the bytecode is a conditional jump taking | 530 // Returns true if the bytecode is a conditional jump taking |
| 456 // a constant pool entry (OperandType::kIdx). | 531 // a constant pool entry (OperandType::kIdx). |
| 457 static CONSTEXPR bool IsConditionalJumpConstant(Bytecode bytecode) { | 532 static CONSTEXPR bool IsConditionalJumpConstant(Bytecode bytecode) { |
| 458 return bytecode == Bytecode::kJumpIfTrueConstant || | 533 return bytecode >= Bytecode::kJumpIfNullConstant && |
| 459 bytecode == Bytecode::kJumpIfFalseConstant || | 534 bytecode <= Bytecode::kJumpIfToBooleanFalseConstant; |
| 460 bytecode == Bytecode::kJumpIfToBooleanTrueConstant || | |
| 461 bytecode == Bytecode::kJumpIfToBooleanFalseConstant || | |
| 462 bytecode == Bytecode::kJumpIfNotHoleConstant || | |
| 463 bytecode == Bytecode::kJumpIfNullConstant || | |
| 464 bytecode == Bytecode::kJumpIfUndefinedConstant; | |
| 465 } | 535 } |
| 466 | 536 |
| 467 // Returns true if the bytecode is a conditional jump taking | 537 // Returns true if the bytecode is a conditional jump taking |
| 468 // any kind of operand. | 538 // any kind of operand. |
| 469 static CONSTEXPR bool IsConditionalJump(Bytecode bytecode) { | 539 static CONSTEXPR bool IsConditionalJump(Bytecode bytecode) { |
| 470 return IsConditionalJumpImmediate(bytecode) || | 540 return bytecode >= Bytecode::kJumpIfNullConstant && |
| 471 IsConditionalJumpConstant(bytecode); | 541 bytecode <= Bytecode::kJumpIfNotHole; |
| 472 } | 542 } |
| 473 | 543 |
| 474 // Returns true if the bytecode is an unconditional jump. | 544 // Returns true if the bytecode is an unconditional jump. |
| 475 static CONSTEXPR bool IsUnconditionalJump(Bytecode bytecode) { | 545 static CONSTEXPR bool IsUnconditionalJump(Bytecode bytecode) { |
| 476 return bytecode == Bytecode::kJump || bytecode == Bytecode::kJumpConstant || | 546 return bytecode >= Bytecode::kJumpLoop && |
| 477 bytecode == Bytecode::kJumpLoop; | 547 bytecode <= Bytecode::kJumpConstant; |
| 478 } | 548 } |
| 479 | 549 |
| 480 // Returns true if the bytecode is a jump or a conditional jump taking | 550 // Returns true if the bytecode is a jump or a conditional jump taking |
| 481 // an immediate byte operand (OperandType::kImm). | 551 // an immediate byte operand (OperandType::kImm). |
| 482 static CONSTEXPR bool IsJumpImmediate(Bytecode bytecode) { | 552 static CONSTEXPR bool IsJumpImmediate(Bytecode bytecode) { |
| 483 return bytecode == Bytecode::kJump || bytecode == Bytecode::kJumpLoop || | 553 return bytecode == Bytecode::kJump || bytecode == Bytecode::kJumpLoop || |
| 484 IsConditionalJumpImmediate(bytecode); | 554 IsConditionalJumpImmediate(bytecode); |
| 485 } | 555 } |
| 486 | 556 |
| 487 // Returns true if the bytecode is a jump or conditional jump taking a | 557 // Returns true if the bytecode is a jump or conditional jump taking a |
| 488 // constant pool entry (OperandType::kIdx). | 558 // constant pool entry (OperandType::kIdx). |
| 489 static CONSTEXPR bool IsJumpConstant(Bytecode bytecode) { | 559 static CONSTEXPR bool IsJumpConstant(Bytecode bytecode) { |
| 490 return bytecode == Bytecode::kJumpConstant || | 560 return bytecode >= Bytecode::kJumpConstant && |
| 491 IsConditionalJumpConstant(bytecode); | 561 bytecode <= Bytecode::kJumpIfToBooleanFalseConstant; |
| 492 } | 562 } |
| 493 | 563 |
| 494 // Returns true if the bytecode is a jump that internally coerces the | 564 // Returns true if the bytecode is a jump that internally coerces the |
| 495 // accumulator to a boolean. | 565 // accumulator to a boolean. |
| 496 static CONSTEXPR bool IsJumpIfToBoolean(Bytecode bytecode) { | 566 static CONSTEXPR bool IsJumpIfToBoolean(Bytecode bytecode) { |
| 497 return bytecode == Bytecode::kJumpIfToBooleanTrue || | 567 return bytecode >= Bytecode::kJumpIfToBooleanTrueConstant && |
| 498 bytecode == Bytecode::kJumpIfToBooleanFalse || | 568 bytecode <= Bytecode::kJumpIfToBooleanFalse; |
| 499 bytecode == Bytecode::kJumpIfToBooleanTrueConstant || | |
| 500 bytecode == Bytecode::kJumpIfToBooleanFalseConstant; | |
| 501 } | 569 } |
| 502 | 570 |
| 503 // Returns true if the bytecode is a jump or conditional jump taking | 571 // Returns true if the bytecode is a jump or conditional jump taking |
| 504 // any kind of operand. | 572 // any kind of operand. |
| 505 static CONSTEXPR bool IsJump(Bytecode bytecode) { | 573 static CONSTEXPR bool IsJump(Bytecode bytecode) { |
| 506 return IsJumpImmediate(bytecode) || IsJumpConstant(bytecode); | 574 return bytecode >= Bytecode::kJumpLoop && |
| 575 bytecode <= Bytecode::kJumpIfNotHole; | |
| 507 } | 576 } |
| 508 | 577 |
| 509 // Returns true if the bytecode is a forward jump or conditional jump taking | 578 // Returns true if the bytecode is a forward jump or conditional jump taking |
| 510 // any kind of operand. | 579 // any kind of operand. |
| 511 static CONSTEXPR bool IsForwardJump(Bytecode bytecode) { | 580 static CONSTEXPR bool IsForwardJump(Bytecode bytecode) { |
| 512 return bytecode != Bytecode::kJumpLoop && IsJump(bytecode); | 581 return bytecode >= Bytecode::kJump && bytecode <= Bytecode::kJumpIfNotHole; |
| 513 } | 582 } |
| 514 | 583 |
| 515 // Returns true if the bytecode is a conditional jump, a jump, or a return. | 584 // Returns true if the bytecode is a conditional jump, a jump, or a return. |
| 516 static CONSTEXPR bool IsJumpOrReturn(Bytecode bytecode) { | 585 static CONSTEXPR bool IsJumpOrReturn(Bytecode bytecode) { |
| 517 return bytecode == Bytecode::kReturn || IsJump(bytecode); | 586 return bytecode == Bytecode::kReturn || IsJump(bytecode); |
| 518 } | 587 } |
| 519 | 588 |
| 520 // Return true if |bytecode| is a jump without effects, | 589 // Return true if |bytecode| is a jump without effects, |
| 521 // e.g. any jump excluding those that include type coercion like | 590 // e.g. any jump excluding those that include type coercion like |
| 522 // JumpIfTrueToBoolean. | 591 // JumpIfTrueToBoolean. |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 753 #undef CONSTEXPR | 822 #undef CONSTEXPR |
| 754 | 823 |
| 755 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, | 824 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, |
| 756 const Bytecode& bytecode); | 825 const Bytecode& bytecode); |
| 757 | 826 |
| 758 } // namespace interpreter | 827 } // namespace interpreter |
| 759 } // namespace internal | 828 } // namespace internal |
| 760 } // namespace v8 | 829 } // namespace v8 |
| 761 | 830 |
| 762 #endif // V8_INTERPRETER_BYTECODES_H_ | 831 #endif // V8_INTERPRETER_BYTECODES_H_ |
| OLD | NEW |