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

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

Issue 2793923002: [Interpreter] Optimize code of the form 'if (x === undefined)'. (Closed)
Patch Set: Rebase Created 3 years, 8 months 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
« no previous file with comments | « src/interpreter/bytecode-peephole-table.h ('k') | src/interpreter/interpreter-generator.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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_
OLDNEW
« no previous file with comments | « src/interpreter/bytecode-peephole-table.h ('k') | src/interpreter/interpreter-generator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698