blob: 2249cbcb3f52d9e1be32458f305ab5d89b92ffdd [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// 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 "src/compiler/bytecode-graph-builder.h"
6
7#include "src/compiler/bytecode-branch-analysis.h"
8#include "src/compiler/linkage.h"
9#include "src/compiler/operator-properties.h"
10#include "src/interpreter/bytecodes.h"
11
12namespace v8 {
13namespace internal {
14namespace compiler {
15
Ben Murdoch097c5b22016-05-18 11:27:45 +010016// The abstract execution environment simulates the content of the interpreter
17// register file. The environment performs SSA-renaming of all tracked nodes at
18// split and merge points in the control flow.
19class BytecodeGraphBuilder::Environment : public ZoneObject {
20 public:
21 Environment(BytecodeGraphBuilder* builder, int register_count,
22 int parameter_count, Node* control_dependency, Node* context);
23
24 int parameter_count() const { return parameter_count_; }
25 int register_count() const { return register_count_; }
26
27 Node* LookupAccumulator() const;
28 Node* LookupRegister(interpreter::Register the_register) const;
29
30 void BindAccumulator(Node* node, FrameStateBeforeAndAfter* states = nullptr);
31 void BindRegister(interpreter::Register the_register, Node* node,
32 FrameStateBeforeAndAfter* states = nullptr);
33 void BindRegistersToProjections(interpreter::Register first_reg, Node* node,
34 FrameStateBeforeAndAfter* states = nullptr);
35 void RecordAfterState(Node* node, FrameStateBeforeAndAfter* states);
36
37 // Effect dependency tracked by this environment.
38 Node* GetEffectDependency() { return effect_dependency_; }
39 void UpdateEffectDependency(Node* dependency) {
40 effect_dependency_ = dependency;
41 }
42
43 // Preserve a checkpoint of the environment for the IR graph. Any
44 // further mutation of the environment will not affect checkpoints.
45 Node* Checkpoint(BailoutId bytecode_offset, OutputFrameStateCombine combine);
46
47 // Returns true if the state values are up to date with the current
48 // environment.
49 bool StateValuesAreUpToDate(int output_poke_offset, int output_poke_count);
50
51 // Control dependency tracked by this environment.
52 Node* GetControlDependency() const { return control_dependency_; }
53 void UpdateControlDependency(Node* dependency) {
54 control_dependency_ = dependency;
55 }
56
57 Node* Context() const { return context_; }
58 void SetContext(Node* new_context) { context_ = new_context; }
59
60 Environment* CopyForConditional() const;
61 Environment* CopyForLoop();
62 void Merge(Environment* other);
63
64 private:
65 explicit Environment(const Environment* copy);
66 void PrepareForLoop();
67 bool StateValuesAreUpToDate(Node** state_values, int offset, int count,
68 int output_poke_start, int output_poke_end);
69 bool StateValuesRequireUpdate(Node** state_values, int offset, int count);
70 void UpdateStateValues(Node** state_values, int offset, int count);
71
72 int RegisterToValuesIndex(interpreter::Register the_register) const;
73
74 Zone* zone() const { return builder_->local_zone(); }
75 Graph* graph() const { return builder_->graph(); }
76 CommonOperatorBuilder* common() const { return builder_->common(); }
77 BytecodeGraphBuilder* builder() const { return builder_; }
78 const NodeVector* values() const { return &values_; }
79 NodeVector* values() { return &values_; }
80 int register_base() const { return register_base_; }
81 int accumulator_base() const { return accumulator_base_; }
82
83 BytecodeGraphBuilder* builder_;
84 int register_count_;
85 int parameter_count_;
86 Node* context_;
87 Node* control_dependency_;
88 Node* effect_dependency_;
89 NodeVector values_;
90 Node* parameters_state_values_;
91 Node* registers_state_values_;
92 Node* accumulator_state_values_;
93 int register_base_;
94 int accumulator_base_;
95};
96
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000097// Helper for generating frame states for before and after a bytecode.
98class BytecodeGraphBuilder::FrameStateBeforeAndAfter {
99 public:
Ben Murdoch097c5b22016-05-18 11:27:45 +0100100 explicit FrameStateBeforeAndAfter(BytecodeGraphBuilder* builder)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000101 : builder_(builder),
102 id_after_(BailoutId::None()),
103 added_to_node_(false),
Ben Murdoch097c5b22016-05-18 11:27:45 +0100104 frame_states_unused_(false),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000105 output_poke_offset_(0),
106 output_poke_count_(0) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100107 BailoutId id_before(builder->bytecode_iterator().current_offset());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000108 frame_state_before_ = builder_->environment()->Checkpoint(
109 id_before, OutputFrameStateCombine::Ignore());
Ben Murdoch097c5b22016-05-18 11:27:45 +0100110 id_after_ = BailoutId(id_before.ToInt() +
111 builder->bytecode_iterator().current_bytecode_size());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000112 }
113
114 ~FrameStateBeforeAndAfter() {
115 DCHECK(added_to_node_);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100116 DCHECK(frame_states_unused_ ||
117 builder_->environment()->StateValuesAreUpToDate(output_poke_offset_,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000118 output_poke_count_));
119 }
120
121 private:
122 friend class Environment;
123
124 void AddToNode(Node* node, OutputFrameStateCombine combine) {
125 DCHECK(!added_to_node_);
126 int count = OperatorProperties::GetFrameStateInputCount(node->op());
127 DCHECK_LE(count, 2);
128 if (count >= 1) {
129 // Add the frame state for after the operation.
130 DCHECK_EQ(IrOpcode::kDead,
131 NodeProperties::GetFrameStateInput(node, 0)->opcode());
132 Node* frame_state_after =
133 builder_->environment()->Checkpoint(id_after_, combine);
134 NodeProperties::ReplaceFrameStateInput(node, 0, frame_state_after);
135 }
136
137 if (count >= 2) {
138 // Add the frame state for before the operation.
139 DCHECK_EQ(IrOpcode::kDead,
140 NodeProperties::GetFrameStateInput(node, 1)->opcode());
141 NodeProperties::ReplaceFrameStateInput(node, 1, frame_state_before_);
142 }
143
144 if (!combine.IsOutputIgnored()) {
145 output_poke_offset_ = static_cast<int>(combine.GetOffsetToPokeAt());
146 output_poke_count_ = node->op()->ValueOutputCount();
147 }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100148 frame_states_unused_ = count == 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000149 added_to_node_ = true;
150 }
151
152 BytecodeGraphBuilder* builder_;
153 Node* frame_state_before_;
154 BailoutId id_after_;
155
156 bool added_to_node_;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100157 bool frame_states_unused_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000158 int output_poke_offset_;
159 int output_poke_count_;
160};
161
162
163// Issues:
164// - Scopes - intimately tied to AST. Need to eval what is needed.
165// - Need to resolve closure parameter treatment.
166BytecodeGraphBuilder::Environment::Environment(BytecodeGraphBuilder* builder,
167 int register_count,
168 int parameter_count,
169 Node* control_dependency,
170 Node* context)
171 : builder_(builder),
172 register_count_(register_count),
173 parameter_count_(parameter_count),
174 context_(context),
175 control_dependency_(control_dependency),
176 effect_dependency_(control_dependency),
177 values_(builder->local_zone()),
178 parameters_state_values_(nullptr),
179 registers_state_values_(nullptr),
180 accumulator_state_values_(nullptr) {
181 // The layout of values_ is:
182 //
183 // [receiver] [parameters] [registers] [accumulator]
184 //
185 // parameter[0] is the receiver (this), parameters 1..N are the
186 // parameters supplied to the method (arg0..argN-1). The accumulator
187 // is stored separately.
188
189 // Parameters including the receiver
190 for (int i = 0; i < parameter_count; i++) {
191 const char* debug_name = (i == 0) ? "%this" : nullptr;
192 const Operator* op = common()->Parameter(i, debug_name);
193 Node* parameter = builder->graph()->NewNode(op, graph()->start());
194 values()->push_back(parameter);
195 }
196
197 // Registers
198 register_base_ = static_cast<int>(values()->size());
199 Node* undefined_constant = builder->jsgraph()->UndefinedConstant();
200 values()->insert(values()->end(), register_count, undefined_constant);
201
202 // Accumulator
203 accumulator_base_ = static_cast<int>(values()->size());
204 values()->push_back(undefined_constant);
205}
206
207
208BytecodeGraphBuilder::Environment::Environment(
209 const BytecodeGraphBuilder::Environment* other)
210 : builder_(other->builder_),
211 register_count_(other->register_count_),
212 parameter_count_(other->parameter_count_),
213 context_(other->context_),
214 control_dependency_(other->control_dependency_),
215 effect_dependency_(other->effect_dependency_),
216 values_(other->zone()),
217 parameters_state_values_(nullptr),
218 registers_state_values_(nullptr),
219 accumulator_state_values_(nullptr),
220 register_base_(other->register_base_),
221 accumulator_base_(other->accumulator_base_) {
222 values_ = other->values_;
223}
224
225
226int BytecodeGraphBuilder::Environment::RegisterToValuesIndex(
227 interpreter::Register the_register) const {
228 if (the_register.is_parameter()) {
229 return the_register.ToParameterIndex(parameter_count());
230 } else {
231 return the_register.index() + register_base();
232 }
233}
234
235
236Node* BytecodeGraphBuilder::Environment::LookupAccumulator() const {
237 return values()->at(accumulator_base_);
238}
239
240
241Node* BytecodeGraphBuilder::Environment::LookupRegister(
242 interpreter::Register the_register) const {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100243 if (the_register.is_current_context()) {
244 return Context();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000245 } else if (the_register.is_function_closure()) {
246 return builder()->GetFunctionClosure();
247 } else if (the_register.is_new_target()) {
248 return builder()->GetNewTarget();
249 } else {
250 int values_index = RegisterToValuesIndex(the_register);
251 return values()->at(values_index);
252 }
253}
254
255
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000256void BytecodeGraphBuilder::Environment::BindAccumulator(
257 Node* node, FrameStateBeforeAndAfter* states) {
258 if (states) {
259 states->AddToNode(node, OutputFrameStateCombine::PokeAt(0));
260 }
261 values()->at(accumulator_base_) = node;
262}
263
264
265void BytecodeGraphBuilder::Environment::BindRegister(
266 interpreter::Register the_register, Node* node,
267 FrameStateBeforeAndAfter* states) {
268 int values_index = RegisterToValuesIndex(the_register);
269 if (states) {
270 states->AddToNode(node, OutputFrameStateCombine::PokeAt(accumulator_base_ -
271 values_index));
272 }
273 values()->at(values_index) = node;
274}
275
276
277void BytecodeGraphBuilder::Environment::BindRegistersToProjections(
278 interpreter::Register first_reg, Node* node,
279 FrameStateBeforeAndAfter* states) {
280 int values_index = RegisterToValuesIndex(first_reg);
281 if (states) {
282 states->AddToNode(node, OutputFrameStateCombine::PokeAt(accumulator_base_ -
283 values_index));
284 }
285 for (int i = 0; i < node->op()->ValueOutputCount(); i++) {
286 values()->at(values_index + i) =
287 builder()->NewNode(common()->Projection(i), node);
288 }
289}
290
291
292void BytecodeGraphBuilder::Environment::RecordAfterState(
293 Node* node, FrameStateBeforeAndAfter* states) {
294 states->AddToNode(node, OutputFrameStateCombine::Ignore());
295}
296
297
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000298BytecodeGraphBuilder::Environment*
299BytecodeGraphBuilder::Environment::CopyForLoop() {
300 PrepareForLoop();
301 return new (zone()) Environment(this);
302}
303
304
305BytecodeGraphBuilder::Environment*
306BytecodeGraphBuilder::Environment::CopyForConditional() const {
307 return new (zone()) Environment(this);
308}
309
310
311void BytecodeGraphBuilder::Environment::Merge(
312 BytecodeGraphBuilder::Environment* other) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000313 // Create a merge of the control dependencies of both environments and update
314 // the current environment's control dependency accordingly.
315 Node* control = builder()->MergeControl(GetControlDependency(),
316 other->GetControlDependency());
317 UpdateControlDependency(control);
318
319 // Create a merge of the effect dependencies of both environments and update
320 // the current environment's effect dependency accordingly.
321 Node* effect = builder()->MergeEffect(GetEffectDependency(),
322 other->GetEffectDependency(), control);
323 UpdateEffectDependency(effect);
324
325 // Introduce Phi nodes for values that have differing input at merge points,
326 // potentially extending an existing Phi node if possible.
327 context_ = builder()->MergeValue(context_, other->context_, control);
328 for (size_t i = 0; i < values_.size(); i++) {
329 values_[i] = builder()->MergeValue(values_[i], other->values_[i], control);
330 }
331}
332
333
334void BytecodeGraphBuilder::Environment::PrepareForLoop() {
335 // Create a control node for the loop header.
336 Node* control = builder()->NewLoop();
337
338 // Create a Phi for external effects.
339 Node* effect = builder()->NewEffectPhi(1, GetEffectDependency(), control);
340 UpdateEffectDependency(effect);
341
342 // Assume everything in the loop is updated.
343 context_ = builder()->NewPhi(1, context_, control);
344 int size = static_cast<int>(values()->size());
345 for (int i = 0; i < size; i++) {
346 values()->at(i) = builder()->NewPhi(1, values()->at(i), control);
347 }
348
349 // Connect to the loop end.
350 Node* terminate = builder()->graph()->NewNode(
351 builder()->common()->Terminate(), effect, control);
352 builder()->exit_controls_.push_back(terminate);
353}
354
355
356bool BytecodeGraphBuilder::Environment::StateValuesRequireUpdate(
357 Node** state_values, int offset, int count) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100358 if (!builder()->deoptimization_enabled_) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000359 return false;
360 }
361 if (*state_values == nullptr) {
362 return true;
363 }
364 DCHECK_EQ((*state_values)->InputCount(), count);
365 DCHECK_LE(static_cast<size_t>(offset + count), values()->size());
366 Node** env_values = (count == 0) ? nullptr : &values()->at(offset);
367 for (int i = 0; i < count; i++) {
368 if ((*state_values)->InputAt(i) != env_values[i]) {
369 return true;
370 }
371 }
372 return false;
373}
374
375
376void BytecodeGraphBuilder::Environment::UpdateStateValues(Node** state_values,
377 int offset,
378 int count) {
379 if (StateValuesRequireUpdate(state_values, offset, count)) {
380 const Operator* op = common()->StateValues(count);
381 (*state_values) = graph()->NewNode(op, count, &values()->at(offset));
382 }
383}
384
385
386Node* BytecodeGraphBuilder::Environment::Checkpoint(
387 BailoutId bailout_id, OutputFrameStateCombine combine) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100388 if (!builder()->deoptimization_enabled_) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000389 return builder()->jsgraph()->EmptyFrameState();
390 }
391
392 // TODO(rmcilroy): Consider using StateValuesCache for some state values.
393 UpdateStateValues(&parameters_state_values_, 0, parameter_count());
394 UpdateStateValues(&registers_state_values_, register_base(),
395 register_count());
396 UpdateStateValues(&accumulator_state_values_, accumulator_base(), 1);
397
398 const Operator* op = common()->FrameState(
399 bailout_id, combine, builder()->frame_state_function_info());
400 Node* result = graph()->NewNode(
401 op, parameters_state_values_, registers_state_values_,
402 accumulator_state_values_, Context(), builder()->GetFunctionClosure(),
403 builder()->graph()->start());
404
405 return result;
406}
407
408
409bool BytecodeGraphBuilder::Environment::StateValuesAreUpToDate(
410 Node** state_values, int offset, int count, int output_poke_start,
411 int output_poke_end) {
412 DCHECK_LE(static_cast<size_t>(offset + count), values()->size());
413 for (int i = 0; i < count; i++, offset++) {
414 if (offset < output_poke_start || offset >= output_poke_end) {
415 if ((*state_values)->InputAt(i) != values()->at(offset)) {
416 return false;
417 }
418 }
419 }
420 return true;
421}
422
423
424bool BytecodeGraphBuilder::Environment::StateValuesAreUpToDate(
425 int output_poke_offset, int output_poke_count) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100426 if (!builder()->deoptimization_enabled_) return true;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000427 // Poke offset is relative to the top of the stack (i.e., the accumulator).
428 int output_poke_start = accumulator_base() - output_poke_offset;
429 int output_poke_end = output_poke_start + output_poke_count;
430 return StateValuesAreUpToDate(&parameters_state_values_, 0, parameter_count(),
431 output_poke_start, output_poke_end) &&
432 StateValuesAreUpToDate(&registers_state_values_, register_base(),
433 register_count(), output_poke_start,
434 output_poke_end) &&
435 StateValuesAreUpToDate(&accumulator_state_values_, accumulator_base(),
436 1, output_poke_start, output_poke_end);
437}
438
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000439BytecodeGraphBuilder::BytecodeGraphBuilder(Zone* local_zone,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100440 CompilationInfo* info,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000441 JSGraph* jsgraph)
442 : local_zone_(local_zone),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000443 jsgraph_(jsgraph),
Ben Murdoch097c5b22016-05-18 11:27:45 +0100444 bytecode_array_(handle(info->shared_info()->bytecode_array())),
445 exception_handler_table_(
446 handle(HandlerTable::cast(bytecode_array()->handler_table()))),
Ben Murdochda12d292016-06-02 14:46:10 +0100447 feedback_vector_(handle(info->shared_info()->feedback_vector())),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000448 frame_state_function_info_(common()->CreateFrameStateFunctionInfo(
449 FrameStateType::kInterpretedFunction,
450 bytecode_array()->parameter_count(),
Ben Murdoch097c5b22016-05-18 11:27:45 +0100451 bytecode_array()->register_count(), info->shared_info())),
452 deoptimization_enabled_(info->is_deoptimization_enabled()),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000453 merge_environments_(local_zone),
Ben Murdoch097c5b22016-05-18 11:27:45 +0100454 exception_handlers_(local_zone),
455 current_exception_handler_(0),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000456 input_buffer_size_(0),
457 input_buffer_(nullptr),
458 exit_controls_(local_zone) {}
459
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000460Node* BytecodeGraphBuilder::GetNewTarget() {
461 if (!new_target_.is_set()) {
462 int params = bytecode_array()->parameter_count();
463 int index = Linkage::GetJSCallNewTargetParamIndex(params);
464 const Operator* op = common()->Parameter(index, "%new.target");
465 Node* node = NewNode(op, graph()->start());
466 new_target_.set(node);
467 }
468 return new_target_.get();
469}
470
471
472Node* BytecodeGraphBuilder::GetFunctionContext() {
473 if (!function_context_.is_set()) {
474 int params = bytecode_array()->parameter_count();
475 int index = Linkage::GetJSCallContextParamIndex(params);
476 const Operator* op = common()->Parameter(index, "%context");
477 Node* node = NewNode(op, graph()->start());
478 function_context_.set(node);
479 }
480 return function_context_.get();
481}
482
483
484Node* BytecodeGraphBuilder::GetFunctionClosure() {
485 if (!function_closure_.is_set()) {
486 int index = Linkage::kJSCallClosureParamIndex;
487 const Operator* op = common()->Parameter(index, "%closure");
488 Node* node = NewNode(op, graph()->start());
489 function_closure_.set(node);
490 }
491 return function_closure_.get();
492}
493
494
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000495Node* BytecodeGraphBuilder::BuildLoadNativeContextField(int index) {
496 const Operator* op =
497 javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true);
498 Node* native_context = NewNode(op, environment()->Context());
499 return NewNode(javascript()->LoadContext(0, index, true), native_context);
500}
501
502
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000503VectorSlotPair BytecodeGraphBuilder::CreateVectorSlotPair(int slot_id) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000504 FeedbackVectorSlot slot;
505 if (slot_id >= TypeFeedbackVector::kReservedIndexCount) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100506 slot = feedback_vector()->ToSlot(slot_id);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000507 }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100508 return VectorSlotPair(feedback_vector(), slot);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000509}
510
Ben Murdoch097c5b22016-05-18 11:27:45 +0100511bool BytecodeGraphBuilder::CreateGraph() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000512 // Set up the basic structure of the graph. Outputs for {Start} are
513 // the formal parameters (including the receiver) plus context and
514 // closure.
515
516 // Set up the basic structure of the graph. Outputs for {Start} are the formal
517 // parameters (including the receiver) plus new target, number of arguments,
518 // context and closure.
519 int actual_parameter_count = bytecode_array()->parameter_count() + 4;
520 graph()->SetStart(graph()->NewNode(common()->Start(actual_parameter_count)));
521
522 Environment env(this, bytecode_array()->register_count(),
523 bytecode_array()->parameter_count(), graph()->start(),
524 GetFunctionContext());
525 set_environment(&env);
526
Ben Murdoch097c5b22016-05-18 11:27:45 +0100527 VisitBytecodes();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000528
529 // Finish the basic structure of the graph.
530 DCHECK_NE(0u, exit_controls_.size());
531 int const input_count = static_cast<int>(exit_controls_.size());
532 Node** const inputs = &exit_controls_.front();
533 Node* end = graph()->NewNode(common()->End(input_count), input_count, inputs);
534 graph()->SetEnd(end);
535
536 return true;
537}
538
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000539void BytecodeGraphBuilder::VisitBytecodes() {
540 BytecodeBranchAnalysis analysis(bytecode_array(), local_zone());
541 analysis.Analyze();
542 set_branch_analysis(&analysis);
543 interpreter::BytecodeArrayIterator iterator(bytecode_array());
544 set_bytecode_iterator(&iterator);
545 while (!iterator.done()) {
546 int current_offset = iterator.current_offset();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100547 EnterAndExitExceptionHandlers(current_offset);
548 SwitchToMergeEnvironment(current_offset);
549 if (environment() != nullptr) {
550 BuildLoopHeaderEnvironment(current_offset);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000551
552 switch (iterator.current_bytecode()) {
553#define BYTECODE_CASE(name, ...) \
554 case interpreter::Bytecode::k##name: \
Ben Murdoch097c5b22016-05-18 11:27:45 +0100555 Visit##name(); \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000556 break;
557 BYTECODE_LIST(BYTECODE_CASE)
558#undef BYTECODE_CODE
559 }
560 }
561 iterator.Advance();
562 }
563 set_branch_analysis(nullptr);
564 set_bytecode_iterator(nullptr);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100565 DCHECK(exception_handlers_.empty());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000566}
567
Ben Murdoch097c5b22016-05-18 11:27:45 +0100568void BytecodeGraphBuilder::VisitLdaZero() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000569 Node* node = jsgraph()->ZeroConstant();
570 environment()->BindAccumulator(node);
571}
572
Ben Murdochda12d292016-06-02 14:46:10 +0100573void BytecodeGraphBuilder::VisitLdaSmi() {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100574 Node* node = jsgraph()->Constant(bytecode_iterator().GetImmediateOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000575 environment()->BindAccumulator(node);
576}
577
Ben Murdoch097c5b22016-05-18 11:27:45 +0100578void BytecodeGraphBuilder::VisitLdaConstant() {
579 Node* node =
580 jsgraph()->Constant(bytecode_iterator().GetConstantForIndexOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000581 environment()->BindAccumulator(node);
582}
583
Ben Murdoch097c5b22016-05-18 11:27:45 +0100584void BytecodeGraphBuilder::VisitLdaUndefined() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000585 Node* node = jsgraph()->UndefinedConstant();
586 environment()->BindAccumulator(node);
587}
588
Ben Murdoch097c5b22016-05-18 11:27:45 +0100589void BytecodeGraphBuilder::VisitLdaNull() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000590 Node* node = jsgraph()->NullConstant();
591 environment()->BindAccumulator(node);
592}
593
Ben Murdoch097c5b22016-05-18 11:27:45 +0100594void BytecodeGraphBuilder::VisitLdaTheHole() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000595 Node* node = jsgraph()->TheHoleConstant();
596 environment()->BindAccumulator(node);
597}
598
Ben Murdoch097c5b22016-05-18 11:27:45 +0100599void BytecodeGraphBuilder::VisitLdaTrue() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000600 Node* node = jsgraph()->TrueConstant();
601 environment()->BindAccumulator(node);
602}
603
Ben Murdoch097c5b22016-05-18 11:27:45 +0100604void BytecodeGraphBuilder::VisitLdaFalse() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000605 Node* node = jsgraph()->FalseConstant();
606 environment()->BindAccumulator(node);
607}
608
Ben Murdoch097c5b22016-05-18 11:27:45 +0100609void BytecodeGraphBuilder::VisitLdar() {
610 Node* value =
611 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000612 environment()->BindAccumulator(value);
613}
614
Ben Murdoch097c5b22016-05-18 11:27:45 +0100615void BytecodeGraphBuilder::VisitStar() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000616 Node* value = environment()->LookupAccumulator();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100617 environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0), value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000618}
619
Ben Murdoch097c5b22016-05-18 11:27:45 +0100620void BytecodeGraphBuilder::VisitMov() {
621 Node* value =
622 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
623 environment()->BindRegister(bytecode_iterator().GetRegisterOperand(1), value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000624}
625
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000626void BytecodeGraphBuilder::BuildLoadGlobal(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000627 TypeofMode typeof_mode) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100628 FrameStateBeforeAndAfter states(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000629 Handle<Name> name =
Ben Murdoch097c5b22016-05-18 11:27:45 +0100630 Handle<Name>::cast(bytecode_iterator().GetConstantForIndexOperand(0));
631 VectorSlotPair feedback =
632 CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(1));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000633
634 const Operator* op = javascript()->LoadGlobal(name, feedback, typeof_mode);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100635 Node* node = NewNode(op, GetFunctionClosure());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000636 environment()->BindAccumulator(node, &states);
637}
638
Ben Murdoch097c5b22016-05-18 11:27:45 +0100639void BytecodeGraphBuilder::VisitLdaGlobal() {
640 BuildLoadGlobal(TypeofMode::NOT_INSIDE_TYPEOF);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000641}
642
Ben Murdoch097c5b22016-05-18 11:27:45 +0100643void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeof() {
644 BuildLoadGlobal(TypeofMode::INSIDE_TYPEOF);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000645}
646
Ben Murdoch097c5b22016-05-18 11:27:45 +0100647void BytecodeGraphBuilder::BuildStoreGlobal(LanguageMode language_mode) {
648 FrameStateBeforeAndAfter states(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000649 Handle<Name> name =
Ben Murdoch097c5b22016-05-18 11:27:45 +0100650 Handle<Name>::cast(bytecode_iterator().GetConstantForIndexOperand(0));
651 VectorSlotPair feedback =
652 CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(1));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000653 Node* value = environment()->LookupAccumulator();
654
Ben Murdoch097c5b22016-05-18 11:27:45 +0100655 const Operator* op = javascript()->StoreGlobal(language_mode, name, feedback);
656 Node* node = NewNode(op, value, GetFunctionClosure());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000657 environment()->RecordAfterState(node, &states);
658}
659
Ben Murdoch097c5b22016-05-18 11:27:45 +0100660void BytecodeGraphBuilder::VisitStaGlobalSloppy() {
661 BuildStoreGlobal(LanguageMode::SLOPPY);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000662}
663
Ben Murdoch097c5b22016-05-18 11:27:45 +0100664void BytecodeGraphBuilder::VisitStaGlobalStrict() {
665 BuildStoreGlobal(LanguageMode::STRICT);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000666}
667
Ben Murdoch097c5b22016-05-18 11:27:45 +0100668void BytecodeGraphBuilder::VisitLdaContextSlot() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000669 // TODO(mythria): LoadContextSlots are unrolled by the required depth when
670 // generating bytecode. Hence the value of depth is always 0. Update this
671 // code, when the implementation changes.
672 // TODO(mythria): immutable flag is also set to false. This information is not
673 // available in bytecode array. update this code when the implementation
674 // changes.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100675 const Operator* op = javascript()->LoadContext(
676 0, bytecode_iterator().GetIndexOperand(1), false);
677 Node* context =
678 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000679 Node* node = NewNode(op, context);
680 environment()->BindAccumulator(node);
681}
682
Ben Murdoch097c5b22016-05-18 11:27:45 +0100683void BytecodeGraphBuilder::VisitStaContextSlot() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000684 // TODO(mythria): LoadContextSlots are unrolled by the required depth when
685 // generating bytecode. Hence the value of depth is always 0. Update this
686 // code, when the implementation changes.
687 const Operator* op =
Ben Murdoch097c5b22016-05-18 11:27:45 +0100688 javascript()->StoreContext(0, bytecode_iterator().GetIndexOperand(1));
689 Node* context =
690 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000691 Node* value = environment()->LookupAccumulator();
692 NewNode(op, context, value);
693}
694
Ben Murdoch097c5b22016-05-18 11:27:45 +0100695void BytecodeGraphBuilder::BuildLdaLookupSlot(TypeofMode typeof_mode) {
696 FrameStateBeforeAndAfter states(this);
697 Node* name =
698 jsgraph()->Constant(bytecode_iterator().GetConstantForIndexOperand(0));
699 const Operator* op =
700 javascript()->CallRuntime(typeof_mode == TypeofMode::NOT_INSIDE_TYPEOF
701 ? Runtime::kLoadLookupSlot
702 : Runtime::kLoadLookupSlotInsideTypeof);
703 Node* value = NewNode(op, name);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000704 environment()->BindAccumulator(value, &states);
705}
706
Ben Murdoch097c5b22016-05-18 11:27:45 +0100707void BytecodeGraphBuilder::VisitLdaLookupSlot() {
708 BuildLdaLookupSlot(TypeofMode::NOT_INSIDE_TYPEOF);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000709}
710
Ben Murdoch097c5b22016-05-18 11:27:45 +0100711void BytecodeGraphBuilder::VisitLdaLookupSlotInsideTypeof() {
712 BuildLdaLookupSlot(TypeofMode::INSIDE_TYPEOF);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000713}
714
Ben Murdoch097c5b22016-05-18 11:27:45 +0100715void BytecodeGraphBuilder::BuildStaLookupSlot(LanguageMode language_mode) {
716 FrameStateBeforeAndAfter states(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000717 Node* value = environment()->LookupAccumulator();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100718 Node* name =
719 jsgraph()->Constant(bytecode_iterator().GetConstantForIndexOperand(0));
720 const Operator* op = javascript()->CallRuntime(
721 is_strict(language_mode) ? Runtime::kStoreLookupSlot_Strict
722 : Runtime::kStoreLookupSlot_Sloppy);
723 Node* store = NewNode(op, name, value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000724 environment()->BindAccumulator(store, &states);
725}
726
Ben Murdoch097c5b22016-05-18 11:27:45 +0100727void BytecodeGraphBuilder::VisitStaLookupSlotSloppy() {
728 BuildStaLookupSlot(LanguageMode::SLOPPY);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000729}
730
Ben Murdoch097c5b22016-05-18 11:27:45 +0100731void BytecodeGraphBuilder::VisitStaLookupSlotStrict() {
732 BuildStaLookupSlot(LanguageMode::STRICT);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000733}
734
Ben Murdoch097c5b22016-05-18 11:27:45 +0100735void BytecodeGraphBuilder::BuildNamedLoad() {
736 FrameStateBeforeAndAfter states(this);
737 Node* object =
738 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000739 Handle<Name> name =
Ben Murdoch097c5b22016-05-18 11:27:45 +0100740 Handle<Name>::cast(bytecode_iterator().GetConstantForIndexOperand(1));
741 VectorSlotPair feedback =
742 CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(2));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000743
Ben Murdoch097c5b22016-05-18 11:27:45 +0100744 const Operator* op = javascript()->LoadNamed(name, feedback);
745 Node* node = NewNode(op, object, GetFunctionClosure());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000746 environment()->BindAccumulator(node, &states);
747}
748
Ben Murdoch097c5b22016-05-18 11:27:45 +0100749void BytecodeGraphBuilder::VisitLoadIC() { BuildNamedLoad(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000750
Ben Murdoch097c5b22016-05-18 11:27:45 +0100751void BytecodeGraphBuilder::BuildKeyedLoad() {
752 FrameStateBeforeAndAfter states(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000753 Node* key = environment()->LookupAccumulator();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100754 Node* object =
755 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
756 VectorSlotPair feedback =
757 CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(1));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000758
Ben Murdoch097c5b22016-05-18 11:27:45 +0100759 const Operator* op = javascript()->LoadProperty(feedback);
760 Node* node = NewNode(op, object, key, GetFunctionClosure());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000761 environment()->BindAccumulator(node, &states);
762}
763
Ben Murdoch097c5b22016-05-18 11:27:45 +0100764void BytecodeGraphBuilder::VisitKeyedLoadIC() { BuildKeyedLoad(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000765
Ben Murdoch097c5b22016-05-18 11:27:45 +0100766void BytecodeGraphBuilder::BuildNamedStore(LanguageMode language_mode) {
767 FrameStateBeforeAndAfter states(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000768 Node* value = environment()->LookupAccumulator();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100769 Node* object =
770 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000771 Handle<Name> name =
Ben Murdoch097c5b22016-05-18 11:27:45 +0100772 Handle<Name>::cast(bytecode_iterator().GetConstantForIndexOperand(1));
773 VectorSlotPair feedback =
774 CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(2));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000775
Ben Murdoch097c5b22016-05-18 11:27:45 +0100776 const Operator* op = javascript()->StoreNamed(language_mode, name, feedback);
777 Node* node = NewNode(op, object, value, GetFunctionClosure());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000778 environment()->RecordAfterState(node, &states);
779}
780
Ben Murdoch097c5b22016-05-18 11:27:45 +0100781void BytecodeGraphBuilder::VisitStoreICSloppy() {
782 BuildNamedStore(LanguageMode::SLOPPY);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000783}
784
Ben Murdoch097c5b22016-05-18 11:27:45 +0100785void BytecodeGraphBuilder::VisitStoreICStrict() {
786 BuildNamedStore(LanguageMode::STRICT);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000787}
788
Ben Murdoch097c5b22016-05-18 11:27:45 +0100789void BytecodeGraphBuilder::BuildKeyedStore(LanguageMode language_mode) {
790 FrameStateBeforeAndAfter states(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000791 Node* value = environment()->LookupAccumulator();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100792 Node* object =
793 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
794 Node* key =
795 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
796 VectorSlotPair feedback =
797 CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(2));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000798
Ben Murdoch097c5b22016-05-18 11:27:45 +0100799 const Operator* op = javascript()->StoreProperty(language_mode, feedback);
800 Node* node = NewNode(op, object, key, value, GetFunctionClosure());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000801 environment()->RecordAfterState(node, &states);
802}
803
Ben Murdoch097c5b22016-05-18 11:27:45 +0100804void BytecodeGraphBuilder::VisitKeyedStoreICSloppy() {
805 BuildKeyedStore(LanguageMode::SLOPPY);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000806}
807
Ben Murdoch097c5b22016-05-18 11:27:45 +0100808void BytecodeGraphBuilder::VisitKeyedStoreICStrict() {
809 BuildKeyedStore(LanguageMode::STRICT);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000810}
811
Ben Murdoch097c5b22016-05-18 11:27:45 +0100812void BytecodeGraphBuilder::VisitPushContext() {
813 Node* new_context = environment()->LookupAccumulator();
814 environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0),
815 environment()->Context());
816 environment()->SetContext(new_context);
817}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000818
Ben Murdoch097c5b22016-05-18 11:27:45 +0100819void BytecodeGraphBuilder::VisitPopContext() {
820 Node* context =
821 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000822 environment()->SetContext(context);
823}
824
Ben Murdoch097c5b22016-05-18 11:27:45 +0100825void BytecodeGraphBuilder::VisitCreateClosure() {
826 Handle<SharedFunctionInfo> shared_info = Handle<SharedFunctionInfo>::cast(
827 bytecode_iterator().GetConstantForIndexOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000828 PretenureFlag tenured =
Ben Murdochda12d292016-06-02 14:46:10 +0100829 bytecode_iterator().GetFlagOperand(1) ? TENURED : NOT_TENURED;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000830 const Operator* op = javascript()->CreateClosure(shared_info, tenured);
831 Node* closure = NewNode(op);
832 environment()->BindAccumulator(closure);
833}
834
Ben Murdoch097c5b22016-05-18 11:27:45 +0100835void BytecodeGraphBuilder::BuildCreateArguments(CreateArgumentsType type) {
836 FrameStateBeforeAndAfter states(this);
837 const Operator* op = javascript()->CreateArguments(type);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000838 Node* object = NewNode(op, GetFunctionClosure());
839 environment()->BindAccumulator(object, &states);
840}
841
Ben Murdoch097c5b22016-05-18 11:27:45 +0100842void BytecodeGraphBuilder::VisitCreateMappedArguments() {
843 BuildCreateArguments(CreateArgumentsType::kMappedArguments);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000844}
845
Ben Murdoch097c5b22016-05-18 11:27:45 +0100846void BytecodeGraphBuilder::VisitCreateUnmappedArguments() {
847 BuildCreateArguments(CreateArgumentsType::kUnmappedArguments);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000848}
849
Ben Murdoch097c5b22016-05-18 11:27:45 +0100850void BytecodeGraphBuilder::VisitCreateRestParameter() {
851 BuildCreateArguments(CreateArgumentsType::kRestParameter);
852}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000853
Ben Murdoch097c5b22016-05-18 11:27:45 +0100854void BytecodeGraphBuilder::BuildCreateLiteral(const Operator* op) {
855 FrameStateBeforeAndAfter states(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000856 Node* literal = NewNode(op, GetFunctionClosure());
857 environment()->BindAccumulator(literal, &states);
858}
859
Ben Murdochda12d292016-06-02 14:46:10 +0100860void BytecodeGraphBuilder::VisitCreateRegExpLiteral() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000861 Handle<String> constant_pattern =
Ben Murdoch097c5b22016-05-18 11:27:45 +0100862 Handle<String>::cast(bytecode_iterator().GetConstantForIndexOperand(0));
863 int literal_index = bytecode_iterator().GetIndexOperand(1);
Ben Murdochda12d292016-06-02 14:46:10 +0100864 int literal_flags = bytecode_iterator().GetFlagOperand(2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000865 const Operator* op = javascript()->CreateLiteralRegExp(
866 constant_pattern, literal_flags, literal_index);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100867 BuildCreateLiteral(op);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000868}
869
Ben Murdochda12d292016-06-02 14:46:10 +0100870void BytecodeGraphBuilder::VisitCreateArrayLiteral() {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100871 Handle<FixedArray> constant_elements = Handle<FixedArray>::cast(
872 bytecode_iterator().GetConstantForIndexOperand(0));
873 int literal_index = bytecode_iterator().GetIndexOperand(1);
Ben Murdochda12d292016-06-02 14:46:10 +0100874 int literal_flags = bytecode_iterator().GetFlagOperand(2);
875 int number_of_elements = constant_elements->length();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000876 const Operator* op = javascript()->CreateLiteralArray(
Ben Murdochda12d292016-06-02 14:46:10 +0100877 constant_elements, literal_flags, literal_index, number_of_elements);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100878 BuildCreateLiteral(op);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000879}
880
Ben Murdoch097c5b22016-05-18 11:27:45 +0100881void BytecodeGraphBuilder::VisitCreateObjectLiteral() {
Ben Murdochda12d292016-06-02 14:46:10 +0100882 Handle<FixedArray> constant_properties = Handle<FixedArray>::cast(
883 bytecode_iterator().GetConstantForIndexOperand(0));
884 int literal_index = bytecode_iterator().GetIndexOperand(1);
885 int literal_flags = bytecode_iterator().GetFlagOperand(2);
886 // TODO(mstarzinger): Thread through number of properties.
887 int number_of_properties = constant_properties->length() / 2;
888 const Operator* op = javascript()->CreateLiteralObject(
889 constant_properties, literal_flags, literal_index, number_of_properties);
890 BuildCreateLiteral(op);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000891}
892
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000893Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op,
894 Node* callee,
895 interpreter::Register receiver,
896 size_t arity) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100897 Node** all = local_zone()->NewArray<Node*>(static_cast<int>(arity));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000898 all[0] = callee;
899 all[1] = environment()->LookupRegister(receiver);
900 int receiver_index = receiver.index();
901 for (int i = 2; i < static_cast<int>(arity); ++i) {
902 all[i] = environment()->LookupRegister(
903 interpreter::Register(receiver_index + i - 1));
904 }
905 Node* value = MakeNode(call_op, static_cast<int>(arity), all, false);
906 return value;
907}
908
Ben Murdoch097c5b22016-05-18 11:27:45 +0100909void BytecodeGraphBuilder::BuildCall(TailCallMode tail_call_mode) {
910 FrameStateBeforeAndAfter states(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000911 // TODO(rmcilroy): Set receiver_hint correctly based on whether the receiver
912 // register has been loaded with null / undefined explicitly or we are sure it
913 // is not null / undefined.
914 ConvertReceiverMode receiver_hint = ConvertReceiverMode::kAny;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100915 Node* callee =
916 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
917 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
918 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
919 VectorSlotPair feedback =
920 CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(3));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000921
922 const Operator* call = javascript()->CallFunction(
Ben Murdoch097c5b22016-05-18 11:27:45 +0100923 arg_count + 1, feedback, receiver_hint, tail_call_mode);
924 Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000925 environment()->BindAccumulator(value, &states);
926}
927
Ben Murdoch097c5b22016-05-18 11:27:45 +0100928void BytecodeGraphBuilder::VisitCall() { BuildCall(TailCallMode::kDisallow); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000929
Ben Murdochda12d292016-06-02 14:46:10 +0100930void BytecodeGraphBuilder::VisitTailCall() {
931 TailCallMode tail_call_mode =
932 bytecode_array_->GetIsolate()->is_tail_call_elimination_enabled()
933 ? TailCallMode::kAllow
934 : TailCallMode::kDisallow;
935 BuildCall(tail_call_mode);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000936}
937
Ben Murdochda12d292016-06-02 14:46:10 +0100938void BytecodeGraphBuilder::VisitCallJSRuntime() {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100939 FrameStateBeforeAndAfter states(this);
940 Node* callee =
941 BuildLoadNativeContextField(bytecode_iterator().GetIndexOperand(0));
942 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
943 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000944
945 // Create node to perform the JS runtime call.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100946 const Operator* call = javascript()->CallFunction(arg_count + 1);
947 Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000948 environment()->BindAccumulator(value, &states);
949}
950
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000951Node* BytecodeGraphBuilder::ProcessCallRuntimeArguments(
952 const Operator* call_runtime_op, interpreter::Register first_arg,
953 size_t arity) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100954 Node** all = local_zone()->NewArray<Node*>(arity);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000955 int first_arg_index = first_arg.index();
956 for (int i = 0; i < static_cast<int>(arity); ++i) {
957 all[i] = environment()->LookupRegister(
958 interpreter::Register(first_arg_index + i));
959 }
960 Node* value = MakeNode(call_runtime_op, static_cast<int>(arity), all, false);
961 return value;
962}
963
Ben Murdochda12d292016-06-02 14:46:10 +0100964void BytecodeGraphBuilder::VisitCallRuntime() {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100965 FrameStateBeforeAndAfter states(this);
Ben Murdochda12d292016-06-02 14:46:10 +0100966 Runtime::FunctionId functionId = static_cast<Runtime::FunctionId>(
967 bytecode_iterator().GetRuntimeIdOperand(0));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100968 interpreter::Register first_arg = bytecode_iterator().GetRegisterOperand(1);
969 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000970
971 // Create node to perform the runtime call.
972 const Operator* call = javascript()->CallRuntime(functionId, arg_count);
973 Node* value = ProcessCallRuntimeArguments(call, first_arg, arg_count);
974 environment()->BindAccumulator(value, &states);
975}
976
Ben Murdochda12d292016-06-02 14:46:10 +0100977void BytecodeGraphBuilder::VisitCallRuntimeForPair() {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100978 FrameStateBeforeAndAfter states(this);
Ben Murdochda12d292016-06-02 14:46:10 +0100979 Runtime::FunctionId functionId = static_cast<Runtime::FunctionId>(
980 bytecode_iterator().GetRuntimeIdOperand(0));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100981 interpreter::Register first_arg = bytecode_iterator().GetRegisterOperand(1);
982 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
983 interpreter::Register first_return =
984 bytecode_iterator().GetRegisterOperand(3);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000985
986 // Create node to perform the runtime call.
987 const Operator* call = javascript()->CallRuntime(functionId, arg_count);
988 Node* return_pair = ProcessCallRuntimeArguments(call, first_arg, arg_count);
989 environment()->BindRegistersToProjections(first_return, return_pair, &states);
990}
991
Ben Murdochda12d292016-06-02 14:46:10 +0100992void BytecodeGraphBuilder::VisitInvokeIntrinsic() {
993 FrameStateBeforeAndAfter states(this);
994 Runtime::FunctionId functionId = static_cast<Runtime::FunctionId>(
995 bytecode_iterator().GetRuntimeIdOperand(0));
996 interpreter::Register first_arg = bytecode_iterator().GetRegisterOperand(1);
997 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100998
Ben Murdochda12d292016-06-02 14:46:10 +0100999 // Create node to perform the runtime call. Turbofan will take care of the
1000 // lowering.
1001 const Operator* call = javascript()->CallRuntime(functionId, arg_count);
1002 Node* value = ProcessCallRuntimeArguments(call, first_arg, arg_count);
1003 environment()->BindAccumulator(value, &states);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001004}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001005
1006Node* BytecodeGraphBuilder::ProcessCallNewArguments(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001007 const Operator* call_new_op, Node* callee, Node* new_target,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001008 interpreter::Register first_arg, size_t arity) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001009 Node** all = local_zone()->NewArray<Node*>(arity);
1010 all[0] = new_target;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001011 int first_arg_index = first_arg.index();
1012 for (int i = 1; i < static_cast<int>(arity) - 1; ++i) {
1013 all[i] = environment()->LookupRegister(
1014 interpreter::Register(first_arg_index + i - 1));
1015 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01001016 all[arity - 1] = callee;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001017 Node* value = MakeNode(call_new_op, static_cast<int>(arity), all, false);
1018 return value;
1019}
1020
Ben Murdochda12d292016-06-02 14:46:10 +01001021void BytecodeGraphBuilder::VisitNew() {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001022 FrameStateBeforeAndAfter states(this);
1023 interpreter::Register callee_reg = bytecode_iterator().GetRegisterOperand(0);
1024 interpreter::Register first_arg = bytecode_iterator().GetRegisterOperand(1);
1025 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001026
Ben Murdoch097c5b22016-05-18 11:27:45 +01001027 Node* new_target = environment()->LookupAccumulator();
1028 Node* callee = environment()->LookupRegister(callee_reg);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001029 // TODO(turbofan): Pass the feedback here.
1030 const Operator* call = javascript()->CallConstruct(
1031 static_cast<int>(arg_count) + 2, VectorSlotPair());
Ben Murdoch097c5b22016-05-18 11:27:45 +01001032 Node* value = ProcessCallNewArguments(call, callee, new_target, first_arg,
1033 arg_count + 2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001034 environment()->BindAccumulator(value, &states);
1035}
1036
Ben Murdoch097c5b22016-05-18 11:27:45 +01001037void BytecodeGraphBuilder::BuildThrow() {
1038 FrameStateBeforeAndAfter states(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001039 Node* value = environment()->LookupAccumulator();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001040 Node* call = NewNode(javascript()->CallRuntime(Runtime::kThrow), value);
1041 environment()->BindAccumulator(call, &states);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001042}
1043
Ben Murdoch097c5b22016-05-18 11:27:45 +01001044void BytecodeGraphBuilder::VisitThrow() {
1045 BuildThrow();
1046 Node* call = environment()->LookupAccumulator();
1047 Node* control = NewNode(common()->Throw(), call);
1048 MergeControlToLeaveFunction(control);
1049}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001050
Ben Murdoch097c5b22016-05-18 11:27:45 +01001051void BytecodeGraphBuilder::VisitReThrow() {
1052 Node* value = environment()->LookupAccumulator();
1053 Node* call = NewNode(javascript()->CallRuntime(Runtime::kReThrow), value);
1054 Node* control = NewNode(common()->Throw(), call);
1055 MergeControlToLeaveFunction(control);
1056}
1057
1058void BytecodeGraphBuilder::BuildBinaryOp(const Operator* js_op) {
1059 FrameStateBeforeAndAfter states(this);
1060 Node* left =
1061 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001062 Node* right = environment()->LookupAccumulator();
1063 Node* node = NewNode(js_op, left, right);
1064 environment()->BindAccumulator(node, &states);
1065}
1066
Ben Murdoch097c5b22016-05-18 11:27:45 +01001067void BytecodeGraphBuilder::VisitAdd() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001068 BinaryOperationHints hints = BinaryOperationHints::Any();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001069 BuildBinaryOp(javascript()->Add(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001070}
1071
Ben Murdoch097c5b22016-05-18 11:27:45 +01001072void BytecodeGraphBuilder::VisitSub() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001073 BinaryOperationHints hints = BinaryOperationHints::Any();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001074 BuildBinaryOp(javascript()->Subtract(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001075}
1076
Ben Murdoch097c5b22016-05-18 11:27:45 +01001077void BytecodeGraphBuilder::VisitMul() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001078 BinaryOperationHints hints = BinaryOperationHints::Any();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001079 BuildBinaryOp(javascript()->Multiply(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001080}
1081
Ben Murdoch097c5b22016-05-18 11:27:45 +01001082void BytecodeGraphBuilder::VisitDiv() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001083 BinaryOperationHints hints = BinaryOperationHints::Any();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001084 BuildBinaryOp(javascript()->Divide(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001085}
1086
Ben Murdoch097c5b22016-05-18 11:27:45 +01001087void BytecodeGraphBuilder::VisitMod() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001088 BinaryOperationHints hints = BinaryOperationHints::Any();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001089 BuildBinaryOp(javascript()->Modulus(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001090}
1091
Ben Murdoch097c5b22016-05-18 11:27:45 +01001092void BytecodeGraphBuilder::VisitBitwiseOr() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001093 BinaryOperationHints hints = BinaryOperationHints::Any();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001094 BuildBinaryOp(javascript()->BitwiseOr(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001095}
1096
Ben Murdoch097c5b22016-05-18 11:27:45 +01001097void BytecodeGraphBuilder::VisitBitwiseXor() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001098 BinaryOperationHints hints = BinaryOperationHints::Any();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001099 BuildBinaryOp(javascript()->BitwiseXor(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001100}
1101
Ben Murdoch097c5b22016-05-18 11:27:45 +01001102void BytecodeGraphBuilder::VisitBitwiseAnd() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001103 BinaryOperationHints hints = BinaryOperationHints::Any();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001104 BuildBinaryOp(javascript()->BitwiseAnd(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001105}
1106
Ben Murdoch097c5b22016-05-18 11:27:45 +01001107void BytecodeGraphBuilder::VisitShiftLeft() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001108 BinaryOperationHints hints = BinaryOperationHints::Any();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001109 BuildBinaryOp(javascript()->ShiftLeft(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001110}
1111
Ben Murdoch097c5b22016-05-18 11:27:45 +01001112void BytecodeGraphBuilder::VisitShiftRight() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001113 BinaryOperationHints hints = BinaryOperationHints::Any();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001114 BuildBinaryOp(javascript()->ShiftRight(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001115}
1116
Ben Murdoch097c5b22016-05-18 11:27:45 +01001117void BytecodeGraphBuilder::VisitShiftRightLogical() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001118 BinaryOperationHints hints = BinaryOperationHints::Any();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001119 BuildBinaryOp(javascript()->ShiftRightLogical(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001120}
1121
Ben Murdoch097c5b22016-05-18 11:27:45 +01001122void BytecodeGraphBuilder::VisitInc() {
1123 FrameStateBeforeAndAfter states(this);
1124 const Operator* js_op = javascript()->Add(BinaryOperationHints::Any());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001125 Node* node = NewNode(js_op, environment()->LookupAccumulator(),
1126 jsgraph()->OneConstant());
1127 environment()->BindAccumulator(node, &states);
1128}
1129
Ben Murdoch097c5b22016-05-18 11:27:45 +01001130void BytecodeGraphBuilder::VisitDec() {
1131 FrameStateBeforeAndAfter states(this);
1132 const Operator* js_op = javascript()->Subtract(BinaryOperationHints::Any());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001133 Node* node = NewNode(js_op, environment()->LookupAccumulator(),
1134 jsgraph()->OneConstant());
1135 environment()->BindAccumulator(node, &states);
1136}
1137
Ben Murdoch097c5b22016-05-18 11:27:45 +01001138void BytecodeGraphBuilder::VisitLogicalNot() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001139 Node* value = NewNode(javascript()->ToBoolean(ToBooleanHint::kAny),
1140 environment()->LookupAccumulator());
1141 Node* node = NewNode(common()->Select(MachineRepresentation::kTagged), value,
1142 jsgraph()->FalseConstant(), jsgraph()->TrueConstant());
1143 environment()->BindAccumulator(node);
1144}
1145
Ben Murdoch097c5b22016-05-18 11:27:45 +01001146void BytecodeGraphBuilder::VisitTypeOf() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001147 Node* node =
1148 NewNode(javascript()->TypeOf(), environment()->LookupAccumulator());
1149 environment()->BindAccumulator(node);
1150}
1151
Ben Murdoch097c5b22016-05-18 11:27:45 +01001152void BytecodeGraphBuilder::BuildDelete(LanguageMode language_mode) {
1153 FrameStateBeforeAndAfter states(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001154 Node* key = environment()->LookupAccumulator();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001155 Node* object =
1156 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001157 Node* node =
Ben Murdoch097c5b22016-05-18 11:27:45 +01001158 NewNode(javascript()->DeleteProperty(language_mode), object, key);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001159 environment()->BindAccumulator(node, &states);
1160}
1161
Ben Murdoch097c5b22016-05-18 11:27:45 +01001162void BytecodeGraphBuilder::VisitDeletePropertyStrict() {
1163 BuildDelete(LanguageMode::STRICT);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001164}
1165
Ben Murdoch097c5b22016-05-18 11:27:45 +01001166void BytecodeGraphBuilder::VisitDeletePropertySloppy() {
1167 BuildDelete(LanguageMode::SLOPPY);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001168}
1169
Ben Murdoch097c5b22016-05-18 11:27:45 +01001170void BytecodeGraphBuilder::BuildCompareOp(const Operator* js_op) {
1171 FrameStateBeforeAndAfter states(this);
1172 Node* left =
1173 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001174 Node* right = environment()->LookupAccumulator();
1175 Node* node = NewNode(js_op, left, right);
1176 environment()->BindAccumulator(node, &states);
1177}
1178
Ben Murdoch097c5b22016-05-18 11:27:45 +01001179void BytecodeGraphBuilder::VisitTestEqual() {
1180 BuildCompareOp(javascript()->Equal());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001181}
1182
Ben Murdoch097c5b22016-05-18 11:27:45 +01001183void BytecodeGraphBuilder::VisitTestNotEqual() {
1184 BuildCompareOp(javascript()->NotEqual());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001185}
1186
Ben Murdoch097c5b22016-05-18 11:27:45 +01001187void BytecodeGraphBuilder::VisitTestEqualStrict() {
1188 BuildCompareOp(javascript()->StrictEqual());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001189}
1190
Ben Murdoch097c5b22016-05-18 11:27:45 +01001191void BytecodeGraphBuilder::VisitTestLessThan() {
1192 BuildCompareOp(javascript()->LessThan());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001193}
1194
Ben Murdoch097c5b22016-05-18 11:27:45 +01001195void BytecodeGraphBuilder::VisitTestGreaterThan() {
1196 BuildCompareOp(javascript()->GreaterThan());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001197}
1198
Ben Murdoch097c5b22016-05-18 11:27:45 +01001199void BytecodeGraphBuilder::VisitTestLessThanOrEqual() {
1200 BuildCompareOp(javascript()->LessThanOrEqual());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001201}
1202
Ben Murdoch097c5b22016-05-18 11:27:45 +01001203void BytecodeGraphBuilder::VisitTestGreaterThanOrEqual() {
1204 BuildCompareOp(javascript()->GreaterThanOrEqual());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001205}
1206
Ben Murdoch097c5b22016-05-18 11:27:45 +01001207void BytecodeGraphBuilder::VisitTestIn() {
1208 BuildCompareOp(javascript()->HasProperty());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001209}
1210
Ben Murdoch097c5b22016-05-18 11:27:45 +01001211void BytecodeGraphBuilder::VisitTestInstanceOf() {
Ben Murdochda12d292016-06-02 14:46:10 +01001212 DCHECK(!FLAG_harmony_instanceof);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001213 BuildCompareOp(javascript()->InstanceOf());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001214}
1215
Ben Murdoch097c5b22016-05-18 11:27:45 +01001216void BytecodeGraphBuilder::BuildCastOperator(const Operator* js_op) {
1217 FrameStateBeforeAndAfter states(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001218 Node* node = NewNode(js_op, environment()->LookupAccumulator());
1219 environment()->BindAccumulator(node, &states);
1220}
1221
Ben Murdoch097c5b22016-05-18 11:27:45 +01001222void BytecodeGraphBuilder::VisitToName() {
1223 BuildCastOperator(javascript()->ToName());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001224}
1225
Ben Murdoch097c5b22016-05-18 11:27:45 +01001226void BytecodeGraphBuilder::VisitToObject() {
1227 BuildCastOperator(javascript()->ToObject());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001228}
1229
Ben Murdoch097c5b22016-05-18 11:27:45 +01001230void BytecodeGraphBuilder::VisitToNumber() {
1231 BuildCastOperator(javascript()->ToNumber());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001232}
1233
Ben Murdoch097c5b22016-05-18 11:27:45 +01001234void BytecodeGraphBuilder::VisitJump() { BuildJump(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001235
Ben Murdoch097c5b22016-05-18 11:27:45 +01001236void BytecodeGraphBuilder::VisitJumpConstant() { BuildJump(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001237
1238
Ben Murdoch097c5b22016-05-18 11:27:45 +01001239void BytecodeGraphBuilder::VisitJumpIfTrue() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001240 BuildJumpIfEqual(jsgraph()->TrueConstant());
1241}
1242
Ben Murdoch097c5b22016-05-18 11:27:45 +01001243void BytecodeGraphBuilder::VisitJumpIfTrueConstant() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001244 BuildJumpIfEqual(jsgraph()->TrueConstant());
1245}
1246
Ben Murdoch097c5b22016-05-18 11:27:45 +01001247void BytecodeGraphBuilder::VisitJumpIfFalse() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001248 BuildJumpIfEqual(jsgraph()->FalseConstant());
1249}
1250
Ben Murdoch097c5b22016-05-18 11:27:45 +01001251void BytecodeGraphBuilder::VisitJumpIfFalseConstant() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001252 BuildJumpIfEqual(jsgraph()->FalseConstant());
1253}
1254
Ben Murdoch097c5b22016-05-18 11:27:45 +01001255void BytecodeGraphBuilder::VisitJumpIfToBooleanTrue() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001256 BuildJumpIfToBooleanEqual(jsgraph()->TrueConstant());
1257}
1258
Ben Murdoch097c5b22016-05-18 11:27:45 +01001259void BytecodeGraphBuilder::VisitJumpIfToBooleanTrueConstant() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001260 BuildJumpIfToBooleanEqual(jsgraph()->TrueConstant());
1261}
1262
Ben Murdoch097c5b22016-05-18 11:27:45 +01001263void BytecodeGraphBuilder::VisitJumpIfToBooleanFalse() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001264 BuildJumpIfToBooleanEqual(jsgraph()->FalseConstant());
1265}
1266
Ben Murdoch097c5b22016-05-18 11:27:45 +01001267void BytecodeGraphBuilder::VisitJumpIfToBooleanFalseConstant() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001268 BuildJumpIfToBooleanEqual(jsgraph()->FalseConstant());
1269}
1270
Ben Murdoch097c5b22016-05-18 11:27:45 +01001271void BytecodeGraphBuilder::VisitJumpIfNotHole() { BuildJumpIfNotHole(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001272
Ben Murdoch097c5b22016-05-18 11:27:45 +01001273void BytecodeGraphBuilder::VisitJumpIfNotHoleConstant() {
1274 BuildJumpIfNotHole();
1275}
1276
Ben Murdoch097c5b22016-05-18 11:27:45 +01001277void BytecodeGraphBuilder::VisitJumpIfNull() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001278 BuildJumpIfEqual(jsgraph()->NullConstant());
1279}
1280
Ben Murdoch097c5b22016-05-18 11:27:45 +01001281void BytecodeGraphBuilder::VisitJumpIfNullConstant() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001282 BuildJumpIfEqual(jsgraph()->NullConstant());
1283}
1284
Ben Murdoch097c5b22016-05-18 11:27:45 +01001285void BytecodeGraphBuilder::VisitJumpIfUndefined() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001286 BuildJumpIfEqual(jsgraph()->UndefinedConstant());
1287}
1288
Ben Murdoch097c5b22016-05-18 11:27:45 +01001289void BytecodeGraphBuilder::VisitJumpIfUndefinedConstant() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001290 BuildJumpIfEqual(jsgraph()->UndefinedConstant());
1291}
1292
Ben Murdoch097c5b22016-05-18 11:27:45 +01001293void BytecodeGraphBuilder::VisitStackCheck() {
1294 FrameStateBeforeAndAfter states(this);
1295 Node* node = NewNode(javascript()->StackCheck());
1296 environment()->RecordAfterState(node, &states);
1297}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001298
Ben Murdoch097c5b22016-05-18 11:27:45 +01001299void BytecodeGraphBuilder::VisitReturn() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001300 Node* control =
1301 NewNode(common()->Return(), environment()->LookupAccumulator());
Ben Murdoch097c5b22016-05-18 11:27:45 +01001302 MergeControlToLeaveFunction(control);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001303}
1304
Ben Murdoch097c5b22016-05-18 11:27:45 +01001305void BytecodeGraphBuilder::VisitDebugger() {
1306 FrameStateBeforeAndAfter states(this);
1307 Node* call =
1308 NewNode(javascript()->CallRuntime(Runtime::kHandleDebuggerStatement));
1309 environment()->BindAccumulator(call, &states);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001310}
1311
Ben Murdoch097c5b22016-05-18 11:27:45 +01001312// We cannot create a graph from the debugger copy of the bytecode array.
1313#define DEBUG_BREAK(Name, ...) \
1314 void BytecodeGraphBuilder::Visit##Name() { UNREACHABLE(); }
1315DEBUG_BREAK_BYTECODE_LIST(DEBUG_BREAK);
1316#undef DEBUG_BREAK
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001317
Ben Murdoch097c5b22016-05-18 11:27:45 +01001318void BytecodeGraphBuilder::BuildForInPrepare() {
1319 FrameStateBeforeAndAfter states(this);
1320 Node* receiver = environment()->LookupAccumulator();
1321 Node* prepare = NewNode(javascript()->ForInPrepare(), receiver);
1322 environment()->BindRegistersToProjections(
1323 bytecode_iterator().GetRegisterOperand(0), prepare, &states);
1324}
1325
1326void BytecodeGraphBuilder::VisitForInPrepare() { BuildForInPrepare(); }
1327
Ben Murdoch097c5b22016-05-18 11:27:45 +01001328void BytecodeGraphBuilder::VisitForInDone() {
1329 FrameStateBeforeAndAfter states(this);
1330 Node* index =
1331 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001332 Node* cache_length =
Ben Murdoch097c5b22016-05-18 11:27:45 +01001333 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001334 Node* exit_cond = NewNode(javascript()->ForInDone(), index, cache_length);
1335 environment()->BindAccumulator(exit_cond, &states);
1336}
1337
Ben Murdoch097c5b22016-05-18 11:27:45 +01001338void BytecodeGraphBuilder::BuildForInNext() {
1339 FrameStateBeforeAndAfter states(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001340 Node* receiver =
Ben Murdoch097c5b22016-05-18 11:27:45 +01001341 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1342 Node* index =
1343 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
1344 int catch_reg_pair_index = bytecode_iterator().GetRegisterOperand(2).index();
1345 Node* cache_type = environment()->LookupRegister(
1346 interpreter::Register(catch_reg_pair_index));
1347 Node* cache_array = environment()->LookupRegister(
1348 interpreter::Register(catch_reg_pair_index + 1));
1349
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001350 Node* value = NewNode(javascript()->ForInNext(), receiver, cache_array,
1351 cache_type, index);
1352 environment()->BindAccumulator(value, &states);
1353}
1354
Ben Murdoch097c5b22016-05-18 11:27:45 +01001355void BytecodeGraphBuilder::VisitForInNext() { BuildForInNext(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001356
Ben Murdoch097c5b22016-05-18 11:27:45 +01001357void BytecodeGraphBuilder::VisitForInStep() {
1358 FrameStateBeforeAndAfter states(this);
1359 Node* index =
1360 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001361 index = NewNode(javascript()->ForInStep(), index);
1362 environment()->BindAccumulator(index, &states);
1363}
1364
Ben Murdochda12d292016-06-02 14:46:10 +01001365void BytecodeGraphBuilder::VisitWide() {
1366 // Consumed by the BytecodeArrayIterator.
1367 UNREACHABLE();
1368}
1369
1370void BytecodeGraphBuilder::VisitExtraWide() {
1371 // Consumed by the BytecodeArrayIterator.
1372 UNREACHABLE();
1373}
1374
1375void BytecodeGraphBuilder::VisitIllegal() {
1376 // Never present in valid bytecode.
1377 UNREACHABLE();
1378}
1379
Ben Murdoch097c5b22016-05-18 11:27:45 +01001380void BytecodeGraphBuilder::SwitchToMergeEnvironment(int current_offset) {
1381 if (merge_environments_[current_offset] != nullptr) {
1382 if (environment() != nullptr) {
1383 merge_environments_[current_offset]->Merge(environment());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001384 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01001385 set_environment(merge_environments_[current_offset]);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001386 }
1387}
1388
Ben Murdoch097c5b22016-05-18 11:27:45 +01001389void BytecodeGraphBuilder::BuildLoopHeaderEnvironment(int current_offset) {
1390 if (branch_analysis()->backward_branches_target(current_offset)) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001391 // Add loop header and store a copy so we can connect merged back
1392 // edge inputs to the loop header.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001393 merge_environments_[current_offset] = environment()->CopyForLoop();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001394 }
1395}
1396
Ben Murdoch097c5b22016-05-18 11:27:45 +01001397void BytecodeGraphBuilder::MergeIntoSuccessorEnvironment(int target_offset) {
1398 if (merge_environments_[target_offset] == nullptr) {
1399 // Append merge nodes to the environment. We may merge here with another
1400 // environment. So add a place holder for merge nodes. We may add redundant
1401 // but will be eliminated in a later pass.
1402 // TODO(mstarzinger): Be smarter about this!
1403 NewMerge();
1404 merge_environments_[target_offset] = environment();
1405 } else {
1406 merge_environments_[target_offset]->Merge(environment());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001407 }
1408 set_environment(nullptr);
1409}
1410
Ben Murdoch097c5b22016-05-18 11:27:45 +01001411void BytecodeGraphBuilder::MergeControlToLeaveFunction(Node* exit) {
1412 exit_controls_.push_back(exit);
1413 set_environment(nullptr);
1414}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001415
1416void BytecodeGraphBuilder::BuildJump() {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001417 MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001418}
1419
1420
1421void BytecodeGraphBuilder::BuildConditionalJump(Node* condition) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001422 NewBranch(condition);
1423 Environment* if_false_environment = environment()->CopyForConditional();
1424 NewIfTrue();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001425 MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001426 set_environment(if_false_environment);
1427 NewIfFalse();
1428}
1429
1430
1431void BytecodeGraphBuilder::BuildJumpIfEqual(Node* comperand) {
1432 Node* accumulator = environment()->LookupAccumulator();
1433 Node* condition =
1434 NewNode(javascript()->StrictEqual(), accumulator, comperand);
1435 BuildConditionalJump(condition);
1436}
1437
1438
1439void BytecodeGraphBuilder::BuildJumpIfToBooleanEqual(Node* comperand) {
1440 Node* accumulator = environment()->LookupAccumulator();
1441 Node* to_boolean =
1442 NewNode(javascript()->ToBoolean(ToBooleanHint::kAny), accumulator);
1443 Node* condition = NewNode(javascript()->StrictEqual(), to_boolean, comperand);
1444 BuildConditionalJump(condition);
1445}
1446
Ben Murdoch097c5b22016-05-18 11:27:45 +01001447void BytecodeGraphBuilder::BuildJumpIfNotHole() {
1448 Node* accumulator = environment()->LookupAccumulator();
1449 Node* condition = NewNode(javascript()->StrictEqual(), accumulator,
1450 jsgraph()->TheHoleConstant());
1451 Node* node =
1452 NewNode(common()->Select(MachineRepresentation::kTagged), condition,
1453 jsgraph()->FalseConstant(), jsgraph()->TrueConstant());
1454 BuildConditionalJump(node);
1455}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001456
1457Node** BytecodeGraphBuilder::EnsureInputBufferSize(int size) {
1458 if (size > input_buffer_size_) {
1459 size = size + kInputBufferSizeIncrement + input_buffer_size_;
1460 input_buffer_ = local_zone()->NewArray<Node*>(size);
1461 input_buffer_size_ = size;
1462 }
1463 return input_buffer_;
1464}
1465
Ben Murdoch097c5b22016-05-18 11:27:45 +01001466void BytecodeGraphBuilder::EnterAndExitExceptionHandlers(int current_offset) {
1467 Handle<HandlerTable> table = exception_handler_table();
1468 int num_entries = table->NumberOfRangeEntries();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001469
Ben Murdoch097c5b22016-05-18 11:27:45 +01001470 // Potentially exit exception handlers.
1471 while (!exception_handlers_.empty()) {
1472 int current_end = exception_handlers_.top().end_offset_;
1473 if (current_offset < current_end) break; // Still covered by range.
1474 exception_handlers_.pop();
1475 }
1476
1477 // Potentially enter exception handlers.
1478 while (current_exception_handler_ < num_entries) {
1479 int next_start = table->GetRangeStart(current_exception_handler_);
1480 if (current_offset < next_start) break; // Not yet covered by range.
1481 int next_end = table->GetRangeEnd(current_exception_handler_);
1482 int next_handler = table->GetRangeHandler(current_exception_handler_);
1483 int context_register = table->GetRangeData(current_exception_handler_);
1484 CatchPrediction pred =
1485 table->GetRangePrediction(current_exception_handler_);
1486 exception_handlers_.push(
1487 {next_start, next_end, next_handler, context_register, pred});
1488 current_exception_handler_++;
1489 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001490}
1491
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001492Node* BytecodeGraphBuilder::MakeNode(const Operator* op, int value_input_count,
1493 Node** value_inputs, bool incomplete) {
1494 DCHECK_EQ(op->ValueInputCount(), value_input_count);
1495
1496 bool has_context = OperatorProperties::HasContextInput(op);
1497 int frame_state_count = OperatorProperties::GetFrameStateInputCount(op);
1498 bool has_control = op->ControlInputCount() == 1;
1499 bool has_effect = op->EffectInputCount() == 1;
1500
1501 DCHECK_LT(op->ControlInputCount(), 2);
1502 DCHECK_LT(op->EffectInputCount(), 2);
1503
1504 Node* result = nullptr;
1505 if (!has_context && frame_state_count == 0 && !has_control && !has_effect) {
1506 result = graph()->NewNode(op, value_input_count, value_inputs, incomplete);
1507 } else {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001508 bool inside_handler = !exception_handlers_.empty();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001509 int input_count_with_deps = value_input_count;
1510 if (has_context) ++input_count_with_deps;
1511 input_count_with_deps += frame_state_count;
1512 if (has_control) ++input_count_with_deps;
1513 if (has_effect) ++input_count_with_deps;
1514 Node** buffer = EnsureInputBufferSize(input_count_with_deps);
1515 memcpy(buffer, value_inputs, kPointerSize * value_input_count);
1516 Node** current_input = buffer + value_input_count;
1517 if (has_context) {
1518 *current_input++ = environment()->Context();
1519 }
1520 for (int i = 0; i < frame_state_count; i++) {
1521 // The frame state will be inserted later. Here we misuse
1522 // the {Dead} node as a sentinel to be later overwritten
1523 // with the real frame state.
1524 *current_input++ = jsgraph()->Dead();
1525 }
1526 if (has_effect) {
1527 *current_input++ = environment()->GetEffectDependency();
1528 }
1529 if (has_control) {
1530 *current_input++ = environment()->GetControlDependency();
1531 }
1532 result = graph()->NewNode(op, input_count_with_deps, buffer, incomplete);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001533 // Update the current control dependency for control-producing nodes.
1534 if (NodeProperties::IsControl(result)) {
1535 environment()->UpdateControlDependency(result);
1536 }
1537 // Update the current effect dependency for effect-producing nodes.
1538 if (result->op()->EffectOutputCount() > 0) {
1539 environment()->UpdateEffectDependency(result);
1540 }
1541 // Add implicit exception continuation for throwing nodes.
1542 if (!result->op()->HasProperty(Operator::kNoThrow) && inside_handler) {
1543 int handler_offset = exception_handlers_.top().handler_offset_;
1544 int context_index = exception_handlers_.top().context_register_;
1545 CatchPrediction prediction = exception_handlers_.top().pred_;
1546 interpreter::Register context_register(context_index);
1547 IfExceptionHint hint = prediction == CatchPrediction::CAUGHT
1548 ? IfExceptionHint::kLocallyCaught
1549 : IfExceptionHint::kLocallyUncaught;
1550 Environment* success_env = environment()->CopyForConditional();
1551 const Operator* op = common()->IfException(hint);
1552 Node* effect = environment()->GetEffectDependency();
1553 Node* on_exception = graph()->NewNode(op, effect, result);
1554 Node* context = environment()->LookupRegister(context_register);
1555 environment()->UpdateControlDependency(on_exception);
1556 environment()->UpdateEffectDependency(on_exception);
1557 environment()->BindAccumulator(on_exception);
1558 environment()->SetContext(context);
1559 MergeIntoSuccessorEnvironment(handler_offset);
1560 set_environment(success_env);
1561 }
1562 // Add implicit success continuation for throwing nodes.
1563 if (!result->op()->HasProperty(Operator::kNoThrow)) {
1564 const Operator* if_success = common()->IfSuccess();
1565 Node* on_success = graph()->NewNode(if_success, result);
1566 environment()->UpdateControlDependency(on_success);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001567 }
1568 }
1569
1570 return result;
1571}
1572
1573
1574Node* BytecodeGraphBuilder::NewPhi(int count, Node* input, Node* control) {
1575 const Operator* phi_op = common()->Phi(MachineRepresentation::kTagged, count);
1576 Node** buffer = EnsureInputBufferSize(count + 1);
1577 MemsetPointer(buffer, input, count);
1578 buffer[count] = control;
1579 return graph()->NewNode(phi_op, count + 1, buffer, true);
1580}
1581
1582
1583Node* BytecodeGraphBuilder::NewEffectPhi(int count, Node* input,
1584 Node* control) {
1585 const Operator* phi_op = common()->EffectPhi(count);
1586 Node** buffer = EnsureInputBufferSize(count + 1);
1587 MemsetPointer(buffer, input, count);
1588 buffer[count] = control;
1589 return graph()->NewNode(phi_op, count + 1, buffer, true);
1590}
1591
1592
1593Node* BytecodeGraphBuilder::MergeControl(Node* control, Node* other) {
1594 int inputs = control->op()->ControlInputCount() + 1;
1595 if (control->opcode() == IrOpcode::kLoop) {
1596 // Control node for loop exists, add input.
1597 const Operator* op = common()->Loop(inputs);
1598 control->AppendInput(graph_zone(), other);
1599 NodeProperties::ChangeOp(control, op);
1600 } else if (control->opcode() == IrOpcode::kMerge) {
1601 // Control node for merge exists, add input.
1602 const Operator* op = common()->Merge(inputs);
1603 control->AppendInput(graph_zone(), other);
1604 NodeProperties::ChangeOp(control, op);
1605 } else {
1606 // Control node is a singleton, introduce a merge.
1607 const Operator* op = common()->Merge(inputs);
1608 Node* merge_inputs[] = {control, other};
1609 control = graph()->NewNode(op, arraysize(merge_inputs), merge_inputs, true);
1610 }
1611 return control;
1612}
1613
1614
1615Node* BytecodeGraphBuilder::MergeEffect(Node* value, Node* other,
1616 Node* control) {
1617 int inputs = control->op()->ControlInputCount();
1618 if (value->opcode() == IrOpcode::kEffectPhi &&
1619 NodeProperties::GetControlInput(value) == control) {
1620 // Phi already exists, add input.
1621 value->InsertInput(graph_zone(), inputs - 1, other);
1622 NodeProperties::ChangeOp(value, common()->EffectPhi(inputs));
1623 } else if (value != other) {
1624 // Phi does not exist yet, introduce one.
1625 value = NewEffectPhi(inputs, value, control);
1626 value->ReplaceInput(inputs - 1, other);
1627 }
1628 return value;
1629}
1630
1631
1632Node* BytecodeGraphBuilder::MergeValue(Node* value, Node* other,
1633 Node* control) {
1634 int inputs = control->op()->ControlInputCount();
1635 if (value->opcode() == IrOpcode::kPhi &&
1636 NodeProperties::GetControlInput(value) == control) {
1637 // Phi already exists, add input.
1638 value->InsertInput(graph_zone(), inputs - 1, other);
1639 NodeProperties::ChangeOp(
1640 value, common()->Phi(MachineRepresentation::kTagged, inputs));
1641 } else if (value != other) {
1642 // Phi does not exist yet, introduce one.
1643 value = NewPhi(inputs, value, control);
1644 value->ReplaceInput(inputs - 1, other);
1645 }
1646 return value;
1647}
1648
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001649} // namespace compiler
1650} // namespace internal
1651} // namespace v8