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

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

Issue 1688283003: [Interpreter] Implements calls through CallICStub in the interpreter. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: removes an unused label declaration. Created 4 years, 9 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
« no previous file with comments | « test/cctest/interpreter/test-bytecode-generator.cc ('k') | test/mjsunit/mjsunit.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/interpreter.h" 10 #include "src/interpreter/interpreter.h"
(...skipping 910 matching lines...) Expand 10 before | Expand all | Expand 10 after
921 CHECK_EQ(Smi::cast(*result), Smi::FromInt(999)); 921 CHECK_EQ(Smi::cast(*result), Smi::FromInt(999));
922 922
923 // Test transition to megamorphic IC. 923 // Test transition to megamorphic IC.
924 Handle<Object> object2 = 924 Handle<Object> object2 =
925 InterpreterTester::NewObject("({ val : 456, other : 123 })"); 925 InterpreterTester::NewObject("({ val : 456, other : 123 })");
926 callable(object2).ToHandleChecked(); 926 callable(object2).ToHandleChecked();
927 CHECK(Runtime::GetObjectProperty(isolate, object2, name).ToHandle(&result)); 927 CHECK(Runtime::GetObjectProperty(isolate, object2, name).ToHandle(&result));
928 CHECK_EQ(Smi::cast(*result), Smi::FromInt(999)); 928 CHECK_EQ(Smi::cast(*result), Smi::FromInt(999));
929 } 929 }
930 930
931 static void TestInterpreterCall(TailCallMode tail_call_mode) { 931 static void TestInterpreterCall(TailCallMode tail_call_mode,
932 bool has_feedback_slot) {
932 HandleAndZoneScope handles; 933 HandleAndZoneScope handles;
933 i::Isolate* isolate = handles.main_isolate(); 934 i::Isolate* isolate = handles.main_isolate();
934 i::Factory* factory = isolate->factory(); 935 i::Factory* factory = isolate->factory();
935 i::Zone zone; 936 i::Zone zone;
936 937
937 i::FeedbackVectorSpec feedback_spec(&zone); 938 i::FeedbackVectorSpec feedback_spec(&zone);
938 i::FeedbackVectorSlot slot = feedback_spec.AddLoadICSlot(); 939 i::FeedbackVectorSlot slot = feedback_spec.AddLoadICSlot();
940 i::FeedbackVectorSlot call_slot = feedback_spec.AddCallICSlot();
939 941
940 Handle<i::TypeFeedbackVector> vector = 942 Handle<i::TypeFeedbackVector> vector =
941 i::NewTypeFeedbackVector(isolate, &feedback_spec); 943 i::NewTypeFeedbackVector(isolate, &feedback_spec);
942 int slot_index = vector->GetIndex(slot); 944 int slot_index = vector->GetIndex(slot);
945 int call_slot_index = -1;
946 if (has_feedback_slot) {
947 call_slot_index = vector->GetIndex(call_slot);
948 }
943 949
944 Handle<i::String> name = factory->NewStringFromAsciiChecked("func"); 950 Handle<i::String> name = factory->NewStringFromAsciiChecked("func");
945 name = factory->string_table()->LookupString(isolate, name); 951 name = factory->string_table()->LookupString(isolate, name);
946 952
947 // Check with no args. 953 // Check with no args.
948 { 954 {
949 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone(), 1, 955 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone(), 1,
950 0, 1); 956 0, 1);
951 builder.LoadNamedProperty(builder.Parameter(0), name, slot_index) 957 builder.LoadNamedProperty(builder.Parameter(0), name, slot_index)
952 .StoreAccumulatorInRegister(Register(0)) 958 .StoreAccumulatorInRegister(Register(0));
953 .Call(Register(0), builder.Parameter(0), 1, 0, tail_call_mode) 959
954 .Return(); 960 if (has_feedback_slot) {
961 builder.CallIC(Register(0), builder.Parameter(0), 1, call_slot_index,
962 tail_call_mode);
963 } else {
964 builder.Call(Register(0), builder.Parameter(0), 1, tail_call_mode);
965 }
966
967 builder.Return();
955 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); 968 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray();
956 969
957 InterpreterTester tester(handles.main_isolate(), bytecode_array, vector); 970 InterpreterTester tester(handles.main_isolate(), bytecode_array, vector);
958 auto callable = tester.GetCallable<Handle<Object>>(); 971 auto callable = tester.GetCallable<Handle<Object>>();
959 972
960 Handle<Object> object = InterpreterTester::NewObject( 973 Handle<Object> object = InterpreterTester::NewObject(
961 "new (function Obj() { this.func = function() { return 0x265; }})()"); 974 "new (function Obj() { this.func = function() { return 0x265; }})()");
962 Handle<Object> return_val = callable(object).ToHandleChecked(); 975 Handle<Object> return_val = callable(object).ToHandleChecked();
963 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(0x265)); 976 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(0x265));
964 } 977 }
965 978
966 // Check that receiver is passed properly. 979 // Check that receiver is passed properly.
967 { 980 {
968 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone(), 1, 981 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone(), 1,
969 0, 1); 982 0, 1);
970 builder.LoadNamedProperty(builder.Parameter(0), name, slot_index) 983 builder.LoadNamedProperty(builder.Parameter(0), name, slot_index)
971 .StoreAccumulatorInRegister(Register(0)) 984 .StoreAccumulatorInRegister(Register(0));
972 .Call(Register(0), builder.Parameter(0), 1, 0, tail_call_mode) 985 if (has_feedback_slot) {
973 .Return(); 986 builder.CallIC(Register(0), builder.Parameter(0), 1, call_slot_index,
987 tail_call_mode);
988 } else {
989 builder.Call(Register(0), builder.Parameter(0), 1, tail_call_mode);
990 }
991 builder.Return();
974 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); 992 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray();
975 993
976 InterpreterTester tester(handles.main_isolate(), bytecode_array, vector); 994 InterpreterTester tester(handles.main_isolate(), bytecode_array, vector);
977 auto callable = tester.GetCallable<Handle<Object>>(); 995 auto callable = tester.GetCallable<Handle<Object>>();
978 996
979 Handle<Object> object = InterpreterTester::NewObject( 997 Handle<Object> object = InterpreterTester::NewObject(
980 "new (function Obj() {" 998 "new (function Obj() {"
981 " this.val = 1234;" 999 " this.val = 1234;"
982 " this.func = function() { return this.val; };" 1000 " this.func = function() { return this.val; };"
983 "})()"); 1001 "})()");
984 Handle<Object> return_val = callable(object).ToHandleChecked(); 1002 Handle<Object> return_val = callable(object).ToHandleChecked();
985 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(1234)); 1003 CHECK_EQ(Smi::cast(*return_val), Smi::FromInt(1234));
986 } 1004 }
987 1005
988 // Check with two parameters (+ receiver). 1006 // Check with two parameters (+ receiver).
989 { 1007 {
990 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone(), 1, 1008 BytecodeArrayBuilder builder(handles.main_isolate(), handles.main_zone(), 1,
991 0, 4); 1009 0, 4);
992 builder.LoadNamedProperty(builder.Parameter(0), name, slot_index) 1010 builder.LoadNamedProperty(builder.Parameter(0), name, slot_index)
993 .StoreAccumulatorInRegister(Register(0)) 1011 .StoreAccumulatorInRegister(Register(0))
994 .LoadAccumulatorWithRegister(builder.Parameter(0)) 1012 .LoadAccumulatorWithRegister(builder.Parameter(0))
995 .StoreAccumulatorInRegister(Register(1)) 1013 .StoreAccumulatorInRegister(Register(1))
996 .LoadLiteral(Smi::FromInt(51)) 1014 .LoadLiteral(Smi::FromInt(51))
997 .StoreAccumulatorInRegister(Register(2)) 1015 .StoreAccumulatorInRegister(Register(2))
998 .LoadLiteral(Smi::FromInt(11)) 1016 .LoadLiteral(Smi::FromInt(11))
999 .StoreAccumulatorInRegister(Register(3)) 1017 .StoreAccumulatorInRegister(Register(3));
1000 .Call(Register(0), Register(1), 3, 0, tail_call_mode) 1018
1001 .Return(); 1019 if (has_feedback_slot) {
1020 builder.CallIC(Register(0), Register(1), 3, call_slot_index,
1021 tail_call_mode);
1022 } else {
1023 builder.Call(Register(0), Register(1), 3, tail_call_mode);
1024 }
1025
1026 builder.Return();
1027
1002 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); 1028 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray();
1003 1029
1004 InterpreterTester tester(handles.main_isolate(), bytecode_array, vector); 1030 InterpreterTester tester(handles.main_isolate(), bytecode_array, vector);
1005 auto callable = tester.GetCallable<Handle<Object>>(); 1031 auto callable = tester.GetCallable<Handle<Object>>();
1006 1032
1007 Handle<Object> object = InterpreterTester::NewObject( 1033 Handle<Object> object = InterpreterTester::NewObject(
1008 "new (function Obj() { " 1034 "new (function Obj() { "
1009 " this.func = function(a, b) { return a - b; }" 1035 " this.func = function(a, b) { return a - b; }"
1010 "})()"); 1036 "})()");
1011 Handle<Object> return_val = callable(object).ToHandleChecked(); 1037 Handle<Object> return_val = callable(object).ToHandleChecked();
(...skipping 20 matching lines...) Expand all
1032 .StoreAccumulatorInRegister(Register(6)) 1058 .StoreAccumulatorInRegister(Register(6))
1033 .LoadLiteral(factory->NewStringFromAsciiChecked("f")) 1059 .LoadLiteral(factory->NewStringFromAsciiChecked("f"))
1034 .StoreAccumulatorInRegister(Register(7)) 1060 .StoreAccumulatorInRegister(Register(7))
1035 .LoadLiteral(factory->NewStringFromAsciiChecked("g")) 1061 .LoadLiteral(factory->NewStringFromAsciiChecked("g"))
1036 .StoreAccumulatorInRegister(Register(8)) 1062 .StoreAccumulatorInRegister(Register(8))
1037 .LoadLiteral(factory->NewStringFromAsciiChecked("h")) 1063 .LoadLiteral(factory->NewStringFromAsciiChecked("h"))
1038 .StoreAccumulatorInRegister(Register(9)) 1064 .StoreAccumulatorInRegister(Register(9))
1039 .LoadLiteral(factory->NewStringFromAsciiChecked("i")) 1065 .LoadLiteral(factory->NewStringFromAsciiChecked("i"))
1040 .StoreAccumulatorInRegister(Register(10)) 1066 .StoreAccumulatorInRegister(Register(10))
1041 .LoadLiteral(factory->NewStringFromAsciiChecked("j")) 1067 .LoadLiteral(factory->NewStringFromAsciiChecked("j"))
1042 .StoreAccumulatorInRegister(Register(11)) 1068 .StoreAccumulatorInRegister(Register(11));
1043 .Call(Register(0), Register(1), 11, 0, tail_call_mode) 1069
1044 .Return(); 1070 if (has_feedback_slot) {
1071 builder.CallIC(Register(0), Register(1), 11, call_slot_index,
1072 tail_call_mode);
1073 } else {
1074 builder.Call(Register(0), Register(1), 11, tail_call_mode);
1075 }
1076
1077 builder.Return();
1078
1045 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(); 1079 Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray();
1046 1080
1047 InterpreterTester tester(handles.main_isolate(), bytecode_array, vector); 1081 InterpreterTester tester(handles.main_isolate(), bytecode_array, vector);
1048 auto callable = tester.GetCallable<Handle<Object>>(); 1082 auto callable = tester.GetCallable<Handle<Object>>();
1049 1083
1050 Handle<Object> object = InterpreterTester::NewObject( 1084 Handle<Object> object = InterpreterTester::NewObject(
1051 "new (function Obj() { " 1085 "new (function Obj() { "
1052 " this.prefix = \"prefix_\";" 1086 " this.prefix = \"prefix_\";"
1053 " this.func = function(a, b, c, d, e, f, g, h, i, j) {" 1087 " this.func = function(a, b, c, d, e, f, g, h, i, j) {"
1054 " return this.prefix + a + b + c + d + e + f + g + h + i + j;" 1088 " return this.prefix + a + b + c + d + e + f + g + h + i + j;"
1055 " }" 1089 " }"
1056 "})()"); 1090 "})()");
1057 Handle<Object> return_val = callable(object).ToHandleChecked(); 1091 Handle<Object> return_val = callable(object).ToHandleChecked();
1058 Handle<i::String> expected = 1092 Handle<i::String> expected =
1059 factory->NewStringFromAsciiChecked("prefix_abcdefghij"); 1093 factory->NewStringFromAsciiChecked("prefix_abcdefghij");
1060 CHECK(i::String::cast(*return_val)->Equals(*expected)); 1094 CHECK(i::String::cast(*return_val)->Equals(*expected));
1061 } 1095 }
1062 } 1096 }
1063 1097
1064 TEST(InterpreterCall) { TestInterpreterCall(TailCallMode::kDisallow); } 1098 TEST(InterpreterCall) { TestInterpreterCall(TailCallMode::kDisallow, false); }
1065 1099
1066 TEST(InterpreterTailCall) { TestInterpreterCall(TailCallMode::kAllow); } 1100 TEST(InterpreterTailCall) { TestInterpreterCall(TailCallMode::kAllow, false); }
1101
1102 TEST(InterpreterCallIC) { TestInterpreterCall(TailCallMode::kDisallow, true); }
1103
1104 TEST(InterpreterTailCallIC) { TestInterpreterCall(TailCallMode::kAllow, true); }
1067 1105
1068 static BytecodeArrayBuilder& SetRegister(BytecodeArrayBuilder& builder, 1106 static BytecodeArrayBuilder& SetRegister(BytecodeArrayBuilder& builder,
1069 Register reg, int value, 1107 Register reg, int value,
1070 Register scratch) { 1108 Register scratch) {
1071 return builder.StoreAccumulatorInRegister(scratch) 1109 return builder.StoreAccumulatorInRegister(scratch)
1072 .LoadLiteral(Smi::FromInt(value)) 1110 .LoadLiteral(Smi::FromInt(value))
1073 .StoreAccumulatorInRegister(reg) 1111 .StoreAccumulatorInRegister(reg)
1074 .LoadAccumulatorWithRegister(scratch); 1112 .LoadAccumulatorWithRegister(scratch);
1075 } 1113 }
1076 1114
(...skipping 3081 matching lines...) Expand 10 before | Expand all | Expand 10 after
4158 Handle<i::Object> return_value = callable().ToHandleChecked(); 4196 Handle<i::Object> return_value = callable().ToHandleChecked();
4159 CHECK(return_value->SameValue(*const_decl[i].second)); 4197 CHECK(return_value->SameValue(*const_decl[i].second));
4160 } 4198 }
4161 4199
4162 FLAG_legacy_const = old_flag_legacy_const; 4200 FLAG_legacy_const = old_flag_legacy_const;
4163 } 4201 }
4164 4202
4165 } // namespace interpreter 4203 } // namespace interpreter
4166 } // namespace internal 4204 } // namespace internal
4167 } // namespace v8 4205 } // namespace v8
OLDNEW
« no previous file with comments | « test/cctest/interpreter/test-bytecode-generator.cc ('k') | test/mjsunit/mjsunit.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698