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 #include <iostream> | 5 #include <iostream> |
6 | 6 |
7 #include "src/compiler/bytecode-graph-builder.h" | 7 #include "src/compiler/bytecode-graph-builder.h" |
8 #include "src/compiler/common-operator.h" | 8 #include "src/compiler/common-operator.h" |
9 #include "src/compiler/graph-visualizer.h" | 9 #include "src/compiler/graph-visualizer.h" |
10 #include "src/compiler/instruction.h" | 10 #include "src/compiler/instruction.h" |
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
358 | 358 |
359 interpreter::BytecodeArrayBuilder array_builder(isolate(), zone()); | 359 interpreter::BytecodeArrayBuilder array_builder(isolate(), zone()); |
360 array_builder.set_locals_count(1); | 360 array_builder.set_locals_count(1); |
361 array_builder.set_context_count(0); | 361 array_builder.set_context_count(0); |
362 array_builder.set_parameter_count(2); | 362 array_builder.set_parameter_count(2); |
363 | 363 |
364 Handle<Name> func_name = GetName(isolate(), "func"); | 364 Handle<Name> func_name = GetName(isolate(), "func"); |
365 size_t func_name_index = array_builder.GetConstantPoolEntry(func_name); | 365 size_t func_name_index = array_builder.GetConstantPoolEntry(func_name); |
366 | 366 |
367 interpreter::Register reg0 = interpreter::Register(0); | 367 interpreter::Register reg0 = interpreter::Register(0); |
368 array_builder.LoadNamedProperty( | 368 array_builder.LoadNamedProperty(array_builder.Parameter(1), func_name_index, |
369 array_builder.Parameter(1), func_name_index, | 369 vector->GetIndex(load_slot), |
370 vector->GetIndex(load_slot), LanguageMode::SLOPPY) | 370 LanguageMode::SLOPPY) |
371 .StoreAccumulatorInRegister(reg0) | 371 .StoreAccumulatorInRegister(reg0) |
372 .Call(reg0, array_builder.Parameter(1), 0, vector->GetIndex(call_slot)) | 372 .Call(reg0, array_builder.Parameter(1), 0, vector->GetIndex(call_slot)) |
373 .Return(); | 373 .Return(); |
374 | 374 |
375 Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray(), vector); | 375 Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray(), vector); |
376 Node* ret = graph->end()->InputAt(0); | 376 Node* ret = graph->end()->InputAt(0); |
377 Node* start = graph->start(); | 377 Node* start = graph->start(); |
378 | 378 |
379 Matcher<Node*> feedback_vector_matcher = IsFeedbackVector(start, start); | 379 Matcher<Node*> feedback_vector_matcher = IsFeedbackVector(start, start); |
380 Matcher<Node*> load_named_matcher = IsJSLoadNamed( | 380 Matcher<Node*> load_named_matcher = IsJSLoadNamed( |
(...skipping 20 matching lines...) Expand all Loading... |
401 array_builder.set_context_count(0); | 401 array_builder.set_context_count(0); |
402 array_builder.set_parameter_count(4); | 402 array_builder.set_parameter_count(4); |
403 | 403 |
404 Handle<Name> func_name = GetName(isolate(), "func"); | 404 Handle<Name> func_name = GetName(isolate(), "func"); |
405 size_t func_name_index = array_builder.GetConstantPoolEntry(func_name); | 405 size_t func_name_index = array_builder.GetConstantPoolEntry(func_name); |
406 | 406 |
407 interpreter::Register reg0 = interpreter::Register(0); | 407 interpreter::Register reg0 = interpreter::Register(0); |
408 interpreter::Register reg1 = interpreter::Register(1); | 408 interpreter::Register reg1 = interpreter::Register(1); |
409 interpreter::Register reg2 = interpreter::Register(2); | 409 interpreter::Register reg2 = interpreter::Register(2); |
410 interpreter::Register reg3 = interpreter::Register(3); | 410 interpreter::Register reg3 = interpreter::Register(3); |
411 array_builder.LoadNamedProperty( | 411 array_builder.LoadNamedProperty(array_builder.Parameter(1), func_name_index, |
412 array_builder.Parameter(1), func_name_index, | 412 vector->GetIndex(load_slot), |
413 vector->GetIndex(load_slot), LanguageMode::SLOPPY) | 413 LanguageMode::SLOPPY) |
414 .StoreAccumulatorInRegister(reg0) | 414 .StoreAccumulatorInRegister(reg0) |
415 .LoadAccumulatorWithRegister(array_builder.Parameter(1)) | 415 .LoadAccumulatorWithRegister(array_builder.Parameter(1)) |
416 .StoreAccumulatorInRegister(reg1) | 416 .StoreAccumulatorInRegister(reg1) |
417 .LoadAccumulatorWithRegister(array_builder.Parameter(2)) | 417 .LoadAccumulatorWithRegister(array_builder.Parameter(2)) |
418 .StoreAccumulatorInRegister(reg2) | 418 .StoreAccumulatorInRegister(reg2) |
419 .LoadAccumulatorWithRegister(array_builder.Parameter(3)) | 419 .LoadAccumulatorWithRegister(array_builder.Parameter(3)) |
420 .StoreAccumulatorInRegister(reg3) | 420 .StoreAccumulatorInRegister(reg3) |
421 .Call(reg0, reg1, 2, vector->GetIndex(call_slot)) | 421 .Call(reg0, reg1, 2, vector->GetIndex(call_slot)) |
422 .Return(); | 422 .Return(); |
423 | 423 |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
584 | 584 |
585 Node* start = graph->start(); | 585 Node* start = graph->start(); |
586 Node* ret = graph->end()->InputAt(0); | 586 Node* ret = graph->end()->InputAt(0); |
587 | 587 |
588 Matcher<Node*> delete_matcher = | 588 Matcher<Node*> delete_matcher = |
589 IsJSDeleteProperty(IsParameter(1), IsHeapConstant(name), start, start); | 589 IsJSDeleteProperty(IsParameter(1), IsHeapConstant(name), start, start); |
590 EXPECT_THAT(ret, IsReturn(delete_matcher, _, _)); | 590 EXPECT_THAT(ret, IsReturn(delete_matcher, _, _)); |
591 } | 591 } |
592 } | 592 } |
593 | 593 |
| 594 |
| 595 TEST_F(BytecodeGraphBuilderTest, KeyedLoad) { |
| 596 const int kValue = 100; |
| 597 const bool kWideBytecode[] = {false, true}; |
| 598 TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) { |
| 599 TRACED_FOREACH(bool, wide_bytecode, kWideBytecode) { |
| 600 FeedbackVectorSpec feedback_spec(zone()); |
| 601 if (wide_bytecode) { |
| 602 for (int i = 0; i < 128; i++) { |
| 603 feedback_spec.AddLoadICSlot(); |
| 604 } |
| 605 } |
| 606 FeedbackVectorSlot slot = feedback_spec.AddLoadICSlot(); |
| 607 Handle<TypeFeedbackVector> vector = |
| 608 NewTypeFeedbackVector(isolate(), &feedback_spec); |
| 609 |
| 610 interpreter::BytecodeArrayBuilder array_builder(isolate(), zone()); |
| 611 array_builder.set_locals_count(1); |
| 612 array_builder.set_context_count(0); |
| 613 array_builder.set_parameter_count(2); |
| 614 |
| 615 array_builder.LoadLiteral(Smi::FromInt(kValue)) |
| 616 .LoadKeyedProperty(array_builder.Parameter(1), vector->GetIndex(slot), |
| 617 language_mode) |
| 618 .Return(); |
| 619 Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray(), vector, |
| 620 language_mode); |
| 621 |
| 622 Node* ret = graph->end()->InputAt(0); |
| 623 Node* start = graph->start(); |
| 624 |
| 625 Matcher<Node*> feedback_vector_matcher = IsFeedbackVector(start, start); |
| 626 Matcher<Node*> load_keyed_matcher = |
| 627 IsJSLoadProperty(IsParameter(1), IsNumberConstant(kValue), |
| 628 feedback_vector_matcher, start, start); |
| 629 |
| 630 EXPECT_THAT(ret, IsReturn(load_keyed_matcher, _, _)); |
| 631 } |
| 632 } |
| 633 } |
| 634 |
| 635 |
| 636 TEST_F(BytecodeGraphBuilderTest, NamedStore) { |
| 637 const int kValue = 100; |
| 638 const bool kWideBytecode[] = {false, true}; |
| 639 TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) { |
| 640 TRACED_FOREACH(bool, wide_bytecode, kWideBytecode) { |
| 641 FeedbackVectorSpec feedback_spec(zone()); |
| 642 if (wide_bytecode) { |
| 643 for (int i = 0; i < 128; i++) { |
| 644 feedback_spec.AddLoadICSlot(); |
| 645 } |
| 646 } |
| 647 FeedbackVectorSlot slot = feedback_spec.AddLoadICSlot(); |
| 648 Handle<TypeFeedbackVector> vector = |
| 649 NewTypeFeedbackVector(isolate(), &feedback_spec); |
| 650 |
| 651 interpreter::BytecodeArrayBuilder array_builder(isolate(), zone()); |
| 652 array_builder.set_locals_count(1); |
| 653 array_builder.set_context_count(0); |
| 654 array_builder.set_parameter_count(2); |
| 655 |
| 656 Handle<Name> name = GetName(isolate(), "val"); |
| 657 size_t name_index = array_builder.GetConstantPoolEntry(name); |
| 658 |
| 659 array_builder.LoadLiteral(Smi::FromInt(kValue)) |
| 660 .StoreNamedProperty(array_builder.Parameter(1), name_index, |
| 661 vector->GetIndex(slot), language_mode) |
| 662 .Return(); |
| 663 Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray(), vector, |
| 664 language_mode); |
| 665 |
| 666 Node* ret = graph->end()->InputAt(0); |
| 667 Node* start = graph->start(); |
| 668 |
| 669 Matcher<Node*> feedback_vector_matcher = IsFeedbackVector(start, start); |
| 670 Matcher<Node*> store_named_matcher = |
| 671 IsJSStoreNamed(name, IsParameter(1), IsNumberConstant(kValue), |
| 672 feedback_vector_matcher, start, start); |
| 673 |
| 674 EXPECT_THAT(ret, IsReturn(_, store_named_matcher, _)); |
| 675 } |
| 676 } |
| 677 } |
| 678 |
| 679 |
| 680 TEST_F(BytecodeGraphBuilderTest, KeyedStore) { |
| 681 const int kValue = 100; |
| 682 const int kKey = 10; |
| 683 const bool kWideBytecode[] = {false, true}; |
| 684 TRACED_FOREACH(LanguageMode, language_mode, kLanguageModes) { |
| 685 TRACED_FOREACH(bool, wide_bytecode, kWideBytecode) { |
| 686 FeedbackVectorSpec feedback_spec(zone()); |
| 687 if (wide_bytecode) { |
| 688 for (int i = 0; i < 128; i++) { |
| 689 feedback_spec.AddStoreICSlot(); |
| 690 } |
| 691 } |
| 692 FeedbackVectorSlot slot = feedback_spec.AddStoreICSlot(); |
| 693 Handle<TypeFeedbackVector> vector = |
| 694 NewTypeFeedbackVector(isolate(), &feedback_spec); |
| 695 |
| 696 interpreter::BytecodeArrayBuilder array_builder(isolate(), zone()); |
| 697 array_builder.set_locals_count(1); |
| 698 array_builder.set_context_count(0); |
| 699 array_builder.set_parameter_count(2); |
| 700 |
| 701 array_builder.LoadLiteral(Smi::FromInt(kKey)) |
| 702 .StoreAccumulatorInRegister(interpreter::Register(0)) |
| 703 .LoadLiteral(Smi::FromInt(kValue)) |
| 704 .StoreKeyedProperty(array_builder.Parameter(1), |
| 705 interpreter::Register(0), vector->GetIndex(slot), |
| 706 language_mode) |
| 707 .Return(); |
| 708 Graph* graph = GetCompletedGraph(array_builder.ToBytecodeArray(), vector, |
| 709 language_mode); |
| 710 |
| 711 Node* ret = graph->end()->InputAt(0); |
| 712 Node* start = graph->start(); |
| 713 |
| 714 Matcher<Node*> feedback_vector_matcher = IsFeedbackVector(start, start); |
| 715 Matcher<Node*> store_keyed_matcher = IsJSStoreProperty( |
| 716 IsParameter(1), IsNumberConstant(kKey), IsNumberConstant(kValue), |
| 717 feedback_vector_matcher, start, start); |
| 718 |
| 719 EXPECT_THAT(ret, IsReturn(_, store_keyed_matcher, _)); |
| 720 } |
| 721 } |
| 722 } |
| 723 |
594 } // namespace compiler | 724 } // namespace compiler |
595 } // namespace internal | 725 } // namespace internal |
596 } // namespace v8 | 726 } // namespace v8 |
OLD | NEW |