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

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: 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
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 16 matching lines...) Expand all
27 i::FLAG_ignition_filter = StrDup(kFunctionName); 27 i::FLAG_ignition_filter = StrDup(kFunctionName);
28 i::FLAG_always_opt = false; 28 i::FLAG_always_opt = false;
29 i::FLAG_allow_natives_syntax = true; 29 i::FLAG_allow_natives_syntax = true;
30 CcTest::i_isolate()->interpreter()->Initialize(); 30 CcTest::i_isolate()->interpreter()->Initialize();
31 } 31 }
32 32
33 33
34 Factory* factory() { return CcTest::i_isolate()->factory(); } 34 Factory* factory() { return CcTest::i_isolate()->factory(); }
35 35
36 36
37 Handle<BytecodeArray> MakeTopLevelBytecode(const char* source) {
38 const char* old_ignition_filter = i::FLAG_ignition_filter;
39 i::FLAG_ignition_filter = "*";
40 Local<v8::Script> script = v8_compile(source);
41 i::FLAG_ignition_filter = old_ignition_filter;
42 i::Handle<i::JSFunction> js_function = v8::Utils::OpenHandle(*script);
43 return handle(js_function->shared()->bytecode_array(), CcTest::i_isolate());
44 }
45
46
37 Handle<BytecodeArray> MakeBytecode(const char* script, 47 Handle<BytecodeArray> MakeBytecode(const char* script,
38 const char* function_name) { 48 const char* function_name) {
39 CompileRun(script); 49 CompileRun(script);
40 Local<Function> function = 50 Local<Function> function =
41 Local<Function>::Cast(CcTest::global()->Get(v8_str(function_name))); 51 Local<Function>::Cast(CcTest::global()->Get(v8_str(function_name)));
42 i::Handle<i::JSFunction> js_function = v8::Utils::OpenHandle(*function); 52 i::Handle<i::JSFunction> js_function = v8::Utils::OpenHandle(*function);
43 return handle(js_function->shared()->bytecode_array(), CcTest::i_isolate()); 53 return handle(js_function->shared()->bytecode_array(), CcTest::i_isolate());
44 } 54 }
45 55
46 56
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 } 119 }
110 120
111 121
112 template <typename T> 122 template <typename T>
113 static void CheckBytecodeArrayEqual(struct ExpectedSnippet<T> expected, 123 static void CheckBytecodeArrayEqual(struct ExpectedSnippet<T> expected,
114 Handle<BytecodeArray> actual, 124 Handle<BytecodeArray> actual,
115 bool has_unknown = false) { 125 bool has_unknown = false) {
116 CHECK_EQ(actual->frame_size(), expected.frame_size); 126 CHECK_EQ(actual->frame_size(), expected.frame_size);
117 CHECK_EQ(actual->parameter_count(), expected.parameter_count); 127 CHECK_EQ(actual->parameter_count(), expected.parameter_count);
118 CHECK_EQ(actual->length(), expected.bytecode_length); 128 CHECK_EQ(actual->length(), expected.bytecode_length);
119 if (expected.constant_count == 0) { 129 if (expected.constant_count != -1) {
120 CHECK_EQ(actual->constant_pool(), CcTest::heap()->empty_fixed_array()); 130 if (expected.constant_count == 0) {
121 } else { 131 CHECK_EQ(actual->constant_pool(), CcTest::heap()->empty_fixed_array());
122 CHECK_EQ(actual->constant_pool()->length(), expected.constant_count); 132 } else {
123 for (int i = 0; i < expected.constant_count; i++) { 133 CHECK_EQ(actual->constant_pool()->length(), expected.constant_count);
124 CheckConstant(expected.constants[i], actual->constant_pool()->get(i)); 134 for (int i = 0; i < expected.constant_count; i++) {
135 CheckConstant(expected.constants[i], actual->constant_pool()->get(i));
136 }
125 } 137 }
126 } 138 }
127 139
128 BytecodeArrayIterator iterator(actual); 140 BytecodeArrayIterator iterator(actual);
129 int i = 0; 141 int i = 0;
130 while (!iterator.done()) { 142 while (!iterator.done()) {
131 int bytecode_index = i++; 143 int bytecode_index = i++;
132 Bytecode bytecode = iterator.current_bytecode(); 144 Bytecode bytecode = iterator.current_bytecode();
133 if (Bytecodes::ToByte(bytecode) != expected.bytecode[bytecode_index]) { 145 if (Bytecodes::ToByte(bytecode) != expected.bytecode[bytecode_index]) {
134 std::ostringstream stream; 146 std::ostringstream stream;
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 ExpectedSnippet<int> snippets[] = { 263 ExpectedSnippet<int> snippets[] = {
252 {"function f() { return this; }", 264 {"function f() { return this; }",
253 0, 1, 3, {B(Ldar), R(helper.kLastParamIndex), B(Return)}, 0}, 265 0, 1, 3, {B(Ldar), R(helper.kLastParamIndex), B(Return)}, 0},
254 {"function f(arg1) { return arg1; }", 266 {"function f(arg1) { return arg1; }",
255 0, 2, 3, {B(Ldar), R(helper.kLastParamIndex), B(Return)}, 0}, 267 0, 2, 3, {B(Ldar), R(helper.kLastParamIndex), B(Return)}, 0},
256 {"function f(arg1) { return this; }", 268 {"function f(arg1) { return this; }",
257 0, 2, 3, {B(Ldar), R(helper.kLastParamIndex - 1), B(Return)}, 0}, 269 0, 2, 3, {B(Ldar), R(helper.kLastParamIndex - 1), B(Return)}, 0},
258 {"function f(arg1, arg2, arg3, arg4, arg5, arg6, arg7) { return arg4; }", 270 {"function f(arg1, arg2, arg3, arg4, arg5, arg6, arg7) { return arg4; }",
259 0, 8, 3, {B(Ldar), R(helper.kLastParamIndex - 3), B(Return)}, 0}, 271 0, 8, 3, {B(Ldar), R(helper.kLastParamIndex - 3), B(Return)}, 0},
260 {"function f(arg1, arg2, arg3, arg4, arg5, arg6, arg7) { return this; }", 272 {"function f(arg1, arg2, arg3, arg4, arg5, arg6, arg7) { return this; }",
261 0, 8, 3, {B(Ldar), R(helper.kLastParamIndex - 7), B(Return)}, 0} 273 0, 8, 3, {B(Ldar), R(helper.kLastParamIndex - 7), B(Return)}, 0},
274 {"function f(arg1) { arg1 = 1; }",
275 0, 2, 6,
276 {B(LdaSmi8), U8(1), //
277 B(Star), R(helper.kLastParamIndex), //
278 B(LdaUndefined), //
279 B(Return)},
280 0},
281 {"function f(arg1, arg2, arg3, arg4) { arg2 = 1; }",
282 0, 5, 6,
283 {B(LdaSmi8), U8(1), //
284 B(Star), R(helper.kLastParamIndex - 2), //
285 B(LdaUndefined), //
286 B(Return)},
287 0},
262 }; 288 };
263 289
264 for (size_t i = 0; i < arraysize(snippets); i++) { 290 for (size_t i = 0; i < arraysize(snippets); i++) {
265 Handle<BytecodeArray> bytecode_array = 291 Handle<BytecodeArray> bytecode_array =
266 helper.MakeBytecodeForFunction(snippets[i].code_snippet); 292 helper.MakeBytecodeForFunction(snippets[i].code_snippet);
267 CheckBytecodeArrayEqual(snippets[i], bytecode_array); 293 CheckBytecodeArrayEqual(snippets[i], bytecode_array);
268 } 294 }
269 } 295 }
270 296
271 297
(...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after
706 }; 732 };
707 733
708 for (size_t i = 0; i < arraysize(snippets); i++) { 734 for (size_t i = 0; i < arraysize(snippets); i++) {
709 Handle<BytecodeArray> bytecode_array = 735 Handle<BytecodeArray> bytecode_array =
710 helper.MakeBytecode(snippets[i].code_snippet, "f"); 736 helper.MakeBytecode(snippets[i].code_snippet, "f");
711 CheckBytecodeArrayEqual(snippets[i], bytecode_array, true); 737 CheckBytecodeArrayEqual(snippets[i], bytecode_array, true);
712 } 738 }
713 } 739 }
714 740
715 741
742 TEST(StoreGlobal) {
743 InitializedHandleScope handle_scope;
744 BytecodeGeneratorHelper helper;
745
746 ExpectedSnippet<int> snippets[] = {
747 {
748 "var a = 1;\nfunction f() { a = 2; }\nf()",
749 0,
750 1,
751 6,
752 {
753 B(LdaSmi8), U8(2), //
754 B(StaGlobal), _, //
755 B(LdaUndefined), //
756 B(Return) //
757 },
758 },
759 {
760 "var a = \"test\"; function f(b) { a = b; }\nf(\"global\")",
761 0,
762 2,
763 6,
764 {
765 B(Ldar), R(helper.kLastParamIndex), //
766 B(StaGlobal), _, //
767 B(LdaUndefined), //
768 B(Return) //
769 },
770 },
771 };
772
773 for (size_t i = 0; i < arraysize(snippets); i++) {
774 Handle<BytecodeArray> bytecode_array =
775 helper.MakeBytecode(snippets[i].code_snippet, "f");
776 CheckBytecodeArrayEqual(snippets[i], bytecode_array, true);
777 }
778 }
779
780
716 TEST(CallGlobal) { 781 TEST(CallGlobal) {
717 InitializedHandleScope handle_scope; 782 InitializedHandleScope handle_scope;
718 BytecodeGeneratorHelper helper; 783 BytecodeGeneratorHelper helper;
719 784
720 ExpectedSnippet<int> snippets[] = { 785 ExpectedSnippet<int> snippets[] = {
721 { 786 {
722 "function t() { }\nfunction f() { return t(); }\nf()", 787 "function t() { }\nfunction f() { return t(); }\nf()",
723 2 * kPointerSize, 788 2 * kPointerSize,
724 1, 789 1,
725 12, 790 12,
(...skipping 30 matching lines...) Expand all
756 821
757 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); 822 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
758 for (size_t i = 0; i < num_snippets; i++) { 823 for (size_t i = 0; i < num_snippets; i++) {
759 Handle<BytecodeArray> bytecode_array = 824 Handle<BytecodeArray> bytecode_array =
760 helper.MakeBytecode(snippets[i].code_snippet, "f"); 825 helper.MakeBytecode(snippets[i].code_snippet, "f");
761 CheckBytecodeArrayEqual(snippets[i], bytecode_array, true); 826 CheckBytecodeArrayEqual(snippets[i], bytecode_array, true);
762 } 827 }
763 } 828 }
764 829
765 830
831 TEST(LoadUnallocated) {
832 InitializedHandleScope handle_scope;
833 BytecodeGeneratorHelper helper;
834
835 int context_reg = Register::function_context().index();
836 int global_index = Context::GLOBAL_OBJECT_INDEX;
837 Code::Kind ic_kinds[] = {i::Code::LOAD_IC};
838 FeedbackVectorSpec feedback_spec(0, 1, ic_kinds);
839 Handle<i::TypeFeedbackVector> vector =
840 helper.factory()->NewTypeFeedbackVector(&feedback_spec);
841
842 ExpectedSnippet<const char*> snippets[] = {
843 {"a = 1;\nfunction f() { return a; }\nf()",
844 1 * kPointerSize,
845 1,
846 11,
847 {B(LdaContextSlot), R(context_reg), U8(global_index), //
848 B(Star), R(0), //
849 B(LdaConstant), U8(0), //
850 B(LoadIC), R(0), U8(vector->first_ic_slot_index()), //
851 B(Return)},
852 1,
853 {"a"}},
854 {"function f() { return t; }\nf()\nt = 1;",
855 1 * kPointerSize,
856 1,
857 11,
858 {B(LdaContextSlot), R(context_reg), U8(global_index), //
859 B(Star), R(0), //
860 B(LdaConstant), U8(0), //
861 B(LoadIC), R(0), U8(vector->first_ic_slot_index()), //
862 B(Return)},
863 1,
864 {"t"}},
865 };
866
867 for (size_t i = 0; i < arraysize(snippets); i++) {
868 Handle<BytecodeArray> bytecode_array =
869 helper.MakeBytecode(snippets[i].code_snippet, "f");
870 CheckBytecodeArrayEqual(snippets[i], bytecode_array, true);
871 }
872 }
873
874
875 TEST(StoreUnallocated) {
876 InitializedHandleScope handle_scope;
877 BytecodeGeneratorHelper helper;
878
879 int context_reg = Register::function_context().index();
880 int global_index = Context::GLOBAL_OBJECT_INDEX;
881 Code::Kind ic_kinds[] = {i::Code::LOAD_IC};
882 FeedbackVectorSpec feedback_spec(0, 1, ic_kinds);
883 Handle<i::TypeFeedbackVector> vector =
884 helper.factory()->NewTypeFeedbackVector(&feedback_spec);
885
886 ExpectedSnippet<const char*> snippets[] = {
887 {"a = 1;\nfunction f() { a = 2; }\nf()",
888 3 * kPointerSize,
889 1,
890 21,
891 {B(LdaSmi8), U8(2), //
892 B(Star), R(0), //
893 B(LdaContextSlot), R(context_reg), U8(global_index), //
894 B(Star), R(1), //
895 B(LdaConstant), U8(0), //
896 B(Star), R(2), //
897 B(Ldar), R(0), //
898 B(StoreIC), R(1), R(2), U8(vector->first_ic_slot_index()), //
899 B(LdaUndefined), //
900 B(Return)},
901 1,
902 {"a"}},
903 {"function f() { t = 4; }\nf()\nt = 1;",
904 3 * kPointerSize,
905 1,
906 21,
907 {B(LdaSmi8), U8(4), //
908 B(Star), R(0), //
909 B(LdaContextSlot), R(context_reg), U8(global_index), //
910 B(Star), R(1), //
911 B(LdaConstant), U8(0), //
912 B(Star), R(2), //
913 B(Ldar), R(0), //
914 B(StoreIC), R(1), R(2), U8(vector->first_ic_slot_index()), //
915 B(LdaUndefined), //
916 B(Return)},
917 1,
918 {"t"}},
919 };
920
921 for (size_t i = 0; i < arraysize(snippets); i++) {
922 Handle<BytecodeArray> bytecode_array =
923 helper.MakeBytecode(snippets[i].code_snippet, "f");
924 CheckBytecodeArrayEqual(snippets[i], bytecode_array, true);
925 }
926 }
927
928
766 TEST(CallRuntime) { 929 TEST(CallRuntime) {
767 InitializedHandleScope handle_scope; 930 InitializedHandleScope handle_scope;
768 BytecodeGeneratorHelper helper; 931 BytecodeGeneratorHelper helper;
769 932
770 ExpectedSnippet<int> snippets[] = { 933 ExpectedSnippet<int> snippets[] = {
771 { 934 {
772 "function f() { %TheHole() }\nf()", 935 "function f() { %TheHole() }\nf()",
773 1 * kPointerSize, 936 1 * kPointerSize,
774 1, 937 1,
775 7, 938 7,
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
946 B(Return), // 1109 B(Return), //
947 B(Jump), U8(5), // TODO(oth): Unreachable jump after return 1110 B(Jump), U8(5), // TODO(oth): Unreachable jump after return
948 B(LdaConstant), U8(3), // 1111 B(LdaConstant), U8(3), //
949 B(Return), // 1112 B(Return), //
950 B(LdaUndefined), // 1113 B(LdaUndefined), //
951 B(Return)}, // 1114 B(Return)}, //
952 4, 1115 4,
953 {helper.factory()->NewHeapNumber(0.01), 1116 {helper.factory()->NewHeapNumber(0.01),
954 helper.factory()->NewNumberFromInt(200), 1117 helper.factory()->NewNumberFromInt(200),
955 helper.factory()->NewNumberFromInt(199), 1118 helper.factory()->NewNumberFromInt(199),
956 helper.factory()->NewNumberFromInt(-200)}}}; 1119 helper.factory()->NewNumberFromInt(-200)}}
1120 };
957 1121
958 for (size_t i = 0; i < arraysize(snippets); i++) { 1122 for (size_t i = 0; i < arraysize(snippets); i++) {
959 Handle<BytecodeArray> bytecode_array = 1123 Handle<BytecodeArray> bytecode_array =
960 helper.MakeBytecodeForFunction(snippets[i].code_snippet); 1124 helper.MakeBytecodeForFunction(snippets[i].code_snippet);
961 CheckBytecodeArrayEqual(snippets[i], bytecode_array); 1125 CheckBytecodeArrayEqual(snippets[i], bytecode_array);
962 } 1126 }
963 } 1127 }
964 1128
965 1129
1130 TEST(DeclareGlobals) {
1131 InitializedHandleScope handle_scope;
1132 BytecodeGeneratorHelper helper;
1133
1134 ExpectedSnippet<int> snippets[] = {
1135 {"var a = 1;",
1136 4 * kPointerSize,
1137 1,
1138 30,
1139 {
1140 B(LdaConstant), U8(0), //
1141 B(Star), R(1), //
1142 B(LdaZero), //
1143 B(Star), R(2), //
1144 B(CallRuntime), U16(Runtime::kDeclareGlobals), R(1), U8(2), //
1145 B(LdaConstant), U8(1), //
1146 B(Star), R(1), //
1147 B(LdaZero), //
1148 B(Star), R(2), //
1149 B(LdaSmi8), U8(1), //
1150 B(Star), R(3), //
1151 B(CallRuntime), U16(Runtime::kInitializeVarGlobal), R(1), //
1152 U8(3), //
1153 B(LdaUndefined), //
1154 B(Return) //
1155 },
1156 -1},
1157 {"function f() {}",
1158 2 * kPointerSize,
1159 1,
1160 14,
1161 {
1162 B(LdaConstant), U8(0), //
1163 B(Star), R(0), //
1164 B(LdaZero), //
1165 B(Star), R(1), //
1166 B(CallRuntime), U16(Runtime::kDeclareGlobals), R(0), U8(2), //
1167 B(LdaUndefined), //
1168 B(Return) //
1169 },
1170 -1},
1171 };
1172
1173 for (size_t i = 0; i < arraysize(snippets); i++) {
1174 Handle<BytecodeArray> bytecode_array =
1175 helper.MakeTopLevelBytecode(snippets[i].code_snippet);
1176 CheckBytecodeArrayEqual(snippets[i], bytecode_array, true);
1177 }
1178 }
1179
1180
966 } // namespace interpreter 1181 } // namespace interpreter
967 } // namespace internal 1182 } // namespace internal
968 } // namespance v8 1183 } // namespance v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698