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

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

Issue 1997653002: [interpreter] Bytecode register optimizer. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Try harder with source positions. Created 4 years, 7 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-register-allocator.h" 9 #include "src/interpreter/bytecode-register-allocator.h"
10 #include "test/unittests/test-utils.h" 10 #include "test/unittests/test-utils.h"
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 .StoreAccumulatorInRegister(reg) 50 .StoreAccumulatorInRegister(reg)
51 .LoadNull() 51 .LoadNull()
52 .StoreAccumulatorInRegister(reg) 52 .StoreAccumulatorInRegister(reg)
53 .LoadTheHole() 53 .LoadTheHole()
54 .StoreAccumulatorInRegister(reg) 54 .StoreAccumulatorInRegister(reg)
55 .LoadTrue() 55 .LoadTrue()
56 .StoreAccumulatorInRegister(reg) 56 .StoreAccumulatorInRegister(reg)
57 .LoadFalse() 57 .LoadFalse()
58 .StoreAccumulatorInRegister(wide); 58 .StoreAccumulatorInRegister(wide);
59 59
60 // Emit Ldar and Star taking care to foil the register optimizer.
60 builder.StackCheck(0) 61 builder.StackCheck(0)
61 .LoadAccumulatorWithRegister(other) 62 .LoadAccumulatorWithRegister(other)
63 .BinaryOperation(Token::ADD, reg)
62 .StoreAccumulatorInRegister(reg) 64 .StoreAccumulatorInRegister(reg)
63 .LoadNull() 65 .LoadNull();
64 .StoreAccumulatorInRegister(reg);
65 66
66 // Emit register-register transfer. 67 // Emit register-register transfer.
67 builder.MoveRegister(reg, other); 68 builder.MoveRegister(reg, other);
68 builder.MoveRegister(reg, wide); 69 builder.MoveRegister(reg, wide);
69 70
70 // Emit global load / store operations. 71 // Emit global load / store operations.
71 Handle<String> name = factory->NewStringFromStaticChars("var_name"); 72 Handle<String> name = factory->NewStringFromStaticChars("var_name");
72 builder.LoadGlobal(name, 1, TypeofMode::NOT_INSIDE_TYPEOF) 73 builder.LoadGlobal(name, 1, TypeofMode::NOT_INSIDE_TYPEOF)
73 .LoadGlobal(name, 1, TypeofMode::INSIDE_TYPEOF) 74 .LoadGlobal(name, 1, TypeofMode::INSIDE_TYPEOF)
74 .StoreGlobal(name, 1, LanguageMode::SLOPPY) 75 .StoreGlobal(name, 1, LanguageMode::SLOPPY)
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 285
285 // Emit wide variant of literal creation operations. 286 // Emit wide variant of literal creation operations.
286 builder.CreateRegExpLiteral(factory->NewStringFromStaticChars("wide_literal"), 287 builder.CreateRegExpLiteral(factory->NewStringFromStaticChars("wide_literal"),
287 0, 0) 288 0, 0)
288 .CreateArrayLiteral(factory->NewFixedArray(2), 0, 0) 289 .CreateArrayLiteral(factory->NewFixedArray(2), 0, 0)
289 .CreateObjectLiteral(factory->NewFixedArray(2), 0, 0); 290 .CreateObjectLiteral(factory->NewFixedArray(2), 0, 0);
290 291
291 // Longer jumps requiring ConstantWide operand 292 // Longer jumps requiring ConstantWide operand
292 builder.Jump(&start).JumpIfNull(&start).JumpIfUndefined(&start).JumpIfNotHole( 293 builder.Jump(&start).JumpIfNull(&start).JumpIfUndefined(&start).JumpIfNotHole(
293 &start); 294 &start);
295
294 // Perform an operation that returns boolean value to 296 // Perform an operation that returns boolean value to
295 // generate JumpIfTrue/False 297 // generate JumpIfTrue/False
296 builder.CompareOperation(Token::Value::EQ, reg) 298 builder.CompareOperation(Token::Value::EQ, reg)
297 .JumpIfTrue(&start) 299 .JumpIfTrue(&start)
298 .CompareOperation(Token::Value::EQ, reg) 300 .CompareOperation(Token::Value::EQ, reg)
299 .JumpIfFalse(&start); 301 .JumpIfFalse(&start);
302
300 // Perform an operation that returns a non-boolean operation to 303 // Perform an operation that returns a non-boolean operation to
301 // generate JumpIfToBooleanTrue/False. 304 // generate JumpIfToBooleanTrue/False.
302 builder.BinaryOperation(Token::Value::ADD, reg) 305 builder.BinaryOperation(Token::Value::ADD, reg)
303 .JumpIfTrue(&start) 306 .JumpIfTrue(&start)
304 .BinaryOperation(Token::Value::ADD, reg) 307 .BinaryOperation(Token::Value::ADD, reg)
305 .JumpIfFalse(&start); 308 .JumpIfFalse(&start);
306 309
307 // Emit generator operations 310 // Emit generator operations
308 builder.SuspendGenerator(reg) 311 builder.SuspendGenerator(reg)
309 .ResumeGenerator(reg); 312 .ResumeGenerator(reg);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 } 366 }
364 367
365 368
366 TEST_F(BytecodeArrayBuilderTest, FrameSizesLookGood) { 369 TEST_F(BytecodeArrayBuilderTest, FrameSizesLookGood) {
367 for (int locals = 0; locals < 5; locals++) { 370 for (int locals = 0; locals < 5; locals++) {
368 for (int contexts = 0; contexts < 4; contexts++) { 371 for (int contexts = 0; contexts < 4; contexts++) {
369 for (int temps = 0; temps < 3; temps++) { 372 for (int temps = 0; temps < 3; temps++) {
370 BytecodeArrayBuilder builder(isolate(), zone(), 0, contexts, locals); 373 BytecodeArrayBuilder builder(isolate(), zone(), 0, contexts, locals);
371 BytecodeRegisterAllocator temporaries( 374 BytecodeRegisterAllocator temporaries(
372 zone(), builder.temporary_register_allocator()); 375 zone(), builder.temporary_register_allocator());
376 for (int i = 0; i < locals + contexts; i++) {
377 builder.LoadLiteral(Smi::FromInt(0));
378 builder.StoreAccumulatorInRegister(Register(i));
379 }
373 for (int i = 0; i < temps; i++) { 380 for (int i = 0; i < temps; i++) {
381 builder.LoadLiteral(Smi::FromInt(0));
374 builder.StoreAccumulatorInRegister(temporaries.NewRegister()); 382 builder.StoreAccumulatorInRegister(temporaries.NewRegister());
375 } 383 }
384 if (temps > 0) {
385 // Ensure temporaries are used so not optimized away by the
386 // register optimizer.
387 builder.New(Register(locals + contexts), Register(locals + contexts),
388 static_cast<size_t>(temps));
389 }
376 builder.Return(); 390 builder.Return();
377 391
378 Handle<BytecodeArray> the_array = builder.ToBytecodeArray(); 392 Handle<BytecodeArray> the_array = builder.ToBytecodeArray();
379 int total_registers = locals + contexts + temps; 393 int total_registers = locals + contexts + temps;
380 CHECK_EQ(the_array->frame_size(), total_registers * kPointerSize); 394 CHECK_EQ(the_array->frame_size(), total_registers * kPointerSize);
381 } 395 }
382 } 396 }
383 } 397 }
384 } 398 }
385 399
386 400
387 TEST_F(BytecodeArrayBuilderTest, RegisterValues) { 401 TEST_F(BytecodeArrayBuilderTest, RegisterValues) {
388 int index = 1; 402 int index = 1;
389 403
390 Register the_register(index); 404 Register the_register(index);
391 CHECK_EQ(the_register.index(), index); 405 CHECK_EQ(the_register.index(), index);
392 406
393 int actual_operand = the_register.ToOperand(); 407 int actual_operand = the_register.ToOperand();
394 int actual_index = Register::FromOperand(actual_operand).index(); 408 int actual_index = Register::FromOperand(actual_operand).index();
395 CHECK_EQ(actual_index, index); 409 CHECK_EQ(actual_index, index);
396 } 410 }
397 411
398 412
399 TEST_F(BytecodeArrayBuilderTest, Parameters) { 413 TEST_F(BytecodeArrayBuilderTest, Parameters) {
400 BytecodeArrayBuilder builder(isolate(), zone(), 10, 0, 0); 414 BytecodeArrayBuilder builder(isolate(), zone(), 10, 0, 0);
415
401 Register param0(builder.Parameter(0)); 416 Register param0(builder.Parameter(0));
402 Register param9(builder.Parameter(9)); 417 Register param9(builder.Parameter(9));
403 CHECK_EQ(param9.index() - param0.index(), 9); 418 CHECK_EQ(param9.index() - param0.index(), 9);
404 } 419 }
405 420
406 421
407 TEST_F(BytecodeArrayBuilderTest, RegisterType) { 422 TEST_F(BytecodeArrayBuilderTest, RegisterType) {
408 BytecodeArrayBuilder builder(isolate(), zone(), 10, 0, 3); 423 BytecodeArrayBuilder builder(isolate(), zone(), 10, 0, 3);
409 BytecodeRegisterAllocator register_allocator( 424 BytecodeRegisterAllocator register_allocator(
410 zone(), builder.temporary_register_allocator()); 425 zone(), builder.temporary_register_allocator());
(...skipping 11 matching lines...) Expand all
422 CHECK_EQ(builder.RegisterIsParameterOrLocal(param0), true); 437 CHECK_EQ(builder.RegisterIsParameterOrLocal(param0), true);
423 CHECK_EQ(builder.RegisterIsParameterOrLocal(param9), true); 438 CHECK_EQ(builder.RegisterIsParameterOrLocal(param9), true);
424 CHECK_EQ(builder.RegisterIsParameterOrLocal(reg0), true); 439 CHECK_EQ(builder.RegisterIsParameterOrLocal(reg0), true);
425 CHECK_EQ(builder.RegisterIsParameterOrLocal(reg1), true); 440 CHECK_EQ(builder.RegisterIsParameterOrLocal(reg1), true);
426 CHECK_EQ(builder.RegisterIsParameterOrLocal(reg2), true); 441 CHECK_EQ(builder.RegisterIsParameterOrLocal(reg2), true);
427 } 442 }
428 443
429 444
430 TEST_F(BytecodeArrayBuilderTest, Constants) { 445 TEST_F(BytecodeArrayBuilderTest, Constants) {
431 BytecodeArrayBuilder builder(isolate(), zone(), 0, 0, 0); 446 BytecodeArrayBuilder builder(isolate(), zone(), 0, 0, 0);
447
432 Factory* factory = isolate()->factory(); 448 Factory* factory = isolate()->factory();
433 Handle<HeapObject> heap_num_1 = factory->NewHeapNumber(3.14); 449 Handle<HeapObject> heap_num_1 = factory->NewHeapNumber(3.14);
434 Handle<HeapObject> heap_num_2 = factory->NewHeapNumber(5.2); 450 Handle<HeapObject> heap_num_2 = factory->NewHeapNumber(5.2);
435 Handle<Object> large_smi(Smi::FromInt(0x12345678), isolate()); 451 Handle<Object> large_smi(Smi::FromInt(0x12345678), isolate());
436 Handle<HeapObject> heap_num_2_copy(*heap_num_2); 452 Handle<HeapObject> heap_num_2_copy(*heap_num_2);
437 builder.LoadLiteral(heap_num_1) 453 builder.LoadLiteral(heap_num_1)
438 .LoadLiteral(heap_num_2) 454 .LoadLiteral(heap_num_2)
439 .LoadLiteral(large_smi) 455 .LoadLiteral(large_smi)
440 .LoadLiteral(heap_num_1) 456 .LoadLiteral(heap_num_1)
441 .LoadLiteral(heap_num_1) 457 .LoadLiteral(heap_num_1)
442 .LoadLiteral(heap_num_2_copy) 458 .LoadLiteral(heap_num_2_copy)
443 .Return(); 459 .Return();
444 460
445 Handle<BytecodeArray> array = builder.ToBytecodeArray(); 461 Handle<BytecodeArray> array = builder.ToBytecodeArray();
446 // Should only have one entry for each identical constant. 462 // Should only have one entry for each identical constant.
447 CHECK_EQ(array->constant_pool()->length(), 3); 463 CHECK_EQ(array->constant_pool()->length(), 3);
448 } 464 }
449 465
450 466
451 TEST_F(BytecodeArrayBuilderTest, ForwardJumps) { 467 TEST_F(BytecodeArrayBuilderTest, ForwardJumps) {
452 static const int kFarJumpDistance = 256; 468 static const int kFarJumpDistance = 256;
453 469
454 BytecodeArrayBuilder builder(isolate(), zone(), 0, 0, 1); 470 BytecodeArrayBuilder builder(isolate(), zone(), 0, 0, 1);
471
455 Register reg(0); 472 Register reg(0);
456 BytecodeLabel far0, far1, far2, far3, far4; 473 BytecodeLabel far0, far1, far2, far3, far4;
457 BytecodeLabel near0, near1, near2, near3, near4; 474 BytecodeLabel near0, near1, near2, near3, near4;
458 475
459 builder.Jump(&near0) 476 builder.Jump(&near0)
460 .CompareOperation(Token::Value::EQ, reg) 477 .CompareOperation(Token::Value::EQ, reg)
461 .JumpIfTrue(&near1) 478 .JumpIfTrue(&near1)
462 .CompareOperation(Token::Value::EQ, reg) 479 .CompareOperation(Token::Value::EQ, reg)
463 .JumpIfFalse(&near2) 480 .JumpIfFalse(&near2)
464 .BinaryOperation(Token::Value::ADD, reg) 481 .BinaryOperation(Token::Value::ADD, reg)
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
556 CHECK_EQ(iterator.current_bytecode(), 573 CHECK_EQ(iterator.current_bytecode(),
557 Bytecode::kJumpIfToBooleanFalseConstant); 574 Bytecode::kJumpIfToBooleanFalseConstant);
558 CHECK_EQ(*iterator.GetConstantForIndexOperand(0), 575 CHECK_EQ(*iterator.GetConstantForIndexOperand(0),
559 Smi::FromInt(kFarJumpDistance - 16)); 576 Smi::FromInt(kFarJumpDistance - 16));
560 iterator.Advance(); 577 iterator.Advance();
561 } 578 }
562 579
563 580
564 TEST_F(BytecodeArrayBuilderTest, BackwardJumps) { 581 TEST_F(BytecodeArrayBuilderTest, BackwardJumps) {
565 BytecodeArrayBuilder builder(isolate(), zone(), 0, 0, 1); 582 BytecodeArrayBuilder builder(isolate(), zone(), 0, 0, 1);
583
566 Register reg(0); 584 Register reg(0);
567 585
568 BytecodeLabel label0, label1, label2, label3, label4; 586 BytecodeLabel label0, label1, label2, label3, label4;
569 builder.Bind(&label0) 587 builder.Bind(&label0)
570 .Jump(&label0) 588 .Jump(&label0)
571 .Bind(&label1) 589 .Bind(&label1)
572 .CompareOperation(Token::Value::EQ, reg) 590 .CompareOperation(Token::Value::EQ, reg)
573 .JumpIfTrue(&label1) 591 .JumpIfTrue(&label1)
574 .Bind(&label2) 592 .Bind(&label2)
575 .CompareOperation(Token::Value::EQ, reg) 593 .CompareOperation(Token::Value::EQ, reg)
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
720 iterator.Advance(); 738 iterator.Advance();
721 } 739 }
722 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); 740 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn);
723 iterator.Advance(); 741 iterator.Advance();
724 CHECK(iterator.done()); 742 CHECK(iterator.done());
725 } 743 }
726 744
727 } // namespace interpreter 745 } // namespace interpreter
728 } // namespace internal 746 } // namespace internal
729 } // namespace v8 747 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698