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

Side by Side Diff: test/cctest/compiler/test-codegen-deopt.cc

Issue 1169103004: [deoptimizer] Basic support inlining based on SharedFunctionInfo. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix Jaros comment. Created 5 years, 6 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/cctest.gyp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 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 "src/v8.h"
6 #include "test/cctest/cctest.h"
7
8 #include "src/compiler/code-generator.h"
9 #include "src/compiler/common-operator.h"
10 #include "src/compiler/graph.h"
11 #include "src/compiler/instruction-selector.h"
12 #include "src/compiler/machine-operator.h"
13 #include "src/compiler/node.h"
14 #include "src/compiler/operator.h"
15 #include "src/compiler/raw-machine-assembler.h"
16 #include "src/compiler/register-allocator.h"
17 #include "src/compiler/schedule.h"
18
19 #include "src/ast-numbering.h"
20 #include "src/full-codegen.h"
21 #include "src/parser.h"
22 #include "src/rewriter.h"
23
24 #include "test/cctest/compiler/c-signature.h"
25 #include "test/cctest/compiler/function-tester.h"
26
27 using namespace v8::internal;
28 using namespace v8::internal::compiler;
29
30
31 #if V8_TURBOFAN_TARGET
32
33 typedef RawMachineAssembler::Label MLabel;
34 typedef v8::internal::compiler::InstructionSequence TestInstrSeq;
35
36 static Handle<JSFunction> NewFunction(const char* source) {
37 return v8::Utils::OpenHandle(
38 *v8::Handle<v8::Function>::Cast(CompileRun(source)));
39 }
40
41
42 class DeoptCodegenTester {
43 public:
44 explicit DeoptCodegenTester(HandleAndZoneScope* scope, const char* src)
45 : scope_(scope),
46 function(NewFunction(src)),
47 parse_info(scope->main_zone(), function),
48 info(&parse_info),
49 bailout_id(-1),
50 tagged_type(1, kMachAnyTagged, zone()),
51 empty_types(zone()) {
52 CHECK(Parser::ParseStatic(&parse_info));
53 info.SetOptimizing(BailoutId::None(), Handle<Code>(function->code()));
54 CHECK(Compiler::Analyze(&parse_info));
55 CHECK(Compiler::EnsureDeoptimizationSupport(&info));
56
57 DCHECK(info.shared_info()->has_deoptimization_support());
58
59 graph = new (scope_->main_zone()) Graph(scope_->main_zone());
60 }
61
62 virtual ~DeoptCodegenTester() {}
63
64 void GenerateCodeFromSchedule(Schedule* schedule) {
65 OFStream os(stdout);
66 if (FLAG_trace_turbo) {
67 os << *schedule;
68 }
69 result_code = Pipeline::GenerateCodeForTesting(&info, graph, schedule);
70 #ifdef OBJECT_PRINT
71 if (FLAG_print_opt_code || FLAG_trace_turbo) {
72 result_code->Print();
73 }
74 #endif
75 }
76
77 Zone* zone() { return scope_->main_zone(); }
78 Isolate* isolate() { return scope_->main_isolate(); }
79
80 HandleAndZoneScope* scope_;
81 Handle<JSFunction> function;
82 ParseInfo parse_info;
83 CompilationInfo info;
84 BailoutId bailout_id;
85 Handle<Code> result_code;
86 TestInstrSeq* code;
87 Graph* graph;
88 ZoneVector<MachineType> tagged_type;
89 ZoneVector<MachineType> empty_types;
90 };
91
92
93 class TrivialDeoptCodegenTester : public DeoptCodegenTester {
94 public:
95 explicit TrivialDeoptCodegenTester(HandleAndZoneScope* scope)
96 : DeoptCodegenTester(scope,
97 "function foo() { deopt(); return 42; }; foo") {}
98
99 void GenerateCode() {
100 GenerateCodeFromSchedule(BuildGraphAndSchedule(graph));
101 }
102
103 Schedule* BuildGraphAndSchedule(Graph* graph) {
104 CommonOperatorBuilder common(zone());
105
106 // Manually construct a schedule for the function below:
107 // function foo() {
108 // deopt();
109 // }
110
111 CSignature1<Object*, Object*> sig;
112 RawMachineAssembler m(isolate(), graph, &sig);
113
114 Handle<JSFunction> deopt_function =
115 NewFunction("function deopt() { %DeoptimizeFunction(foo); }; deopt");
116 Unique<JSFunction> deopt_fun_constant =
117 Unique<JSFunction>::CreateUninitialized(deopt_function);
118 Node* deopt_fun_node = m.NewNode(common.HeapConstant(deopt_fun_constant));
119
120 Handle<Context> caller_context(function->context(), CcTest::i_isolate());
121 Unique<Context> caller_context_constant =
122 Unique<Context>::CreateUninitialized(caller_context);
123 Node* caller_context_node =
124 m.NewNode(common.HeapConstant(caller_context_constant));
125
126 bailout_id = GetCallBailoutId();
127 Node* parameters =
128 m.NewNode(common.TypedStateValues(&tagged_type), m.UndefinedConstant());
129 Node* locals = m.NewNode(common.TypedStateValues(&empty_types));
130 Node* stack = m.NewNode(common.TypedStateValues(&empty_types));
131
132 Node* state_node =
133 m.NewNode(common.FrameState(JS_FRAME, bailout_id,
134 OutputFrameStateCombine::Ignore()),
135 parameters, locals, stack, caller_context_node,
136 deopt_fun_node, m.UndefinedConstant());
137
138 Handle<Context> context(deopt_function->context(), CcTest::i_isolate());
139 Unique<Context> context_constant =
140 Unique<Context>::CreateUninitialized(context);
141 Node* context_node = m.NewNode(common.HeapConstant(context_constant));
142
143 m.CallJS0(deopt_fun_node, m.UndefinedConstant(), context_node, state_node);
144
145 m.Return(m.UndefinedConstant());
146
147 // Schedule the graph:
148 Schedule* schedule = m.Export();
149
150 return schedule;
151 }
152
153 BailoutId GetCallBailoutId() {
154 ZoneList<Statement*>* body = info.function()->body();
155 for (int i = 0; i < body->length(); i++) {
156 if (body->at(i)->IsExpressionStatement() &&
157 body->at(i)->AsExpressionStatement()->expression()->IsCall()) {
158 return body->at(i)->AsExpressionStatement()->expression()->id();
159 }
160 }
161 CHECK(false);
162 return BailoutId(-1);
163 }
164 };
165
166
167 TEST(TurboTrivialDeoptCodegen) {
168 HandleAndZoneScope scope;
169 InitializedHandleScope handles;
170
171 FLAG_allow_natives_syntax = true;
172
173 TrivialDeoptCodegenTester t(&scope);
174 t.GenerateCode();
175
176 DeoptimizationInputData* data =
177 DeoptimizationInputData::cast(t.result_code->deoptimization_data());
178
179 // TODO(jarin) Find a way to test the safepoint.
180
181 // Check that we deoptimize to the right AST id.
182 CHECK_EQ(1, data->DeoptCount());
183 CHECK_EQ(t.bailout_id.ToInt(), data->AstId(0).ToInt());
184 }
185
186
187 TEST(TurboTrivialDeoptCodegenAndRun) {
188 HandleAndZoneScope scope;
189 InitializedHandleScope handles;
190
191 FLAG_allow_natives_syntax = true;
192
193 TrivialDeoptCodegenTester t(&scope);
194 t.GenerateCode();
195
196 t.function->ReplaceCode(*t.result_code);
197 t.info.context()->native_context()->AddOptimizedCode(*t.result_code);
198
199 Isolate* isolate = scope.main_isolate();
200 Handle<Object> result;
201 bool has_pending_exception =
202 !Execution::Call(isolate, t.function,
203 isolate->factory()->undefined_value(), 0, NULL,
204 false).ToHandle(&result);
205 CHECK(!has_pending_exception);
206 CHECK(result->SameValue(Smi::FromInt(42)));
207 }
208
209
210 class TrivialRuntimeDeoptCodegenTester : public DeoptCodegenTester {
211 public:
212 explicit TrivialRuntimeDeoptCodegenTester(HandleAndZoneScope* scope)
213 : DeoptCodegenTester(
214 scope,
215 "function foo() { %DeoptimizeFunction(foo); return 42; }; foo") {}
216
217 void GenerateCode() {
218 GenerateCodeFromSchedule(BuildGraphAndSchedule(graph));
219 }
220
221 Schedule* BuildGraphAndSchedule(Graph* graph) {
222 CommonOperatorBuilder common(zone());
223
224 // Manually construct a schedule for the function below:
225 // function foo() {
226 // %DeoptimizeFunction(foo);
227 // }
228
229 CSignature1<Object*, Object*> sig;
230 RawMachineAssembler m(isolate(), graph, &sig);
231
232 Unique<HeapObject> this_fun_constant =
233 Unique<HeapObject>::CreateUninitialized(function);
234 Node* this_fun_node = m.NewNode(common.HeapConstant(this_fun_constant));
235
236 Handle<Context> context(function->context(), CcTest::i_isolate());
237 Unique<HeapObject> context_constant =
238 Unique<HeapObject>::CreateUninitialized(context);
239 Node* context_node = m.NewNode(common.HeapConstant(context_constant));
240
241 bailout_id = GetCallBailoutId();
242 Node* parameters =
243 m.NewNode(common.TypedStateValues(&tagged_type), m.UndefinedConstant());
244 Node* locals = m.NewNode(common.TypedStateValues(&empty_types));
245 Node* stack = m.NewNode(common.TypedStateValues(&empty_types));
246
247 Node* state_node =
248 m.NewNode(common.FrameState(JS_FRAME, bailout_id,
249 OutputFrameStateCombine::Ignore()),
250 parameters, locals, stack, context_node, this_fun_node,
251 m.UndefinedConstant());
252
253 m.CallRuntime1(Runtime::kDeoptimizeFunction, this_fun_node, context_node,
254 state_node);
255
256 m.Return(m.UndefinedConstant());
257
258 // Schedule the graph:
259 Schedule* schedule = m.Export();
260
261 return schedule;
262 }
263
264 BailoutId GetCallBailoutId() {
265 ZoneList<Statement*>* body = info.function()->body();
266 for (int i = 0; i < body->length(); i++) {
267 if (body->at(i)->IsExpressionStatement() &&
268 body->at(i)->AsExpressionStatement()->expression()->IsCallRuntime()) {
269 return body->at(i)->AsExpressionStatement()->expression()->id();
270 }
271 }
272 CHECK(false);
273 return BailoutId(-1);
274 }
275 };
276
277
278 TEST(TurboTrivialRuntimeDeoptCodegenAndRun) {
279 HandleAndZoneScope scope;
280 InitializedHandleScope handles;
281
282 FLAG_allow_natives_syntax = true;
283
284 TrivialRuntimeDeoptCodegenTester t(&scope);
285 t.GenerateCode();
286
287 t.function->ReplaceCode(*t.result_code);
288 t.info.context()->native_context()->AddOptimizedCode(*t.result_code);
289
290 Isolate* isolate = scope.main_isolate();
291 Handle<Object> result;
292 bool has_pending_exception =
293 !Execution::Call(isolate, t.function,
294 isolate->factory()->undefined_value(), 0, NULL,
295 false).ToHandle(&result);
296 CHECK(!has_pending_exception);
297 CHECK(result->SameValue(Smi::FromInt(42)));
298 }
299
300 #endif
OLDNEW
« no previous file with comments | « test/cctest/cctest.gyp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698