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

Side by Side Diff: test/cctest/compiler/test-run-bytecode-graph-builder.cc

Issue 1291693004: [Interpreter] Bytecode graph builder (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: More fixes for bots (tests w/ ASAN and tests w/ slow asserts enabled). Created 5 years, 3 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include <utility>
6
7 #include "src/v8.h"
8
9 #include "src/compiler/pipeline.h"
10 #include "src/execution.h"
11 #include "src/handles.h"
12 #include "src/interpreter/bytecode-array-builder.h"
13 #include "src/interpreter/interpreter.h"
14 #include "src/parser.h"
15 #include "test/cctest/cctest.h"
16
17 namespace v8 {
18 namespace internal {
19 namespace compiler {
20
21
22 static const char kFunctionName[] = "f";
23
24
25 static MaybeHandle<Object> CallFunction(Isolate* isolate,
26 Handle<JSFunction> function) {
27 return Execution::Call(isolate, function,
28 isolate->factory()->undefined_value(), 0, nullptr,
29 false);
30 }
31
32
33 template <class... A>
34 static MaybeHandle<Object> CallFunction(Isolate* isolate,
35 Handle<JSFunction> function,
36 A... args) {
37 Handle<Object> argv[] = {args...};
38 return Execution::Call(isolate, function,
39 isolate->factory()->undefined_value(), sizeof...(args),
40 argv, false);
41 }
42
43
44 template <class... A>
45 class BytecodeGraphCallable {
46 public:
47 BytecodeGraphCallable(Isolate* isolate, Handle<JSFunction> function)
48 : isolate_(isolate), function_(function) {}
49 virtual ~BytecodeGraphCallable() {}
50
51 MaybeHandle<Object> operator()(A... args) {
52 return CallFunction(isolate_, function_, args...);
53 }
54
55 private:
56 Isolate* isolate_;
57 Handle<JSFunction> function_;
58 };
59
60
61 class BytecodeGraphTester {
62 public:
63 BytecodeGraphTester(Isolate* isolate, Zone* zone, const char* script)
64 : isolate_(isolate), zone_(zone), script_(script) {
65 i::FLAG_ignition = true;
66 i::FLAG_always_opt = false;
67 i::FLAG_vector_stores = true;
68 // Set ignition filter flag via SetFlagsFromString to avoid double-free
69 // (or potential leak with StrDup() based on ownership confusion).
70 ScopedVector<char> ignition_filter(64);
71 SNPrintF(ignition_filter, "--ignition-filter=%s", kFunctionName);
72 FlagList::SetFlagsFromString(ignition_filter.start(),
73 ignition_filter.length());
74 // Ensure handler table is generated.
75 isolate->interpreter()->Initialize();
76 }
77 virtual ~BytecodeGraphTester() {}
78
79 template <class... A>
80 BytecodeGraphCallable<A...> GetCallable() {
81 return BytecodeGraphCallable<A...>(isolate_, GetFunction());
82 }
83
84 private:
85 Isolate* isolate_;
86 Zone* zone_;
87 const char* script_;
88
89 Handle<JSFunction> GetFunction() {
90 CompileRun(script_);
91 Local<Function> api_function =
92 Local<Function>::Cast(CcTest::global()->Get(v8_str(kFunctionName)));
93 Handle<JSFunction> function = v8::Utils::OpenHandle(*api_function);
94 CHECK(function->shared()->HasBytecodeArray());
95
96 ParseInfo parse_info(zone_, function);
97
98 CompilationInfo compilation_info(&parse_info);
99 compilation_info.SetOptimizing(BailoutId::None(), Handle<Code>());
100 Parser parser(&parse_info);
101 CHECK(parser.Parse(&parse_info));
102 compiler::Pipeline pipeline(&compilation_info);
103 Handle<Code> code = pipeline.GenerateCode();
104 function->ReplaceCode(*code);
105
106 return function;
107 }
108
109 DISALLOW_COPY_AND_ASSIGN(BytecodeGraphTester);
110 };
111
112 } // namespace compiler
113 } // namespace internal
114 } // namespace v8
115
116
117 using namespace v8::internal;
118 using namespace v8::internal::compiler;
119
120 template <int N>
121 struct ExpectedSnippet {
122 const char* code_snippet;
123 Handle<Object> return_value_and_parameters[N + 1];
124
125 inline Handle<Object> return_value() const {
126 return return_value_and_parameters[0];
127 }
128
129 inline Handle<Object> parameter(int i) const {
130 return return_value_and_parameters[1 + i];
131 }
132 };
133
134
135 TEST(BytecodeGraphBuilderReturnStatements) {
136 HandleAndZoneScope scope;
137 Isolate* isolate = scope.main_isolate();
138 Zone* zone = scope.main_zone();
139 Factory* factory = isolate->factory();
140
141 ExpectedSnippet<0> snippets[] = {
142 {"return;", {factory->undefined_value()}},
143 {"return null;", {factory->null_value()}},
144 {"return true;", {factory->true_value()}},
145 {"return false;", {factory->false_value()}},
146 {"return 0;", {factory->NewNumberFromInt(0)}},
147 {"return +1;", {factory->NewNumberFromInt(1)}},
148 {"return -1;", {factory->NewNumberFromInt(-1)}},
149 {"return +127;", {factory->NewNumberFromInt(127)}},
150 {"return -128;", {factory->NewNumberFromInt(-128)}},
151 {"return 0.001;", {factory->NewNumber(0.001)}},
152 {"return 3.7e-60;", {factory->NewNumber(3.7e-60)}},
153 {"return -3.7e60;", {factory->NewNumber(-3.7e60)}},
154 {"return '';", {factory->NewStringFromStaticChars("")}},
155 {"return 'catfood';", {factory->NewStringFromStaticChars("catfood")}}
156 // TODO(oth): {"return NaN;", {factory->NewNumber(NAN)}}
157 };
158
159 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
160 for (size_t i = 0; i < num_snippets; i++) {
161 ScopedVector<char> script(1024);
162 SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
163 snippets[i].code_snippet, kFunctionName);
164
165 BytecodeGraphTester tester(isolate, zone, script.start());
166 auto callable = tester.GetCallable<>();
167 Handle<Object> return_value = callable().ToHandleChecked();
168 CHECK(return_value->SameValue(*snippets[i].return_value()));
169 }
170 }
171
172
173 TEST(BytecodeGraphBuilderPrimitiveExpressions) {
174 HandleAndZoneScope scope;
175 Isolate* isolate = scope.main_isolate();
176 Zone* zone = scope.main_zone();
177 Factory* factory = isolate->factory();
178
179 ExpectedSnippet<0> snippets[] = {
180 {"return 1 + 1;", {factory->NewNumberFromInt(2)}},
181 {"return 20 - 30;", {factory->NewNumberFromInt(-10)}},
182 {"return 4 * 100;", {factory->NewNumberFromInt(400)}},
183 {"return 100 / 5;", {factory->NewNumberFromInt(20)}},
184 {"return 25 % 7;", {factory->NewNumberFromInt(4)}},
185 };
186
187 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
188 for (size_t i = 0; i < num_snippets; i++) {
189 ScopedVector<char> script(1024);
190 SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName,
191 snippets[i].code_snippet, kFunctionName);
192
193 BytecodeGraphTester tester(isolate, zone, script.start());
194 auto callable = tester.GetCallable<>();
195 Handle<Object> return_value = callable().ToHandleChecked();
196 CHECK(return_value->SameValue(*snippets[i].return_value()));
197 }
198 }
199
200
201 TEST(BytecodeGraphBuilderTwoParameterTests) {
202 HandleAndZoneScope scope;
203 Isolate* isolate = scope.main_isolate();
204 Zone* zone = scope.main_zone();
205 Factory* factory = isolate->factory();
206
207 ExpectedSnippet<2> snippets[] = {
208 // Integers
209 {"return p1 + p2;",
210 {factory->NewNumberFromInt(-70), factory->NewNumberFromInt(3),
211 factory->NewNumberFromInt(-73)}},
212 {"return p1 + p2 + 3;",
213 {factory->NewNumberFromInt(1139044), factory->NewNumberFromInt(300),
214 factory->NewNumberFromInt(1138741)}},
215 {"return p1 - p2;",
216 {factory->NewNumberFromInt(1100), factory->NewNumberFromInt(1000),
217 factory->NewNumberFromInt(-100)}},
218 {"return p1 * p2;",
219 {factory->NewNumberFromInt(-100000), factory->NewNumberFromInt(1000),
220 factory->NewNumberFromInt(-100)}},
221 {"return p1 / p2;",
222 {factory->NewNumberFromInt(-10), factory->NewNumberFromInt(1000),
223 factory->NewNumberFromInt(-100)}},
224 {"return p1 % p2;",
225 {factory->NewNumberFromInt(5), factory->NewNumberFromInt(373),
226 factory->NewNumberFromInt(16)}},
227 // Doubles
228 {"return p1 + p2;",
229 {factory->NewHeapNumber(9.999), factory->NewHeapNumber(3.333),
230 factory->NewHeapNumber(6.666)}},
231 {"return p1 - p2;",
232 {factory->NewHeapNumber(-3.333), factory->NewHeapNumber(3.333),
233 factory->NewHeapNumber(6.666)}},
234 {"return p1 * p2;",
235 {factory->NewHeapNumber(3.333 * 6.666), factory->NewHeapNumber(3.333),
236 factory->NewHeapNumber(6.666)}},
237 {"return p1 / p2;",
238 {factory->NewHeapNumber(2.25), factory->NewHeapNumber(9),
239 factory->NewHeapNumber(4)}},
240 // Strings
241 {"return p1 + p2;",
242 {factory->NewStringFromStaticChars("abcdef"),
243 factory->NewStringFromStaticChars("abc"),
244 factory->NewStringFromStaticChars("def")}}};
245
246 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]);
247 for (size_t i = 0; i < num_snippets; i++) {
248 ScopedVector<char> script(1024);
249 SNPrintF(script, "function %s(p1, p2) { %s }\n%s(0, 0);", kFunctionName,
250 snippets[i].code_snippet, kFunctionName);
251
252 BytecodeGraphTester tester(isolate, zone, script.start());
253 auto callable = tester.GetCallable<Handle<Object>, Handle<Object>>();
254 Handle<Object> return_value =
255 callable(snippets[i].parameter(0), snippets[i].parameter(1))
256 .ToHandleChecked();
257 CHECK(return_value->SameValue(*snippets[i].return_value()));
258 }
259 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698