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

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

Issue 1426913002: [Interpreter] Merges ToBoolean and JumpIfTrue/False bytecodes (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: rebased the patch and used the new Repeat_32 macro for tests Created 5 years, 1 month 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 | « test/cctest/interpreter/test-interpreter.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "test/unittests/test-utils.h" 9 #include "test/unittests/test-utils.h"
10 10
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 builder.CastAccumulatorToNumber() 143 builder.CastAccumulatorToNumber()
144 .CastAccumulatorToBoolean() 144 .CastAccumulatorToBoolean()
145 .CastAccumulatorToJSObject() 145 .CastAccumulatorToJSObject()
146 .CastAccumulatorToName(); 146 .CastAccumulatorToName();
147 147
148 // Emit control flow. Return must be the last instruction. 148 // Emit control flow. Return must be the last instruction.
149 BytecodeLabel start; 149 BytecodeLabel start;
150 builder.Bind(&start); 150 builder.Bind(&start);
151 // Short jumps with Imm8 operands 151 // Short jumps with Imm8 operands
152 builder.Jump(&start) 152 builder.Jump(&start)
153 .JumpIfTrue(&start)
154 .JumpIfFalse(&start)
155 .JumpIfToBooleanTrue(&start)
156 .JumpIfToBooleanFalse(&start)
157 .JumpIfNull(&start) 153 .JumpIfNull(&start)
158 .JumpIfUndefined(&start); 154 .JumpIfUndefined(&start);
159 155 // Perform an operation that returns boolean value to
156 // generate JumpIfTrue/False
157 builder.CompareOperation(Token::Value::EQ, reg, Strength::WEAK)
158 .JumpIfTrue(&start)
159 .CompareOperation(Token::Value::EQ, reg, Strength::WEAK)
160 .JumpIfFalse(&start);
161 // Perform an operation that returns a non-boolean operation to
162 // generate JumpIfToBooleanTrue/False.
163 builder.BinaryOperation(Token::Value::ADD, reg, Strength::WEAK)
164 .JumpIfTrue(&start)
165 .BinaryOperation(Token::Value::ADD, reg, Strength::WEAK)
166 .JumpIfFalse(&start);
160 // Insert dummy ops to force longer jumps 167 // Insert dummy ops to force longer jumps
161 for (int i = 0; i < 128; i++) { 168 for (int i = 0; i < 128; i++) {
162 builder.LoadTrue(); 169 builder.LoadTrue();
163 } 170 }
164 // Longer jumps requiring Constant operand 171 // Longer jumps requiring Constant operand
165 builder.Jump(&start) 172 builder.Jump(&start)
166 .JumpIfTrue(&start)
167 .JumpIfFalse(&start)
168 .JumpIfToBooleanTrue(&start)
169 .JumpIfToBooleanFalse(&start)
170 .JumpIfNull(&start) 173 .JumpIfNull(&start)
171 .JumpIfUndefined(&start); 174 .JumpIfUndefined(&start);
175 // Perform an operation that returns boolean value to
176 // generate JumpIfTrue/False
177 builder.CompareOperation(Token::Value::EQ, reg, Strength::WEAK)
178 .JumpIfTrue(&start)
179 .CompareOperation(Token::Value::EQ, reg, Strength::WEAK)
180 .JumpIfFalse(&start);
181 // Perform an operation that returns a non-boolean operation to
182 // generate JumpIfToBooleanTrue/False.
183 builder.BinaryOperation(Token::Value::ADD, reg, Strength::WEAK)
184 .JumpIfTrue(&start)
185 .BinaryOperation(Token::Value::ADD, reg, Strength::WEAK)
186 .JumpIfFalse(&start);
172 187
173 builder.EnterBlock() 188 builder.EnterBlock()
174 .Throw() 189 .Throw()
175 .LeaveBlock(); 190 .LeaveBlock();
176 191
177 builder.ForInPrepare(reg).ForInDone(reg).ForInNext(reg, reg); 192 builder.ForInPrepare(reg).ForInDone(reg).ForInNext(reg, reg);
178 193
179 // Wide constant pool loads 194 // Wide constant pool loads
180 for (int i = 0; i < 256; i++) { 195 for (int i = 0; i < 256; i++) {
181 // Emit junk in constant pool to force wide constant pool index. 196 // Emit junk in constant pool to force wide constant pool index.
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 // Should only have one entry for each identical constant. 353 // Should only have one entry for each identical constant.
339 CHECK_EQ(array->constant_pool()->length(), 3); 354 CHECK_EQ(array->constant_pool()->length(), 3);
340 } 355 }
341 356
342 357
343 TEST_F(BytecodeArrayBuilderTest, ForwardJumps) { 358 TEST_F(BytecodeArrayBuilderTest, ForwardJumps) {
344 static const int kFarJumpDistance = 256; 359 static const int kFarJumpDistance = 256;
345 360
346 BytecodeArrayBuilder builder(isolate(), zone()); 361 BytecodeArrayBuilder builder(isolate(), zone());
347 builder.set_parameter_count(0); 362 builder.set_parameter_count(0);
348 builder.set_locals_count(0); 363 builder.set_locals_count(1);
349 builder.set_context_count(0); 364 builder.set_context_count(0);
350 365
351 BytecodeLabel far0, far1, far2; 366 Register reg(0);
352 BytecodeLabel near0, near1, near2; 367 BytecodeLabel far0, far1, far2, far3, far4;
368 BytecodeLabel near0, near1, near2, near3, near4;
353 369
354 builder.Jump(&near0) 370 builder.Jump(&near0)
371 .CompareOperation(Token::Value::EQ, reg, Strength::WEAK)
355 .JumpIfTrue(&near1) 372 .JumpIfTrue(&near1)
373 .CompareOperation(Token::Value::EQ, reg, Strength::WEAK)
356 .JumpIfFalse(&near2) 374 .JumpIfFalse(&near2)
375 .BinaryOperation(Token::Value::ADD, reg, Strength::WEAK)
376 .JumpIfTrue(&near3)
377 .BinaryOperation(Token::Value::ADD, reg, Strength::WEAK)
378 .JumpIfFalse(&near4)
357 .Bind(&near0) 379 .Bind(&near0)
358 .Bind(&near1) 380 .Bind(&near1)
359 .Bind(&near2) 381 .Bind(&near2)
382 .Bind(&near3)
383 .Bind(&near4)
360 .Jump(&far0) 384 .Jump(&far0)
385 .CompareOperation(Token::Value::EQ, reg, Strength::WEAK)
361 .JumpIfTrue(&far1) 386 .JumpIfTrue(&far1)
362 .JumpIfFalse(&far2); 387 .CompareOperation(Token::Value::EQ, reg, Strength::WEAK)
363 for (int i = 0; i < kFarJumpDistance - 6; i++) { 388 .JumpIfFalse(&far2)
389 .BinaryOperation(Token::Value::ADD, reg, Strength::WEAK)
390 .JumpIfTrue(&far3)
391 .BinaryOperation(Token::Value::ADD, reg, Strength::WEAK)
392 .JumpIfFalse(&far4);
393 for (int i = 0; i < kFarJumpDistance - 18; i++) {
364 builder.LoadUndefined(); 394 builder.LoadUndefined();
365 } 395 }
366 builder.Bind(&far0).Bind(&far1).Bind(&far2); 396 builder.Bind(&far0).Bind(&far1).Bind(&far2).Bind(&far3).Bind(&far4);
367 builder.Return(); 397 builder.Return();
368 398
369 Handle<BytecodeArray> array = builder.ToBytecodeArray(); 399 Handle<BytecodeArray> array = builder.ToBytecodeArray();
370 DCHECK_EQ(array->length(), 12 + kFarJumpDistance - 6 + 1); 400 DCHECK_EQ(array->length(), 36 + kFarJumpDistance - 18 + 1);
371 401
372 BytecodeArrayIterator iterator(array); 402 BytecodeArrayIterator iterator(array);
373 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); 403 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
404 CHECK_EQ(iterator.GetImmediateOperand(0), 18);
405 iterator.Advance();
406
407 // Ignore compare operation.
408 iterator.Advance();
409
410 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrue);
411 CHECK_EQ(iterator.GetImmediateOperand(0), 14);
412 iterator.Advance();
413
414 // Ignore compare operation.
415 iterator.Advance();
416
417 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalse);
418 CHECK_EQ(iterator.GetImmediateOperand(0), 10);
419 iterator.Advance();
420
421 // Ignore add operation.
422 iterator.Advance();
423
424 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrue);
374 CHECK_EQ(iterator.GetImmediateOperand(0), 6); 425 CHECK_EQ(iterator.GetImmediateOperand(0), 6);
375 iterator.Advance(); 426 iterator.Advance();
376 427
377 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrue); 428 // Ignore add operation.
378 CHECK_EQ(iterator.GetImmediateOperand(0), 4);
379 iterator.Advance(); 429 iterator.Advance();
380 430
381 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalse); 431 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanFalse);
382 CHECK_EQ(iterator.GetImmediateOperand(0), 2); 432 CHECK_EQ(iterator.GetImmediateOperand(0), 2);
383 iterator.Advance(); 433 iterator.Advance();
384 434
435
385 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpConstant); 436 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpConstant);
386 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), 437 CHECK_EQ(*iterator.GetConstantForIndexOperand(0),
387 Smi::FromInt(kFarJumpDistance)); 438 Smi::FromInt(kFarJumpDistance));
388 CHECK_EQ( 439 iterator.Advance();
389 array->get(iterator.current_offset() + 440
390 Smi::cast(*iterator.GetConstantForIndexOperand(0))->value()), 441 // Ignore compare operation.
391 Bytecodes::ToByte(Bytecode::kReturn));
392 iterator.Advance(); 442 iterator.Advance();
393 443
394 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrueConstant); 444 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrueConstant);
395 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), 445 CHECK_EQ(*iterator.GetConstantForIndexOperand(0),
396 Smi::FromInt(kFarJumpDistance - 2)); 446 Smi::FromInt(kFarJumpDistance - 4));
397 CHECK_EQ( 447 iterator.Advance();
398 array->get(iterator.current_offset() + 448
399 Smi::cast(*iterator.GetConstantForIndexOperand(0))->value()), 449 // Ignore compare operation.
400 Bytecodes::ToByte(Bytecode::kReturn));
401 iterator.Advance(); 450 iterator.Advance();
402 451
403 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalseConstant); 452 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalseConstant);
404 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), 453 CHECK_EQ(*iterator.GetConstantForIndexOperand(0),
405 Smi::FromInt(kFarJumpDistance - 4)); 454 Smi::FromInt(kFarJumpDistance - 8));
406 CHECK_EQ( 455 iterator.Advance();
407 array->get(iterator.current_offset() + 456
408 Smi::cast(*iterator.GetConstantForIndexOperand(0))->value()), 457 // Ignore add operation.
409 Bytecodes::ToByte(Bytecode::kReturn)); 458 iterator.Advance();
459
460 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrueConstant);
461 CHECK_EQ(*iterator.GetConstantForIndexOperand(0),
462 Smi::FromInt(kFarJumpDistance - 12));
463 iterator.Advance();
464
465 // Ignore add operation.
466 iterator.Advance();
467
468 CHECK_EQ(iterator.current_bytecode(),
469 Bytecode::kJumpIfToBooleanFalseConstant);
470 CHECK_EQ(*iterator.GetConstantForIndexOperand(0),
471 Smi::FromInt(kFarJumpDistance - 16));
410 iterator.Advance(); 472 iterator.Advance();
411 } 473 }
412 474
413 475
414 TEST_F(BytecodeArrayBuilderTest, BackwardJumps) { 476 TEST_F(BytecodeArrayBuilderTest, BackwardJumps) {
415 BytecodeArrayBuilder builder(isolate(), zone()); 477 BytecodeArrayBuilder builder(isolate(), zone());
416 builder.set_parameter_count(0); 478 builder.set_parameter_count(0);
417 builder.set_locals_count(0); 479 builder.set_locals_count(1);
418 builder.set_context_count(0); 480 builder.set_context_count(0);
481 Register reg(0);
419 482
420 BytecodeLabel label0, label1, label2; 483 BytecodeLabel label0, label1, label2, label3, label4;
421 builder.Bind(&label0) 484 builder.Bind(&label0)
422 .Jump(&label0) 485 .Jump(&label0)
486 .CompareOperation(Token::Value::EQ, reg, Strength::WEAK)
423 .Bind(&label1) 487 .Bind(&label1)
424 .JumpIfTrue(&label1) 488 .JumpIfTrue(&label1)
489 .CompareOperation(Token::Value::EQ, reg, Strength::WEAK)
425 .Bind(&label2) 490 .Bind(&label2)
491 .JumpIfFalse(&label2)
492 .BinaryOperation(Token::Value::ADD, reg, Strength::WEAK)
493 .Bind(&label3)
494 .JumpIfTrue(&label3)
495 .BinaryOperation(Token::Value::ADD, reg, Strength::WEAK)
496 .Bind(&label4)
497 .JumpIfFalse(&label4);
498 for (int i = 0; i < 64; i++) {
499 builder.Jump(&label4);
500 }
501 builder.BinaryOperation(Token::Value::ADD, reg, Strength::WEAK)
502 .JumpIfFalse(&label4);
503 builder.BinaryOperation(Token::Value::ADD, reg, Strength::WEAK)
504 .JumpIfTrue(&label3);
505 builder.CompareOperation(Token::Value::EQ, reg, Strength::WEAK)
426 .JumpIfFalse(&label2); 506 .JumpIfFalse(&label2);
427 for (int i = 0; i < 64; i++) { 507 builder.CompareOperation(Token::Value::EQ, reg, Strength::WEAK)
428 builder.Jump(&label2); 508 .JumpIfTrue(&label1);
429 }
430 builder.JumpIfFalse(&label2);
431 builder.JumpIfTrue(&label1);
432 builder.Jump(&label0); 509 builder.Jump(&label0);
433 builder.Return(); 510 builder.Return();
434 511
435 Handle<BytecodeArray> array = builder.ToBytecodeArray(); 512 Handle<BytecodeArray> array = builder.ToBytecodeArray();
436 BytecodeArrayIterator iterator(array); 513 BytecodeArrayIterator iterator(array);
437 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); 514 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
438 CHECK_EQ(iterator.GetImmediateOperand(0), 0); 515 CHECK_EQ(iterator.GetImmediateOperand(0), 0);
439 iterator.Advance(); 516 iterator.Advance();
517 // Ignore compare operation.
518 iterator.Advance();
440 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrue); 519 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrue);
441 CHECK_EQ(iterator.GetImmediateOperand(0), 0); 520 CHECK_EQ(iterator.GetImmediateOperand(0), 0);
442 iterator.Advance(); 521 iterator.Advance();
522 // Ignore compare operation.
523 iterator.Advance();
443 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalse); 524 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalse);
444 CHECK_EQ(iterator.GetImmediateOperand(0), 0); 525 CHECK_EQ(iterator.GetImmediateOperand(0), 0);
445 iterator.Advance(); 526 iterator.Advance();
527 // Ignore binary operation.
528 iterator.Advance();
529 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrue);
530 CHECK_EQ(iterator.GetImmediateOperand(0), 0);
531 iterator.Advance();
532 // Ignore binary operation.
533 iterator.Advance();
534 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanFalse);
535 CHECK_EQ(iterator.GetImmediateOperand(0), 0);
536 iterator.Advance();
446 for (int i = 0; i < 64; i++) { 537 for (int i = 0; i < 64; i++) {
447 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump); 538 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJump);
448 CHECK_EQ(iterator.GetImmediateOperand(0), -i * 2 - 2); 539 CHECK_EQ(iterator.GetImmediateOperand(0), -i * 2 - 2);
449 iterator.Advance(); 540 iterator.Advance();
450 } 541 }
542 // Ignore binary operation.
543 iterator.Advance();
544 CHECK_EQ(iterator.current_bytecode(),
545 Bytecode::kJumpIfToBooleanFalseConstant);
546 CHECK_EQ(Smi::cast(*iterator.GetConstantForIndexOperand(0))->value(), -132);
547 iterator.Advance();
548 // Ignore binary operation.
549 iterator.Advance();
550 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfToBooleanTrueConstant);
551 CHECK_EQ(Smi::cast(*iterator.GetConstantForIndexOperand(0))->value(), -140);
552 iterator.Advance();
553 // Ignore compare operation.
554 iterator.Advance();
451 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalseConstant); 555 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfFalseConstant);
452 CHECK_EQ(Smi::cast(*iterator.GetConstantForIndexOperand(0))->value(), -130); 556 CHECK_EQ(Smi::cast(*iterator.GetConstantForIndexOperand(0))->value(), -148);
557 iterator.Advance();
558 // Ignore compare operation.
453 iterator.Advance(); 559 iterator.Advance();
454 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrueConstant); 560 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrueConstant);
455 CHECK_EQ(Smi::cast(*iterator.GetConstantForIndexOperand(0))->value(), -134); 561 CHECK_EQ(Smi::cast(*iterator.GetConstantForIndexOperand(0))->value(), -156);
456 iterator.Advance(); 562 iterator.Advance();
457 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpConstant); 563 CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpConstant);
458 CHECK_EQ(Smi::cast(*iterator.GetConstantForIndexOperand(0))->value(), -138); 564 CHECK_EQ(Smi::cast(*iterator.GetConstantForIndexOperand(0))->value(), -162);
459 iterator.Advance(); 565 iterator.Advance();
460 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); 566 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn);
461 iterator.Advance(); 567 iterator.Advance();
462 CHECK(iterator.done()); 568 CHECK(iterator.done());
463 } 569 }
464 570
465 571
466 TEST_F(BytecodeArrayBuilderTest, LabelReuse) { 572 TEST_F(BytecodeArrayBuilderTest, LabelReuse) {
467 BytecodeArrayBuilder builder(isolate(), zone()); 573 BytecodeArrayBuilder builder(isolate(), zone());
468 builder.set_parameter_count(0); 574 builder.set_parameter_count(0);
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
570 676
571 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); 677 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn);
572 iterator.Advance(); 678 iterator.Advance();
573 CHECK(iterator.done()); 679 CHECK(iterator.done());
574 } 680 }
575 681
576 682
577 } // namespace interpreter 683 } // namespace interpreter
578 } // namespace internal 684 } // namespace internal
579 } // namespace v8 685 } // namespace v8
OLDNEW
« no previous file with comments | « test/cctest/interpreter/test-interpreter.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698