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

Side by Side Diff: src/compiler/js-generic-lowering.cc

Issue 426233002: Land the Fan (disabled) (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 4 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 | Annotate | Revision Log
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/code-stubs.h"
6 #include "src/compiler/common-operator.h"
7 #include "src/compiler/graph-inl.h"
8 #include "src/compiler/js-generic-lowering.h"
9 #include "src/compiler/machine-operator.h"
10 #include "src/compiler/node-aux-data-inl.h"
11 #include "src/compiler/node-properties-inl.h"
12 #include "src/unique.h"
13
14 namespace v8 {
15 namespace internal {
16 namespace compiler {
17
18
19 // TODO(mstarzinger): This is a temporary workaround for non-hydrogen stubs for
20 // which we don't have an interface descriptor yet. Use ReplaceWithICStubCall
21 // once these stub have been made into a HydrogenCodeStub.
22 template <typename T>
23 static CodeStubInterfaceDescriptor* GetInterfaceDescriptor(Isolate* isolate,
24 T* stub) {
25 CodeStub::Major key = static_cast<CodeStub*>(stub)->MajorKey();
26 CodeStubInterfaceDescriptor* d = isolate->code_stub_interface_descriptor(key);
27 stub->InitializeInterfaceDescriptor(isolate, d);
28 return d;
29 }
30
31
32 JSGenericLowering::JSGenericLowering(CompilationInfo* info, JSGraph* jsgraph,
33 MachineOperatorBuilder* machine,
34 SourcePositionTable* source_positions)
35 : LoweringBuilder(jsgraph->graph(), source_positions),
36 info_(info),
37 jsgraph_(jsgraph),
38 linkage_(new (jsgraph->zone()) Linkage(info)),
39 machine_(machine) {}
40
41
42 void JSGenericLowering::PatchOperator(Node* node, Operator* op) {
43 node->set_op(op);
44 }
45
46
47 void JSGenericLowering::PatchInsertInput(Node* node, int index, Node* input) {
48 node->InsertInput(zone(), index, input);
49 }
50
51
52 Node* JSGenericLowering::SmiConstant(int32_t immediate) {
53 return jsgraph()->SmiConstant(immediate);
54 }
55
56
57 Node* JSGenericLowering::Int32Constant(int immediate) {
58 return jsgraph()->Int32Constant(immediate);
59 }
60
61
62 Node* JSGenericLowering::CodeConstant(Handle<Code> code) {
63 return jsgraph()->HeapConstant(code);
64 }
65
66
67 Node* JSGenericLowering::FunctionConstant(Handle<JSFunction> function) {
68 return jsgraph()->HeapConstant(function);
69 }
70
71
72 Node* JSGenericLowering::ExternalConstant(ExternalReference ref) {
73 return jsgraph()->ExternalConstant(ref);
74 }
75
76
77 void JSGenericLowering::Lower(Node* node) {
78 Node* replacement = NULL;
79 // Dispatch according to the opcode.
80 switch (node->opcode()) {
81 #define DECLARE_CASE(x) \
82 case IrOpcode::k##x: \
83 replacement = Lower##x(node); \
84 break;
85 DECLARE_CASE(Branch)
86 JS_OP_LIST(DECLARE_CASE)
87 #undef DECLARE_CASE
88 default:
89 // Nothing to see.
90 return;
91 }
92
93 // Nothing to do if lowering was done by patching the existing node.
94 if (replacement == node) return;
95
96 // Iterate through uses of the original node and replace uses accordingly.
97 UNIMPLEMENTED();
98 }
99
100
101 #define REPLACE_IC_STUB_CALL(op, StubDeclaration) \
102 Node* JSGenericLowering::Lower##op(Node* node) { \
103 StubDeclaration; \
104 ReplaceWithICStubCall(node, &stub); \
105 return node; \
106 }
107 REPLACE_IC_STUB_CALL(JSBitwiseOr,
108 BinaryOpICStub stub(isolate(), Token::BIT_OR))
109 REPLACE_IC_STUB_CALL(JSBitwiseXor,
110 BinaryOpICStub stub(isolate(), Token::BIT_XOR))
111 REPLACE_IC_STUB_CALL(JSBitwiseAnd,
112 BinaryOpICStub stub(isolate(), Token::BIT_AND))
113 REPLACE_IC_STUB_CALL(JSShiftLeft,
114 BinaryOpICStub stub(isolate(), Token::SHL))
115 REPLACE_IC_STUB_CALL(JSShiftRight,
116 BinaryOpICStub stub(isolate(), Token::SAR))
117 REPLACE_IC_STUB_CALL(JSShiftRightLogical,
118 BinaryOpICStub stub(isolate(), Token::SHR))
119 REPLACE_IC_STUB_CALL(JSAdd,
120 BinaryOpICStub stub(isolate(), Token::ADD))
121 REPLACE_IC_STUB_CALL(JSSubtract,
122 BinaryOpICStub stub(isolate(), Token::SUB))
123 REPLACE_IC_STUB_CALL(JSMultiply,
124 BinaryOpICStub stub(isolate(), Token::MUL))
125 REPLACE_IC_STUB_CALL(JSDivide,
126 BinaryOpICStub stub(isolate(), Token::DIV))
127 REPLACE_IC_STUB_CALL(JSModulus,
128 BinaryOpICStub stub(isolate(), Token::MOD))
129 REPLACE_IC_STUB_CALL(JSToNumber,
130 ToNumberStub stub(isolate()))
131 #undef REPLACE_IC_STUB_CALL
132
133
134 #define REPLACE_COMPARE_IC_CALL(op, token, pure) \
135 Node* JSGenericLowering::Lower##op(Node* node) { \
136 ReplaceWithCompareIC(node, token, pure); \
137 return node; \
138 }
139 REPLACE_COMPARE_IC_CALL(JSEqual, Token::EQ, false)
140 REPLACE_COMPARE_IC_CALL(JSNotEqual, Token::NE, false)
141 REPLACE_COMPARE_IC_CALL(JSStrictEqual, Token::EQ_STRICT, true)
142 REPLACE_COMPARE_IC_CALL(JSStrictNotEqual, Token::NE_STRICT, true)
143 REPLACE_COMPARE_IC_CALL(JSLessThan, Token::LT, false)
144 REPLACE_COMPARE_IC_CALL(JSGreaterThan, Token::GT, false)
145 REPLACE_COMPARE_IC_CALL(JSLessThanOrEqual, Token::LTE, false)
146 REPLACE_COMPARE_IC_CALL(JSGreaterThanOrEqual, Token::GTE, false)
147 #undef REPLACE_COMPARE_IC_CALL
148
149
150 #define REPLACE_RUNTIME_CALL(op, fun) \
151 Node* JSGenericLowering::Lower##op(Node* node) { \
152 ReplaceWithRuntimeCall(node, fun); \
153 return node; \
154 }
155 REPLACE_RUNTIME_CALL(JSTypeOf, Runtime::kTypeof)
156 REPLACE_RUNTIME_CALL(JSCreate, Runtime::kAbort)
157 REPLACE_RUNTIME_CALL(JSCreateFunctionContext, Runtime::kNewFunctionContext)
158 REPLACE_RUNTIME_CALL(JSCreateCatchContext, Runtime::kPushCatchContext)
159 REPLACE_RUNTIME_CALL(JSCreateWithContext, Runtime::kPushWithContext)
160 REPLACE_RUNTIME_CALL(JSCreateBlockContext, Runtime::kPushBlockContext)
161 REPLACE_RUNTIME_CALL(JSCreateModuleContext, Runtime::kPushModuleContext)
162 REPLACE_RUNTIME_CALL(JSCreateGlobalContext, Runtime::kAbort)
163 #undef REPLACE_RUNTIME
164
165
166 #define REPLACE_UNIMPLEMENTED(op) \
167 Node* JSGenericLowering::Lower##op(Node* node) { \
168 UNIMPLEMENTED(); \
169 return node; \
170 }
171 REPLACE_UNIMPLEMENTED(JSToString)
172 REPLACE_UNIMPLEMENTED(JSToName)
173 REPLACE_UNIMPLEMENTED(JSYield)
174 REPLACE_UNIMPLEMENTED(JSDebugger)
175 #undef REPLACE_UNIMPLEMENTED
176
177
178 void JSGenericLowering::ReplaceWithCompareIC(
179 Node* node, Token::Value token, bool pure) {
180 BinaryOpICStub stub(isolate(), Token::ADD); // TODO(mstarzinger): Hack.
181 CodeStubInterfaceDescriptor* d = stub.GetInterfaceDescriptor();
182 CallDescriptor* desc_compare = linkage()->GetStubCallDescriptor(d);
183 Handle<Code> ic = CompareIC::GetUninitialized(isolate(), token);
184 Node* compare;
185 if (pure) {
186 // A pure (strict) comparison doesn't have an effect or control.
187 // But for the graph, we need to add these inputs.
188 compare = graph()->NewNode(common()->Call(desc_compare), CodeConstant(ic),
189 NodeProperties::GetValueInput(node, 0),
190 NodeProperties::GetValueInput(node, 1),
191 NodeProperties::GetContextInput(node),
192 graph()->start(), graph()->start());
193 } else {
194 compare = graph()->NewNode(common()->Call(desc_compare), CodeConstant(ic),
195 NodeProperties::GetValueInput(node, 0),
196 NodeProperties::GetValueInput(node, 1),
197 NodeProperties::GetContextInput(node),
198 NodeProperties::GetEffectInput(node),
199 NodeProperties::GetControlInput(node));
200 }
201 node->ReplaceInput(0, compare);
202 node->ReplaceInput(1, SmiConstant(token));
203 ReplaceWithRuntimeCall(node, Runtime::kBooleanize);
204 }
205
206
207 void JSGenericLowering::ReplaceWithICStubCall(Node* node,
208 HydrogenCodeStub* stub) {
209 CodeStubInterfaceDescriptor* d = stub->GetInterfaceDescriptor();
210 CallDescriptor* desc = linkage()->GetStubCallDescriptor(d);
211 Node* stub_code = CodeConstant(stub->GetCode());
212 PatchInsertInput(node, 0, stub_code);
213 PatchOperator(node, common()->Call(desc));
214 }
215
216
217 void JSGenericLowering::ReplaceWithBuiltinCall(Node* node,
218 Builtins::JavaScript id,
219 int nargs) {
220 CallFunctionStub stub(isolate(), nargs - 1, NO_CALL_FUNCTION_FLAGS);
221 CodeStubInterfaceDescriptor* d = GetInterfaceDescriptor(isolate(), &stub);
222 CallDescriptor* desc = linkage()->GetStubCallDescriptor(d, nargs);
223 // TODO(mstarzinger): Accessing the builtins object this way prevents sharing
224 // of code across native contexts. Fix this by loading from given context.
225 Handle<JSFunction> function(JSFunction::cast(
226 info()->context()->builtins()->javascript_builtin(id)));
227 Node* stub_code = CodeConstant(stub.GetCode());
228 Node* function_node = FunctionConstant(function);
229 PatchInsertInput(node, 0, stub_code);
230 PatchInsertInput(node, 1, function_node);
231 PatchOperator(node, common()->Call(desc));
232 }
233
234
235 void JSGenericLowering::ReplaceWithRuntimeCall(Node* node,
236 Runtime::FunctionId f,
237 int nargs_override) {
238 Operator::Property props = node->op()->properties();
239 const Runtime::Function* fun = Runtime::FunctionForId(f);
240 int nargs = (nargs_override < 0) ? fun->nargs : nargs_override;
241 CallDescriptor::DeoptimizationSupport deopt =
242 NodeProperties::CanLazilyDeoptimize(node)
243 ? CallDescriptor::kCanDeoptimize
244 : CallDescriptor::kCannotDeoptimize;
245 CallDescriptor* desc =
246 linkage()->GetRuntimeCallDescriptor(f, nargs, props, deopt);
247 Node* ref = ExternalConstant(ExternalReference(f, isolate()));
248 Node* arity = Int32Constant(nargs);
249 if (!centrystub_constant_.is_set()) {
250 centrystub_constant_.set(CodeConstant(CEntryStub(isolate(), 1).GetCode()));
251 }
252 PatchInsertInput(node, 0, centrystub_constant_.get());
253 PatchInsertInput(node, nargs + 1, ref);
254 PatchInsertInput(node, nargs + 2, arity);
255 PatchOperator(node, common()->Call(desc));
256 }
257
258
259 Node* JSGenericLowering::LowerBranch(Node* node) {
260 Node* test = graph()->NewNode(machine()->WordEqual(), node->InputAt(0),
261 jsgraph()->TrueConstant());
262 node->ReplaceInput(0, test);
263 return node;
264 }
265
266
267 Node* JSGenericLowering::LowerJSUnaryNot(Node* node) {
268 ToBooleanStub stub(isolate());
269 CodeStubInterfaceDescriptor* d = stub.GetInterfaceDescriptor();
270 CallDescriptor* desc = linkage()->GetStubCallDescriptor(d);
271 Node* to_bool =
272 graph()->NewNode(common()->Call(desc), CodeConstant(stub.GetCode()),
273 NodeProperties::GetValueInput(node, 0),
274 NodeProperties::GetContextInput(node),
275 NodeProperties::GetEffectInput(node),
276 NodeProperties::GetControlInput(node));
277 node->ReplaceInput(0, to_bool);
278 PatchInsertInput(node, 1, SmiConstant(Token::EQ));
279 ReplaceWithRuntimeCall(node, Runtime::kBooleanize);
280 return node;
281 }
282
283
284 Node* JSGenericLowering::LowerJSToBoolean(Node* node) {
285 ToBooleanStub stub(isolate());
286 CodeStubInterfaceDescriptor* d = stub.GetInterfaceDescriptor();
287 CallDescriptor* desc = linkage()->GetStubCallDescriptor(d);
288 Node* to_bool =
289 graph()->NewNode(common()->Call(desc), CodeConstant(stub.GetCode()),
290 NodeProperties::GetValueInput(node, 0),
291 NodeProperties::GetContextInput(node),
292 NodeProperties::GetEffectInput(node),
293 NodeProperties::GetControlInput(node));
294 node->ReplaceInput(0, to_bool);
295 PatchInsertInput(node, 1, SmiConstant(Token::NE));
296 ReplaceWithRuntimeCall(node, Runtime::kBooleanize);
297 return node;
298 }
299
300
301 Node* JSGenericLowering::LowerJSToObject(Node* node) {
302 ReplaceWithBuiltinCall(node, Builtins::TO_OBJECT, 1);
303 return node;
304 }
305
306
307 Node* JSGenericLowering::LowerJSLoadProperty(Node* node) {
308 if (FLAG_compiled_keyed_generic_loads) {
309 KeyedLoadGenericElementStub stub(isolate());
310 ReplaceWithICStubCall(node, &stub);
311 } else {
312 ReplaceWithRuntimeCall(node, Runtime::kKeyedGetProperty);
313 }
314 return node;
315 }
316
317
318 Node* JSGenericLowering::LowerJSLoadNamed(Node* node) {
319 Node* key =
320 jsgraph()->HeapConstant(OpParameter<PrintableUnique<Name> >(node));
321 PatchInsertInput(node, 1, key);
322 // TODO(mstarzinger): We cannot yet use KeyedLoadGenericElementStub here,
323 // because named interceptors would not fire correctly yet.
324 ReplaceWithRuntimeCall(node, Runtime::kGetProperty);
325 return node;
326 }
327
328
329 Node* JSGenericLowering::LowerJSStoreProperty(Node* node) {
330 // TODO(mstarzinger): The strict_mode needs to be carried along in the
331 // operator so that graphs are fully compositional for inlining.
332 StrictMode strict_mode = info()->strict_mode();
333 PatchInsertInput(node, 3, SmiConstant(strict_mode));
334 ReplaceWithRuntimeCall(node, Runtime::kSetProperty, 4);
335 return node;
336 }
337
338
339 Node* JSGenericLowering::LowerJSStoreNamed(Node* node) {
340 // TODO(mstarzinger): The strict_mode needs to be carried along in the
341 // operator so that graphs are fully compositional for inlining.
342 StrictMode strict_mode = info()->strict_mode();
343 Node* key =
344 jsgraph()->HeapConstant(OpParameter<PrintableUnique<Name> >(node));
345 PatchInsertInput(node, 1, key);
346 PatchInsertInput(node, 3, SmiConstant(strict_mode));
347 ReplaceWithRuntimeCall(node, Runtime::kSetProperty, 4);
348 return node;
349 }
350
351
352 Node* JSGenericLowering::LowerJSDeleteProperty(Node* node) {
353 StrictMode strict_mode = OpParameter<StrictMode>(node);
354 PatchInsertInput(node, 2, SmiConstant(strict_mode));
355 ReplaceWithBuiltinCall(node, Builtins::DELETE, 3);
356 return node;
357 }
358
359
360 Node* JSGenericLowering::LowerJSHasProperty(Node* node) {
361 ReplaceWithBuiltinCall(node, Builtins::IN, 2);
362 return node;
363 }
364
365
366 Node* JSGenericLowering::LowerJSInstanceOf(Node* node) {
367 InstanceofStub::Flags flags = static_cast<InstanceofStub::Flags>(
368 InstanceofStub::kReturnTrueFalseObject |
369 InstanceofStub::kArgsInRegisters);
370 InstanceofStub stub(isolate(), flags);
371 CodeStubInterfaceDescriptor* d = GetInterfaceDescriptor(isolate(), &stub);
372 CallDescriptor* desc = linkage()->GetStubCallDescriptor(d, 0);
373 Node* stub_code = CodeConstant(stub.GetCode());
374 PatchInsertInput(node, 0, stub_code);
375 PatchOperator(node, common()->Call(desc));
376 return node;
377 }
378
379
380 Node* JSGenericLowering::LowerJSLoadContext(Node* node) {
381 ContextAccess access = OpParameter<ContextAccess>(node);
382 PatchInsertInput(node, 1, SmiConstant(access.depth()));
383 PatchInsertInput(node, 2, SmiConstant(access.index()));
384 ReplaceWithRuntimeCall(node, Runtime::kLoadContextRelative, 3);
385 return node;
386 }
387
388
389 Node* JSGenericLowering::LowerJSStoreContext(Node* node) {
390 ContextAccess access = OpParameter<ContextAccess>(node);
391 PatchInsertInput(node, 1, SmiConstant(access.depth()));
392 PatchInsertInput(node, 2, SmiConstant(access.index()));
393 ReplaceWithRuntimeCall(node, Runtime::kStoreContextRelative, 4);
394 return node;
395 }
396
397
398 Node* JSGenericLowering::LowerJSCallConstruct(Node* node) {
399 int arity = OpParameter<int>(node);
400 CallConstructStub stub(isolate(), NO_CALL_CONSTRUCTOR_FLAGS);
401 CodeStubInterfaceDescriptor* d = GetInterfaceDescriptor(isolate(), &stub);
402 CallDescriptor* desc = linkage()->GetStubCallDescriptor(d, arity);
403 Node* stub_code = CodeConstant(stub.GetCode());
404 Node* construct = NodeProperties::GetValueInput(node, 0);
405 PatchInsertInput(node, 0, stub_code);
406 PatchInsertInput(node, 1, Int32Constant(arity - 1));
407 PatchInsertInput(node, 2, construct);
408 PatchInsertInput(node, 3, jsgraph()->UndefinedConstant());
409 PatchOperator(node, common()->Call(desc));
410 return node;
411 }
412
413
414 Node* JSGenericLowering::LowerJSCallFunction(Node* node) {
415 CallParameters p = OpParameter<CallParameters>(node);
416 CallFunctionStub stub(isolate(), p.arity - 2, p.flags);
417 CodeStubInterfaceDescriptor* d = GetInterfaceDescriptor(isolate(), &stub);
418 CallDescriptor* desc = linkage()->GetStubCallDescriptor(d, p.arity - 1);
419 Node* stub_code = CodeConstant(stub.GetCode());
420 PatchInsertInput(node, 0, stub_code);
421 PatchOperator(node, common()->Call(desc));
422 return node;
423 }
424
425
426 Node* JSGenericLowering::LowerJSCallRuntime(Node* node) {
427 Runtime::FunctionId function = OpParameter<Runtime::FunctionId>(node);
428 int arity = NodeProperties::GetValueInputCount(node);
429 ReplaceWithRuntimeCall(node, function, arity);
430 return node;
431 }
432
433
434 } } } // namespace v8::internal::compiler
OLDNEW
« no previous file with comments | « src/compiler/js-generic-lowering.h ('k') | src/compiler/js-graph.h » ('j') | src/lithium-inl.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698