blob: df2d9086efef37fd02f73d35c947ce7538a73329 [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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-factory.h"
6#include "src/code-stubs.h"
7#include "src/compiler/common-operator.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008#include "src/compiler/js-generic-lowering.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00009#include "src/compiler/js-graph.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010#include "src/compiler/machine-operator.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040011#include "src/compiler/node-matchers.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000012#include "src/compiler/node-properties.h"
13#include "src/compiler/operator-properties.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000014
15namespace v8 {
16namespace internal {
17namespace compiler {
18
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000019static CallDescriptor::Flags AdjustFrameStatesForCall(Node* node) {
20 int count = OperatorProperties::GetFrameStateInputCount(node->op());
21 if (count > 1) {
22 int index = NodeProperties::FirstFrameStateIndex(node) + 1;
23 do {
24 node->RemoveInput(index);
25 } while (--count > 1);
26 }
27 return count > 0 ? CallDescriptor::kNeedsFrameState
28 : CallDescriptor::kNoFlags;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000029}
30
31
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000032JSGenericLowering::JSGenericLowering(bool is_typing_enabled, JSGraph* jsgraph)
33 : is_typing_enabled_(is_typing_enabled), jsgraph_(jsgraph) {}
34
35
36JSGenericLowering::~JSGenericLowering() {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +000037
38
Ben Murdochb8a8cc12014-11-26 15:28:44 +000039Reduction JSGenericLowering::Reduce(Node* node) {
40 switch (node->opcode()) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -040041#define DECLARE_CASE(x) \
42 case IrOpcode::k##x: \
43 Lower##x(node); \
44 break;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000045 JS_OP_LIST(DECLARE_CASE)
46#undef DECLARE_CASE
Emily Bernierd0a1eb72015-03-24 16:35:39 -040047 case IrOpcode::kBranch:
48 // TODO(mstarzinger): If typing is enabled then simplified lowering will
49 // have inserted the correct ChangeBoolToBit, otherwise we need to perform
50 // poor-man's representation inference here and insert manual change.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000051 if (!is_typing_enabled_) {
52 Node* condition = node->InputAt(0);
53 Node* test = graph()->NewNode(machine()->WordEqual(), condition,
Emily Bernierd0a1eb72015-03-24 16:35:39 -040054 jsgraph()->TrueConstant());
55 node->ReplaceInput(0, test);
Emily Bernierd0a1eb72015-03-24 16:35:39 -040056 }
57 // Fall-through.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000058 default:
59 // Nothing to see.
60 return NoChange();
61 }
62 return Changed(node);
63}
64
Ben Murdoch097c5b22016-05-18 11:27:45 +010065#define REPLACE_BINARY_OP_IC_CALL(Op, token) \
66 void JSGenericLowering::Lower##Op(Node* node) { \
67 CallDescriptor::Flags flags = AdjustFrameStatesForCall(node); \
68 ReplaceWithStubCall(node, CodeFactory::BinaryOpIC(isolate(), token), \
69 CallDescriptor::kPatchableCallSiteWithNop | flags); \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000070 }
71REPLACE_BINARY_OP_IC_CALL(JSBitwiseOr, Token::BIT_OR)
72REPLACE_BINARY_OP_IC_CALL(JSBitwiseXor, Token::BIT_XOR)
73REPLACE_BINARY_OP_IC_CALL(JSBitwiseAnd, Token::BIT_AND)
74REPLACE_BINARY_OP_IC_CALL(JSShiftLeft, Token::SHL)
75REPLACE_BINARY_OP_IC_CALL(JSShiftRight, Token::SAR)
76REPLACE_BINARY_OP_IC_CALL(JSShiftRightLogical, Token::SHR)
77REPLACE_BINARY_OP_IC_CALL(JSAdd, Token::ADD)
78REPLACE_BINARY_OP_IC_CALL(JSSubtract, Token::SUB)
79REPLACE_BINARY_OP_IC_CALL(JSMultiply, Token::MUL)
80REPLACE_BINARY_OP_IC_CALL(JSDivide, Token::DIV)
81REPLACE_BINARY_OP_IC_CALL(JSModulus, Token::MOD)
82#undef REPLACE_BINARY_OP_IC_CALL
83
Ben Murdochb8a8cc12014-11-26 15:28:44 +000084#define REPLACE_RUNTIME_CALL(op, fun) \
85 void JSGenericLowering::Lower##op(Node* node) { \
86 ReplaceWithRuntimeCall(node, fun); \
87 }
Ben Murdoch097c5b22016-05-18 11:27:45 +010088REPLACE_RUNTIME_CALL(JSEqual, Runtime::kEqual)
89REPLACE_RUNTIME_CALL(JSNotEqual, Runtime::kNotEqual)
90REPLACE_RUNTIME_CALL(JSStrictEqual, Runtime::kStrictEqual)
91REPLACE_RUNTIME_CALL(JSStrictNotEqual, Runtime::kStrictNotEqual)
92REPLACE_RUNTIME_CALL(JSLessThan, Runtime::kLessThan)
93REPLACE_RUNTIME_CALL(JSGreaterThan, Runtime::kGreaterThan)
94REPLACE_RUNTIME_CALL(JSLessThanOrEqual, Runtime::kLessThanOrEqual)
95REPLACE_RUNTIME_CALL(JSGreaterThanOrEqual, Runtime::kGreaterThanOrEqual)
Ben Murdochb8a8cc12014-11-26 15:28:44 +000096REPLACE_RUNTIME_CALL(JSCreateWithContext, Runtime::kPushWithContext)
Ben Murdochb8a8cc12014-11-26 15:28:44 +000097REPLACE_RUNTIME_CALL(JSCreateModuleContext, Runtime::kPushModuleContext)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000098REPLACE_RUNTIME_CALL(JSConvertReceiver, Runtime::kConvertReceiver)
Ben Murdoch097c5b22016-05-18 11:27:45 +010099#undef REPLACE_RUNTIME_CALL
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000100
101void JSGenericLowering::ReplaceWithStubCall(Node* node, Callable callable,
102 CallDescriptor::Flags flags) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400103 Operator::Properties properties = node->op()->properties();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000104 CallDescriptor* desc = Linkage::GetStubCallDescriptor(
105 isolate(), zone(), callable.descriptor(), 0, flags, properties);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400106 Node* stub_code = jsgraph()->HeapConstant(callable.code());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000107 node->InsertInput(zone(), 0, stub_code);
108 NodeProperties::ChangeOp(node, common()->Call(desc));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000109}
110
111
112void JSGenericLowering::ReplaceWithRuntimeCall(Node* node,
113 Runtime::FunctionId f,
114 int nargs_override) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100115 CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000116 Operator::Properties properties = node->op()->properties();
117 const Runtime::Function* fun = Runtime::FunctionForId(f);
118 int nargs = (nargs_override < 0) ? fun->nargs : nargs_override;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100119 CallDescriptor* desc =
120 Linkage::GetRuntimeCallDescriptor(zone(), f, nargs, properties, flags);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400121 Node* ref = jsgraph()->ExternalConstant(ExternalReference(f, isolate()));
122 Node* arity = jsgraph()->Int32Constant(nargs);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000123 node->InsertInput(zone(), 0, jsgraph()->CEntryStubConstant(fun->result_size));
124 node->InsertInput(zone(), nargs + 1, ref);
125 node->InsertInput(zone(), nargs + 2, arity);
126 NodeProperties::ChangeOp(node, common()->Call(desc));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000127}
128
129
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000130void JSGenericLowering::LowerJSTypeOf(Node* node) {
131 CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
132 Callable callable = CodeFactory::Typeof(isolate());
133 ReplaceWithStubCall(node, callable, flags);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000134}
135
136
137void JSGenericLowering::LowerJSToBoolean(Node* node) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000138 CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
139 Callable callable = CodeFactory::ToBoolean(isolate());
140 ReplaceWithStubCall(node, callable,
141 CallDescriptor::kPatchableCallSite | flags);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000142}
143
144
145void JSGenericLowering::LowerJSToNumber(Node* node) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000146 CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000147 Callable callable = CodeFactory::ToNumber(isolate());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000148 ReplaceWithStubCall(node, callable, flags);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000149}
150
151
152void JSGenericLowering::LowerJSToString(Node* node) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000153 CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
154 Callable callable = CodeFactory::ToString(isolate());
155 ReplaceWithStubCall(node, callable, flags);
156}
157
158
159void JSGenericLowering::LowerJSToName(Node* node) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100160 CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
161 Callable callable = CodeFactory::ToName(isolate());
162 ReplaceWithStubCall(node, callable, flags);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000163}
164
165
166void JSGenericLowering::LowerJSToObject(Node* node) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000167 CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
168 Callable callable = CodeFactory::ToObject(isolate());
169 ReplaceWithStubCall(node, callable, flags);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000170}
171
172
173void JSGenericLowering::LowerJSLoadProperty(Node* node) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100174 Node* closure = NodeProperties::GetValueInput(node, 2);
175 Node* effect = NodeProperties::GetEffectInput(node);
176 Node* control = NodeProperties::GetControlInput(node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000177 CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
178 const PropertyAccess& p = PropertyAccessOf(node->op());
Ben Murdoch097c5b22016-05-18 11:27:45 +0100179 Callable callable =
180 CodeFactory::KeyedLoadICInOptimizedCode(isolate(), UNINITIALIZED);
181 // Load the type feedback vector from the closure.
182 Node* shared_info = effect = graph()->NewNode(
183 machine()->Load(MachineType::AnyTagged()), closure,
184 jsgraph()->IntPtrConstant(JSFunction::kSharedFunctionInfoOffset -
185 kHeapObjectTag),
186 effect, control);
187 Node* vector = effect = graph()->NewNode(
188 machine()->Load(MachineType::AnyTagged()), shared_info,
189 jsgraph()->IntPtrConstant(SharedFunctionInfo::kFeedbackVectorOffset -
190 kHeapObjectTag),
191 effect, control);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000192 node->InsertInput(zone(), 2, jsgraph()->SmiConstant(p.feedback().index()));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100193 node->ReplaceInput(3, vector);
194 node->ReplaceInput(6, effect);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000195 ReplaceWithStubCall(node, callable, flags);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000196}
197
198
199void JSGenericLowering::LowerJSLoadNamed(Node* node) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100200 Node* closure = NodeProperties::GetValueInput(node, 1);
201 Node* effect = NodeProperties::GetEffectInput(node);
202 Node* control = NodeProperties::GetControlInput(node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000203 CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
204 NamedAccess const& p = NamedAccessOf(node->op());
205 Callable callable = CodeFactory::LoadICInOptimizedCode(
Ben Murdoch097c5b22016-05-18 11:27:45 +0100206 isolate(), NOT_INSIDE_TYPEOF, UNINITIALIZED);
207 // Load the type feedback vector from the closure.
208 Node* shared_info = effect = graph()->NewNode(
209 machine()->Load(MachineType::AnyTagged()), closure,
210 jsgraph()->IntPtrConstant(JSFunction::kSharedFunctionInfoOffset -
211 kHeapObjectTag),
212 effect, control);
213 Node* vector = effect = graph()->NewNode(
214 machine()->Load(MachineType::AnyTagged()), shared_info,
215 jsgraph()->IntPtrConstant(SharedFunctionInfo::kFeedbackVectorOffset -
216 kHeapObjectTag),
217 effect, control);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000218 node->InsertInput(zone(), 1, jsgraph()->HeapConstant(p.name()));
219 node->InsertInput(zone(), 2, jsgraph()->SmiConstant(p.feedback().index()));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100220 node->ReplaceInput(3, vector);
221 node->ReplaceInput(6, effect);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000222 ReplaceWithStubCall(node, callable, flags);
223}
224
225
226void JSGenericLowering::LowerJSLoadGlobal(Node* node) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100227 Node* closure = NodeProperties::GetValueInput(node, 0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000228 Node* context = NodeProperties::GetContextInput(node);
229 Node* effect = NodeProperties::GetEffectInput(node);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100230 Node* control = NodeProperties::GetControlInput(node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000231 CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
232 const LoadGlobalParameters& p = LoadGlobalParametersOf(node->op());
233 Callable callable = CodeFactory::LoadICInOptimizedCode(
Ben Murdoch097c5b22016-05-18 11:27:45 +0100234 isolate(), p.typeof_mode(), UNINITIALIZED);
235 // Load the type feedback vector from the closure.
236 Node* shared_info = effect = graph()->NewNode(
237 machine()->Load(MachineType::AnyTagged()), closure,
238 jsgraph()->IntPtrConstant(JSFunction::kSharedFunctionInfoOffset -
239 kHeapObjectTag),
240 effect, control);
241 Node* vector = effect = graph()->NewNode(
242 machine()->Load(MachineType::AnyTagged()), shared_info,
243 jsgraph()->IntPtrConstant(SharedFunctionInfo::kFeedbackVectorOffset -
244 kHeapObjectTag),
245 effect, control);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000246 // Load global object from the context.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100247 Node* native_context = effect =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000248 graph()->NewNode(machine()->Load(MachineType::AnyTagged()), context,
249 jsgraph()->IntPtrConstant(
250 Context::SlotOffset(Context::NATIVE_CONTEXT_INDEX)),
Ben Murdoch097c5b22016-05-18 11:27:45 +0100251 effect, control);
252 Node* global = effect = graph()->NewNode(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000253 machine()->Load(MachineType::AnyTagged()), native_context,
254 jsgraph()->IntPtrConstant(Context::SlotOffset(Context::EXTENSION_INDEX)),
Ben Murdoch097c5b22016-05-18 11:27:45 +0100255 effect, control);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000256 node->InsertInput(zone(), 0, global);
257 node->InsertInput(zone(), 1, jsgraph()->HeapConstant(p.name()));
258 node->InsertInput(zone(), 2, jsgraph()->SmiConstant(p.feedback().index()));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100259 node->ReplaceInput(3, vector);
260 node->ReplaceInput(6, effect);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000261 ReplaceWithStubCall(node, callable, flags);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000262}
263
264
265void JSGenericLowering::LowerJSStoreProperty(Node* node) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100266 Node* closure = NodeProperties::GetValueInput(node, 3);
267 Node* effect = NodeProperties::GetEffectInput(node);
268 Node* control = NodeProperties::GetControlInput(node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000269 CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
270 PropertyAccess const& p = PropertyAccessOf(node->op());
271 LanguageMode language_mode = p.language_mode();
272 Callable callable = CodeFactory::KeyedStoreICInOptimizedCode(
273 isolate(), language_mode, UNINITIALIZED);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100274 // Load the type feedback vector from the closure.
275 Node* shared_info = effect = graph()->NewNode(
276 machine()->Load(MachineType::AnyTagged()), closure,
277 jsgraph()->IntPtrConstant(JSFunction::kSharedFunctionInfoOffset -
278 kHeapObjectTag),
279 effect, control);
280 Node* vector = effect = graph()->NewNode(
281 machine()->Load(MachineType::AnyTagged()), shared_info,
282 jsgraph()->IntPtrConstant(SharedFunctionInfo::kFeedbackVectorOffset -
283 kHeapObjectTag),
284 effect, control);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000285 node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.feedback().index()));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100286 node->ReplaceInput(4, vector);
287 node->ReplaceInput(7, effect);
288 ReplaceWithStubCall(node, callable, flags);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000289}
290
291
292void JSGenericLowering::LowerJSStoreNamed(Node* node) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100293 Node* closure = NodeProperties::GetValueInput(node, 2);
294 Node* effect = NodeProperties::GetEffectInput(node);
295 Node* control = NodeProperties::GetControlInput(node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000296 CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
297 NamedAccess const& p = NamedAccessOf(node->op());
298 Callable callable = CodeFactory::StoreICInOptimizedCode(
299 isolate(), p.language_mode(), UNINITIALIZED);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100300 // Load the type feedback vector from the closure.
301 Node* shared_info = effect = graph()->NewNode(
302 machine()->Load(MachineType::AnyTagged()), closure,
303 jsgraph()->IntPtrConstant(JSFunction::kSharedFunctionInfoOffset -
304 kHeapObjectTag),
305 effect, control);
306 Node* vector = effect = graph()->NewNode(
307 machine()->Load(MachineType::AnyTagged()), shared_info,
308 jsgraph()->IntPtrConstant(SharedFunctionInfo::kFeedbackVectorOffset -
309 kHeapObjectTag),
310 effect, control);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000311 node->InsertInput(zone(), 1, jsgraph()->HeapConstant(p.name()));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000312 node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.feedback().index()));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100313 node->ReplaceInput(4, vector);
314 node->ReplaceInput(7, effect);
315 ReplaceWithStubCall(node, callable, flags);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000316}
317
318
319void JSGenericLowering::LowerJSStoreGlobal(Node* node) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100320 Node* closure = NodeProperties::GetValueInput(node, 1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000321 Node* context = NodeProperties::GetContextInput(node);
322 Node* effect = NodeProperties::GetEffectInput(node);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100323 Node* control = NodeProperties::GetControlInput(node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000324 CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
325 const StoreGlobalParameters& p = StoreGlobalParametersOf(node->op());
326 Callable callable = CodeFactory::StoreICInOptimizedCode(
327 isolate(), p.language_mode(), UNINITIALIZED);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100328 // Load the type feedback vector from the closure.
329 Node* shared_info = effect = graph()->NewNode(
330 machine()->Load(MachineType::AnyTagged()), closure,
331 jsgraph()->IntPtrConstant(JSFunction::kSharedFunctionInfoOffset -
332 kHeapObjectTag),
333 effect, control);
334 Node* vector = effect = graph()->NewNode(
335 machine()->Load(MachineType::AnyTagged()), shared_info,
336 jsgraph()->IntPtrConstant(SharedFunctionInfo::kFeedbackVectorOffset -
337 kHeapObjectTag),
338 effect, control);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000339 // Load global object from the context.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100340 Node* native_context = effect =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000341 graph()->NewNode(machine()->Load(MachineType::AnyTagged()), context,
342 jsgraph()->IntPtrConstant(
343 Context::SlotOffset(Context::NATIVE_CONTEXT_INDEX)),
Ben Murdoch097c5b22016-05-18 11:27:45 +0100344 effect, control);
345 Node* global = effect = graph()->NewNode(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000346 machine()->Load(MachineType::AnyTagged()), native_context,
347 jsgraph()->IntPtrConstant(Context::SlotOffset(Context::EXTENSION_INDEX)),
Ben Murdoch097c5b22016-05-18 11:27:45 +0100348 effect, control);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000349 node->InsertInput(zone(), 0, global);
350 node->InsertInput(zone(), 1, jsgraph()->HeapConstant(p.name()));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000351 node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.feedback().index()));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100352 node->ReplaceInput(4, vector);
353 node->ReplaceInput(7, effect);
354 ReplaceWithStubCall(node, callable, flags);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000355}
356
357
358void JSGenericLowering::LowerJSDeleteProperty(Node* node) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000359 LanguageMode language_mode = OpParameter<LanguageMode>(node);
360 ReplaceWithRuntimeCall(node, is_strict(language_mode)
361 ? Runtime::kDeleteProperty_Strict
362 : Runtime::kDeleteProperty_Sloppy);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000363}
364
365
366void JSGenericLowering::LowerJSHasProperty(Node* node) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000367 ReplaceWithRuntimeCall(node, Runtime::kHasProperty);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000368}
369
370
371void JSGenericLowering::LowerJSInstanceOf(Node* node) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000372 CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
373 Callable callable = CodeFactory::InstanceOf(isolate());
374 ReplaceWithStubCall(node, callable, flags);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000375}
376
377
378void JSGenericLowering::LowerJSLoadContext(Node* node) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400379 const ContextAccess& access = ContextAccessOf(node->op());
380 for (size_t i = 0; i < access.depth(); ++i) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000381 node->ReplaceInput(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000382 0, graph()->NewNode(machine()->Load(MachineType::AnyTagged()),
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400383 NodeProperties::GetValueInput(node, 0),
384 jsgraph()->Int32Constant(
385 Context::SlotOffset(Context::PREVIOUS_INDEX)),
386 NodeProperties::GetEffectInput(node),
387 graph()->start()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000388 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400389 node->ReplaceInput(1, jsgraph()->Int32Constant(Context::SlotOffset(
390 static_cast<int>(access.index()))));
391 node->AppendInput(zone(), graph()->start());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000392 NodeProperties::ChangeOp(node, machine()->Load(MachineType::AnyTagged()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000393}
394
395
396void JSGenericLowering::LowerJSStoreContext(Node* node) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400397 const ContextAccess& access = ContextAccessOf(node->op());
398 for (size_t i = 0; i < access.depth(); ++i) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000399 node->ReplaceInput(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000400 0, graph()->NewNode(machine()->Load(MachineType::AnyTagged()),
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400401 NodeProperties::GetValueInput(node, 0),
402 jsgraph()->Int32Constant(
403 Context::SlotOffset(Context::PREVIOUS_INDEX)),
404 NodeProperties::GetEffectInput(node),
405 graph()->start()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000406 }
407 node->ReplaceInput(2, NodeProperties::GetValueInput(node, 1));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400408 node->ReplaceInput(1, jsgraph()->Int32Constant(Context::SlotOffset(
409 static_cast<int>(access.index()))));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000410 NodeProperties::ChangeOp(
411 node, machine()->Store(StoreRepresentation(MachineRepresentation::kTagged,
412 kFullWriteBarrier)));
413}
414
415
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000416void JSGenericLowering::LowerJSCreate(Node* node) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100417 CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
418 Callable callable = CodeFactory::FastNewObject(isolate());
419 ReplaceWithStubCall(node, callable, flags);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000420}
421
422
423void JSGenericLowering::LowerJSCreateArguments(Node* node) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100424 CreateArgumentsType const type = CreateArgumentsTypeOf(node->op());
425 switch (type) {
426 case CreateArgumentsType::kMappedArguments:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000427 ReplaceWithRuntimeCall(node, Runtime::kNewSloppyArguments_Generic);
428 break;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100429 case CreateArgumentsType::kUnmappedArguments:
430 ReplaceWithRuntimeCall(node, Runtime::kNewStrictArguments);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000431 break;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100432 case CreateArgumentsType::kRestParameter:
433 ReplaceWithRuntimeCall(node, Runtime::kNewRestParameter);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000434 break;
435 }
436}
437
438
439void JSGenericLowering::LowerJSCreateArray(Node* node) {
440 CreateArrayParameters const& p = CreateArrayParametersOf(node->op());
441 int const arity = static_cast<int>(p.arity());
Ben Murdoch097c5b22016-05-18 11:27:45 +0100442 Handle<AllocationSite> const site = p.site();
443
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000444 // TODO(turbofan): We embed the AllocationSite from the Operator at this
445 // point, which we should not do once we want to both consume the feedback
446 // but at the same time shared the optimized code across native contexts,
447 // as the AllocationSite is associated with a single native context (it's
448 // stored in the type feedback vector after all). Once we go for cross
449 // context code generation, we should somehow find a way to get to the
450 // allocation site for the actual native context at runtime.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100451 if (!site.is_null()) {
452 // Reduce {node} to the appropriate ArrayConstructorStub backend.
453 // Note that these stubs "behave" like JSFunctions, which means they
454 // expect a receiver on the stack, which they remove. We just push
455 // undefined for the receiver.
456 ElementsKind elements_kind = site->GetElementsKind();
457 AllocationSiteOverrideMode override_mode =
458 (AllocationSite::GetMode(elements_kind) == TRACK_ALLOCATION_SITE)
459 ? DISABLE_ALLOCATION_SITES
460 : DONT_OVERRIDE;
461 if (arity == 0) {
462 ArrayNoArgumentConstructorStub stub(isolate(), elements_kind,
463 override_mode);
464 CallDescriptor* desc = Linkage::GetStubCallDescriptor(
465 isolate(), graph()->zone(), stub.GetCallInterfaceDescriptor(), 1,
466 CallDescriptor::kNeedsFrameState);
467 node->ReplaceInput(0, jsgraph()->HeapConstant(stub.GetCode()));
468 node->InsertInput(graph()->zone(), 2, jsgraph()->HeapConstant(site));
469 node->InsertInput(graph()->zone(), 3, jsgraph()->UndefinedConstant());
470 NodeProperties::ChangeOp(node, common()->Call(desc));
471 } else if (arity == 1) {
472 // TODO(bmeurer): Optimize for the 0 length non-holey case?
473 ArraySingleArgumentConstructorStub stub(
474 isolate(), GetHoleyElementsKind(elements_kind), override_mode);
475 CallDescriptor* desc = Linkage::GetStubCallDescriptor(
476 isolate(), graph()->zone(), stub.GetCallInterfaceDescriptor(), 2,
477 CallDescriptor::kNeedsFrameState);
478 node->ReplaceInput(0, jsgraph()->HeapConstant(stub.GetCode()));
479 node->InsertInput(graph()->zone(), 2, jsgraph()->HeapConstant(site));
480 node->InsertInput(graph()->zone(), 3, jsgraph()->Int32Constant(1));
481 node->InsertInput(graph()->zone(), 4, jsgraph()->UndefinedConstant());
482 NodeProperties::ChangeOp(node, common()->Call(desc));
483 } else {
484 ArrayNArgumentsConstructorStub stub(isolate(), elements_kind,
485 override_mode);
486 CallDescriptor* desc = Linkage::GetStubCallDescriptor(
487 isolate(), graph()->zone(), stub.GetCallInterfaceDescriptor(),
488 arity + 1, CallDescriptor::kNeedsFrameState);
489 node->ReplaceInput(0, jsgraph()->HeapConstant(stub.GetCode()));
490 node->InsertInput(graph()->zone(), 2, jsgraph()->HeapConstant(site));
491 node->InsertInput(graph()->zone(), 3, jsgraph()->Int32Constant(arity));
492 node->InsertInput(graph()->zone(), 4, jsgraph()->UndefinedConstant());
493 NodeProperties::ChangeOp(node, common()->Call(desc));
494 }
495 } else {
496 Node* new_target = node->InputAt(1);
497 Node* type_info = site.is_null() ? jsgraph()->UndefinedConstant()
498 : jsgraph()->HeapConstant(site);
499 node->RemoveInput(1);
500 node->InsertInput(zone(), 1 + arity, new_target);
501 node->InsertInput(zone(), 2 + arity, type_info);
502 ReplaceWithRuntimeCall(node, Runtime::kNewArray, arity + 3);
503 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000504}
505
506
507void JSGenericLowering::LowerJSCreateClosure(Node* node) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100508 CreateClosureParameters const& p = CreateClosureParametersOf(node->op());
509 CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
510 Handle<SharedFunctionInfo> const shared_info = p.shared_info();
511 node->InsertInput(zone(), 0, jsgraph()->HeapConstant(shared_info));
512
513 // Use the FastNewClosureStub that allocates in new space only for nested
514 // functions that don't need literals cloning.
515 if (p.pretenure() == NOT_TENURED && shared_info->num_literals() == 0) {
516 Callable callable = CodeFactory::FastNewClosure(
517 isolate(), shared_info->language_mode(), shared_info->kind());
518 ReplaceWithStubCall(node, callable, flags);
519 } else {
520 ReplaceWithRuntimeCall(node, (p.pretenure() == TENURED)
521 ? Runtime::kNewClosure_Tenured
522 : Runtime::kNewClosure);
523 }
524}
525
526
527void JSGenericLowering::LowerJSCreateFunctionContext(Node* node) {
528 int const slot_count = OpParameter<int>(node->op());
529 CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
530
531 // Use the FastNewContextStub only for function contexts up maximum size.
532 if (slot_count <= FastNewContextStub::kMaximumSlots) {
533 Callable callable = CodeFactory::FastNewContext(isolate(), slot_count);
534 ReplaceWithStubCall(node, callable, flags);
535 } else {
536 ReplaceWithRuntimeCall(node, Runtime::kNewFunctionContext);
537 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000538}
539
540
541void JSGenericLowering::LowerJSCreateIterResultObject(Node* node) {
542 ReplaceWithRuntimeCall(node, Runtime::kCreateIterResultObject);
543}
544
545
546void JSGenericLowering::LowerJSCreateLiteralArray(Node* node) {
547 CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
Ben Murdoch097c5b22016-05-18 11:27:45 +0100548 CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
549 int const length = Handle<FixedArray>::cast(p.constant())->length();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000550 node->InsertInput(zone(), 1, jsgraph()->SmiConstant(p.index()));
551 node->InsertInput(zone(), 2, jsgraph()->HeapConstant(p.constant()));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100552
553 // Use the FastCloneShallowArrayStub only for shallow boilerplates up to the
554 // initial length limit for arrays with "fast" elements kind.
555 if ((p.flags() & ArrayLiteral::kShallowElements) != 0 &&
556 (p.flags() & ArrayLiteral::kIsStrong) == 0 &&
557 length < JSArray::kInitialMaxFastElementArray) {
558 Callable callable = CodeFactory::FastCloneShallowArray(isolate());
559 ReplaceWithStubCall(node, callable, flags);
560 } else {
561 node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.flags()));
562 ReplaceWithRuntimeCall(node, Runtime::kCreateArrayLiteral);
563 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000564}
565
566
567void JSGenericLowering::LowerJSCreateLiteralObject(Node* node) {
568 CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
Ben Murdoch097c5b22016-05-18 11:27:45 +0100569 CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
570 int const length = Handle<FixedArray>::cast(p.constant())->length();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000571 node->InsertInput(zone(), 1, jsgraph()->SmiConstant(p.index()));
572 node->InsertInput(zone(), 2, jsgraph()->HeapConstant(p.constant()));
573 node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.flags()));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100574
575 // Use the FastCloneShallowObjectStub only for shallow boilerplates without
576 // elements up to the number of properties that the stubs can handle.
577 if ((p.flags() & ObjectLiteral::kShallowProperties) != 0 &&
578 length <= FastCloneShallowObjectStub::kMaximumClonedProperties) {
579 Callable callable = CodeFactory::FastCloneShallowObject(isolate(), length);
580 ReplaceWithStubCall(node, callable, flags);
581 } else {
582 ReplaceWithRuntimeCall(node, Runtime::kCreateObjectLiteral);
583 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000584}
585
586
587void JSGenericLowering::LowerJSCreateLiteralRegExp(Node* node) {
588 CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
589 CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
590 Callable callable = CodeFactory::FastCloneRegExp(isolate());
591 Node* literal_index = jsgraph()->SmiConstant(p.index());
592 Node* literal_flags = jsgraph()->SmiConstant(p.flags());
593 Node* pattern = jsgraph()->HeapConstant(p.constant());
594 node->InsertInput(graph()->zone(), 1, literal_index);
595 node->InsertInput(graph()->zone(), 2, pattern);
596 node->InsertInput(graph()->zone(), 3, literal_flags);
597 ReplaceWithStubCall(node, callable, flags);
598}
599
600
601void JSGenericLowering::LowerJSCreateCatchContext(Node* node) {
602 Handle<String> name = OpParameter<Handle<String>>(node);
603 node->InsertInput(zone(), 0, jsgraph()->HeapConstant(name));
604 ReplaceWithRuntimeCall(node, Runtime::kPushCatchContext);
605}
606
607
608void JSGenericLowering::LowerJSCreateBlockContext(Node* node) {
609 Handle<ScopeInfo> scope_info = OpParameter<Handle<ScopeInfo>>(node);
610 node->InsertInput(zone(), 0, jsgraph()->HeapConstant(scope_info));
611 ReplaceWithRuntimeCall(node, Runtime::kPushBlockContext);
612}
613
614
615void JSGenericLowering::LowerJSCreateScriptContext(Node* node) {
616 Handle<ScopeInfo> scope_info = OpParameter<Handle<ScopeInfo>>(node);
617 node->InsertInput(zone(), 1, jsgraph()->HeapConstant(scope_info));
618 ReplaceWithRuntimeCall(node, Runtime::kNewScriptContext);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000619}
620
621
622void JSGenericLowering::LowerJSCallConstruct(Node* node) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000623 CallConstructParameters const& p = CallConstructParametersOf(node->op());
624 int const arg_count = static_cast<int>(p.arity() - 2);
625 CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
626 Callable callable = CodeFactory::Construct(isolate());
627 CallDescriptor* desc = Linkage::GetStubCallDescriptor(
628 isolate(), zone(), callable.descriptor(), arg_count + 1, flags);
629 Node* stub_code = jsgraph()->HeapConstant(callable.code());
630 Node* stub_arity = jsgraph()->Int32Constant(arg_count);
631 Node* new_target = node->InputAt(arg_count + 1);
632 Node* receiver = jsgraph()->UndefinedConstant();
633 node->RemoveInput(arg_count + 1); // Drop new target.
634 node->InsertInput(zone(), 0, stub_code);
635 node->InsertInput(zone(), 2, new_target);
636 node->InsertInput(zone(), 3, stub_arity);
637 node->InsertInput(zone(), 4, receiver);
638 NodeProperties::ChangeOp(node, common()->Call(desc));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400639}
640
641
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000642void JSGenericLowering::LowerJSCallFunction(Node* node) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000643 CallFunctionParameters const& p = CallFunctionParametersOf(node->op());
644 int const arg_count = static_cast<int>(p.arity() - 2);
645 ConvertReceiverMode const mode = p.convert_mode();
646 Callable callable = CodeFactory::Call(isolate(), mode);
647 CallDescriptor::Flags flags = AdjustFrameStatesForCall(node);
648 if (p.tail_call_mode() == TailCallMode::kAllow) {
649 flags |= CallDescriptor::kSupportsTailCalls;
650 }
651 CallDescriptor* desc = Linkage::GetStubCallDescriptor(
652 isolate(), zone(), callable.descriptor(), arg_count + 1, flags);
653 Node* stub_code = jsgraph()->HeapConstant(callable.code());
654 Node* stub_arity = jsgraph()->Int32Constant(arg_count);
655 node->InsertInput(zone(), 0, stub_code);
656 node->InsertInput(zone(), 2, stub_arity);
657 NodeProperties::ChangeOp(node, common()->Call(desc));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000658}
659
660
661void JSGenericLowering::LowerJSCallRuntime(Node* node) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400662 const CallRuntimeParameters& p = CallRuntimeParametersOf(node->op());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000663 AdjustFrameStatesForCall(node);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400664 ReplaceWithRuntimeCall(node, p.id(), static_cast<int>(p.arity()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000665}
666
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000667
668void JSGenericLowering::LowerJSForInDone(Node* node) {
669 ReplaceWithRuntimeCall(node, Runtime::kForInDone);
670}
671
672
673void JSGenericLowering::LowerJSForInNext(Node* node) {
674 ReplaceWithRuntimeCall(node, Runtime::kForInNext);
675}
676
677
678void JSGenericLowering::LowerJSForInPrepare(Node* node) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100679 ReplaceWithRuntimeCall(node, Runtime::kForInPrepare);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000680}
681
682
683void JSGenericLowering::LowerJSForInStep(Node* node) {
684 ReplaceWithRuntimeCall(node, Runtime::kForInStep);
685}
686
687
688void JSGenericLowering::LowerJSLoadMessage(Node* node) {
689 ExternalReference message_address =
690 ExternalReference::address_of_pending_message_obj(isolate());
691 node->RemoveInput(NodeProperties::FirstContextIndex(node));
692 node->InsertInput(zone(), 0, jsgraph()->ExternalConstant(message_address));
693 node->InsertInput(zone(), 1, jsgraph()->IntPtrConstant(0));
694 NodeProperties::ChangeOp(node, machine()->Load(MachineType::AnyTagged()));
695}
696
697
698void JSGenericLowering::LowerJSStoreMessage(Node* node) {
699 ExternalReference message_address =
700 ExternalReference::address_of_pending_message_obj(isolate());
701 node->RemoveInput(NodeProperties::FirstContextIndex(node));
702 node->InsertInput(zone(), 0, jsgraph()->ExternalConstant(message_address));
703 node->InsertInput(zone(), 1, jsgraph()->IntPtrConstant(0));
704 StoreRepresentation representation(MachineRepresentation::kTagged,
705 kNoWriteBarrier);
706 NodeProperties::ChangeOp(node, machine()->Store(representation));
707}
708
709
710void JSGenericLowering::LowerJSYield(Node* node) { UNIMPLEMENTED(); }
711
712
713void JSGenericLowering::LowerJSStackCheck(Node* node) {
714 Node* effect = NodeProperties::GetEffectInput(node);
715 Node* control = NodeProperties::GetControlInput(node);
716
717 Node* limit = graph()->NewNode(
718 machine()->Load(MachineType::Pointer()),
719 jsgraph()->ExternalConstant(
720 ExternalReference::address_of_stack_limit(isolate())),
721 jsgraph()->IntPtrConstant(0), effect, control);
722 Node* pointer = graph()->NewNode(machine()->LoadStackPointer());
723
724 Node* check = graph()->NewNode(machine()->UintLessThan(), limit, pointer);
725 Node* branch =
726 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
727
728 Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
729 Node* etrue = effect;
730
731 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
732 NodeProperties::ReplaceControlInput(node, if_false);
733 Node* efalse = node;
734
735 Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
736 Node* ephi = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, merge);
737
738 // Wire the new diamond into the graph, {node} can still throw.
739 NodeProperties::ReplaceUses(node, node, ephi, node, node);
740 NodeProperties::ReplaceEffectInput(ephi, efalse, 1);
741
742 // TODO(mstarzinger): This iteration cuts out the IfSuccess projection from
743 // the node and places it inside the diamond. Come up with a helper method!
744 for (Node* use : node->uses()) {
745 if (use->opcode() == IrOpcode::kIfSuccess) {
746 use->ReplaceUses(merge);
747 merge->ReplaceInput(1, use);
748 }
749 }
750
751 // Turn the stack check into a runtime call.
752 ReplaceWithRuntimeCall(node, Runtime::kStackGuard);
753}
754
755
756Zone* JSGenericLowering::zone() const { return graph()->zone(); }
757
758
759Isolate* JSGenericLowering::isolate() const { return jsgraph()->isolate(); }
760
761
762Graph* JSGenericLowering::graph() const { return jsgraph()->graph(); }
763
764
765CommonOperatorBuilder* JSGenericLowering::common() const {
766 return jsgraph()->common();
767}
768
769
770MachineOperatorBuilder* JSGenericLowering::machine() const {
771 return jsgraph()->machine();
772}
773
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000774} // namespace compiler
775} // namespace internal
776} // namespace v8