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

Side by Side Diff: test/cctest/interpreter/test-interpreter.cc

Issue 2122183002: [Interpreter] Collect type feedback for calls in the bytecode handler (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fixed few comments. Created 4 years, 5 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 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 "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/execution.h" 7 #include "src/execution.h"
8 #include "src/handles.h" 8 #include "src/handles.h"
9 #include "src/interpreter/bytecode-array-builder.h" 9 #include "src/interpreter/bytecode-array-builder.h"
10 #include "src/interpreter/bytecode-array-iterator.h" 10 #include "src/interpreter/bytecode-array-iterator.h"
(...skipping 772 matching lines...) Expand 10 before | Expand all | Expand 10 after
783 CHECK_EQ(Smi::cast(*result), Smi::FromInt(999)); 783 CHECK_EQ(Smi::cast(*result), Smi::FromInt(999));
784 784
785 // Test transition to megamorphic IC. 785 // Test transition to megamorphic IC.
786 Handle<Object> object2 = 786 Handle<Object> object2 =
787 InterpreterTester::NewObject("({ val : 456, other : 123 })"); 787 InterpreterTester::NewObject("({ val : 456, other : 123 })");
788 callable(object2).ToHandleChecked(); 788 callable(object2).ToHandleChecked();
789 CHECK(Runtime::GetObjectProperty(isolate, object2, name).ToHandle(&result)); 789 CHECK(Runtime::GetObjectProperty(isolate, object2, name).ToHandle(&result));
790 CHECK_EQ(Smi::cast(*result), Smi::FromInt(999)); 790 CHECK_EQ(Smi::cast(*result), Smi::FromInt(999));
791 } 791 }
792 792
793 static void TestInterpreterCall(TailCallMode tail_call_mode) { 793 static void TestInterpreterCall(TailCallMode tail_call_mode,
794 bool has_feedback_slot) {
794 HandleAndZoneScope handles; 795 HandleAndZoneScope handles;
795 i::Isolate* isolate = handles.main_isolate(); 796 i::Isolate* isolate = handles.main_isolate();
796 i::Factory* factory = isolate->factory(); 797 i::Factory* factory = isolate->factory();
797 i::Zone zone(isolate->allocator()); 798 i::Zone zone(isolate->allocator());
798 799
799 i::FeedbackVectorSpec feedback_spec(&zone); 800 i::FeedbackVectorSpec feedback_spec(&zone);
800 i::FeedbackVectorSlot slot = feedback_spec.AddLoadICSlot(); 801 i::FeedbackVectorSlot slot = feedback_spec.AddLoadICSlot();
802 i::FeedbackVectorSlot call_slot = feedback_spec.AddCallICSlot();
801 803
802 Handle<i::TypeFeedbackVector> vector = 804 Handle<i::TypeFeedbackVector> vector =
803 i::NewTypeFeedbackVector(isolate, &feedback_spec); 805 i::NewTypeFeedbackVector(isolate, &feedback_spec);
804 int slot_index = vector->GetIndex(slot); 806 int slot_index = vector->GetIndex(slot);
807 int call_slot_index = -1;
808 if (has_feedback_slot) {
809 call_slot_index = vector->GetIndex(call_slot);
810 }
805 811
806 Handle<i::String> name = factory->NewStringFromAsciiChecked("func"); 812 Handle<i::String> name = factory->NewStringFromAsciiChecked("func");
807 name = factory->string_table()->LookupString(isolate, name); 813 name = factory->string_table()->LookupString(isolate, name);
808 814
809 // Check with no args. 815 // Check with no args.
810 { 816 {
811 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone(), 1, 817 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone(), 1,
812 0, 1); 818 0, 1);
813 819
814 builder.LoadNamedProperty(builder.Parameter(0), name, slot_index) 820 builder.LoadNamedProperty(builder.Parameter(0), name, slot_index)
815 .StoreAccumulatorInRegister(Register(0)) 821 .StoreAccumulatorInRegister(Register(0));
816 .Call(Register(0), builder.Parameter(0), 1, 0, tail_call_mode) 822
817 .Return(); 823 if (has_feedback_slot) {
824 builder.CallWithFeedback(Register(0), builder.Parameter(0), 1,
825 call_slot_index, tail_call_mode);
826 } else {
827 builder.Call(Register(0), builder.Parameter(0), 1, tail_call_mode);
828 }
829
830 builder.Return();
818 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); 831 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray();
819 832
820 InterpreterTester tester(handles.main_isolate(), bytecode_array, vector); 833 InterpreterTester tester(handles.main_isolate(), bytecode_array, vector);
821 auto callable = tester.GetCallable<Handle<Object>>(); 834 auto callable = tester.GetCallable<Handle<Object>>();
822 835
823 Handle<Object> object = InterpreterTester::NewObject( 836 Handle<Object> object = InterpreterTester::NewObject(
824 "new (function Obj() { this.func = function() { return 0x265; }})()"); 837 "new (function Obj() { this.func = function() { return 0x265; }})()");
825 Handle<Object> return_val = callable(object).ToHandleChecked(); 838 Handle<Object> return_val = callable(object).ToHandleChecked();
826 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(0x265)); 839 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(0x265));
827 } 840 }
828 841
829 // Check that receiver is passed properly. 842 // Check that receiver is passed properly.
830 { 843 {
831 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone(), 1, 844 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone(), 1,
832 0, 1); 845 0, 1);
833 846
834 builder.LoadNamedProperty(builder.Parameter(0), name, slot_index) 847 builder.LoadNamedProperty(builder.Parameter(0), name, slot_index)
835 .StoreAccumulatorInRegister(Register(0)) 848 .StoreAccumulatorInRegister(Register(0));
836 .Call(Register(0), builder.Parameter(0), 1, 0, tail_call_mode) 849 if (has_feedback_slot) {
837 .Return(); 850 builder.CallWithFeedback(Register(0), builder.Parameter(0), 1,
851 call_slot_index, tail_call_mode);
852 } else {
853 builder.Call(Register(0), builder.Parameter(0), 1, tail_call_mode);
854 }
855 builder.Return();
838 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); 856 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray();
839 857
840 InterpreterTester tester(handles.main_isolate(), bytecode_array, vector); 858 InterpreterTester tester(handles.main_isolate(), bytecode_array, vector);
841 auto callable = tester.GetCallable<Handle<Object>>(); 859 auto callable = tester.GetCallable<Handle<Object>>();
842 860
843 Handle<Object> object = InterpreterTester::NewObject( 861 Handle<Object> object = InterpreterTester::NewObject(
844 "new (function Obj() {" 862 "new (function Obj() {"
845 " this.val = 1234;" 863 " this.val = 1234;"
846 " this.func = function() { return this.val; };" 864 " this.func = function() { return this.val; };"
847 "})()"); 865 "})()");
848 Handle<Object> return_val = callable(object).ToHandleChecked(); 866 Handle<Object> return_val = callable(object).ToHandleChecked();
849 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(1234)); 867 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(1234));
850 } 868 }
851 869
852 // Check with two parameters (+ receiver). 870 // Check with two parameters (+ receiver).
853 { 871 {
854 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone(), 1, 872 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone(), 1,
855 0, 4); 873 0, 4);
856 874
857 builder.LoadNamedProperty(builder.Parameter(0), name, slot_index) 875 builder.LoadNamedProperty(builder.Parameter(0), name, slot_index)
858 .StoreAccumulatorInRegister(Register(0)) 876 .StoreAccumulatorInRegister(Register(0))
859 .LoadAccumulatorWithRegister(builder.Parameter(0)) 877 .LoadAccumulatorWithRegister(builder.Parameter(0))
860 .StoreAccumulatorInRegister(Register(1)) 878 .StoreAccumulatorInRegister(Register(1))
861 .LoadLiteral(Smi::FromInt(51)) 879 .LoadLiteral(Smi::FromInt(51))
862 .StoreAccumulatorInRegister(Register(2)) 880 .StoreAccumulatorInRegister(Register(2))
863 .LoadLiteral(Smi::FromInt(11)) 881 .LoadLiteral(Smi::FromInt(11))
864 .StoreAccumulatorInRegister(Register(3)) 882 .StoreAccumulatorInRegister(Register(3));
865 .Call(Register(0), Register(1), 3, 0, tail_call_mode) 883
866 .Return(); 884 if (has_feedback_slot) {
885 builder.CallWithFeedback(Register(0), Register(1), 3, call_slot_index,
886 tail_call_mode);
887 } else {
888 builder.Call(Register(0), Register(1), 3, tail_call_mode);
889 }
890
891 builder.Return();
892
867 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); 893 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray();
868 894
869 InterpreterTester tester(handles.main_isolate(), bytecode_array, vector); 895 InterpreterTester tester(handles.main_isolate(), bytecode_array, vector);
870 auto callable = tester.GetCallable<Handle<Object>>(); 896 auto callable = tester.GetCallable<Handle<Object>>();
871 897
872 Handle<Object> object = InterpreterTester::NewObject( 898 Handle<Object> object = InterpreterTester::NewObject(
873 "new (function Obj() { " 899 "new (function Obj() { "
874 " this.func = function(a, b) { return a - b; }" 900 " this.func = function(a, b) { return a - b; }"
875 "})()"); 901 "})()");
876 Handle<Object> return_val = callable(object).ToHandleChecked(); 902 Handle<Object> return_val = callable(object).ToHandleChecked();
(...skipping 21 matching lines...) Expand all
898 .StoreAccumulatorInRegister(Register(6)) 924 .StoreAccumulatorInRegister(Register(6))
899 .LoadLiteral(factory->NewStringFromAsciiChecked("f")) 925 .LoadLiteral(factory->NewStringFromAsciiChecked("f"))
900 .StoreAccumulatorInRegister(Register(7)) 926 .StoreAccumulatorInRegister(Register(7))
901 .LoadLiteral(factory->NewStringFromAsciiChecked("g")) 927 .LoadLiteral(factory->NewStringFromAsciiChecked("g"))
902 .StoreAccumulatorInRegister(Register(8)) 928 .StoreAccumulatorInRegister(Register(8))
903 .LoadLiteral(factory->NewStringFromAsciiChecked("h")) 929 .LoadLiteral(factory->NewStringFromAsciiChecked("h"))
904 .StoreAccumulatorInRegister(Register(9)) 930 .StoreAccumulatorInRegister(Register(9))
905 .LoadLiteral(factory->NewStringFromAsciiChecked("i")) 931 .LoadLiteral(factory->NewStringFromAsciiChecked("i"))
906 .StoreAccumulatorInRegister(Register(10)) 932 .StoreAccumulatorInRegister(Register(10))
907 .LoadLiteral(factory->NewStringFromAsciiChecked("j")) 933 .LoadLiteral(factory->NewStringFromAsciiChecked("j"))
908 .StoreAccumulatorInRegister(Register(11)) 934 .StoreAccumulatorInRegister(Register(11));
909 .Call(Register(0), Register(1), 11, 0, tail_call_mode) 935
910 .Return(); 936 if (has_feedback_slot) {
937 builder.CallWithFeedback(Register(0), Register(1), 11, call_slot_index,
938 tail_call_mode);
939 } else {
940 builder.Call(Register(0), Register(1), 11, tail_call_mode);
941 }
942
943 builder.Return();
944
911 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); 945 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray();
912 946
913 InterpreterTester tester(handles.main_isolate(), bytecode_array, vector); 947 InterpreterTester tester(handles.main_isolate(), bytecode_array, vector);
914 auto callable = tester.GetCallable<Handle<Object>>(); 948 auto callable = tester.GetCallable<Handle<Object>>();
915 949
916 Handle<Object> object = InterpreterTester::NewObject( 950 Handle<Object> object = InterpreterTester::NewObject(
917 "new (function Obj() { " 951 "new (function Obj() { "
918 " this.prefix = \"prefix_\";" 952 " this.prefix = \"prefix_\";"
919 " this.func = function(a, b, c, d, e, f, g, h, i, j) {" 953 " this.func = function(a, b, c, d, e, f, g, h, i, j) {"
920 " return this.prefix + a + b + c + d + e + f + g + h + i + j;" 954 " return this.prefix + a + b + c + d + e + f + g + h + i + j;"
921 " }" 955 " }"
922 "})()"); 956 "})()");
923 Handle<Object> return_val = callable(object).ToHandleChecked(); 957 Handle<Object> return_val = callable(object).ToHandleChecked();
924 Handle<i::String> expected = 958 Handle<i::String> expected =
925 factory->NewStringFromAsciiChecked("prefix_abcdefghij"); 959 factory->NewStringFromAsciiChecked("prefix_abcdefghij");
926 CHECK(i::String::cast(*return_val)->Equals(*expected)); 960 CHECK(i::String::cast(*return_val)->Equals(*expected));
927 } 961 }
928 } 962 }
929 963
930 TEST(InterpreterCall) { TestInterpreterCall(TailCallMode::kDisallow); } 964 TEST(InterpreterCall) { TestInterpreterCall(TailCallMode::kDisallow, false); }
931 965
932 TEST(InterpreterTailCall) { TestInterpreterCall(TailCallMode::kAllow); } 966 TEST(InterpreterTailCall) { TestInterpreterCall(TailCallMode::kAllow, false); }
967
968 TEST(InterpreterCallWithFeedback) {
969 TestInterpreterCall(TailCallMode::kDisallow, true);
970 }
971
972 TEST(InterpreterTailCallWithFeedback) {
973 TestInterpreterCall(TailCallMode::kAllow, true);
974 }
933 975
934 static BytecodeArrayBuilder& SetRegister(BytecodeArrayBuilder& builder, 976 static BytecodeArrayBuilder& SetRegister(BytecodeArrayBuilder& builder,
935 Register reg, int value, 977 Register reg, int value,
936 Register scratch) { 978 Register scratch) {
937 return builder.StoreAccumulatorInRegister(scratch) 979 return builder.StoreAccumulatorInRegister(scratch)
938 .LoadLiteral(Smi::FromInt(value)) 980 .LoadLiteral(Smi::FromInt(value))
939 .StoreAccumulatorInRegister(reg) 981 .StoreAccumulatorInRegister(reg)
940 .LoadAccumulatorWithRegister(scratch); 982 .LoadAccumulatorWithRegister(scratch);
941 } 983 }
942 984
(...skipping 3251 matching lines...) Expand 10 before | Expand all | Expand 10 after
4194 Handle<i::Object> return_value = callable().ToHandleChecked(); 4236 Handle<i::Object> return_value = callable().ToHandleChecked();
4195 CHECK(return_value->SameValue(*tests[i].second)); 4237 CHECK(return_value->SameValue(*tests[i].second));
4196 } 4238 }
4197 4239
4198 FLAG_ignition_generators = old_flag; 4240 FLAG_ignition_generators = old_flag;
4199 } 4241 }
4200 4242
4201 } // namespace interpreter 4243 } // namespace interpreter
4202 } // namespace internal 4244 } // namespace internal
4203 } // namespace v8 4245 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698