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 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 OperandType::kIdx) \ | 200 OperandType::kIdx) \ |
201 V(TestGreaterThan, AccumulatorUse::kReadWrite, OperandType::kReg, \ | 201 V(TestGreaterThan, AccumulatorUse::kReadWrite, OperandType::kReg, \ |
202 OperandType::kIdx) \ | 202 OperandType::kIdx) \ |
203 V(TestLessThanOrEqual, AccumulatorUse::kReadWrite, OperandType::kReg, \ | 203 V(TestLessThanOrEqual, AccumulatorUse::kReadWrite, OperandType::kReg, \ |
204 OperandType::kIdx) \ | 204 OperandType::kIdx) \ |
205 V(TestGreaterThanOrEqual, AccumulatorUse::kReadWrite, OperandType::kReg, \ | 205 V(TestGreaterThanOrEqual, AccumulatorUse::kReadWrite, OperandType::kReg, \ |
206 OperandType::kIdx) \ | 206 OperandType::kIdx) \ |
207 V(TestEqualStrictNoFeedback, AccumulatorUse::kReadWrite, OperandType::kReg) \ | 207 V(TestEqualStrictNoFeedback, AccumulatorUse::kReadWrite, OperandType::kReg) \ |
208 V(TestInstanceOf, AccumulatorUse::kReadWrite, OperandType::kReg) \ | 208 V(TestInstanceOf, AccumulatorUse::kReadWrite, OperandType::kReg) \ |
209 V(TestIn, AccumulatorUse::kReadWrite, OperandType::kReg) \ | 209 V(TestIn, AccumulatorUse::kReadWrite, OperandType::kReg) \ |
210 V(TestUndetectable, AccumulatorUse::kWrite, OperandType::kReg) \ | 210 V(TestUndetectable, AccumulatorUse::kReadWrite) \ |
211 V(TestNull, AccumulatorUse::kWrite, OperandType::kReg) \ | 211 V(TestNull, AccumulatorUse::kReadWrite) \ |
212 V(TestUndefined, AccumulatorUse::kWrite, OperandType::kReg) \ | 212 V(TestUndefined, AccumulatorUse::kReadWrite) \ |
213 V(TestTypeOf, AccumulatorUse::kReadWrite, OperandType::kFlag8) \ | 213 V(TestTypeOf, AccumulatorUse::kReadWrite, OperandType::kFlag8) \ |
214 \ | 214 \ |
215 /* Cast operators */ \ | 215 /* Cast operators */ \ |
216 V(ToName, AccumulatorUse::kRead, OperandType::kRegOut) \ | 216 V(ToName, AccumulatorUse::kRead, OperandType::kRegOut) \ |
217 V(ToNumber, AccumulatorUse::kRead, OperandType::kRegOut) \ | 217 V(ToNumber, AccumulatorUse::kRead, OperandType::kRegOut) \ |
218 V(ToObject, AccumulatorUse::kRead, OperandType::kRegOut) \ | 218 V(ToObject, AccumulatorUse::kRead, OperandType::kRegOut) \ |
219 \ | 219 \ |
220 /* Literals */ \ | 220 /* Literals */ \ |
221 V(CreateRegExpLiteral, AccumulatorUse::kWrite, OperandType::kIdx, \ | 221 V(CreateRegExpLiteral, AccumulatorUse::kWrite, OperandType::kIdx, \ |
222 OperandType::kIdx, OperandType::kFlag8) \ | 222 OperandType::kIdx, OperandType::kFlag8) \ |
(...skipping 23 matching lines...) Expand all Loading... |
246 /* Control Flow -- carefully ordered for efficient checks */ \ | 246 /* Control Flow -- carefully ordered for efficient checks */ \ |
247 /* - [Unconditional jumps] */ \ | 247 /* - [Unconditional jumps] */ \ |
248 V(JumpLoop, AccumulatorUse::kNone, OperandType::kUImm, OperandType::kImm) \ | 248 V(JumpLoop, AccumulatorUse::kNone, OperandType::kUImm, OperandType::kImm) \ |
249 /* - [Forward jumps] */ \ | 249 /* - [Forward jumps] */ \ |
250 V(Jump, AccumulatorUse::kNone, OperandType::kUImm) \ | 250 V(Jump, AccumulatorUse::kNone, OperandType::kUImm) \ |
251 /* - [Start constant jumps] */ \ | 251 /* - [Start constant jumps] */ \ |
252 V(JumpConstant, AccumulatorUse::kNone, OperandType::kIdx) \ | 252 V(JumpConstant, AccumulatorUse::kNone, OperandType::kIdx) \ |
253 /* - [Conditional jumps] */ \ | 253 /* - [Conditional jumps] */ \ |
254 /* - [Conditional constant jumps] */ \ | 254 /* - [Conditional constant jumps] */ \ |
255 V(JumpIfNullConstant, AccumulatorUse::kRead, OperandType::kIdx) \ | 255 V(JumpIfNullConstant, AccumulatorUse::kRead, OperandType::kIdx) \ |
| 256 V(JumpIfNotNullConstant, AccumulatorUse::kRead, OperandType::kIdx) \ |
256 V(JumpIfUndefinedConstant, AccumulatorUse::kRead, OperandType::kIdx) \ | 257 V(JumpIfUndefinedConstant, AccumulatorUse::kRead, OperandType::kIdx) \ |
| 258 V(JumpIfNotUndefinedConstant, AccumulatorUse::kRead, OperandType::kIdx) \ |
257 V(JumpIfTrueConstant, AccumulatorUse::kRead, OperandType::kIdx) \ | 259 V(JumpIfTrueConstant, AccumulatorUse::kRead, OperandType::kIdx) \ |
258 V(JumpIfFalseConstant, AccumulatorUse::kRead, OperandType::kIdx) \ | 260 V(JumpIfFalseConstant, AccumulatorUse::kRead, OperandType::kIdx) \ |
259 V(JumpIfJSReceiverConstant, AccumulatorUse::kRead, OperandType::kIdx) \ | 261 V(JumpIfJSReceiverConstant, AccumulatorUse::kRead, OperandType::kIdx) \ |
260 V(JumpIfNotHoleConstant, AccumulatorUse::kRead, OperandType::kIdx) \ | 262 V(JumpIfNotHoleConstant, AccumulatorUse::kRead, OperandType::kIdx) \ |
261 /* - [Start ToBoolean jumps] */ \ | 263 /* - [Start ToBoolean jumps] */ \ |
262 V(JumpIfToBooleanTrueConstant, AccumulatorUse::kRead, OperandType::kIdx) \ | 264 V(JumpIfToBooleanTrueConstant, AccumulatorUse::kRead, OperandType::kIdx) \ |
263 V(JumpIfToBooleanFalseConstant, AccumulatorUse::kRead, OperandType::kIdx) \ | 265 V(JumpIfToBooleanFalseConstant, AccumulatorUse::kRead, OperandType::kIdx) \ |
264 /* - [End constant jumps] */ \ | 266 /* - [End constant jumps] */ \ |
265 /* - [Conditional immediate jumps] */ \ | 267 /* - [Conditional immediate jumps] */ \ |
266 V(JumpIfToBooleanTrue, AccumulatorUse::kRead, OperandType::kUImm) \ | 268 V(JumpIfToBooleanTrue, AccumulatorUse::kRead, OperandType::kUImm) \ |
267 V(JumpIfToBooleanFalse, AccumulatorUse::kRead, OperandType::kUImm) \ | 269 V(JumpIfToBooleanFalse, AccumulatorUse::kRead, OperandType::kUImm) \ |
268 /* - [End ToBoolean jumps] */ \ | 270 /* - [End ToBoolean jumps] */ \ |
269 V(JumpIfTrue, AccumulatorUse::kRead, OperandType::kUImm) \ | 271 V(JumpIfTrue, AccumulatorUse::kRead, OperandType::kUImm) \ |
270 V(JumpIfFalse, AccumulatorUse::kRead, OperandType::kUImm) \ | 272 V(JumpIfFalse, AccumulatorUse::kRead, OperandType::kUImm) \ |
271 V(JumpIfNull, AccumulatorUse::kRead, OperandType::kUImm) \ | 273 V(JumpIfNull, AccumulatorUse::kRead, OperandType::kUImm) \ |
| 274 V(JumpIfNotNull, AccumulatorUse::kRead, OperandType::kUImm) \ |
272 V(JumpIfUndefined, AccumulatorUse::kRead, OperandType::kUImm) \ | 275 V(JumpIfUndefined, AccumulatorUse::kRead, OperandType::kUImm) \ |
| 276 V(JumpIfNotUndefined, AccumulatorUse::kRead, OperandType::kUImm) \ |
273 V(JumpIfJSReceiver, AccumulatorUse::kRead, OperandType::kUImm) \ | 277 V(JumpIfJSReceiver, AccumulatorUse::kRead, OperandType::kUImm) \ |
274 V(JumpIfNotHole, AccumulatorUse::kRead, OperandType::kUImm) \ | 278 V(JumpIfNotHole, AccumulatorUse::kRead, OperandType::kUImm) \ |
275 \ | 279 \ |
276 /* Complex flow control For..in */ \ | 280 /* Complex flow control For..in */ \ |
277 V(ForInPrepare, AccumulatorUse::kNone, OperandType::kReg, \ | 281 V(ForInPrepare, AccumulatorUse::kNone, OperandType::kReg, \ |
278 OperandType::kRegOutTriple) \ | 282 OperandType::kRegOutTriple) \ |
279 V(ForInContinue, AccumulatorUse::kWrite, OperandType::kReg, \ | 283 V(ForInContinue, AccumulatorUse::kWrite, OperandType::kReg, \ |
280 OperandType::kReg) \ | 284 OperandType::kReg) \ |
281 V(ForInNext, AccumulatorUse::kWrite, OperandType::kReg, OperandType::kReg, \ | 285 V(ForInNext, AccumulatorUse::kWrite, OperandType::kReg, OperandType::kReg, \ |
282 OperandType::kRegPair, OperandType::kIdx) \ | 286 OperandType::kRegPair, OperandType::kIdx) \ |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
356 | 360 |
357 #define JUMP_TOBOOLEAN_CONDITIONAL_CONSTANT_BYTECODE_LIST(V) \ | 361 #define JUMP_TOBOOLEAN_CONDITIONAL_CONSTANT_BYTECODE_LIST(V) \ |
358 V(JumpIfToBooleanTrueConstant) \ | 362 V(JumpIfToBooleanTrueConstant) \ |
359 V(JumpIfToBooleanFalseConstant) | 363 V(JumpIfToBooleanFalseConstant) |
360 | 364 |
361 #define JUMP_CONDITIONAL_IMMEDIATE_BYTECODE_LIST(V) \ | 365 #define JUMP_CONDITIONAL_IMMEDIATE_BYTECODE_LIST(V) \ |
362 JUMP_TOBOOLEAN_CONDITIONAL_IMMEDIATE_BYTECODE_LIST(V) \ | 366 JUMP_TOBOOLEAN_CONDITIONAL_IMMEDIATE_BYTECODE_LIST(V) \ |
363 V(JumpIfTrue) \ | 367 V(JumpIfTrue) \ |
364 V(JumpIfFalse) \ | 368 V(JumpIfFalse) \ |
365 V(JumpIfNull) \ | 369 V(JumpIfNull) \ |
| 370 V(JumpIfNotNull) \ |
366 V(JumpIfUndefined) \ | 371 V(JumpIfUndefined) \ |
| 372 V(JumpIfNotUndefined) \ |
367 V(JumpIfJSReceiver) \ | 373 V(JumpIfJSReceiver) \ |
368 V(JumpIfNotHole) | 374 V(JumpIfNotHole) |
369 | 375 |
370 #define JUMP_CONDITIONAL_CONSTANT_BYTECODE_LIST(V) \ | 376 #define JUMP_CONDITIONAL_CONSTANT_BYTECODE_LIST(V) \ |
371 JUMP_TOBOOLEAN_CONDITIONAL_CONSTANT_BYTECODE_LIST(V) \ | 377 JUMP_TOBOOLEAN_CONDITIONAL_CONSTANT_BYTECODE_LIST(V) \ |
372 V(JumpIfNullConstant) \ | 378 V(JumpIfNullConstant) \ |
| 379 V(JumpIfNotNullConstant) \ |
373 V(JumpIfUndefinedConstant) \ | 380 V(JumpIfUndefinedConstant) \ |
| 381 V(JumpIfNotUndefinedConstant) \ |
374 V(JumpIfTrueConstant) \ | 382 V(JumpIfTrueConstant) \ |
375 V(JumpIfFalseConstant) \ | 383 V(JumpIfFalseConstant) \ |
376 V(JumpIfJSReceiverConstant) \ | 384 V(JumpIfJSReceiverConstant) \ |
377 V(JumpIfNotHoleConstant) | 385 V(JumpIfNotHoleConstant) |
378 | 386 |
379 #define JUMP_CONSTANT_BYTECODE_LIST(V) \ | 387 #define JUMP_CONSTANT_BYTECODE_LIST(V) \ |
380 JUMP_UNCONDITIONAL_CONSTANT_BYTECODE_LIST(V) \ | 388 JUMP_UNCONDITIONAL_CONSTANT_BYTECODE_LIST(V) \ |
381 JUMP_CONDITIONAL_CONSTANT_BYTECODE_LIST(V) | 389 JUMP_CONDITIONAL_CONSTANT_BYTECODE_LIST(V) |
382 | 390 |
383 #define JUMP_IMMEDIATE_BYTECODE_LIST(V) \ | 391 #define JUMP_IMMEDIATE_BYTECODE_LIST(V) \ |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
527 bytecode == Bytecode::kLdaTrue || bytecode == Bytecode::kLdaFalse || | 535 bytecode == Bytecode::kLdaTrue || bytecode == Bytecode::kLdaFalse || |
528 bytecode == Bytecode::kLdaUndefined || | 536 bytecode == Bytecode::kLdaUndefined || |
529 bytecode == Bytecode::kLdaTheHole || | 537 bytecode == Bytecode::kLdaTheHole || |
530 bytecode == Bytecode::kLdaConstant || | 538 bytecode == Bytecode::kLdaConstant || |
531 bytecode == Bytecode::kLdaContextSlot || | 539 bytecode == Bytecode::kLdaContextSlot || |
532 bytecode == Bytecode::kLdaCurrentContextSlot || | 540 bytecode == Bytecode::kLdaCurrentContextSlot || |
533 bytecode == Bytecode::kLdaImmutableContextSlot || | 541 bytecode == Bytecode::kLdaImmutableContextSlot || |
534 bytecode == Bytecode::kLdaImmutableCurrentContextSlot; | 542 bytecode == Bytecode::kLdaImmutableCurrentContextSlot; |
535 } | 543 } |
536 | 544 |
| 545 // Returns true if |bytecode| is a compare operation without external effects |
| 546 // (e.g., Type cooersion). |
| 547 static constexpr bool IsCompareWithoutEffects(Bytecode bytecode) { |
| 548 return bytecode == Bytecode::kTestUndetectable || |
| 549 bytecode == Bytecode::kTestNull || |
| 550 bytecode == Bytecode::kTestUndefined || |
| 551 bytecode == Bytecode::kTestTypeOf; |
| 552 } |
| 553 |
537 // Return true if |bytecode| is a register load without effects, | 554 // Return true if |bytecode| is a register load without effects, |
538 // e.g. Mov, Star. | 555 // e.g. Mov, Star. |
539 static constexpr bool IsRegisterLoadWithoutEffects(Bytecode bytecode) { | 556 static constexpr bool IsRegisterLoadWithoutEffects(Bytecode bytecode) { |
540 return bytecode == Bytecode::kMov || bytecode == Bytecode::kPopContext || | 557 return bytecode == Bytecode::kMov || bytecode == Bytecode::kPopContext || |
541 bytecode == Bytecode::kPushContext || bytecode == Bytecode::kStar; | 558 bytecode == Bytecode::kPushContext || bytecode == Bytecode::kStar; |
542 } | 559 } |
543 | 560 |
544 // Returns true if the bytecode is a conditional jump taking | 561 // Returns true if the bytecode is a conditional jump taking |
545 // an immediate byte operand (OperandType::kImm). | 562 // an immediate byte operand (OperandType::kImm). |
546 static constexpr bool IsConditionalJumpImmediate(Bytecode bytecode) { | 563 static constexpr bool IsConditionalJumpImmediate(Bytecode bytecode) { |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
612 // JumpIfTrueToBoolean. | 629 // JumpIfTrueToBoolean. |
613 static constexpr bool IsJumpWithoutEffects(Bytecode bytecode) { | 630 static constexpr bool IsJumpWithoutEffects(Bytecode bytecode) { |
614 return IsJump(bytecode) && !IsJumpIfToBoolean(bytecode); | 631 return IsJump(bytecode) && !IsJumpIfToBoolean(bytecode); |
615 } | 632 } |
616 | 633 |
617 // Returns true if |bytecode| has no effects. These bytecodes only manipulate | 634 // Returns true if |bytecode| has no effects. These bytecodes only manipulate |
618 // interpreter frame state and will never throw. | 635 // interpreter frame state and will never throw. |
619 static constexpr bool IsWithoutExternalSideEffects(Bytecode bytecode) { | 636 static constexpr bool IsWithoutExternalSideEffects(Bytecode bytecode) { |
620 return (IsAccumulatorLoadWithoutEffects(bytecode) || | 637 return (IsAccumulatorLoadWithoutEffects(bytecode) || |
621 IsRegisterLoadWithoutEffects(bytecode) || | 638 IsRegisterLoadWithoutEffects(bytecode) || |
622 bytecode == Bytecode::kNop || IsJumpWithoutEffects(bytecode)); | 639 IsCompareWithoutEffects(bytecode) || bytecode == Bytecode::kNop || |
| 640 IsJumpWithoutEffects(bytecode)); |
623 } | 641 } |
624 | 642 |
625 // Returns true if the bytecode is Ldar or Star. | 643 // Returns true if the bytecode is Ldar or Star. |
626 static constexpr bool IsLdarOrStar(Bytecode bytecode) { | 644 static constexpr bool IsLdarOrStar(Bytecode bytecode) { |
627 return bytecode == Bytecode::kLdar || bytecode == Bytecode::kStar; | 645 return bytecode == Bytecode::kLdar || bytecode == Bytecode::kStar; |
628 } | 646 } |
629 | 647 |
630 // Returns true if |bytecode| puts a name in the accumulator. | 648 // Returns true if |bytecode| puts a name in the accumulator. |
631 static constexpr bool PutsNameInAccumulator(Bytecode bytecode) { | 649 static constexpr bool PutsNameInAccumulator(Bytecode bytecode) { |
632 return bytecode == Bytecode::kTypeOf; | 650 return bytecode == Bytecode::kTypeOf; |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
855 }; | 873 }; |
856 | 874 |
857 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, | 875 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, |
858 const Bytecode& bytecode); | 876 const Bytecode& bytecode); |
859 | 877 |
860 } // namespace interpreter | 878 } // namespace interpreter |
861 } // namespace internal | 879 } // namespace internal |
862 } // namespace v8 | 880 } // namespace v8 |
863 | 881 |
864 #endif // V8_INTERPRETER_BYTECODES_H_ | 882 #endif // V8_INTERPRETER_BYTECODES_H_ |
OLD | NEW |