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

Side by Side Diff: test/unittests/interpreter/bytecode-array-builder-unittest.cc

Issue 2038083002: [Interpreter] Add a simple dead-code elimination bytecode optimizer. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@int_jump_writer
Patch Set: Fix tests Created 4 years, 6 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
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 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/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/interpreter/bytecode-array-builder.h" 7 #include "src/interpreter/bytecode-array-builder.h"
8 #include "src/interpreter/bytecode-array-iterator.h" 8 #include "src/interpreter/bytecode-array-iterator.h"
9 #include "src/interpreter/bytecode-label.h" 9 #include "src/interpreter/bytecode-label.h"
10 #include "src/interpreter/bytecode-register-allocator.h" 10 #include "src/interpreter/bytecode-register-allocator.h"
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 .CompareOperation(Token::Value::IN, reg); 164 .CompareOperation(Token::Value::IN, reg);
165 165
166 // Emit cast operator invocations. 166 // Emit cast operator invocations.
167 builder.CastAccumulatorToNumber() 167 builder.CastAccumulatorToNumber()
168 .CastAccumulatorToJSObject() 168 .CastAccumulatorToJSObject()
169 .CastAccumulatorToName(); 169 .CastAccumulatorToName();
170 170
171 // Emit control flow. Return must be the last instruction. 171 // Emit control flow. Return must be the last instruction.
172 BytecodeLabel start; 172 BytecodeLabel start;
173 builder.Bind(&start); 173 builder.Bind(&start);
174 // Short jumps with Imm8 operands 174 {
175 builder.Jump(&start) 175 // Short jumps with Imm8 operands
176 .JumpIfNull(&start) 176 BytecodeLabel after_jump;
177 .JumpIfUndefined(&start) 177 builder.Jump(&start)
178 .JumpIfNotHole(&start); 178 .Bind(&after_jump)
179 .JumpIfNull(&start)
180 .JumpIfUndefined(&start)
181 .JumpIfNotHole(&start);
182 }
179 183
180 // Longer jumps with constant operands 184 // Longer jumps with constant operands
181 BytecodeLabel end[8]; 185 BytecodeLabel end[8];
182 builder.Jump(&end[0]) 186 {
183 .LoadTrue() 187 BytecodeLabel after_jump;
184 .JumpIfTrue(&end[1]) 188 builder.Jump(&end[0])
185 .LoadTrue() 189 .Bind(&after_jump)
186 .JumpIfFalse(&end[2]) 190 .LoadTrue()
187 .LoadLiteral(Smi::FromInt(0)) 191 .JumpIfTrue(&end[1])
188 .JumpIfTrue(&end[3]) 192 .LoadTrue()
189 .LoadLiteral(Smi::FromInt(0)) 193 .JumpIfFalse(&end[2])
190 .JumpIfFalse(&end[4]) 194 .LoadLiteral(Smi::FromInt(0))
191 .JumpIfNull(&end[5]) 195 .JumpIfTrue(&end[3])
192 .JumpIfUndefined(&end[6]) 196 .LoadLiteral(Smi::FromInt(0))
193 .JumpIfNotHole(&end[7]); 197 .JumpIfFalse(&end[4])
198 .JumpIfNull(&end[5])
199 .JumpIfUndefined(&end[6])
200 .JumpIfNotHole(&end[7]);
201 }
194 202
195 // Perform an operation that returns boolean value to 203 // Perform an operation that returns boolean value to
196 // generate JumpIfTrue/False 204 // generate JumpIfTrue/False
197 builder.CompareOperation(Token::Value::EQ, reg) 205 builder.CompareOperation(Token::Value::EQ, reg)
198 .JumpIfTrue(&start) 206 .JumpIfTrue(&start)
199 .CompareOperation(Token::Value::EQ, reg) 207 .CompareOperation(Token::Value::EQ, reg)
200 .JumpIfFalse(&start); 208 .JumpIfFalse(&start);
201 // Perform an operation that returns a non-boolean operation to 209 // Perform an operation that returns a non-boolean operation to
202 // generate JumpIfToBooleanTrue/False. 210 // generate JumpIfToBooleanTrue/False.
203 builder.BinaryOperation(Token::Value::ADD, reg) 211 builder.BinaryOperation(Token::Value::ADD, reg)
204 .JumpIfTrue(&start) 212 .JumpIfTrue(&start)
205 .BinaryOperation(Token::Value::ADD, reg) 213 .BinaryOperation(Token::Value::ADD, reg)
206 .JumpIfFalse(&start); 214 .JumpIfFalse(&start);
207 // Insert dummy ops to force longer jumps 215 // Insert dummy ops to force longer jumps
208 for (int i = 0; i < 128; i++) { 216 for (int i = 0; i < 128; i++) {
209 builder.LoadTrue(); 217 builder.LoadTrue();
210 } 218 }
211 // Longer jumps requiring Constant operand 219 // Longer jumps requiring Constant operand
212 builder.Jump(&start).JumpIfNull(&start).JumpIfUndefined(&start).JumpIfNotHole( 220 {
213 &start); 221 BytecodeLabel after_jump;
214 // Perform an operation that returns boolean value to 222 builder.Jump(&start)
215 // generate JumpIfTrue/False 223 .Bind(&after_jump)
216 builder.CompareOperation(Token::Value::EQ, reg) 224 .JumpIfNull(&start)
217 .JumpIfTrue(&start) 225 .JumpIfUndefined(&start)
218 .CompareOperation(Token::Value::EQ, reg) 226 .JumpIfNotHole(&start);
219 .JumpIfFalse(&start); 227 // Perform an operation that returns boolean value to
220 // Perform an operation that returns a non-boolean operation to 228 // generate JumpIfTrue/False
221 // generate JumpIfToBooleanTrue/False. 229 builder.CompareOperation(Token::Value::EQ, reg)
222 builder.BinaryOperation(Token::Value::ADD, reg) 230 .JumpIfTrue(&start)
223 .JumpIfTrue(&start) 231 .CompareOperation(Token::Value::EQ, reg)
224 .BinaryOperation(Token::Value::ADD, reg) 232 .JumpIfFalse(&start);
225 .JumpIfFalse(&start); 233 // Perform an operation that returns a non-boolean operation to
234 // generate JumpIfToBooleanTrue/False.
235 builder.BinaryOperation(Token::Value::ADD, reg)
236 .JumpIfTrue(&start)
237 .BinaryOperation(Token::Value::ADD, reg)
238 .JumpIfFalse(&start);
239 }
226 240
227 // Emit stack check bytecode. 241 // Emit stack check bytecode.
228 builder.StackCheck(0); 242 builder.StackCheck(0);
229 243
230 // Emit throw and re-throw in it's own basic block so that the rest of the 244 // Emit throw and re-throw in it's own basic block so that the rest of the
231 // code isn't omitted due to being dead. 245 // code isn't omitted due to being dead.
232 BytecodeLabel after_throw; 246 BytecodeLabel after_throw;
233 builder.Jump(&after_throw).Throw().Bind(&after_throw); 247 builder.Throw().Bind(&after_throw);
234 BytecodeLabel after_rethrow; 248 BytecodeLabel after_rethrow;
235 builder.Jump(&after_rethrow).ReThrow().Bind(&after_rethrow); 249 builder.ReThrow().Bind(&after_rethrow);
236 250
237 builder.ForInPrepare(reg) 251 builder.ForInPrepare(reg)
238 .ForInDone(reg, reg) 252 .ForInDone(reg, reg)
239 .ForInNext(reg, reg, reg, 1) 253 .ForInNext(reg, reg, reg, 1)
240 .ForInStep(reg); 254 .ForInStep(reg);
241 builder.ForInPrepare(wide) 255 builder.ForInPrepare(wide)
242 .ForInDone(reg, other) 256 .ForInDone(reg, other)
243 .ForInNext(wide, wide, wide, 1024) 257 .ForInNext(wide, wide, wide, 1024)
244 .ForInStep(reg); 258 .ForInStep(reg);
245 259
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 false); 311 false);
298 builder.CreateClosure(shared_info2, NOT_TENURED); 312 builder.CreateClosure(shared_info2, NOT_TENURED);
299 313
300 // Emit wide variant of literal creation operations. 314 // Emit wide variant of literal creation operations.
301 builder.CreateRegExpLiteral(factory->NewStringFromStaticChars("wide_literal"), 315 builder.CreateRegExpLiteral(factory->NewStringFromStaticChars("wide_literal"),
302 0, 0) 316 0, 0)
303 .CreateArrayLiteral(factory->NewFixedArray(2), 0, 0) 317 .CreateArrayLiteral(factory->NewFixedArray(2), 0, 0)
304 .CreateObjectLiteral(factory->NewFixedArray(2), 0, 0); 318 .CreateObjectLiteral(factory->NewFixedArray(2), 0, 0);
305 319
306 // Longer jumps requiring ConstantWide operand 320 // Longer jumps requiring ConstantWide operand
307 builder.Jump(&start).JumpIfNull(&start).JumpIfUndefined(&start).JumpIfNotHole( 321 {
308 &start); 322 BytecodeLabel after_jump;
323 builder.Jump(&start)
324 .Bind(&after_jump)
325 .JumpIfNull(&start)
326 .JumpIfUndefined(&start)
327 .JumpIfNotHole(&start);
328 }
309 329
310 // Perform an operation that returns boolean value to 330 // Perform an operation that returns boolean value to
311 // generate JumpIfTrue/False 331 // generate JumpIfTrue/False
312 builder.CompareOperation(Token::Value::EQ, reg) 332 builder.CompareOperation(Token::Value::EQ, reg)
313 .JumpIfTrue(&start) 333 .JumpIfTrue(&start)
314 .CompareOperation(Token::Value::EQ, reg) 334 .CompareOperation(Token::Value::EQ, reg)
315 .JumpIfFalse(&start); 335 .JumpIfFalse(&start);
316 336
317 // Perform an operation that returns a non-boolean operation to 337 // Perform an operation that returns a non-boolean operation to
318 // generate JumpIfToBooleanTrue/False. 338 // generate JumpIfToBooleanTrue/False.
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 } 519 }
500 520
501 TEST_F(BytecodeArrayBuilderTest, ForwardJumps) { 521 TEST_F(BytecodeArrayBuilderTest, ForwardJumps) {
502 static const int kFarJumpDistance = 256; 522 static const int kFarJumpDistance = 256;
503 523
504 BytecodeArrayBuilder builder(isolate(), zone(), 0, 0, 1); 524 BytecodeArrayBuilder builder(isolate(), zone(), 0, 0, 1);
505 525
506 Register reg(0); 526 Register reg(0);
507 BytecodeLabel far0, far1, far2, far3, far4; 527 BytecodeLabel far0, far1, far2, far3, far4;
508 BytecodeLabel near0, near1, near2, near3, near4; 528 BytecodeLabel near0, near1, near2, near3, near4;
529 BytecodeLabel after_jump0, after_jump1;
509 530
510 builder.Jump(&near0) 531 builder.Jump(&near0)
532 .Bind(&after_jump0)
511 .CompareOperation(Token::Value::EQ, reg) 533 .CompareOperation(Token::Value::EQ, reg)
512 .JumpIfTrue(&near1) 534 .JumpIfTrue(&near1)
513 .CompareOperation(Token::Value::EQ, reg) 535 .CompareOperation(Token::Value::EQ, reg)
514 .JumpIfFalse(&near2) 536 .JumpIfFalse(&near2)
515 .BinaryOperation(Token::Value::ADD, reg) 537 .BinaryOperation(Token::Value::ADD, reg)
516 .JumpIfTrue(&near3) 538 .JumpIfTrue(&near3)
517 .BinaryOperation(Token::Value::ADD, reg) 539 .BinaryOperation(Token::Value::ADD, reg)
518 .JumpIfFalse(&near4) 540 .JumpIfFalse(&near4)
519 .Bind(&near0) 541 .Bind(&near0)
520 .Bind(&near1) 542 .Bind(&near1)
521 .Bind(&near2) 543 .Bind(&near2)
522 .Bind(&near3) 544 .Bind(&near3)
523 .Bind(&near4) 545 .Bind(&near4)
524 .Jump(&far0) 546 .Jump(&far0)
547 .Bind(&after_jump1)
525 .CompareOperation(Token::Value::EQ, reg) 548 .CompareOperation(Token::Value::EQ, reg)
526 .JumpIfTrue(&far1) 549 .JumpIfTrue(&far1)
527 .CompareOperation(Token::Value::EQ, reg) 550 .CompareOperation(Token::Value::EQ, reg)
528 .JumpIfFalse(&far2) 551 .JumpIfFalse(&far2)
529 .BinaryOperation(Token::Value::ADD, reg) 552 .BinaryOperation(Token::Value::ADD, reg)
530 .JumpIfTrue(&far3) 553 .JumpIfTrue(&far3)
531 .BinaryOperation(Token::Value::ADD, reg) 554 .BinaryOperation(Token::Value::ADD, reg)
532 .JumpIfFalse(&far4); 555 .JumpIfFalse(&far4);
533 for (int i = 0; i < kFarJumpDistance - 18; i++) { 556 for (int i = 0; i < kFarJumpDistance - 18; i++) {
534 builder.Debugger(); 557 builder.Debugger();
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
630 .Bind(&label2) 653 .Bind(&label2)
631 .CompareOperation(Token::Value::EQ, reg) 654 .CompareOperation(Token::Value::EQ, reg)
632 .JumpIfFalse(&label2) 655 .JumpIfFalse(&label2)
633 .Bind(&label3) 656 .Bind(&label3)
634 .BinaryOperation(Token::Value::ADD, reg) 657 .BinaryOperation(Token::Value::ADD, reg)
635 .JumpIfTrue(&label3) 658 .JumpIfTrue(&label3)
636 .Bind(&label4) 659 .Bind(&label4)
637 .BinaryOperation(Token::Value::ADD, reg) 660 .BinaryOperation(Token::Value::ADD, reg)
638 .JumpIfFalse(&label4); 661 .JumpIfFalse(&label4);
639 for (int i = 0; i < 63; i++) { 662 for (int i = 0; i < 63; i++) {
640 builder.Jump(&label4); 663 BytecodeLabel after_jump;
664 builder.Jump(&label4).Bind(&after_jump);
641 } 665 }
642 666
643 // Add padding to force wide backwards jumps. 667 // Add padding to force wide backwards jumps.
644 for (int i = 0; i < 256; i++) { 668 for (int i = 0; i < 256; i++) {
645 builder.Debugger(); 669 builder.Debugger();
646 } 670 }
647 671
648 builder.BinaryOperation(Token::Value::ADD, reg).JumpIfFalse(&label4); 672 builder.BinaryOperation(Token::Value::ADD, reg).JumpIfFalse(&label4);
649 builder.BinaryOperation(Token::Value::ADD, reg).JumpIfTrue(&label3); 673 builder.BinaryOperation(Token::Value::ADD, reg).JumpIfTrue(&label3);
650 builder.CompareOperation(Token::Value::EQ, reg).JumpIfFalse(&label2); 674 builder.CompareOperation(Token::Value::EQ, reg).JumpIfFalse(&label2);
651 builder.CompareOperation(Token::Value::EQ, reg).JumpIfTrue(&label1); 675 builder.CompareOperation(Token::Value::EQ, reg).JumpIfTrue(&label1);
652 builder.Jump(&label0); 676 builder.Jump(&label0);
677 BytecodeLabel end;
678 builder.Bind(&end);
653 builder.Return(); 679 builder.Return();
654 680
655 Handle<BytecodeArray> array = builder.ToBytecodeArray(); 681 Handle<BytecodeArray> array = builder.ToBytecodeArray();
656 BytecodeArrayIterator iterator(array); 682 BytecodeArrayIterator iterator(array);
657 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); 683 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
658 CHECK_EQ(iterator.GetImmediateOperand(0), 0); 684 CHECK_EQ(iterator.GetImmediateOperand(0), 0);
659 iterator.Advance(); 685 iterator.Advance();
660 // Ignore compare operation. 686 // Ignore compare operation.
661 iterator.Advance(); 687 iterator.Advance();
662 CHECK_EQ(iterator.current_bytecode(), 688 CHECK_EQ(iterator.current_bytecode(),
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
728 iterator.Advance(); 754 iterator.Advance();
729 CHECK(iterator.done()); 755 CHECK(iterator.done());
730 } 756 }
731 757
732 758
733 TEST_F(BytecodeArrayBuilderTest, LabelReuse) { 759 TEST_F(BytecodeArrayBuilderTest, LabelReuse) {
734 BytecodeArrayBuilder builder(isolate(), zone(), 0, 0, 0); 760 BytecodeArrayBuilder builder(isolate(), zone(), 0, 0, 0);
735 761
736 // Labels can only have 1 forward reference, but 762 // Labels can only have 1 forward reference, but
737 // can be referred to mulitple times once bound. 763 // can be referred to mulitple times once bound.
738 BytecodeLabel label; 764 BytecodeLabel label, after_jump0, after_jump1;
739 765
740 builder.Jump(&label).Bind(&label).Jump(&label).Jump(&label).Return(); 766 builder.Jump(&label)
767 .Bind(&label)
768 .Jump(&label)
769 .Bind(&after_jump0)
770 .Jump(&label)
771 .Bind(&after_jump1)
772 .Return();
741 773
742 Handle<BytecodeArray> array = builder.ToBytecodeArray(); 774 Handle<BytecodeArray> array = builder.ToBytecodeArray();
743 BytecodeArrayIterator iterator(array); 775 BytecodeArrayIterator iterator(array);
744 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); 776 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
745 CHECK_EQ(iterator.GetImmediateOperand(0), 2); 777 CHECK_EQ(iterator.GetImmediateOperand(0), 2);
746 iterator.Advance(); 778 iterator.Advance();
747 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); 779 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
748 CHECK_EQ(iterator.GetImmediateOperand(0), 0); 780 CHECK_EQ(iterator.GetImmediateOperand(0), 0);
749 iterator.Advance(); 781 iterator.Advance();
750 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); 782 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
751 CHECK_EQ(iterator.GetImmediateOperand(0), -2); 783 CHECK_EQ(iterator.GetImmediateOperand(0), -2);
752 iterator.Advance(); 784 iterator.Advance();
753 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); 785 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn);
754 iterator.Advance(); 786 iterator.Advance();
755 CHECK(iterator.done()); 787 CHECK(iterator.done());
756 } 788 }
757 789
758 790
759 TEST_F(BytecodeArrayBuilderTest, LabelAddressReuse) { 791 TEST_F(BytecodeArrayBuilderTest, LabelAddressReuse) {
760 static const int kRepeats = 3; 792 static const int kRepeats = 3;
761 793
762 BytecodeArrayBuilder builder(isolate(), zone(), 0, 0, 0); 794 BytecodeArrayBuilder builder(isolate(), zone(), 0, 0, 0);
763 for (int i = 0; i < kRepeats; i++) { 795 for (int i = 0; i < kRepeats; i++) {
764 BytecodeLabel label; 796 BytecodeLabel label, after_jump0, after_jump1;
765 builder.Jump(&label).Bind(&label).Jump(&label).Jump(&label); 797 builder.Jump(&label)
798 .Bind(&label)
799 .Jump(&label)
800 .Bind(&after_jump0)
801 .Jump(&label)
802 .Bind(&after_jump1);
766 } 803 }
767 builder.Return(); 804 builder.Return();
768 805
769 Handle<BytecodeArray> array = builder.ToBytecodeArray(); 806 Handle<BytecodeArray> array = builder.ToBytecodeArray();
770 BytecodeArrayIterator iterator(array); 807 BytecodeArrayIterator iterator(array);
771 for (int i = 0; i < kRepeats; i++) { 808 for (int i = 0; i < kRepeats; i++) {
772 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); 809 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
773 CHECK_EQ(iterator.GetImmediateOperand(0), 2); 810 CHECK_EQ(iterator.GetImmediateOperand(0), 2);
774 iterator.Advance(); 811 iterator.Advance();
775 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); 812 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
776 CHECK_EQ(iterator.GetImmediateOperand(0), 0); 813 CHECK_EQ(iterator.GetImmediateOperand(0), 0);
777 iterator.Advance(); 814 iterator.Advance();
778 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); 815 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
779 CHECK_EQ(iterator.GetImmediateOperand(0), -2); 816 CHECK_EQ(iterator.GetImmediateOperand(0), -2);
780 iterator.Advance(); 817 iterator.Advance();
781 } 818 }
782 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); 819 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn);
783 iterator.Advance(); 820 iterator.Advance();
784 CHECK(iterator.done()); 821 CHECK(iterator.done());
785 } 822 }
786 823
787 } // namespace interpreter 824 } // namespace interpreter
788 } // namespace internal 825 } // namespace internal
789 } // namespace v8 826 } // namespace v8
OLDNEW
« no previous file with comments | « test/unittests/BUILD.gn ('k') | test/unittests/interpreter/bytecode-dead-code-optimizer-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698