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

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

Issue 1378523005: [Interpreter] Add support for global declarations and load/store of global variables (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@int_toplevel
Patch Set: Fix test Created 5 years, 2 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 | « src/interpreter/interpreter.cc ('k') | test/cctest/interpreter/test-interpreter.cc » ('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/compiler.h" 7 #include "src/compiler.h"
8 #include "src/interpreter/bytecode-array-iterator.h" 8 #include "src/interpreter/bytecode-array-iterator.h"
9 #include "src/interpreter/bytecode-generator.h" 9 #include "src/interpreter/bytecode-generator.h"
10 #include "src/interpreter/interpreter.h" 10 #include "src/interpreter/interpreter.h"
(...skipping 17 matching lines...) Expand all
28 i::FLAG_ignition_filter = StrDup(kFunctionName); 28 i::FLAG_ignition_filter = StrDup(kFunctionName);
29 i::FLAG_always_opt = false; 29 i::FLAG_always_opt = false;
30 i::FLAG_allow_natives_syntax = true; 30 i::FLAG_allow_natives_syntax = true;
31 CcTest::i_isolate()->interpreter()->Initialize(); 31 CcTest::i_isolate()->interpreter()->Initialize();
32 } 32 }
33 33
34 Isolate* isolate() { return CcTest::i_isolate(); } 34 Isolate* isolate() { return CcTest::i_isolate(); }
35 Factory* factory() { return CcTest::i_isolate()->factory(); } 35 Factory* factory() { return CcTest::i_isolate()->factory(); }
36 36
37 37
38 Handle<BytecodeArray> MakeTopLevelBytecode(const char* source) {
39 const char* old_ignition_filter = i::FLAG_ignition_filter;
40 i::FLAG_ignition_filter = "*";
41 Local<v8::Script> script = v8_compile(source);
42 i::FLAG_ignition_filter = old_ignition_filter;
43 i::Handle<i::JSFunction> js_function = v8::Utils::OpenHandle(*script);
44 return handle(js_function->shared()->bytecode_array(), CcTest::i_isolate());
45 }
46
47
38 Handle<BytecodeArray> MakeBytecode(const char* script, 48 Handle<BytecodeArray> MakeBytecode(const char* script,
39 const char* function_name) { 49 const char* function_name) {
40 CompileRun(script); 50 CompileRun(script);
41 Local<Function> function = 51 Local<Function> function =
42 Local<Function>::Cast(CcTest::global()->Get(v8_str(function_name))); 52 Local<Function>::Cast(CcTest::global()->Get(v8_str(function_name)));
43 i::Handle<i::JSFunction> js_function = v8::Utils::OpenHandle(*function); 53 i::Handle<i::JSFunction> js_function = v8::Utils::OpenHandle(*function);
44 return handle(js_function->shared()->bytecode_array(), CcTest::i_isolate()); 54 return handle(js_function->shared()->bytecode_array(), CcTest::i_isolate());
45 } 55 }
46 56
47 57
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 } 121 }
112 122
113 123
114 template <typename T> 124 template <typename T>
115 static void CheckBytecodeArrayEqual(struct ExpectedSnippet<T> expected, 125 static void CheckBytecodeArrayEqual(struct ExpectedSnippet<T> expected,
116 Handle<BytecodeArray> actual, 126 Handle<BytecodeArray> actual,
117 bool has_unknown = false) { 127 bool has_unknown = false) {
118 CHECK_EQ(actual->frame_size(), expected.frame_size); 128 CHECK_EQ(actual->frame_size(), expected.frame_size);
119 CHECK_EQ(actual->parameter_count(), expected.parameter_count); 129 CHECK_EQ(actual->parameter_count(), expected.parameter_count);
120 CHECK_EQ(actual->length(), expected.bytecode_length); 130 CHECK_EQ(actual->length(), expected.bytecode_length);
121 if (expected.constant_count == 0) { 131 if (expected.constant_count != -1) {
122 CHECK_EQ(actual->constant_pool(), CcTest::heap()->empty_fixed_array()); 132 if (expected.constant_count == 0) {
123 } else { 133 CHECK_EQ(actual->constant_pool(), CcTest::heap()->empty_fixed_array());
124 CHECK_EQ(actual->constant_pool()->length(), expected.constant_count); 134 } else {
125 for (int i = 0; i < expected.constant_count; i++) { 135 CHECK_EQ(actual->constant_pool()->length(), expected.constant_count);
126 CheckConstant(expected.constants[i], actual->constant_pool()->get(i)); 136 for (int i = 0; i < expected.constant_count; i++) {
137 CheckConstant(expected.constants[i], actual->constant_pool()->get(i));
138 }
127 } 139 }
128 } 140 }
129 141
130 BytecodeArrayIterator iterator(actual); 142 BytecodeArrayIterator iterator(actual);
131 int i = 0; 143 int i = 0;
132 while (!iterator.done()) { 144 while (!iterator.done()) {
133 int bytecode_index = i++; 145 int bytecode_index = i++;
134 Bytecode bytecode = iterator.current_bytecode(); 146 Bytecode bytecode = iterator.current_bytecode();
135 if (Bytecodes::ToByte(bytecode) != expected.bytecode[bytecode_index]) { 147 if (Bytecodes::ToByte(bytecode) != expected.bytecode[bytecode_index]) {
136 std::ostringstream stream; 148 std::ostringstream stream;
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 ExpectedSnippet<int> snippets[] = { 269 ExpectedSnippet<int> snippets[] = {
258 {"function f() { return this; }", 270 {"function f() { return this; }",
259 0, 1, 3, {B(Ldar), R(helper.kLastParamIndex), B(Return)}, 0}, 271 0, 1, 3, {B(Ldar), R(helper.kLastParamIndex), B(Return)}, 0},
260 {"function f(arg1) { return arg1; }", 272 {"function f(arg1) { return arg1; }",
261 0, 2, 3, {B(Ldar), R(helper.kLastParamIndex), B(Return)}, 0}, 273 0, 2, 3, {B(Ldar), R(helper.kLastParamIndex), B(Return)}, 0},
262 {"function f(arg1) { return this; }", 274 {"function f(arg1) { return this; }",
263 0, 2, 3, {B(Ldar), R(helper.kLastParamIndex - 1), B(Return)}, 0}, 275 0, 2, 3, {B(Ldar), R(helper.kLastParamIndex - 1), B(Return)}, 0},
264 {"function f(arg1, arg2, arg3, arg4, arg5, arg6, arg7) { return arg4; }", 276 {"function f(arg1, arg2, arg3, arg4, arg5, arg6, arg7) { return arg4; }",
265 0, 8, 3, {B(Ldar), R(helper.kLastParamIndex - 3), B(Return)}, 0}, 277 0, 8, 3, {B(Ldar), R(helper.kLastParamIndex - 3), B(Return)}, 0},
266 {"function f(arg1, arg2, arg3, arg4, arg5, arg6, arg7) { return this; }", 278 {"function f(arg1, arg2, arg3, arg4, arg5, arg6, arg7) { return this; }",
267 0, 8, 3, {B(Ldar), R(helper.kLastParamIndex - 7), B(Return)}, 0} 279 0, 8, 3, {B(Ldar), R(helper.kLastParamIndex - 7), B(Return)}, 0},
280 {"function f(arg1) { arg1 = 1; }",
281 0, 2, 6,
282 {B(LdaSmi8), U8(1), //
283 B(Star), R(helper.kLastParamIndex), //
284 B(LdaUndefined), //
285 B(Return)},
286 0},
287 {"function f(arg1, arg2, arg3, arg4) { arg2 = 1; }",
288 0, 5, 6,
289 {B(LdaSmi8), U8(1), //
290 B(Star), R(helper.kLastParamIndex - 2), //
291 B(LdaUndefined), //
292 B(Return)},
293 0},
268 }; 294 };
269 295
270 for (size_t i = 0; i < arraysize(snippets); i++) { 296 for (size_t i = 0; i < arraysize(snippets); i++) {
271 Handle<BytecodeArray> bytecode_array = 297 Handle<BytecodeArray> bytecode_array =
272 helper.MakeBytecodeForFunction(snippets[i].code_snippet); 298 helper.MakeBytecodeForFunction(snippets[i].code_snippet);
273 CheckBytecodeArrayEqual(snippets[i], bytecode_array); 299 CheckBytecodeArrayEqual(snippets[i], bytecode_array);
274 } 300 }
275 } 301 }
276 302
277 303
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after
684 CheckBytecodeArrayEqual(snippets[i], bytecode_array); 710 CheckBytecodeArrayEqual(snippets[i], bytecode_array);
685 } 711 }
686 } 712 }
687 713
688 714
689 #define FUNC_ARG "new (function Obj() { this.func = function() { return; }})()" 715 #define FUNC_ARG "new (function Obj() { this.func = function() { return; }})()"
690 716
691 717
692 TEST(PropertyCall) { 718 TEST(PropertyCall) {
693 InitializedHandleScope handle_scope; 719 InitializedHandleScope handle_scope;
694 BytecodeGeneratorHelper helper; // 720 BytecodeGeneratorHelper helper;
695 Zone zone; 721 Zone zone;
696 722
697 FeedbackVectorSpec feedback_spec(&zone); 723 FeedbackVectorSpec feedback_spec(&zone);
698 FeedbackVectorSlot slot1 = feedback_spec.AddLoadICSlot(); 724 FeedbackVectorSlot slot1 = feedback_spec.AddLoadICSlot();
699 FeedbackVectorSlot slot2 = feedback_spec.AddLoadICSlot(); 725 FeedbackVectorSlot slot2 = feedback_spec.AddLoadICSlot();
700 USE(slot1); 726 USE(slot1);
701 727
702 Handle<i::TypeFeedbackVector> vector = 728 Handle<i::TypeFeedbackVector> vector =
703 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec); 729 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec);
704 730
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
795 }; 821 };
796 822
797 for (size_t i = 0; i < arraysize(snippets); i++) { 823 for (size_t i = 0; i < arraysize(snippets); i++) {
798 Handle<BytecodeArray> bytecode_array = 824 Handle<BytecodeArray> bytecode_array =
799 helper.MakeBytecode(snippets[i].code_snippet, "f"); 825 helper.MakeBytecode(snippets[i].code_snippet, "f");
800 CheckBytecodeArrayEqual(snippets[i], bytecode_array, true); 826 CheckBytecodeArrayEqual(snippets[i], bytecode_array, true);
801 } 827 }
802 } 828 }
803 829
804 830
831 TEST(StoreGlobal) {
832 InitializedHandleScope handle_scope;
833 BytecodeGeneratorHelper helper;
834
835 ExpectedSnippet<int> snippets[] = {
836 {
837 "var a = 1;\nfunction f() { a = 2; }\nf()",
838 0,
839 1,
840 6,
841 {
842 B(LdaSmi8), U8(2), //
843 B(StaGlobal), _, //
844 B(LdaUndefined), //
845 B(Return) //
846 },
847 },
848 {
849 "var a = \"test\"; function f(b) { a = b; }\nf(\"global\")",
850 0,
851 2,
852 6,
853 {
854 B(Ldar), R(helper.kLastParamIndex), //
855 B(StaGlobal), _, //
856 B(LdaUndefined), //
857 B(Return) //
858 },
859 },
860 };
861
862 for (size_t i = 0; i < arraysize(snippets); i++) {
863 Handle<BytecodeArray> bytecode_array =
864 helper.MakeBytecode(snippets[i].code_snippet, "f");
865 CheckBytecodeArrayEqual(snippets[i], bytecode_array, true);
866 }
867 }
868
869
805 TEST(CallGlobal) { 870 TEST(CallGlobal) {
806 InitializedHandleScope handle_scope; 871 InitializedHandleScope handle_scope;
807 BytecodeGeneratorHelper helper; 872 BytecodeGeneratorHelper helper;
808 873
809 ExpectedSnippet<int> snippets[] = { 874 ExpectedSnippet<int> snippets[] = {
810 { 875 {
811 "function t() { }\nfunction f() { return t(); }\nf()", 876 "function t() { }\nfunction f() { return t(); }\nf()",
812 2 * kPointerSize, 877 2 * kPointerSize,
813 1, 878 1,
814 12, 879 12,
(...skipping 30 matching lines...) Expand all
845 910
846 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); 911 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
847 for (size_t i = 0; i < num_snippets; i++) { 912 for (size_t i = 0; i < num_snippets; i++) {
848 Handle<BytecodeArray> bytecode_array = 913 Handle<BytecodeArray> bytecode_array =
849 helper.MakeBytecode(snippets[i].code_snippet, "f"); 914 helper.MakeBytecode(snippets[i].code_snippet, "f");
850 CheckBytecodeArrayEqual(snippets[i], bytecode_array, true); 915 CheckBytecodeArrayEqual(snippets[i], bytecode_array, true);
851 } 916 }
852 } 917 }
853 918
854 919
920 TEST(LoadUnallocated) {
921 InitializedHandleScope handle_scope;
922 BytecodeGeneratorHelper helper;
923 Zone zone;
924
925 int context_reg = Register::function_context().index();
926 int global_index = Context::GLOBAL_OBJECT_INDEX;
927
928 FeedbackVectorSpec feedback_spec(&zone);
929 FeedbackVectorSlot slot1 = feedback_spec.AddStoreICSlot();
930
931 Handle<i::TypeFeedbackVector> vector =
932 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec);
933
934 ExpectedSnippet<const char*> snippets[] = {
935 {"a = 1;\nfunction f() { return a; }\nf()",
936 1 * kPointerSize,
937 1,
938 11,
939 {B(LdaContextSlot), R(context_reg), U8(global_index), //
940 B(Star), R(0), //
941 B(LdaConstant), U8(0), //
942 B(LoadICSloppy), R(0), U8(vector->GetIndex(slot1)), //
943 B(Return)},
944 1,
945 {"a"}},
946 {"function f() { return t; }\nt = 1;\nf()",
947 1 * kPointerSize,
948 1,
949 11,
950 {B(LdaContextSlot), R(context_reg), U8(global_index), //
951 B(Star), R(0), //
952 B(LdaConstant), U8(0), //
953 B(LoadICSloppy), R(0), U8(vector->GetIndex(slot1)), //
954 B(Return)},
955 1,
956 {"t"}},
957 };
958
959 for (size_t i = 0; i < arraysize(snippets); i++) {
960 Handle<BytecodeArray> bytecode_array =
961 helper.MakeBytecode(snippets[i].code_snippet, "f");
962 CheckBytecodeArrayEqual(snippets[i], bytecode_array, true);
963 }
964 }
965
966
967 TEST(StoreUnallocated) {
968 InitializedHandleScope handle_scope;
969 BytecodeGeneratorHelper helper;
970 Zone zone;
971
972 int context_reg = Register::function_context().index();
973 int global_index = Context::GLOBAL_OBJECT_INDEX;
974
975 FeedbackVectorSpec feedback_spec(&zone);
976 FeedbackVectorSlot slot1 = feedback_spec.AddStoreICSlot();
977
978 Handle<i::TypeFeedbackVector> vector =
979 i::NewTypeFeedbackVector(helper.isolate(), &feedback_spec);
980
981 ExpectedSnippet<const char*> snippets[] = {
982 {"a = 1;\nfunction f() { a = 2; }\nf()",
983 3 * kPointerSize,
984 1,
985 21,
986 {B(LdaSmi8), U8(2), //
987 B(Star), R(0), //
988 B(LdaContextSlot), R(context_reg), U8(global_index), //
989 B(Star), R(1), //
990 B(LdaConstant), U8(0), //
991 B(Star), R(2), //
992 B(Ldar), R(0), //
993 B(StoreICSloppy), R(1), R(2), U8(vector->GetIndex(slot1)), //
994 B(LdaUndefined), //
995 B(Return)},
996 1,
997 {"a"}},
998 {"function f() { t = 4; }\nf()\nt = 1;",
999 3 * kPointerSize,
1000 1,
1001 21,
1002 {B(LdaSmi8), U8(4), //
1003 B(Star), R(0), //
1004 B(LdaContextSlot), R(context_reg), U8(global_index), //
1005 B(Star), R(1), //
1006 B(LdaConstant), U8(0), //
1007 B(Star), R(2), //
1008 B(Ldar), R(0), //
1009 B(StoreICSloppy), R(1), R(2), U8(vector->GetIndex(slot1)), //
1010 B(LdaUndefined), //
1011 B(Return)},
1012 1,
1013 {"t"}},
1014 };
1015
1016 for (size_t i = 0; i < arraysize(snippets); i++) {
1017 Handle<BytecodeArray> bytecode_array =
1018 helper.MakeBytecode(snippets[i].code_snippet, "f");
1019 CheckBytecodeArrayEqual(snippets[i], bytecode_array, true);
1020 }
1021 }
1022
1023
855 TEST(CallRuntime) { 1024 TEST(CallRuntime) {
856 InitializedHandleScope handle_scope; 1025 InitializedHandleScope handle_scope;
857 BytecodeGeneratorHelper helper; 1026 BytecodeGeneratorHelper helper;
858 1027
859 ExpectedSnippet<int> snippets[] = { 1028 ExpectedSnippet<int> snippets[] = {
860 { 1029 {
861 "function f() { %TheHole() }\nf()", 1030 "function f() { %TheHole() }\nf()",
862 1 * kPointerSize, 1031 1 * kPointerSize,
863 1, 1032 1,
864 7, 1033 7,
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
1068 }; 1237 };
1069 1238
1070 for (size_t i = 0; i < arraysize(snippets); i++) { 1239 for (size_t i = 0; i < arraysize(snippets); i++) {
1071 Handle<BytecodeArray> bytecode_array = 1240 Handle<BytecodeArray> bytecode_array =
1072 helper.MakeBytecode(snippets[i].code_snippet, helper.kFunctionName); 1241 helper.MakeBytecode(snippets[i].code_snippet, helper.kFunctionName);
1073 CheckBytecodeArrayEqual(snippets[i], bytecode_array); 1242 CheckBytecodeArrayEqual(snippets[i], bytecode_array);
1074 } 1243 }
1075 } 1244 }
1076 1245
1077 1246
1247 TEST(DeclareGlobals) {
1248 InitializedHandleScope handle_scope;
1249 BytecodeGeneratorHelper helper;
1250
1251 ExpectedSnippet<int> snippets[] = {
1252 {"var a = 1;",
1253 4 * kPointerSize,
1254 1,
1255 30,
1256 {
1257 B(LdaConstant), U8(0), //
1258 B(Star), R(1), //
1259 B(LdaZero), //
1260 B(Star), R(2), //
1261 B(CallRuntime), U16(Runtime::kDeclareGlobals), R(1), U8(2), //
1262 B(LdaConstant), U8(1), //
1263 B(Star), R(1), //
1264 B(LdaZero), //
1265 B(Star), R(2), //
1266 B(LdaSmi8), U8(1), //
1267 B(Star), R(3), //
1268 B(CallRuntime), U16(Runtime::kInitializeVarGlobal), R(1), //
1269 U8(3), //
1270 B(LdaUndefined), //
1271 B(Return) //
1272 },
1273 -1},
1274 {"function f() {}",
1275 2 * kPointerSize,
1276 1,
1277 14,
1278 {
1279 B(LdaConstant), U8(0), //
1280 B(Star), R(0), //
1281 B(LdaZero), //
1282 B(Star), R(1), //
1283 B(CallRuntime), U16(Runtime::kDeclareGlobals), R(0), U8(2), //
1284 B(LdaUndefined), //
1285 B(Return) //
1286 },
1287 -1},
1288 };
1289
1290 for (size_t i = 0; i < arraysize(snippets); i++) {
1291 Handle<BytecodeArray> bytecode_array =
1292 helper.MakeTopLevelBytecode(snippets[i].code_snippet);
1293 CheckBytecodeArrayEqual(snippets[i], bytecode_array, true);
1294 }
1295 }
1296
1297
1078 TEST(BasicLoops) { 1298 TEST(BasicLoops) {
1079 InitializedHandleScope handle_scope; 1299 InitializedHandleScope handle_scope;
1080 BytecodeGeneratorHelper helper; 1300 BytecodeGeneratorHelper helper;
1081 1301
1082 ExpectedSnippet<int> snippets[] = { 1302 ExpectedSnippet<int> snippets[] = {
1083 {"var x = 0;" 1303 {"var x = 0;"
1084 "var y = 1;" 1304 "var y = 1;"
1085 "while (x < 10) {" 1305 "while (x < 10) {"
1086 " y = y * 10;" 1306 " y = y * 10;"
1087 " x = x + 1;" 1307 " x = x + 1;"
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after
1451 Handle<BytecodeArray> bytecode_array = 1671 Handle<BytecodeArray> bytecode_array =
1452 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet); 1672 helper.MakeBytecodeForFunctionBody(snippets[i].code_snippet);
1453 CheckBytecodeArrayEqual(snippets[i], bytecode_array); 1673 CheckBytecodeArrayEqual(snippets[i], bytecode_array);
1454 } 1674 }
1455 } 1675 }
1456 1676
1457 1677
1458 } // namespace interpreter 1678 } // namespace interpreter
1459 } // namespace internal 1679 } // namespace internal
1460 } // namespace v8 1680 } // namespace v8
OLDNEW
« no previous file with comments | « src/interpreter/interpreter.cc ('k') | test/cctest/interpreter/test-interpreter.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698