blob: 22299de3b83af5ff0c7f77efe729b39f36ab0dda [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);
Ben Murdochc5610432016-08-08 18:44:38 +0100885 int bytecode_flags = bytecode_iterator().GetFlagOperand(2);
886 int literal_flags =
887 interpreter::CreateObjectLiteralFlags::FlagsBits::decode(bytecode_flags);
Ben Murdochda12d292016-06-02 14:46:10 +0100888 // TODO(mstarzinger): Thread through number of properties.
889 int number_of_properties = constant_properties->length() / 2;
890 const Operator* op = javascript()->CreateLiteralObject(
891 constant_properties, literal_flags, literal_index, number_of_properties);
892 BuildCreateLiteral(op);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000893}
894
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000895Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op,
896 Node* callee,
897 interpreter::Register receiver,
898 size_t arity) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100899 Node** all = local_zone()->NewArray<Node*>(static_cast<int>(arity));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000900 all[0] = callee;
901 all[1] = environment()->LookupRegister(receiver);
902 int receiver_index = receiver.index();
903 for (int i = 2; i < static_cast<int>(arity); ++i) {
904 all[i] = environment()->LookupRegister(
905 interpreter::Register(receiver_index + i - 1));
906 }
907 Node* value = MakeNode(call_op, static_cast<int>(arity), all, false);
908 return value;
909}
910
Ben Murdoch097c5b22016-05-18 11:27:45 +0100911void BytecodeGraphBuilder::BuildCall(TailCallMode tail_call_mode) {
912 FrameStateBeforeAndAfter states(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000913 // TODO(rmcilroy): Set receiver_hint correctly based on whether the receiver
914 // register has been loaded with null / undefined explicitly or we are sure it
915 // is not null / undefined.
916 ConvertReceiverMode receiver_hint = ConvertReceiverMode::kAny;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100917 Node* callee =
918 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
919 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
920 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
921 VectorSlotPair feedback =
922 CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(3));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000923
924 const Operator* call = javascript()->CallFunction(
Ben Murdoch097c5b22016-05-18 11:27:45 +0100925 arg_count + 1, feedback, receiver_hint, tail_call_mode);
926 Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000927 environment()->BindAccumulator(value, &states);
928}
929
Ben Murdoch097c5b22016-05-18 11:27:45 +0100930void BytecodeGraphBuilder::VisitCall() { BuildCall(TailCallMode::kDisallow); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000931
Ben Murdochda12d292016-06-02 14:46:10 +0100932void BytecodeGraphBuilder::VisitTailCall() {
933 TailCallMode tail_call_mode =
934 bytecode_array_->GetIsolate()->is_tail_call_elimination_enabled()
935 ? TailCallMode::kAllow
936 : TailCallMode::kDisallow;
937 BuildCall(tail_call_mode);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000938}
939
Ben Murdochda12d292016-06-02 14:46:10 +0100940void BytecodeGraphBuilder::VisitCallJSRuntime() {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100941 FrameStateBeforeAndAfter states(this);
942 Node* callee =
943 BuildLoadNativeContextField(bytecode_iterator().GetIndexOperand(0));
944 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
945 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000946
947 // Create node to perform the JS runtime call.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100948 const Operator* call = javascript()->CallFunction(arg_count + 1);
949 Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000950 environment()->BindAccumulator(value, &states);
951}
952
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000953Node* BytecodeGraphBuilder::ProcessCallRuntimeArguments(
954 const Operator* call_runtime_op, interpreter::Register first_arg,
955 size_t arity) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100956 Node** all = local_zone()->NewArray<Node*>(arity);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000957 int first_arg_index = first_arg.index();
958 for (int i = 0; i < static_cast<int>(arity); ++i) {
959 all[i] = environment()->LookupRegister(
960 interpreter::Register(first_arg_index + i));
961 }
962 Node* value = MakeNode(call_runtime_op, static_cast<int>(arity), all, false);
963 return value;
964}
965
Ben Murdochda12d292016-06-02 14:46:10 +0100966void BytecodeGraphBuilder::VisitCallRuntime() {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100967 FrameStateBeforeAndAfter states(this);
Ben Murdochda12d292016-06-02 14:46:10 +0100968 Runtime::FunctionId functionId = static_cast<Runtime::FunctionId>(
969 bytecode_iterator().GetRuntimeIdOperand(0));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100970 interpreter::Register first_arg = bytecode_iterator().GetRegisterOperand(1);
971 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000972
973 // Create node to perform the runtime call.
974 const Operator* call = javascript()->CallRuntime(functionId, arg_count);
975 Node* value = ProcessCallRuntimeArguments(call, first_arg, arg_count);
976 environment()->BindAccumulator(value, &states);
977}
978
Ben Murdochda12d292016-06-02 14:46:10 +0100979void BytecodeGraphBuilder::VisitCallRuntimeForPair() {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100980 FrameStateBeforeAndAfter states(this);
Ben Murdochda12d292016-06-02 14:46:10 +0100981 Runtime::FunctionId functionId = static_cast<Runtime::FunctionId>(
982 bytecode_iterator().GetRuntimeIdOperand(0));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100983 interpreter::Register first_arg = bytecode_iterator().GetRegisterOperand(1);
984 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
985 interpreter::Register first_return =
986 bytecode_iterator().GetRegisterOperand(3);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000987
988 // Create node to perform the runtime call.
989 const Operator* call = javascript()->CallRuntime(functionId, arg_count);
990 Node* return_pair = ProcessCallRuntimeArguments(call, first_arg, arg_count);
991 environment()->BindRegistersToProjections(first_return, return_pair, &states);
992}
993
Ben Murdochda12d292016-06-02 14:46:10 +0100994void BytecodeGraphBuilder::VisitInvokeIntrinsic() {
995 FrameStateBeforeAndAfter states(this);
996 Runtime::FunctionId functionId = static_cast<Runtime::FunctionId>(
997 bytecode_iterator().GetRuntimeIdOperand(0));
998 interpreter::Register first_arg = bytecode_iterator().GetRegisterOperand(1);
999 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001000
Ben Murdochda12d292016-06-02 14:46:10 +01001001 // Create node to perform the runtime call. Turbofan will take care of the
1002 // lowering.
1003 const Operator* call = javascript()->CallRuntime(functionId, arg_count);
1004 Node* value = ProcessCallRuntimeArguments(call, first_arg, arg_count);
1005 environment()->BindAccumulator(value, &states);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001006}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001007
1008Node* BytecodeGraphBuilder::ProcessCallNewArguments(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001009 const Operator* call_new_op, Node* callee, Node* new_target,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001010 interpreter::Register first_arg, size_t arity) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001011 Node** all = local_zone()->NewArray<Node*>(arity);
1012 all[0] = new_target;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001013 int first_arg_index = first_arg.index();
1014 for (int i = 1; i < static_cast<int>(arity) - 1; ++i) {
1015 all[i] = environment()->LookupRegister(
1016 interpreter::Register(first_arg_index + i - 1));
1017 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01001018 all[arity - 1] = callee;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001019 Node* value = MakeNode(call_new_op, static_cast<int>(arity), all, false);
1020 return value;
1021}
1022
Ben Murdochda12d292016-06-02 14:46:10 +01001023void BytecodeGraphBuilder::VisitNew() {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001024 FrameStateBeforeAndAfter states(this);
1025 interpreter::Register callee_reg = bytecode_iterator().GetRegisterOperand(0);
1026 interpreter::Register first_arg = bytecode_iterator().GetRegisterOperand(1);
1027 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001028
Ben Murdoch097c5b22016-05-18 11:27:45 +01001029 Node* new_target = environment()->LookupAccumulator();
1030 Node* callee = environment()->LookupRegister(callee_reg);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001031 // TODO(turbofan): Pass the feedback here.
1032 const Operator* call = javascript()->CallConstruct(
1033 static_cast<int>(arg_count) + 2, VectorSlotPair());
Ben Murdoch097c5b22016-05-18 11:27:45 +01001034 Node* value = ProcessCallNewArguments(call, callee, new_target, first_arg,
1035 arg_count + 2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001036 environment()->BindAccumulator(value, &states);
1037}
1038
Ben Murdoch097c5b22016-05-18 11:27:45 +01001039void BytecodeGraphBuilder::BuildThrow() {
1040 FrameStateBeforeAndAfter states(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001041 Node* value = environment()->LookupAccumulator();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001042 Node* call = NewNode(javascript()->CallRuntime(Runtime::kThrow), value);
1043 environment()->BindAccumulator(call, &states);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001044}
1045
Ben Murdoch097c5b22016-05-18 11:27:45 +01001046void BytecodeGraphBuilder::VisitThrow() {
1047 BuildThrow();
1048 Node* call = environment()->LookupAccumulator();
1049 Node* control = NewNode(common()->Throw(), call);
1050 MergeControlToLeaveFunction(control);
1051}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001052
Ben Murdoch097c5b22016-05-18 11:27:45 +01001053void BytecodeGraphBuilder::VisitReThrow() {
1054 Node* value = environment()->LookupAccumulator();
1055 Node* call = NewNode(javascript()->CallRuntime(Runtime::kReThrow), value);
1056 Node* control = NewNode(common()->Throw(), call);
1057 MergeControlToLeaveFunction(control);
1058}
1059
1060void BytecodeGraphBuilder::BuildBinaryOp(const Operator* js_op) {
1061 FrameStateBeforeAndAfter states(this);
1062 Node* left =
1063 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001064 Node* right = environment()->LookupAccumulator();
1065 Node* node = NewNode(js_op, left, right);
1066 environment()->BindAccumulator(node, &states);
1067}
1068
Ben Murdoch097c5b22016-05-18 11:27:45 +01001069void BytecodeGraphBuilder::VisitAdd() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001070 BinaryOperationHints hints = BinaryOperationHints::Any();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001071 BuildBinaryOp(javascript()->Add(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001072}
1073
Ben Murdoch097c5b22016-05-18 11:27:45 +01001074void BytecodeGraphBuilder::VisitSub() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001075 BinaryOperationHints hints = BinaryOperationHints::Any();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001076 BuildBinaryOp(javascript()->Subtract(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001077}
1078
Ben Murdoch097c5b22016-05-18 11:27:45 +01001079void BytecodeGraphBuilder::VisitMul() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001080 BinaryOperationHints hints = BinaryOperationHints::Any();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001081 BuildBinaryOp(javascript()->Multiply(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001082}
1083
Ben Murdoch097c5b22016-05-18 11:27:45 +01001084void BytecodeGraphBuilder::VisitDiv() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001085 BinaryOperationHints hints = BinaryOperationHints::Any();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001086 BuildBinaryOp(javascript()->Divide(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001087}
1088
Ben Murdoch097c5b22016-05-18 11:27:45 +01001089void BytecodeGraphBuilder::VisitMod() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001090 BinaryOperationHints hints = BinaryOperationHints::Any();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001091 BuildBinaryOp(javascript()->Modulus(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001092}
1093
Ben Murdoch097c5b22016-05-18 11:27:45 +01001094void BytecodeGraphBuilder::VisitBitwiseOr() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001095 BinaryOperationHints hints = BinaryOperationHints::Any();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001096 BuildBinaryOp(javascript()->BitwiseOr(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001097}
1098
Ben Murdoch097c5b22016-05-18 11:27:45 +01001099void BytecodeGraphBuilder::VisitBitwiseXor() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001100 BinaryOperationHints hints = BinaryOperationHints::Any();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001101 BuildBinaryOp(javascript()->BitwiseXor(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001102}
1103
Ben Murdoch097c5b22016-05-18 11:27:45 +01001104void BytecodeGraphBuilder::VisitBitwiseAnd() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001105 BinaryOperationHints hints = BinaryOperationHints::Any();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001106 BuildBinaryOp(javascript()->BitwiseAnd(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001107}
1108
Ben Murdoch097c5b22016-05-18 11:27:45 +01001109void BytecodeGraphBuilder::VisitShiftLeft() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001110 BinaryOperationHints hints = BinaryOperationHints::Any();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001111 BuildBinaryOp(javascript()->ShiftLeft(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001112}
1113
Ben Murdoch097c5b22016-05-18 11:27:45 +01001114void BytecodeGraphBuilder::VisitShiftRight() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001115 BinaryOperationHints hints = BinaryOperationHints::Any();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001116 BuildBinaryOp(javascript()->ShiftRight(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001117}
1118
Ben Murdoch097c5b22016-05-18 11:27:45 +01001119void BytecodeGraphBuilder::VisitShiftRightLogical() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001120 BinaryOperationHints hints = BinaryOperationHints::Any();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001121 BuildBinaryOp(javascript()->ShiftRightLogical(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001122}
1123
Ben Murdoch097c5b22016-05-18 11:27:45 +01001124void BytecodeGraphBuilder::VisitInc() {
1125 FrameStateBeforeAndAfter states(this);
Ben Murdochc5610432016-08-08 18:44:38 +01001126 // Note: Use subtract -1 here instead of add 1 to ensure we always convert to
1127 // a number, not a string.
1128 const Operator* js_op = javascript()->Subtract(BinaryOperationHints::Any());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001129 Node* node = NewNode(js_op, environment()->LookupAccumulator(),
Ben Murdochc5610432016-08-08 18:44:38 +01001130 jsgraph()->Constant(-1.0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001131 environment()->BindAccumulator(node, &states);
1132}
1133
Ben Murdoch097c5b22016-05-18 11:27:45 +01001134void BytecodeGraphBuilder::VisitDec() {
1135 FrameStateBeforeAndAfter states(this);
1136 const Operator* js_op = javascript()->Subtract(BinaryOperationHints::Any());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001137 Node* node = NewNode(js_op, environment()->LookupAccumulator(),
1138 jsgraph()->OneConstant());
1139 environment()->BindAccumulator(node, &states);
1140}
1141
Ben Murdoch097c5b22016-05-18 11:27:45 +01001142void BytecodeGraphBuilder::VisitLogicalNot() {
Ben Murdochc5610432016-08-08 18:44:38 +01001143 Node* value = environment()->LookupAccumulator();
1144 Node* node = NewNode(common()->Select(MachineRepresentation::kTagged), value,
1145 jsgraph()->FalseConstant(), jsgraph()->TrueConstant());
1146 environment()->BindAccumulator(node);
1147}
1148
1149void BytecodeGraphBuilder::VisitToBooleanLogicalNot() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001150 Node* value = NewNode(javascript()->ToBoolean(ToBooleanHint::kAny),
1151 environment()->LookupAccumulator());
1152 Node* node = NewNode(common()->Select(MachineRepresentation::kTagged), value,
1153 jsgraph()->FalseConstant(), jsgraph()->TrueConstant());
1154 environment()->BindAccumulator(node);
1155}
1156
Ben Murdoch097c5b22016-05-18 11:27:45 +01001157void BytecodeGraphBuilder::VisitTypeOf() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001158 Node* node =
1159 NewNode(javascript()->TypeOf(), environment()->LookupAccumulator());
1160 environment()->BindAccumulator(node);
1161}
1162
Ben Murdoch097c5b22016-05-18 11:27:45 +01001163void BytecodeGraphBuilder::BuildDelete(LanguageMode language_mode) {
1164 FrameStateBeforeAndAfter states(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001165 Node* key = environment()->LookupAccumulator();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001166 Node* object =
1167 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001168 Node* node =
Ben Murdoch097c5b22016-05-18 11:27:45 +01001169 NewNode(javascript()->DeleteProperty(language_mode), object, key);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001170 environment()->BindAccumulator(node, &states);
1171}
1172
Ben Murdoch097c5b22016-05-18 11:27:45 +01001173void BytecodeGraphBuilder::VisitDeletePropertyStrict() {
1174 BuildDelete(LanguageMode::STRICT);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001175}
1176
Ben Murdoch097c5b22016-05-18 11:27:45 +01001177void BytecodeGraphBuilder::VisitDeletePropertySloppy() {
1178 BuildDelete(LanguageMode::SLOPPY);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001179}
1180
Ben Murdoch097c5b22016-05-18 11:27:45 +01001181void BytecodeGraphBuilder::BuildCompareOp(const Operator* js_op) {
1182 FrameStateBeforeAndAfter states(this);
1183 Node* left =
1184 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001185 Node* right = environment()->LookupAccumulator();
1186 Node* node = NewNode(js_op, left, right);
1187 environment()->BindAccumulator(node, &states);
1188}
1189
Ben Murdoch097c5b22016-05-18 11:27:45 +01001190void BytecodeGraphBuilder::VisitTestEqual() {
1191 BuildCompareOp(javascript()->Equal());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001192}
1193
Ben Murdoch097c5b22016-05-18 11:27:45 +01001194void BytecodeGraphBuilder::VisitTestNotEqual() {
1195 BuildCompareOp(javascript()->NotEqual());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001196}
1197
Ben Murdoch097c5b22016-05-18 11:27:45 +01001198void BytecodeGraphBuilder::VisitTestEqualStrict() {
1199 BuildCompareOp(javascript()->StrictEqual());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001200}
1201
Ben Murdoch097c5b22016-05-18 11:27:45 +01001202void BytecodeGraphBuilder::VisitTestLessThan() {
1203 BuildCompareOp(javascript()->LessThan());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001204}
1205
Ben Murdoch097c5b22016-05-18 11:27:45 +01001206void BytecodeGraphBuilder::VisitTestGreaterThan() {
1207 BuildCompareOp(javascript()->GreaterThan());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001208}
1209
Ben Murdoch097c5b22016-05-18 11:27:45 +01001210void BytecodeGraphBuilder::VisitTestLessThanOrEqual() {
1211 BuildCompareOp(javascript()->LessThanOrEqual());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001212}
1213
Ben Murdoch097c5b22016-05-18 11:27:45 +01001214void BytecodeGraphBuilder::VisitTestGreaterThanOrEqual() {
1215 BuildCompareOp(javascript()->GreaterThanOrEqual());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001216}
1217
Ben Murdoch097c5b22016-05-18 11:27:45 +01001218void BytecodeGraphBuilder::VisitTestIn() {
1219 BuildCompareOp(javascript()->HasProperty());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001220}
1221
Ben Murdoch097c5b22016-05-18 11:27:45 +01001222void BytecodeGraphBuilder::VisitTestInstanceOf() {
1223 BuildCompareOp(javascript()->InstanceOf());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001224}
1225
Ben Murdoch097c5b22016-05-18 11:27:45 +01001226void BytecodeGraphBuilder::BuildCastOperator(const Operator* js_op) {
1227 FrameStateBeforeAndAfter states(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001228 Node* node = NewNode(js_op, environment()->LookupAccumulator());
1229 environment()->BindAccumulator(node, &states);
1230}
1231
Ben Murdoch097c5b22016-05-18 11:27:45 +01001232void BytecodeGraphBuilder::VisitToName() {
1233 BuildCastOperator(javascript()->ToName());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001234}
1235
Ben Murdoch097c5b22016-05-18 11:27:45 +01001236void BytecodeGraphBuilder::VisitToObject() {
1237 BuildCastOperator(javascript()->ToObject());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001238}
1239
Ben Murdoch097c5b22016-05-18 11:27:45 +01001240void BytecodeGraphBuilder::VisitToNumber() {
1241 BuildCastOperator(javascript()->ToNumber());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001242}
1243
Ben Murdoch097c5b22016-05-18 11:27:45 +01001244void BytecodeGraphBuilder::VisitJump() { BuildJump(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001245
Ben Murdoch097c5b22016-05-18 11:27:45 +01001246void BytecodeGraphBuilder::VisitJumpConstant() { BuildJump(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001247
1248
Ben Murdoch097c5b22016-05-18 11:27:45 +01001249void BytecodeGraphBuilder::VisitJumpIfTrue() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001250 BuildJumpIfEqual(jsgraph()->TrueConstant());
1251}
1252
Ben Murdoch097c5b22016-05-18 11:27:45 +01001253void BytecodeGraphBuilder::VisitJumpIfTrueConstant() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001254 BuildJumpIfEqual(jsgraph()->TrueConstant());
1255}
1256
Ben Murdoch097c5b22016-05-18 11:27:45 +01001257void BytecodeGraphBuilder::VisitJumpIfFalse() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001258 BuildJumpIfEqual(jsgraph()->FalseConstant());
1259}
1260
Ben Murdoch097c5b22016-05-18 11:27:45 +01001261void BytecodeGraphBuilder::VisitJumpIfFalseConstant() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001262 BuildJumpIfEqual(jsgraph()->FalseConstant());
1263}
1264
Ben Murdoch097c5b22016-05-18 11:27:45 +01001265void BytecodeGraphBuilder::VisitJumpIfToBooleanTrue() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001266 BuildJumpIfToBooleanEqual(jsgraph()->TrueConstant());
1267}
1268
Ben Murdoch097c5b22016-05-18 11:27:45 +01001269void BytecodeGraphBuilder::VisitJumpIfToBooleanTrueConstant() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001270 BuildJumpIfToBooleanEqual(jsgraph()->TrueConstant());
1271}
1272
Ben Murdoch097c5b22016-05-18 11:27:45 +01001273void BytecodeGraphBuilder::VisitJumpIfToBooleanFalse() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001274 BuildJumpIfToBooleanEqual(jsgraph()->FalseConstant());
1275}
1276
Ben Murdoch097c5b22016-05-18 11:27:45 +01001277void BytecodeGraphBuilder::VisitJumpIfToBooleanFalseConstant() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001278 BuildJumpIfToBooleanEqual(jsgraph()->FalseConstant());
1279}
1280
Ben Murdoch097c5b22016-05-18 11:27:45 +01001281void BytecodeGraphBuilder::VisitJumpIfNotHole() { BuildJumpIfNotHole(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001282
Ben Murdoch097c5b22016-05-18 11:27:45 +01001283void BytecodeGraphBuilder::VisitJumpIfNotHoleConstant() {
1284 BuildJumpIfNotHole();
1285}
1286
Ben Murdoch097c5b22016-05-18 11:27:45 +01001287void BytecodeGraphBuilder::VisitJumpIfNull() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001288 BuildJumpIfEqual(jsgraph()->NullConstant());
1289}
1290
Ben Murdoch097c5b22016-05-18 11:27:45 +01001291void BytecodeGraphBuilder::VisitJumpIfNullConstant() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001292 BuildJumpIfEqual(jsgraph()->NullConstant());
1293}
1294
Ben Murdoch097c5b22016-05-18 11:27:45 +01001295void BytecodeGraphBuilder::VisitJumpIfUndefined() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001296 BuildJumpIfEqual(jsgraph()->UndefinedConstant());
1297}
1298
Ben Murdoch097c5b22016-05-18 11:27:45 +01001299void BytecodeGraphBuilder::VisitJumpIfUndefinedConstant() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001300 BuildJumpIfEqual(jsgraph()->UndefinedConstant());
1301}
1302
Ben Murdoch097c5b22016-05-18 11:27:45 +01001303void BytecodeGraphBuilder::VisitStackCheck() {
1304 FrameStateBeforeAndAfter states(this);
1305 Node* node = NewNode(javascript()->StackCheck());
1306 environment()->RecordAfterState(node, &states);
1307}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001308
Ben Murdoch097c5b22016-05-18 11:27:45 +01001309void BytecodeGraphBuilder::VisitReturn() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001310 Node* control =
1311 NewNode(common()->Return(), environment()->LookupAccumulator());
Ben Murdoch097c5b22016-05-18 11:27:45 +01001312 MergeControlToLeaveFunction(control);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001313}
1314
Ben Murdoch097c5b22016-05-18 11:27:45 +01001315void BytecodeGraphBuilder::VisitDebugger() {
1316 FrameStateBeforeAndAfter states(this);
1317 Node* call =
1318 NewNode(javascript()->CallRuntime(Runtime::kHandleDebuggerStatement));
1319 environment()->BindAccumulator(call, &states);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001320}
1321
Ben Murdoch097c5b22016-05-18 11:27:45 +01001322// We cannot create a graph from the debugger copy of the bytecode array.
1323#define DEBUG_BREAK(Name, ...) \
1324 void BytecodeGraphBuilder::Visit##Name() { UNREACHABLE(); }
1325DEBUG_BREAK_BYTECODE_LIST(DEBUG_BREAK);
1326#undef DEBUG_BREAK
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001327
Ben Murdoch097c5b22016-05-18 11:27:45 +01001328void BytecodeGraphBuilder::BuildForInPrepare() {
1329 FrameStateBeforeAndAfter states(this);
1330 Node* receiver = environment()->LookupAccumulator();
1331 Node* prepare = NewNode(javascript()->ForInPrepare(), receiver);
1332 environment()->BindRegistersToProjections(
1333 bytecode_iterator().GetRegisterOperand(0), prepare, &states);
1334}
1335
1336void BytecodeGraphBuilder::VisitForInPrepare() { BuildForInPrepare(); }
1337
Ben Murdoch097c5b22016-05-18 11:27:45 +01001338void BytecodeGraphBuilder::VisitForInDone() {
1339 FrameStateBeforeAndAfter states(this);
1340 Node* index =
1341 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001342 Node* cache_length =
Ben Murdoch097c5b22016-05-18 11:27:45 +01001343 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001344 Node* exit_cond = NewNode(javascript()->ForInDone(), index, cache_length);
1345 environment()->BindAccumulator(exit_cond, &states);
1346}
1347
Ben Murdoch097c5b22016-05-18 11:27:45 +01001348void BytecodeGraphBuilder::BuildForInNext() {
1349 FrameStateBeforeAndAfter states(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001350 Node* receiver =
Ben Murdoch097c5b22016-05-18 11:27:45 +01001351 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1352 Node* index =
1353 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
1354 int catch_reg_pair_index = bytecode_iterator().GetRegisterOperand(2).index();
1355 Node* cache_type = environment()->LookupRegister(
1356 interpreter::Register(catch_reg_pair_index));
1357 Node* cache_array = environment()->LookupRegister(
1358 interpreter::Register(catch_reg_pair_index + 1));
1359
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001360 Node* value = NewNode(javascript()->ForInNext(), receiver, cache_array,
1361 cache_type, index);
1362 environment()->BindAccumulator(value, &states);
1363}
1364
Ben Murdoch097c5b22016-05-18 11:27:45 +01001365void BytecodeGraphBuilder::VisitForInNext() { BuildForInNext(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001366
Ben Murdoch097c5b22016-05-18 11:27:45 +01001367void BytecodeGraphBuilder::VisitForInStep() {
1368 FrameStateBeforeAndAfter states(this);
1369 Node* index =
1370 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001371 index = NewNode(javascript()->ForInStep(), index);
1372 environment()->BindAccumulator(index, &states);
1373}
1374
Ben Murdochc5610432016-08-08 18:44:38 +01001375void BytecodeGraphBuilder::VisitSuspendGenerator() {
1376 Node* state = environment()->LookupAccumulator();
1377 Node* generator = environment()->LookupRegister(
1378 bytecode_iterator().GetRegisterOperand(0));
1379
1380 for (int i = 0; i < environment()->register_count(); ++i) {
1381 Node* value = environment()->LookupRegister(interpreter::Register(i));
1382 NewNode(javascript()->CallRuntime(Runtime::kGeneratorStoreRegister),
1383 generator, jsgraph()->Constant(i), value);
1384 }
1385
1386 NewNode(javascript()->CallRuntime(Runtime::kGeneratorSetContext), generator);
1387 NewNode(javascript()->CallRuntime(Runtime::kGeneratorSetContinuation),
1388 generator, state);
1389}
1390
1391void BytecodeGraphBuilder::VisitResumeGenerator() {
1392 FrameStateBeforeAndAfter states(this);
1393
1394 Node* generator = environment()->LookupRegister(
1395 bytecode_iterator().GetRegisterOperand(0));
1396 Node* state = NewNode(javascript()->CallRuntime(
1397 Runtime::kGeneratorGetContinuation), generator);
1398
1399 // Bijection between registers and array indices must match that used in
1400 // InterpreterAssembler::ExportRegisterFile.
1401 for (int i = 0; i < environment()->register_count(); ++i) {
1402 Node* value = NewNode(
1403 javascript()->CallRuntime(Runtime::kGeneratorLoadRegister),
1404 generator, jsgraph()->Constant(i));
1405 environment()->BindRegister(interpreter::Register(i), value);
1406
1407 NewNode(javascript()->CallRuntime(Runtime::kGeneratorStoreRegister),
1408 generator, jsgraph()->Constant(i), jsgraph()->StaleRegisterConstant());
1409 }
1410
1411 NewNode(javascript()->CallRuntime(Runtime::kGeneratorSetContinuation),
1412 generator, jsgraph()->Constant(JSGeneratorObject::kGeneratorExecuting));
1413
1414 environment()->BindAccumulator(state, &states);
1415}
1416
Ben Murdochda12d292016-06-02 14:46:10 +01001417void BytecodeGraphBuilder::VisitWide() {
1418 // Consumed by the BytecodeArrayIterator.
1419 UNREACHABLE();
1420}
1421
1422void BytecodeGraphBuilder::VisitExtraWide() {
1423 // Consumed by the BytecodeArrayIterator.
1424 UNREACHABLE();
1425}
1426
1427void BytecodeGraphBuilder::VisitIllegal() {
Ben Murdochc5610432016-08-08 18:44:38 +01001428 // Not emitted in valid bytecode.
Ben Murdochda12d292016-06-02 14:46:10 +01001429 UNREACHABLE();
1430}
1431
Ben Murdochc5610432016-08-08 18:44:38 +01001432void BytecodeGraphBuilder::VisitNop() {}
1433
Ben Murdoch097c5b22016-05-18 11:27:45 +01001434void BytecodeGraphBuilder::SwitchToMergeEnvironment(int current_offset) {
1435 if (merge_environments_[current_offset] != nullptr) {
1436 if (environment() != nullptr) {
1437 merge_environments_[current_offset]->Merge(environment());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001438 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01001439 set_environment(merge_environments_[current_offset]);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001440 }
1441}
1442
Ben Murdoch097c5b22016-05-18 11:27:45 +01001443void BytecodeGraphBuilder::BuildLoopHeaderEnvironment(int current_offset) {
1444 if (branch_analysis()->backward_branches_target(current_offset)) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001445 // Add loop header and store a copy so we can connect merged back
1446 // edge inputs to the loop header.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001447 merge_environments_[current_offset] = environment()->CopyForLoop();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001448 }
1449}
1450
Ben Murdoch097c5b22016-05-18 11:27:45 +01001451void BytecodeGraphBuilder::MergeIntoSuccessorEnvironment(int target_offset) {
1452 if (merge_environments_[target_offset] == nullptr) {
1453 // Append merge nodes to the environment. We may merge here with another
1454 // environment. So add a place holder for merge nodes. We may add redundant
1455 // but will be eliminated in a later pass.
1456 // TODO(mstarzinger): Be smarter about this!
1457 NewMerge();
1458 merge_environments_[target_offset] = environment();
1459 } else {
1460 merge_environments_[target_offset]->Merge(environment());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001461 }
1462 set_environment(nullptr);
1463}
1464
Ben Murdoch097c5b22016-05-18 11:27:45 +01001465void BytecodeGraphBuilder::MergeControlToLeaveFunction(Node* exit) {
1466 exit_controls_.push_back(exit);
1467 set_environment(nullptr);
1468}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001469
1470void BytecodeGraphBuilder::BuildJump() {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001471 MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001472}
1473
1474
1475void BytecodeGraphBuilder::BuildConditionalJump(Node* condition) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001476 NewBranch(condition);
1477 Environment* if_false_environment = environment()->CopyForConditional();
1478 NewIfTrue();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001479 MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001480 set_environment(if_false_environment);
1481 NewIfFalse();
1482}
1483
1484
1485void BytecodeGraphBuilder::BuildJumpIfEqual(Node* comperand) {
1486 Node* accumulator = environment()->LookupAccumulator();
1487 Node* condition =
1488 NewNode(javascript()->StrictEqual(), accumulator, comperand);
1489 BuildConditionalJump(condition);
1490}
1491
1492
1493void BytecodeGraphBuilder::BuildJumpIfToBooleanEqual(Node* comperand) {
1494 Node* accumulator = environment()->LookupAccumulator();
1495 Node* to_boolean =
1496 NewNode(javascript()->ToBoolean(ToBooleanHint::kAny), accumulator);
1497 Node* condition = NewNode(javascript()->StrictEqual(), to_boolean, comperand);
1498 BuildConditionalJump(condition);
1499}
1500
Ben Murdoch097c5b22016-05-18 11:27:45 +01001501void BytecodeGraphBuilder::BuildJumpIfNotHole() {
1502 Node* accumulator = environment()->LookupAccumulator();
1503 Node* condition = NewNode(javascript()->StrictEqual(), accumulator,
1504 jsgraph()->TheHoleConstant());
1505 Node* node =
1506 NewNode(common()->Select(MachineRepresentation::kTagged), condition,
1507 jsgraph()->FalseConstant(), jsgraph()->TrueConstant());
1508 BuildConditionalJump(node);
1509}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001510
1511Node** BytecodeGraphBuilder::EnsureInputBufferSize(int size) {
1512 if (size > input_buffer_size_) {
1513 size = size + kInputBufferSizeIncrement + input_buffer_size_;
1514 input_buffer_ = local_zone()->NewArray<Node*>(size);
1515 input_buffer_size_ = size;
1516 }
1517 return input_buffer_;
1518}
1519
Ben Murdoch097c5b22016-05-18 11:27:45 +01001520void BytecodeGraphBuilder::EnterAndExitExceptionHandlers(int current_offset) {
1521 Handle<HandlerTable> table = exception_handler_table();
1522 int num_entries = table->NumberOfRangeEntries();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001523
Ben Murdoch097c5b22016-05-18 11:27:45 +01001524 // Potentially exit exception handlers.
1525 while (!exception_handlers_.empty()) {
1526 int current_end = exception_handlers_.top().end_offset_;
1527 if (current_offset < current_end) break; // Still covered by range.
1528 exception_handlers_.pop();
1529 }
1530
1531 // Potentially enter exception handlers.
1532 while (current_exception_handler_ < num_entries) {
1533 int next_start = table->GetRangeStart(current_exception_handler_);
1534 if (current_offset < next_start) break; // Not yet covered by range.
1535 int next_end = table->GetRangeEnd(current_exception_handler_);
1536 int next_handler = table->GetRangeHandler(current_exception_handler_);
1537 int context_register = table->GetRangeData(current_exception_handler_);
1538 CatchPrediction pred =
1539 table->GetRangePrediction(current_exception_handler_);
1540 exception_handlers_.push(
1541 {next_start, next_end, next_handler, context_register, pred});
1542 current_exception_handler_++;
1543 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001544}
1545
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001546Node* BytecodeGraphBuilder::MakeNode(const Operator* op, int value_input_count,
1547 Node** value_inputs, bool incomplete) {
1548 DCHECK_EQ(op->ValueInputCount(), value_input_count);
1549
1550 bool has_context = OperatorProperties::HasContextInput(op);
1551 int frame_state_count = OperatorProperties::GetFrameStateInputCount(op);
1552 bool has_control = op->ControlInputCount() == 1;
1553 bool has_effect = op->EffectInputCount() == 1;
1554
1555 DCHECK_LT(op->ControlInputCount(), 2);
1556 DCHECK_LT(op->EffectInputCount(), 2);
1557
1558 Node* result = nullptr;
1559 if (!has_context && frame_state_count == 0 && !has_control && !has_effect) {
1560 result = graph()->NewNode(op, value_input_count, value_inputs, incomplete);
1561 } else {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001562 bool inside_handler = !exception_handlers_.empty();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001563 int input_count_with_deps = value_input_count;
1564 if (has_context) ++input_count_with_deps;
1565 input_count_with_deps += frame_state_count;
1566 if (has_control) ++input_count_with_deps;
1567 if (has_effect) ++input_count_with_deps;
1568 Node** buffer = EnsureInputBufferSize(input_count_with_deps);
1569 memcpy(buffer, value_inputs, kPointerSize * value_input_count);
1570 Node** current_input = buffer + value_input_count;
1571 if (has_context) {
1572 *current_input++ = environment()->Context();
1573 }
1574 for (int i = 0; i < frame_state_count; i++) {
1575 // The frame state will be inserted later. Here we misuse
1576 // the {Dead} node as a sentinel to be later overwritten
1577 // with the real frame state.
1578 *current_input++ = jsgraph()->Dead();
1579 }
1580 if (has_effect) {
1581 *current_input++ = environment()->GetEffectDependency();
1582 }
1583 if (has_control) {
1584 *current_input++ = environment()->GetControlDependency();
1585 }
1586 result = graph()->NewNode(op, input_count_with_deps, buffer, incomplete);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001587 // Update the current control dependency for control-producing nodes.
1588 if (NodeProperties::IsControl(result)) {
1589 environment()->UpdateControlDependency(result);
1590 }
1591 // Update the current effect dependency for effect-producing nodes.
1592 if (result->op()->EffectOutputCount() > 0) {
1593 environment()->UpdateEffectDependency(result);
1594 }
1595 // Add implicit exception continuation for throwing nodes.
1596 if (!result->op()->HasProperty(Operator::kNoThrow) && inside_handler) {
1597 int handler_offset = exception_handlers_.top().handler_offset_;
1598 int context_index = exception_handlers_.top().context_register_;
1599 CatchPrediction prediction = exception_handlers_.top().pred_;
1600 interpreter::Register context_register(context_index);
1601 IfExceptionHint hint = prediction == CatchPrediction::CAUGHT
1602 ? IfExceptionHint::kLocallyCaught
1603 : IfExceptionHint::kLocallyUncaught;
1604 Environment* success_env = environment()->CopyForConditional();
1605 const Operator* op = common()->IfException(hint);
1606 Node* effect = environment()->GetEffectDependency();
1607 Node* on_exception = graph()->NewNode(op, effect, result);
1608 Node* context = environment()->LookupRegister(context_register);
1609 environment()->UpdateControlDependency(on_exception);
1610 environment()->UpdateEffectDependency(on_exception);
1611 environment()->BindAccumulator(on_exception);
1612 environment()->SetContext(context);
1613 MergeIntoSuccessorEnvironment(handler_offset);
1614 set_environment(success_env);
1615 }
1616 // Add implicit success continuation for throwing nodes.
1617 if (!result->op()->HasProperty(Operator::kNoThrow)) {
1618 const Operator* if_success = common()->IfSuccess();
1619 Node* on_success = graph()->NewNode(if_success, result);
1620 environment()->UpdateControlDependency(on_success);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001621 }
1622 }
1623
1624 return result;
1625}
1626
1627
1628Node* BytecodeGraphBuilder::NewPhi(int count, Node* input, Node* control) {
1629 const Operator* phi_op = common()->Phi(MachineRepresentation::kTagged, count);
1630 Node** buffer = EnsureInputBufferSize(count + 1);
1631 MemsetPointer(buffer, input, count);
1632 buffer[count] = control;
1633 return graph()->NewNode(phi_op, count + 1, buffer, true);
1634}
1635
1636
1637Node* BytecodeGraphBuilder::NewEffectPhi(int count, Node* input,
1638 Node* control) {
1639 const Operator* phi_op = common()->EffectPhi(count);
1640 Node** buffer = EnsureInputBufferSize(count + 1);
1641 MemsetPointer(buffer, input, count);
1642 buffer[count] = control;
1643 return graph()->NewNode(phi_op, count + 1, buffer, true);
1644}
1645
1646
1647Node* BytecodeGraphBuilder::MergeControl(Node* control, Node* other) {
1648 int inputs = control->op()->ControlInputCount() + 1;
1649 if (control->opcode() == IrOpcode::kLoop) {
1650 // Control node for loop exists, add input.
1651 const Operator* op = common()->Loop(inputs);
1652 control->AppendInput(graph_zone(), other);
1653 NodeProperties::ChangeOp(control, op);
1654 } else if (control->opcode() == IrOpcode::kMerge) {
1655 // Control node for merge exists, add input.
1656 const Operator* op = common()->Merge(inputs);
1657 control->AppendInput(graph_zone(), other);
1658 NodeProperties::ChangeOp(control, op);
1659 } else {
1660 // Control node is a singleton, introduce a merge.
1661 const Operator* op = common()->Merge(inputs);
1662 Node* merge_inputs[] = {control, other};
1663 control = graph()->NewNode(op, arraysize(merge_inputs), merge_inputs, true);
1664 }
1665 return control;
1666}
1667
1668
1669Node* BytecodeGraphBuilder::MergeEffect(Node* value, Node* other,
1670 Node* control) {
1671 int inputs = control->op()->ControlInputCount();
1672 if (value->opcode() == IrOpcode::kEffectPhi &&
1673 NodeProperties::GetControlInput(value) == control) {
1674 // Phi already exists, add input.
1675 value->InsertInput(graph_zone(), inputs - 1, other);
1676 NodeProperties::ChangeOp(value, common()->EffectPhi(inputs));
1677 } else if (value != other) {
1678 // Phi does not exist yet, introduce one.
1679 value = NewEffectPhi(inputs, value, control);
1680 value->ReplaceInput(inputs - 1, other);
1681 }
1682 return value;
1683}
1684
1685
1686Node* BytecodeGraphBuilder::MergeValue(Node* value, Node* other,
1687 Node* control) {
1688 int inputs = control->op()->ControlInputCount();
1689 if (value->opcode() == IrOpcode::kPhi &&
1690 NodeProperties::GetControlInput(value) == control) {
1691 // Phi already exists, add input.
1692 value->InsertInput(graph_zone(), inputs - 1, other);
1693 NodeProperties::ChangeOp(
1694 value, common()->Phi(MachineRepresentation::kTagged, inputs));
1695 } else if (value != other) {
1696 // Phi does not exist yet, introduce one.
1697 value = NewPhi(inputs, value, control);
1698 value->ReplaceInput(inputs - 1, other);
1699 }
1700 return value;
1701}
1702
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001703} // namespace compiler
1704} // namespace internal
1705} // namespace v8