Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(181)

Side by Side Diff: src/interpreter/bytecodes.h

Issue 2542903003: [Interpreter] Templatize AccumulatorUsage and OperandType for bytecode creation. (Closed)
Patch Set: Rebase Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 #define DECLARE_BYTECODE(Name, ...) k##Name, 305 #define DECLARE_BYTECODE(Name, ...) k##Name,
306 BYTECODE_LIST(DECLARE_BYTECODE) 306 BYTECODE_LIST(DECLARE_BYTECODE)
307 #undef DECLARE_BYTECODE 307 #undef DECLARE_BYTECODE
308 #define COUNT_BYTECODE(x, ...) +1 308 #define COUNT_BYTECODE(x, ...) +1
309 // The COUNT_BYTECODE macro will turn this into kLast = -1 +1 +1... which will 309 // 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. 310 // evaluate to the same value as the last real bytecode.
311 kLast = -1 BYTECODE_LIST(COUNT_BYTECODE) 311 kLast = -1 BYTECODE_LIST(COUNT_BYTECODE)
312 #undef COUNT_BYTECODE 312 #undef COUNT_BYTECODE
313 }; 313 };
314 314
315 // TODO(rmcilroy): Remove once we switch to MSVC 2015 which supports constexpr.
316 // See crbug.com/603131.
317 #if V8_CC_MSVC
318 #define CONSTEXPR const
319 #else
320 #define CONSTEXPR constexpr
321 #endif
322
323 class V8_EXPORT_PRIVATE Bytecodes final { 315 class V8_EXPORT_PRIVATE Bytecodes final {
324 public: 316 public:
325 // The maximum number of operands a bytecode may have. 317 // The maximum number of operands a bytecode may have.
326 static const int kMaxOperands = 4; 318 static const int kMaxOperands = 4;
327 319
328 // Returns string representation of |bytecode|. 320 // Returns string representation of |bytecode|.
329 static const char* ToString(Bytecode bytecode); 321 static const char* ToString(Bytecode bytecode);
330 322
331 // Returns string representation of |bytecode|. 323 // Returns string representation of |bytecode|.
332 static std::string ToString(Bytecode bytecode, OperandScale operand_scale); 324 static std::string ToString(Bytecode bytecode, OperandScale operand_scale);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
380 } 372 }
381 373
382 // Returns how accumulator is used by |bytecode|. 374 // Returns how accumulator is used by |bytecode|.
383 static AccumulatorUse GetAccumulatorUse(Bytecode bytecode) { 375 static AccumulatorUse GetAccumulatorUse(Bytecode bytecode) {
384 DCHECK(bytecode <= Bytecode::kLast); 376 DCHECK(bytecode <= Bytecode::kLast);
385 return kAccumulatorUse[static_cast<size_t>(bytecode)]; 377 return kAccumulatorUse[static_cast<size_t>(bytecode)];
386 } 378 }
387 379
388 // Returns true if |bytecode| reads the accumulator. 380 // Returns true if |bytecode| reads the accumulator.
389 static bool ReadsAccumulator(Bytecode bytecode) { 381 static bool ReadsAccumulator(Bytecode bytecode) {
390 return (GetAccumulatorUse(bytecode) & AccumulatorUse::kRead) == 382 return BytecodeOperands::ReadsAccumulator(GetAccumulatorUse(bytecode));
391 AccumulatorUse::kRead;
392 } 383 }
393 384
394 // Returns true if |bytecode| writes the accumulator. 385 // Returns true if |bytecode| writes the accumulator.
395 static bool WritesAccumulator(Bytecode bytecode) { 386 static bool WritesAccumulator(Bytecode bytecode) {
396 return (GetAccumulatorUse(bytecode) & AccumulatorUse::kWrite) == 387 return BytecodeOperands::WritesAccumulator(GetAccumulatorUse(bytecode));
397 AccumulatorUse::kWrite;
398 } 388 }
399 389
400 // Return true if |bytecode| writes the accumulator with a boolean value. 390 // Return true if |bytecode| writes the accumulator with a boolean value.
401 static bool WritesBooleanToAccumulator(Bytecode bytecode) { 391 static bool WritesBooleanToAccumulator(Bytecode bytecode) {
402 switch (bytecode) { 392 switch (bytecode) {
403 case Bytecode::kLdaTrue: 393 case Bytecode::kLdaTrue:
404 case Bytecode::kLdaFalse: 394 case Bytecode::kLdaFalse:
405 case Bytecode::kToBooleanLogicalNot: 395 case Bytecode::kToBooleanLogicalNot:
406 case Bytecode::kLogicalNot: 396 case Bytecode::kLogicalNot:
407 case Bytecode::kTestEqual: 397 case Bytecode::kTestEqual:
408 case Bytecode::kTestNotEqual: 398 case Bytecode::kTestNotEqual:
409 case Bytecode::kTestEqualStrict: 399 case Bytecode::kTestEqualStrict:
410 case Bytecode::kTestLessThan: 400 case Bytecode::kTestLessThan:
411 case Bytecode::kTestLessThanOrEqual: 401 case Bytecode::kTestLessThanOrEqual:
412 case Bytecode::kTestGreaterThan: 402 case Bytecode::kTestGreaterThan:
413 case Bytecode::kTestGreaterThanOrEqual: 403 case Bytecode::kTestGreaterThanOrEqual:
414 case Bytecode::kTestInstanceOf: 404 case Bytecode::kTestInstanceOf:
415 case Bytecode::kTestIn: 405 case Bytecode::kTestIn:
416 case Bytecode::kForInContinue: 406 case Bytecode::kForInContinue:
417 return true; 407 return true;
418 default: 408 default:
419 return false; 409 return false;
420 } 410 }
421 } 411 }
422 412
423 // Return true if |bytecode| is an accumulator load without effects, 413 // Return true if |bytecode| is an accumulator load without effects,
424 // e.g. LdaConstant, LdaTrue, Ldar. 414 // e.g. LdaConstant, LdaTrue, Ldar.
425 static CONSTEXPR bool IsAccumulatorLoadWithoutEffects(Bytecode bytecode) { 415 static constexpr bool IsAccumulatorLoadWithoutEffects(Bytecode bytecode) {
426 return bytecode == Bytecode::kLdar || bytecode == Bytecode::kLdaZero || 416 return bytecode == Bytecode::kLdar || bytecode == Bytecode::kLdaZero ||
427 bytecode == Bytecode::kLdaSmi || bytecode == Bytecode::kLdaNull || 417 bytecode == Bytecode::kLdaSmi || bytecode == Bytecode::kLdaNull ||
428 bytecode == Bytecode::kLdaTrue || bytecode == Bytecode::kLdaFalse || 418 bytecode == Bytecode::kLdaTrue || bytecode == Bytecode::kLdaFalse ||
429 bytecode == Bytecode::kLdaUndefined || 419 bytecode == Bytecode::kLdaUndefined ||
430 bytecode == Bytecode::kLdaTheHole || 420 bytecode == Bytecode::kLdaTheHole ||
431 bytecode == Bytecode::kLdaConstant || 421 bytecode == Bytecode::kLdaConstant ||
432 bytecode == Bytecode::kLdaContextSlot || 422 bytecode == Bytecode::kLdaContextSlot ||
433 bytecode == Bytecode::kLdaCurrentContextSlot; 423 bytecode == Bytecode::kLdaCurrentContextSlot;
434 } 424 }
435 425
436 // Return true if |bytecode| is a register load without effects, 426 // Return true if |bytecode| is a register load without effects,
437 // e.g. Mov, Star. 427 // e.g. Mov, Star.
438 static CONSTEXPR bool IsRegisterLoadWithoutEffects(Bytecode bytecode) { 428 static constexpr bool IsRegisterLoadWithoutEffects(Bytecode bytecode) {
439 return bytecode == Bytecode::kMov || bytecode == Bytecode::kPopContext || 429 return bytecode == Bytecode::kMov || bytecode == Bytecode::kPopContext ||
440 bytecode == Bytecode::kPushContext || bytecode == Bytecode::kStar; 430 bytecode == Bytecode::kPushContext || bytecode == Bytecode::kStar;
441 } 431 }
442 432
443 // Returns true if the bytecode is a conditional jump taking 433 // Returns true if the bytecode is a conditional jump taking
444 // an immediate byte operand (OperandType::kImm). 434 // an immediate byte operand (OperandType::kImm).
445 static CONSTEXPR bool IsConditionalJumpImmediate(Bytecode bytecode) { 435 static constexpr bool IsConditionalJumpImmediate(Bytecode bytecode) {
446 return bytecode == Bytecode::kJumpIfTrue || 436 return bytecode == Bytecode::kJumpIfTrue ||
447 bytecode == Bytecode::kJumpIfFalse || 437 bytecode == Bytecode::kJumpIfFalse ||
448 bytecode == Bytecode::kJumpIfToBooleanTrue || 438 bytecode == Bytecode::kJumpIfToBooleanTrue ||
449 bytecode == Bytecode::kJumpIfToBooleanFalse || 439 bytecode == Bytecode::kJumpIfToBooleanFalse ||
450 bytecode == Bytecode::kJumpIfNotHole || 440 bytecode == Bytecode::kJumpIfNotHole ||
451 bytecode == Bytecode::kJumpIfNull || 441 bytecode == Bytecode::kJumpIfNull ||
452 bytecode == Bytecode::kJumpIfUndefined; 442 bytecode == Bytecode::kJumpIfUndefined;
453 } 443 }
454 444
455 // Returns true if the bytecode is a conditional jump taking 445 // Returns true if the bytecode is a conditional jump taking
456 // a constant pool entry (OperandType::kIdx). 446 // a constant pool entry (OperandType::kIdx).
457 static CONSTEXPR bool IsConditionalJumpConstant(Bytecode bytecode) { 447 static constexpr bool IsConditionalJumpConstant(Bytecode bytecode) {
458 return bytecode == Bytecode::kJumpIfTrueConstant || 448 return bytecode == Bytecode::kJumpIfTrueConstant ||
459 bytecode == Bytecode::kJumpIfFalseConstant || 449 bytecode == Bytecode::kJumpIfFalseConstant ||
460 bytecode == Bytecode::kJumpIfToBooleanTrueConstant || 450 bytecode == Bytecode::kJumpIfToBooleanTrueConstant ||
461 bytecode == Bytecode::kJumpIfToBooleanFalseConstant || 451 bytecode == Bytecode::kJumpIfToBooleanFalseConstant ||
462 bytecode == Bytecode::kJumpIfNotHoleConstant || 452 bytecode == Bytecode::kJumpIfNotHoleConstant ||
463 bytecode == Bytecode::kJumpIfNullConstant || 453 bytecode == Bytecode::kJumpIfNullConstant ||
464 bytecode == Bytecode::kJumpIfUndefinedConstant; 454 bytecode == Bytecode::kJumpIfUndefinedConstant;
465 } 455 }
466 456
467 // Returns true if the bytecode is a conditional jump taking 457 // Returns true if the bytecode is a conditional jump taking
468 // any kind of operand. 458 // any kind of operand.
469 static CONSTEXPR bool IsConditionalJump(Bytecode bytecode) { 459 static constexpr bool IsConditionalJump(Bytecode bytecode) {
470 return IsConditionalJumpImmediate(bytecode) || 460 return IsConditionalJumpImmediate(bytecode) ||
471 IsConditionalJumpConstant(bytecode); 461 IsConditionalJumpConstant(bytecode);
472 } 462 }
473 463
474 // Returns true if the bytecode is an unconditional jump. 464 // Returns true if the bytecode is an unconditional jump.
475 static CONSTEXPR bool IsUnconditionalJump(Bytecode bytecode) { 465 static constexpr bool IsUnconditionalJump(Bytecode bytecode) {
476 return bytecode == Bytecode::kJump || bytecode == Bytecode::kJumpConstant || 466 return bytecode == Bytecode::kJump || bytecode == Bytecode::kJumpConstant ||
477 bytecode == Bytecode::kJumpLoop; 467 bytecode == Bytecode::kJumpLoop;
478 } 468 }
479 469
480 // Returns true if the bytecode is a jump or a conditional jump taking 470 // Returns true if the bytecode is a jump or a conditional jump taking
481 // an immediate byte operand (OperandType::kImm). 471 // an immediate byte operand (OperandType::kImm).
482 static CONSTEXPR bool IsJumpImmediate(Bytecode bytecode) { 472 static constexpr bool IsJumpImmediate(Bytecode bytecode) {
483 return bytecode == Bytecode::kJump || bytecode == Bytecode::kJumpLoop || 473 return bytecode == Bytecode::kJump || bytecode == Bytecode::kJumpLoop ||
484 IsConditionalJumpImmediate(bytecode); 474 IsConditionalJumpImmediate(bytecode);
485 } 475 }
486 476
487 // Returns true if the bytecode is a jump or conditional jump taking a 477 // Returns true if the bytecode is a jump or conditional jump taking a
488 // constant pool entry (OperandType::kIdx). 478 // constant pool entry (OperandType::kIdx).
489 static CONSTEXPR bool IsJumpConstant(Bytecode bytecode) { 479 static constexpr bool IsJumpConstant(Bytecode bytecode) {
490 return bytecode == Bytecode::kJumpConstant || 480 return bytecode == Bytecode::kJumpConstant ||
491 IsConditionalJumpConstant(bytecode); 481 IsConditionalJumpConstant(bytecode);
492 } 482 }
493 483
494 // Returns true if the bytecode is a jump that internally coerces the 484 // Returns true if the bytecode is a jump that internally coerces the
495 // accumulator to a boolean. 485 // accumulator to a boolean.
496 static CONSTEXPR bool IsJumpIfToBoolean(Bytecode bytecode) { 486 static constexpr bool IsJumpIfToBoolean(Bytecode bytecode) {
497 return bytecode == Bytecode::kJumpIfToBooleanTrue || 487 return bytecode == Bytecode::kJumpIfToBooleanTrue ||
498 bytecode == Bytecode::kJumpIfToBooleanFalse || 488 bytecode == Bytecode::kJumpIfToBooleanFalse ||
499 bytecode == Bytecode::kJumpIfToBooleanTrueConstant || 489 bytecode == Bytecode::kJumpIfToBooleanTrueConstant ||
500 bytecode == Bytecode::kJumpIfToBooleanFalseConstant; 490 bytecode == Bytecode::kJumpIfToBooleanFalseConstant;
501 } 491 }
502 492
503 // Returns true if the bytecode is a jump or conditional jump taking 493 // Returns true if the bytecode is a jump or conditional jump taking
504 // any kind of operand. 494 // any kind of operand.
505 static CONSTEXPR bool IsJump(Bytecode bytecode) { 495 static constexpr bool IsJump(Bytecode bytecode) {
506 return IsJumpImmediate(bytecode) || IsJumpConstant(bytecode); 496 return IsJumpImmediate(bytecode) || IsJumpConstant(bytecode);
507 } 497 }
508 498
509 // Returns true if the bytecode is a forward jump or conditional jump taking 499 // Returns true if the bytecode is a forward jump or conditional jump taking
510 // any kind of operand. 500 // any kind of operand.
511 static CONSTEXPR bool IsForwardJump(Bytecode bytecode) { 501 static constexpr bool IsForwardJump(Bytecode bytecode) {
512 return bytecode != Bytecode::kJumpLoop && IsJump(bytecode); 502 return bytecode != Bytecode::kJumpLoop && IsJump(bytecode);
513 } 503 }
514 504
515 // Returns true if the bytecode is a conditional jump, a jump, or a return. 505 // Returns true if the bytecode is a conditional jump, a jump, or a return.
516 static CONSTEXPR bool IsJumpOrReturn(Bytecode bytecode) { 506 static constexpr bool IsJumpOrReturn(Bytecode bytecode) {
517 return bytecode == Bytecode::kReturn || IsJump(bytecode); 507 return bytecode == Bytecode::kReturn || IsJump(bytecode);
518 } 508 }
519 509
520 // Return true if |bytecode| is a jump without effects, 510 // Return true if |bytecode| is a jump without effects,
521 // e.g. any jump excluding those that include type coercion like 511 // e.g. any jump excluding those that include type coercion like
522 // JumpIfTrueToBoolean. 512 // JumpIfTrueToBoolean.
523 static CONSTEXPR bool IsJumpWithoutEffects(Bytecode bytecode) { 513 static constexpr bool IsJumpWithoutEffects(Bytecode bytecode) {
524 return IsJump(bytecode) && !IsJumpIfToBoolean(bytecode); 514 return IsJump(bytecode) && !IsJumpIfToBoolean(bytecode);
525 } 515 }
526 516
527 // Returns true if |bytecode| has no effects. These bytecodes only manipulate 517 // Returns true if |bytecode| has no effects. These bytecodes only manipulate
528 // interpreter frame state and will never throw. 518 // interpreter frame state and will never throw.
529 static CONSTEXPR bool IsWithoutExternalSideEffects(Bytecode bytecode) { 519 static constexpr bool IsWithoutExternalSideEffects(Bytecode bytecode) {
530 return (IsAccumulatorLoadWithoutEffects(bytecode) || 520 return (IsAccumulatorLoadWithoutEffects(bytecode) ||
531 IsRegisterLoadWithoutEffects(bytecode) || 521 IsRegisterLoadWithoutEffects(bytecode) ||
532 bytecode == Bytecode::kNop || IsJumpWithoutEffects(bytecode)); 522 bytecode == Bytecode::kNop || IsJumpWithoutEffects(bytecode));
533 } 523 }
534 524
535 // Returns true if the bytecode is Ldar or Star. 525 // Returns true if the bytecode is Ldar or Star.
536 static CONSTEXPR bool IsLdarOrStar(Bytecode bytecode) { 526 static constexpr bool IsLdarOrStar(Bytecode bytecode) {
537 return bytecode == Bytecode::kLdar || bytecode == Bytecode::kStar; 527 return bytecode == Bytecode::kLdar || bytecode == Bytecode::kStar;
538 } 528 }
539 529
540 // Returns true if |bytecode| puts a name in the accumulator. 530 // Returns true if |bytecode| puts a name in the accumulator.
541 static CONSTEXPR bool PutsNameInAccumulator(Bytecode bytecode) { 531 static constexpr bool PutsNameInAccumulator(Bytecode bytecode) {
542 return bytecode == Bytecode::kTypeOf; 532 return bytecode == Bytecode::kTypeOf;
543 } 533 }
544 534
545 // Returns true if the bytecode is a call or a constructor call. 535 // Returns true if the bytecode is a call or a constructor call.
546 static CONSTEXPR bool IsCallOrNew(Bytecode bytecode) { 536 static constexpr bool IsCallOrNew(Bytecode bytecode) {
547 return bytecode == Bytecode::kCall || bytecode == Bytecode::kCallProperty || 537 return bytecode == Bytecode::kCall || bytecode == Bytecode::kCallProperty ||
548 bytecode == Bytecode::kTailCall || bytecode == Bytecode::kNew; 538 bytecode == Bytecode::kTailCall || bytecode == Bytecode::kNew;
549 } 539 }
550 540
551 // Returns true if the bytecode is a call to the runtime. 541 // Returns true if the bytecode is a call to the runtime.
552 static CONSTEXPR bool IsCallRuntime(Bytecode bytecode) { 542 static constexpr bool IsCallRuntime(Bytecode bytecode) {
553 return bytecode == Bytecode::kCallRuntime || 543 return bytecode == Bytecode::kCallRuntime ||
554 bytecode == Bytecode::kCallRuntimeForPair || 544 bytecode == Bytecode::kCallRuntimeForPair ||
555 bytecode == Bytecode::kInvokeIntrinsic; 545 bytecode == Bytecode::kInvokeIntrinsic;
556 } 546 }
557 547
558 // Returns true if the bytecode is a scaling prefix bytecode. 548 // Returns true if the bytecode is a scaling prefix bytecode.
559 static CONSTEXPR bool IsPrefixScalingBytecode(Bytecode bytecode) { 549 static constexpr bool IsPrefixScalingBytecode(Bytecode bytecode) {
560 return bytecode == Bytecode::kExtraWide || bytecode == Bytecode::kWide || 550 return bytecode == Bytecode::kExtraWide || bytecode == Bytecode::kWide ||
561 bytecode == Bytecode::kDebugBreakExtraWide || 551 bytecode == Bytecode::kDebugBreakExtraWide ||
562 bytecode == Bytecode::kDebugBreakWide; 552 bytecode == Bytecode::kDebugBreakWide;
563 } 553 }
564 554
565 // Returns the number of values which |bytecode| returns. 555 // Returns the number of values which |bytecode| returns.
566 static CONSTEXPR size_t ReturnCount(Bytecode bytecode) { 556 static constexpr size_t ReturnCount(Bytecode bytecode) {
567 return bytecode == Bytecode::kReturn ? 1 : 0; 557 return bytecode == Bytecode::kReturn ? 1 : 0;
568 } 558 }
569 559
570 // Returns the number of operands expected by |bytecode|. 560 // Returns the number of operands expected by |bytecode|.
571 static int NumberOfOperands(Bytecode bytecode) { 561 static int NumberOfOperands(Bytecode bytecode) {
572 DCHECK(bytecode <= Bytecode::kLast); 562 DCHECK(bytecode <= Bytecode::kLast);
573 return kOperandCount[static_cast<size_t>(bytecode)]; 563 return kOperandCount[static_cast<size_t>(bytecode)];
574 } 564 }
575 565
576 // Returns the i-th operand of |bytecode|. 566 // Returns the i-th operand of |bytecode|.
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
741 static const OperandType* const kOperandTypes[]; 731 static const OperandType* const kOperandTypes[];
742 static const OperandTypeInfo* const kOperandTypeInfos[]; 732 static const OperandTypeInfo* const kOperandTypeInfos[];
743 static const int kOperandCount[]; 733 static const int kOperandCount[];
744 static const int kNumberOfRegisterOperands[]; 734 static const int kNumberOfRegisterOperands[];
745 static const AccumulatorUse kAccumulatorUse[]; 735 static const AccumulatorUse kAccumulatorUse[];
746 static const bool kIsScalable[]; 736 static const bool kIsScalable[];
747 static const int kBytecodeSizes[][3]; 737 static const int kBytecodeSizes[][3];
748 static const OperandSize* const kOperandSizes[][3]; 738 static const OperandSize* const kOperandSizes[][3];
749 }; 739 };
750 740
751 // TODO(rmcilroy): Remove once we switch to MSVC 2015 which supports constexpr.
752 // See crbug.com/603131.
753 #undef CONSTEXPR
754
755 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, 741 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
756 const Bytecode& bytecode); 742 const Bytecode& bytecode);
757 743
758 } // namespace interpreter 744 } // namespace interpreter
759 } // namespace internal 745 } // namespace internal
760 } // namespace v8 746 } // namespace v8
761 747
762 #endif // V8_INTERPRETER_BYTECODES_H_ 748 #endif // V8_INTERPRETER_BYTECODES_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698