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 "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/compiler/pipeline.h" | 7 #include "src/compiler/pipeline.h" |
8 #include "src/handles.h" | 8 #include "src/handles.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" |
11 #include "src/isolate.h" | 11 #include "src/isolate.h" |
12 #include "src/parsing/parser.h" | 12 #include "src/parsing/parser.h" |
13 #include "test/cctest/cctest.h" | 13 #include "test/cctest/cctest.h" |
14 #include "test/cctest/interpreter/source-position-matcher.h" | 14 #include "test/cctest/interpreter/source-position-matcher.h" |
15 | 15 |
16 namespace v8 { | 16 namespace v8 { |
17 namespace internal { | 17 namespace internal { |
18 namespace interpreter { | 18 namespace interpreter { |
19 | 19 |
20 // Flags enabling optimizations that change generated bytecode array. | 20 // Flags enabling optimizations that change generated bytecode array. |
21 // Format is <command-line flag> <flag name> <bit index> | 21 // Format is <command-line flag> <flag name> <bit index> |
22 #define OPTIMIZATION_FLAGS(V) \ | 22 #define OPTIMIZATION_FLAGS(V) \ |
23 V(FLAG_ignition_reo, kUseReo, 0) \ | 23 V(FLAG_ignition_reo, kUseReo, 0) \ |
24 V(FLAG_ignition_peephole, kUsePeephole, 1) | 24 V(FLAG_ignition_peephole, kUsePeephole, 1) \ |
| 25 V(FLAG_ignition_filter_expression_positions, \ |
| 26 kUseUseFilterExpressionPositions, 2) |
25 | 27 |
26 #define DECLARE_BIT(_, Name, BitIndex) static const int Name = 1 << BitIndex; | 28 #define DECLARE_BIT(_, Name, BitIndex) static const int Name = 1 << BitIndex; |
27 OPTIMIZATION_FLAGS(DECLARE_BIT) | 29 OPTIMIZATION_FLAGS(DECLARE_BIT) |
28 #undef DECLARE_BIT | 30 #undef DECLARE_BIT |
29 | 31 |
30 // Test cases source positions are checked for. Please ensure all | 32 // Test cases source positions are checked for. Please ensure all |
31 // combinations of flags are present here. This is done manually | 33 // combinations of flags are present here. This is done manually |
32 // because it provides easier to comprehend failure case for humans. | 34 // because it provides easier to comprehend failure case for humans. |
33 #define TEST_CASES(V) \ | 35 #define TEST_CASES(V) \ |
34 V(UsingReo, kUseReo) \ | 36 V(UsingReo, kUseReo) \ |
35 V(UsingReoAndPeephole, kUseReo | kUsePeephole) \ | 37 V(UsingPeephole, kUsePeephole) \ |
36 V(UsingPeephole, kUsePeephole) | 38 V(UsingReoAndPeephole, kUseReo | kUsePeephole) \ |
| 39 V(UsingUseFilterExpressionPositions, kUseUseFilterExpressionPositions) \ |
| 40 V(UsingReoAndUseFilterExpressionPositions, \ |
| 41 kUseReo | kUseUseFilterExpressionPositions) \ |
| 42 V(UsingPeepholeAndUseFilterExpressionPositions, \ |
| 43 kUsePeephole | kUseUseFilterExpressionPositions) \ |
| 44 V(UsingAllOptimizations, \ |
| 45 kUseReo | kUsePeephole | kUseUseFilterExpressionPositions) |
37 | 46 |
38 static const char* kTestScripts[] = { | 47 struct TestCaseData { |
39 "var x = (y = 3) + (x = y); return x + y;", | 48 TestCaseData(const char* const script, |
| 49 const char* const declaration_parameters = "", |
| 50 const char* const arguments = "") |
| 51 : script_(script), |
| 52 declaration_parameters_(declaration_parameters), |
| 53 arguments_(arguments) {} |
40 | 54 |
41 "var x = 55;\n" | 55 const char* const script() const { return script_; } |
42 "var y = x + (x = 1) + (x = 2) + (x = 3);\n" | 56 const char* const declaration_parameters() const { |
43 "return y;", | 57 return declaration_parameters_; |
| 58 } |
| 59 const char* const arguments() const { return arguments_; } |
44 | 60 |
45 "var x = 10; return x >>> 3;", | 61 private: |
| 62 TestCaseData(); |
46 | 63 |
47 "var x = 0; return x || (1, 2, 3);", | 64 const char* const script_; |
| 65 const char* const declaration_parameters_; |
| 66 const char* const arguments_; |
| 67 }; |
48 | 68 |
49 "return a || (a, b, a, b, c = 5, 3); ", | 69 static const TestCaseData kTestCaseData[] = { |
50 | 70 {"var x = (y = 3) + (x = y); return x + y;"}, |
51 "var a = 3; var b = 4; a = b; b = a; a = b; return a;", | 71 {"var x = 55;\n" |
52 | 72 "var y = x + (x = 1) + (x = 2) + (x = 3);\n" |
53 "var a = 1; return [[a, 2], [a + 2]];", | 73 "return y;"}, |
54 | 74 {"var x = 10; return x >>> 3;\n"}, |
55 "var a = 1; if (a || a < 0) { return 1; }", | 75 {"var x = 0; return x || (1, 2, 3);\n"}, |
56 | 76 {"return a || (a, b, a, b, c = 5, 3);\n"}, |
57 "var b;" | 77 {"var a = 3; var b = 4; a = b; b = a; a = b; return a;\n"}, |
58 "b = a.name;" | 78 {"var a = 1; return [[a, 2], [a + 2]];\n"}, |
59 "b = a.name;" | 79 {"var a = 1; if (a || a < 0) { return 1; }\n"}, |
60 "a.name = a;" | 80 {"var b;" |
61 "b = a.name;" | 81 "b = a.name;" |
62 "a.name = a;" | 82 "b = a.name;" |
63 "return b;", | 83 "a.name = a;" |
64 | 84 "b = a.name;" |
65 "var sum = 0;\n" | 85 "a.name = a;" |
66 "outer: {\n" | 86 "return b;"}, |
67 " for (var x = 0; x < 10; ++x) {\n" | 87 {"var sum = 0;\n" |
68 " for (var y = 0; y < 3; ++y) {\n" | 88 "outer: {\n" |
69 " ++sum;\n" | 89 " for (var x = 0; x < 10; ++x) {\n" |
70 " if (x + y == 12) { break outer; }\n" | 90 " for (var y = 0; y < 3; ++y) {\n" |
71 " }\n" | 91 " ++sum;\n" |
72 " }\n" | 92 " if (x + y == 12) { break outer; }\n" |
73 "}\n" | 93 " }\n" |
74 "return sum;\n", | 94 " }\n" |
75 | 95 "}\n" |
76 "var a = 1;" | 96 "return sum;\n"}, |
77 "switch (a) {" | 97 {"var a = 1;" |
78 " case 1: return a * a + 1;" | 98 "switch (a) {" |
79 " case 1: break;" | 99 " case 1: return a * a + 1;" |
80 " case 2: return (a = 3) * a + (a = 4);" | 100 " case 1: break;" |
81 " case 3:" | 101 " case 2: return (a = 3) * a + (a = 4);" |
82 "}" | 102 " case 3:" |
83 "return a;", | 103 "}" |
84 | 104 "return a;"}, |
85 "for (var p of [0, 1, 2]) {}", | 105 {"for (var p of [0, 1, 2]) {}"}, |
86 | 106 {"var x = { 'a': 1, 'b': 2 };" |
87 "var x = { 'a': 1, 'b': 2 };" | 107 "for (x['a'] of [1,2,3]) { return x['a']; }"}, |
88 "for (x['a'] of [1,2,3]) { return x['a']; }", | 108 {"while (x == 4) {\n" |
89 | 109 " var y = x + 1;\n" |
90 "while (x == 4) {\n" | 110 " if (y == 2) break;\n" |
91 " var y = x + 1;\n" | 111 " for (z['a'] of [0]) {\n" |
92 " if (y == 2) break;\n" | 112 " x += (x *= 3) + y;" |
93 " for (z['a'] of [0]) {\n" | 113 " }\n" |
94 " x += (x *= 3) + y;" | 114 "}\n"}, |
95 " }\n" | 115 {"function g(a, b) { return a.func(b + b, b); }\n" |
96 "}\n", | 116 "g(new (function Obj() { this.func = function() { return; }})(), 1)\n"}, |
97 | 117 {"return some_global[name];", "name", "'a'"}}; |
98 "function g(a, b) { return a.func(b + b, b); }\n" | |
99 "g(new (function Obj() { this.func = function() { return; }})(), 1)\n"}; | |
100 | 118 |
101 class OptimizedBytecodeSourcePositionTester final { | 119 class OptimizedBytecodeSourcePositionTester final { |
102 public: | 120 public: |
103 explicit OptimizedBytecodeSourcePositionTester(Isolate* isolate) | 121 explicit OptimizedBytecodeSourcePositionTester(Isolate* isolate) |
104 : isolate_(isolate) { | 122 : isolate_(isolate) { |
105 SaveOptimizationFlags(); | 123 SaveOptimizationFlags(); |
106 saved_flag_ignition_ = FLAG_ignition; | 124 saved_flag_ignition_ = FLAG_ignition; |
107 FLAG_ignition = true; | 125 FLAG_ignition = true; |
108 saved_flag_always_opt_ = FLAG_always_opt; | 126 saved_flag_always_opt_ = FLAG_always_opt; |
109 FLAG_always_opt = false; | 127 FLAG_always_opt = false; |
110 } | 128 } |
111 | 129 |
112 ~OptimizedBytecodeSourcePositionTester() { | 130 ~OptimizedBytecodeSourcePositionTester() { |
113 RestoreOptimizationFlags(); | 131 RestoreOptimizationFlags(); |
114 FLAG_ignition = saved_flag_ignition_; | 132 FLAG_ignition = saved_flag_ignition_; |
115 FLAG_always_opt = saved_flag_always_opt_; | 133 FLAG_always_opt = saved_flag_always_opt_; |
116 } | 134 } |
117 | 135 |
118 bool SourcePositionsMatch(int optimization_bitmap, const char* function_body, | 136 bool SourcePositionsMatch(int optimization_bitmap, const char* function_body, |
119 const char* function_decl_params = "", | 137 const char* function_decl_params, |
120 const char* function_args = ""); | 138 const char* function_args); |
121 | 139 |
122 private: | 140 private: |
123 Handle<BytecodeArray> MakeBytecode(int optimization_bitmap, | 141 Handle<BytecodeArray> MakeBytecode(int optimization_bitmap, |
124 const char* function_body, | 142 const char* function_body, |
125 const char* function_decl_params, | 143 const char* function_decl_params, |
126 const char* function_args); | 144 const char* function_args); |
127 static std::string MakeFunctionName(int optimization_bitmap); | 145 static std::string MakeFunctionName(int optimization_bitmap); |
128 static std::string MakeScript(const char* function_name, | 146 static std::string MakeScript(const char* function_name, |
129 const char* function_body, | 147 const char* function_body, |
130 const char* function_decl_params, | 148 const char* function_decl_params, |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
213 } | 231 } |
214 return true; | 232 return true; |
215 } | 233 } |
216 | 234 |
217 void TestSourcePositionsEquivalent(int optimization_bitmap) { | 235 void TestSourcePositionsEquivalent(int optimization_bitmap) { |
218 HandleAndZoneScope handles; | 236 HandleAndZoneScope handles; |
219 // Ensure handler table is generated. | 237 // Ensure handler table is generated. |
220 handles.main_isolate()->interpreter()->Initialize(); | 238 handles.main_isolate()->interpreter()->Initialize(); |
221 | 239 |
222 OptimizedBytecodeSourcePositionTester tester(handles.main_isolate()); | 240 OptimizedBytecodeSourcePositionTester tester(handles.main_isolate()); |
223 for (auto test_script : kTestScripts) { | 241 for (auto test_case_data : kTestCaseData) { |
224 CHECK(tester.SourcePositionsMatch(optimization_bitmap, test_script)); | 242 CHECK(tester.SourcePositionsMatch( |
| 243 optimization_bitmap, test_case_data.script(), |
| 244 test_case_data.declaration_parameters(), test_case_data.arguments())); |
225 } | 245 } |
226 } | 246 } |
227 | 247 |
228 #define MAKE_TEST(Name, Bitmap) \ | 248 #define MAKE_TEST(Name, Bitmap) \ |
229 TEST(TestSourcePositionsEquivalent##Name) { \ | 249 TEST(TestSourcePositionsEquivalent##Name) { \ |
230 TestSourcePositionsEquivalent(Bitmap); \ | 250 TestSourcePositionsEquivalent(Bitmap); \ |
231 } | 251 } |
232 TEST_CASES(MAKE_TEST) | 252 TEST_CASES(MAKE_TEST) |
233 #undef MAKE_TEST | 253 #undef MAKE_TEST |
234 | 254 |
235 } // namespace interpreter | 255 } // namespace interpreter |
236 } // namespace internal | 256 } // namespace internal |
237 } // namespace v8 | 257 } // namespace v8 |
OLD | NEW |