blob: 79d8ff2bc56ba6111dde192945b3880379f9851c [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 Murdoch61f157c2016-09-16 13:49:30 +0100112 // Create an explicit checkpoint node for before the operation.
113 Node* node = builder_->NewNode(builder_->common()->Checkpoint());
114 DCHECK_EQ(IrOpcode::kDead,
115 NodeProperties::GetFrameStateInput(node, 0)->opcode());
116 NodeProperties::ReplaceFrameStateInput(node, 0, frame_state_before_);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000117 }
118
119 ~FrameStateBeforeAndAfter() {
120 DCHECK(added_to_node_);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100121 DCHECK(frame_states_unused_ ||
122 builder_->environment()->StateValuesAreUpToDate(output_poke_offset_,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000123 output_poke_count_));
124 }
125
126 private:
127 friend class Environment;
128
129 void AddToNode(Node* node, OutputFrameStateCombine combine) {
130 DCHECK(!added_to_node_);
131 int count = OperatorProperties::GetFrameStateInputCount(node->op());
132 DCHECK_LE(count, 2);
133 if (count >= 1) {
134 // Add the frame state for after the operation.
135 DCHECK_EQ(IrOpcode::kDead,
136 NodeProperties::GetFrameStateInput(node, 0)->opcode());
137 Node* frame_state_after =
138 builder_->environment()->Checkpoint(id_after_, combine);
139 NodeProperties::ReplaceFrameStateInput(node, 0, frame_state_after);
140 }
141
142 if (count >= 2) {
143 // Add the frame state for before the operation.
Ben Murdoch61f157c2016-09-16 13:49:30 +0100144 // TODO(mstarzinger): Get rid of frame state input before!
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000145 DCHECK_EQ(IrOpcode::kDead,
146 NodeProperties::GetFrameStateInput(node, 1)->opcode());
147 NodeProperties::ReplaceFrameStateInput(node, 1, frame_state_before_);
148 }
149
150 if (!combine.IsOutputIgnored()) {
151 output_poke_offset_ = static_cast<int>(combine.GetOffsetToPokeAt());
152 output_poke_count_ = node->op()->ValueOutputCount();
153 }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100154 frame_states_unused_ = count == 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000155 added_to_node_ = true;
156 }
157
158 BytecodeGraphBuilder* builder_;
159 Node* frame_state_before_;
160 BailoutId id_after_;
161
162 bool added_to_node_;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100163 bool frame_states_unused_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000164 int output_poke_offset_;
165 int output_poke_count_;
166};
167
168
169// Issues:
170// - Scopes - intimately tied to AST. Need to eval what is needed.
171// - Need to resolve closure parameter treatment.
172BytecodeGraphBuilder::Environment::Environment(BytecodeGraphBuilder* builder,
173 int register_count,
174 int parameter_count,
175 Node* control_dependency,
176 Node* context)
177 : builder_(builder),
178 register_count_(register_count),
179 parameter_count_(parameter_count),
180 context_(context),
181 control_dependency_(control_dependency),
182 effect_dependency_(control_dependency),
183 values_(builder->local_zone()),
184 parameters_state_values_(nullptr),
185 registers_state_values_(nullptr),
186 accumulator_state_values_(nullptr) {
187 // The layout of values_ is:
188 //
189 // [receiver] [parameters] [registers] [accumulator]
190 //
191 // parameter[0] is the receiver (this), parameters 1..N are the
192 // parameters supplied to the method (arg0..argN-1). The accumulator
193 // is stored separately.
194
195 // Parameters including the receiver
196 for (int i = 0; i < parameter_count; i++) {
197 const char* debug_name = (i == 0) ? "%this" : nullptr;
198 const Operator* op = common()->Parameter(i, debug_name);
199 Node* parameter = builder->graph()->NewNode(op, graph()->start());
200 values()->push_back(parameter);
201 }
202
203 // Registers
204 register_base_ = static_cast<int>(values()->size());
205 Node* undefined_constant = builder->jsgraph()->UndefinedConstant();
206 values()->insert(values()->end(), register_count, undefined_constant);
207
208 // Accumulator
209 accumulator_base_ = static_cast<int>(values()->size());
210 values()->push_back(undefined_constant);
211}
212
213
214BytecodeGraphBuilder::Environment::Environment(
215 const BytecodeGraphBuilder::Environment* other)
216 : builder_(other->builder_),
217 register_count_(other->register_count_),
218 parameter_count_(other->parameter_count_),
219 context_(other->context_),
220 control_dependency_(other->control_dependency_),
221 effect_dependency_(other->effect_dependency_),
222 values_(other->zone()),
223 parameters_state_values_(nullptr),
224 registers_state_values_(nullptr),
225 accumulator_state_values_(nullptr),
226 register_base_(other->register_base_),
227 accumulator_base_(other->accumulator_base_) {
228 values_ = other->values_;
229}
230
231
232int BytecodeGraphBuilder::Environment::RegisterToValuesIndex(
233 interpreter::Register the_register) const {
234 if (the_register.is_parameter()) {
235 return the_register.ToParameterIndex(parameter_count());
236 } else {
237 return the_register.index() + register_base();
238 }
239}
240
241
242Node* BytecodeGraphBuilder::Environment::LookupAccumulator() const {
243 return values()->at(accumulator_base_);
244}
245
246
247Node* BytecodeGraphBuilder::Environment::LookupRegister(
248 interpreter::Register the_register) const {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100249 if (the_register.is_current_context()) {
250 return Context();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000251 } else if (the_register.is_function_closure()) {
252 return builder()->GetFunctionClosure();
253 } else if (the_register.is_new_target()) {
254 return builder()->GetNewTarget();
255 } else {
256 int values_index = RegisterToValuesIndex(the_register);
257 return values()->at(values_index);
258 }
259}
260
261
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000262void BytecodeGraphBuilder::Environment::BindAccumulator(
263 Node* node, FrameStateBeforeAndAfter* states) {
264 if (states) {
265 states->AddToNode(node, OutputFrameStateCombine::PokeAt(0));
266 }
267 values()->at(accumulator_base_) = node;
268}
269
270
271void BytecodeGraphBuilder::Environment::BindRegister(
272 interpreter::Register the_register, Node* node,
273 FrameStateBeforeAndAfter* states) {
274 int values_index = RegisterToValuesIndex(the_register);
275 if (states) {
276 states->AddToNode(node, OutputFrameStateCombine::PokeAt(accumulator_base_ -
277 values_index));
278 }
279 values()->at(values_index) = node;
280}
281
282
283void BytecodeGraphBuilder::Environment::BindRegistersToProjections(
284 interpreter::Register first_reg, Node* node,
285 FrameStateBeforeAndAfter* states) {
286 int values_index = RegisterToValuesIndex(first_reg);
287 if (states) {
288 states->AddToNode(node, OutputFrameStateCombine::PokeAt(accumulator_base_ -
289 values_index));
290 }
291 for (int i = 0; i < node->op()->ValueOutputCount(); i++) {
292 values()->at(values_index + i) =
293 builder()->NewNode(common()->Projection(i), node);
294 }
295}
296
297
298void BytecodeGraphBuilder::Environment::RecordAfterState(
299 Node* node, FrameStateBeforeAndAfter* states) {
300 states->AddToNode(node, OutputFrameStateCombine::Ignore());
301}
302
303
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000304BytecodeGraphBuilder::Environment*
305BytecodeGraphBuilder::Environment::CopyForLoop() {
306 PrepareForLoop();
307 return new (zone()) Environment(this);
308}
309
310
311BytecodeGraphBuilder::Environment*
312BytecodeGraphBuilder::Environment::CopyForConditional() const {
313 return new (zone()) Environment(this);
314}
315
316
317void BytecodeGraphBuilder::Environment::Merge(
318 BytecodeGraphBuilder::Environment* other) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000319 // Create a merge of the control dependencies of both environments and update
320 // the current environment's control dependency accordingly.
321 Node* control = builder()->MergeControl(GetControlDependency(),
322 other->GetControlDependency());
323 UpdateControlDependency(control);
324
325 // Create a merge of the effect dependencies of both environments and update
326 // the current environment's effect dependency accordingly.
327 Node* effect = builder()->MergeEffect(GetEffectDependency(),
328 other->GetEffectDependency(), control);
329 UpdateEffectDependency(effect);
330
331 // Introduce Phi nodes for values that have differing input at merge points,
332 // potentially extending an existing Phi node if possible.
333 context_ = builder()->MergeValue(context_, other->context_, control);
334 for (size_t i = 0; i < values_.size(); i++) {
335 values_[i] = builder()->MergeValue(values_[i], other->values_[i], control);
336 }
337}
338
339
340void BytecodeGraphBuilder::Environment::PrepareForLoop() {
341 // Create a control node for the loop header.
342 Node* control = builder()->NewLoop();
343
344 // Create a Phi for external effects.
345 Node* effect = builder()->NewEffectPhi(1, GetEffectDependency(), control);
346 UpdateEffectDependency(effect);
347
348 // Assume everything in the loop is updated.
349 context_ = builder()->NewPhi(1, context_, control);
350 int size = static_cast<int>(values()->size());
351 for (int i = 0; i < size; i++) {
352 values()->at(i) = builder()->NewPhi(1, values()->at(i), control);
353 }
354
355 // Connect to the loop end.
356 Node* terminate = builder()->graph()->NewNode(
357 builder()->common()->Terminate(), effect, control);
358 builder()->exit_controls_.push_back(terminate);
359}
360
361
362bool BytecodeGraphBuilder::Environment::StateValuesRequireUpdate(
363 Node** state_values, int offset, int count) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000364 if (*state_values == nullptr) {
365 return true;
366 }
367 DCHECK_EQ((*state_values)->InputCount(), count);
368 DCHECK_LE(static_cast<size_t>(offset + count), values()->size());
369 Node** env_values = (count == 0) ? nullptr : &values()->at(offset);
370 for (int i = 0; i < count; i++) {
371 if ((*state_values)->InputAt(i) != env_values[i]) {
372 return true;
373 }
374 }
375 return false;
376}
377
378
379void BytecodeGraphBuilder::Environment::UpdateStateValues(Node** state_values,
380 int offset,
381 int count) {
382 if (StateValuesRequireUpdate(state_values, offset, count)) {
383 const Operator* op = common()->StateValues(count);
384 (*state_values) = graph()->NewNode(op, count, &values()->at(offset));
385 }
386}
387
388
389Node* BytecodeGraphBuilder::Environment::Checkpoint(
390 BailoutId bailout_id, OutputFrameStateCombine combine) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000391 // TODO(rmcilroy): Consider using StateValuesCache for some state values.
392 UpdateStateValues(&parameters_state_values_, 0, parameter_count());
393 UpdateStateValues(&registers_state_values_, register_base(),
394 register_count());
395 UpdateStateValues(&accumulator_state_values_, accumulator_base(), 1);
396
397 const Operator* op = common()->FrameState(
398 bailout_id, combine, builder()->frame_state_function_info());
399 Node* result = graph()->NewNode(
400 op, parameters_state_values_, registers_state_values_,
401 accumulator_state_values_, Context(), builder()->GetFunctionClosure(),
402 builder()->graph()->start());
403
404 return result;
405}
406
407
408bool BytecodeGraphBuilder::Environment::StateValuesAreUpToDate(
409 Node** state_values, int offset, int count, int output_poke_start,
410 int output_poke_end) {
411 DCHECK_LE(static_cast<size_t>(offset + count), values()->size());
412 for (int i = 0; i < count; i++, offset++) {
413 if (offset < output_poke_start || offset >= output_poke_end) {
414 if ((*state_values)->InputAt(i) != values()->at(offset)) {
415 return false;
416 }
417 }
418 }
419 return true;
420}
421
422
423bool BytecodeGraphBuilder::Environment::StateValuesAreUpToDate(
424 int output_poke_offset, int output_poke_count) {
425 // Poke offset is relative to the top of the stack (i.e., the accumulator).
426 int output_poke_start = accumulator_base() - output_poke_offset;
427 int output_poke_end = output_poke_start + output_poke_count;
428 return StateValuesAreUpToDate(&parameters_state_values_, 0, parameter_count(),
429 output_poke_start, output_poke_end) &&
430 StateValuesAreUpToDate(&registers_state_values_, register_base(),
431 register_count(), output_poke_start,
432 output_poke_end) &&
433 StateValuesAreUpToDate(&accumulator_state_values_, accumulator_base(),
434 1, output_poke_start, output_poke_end);
435}
436
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000437BytecodeGraphBuilder::BytecodeGraphBuilder(Zone* local_zone,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100438 CompilationInfo* info,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000439 JSGraph* jsgraph)
440 : local_zone_(local_zone),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000441 jsgraph_(jsgraph),
Ben Murdoch097c5b22016-05-18 11:27:45 +0100442 bytecode_array_(handle(info->shared_info()->bytecode_array())),
443 exception_handler_table_(
444 handle(HandlerTable::cast(bytecode_array()->handler_table()))),
Ben Murdoch61f157c2016-09-16 13:49:30 +0100445 feedback_vector_(handle(info->closure()->feedback_vector())),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000446 frame_state_function_info_(common()->CreateFrameStateFunctionInfo(
447 FrameStateType::kInterpretedFunction,
448 bytecode_array()->parameter_count(),
Ben Murdoch097c5b22016-05-18 11:27:45 +0100449 bytecode_array()->register_count(), info->shared_info())),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000450 merge_environments_(local_zone),
Ben Murdoch097c5b22016-05-18 11:27:45 +0100451 exception_handlers_(local_zone),
452 current_exception_handler_(0),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000453 input_buffer_size_(0),
454 input_buffer_(nullptr),
455 exit_controls_(local_zone) {}
456
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000457Node* BytecodeGraphBuilder::GetNewTarget() {
458 if (!new_target_.is_set()) {
459 int params = bytecode_array()->parameter_count();
460 int index = Linkage::GetJSCallNewTargetParamIndex(params);
461 const Operator* op = common()->Parameter(index, "%new.target");
462 Node* node = NewNode(op, graph()->start());
463 new_target_.set(node);
464 }
465 return new_target_.get();
466}
467
468
469Node* BytecodeGraphBuilder::GetFunctionContext() {
470 if (!function_context_.is_set()) {
471 int params = bytecode_array()->parameter_count();
472 int index = Linkage::GetJSCallContextParamIndex(params);
473 const Operator* op = common()->Parameter(index, "%context");
474 Node* node = NewNode(op, graph()->start());
475 function_context_.set(node);
476 }
477 return function_context_.get();
478}
479
480
481Node* BytecodeGraphBuilder::GetFunctionClosure() {
482 if (!function_closure_.is_set()) {
483 int index = Linkage::kJSCallClosureParamIndex;
484 const Operator* op = common()->Parameter(index, "%closure");
485 Node* node = NewNode(op, graph()->start());
486 function_closure_.set(node);
487 }
488 return function_closure_.get();
489}
490
491
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000492Node* BytecodeGraphBuilder::BuildLoadNativeContextField(int index) {
493 const Operator* op =
494 javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true);
495 Node* native_context = NewNode(op, environment()->Context());
496 return NewNode(javascript()->LoadContext(0, index, true), native_context);
497}
498
499
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000500VectorSlotPair BytecodeGraphBuilder::CreateVectorSlotPair(int slot_id) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000501 FeedbackVectorSlot slot;
502 if (slot_id >= TypeFeedbackVector::kReservedIndexCount) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100503 slot = feedback_vector()->ToSlot(slot_id);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000504 }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100505 return VectorSlotPair(feedback_vector(), slot);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000506}
507
Ben Murdoch097c5b22016-05-18 11:27:45 +0100508bool BytecodeGraphBuilder::CreateGraph() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000509 // Set up the basic structure of the graph. Outputs for {Start} are
510 // the formal parameters (including the receiver) plus context and
511 // closure.
512
513 // Set up the basic structure of the graph. Outputs for {Start} are the formal
514 // parameters (including the receiver) plus new target, number of arguments,
515 // context and closure.
516 int actual_parameter_count = bytecode_array()->parameter_count() + 4;
517 graph()->SetStart(graph()->NewNode(common()->Start(actual_parameter_count)));
518
519 Environment env(this, bytecode_array()->register_count(),
520 bytecode_array()->parameter_count(), graph()->start(),
521 GetFunctionContext());
522 set_environment(&env);
523
Ben Murdoch097c5b22016-05-18 11:27:45 +0100524 VisitBytecodes();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000525
526 // Finish the basic structure of the graph.
527 DCHECK_NE(0u, exit_controls_.size());
528 int const input_count = static_cast<int>(exit_controls_.size());
529 Node** const inputs = &exit_controls_.front();
530 Node* end = graph()->NewNode(common()->End(input_count), input_count, inputs);
531 graph()->SetEnd(end);
532
533 return true;
534}
535
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000536void BytecodeGraphBuilder::VisitBytecodes() {
537 BytecodeBranchAnalysis analysis(bytecode_array(), local_zone());
538 analysis.Analyze();
539 set_branch_analysis(&analysis);
540 interpreter::BytecodeArrayIterator iterator(bytecode_array());
541 set_bytecode_iterator(&iterator);
542 while (!iterator.done()) {
543 int current_offset = iterator.current_offset();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100544 EnterAndExitExceptionHandlers(current_offset);
545 SwitchToMergeEnvironment(current_offset);
546 if (environment() != nullptr) {
547 BuildLoopHeaderEnvironment(current_offset);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000548
549 switch (iterator.current_bytecode()) {
550#define BYTECODE_CASE(name, ...) \
551 case interpreter::Bytecode::k##name: \
Ben Murdoch097c5b22016-05-18 11:27:45 +0100552 Visit##name(); \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000553 break;
554 BYTECODE_LIST(BYTECODE_CASE)
555#undef BYTECODE_CODE
556 }
557 }
558 iterator.Advance();
559 }
560 set_branch_analysis(nullptr);
561 set_bytecode_iterator(nullptr);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100562 DCHECK(exception_handlers_.empty());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000563}
564
Ben Murdoch097c5b22016-05-18 11:27:45 +0100565void BytecodeGraphBuilder::VisitLdaZero() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000566 Node* node = jsgraph()->ZeroConstant();
567 environment()->BindAccumulator(node);
568}
569
Ben Murdochda12d292016-06-02 14:46:10 +0100570void BytecodeGraphBuilder::VisitLdaSmi() {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100571 Node* node = jsgraph()->Constant(bytecode_iterator().GetImmediateOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000572 environment()->BindAccumulator(node);
573}
574
Ben Murdoch097c5b22016-05-18 11:27:45 +0100575void BytecodeGraphBuilder::VisitLdaConstant() {
576 Node* node =
577 jsgraph()->Constant(bytecode_iterator().GetConstantForIndexOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000578 environment()->BindAccumulator(node);
579}
580
Ben Murdoch097c5b22016-05-18 11:27:45 +0100581void BytecodeGraphBuilder::VisitLdaUndefined() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000582 Node* node = jsgraph()->UndefinedConstant();
583 environment()->BindAccumulator(node);
584}
585
Ben Murdoch61f157c2016-09-16 13:49:30 +0100586void BytecodeGraphBuilder::VisitLdrUndefined() {
587 Node* node = jsgraph()->UndefinedConstant();
588 environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0), node);
589}
590
Ben Murdoch097c5b22016-05-18 11:27:45 +0100591void BytecodeGraphBuilder::VisitLdaNull() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000592 Node* node = jsgraph()->NullConstant();
593 environment()->BindAccumulator(node);
594}
595
Ben Murdoch097c5b22016-05-18 11:27:45 +0100596void BytecodeGraphBuilder::VisitLdaTheHole() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000597 Node* node = jsgraph()->TheHoleConstant();
598 environment()->BindAccumulator(node);
599}
600
Ben Murdoch097c5b22016-05-18 11:27:45 +0100601void BytecodeGraphBuilder::VisitLdaTrue() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000602 Node* node = jsgraph()->TrueConstant();
603 environment()->BindAccumulator(node);
604}
605
Ben Murdoch097c5b22016-05-18 11:27:45 +0100606void BytecodeGraphBuilder::VisitLdaFalse() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000607 Node* node = jsgraph()->FalseConstant();
608 environment()->BindAccumulator(node);
609}
610
Ben Murdoch097c5b22016-05-18 11:27:45 +0100611void BytecodeGraphBuilder::VisitLdar() {
612 Node* value =
613 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000614 environment()->BindAccumulator(value);
615}
616
Ben Murdoch097c5b22016-05-18 11:27:45 +0100617void BytecodeGraphBuilder::VisitStar() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000618 Node* value = environment()->LookupAccumulator();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100619 environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0), value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000620}
621
Ben Murdoch097c5b22016-05-18 11:27:45 +0100622void BytecodeGraphBuilder::VisitMov() {
623 Node* value =
624 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
625 environment()->BindRegister(bytecode_iterator().GetRegisterOperand(1), value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000626}
627
Ben Murdoch61f157c2016-09-16 13:49:30 +0100628Node* BytecodeGraphBuilder::BuildLoadGlobal(TypeofMode typeof_mode) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100629 VectorSlotPair feedback =
Ben Murdoch61f157c2016-09-16 13:49:30 +0100630 CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(0));
631 DCHECK_EQ(FeedbackVectorSlotKind::LOAD_GLOBAL_IC,
632 feedback_vector()->GetKind(feedback.slot()));
633 Handle<Name> name(feedback_vector()->GetName(feedback.slot()));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000634 const Operator* op = javascript()->LoadGlobal(name, feedback, typeof_mode);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100635 return NewNode(op, GetFunctionClosure());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000636}
637
Ben Murdoch097c5b22016-05-18 11:27:45 +0100638void BytecodeGraphBuilder::VisitLdaGlobal() {
Ben Murdoch61f157c2016-09-16 13:49:30 +0100639 FrameStateBeforeAndAfter states(this);
640 Node* node = BuildLoadGlobal(TypeofMode::NOT_INSIDE_TYPEOF);
641 environment()->BindAccumulator(node, &states);
642}
643
644void BytecodeGraphBuilder::VisitLdrGlobal() {
645 FrameStateBeforeAndAfter states(this);
646 Node* node = BuildLoadGlobal(TypeofMode::NOT_INSIDE_TYPEOF);
647 environment()->BindRegister(bytecode_iterator().GetRegisterOperand(1), node,
648 &states);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000649}
650
Ben Murdoch097c5b22016-05-18 11:27:45 +0100651void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeof() {
Ben Murdoch61f157c2016-09-16 13:49:30 +0100652 FrameStateBeforeAndAfter states(this);
653 Node* node = BuildLoadGlobal(TypeofMode::INSIDE_TYPEOF);
654 environment()->BindAccumulator(node, &states);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000655}
656
Ben Murdoch097c5b22016-05-18 11:27:45 +0100657void BytecodeGraphBuilder::BuildStoreGlobal(LanguageMode language_mode) {
658 FrameStateBeforeAndAfter states(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000659 Handle<Name> name =
Ben Murdoch097c5b22016-05-18 11:27:45 +0100660 Handle<Name>::cast(bytecode_iterator().GetConstantForIndexOperand(0));
661 VectorSlotPair feedback =
662 CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(1));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000663 Node* value = environment()->LookupAccumulator();
664
Ben Murdoch097c5b22016-05-18 11:27:45 +0100665 const Operator* op = javascript()->StoreGlobal(language_mode, name, feedback);
666 Node* node = NewNode(op, value, GetFunctionClosure());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000667 environment()->RecordAfterState(node, &states);
668}
669
Ben Murdoch097c5b22016-05-18 11:27:45 +0100670void BytecodeGraphBuilder::VisitStaGlobalSloppy() {
671 BuildStoreGlobal(LanguageMode::SLOPPY);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000672}
673
Ben Murdoch097c5b22016-05-18 11:27:45 +0100674void BytecodeGraphBuilder::VisitStaGlobalStrict() {
675 BuildStoreGlobal(LanguageMode::STRICT);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000676}
677
Ben Murdoch61f157c2016-09-16 13:49:30 +0100678Node* BytecodeGraphBuilder::BuildLoadContextSlot() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000679 // TODO(mythria): LoadContextSlots are unrolled by the required depth when
680 // generating bytecode. Hence the value of depth is always 0. Update this
681 // code, when the implementation changes.
682 // TODO(mythria): immutable flag is also set to false. This information is not
683 // available in bytecode array. update this code when the implementation
684 // changes.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100685 const Operator* op = javascript()->LoadContext(
686 0, bytecode_iterator().GetIndexOperand(1), false);
687 Node* context =
688 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Ben Murdoch61f157c2016-09-16 13:49:30 +0100689 return NewNode(op, context);
690}
691
692void BytecodeGraphBuilder::VisitLdaContextSlot() {
693 Node* node = BuildLoadContextSlot();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000694 environment()->BindAccumulator(node);
695}
696
Ben Murdoch61f157c2016-09-16 13:49:30 +0100697void BytecodeGraphBuilder::VisitLdrContextSlot() {
698 Node* node = BuildLoadContextSlot();
699 environment()->BindRegister(bytecode_iterator().GetRegisterOperand(2), node);
700}
701
Ben Murdoch097c5b22016-05-18 11:27:45 +0100702void BytecodeGraphBuilder::VisitStaContextSlot() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000703 // TODO(mythria): LoadContextSlots are unrolled by the required depth when
704 // generating bytecode. Hence the value of depth is always 0. Update this
705 // code, when the implementation changes.
706 const Operator* op =
Ben Murdoch097c5b22016-05-18 11:27:45 +0100707 javascript()->StoreContext(0, bytecode_iterator().GetIndexOperand(1));
708 Node* context =
709 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000710 Node* value = environment()->LookupAccumulator();
711 NewNode(op, context, value);
712}
713
Ben Murdoch097c5b22016-05-18 11:27:45 +0100714void BytecodeGraphBuilder::BuildLdaLookupSlot(TypeofMode typeof_mode) {
715 FrameStateBeforeAndAfter states(this);
716 Node* name =
717 jsgraph()->Constant(bytecode_iterator().GetConstantForIndexOperand(0));
718 const Operator* op =
719 javascript()->CallRuntime(typeof_mode == TypeofMode::NOT_INSIDE_TYPEOF
720 ? Runtime::kLoadLookupSlot
721 : Runtime::kLoadLookupSlotInsideTypeof);
722 Node* value = NewNode(op, name);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000723 environment()->BindAccumulator(value, &states);
724}
725
Ben Murdoch097c5b22016-05-18 11:27:45 +0100726void BytecodeGraphBuilder::VisitLdaLookupSlot() {
727 BuildLdaLookupSlot(TypeofMode::NOT_INSIDE_TYPEOF);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000728}
729
Ben Murdoch097c5b22016-05-18 11:27:45 +0100730void BytecodeGraphBuilder::VisitLdaLookupSlotInsideTypeof() {
731 BuildLdaLookupSlot(TypeofMode::INSIDE_TYPEOF);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000732}
733
Ben Murdoch097c5b22016-05-18 11:27:45 +0100734void BytecodeGraphBuilder::BuildStaLookupSlot(LanguageMode language_mode) {
735 FrameStateBeforeAndAfter states(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000736 Node* value = environment()->LookupAccumulator();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100737 Node* name =
738 jsgraph()->Constant(bytecode_iterator().GetConstantForIndexOperand(0));
739 const Operator* op = javascript()->CallRuntime(
740 is_strict(language_mode) ? Runtime::kStoreLookupSlot_Strict
741 : Runtime::kStoreLookupSlot_Sloppy);
742 Node* store = NewNode(op, name, value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000743 environment()->BindAccumulator(store, &states);
744}
745
Ben Murdoch097c5b22016-05-18 11:27:45 +0100746void BytecodeGraphBuilder::VisitStaLookupSlotSloppy() {
747 BuildStaLookupSlot(LanguageMode::SLOPPY);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000748}
749
Ben Murdoch097c5b22016-05-18 11:27:45 +0100750void BytecodeGraphBuilder::VisitStaLookupSlotStrict() {
751 BuildStaLookupSlot(LanguageMode::STRICT);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000752}
753
Ben Murdoch61f157c2016-09-16 13:49:30 +0100754Node* BytecodeGraphBuilder::BuildNamedLoad() {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100755 Node* object =
756 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000757 Handle<Name> name =
Ben Murdoch097c5b22016-05-18 11:27:45 +0100758 Handle<Name>::cast(bytecode_iterator().GetConstantForIndexOperand(1));
759 VectorSlotPair feedback =
760 CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(2));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000761
Ben Murdoch097c5b22016-05-18 11:27:45 +0100762 const Operator* op = javascript()->LoadNamed(name, feedback);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100763 return NewNode(op, object, GetFunctionClosure());
764}
765
766void BytecodeGraphBuilder::VisitLdaNamedProperty() {
767 FrameStateBeforeAndAfter states(this);
768 Node* node = BuildNamedLoad();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000769 environment()->BindAccumulator(node, &states);
770}
771
Ben Murdoch61f157c2016-09-16 13:49:30 +0100772void BytecodeGraphBuilder::VisitLdrNamedProperty() {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100773 FrameStateBeforeAndAfter states(this);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100774 Node* node = BuildNamedLoad();
775 environment()->BindRegister(bytecode_iterator().GetRegisterOperand(3), node,
776 &states);
777}
778
779Node* BytecodeGraphBuilder::BuildKeyedLoad() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000780 Node* key = environment()->LookupAccumulator();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100781 Node* object =
782 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
783 VectorSlotPair feedback =
784 CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(1));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000785
Ben Murdoch097c5b22016-05-18 11:27:45 +0100786 const Operator* op = javascript()->LoadProperty(feedback);
Ben Murdoch61f157c2016-09-16 13:49:30 +0100787 return NewNode(op, object, key, GetFunctionClosure());
788}
789
790void BytecodeGraphBuilder::VisitLdaKeyedProperty() {
791 FrameStateBeforeAndAfter states(this);
792 Node* node = BuildKeyedLoad();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000793 environment()->BindAccumulator(node, &states);
794}
795
Ben Murdoch61f157c2016-09-16 13:49:30 +0100796void BytecodeGraphBuilder::VisitLdrKeyedProperty() {
797 FrameStateBeforeAndAfter states(this);
798 Node* node = BuildKeyedLoad();
799 environment()->BindRegister(bytecode_iterator().GetRegisterOperand(2), node,
800 &states);
801}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000802
Ben Murdoch097c5b22016-05-18 11:27:45 +0100803void BytecodeGraphBuilder::BuildNamedStore(LanguageMode language_mode) {
804 FrameStateBeforeAndAfter states(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000805 Node* value = environment()->LookupAccumulator();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100806 Node* object =
807 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000808 Handle<Name> name =
Ben Murdoch097c5b22016-05-18 11:27:45 +0100809 Handle<Name>::cast(bytecode_iterator().GetConstantForIndexOperand(1));
810 VectorSlotPair feedback =
811 CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(2));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000812
Ben Murdoch097c5b22016-05-18 11:27:45 +0100813 const Operator* op = javascript()->StoreNamed(language_mode, name, feedback);
814 Node* node = NewNode(op, object, value, GetFunctionClosure());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000815 environment()->RecordAfterState(node, &states);
816}
817
Ben Murdoch61f157c2016-09-16 13:49:30 +0100818void BytecodeGraphBuilder::VisitStaNamedPropertySloppy() {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100819 BuildNamedStore(LanguageMode::SLOPPY);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000820}
821
Ben Murdoch61f157c2016-09-16 13:49:30 +0100822void BytecodeGraphBuilder::VisitStaNamedPropertyStrict() {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100823 BuildNamedStore(LanguageMode::STRICT);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000824}
825
Ben Murdoch097c5b22016-05-18 11:27:45 +0100826void BytecodeGraphBuilder::BuildKeyedStore(LanguageMode language_mode) {
827 FrameStateBeforeAndAfter states(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000828 Node* value = environment()->LookupAccumulator();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100829 Node* object =
830 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
831 Node* key =
832 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
833 VectorSlotPair feedback =
834 CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(2));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000835
Ben Murdoch097c5b22016-05-18 11:27:45 +0100836 const Operator* op = javascript()->StoreProperty(language_mode, feedback);
837 Node* node = NewNode(op, object, key, value, GetFunctionClosure());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000838 environment()->RecordAfterState(node, &states);
839}
840
Ben Murdoch61f157c2016-09-16 13:49:30 +0100841void BytecodeGraphBuilder::VisitStaKeyedPropertySloppy() {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100842 BuildKeyedStore(LanguageMode::SLOPPY);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000843}
844
Ben Murdoch61f157c2016-09-16 13:49:30 +0100845void BytecodeGraphBuilder::VisitStaKeyedPropertyStrict() {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100846 BuildKeyedStore(LanguageMode::STRICT);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000847}
848
Ben Murdoch097c5b22016-05-18 11:27:45 +0100849void BytecodeGraphBuilder::VisitPushContext() {
850 Node* new_context = environment()->LookupAccumulator();
851 environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0),
852 environment()->Context());
853 environment()->SetContext(new_context);
854}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000855
Ben Murdoch097c5b22016-05-18 11:27:45 +0100856void BytecodeGraphBuilder::VisitPopContext() {
857 Node* context =
858 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000859 environment()->SetContext(context);
860}
861
Ben Murdoch097c5b22016-05-18 11:27:45 +0100862void BytecodeGraphBuilder::VisitCreateClosure() {
863 Handle<SharedFunctionInfo> shared_info = Handle<SharedFunctionInfo>::cast(
864 bytecode_iterator().GetConstantForIndexOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000865 PretenureFlag tenured =
Ben Murdochda12d292016-06-02 14:46:10 +0100866 bytecode_iterator().GetFlagOperand(1) ? TENURED : NOT_TENURED;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000867 const Operator* op = javascript()->CreateClosure(shared_info, tenured);
868 Node* closure = NewNode(op);
869 environment()->BindAccumulator(closure);
870}
871
Ben Murdoch097c5b22016-05-18 11:27:45 +0100872void BytecodeGraphBuilder::BuildCreateArguments(CreateArgumentsType type) {
873 FrameStateBeforeAndAfter states(this);
874 const Operator* op = javascript()->CreateArguments(type);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000875 Node* object = NewNode(op, GetFunctionClosure());
876 environment()->BindAccumulator(object, &states);
877}
878
Ben Murdoch097c5b22016-05-18 11:27:45 +0100879void BytecodeGraphBuilder::VisitCreateMappedArguments() {
880 BuildCreateArguments(CreateArgumentsType::kMappedArguments);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000881}
882
Ben Murdoch097c5b22016-05-18 11:27:45 +0100883void BytecodeGraphBuilder::VisitCreateUnmappedArguments() {
884 BuildCreateArguments(CreateArgumentsType::kUnmappedArguments);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000885}
886
Ben Murdoch097c5b22016-05-18 11:27:45 +0100887void BytecodeGraphBuilder::VisitCreateRestParameter() {
888 BuildCreateArguments(CreateArgumentsType::kRestParameter);
889}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000890
Ben Murdoch097c5b22016-05-18 11:27:45 +0100891void BytecodeGraphBuilder::BuildCreateLiteral(const Operator* op) {
892 FrameStateBeforeAndAfter states(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000893 Node* literal = NewNode(op, GetFunctionClosure());
894 environment()->BindAccumulator(literal, &states);
895}
896
Ben Murdochda12d292016-06-02 14:46:10 +0100897void BytecodeGraphBuilder::VisitCreateRegExpLiteral() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000898 Handle<String> constant_pattern =
Ben Murdoch097c5b22016-05-18 11:27:45 +0100899 Handle<String>::cast(bytecode_iterator().GetConstantForIndexOperand(0));
900 int literal_index = bytecode_iterator().GetIndexOperand(1);
Ben Murdochda12d292016-06-02 14:46:10 +0100901 int literal_flags = bytecode_iterator().GetFlagOperand(2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000902 const Operator* op = javascript()->CreateLiteralRegExp(
903 constant_pattern, literal_flags, literal_index);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100904 BuildCreateLiteral(op);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000905}
906
Ben Murdochda12d292016-06-02 14:46:10 +0100907void BytecodeGraphBuilder::VisitCreateArrayLiteral() {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100908 Handle<FixedArray> constant_elements = Handle<FixedArray>::cast(
909 bytecode_iterator().GetConstantForIndexOperand(0));
910 int literal_index = bytecode_iterator().GetIndexOperand(1);
Ben Murdochda12d292016-06-02 14:46:10 +0100911 int literal_flags = bytecode_iterator().GetFlagOperand(2);
912 int number_of_elements = constant_elements->length();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000913 const Operator* op = javascript()->CreateLiteralArray(
Ben Murdochda12d292016-06-02 14:46:10 +0100914 constant_elements, literal_flags, literal_index, number_of_elements);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100915 BuildCreateLiteral(op);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000916}
917
Ben Murdoch097c5b22016-05-18 11:27:45 +0100918void BytecodeGraphBuilder::VisitCreateObjectLiteral() {
Ben Murdochda12d292016-06-02 14:46:10 +0100919 Handle<FixedArray> constant_properties = Handle<FixedArray>::cast(
920 bytecode_iterator().GetConstantForIndexOperand(0));
921 int literal_index = bytecode_iterator().GetIndexOperand(1);
Ben Murdochc5610432016-08-08 18:44:38 +0100922 int bytecode_flags = bytecode_iterator().GetFlagOperand(2);
923 int literal_flags =
924 interpreter::CreateObjectLiteralFlags::FlagsBits::decode(bytecode_flags);
Ben Murdochda12d292016-06-02 14:46:10 +0100925 // TODO(mstarzinger): Thread through number of properties.
926 int number_of_properties = constant_properties->length() / 2;
927 const Operator* op = javascript()->CreateLiteralObject(
928 constant_properties, literal_flags, literal_index, number_of_properties);
929 BuildCreateLiteral(op);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000930}
931
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000932Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op,
933 Node* callee,
934 interpreter::Register receiver,
935 size_t arity) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100936 Node** all = local_zone()->NewArray<Node*>(static_cast<int>(arity));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000937 all[0] = callee;
938 all[1] = environment()->LookupRegister(receiver);
939 int receiver_index = receiver.index();
940 for (int i = 2; i < static_cast<int>(arity); ++i) {
941 all[i] = environment()->LookupRegister(
942 interpreter::Register(receiver_index + i - 1));
943 }
944 Node* value = MakeNode(call_op, static_cast<int>(arity), all, false);
945 return value;
946}
947
Ben Murdoch097c5b22016-05-18 11:27:45 +0100948void BytecodeGraphBuilder::BuildCall(TailCallMode tail_call_mode) {
949 FrameStateBeforeAndAfter states(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000950 // TODO(rmcilroy): Set receiver_hint correctly based on whether the receiver
951 // register has been loaded with null / undefined explicitly or we are sure it
952 // is not null / undefined.
953 ConvertReceiverMode receiver_hint = ConvertReceiverMode::kAny;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100954 Node* callee =
955 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
956 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
957 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
958 VectorSlotPair feedback =
959 CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(3));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000960
961 const Operator* call = javascript()->CallFunction(
Ben Murdoch097c5b22016-05-18 11:27:45 +0100962 arg_count + 1, feedback, receiver_hint, tail_call_mode);
963 Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000964 environment()->BindAccumulator(value, &states);
965}
966
Ben Murdoch097c5b22016-05-18 11:27:45 +0100967void BytecodeGraphBuilder::VisitCall() { BuildCall(TailCallMode::kDisallow); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000968
Ben Murdochda12d292016-06-02 14:46:10 +0100969void BytecodeGraphBuilder::VisitTailCall() {
970 TailCallMode tail_call_mode =
971 bytecode_array_->GetIsolate()->is_tail_call_elimination_enabled()
972 ? TailCallMode::kAllow
973 : TailCallMode::kDisallow;
974 BuildCall(tail_call_mode);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000975}
976
Ben Murdochda12d292016-06-02 14:46:10 +0100977void BytecodeGraphBuilder::VisitCallJSRuntime() {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100978 FrameStateBeforeAndAfter states(this);
979 Node* callee =
980 BuildLoadNativeContextField(bytecode_iterator().GetIndexOperand(0));
981 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
982 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000983
984 // Create node to perform the JS runtime call.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100985 const Operator* call = javascript()->CallFunction(arg_count + 1);
986 Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000987 environment()->BindAccumulator(value, &states);
988}
989
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000990Node* BytecodeGraphBuilder::ProcessCallRuntimeArguments(
991 const Operator* call_runtime_op, interpreter::Register first_arg,
992 size_t arity) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100993 Node** all = local_zone()->NewArray<Node*>(arity);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000994 int first_arg_index = first_arg.index();
995 for (int i = 0; i < static_cast<int>(arity); ++i) {
996 all[i] = environment()->LookupRegister(
997 interpreter::Register(first_arg_index + i));
998 }
999 Node* value = MakeNode(call_runtime_op, static_cast<int>(arity), all, false);
1000 return value;
1001}
1002
Ben Murdochda12d292016-06-02 14:46:10 +01001003void BytecodeGraphBuilder::VisitCallRuntime() {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001004 FrameStateBeforeAndAfter states(this);
Ben Murdoch61f157c2016-09-16 13:49:30 +01001005 Runtime::FunctionId functionId = bytecode_iterator().GetRuntimeIdOperand(0);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001006 interpreter::Register first_arg = bytecode_iterator().GetRegisterOperand(1);
1007 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001008
1009 // Create node to perform the runtime call.
1010 const Operator* call = javascript()->CallRuntime(functionId, arg_count);
1011 Node* value = ProcessCallRuntimeArguments(call, first_arg, arg_count);
1012 environment()->BindAccumulator(value, &states);
1013}
1014
Ben Murdochda12d292016-06-02 14:46:10 +01001015void BytecodeGraphBuilder::VisitCallRuntimeForPair() {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001016 FrameStateBeforeAndAfter states(this);
Ben Murdoch61f157c2016-09-16 13:49:30 +01001017 Runtime::FunctionId functionId = bytecode_iterator().GetRuntimeIdOperand(0);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001018 interpreter::Register first_arg = bytecode_iterator().GetRegisterOperand(1);
1019 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
1020 interpreter::Register first_return =
1021 bytecode_iterator().GetRegisterOperand(3);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001022
1023 // Create node to perform the runtime call.
1024 const Operator* call = javascript()->CallRuntime(functionId, arg_count);
1025 Node* return_pair = ProcessCallRuntimeArguments(call, first_arg, arg_count);
1026 environment()->BindRegistersToProjections(first_return, return_pair, &states);
1027}
1028
Ben Murdochda12d292016-06-02 14:46:10 +01001029void BytecodeGraphBuilder::VisitInvokeIntrinsic() {
1030 FrameStateBeforeAndAfter states(this);
Ben Murdoch61f157c2016-09-16 13:49:30 +01001031 Runtime::FunctionId functionId = bytecode_iterator().GetIntrinsicIdOperand(0);
Ben Murdochda12d292016-06-02 14:46:10 +01001032 interpreter::Register first_arg = bytecode_iterator().GetRegisterOperand(1);
1033 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001034
Ben Murdochda12d292016-06-02 14:46:10 +01001035 // Create node to perform the runtime call. Turbofan will take care of the
1036 // lowering.
1037 const Operator* call = javascript()->CallRuntime(functionId, arg_count);
1038 Node* value = ProcessCallRuntimeArguments(call, first_arg, arg_count);
1039 environment()->BindAccumulator(value, &states);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001040}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001041
1042Node* BytecodeGraphBuilder::ProcessCallNewArguments(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001043 const Operator* call_new_op, Node* callee, Node* new_target,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001044 interpreter::Register first_arg, size_t arity) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001045 Node** all = local_zone()->NewArray<Node*>(arity);
1046 all[0] = new_target;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001047 int first_arg_index = first_arg.index();
1048 for (int i = 1; i < static_cast<int>(arity) - 1; ++i) {
1049 all[i] = environment()->LookupRegister(
1050 interpreter::Register(first_arg_index + i - 1));
1051 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01001052 all[arity - 1] = callee;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001053 Node* value = MakeNode(call_new_op, static_cast<int>(arity), all, false);
1054 return value;
1055}
1056
Ben Murdochda12d292016-06-02 14:46:10 +01001057void BytecodeGraphBuilder::VisitNew() {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001058 FrameStateBeforeAndAfter states(this);
1059 interpreter::Register callee_reg = bytecode_iterator().GetRegisterOperand(0);
1060 interpreter::Register first_arg = bytecode_iterator().GetRegisterOperand(1);
1061 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001062
Ben Murdoch097c5b22016-05-18 11:27:45 +01001063 Node* new_target = environment()->LookupAccumulator();
1064 Node* callee = environment()->LookupRegister(callee_reg);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001065 // TODO(turbofan): Pass the feedback here.
1066 const Operator* call = javascript()->CallConstruct(
1067 static_cast<int>(arg_count) + 2, VectorSlotPair());
Ben Murdoch097c5b22016-05-18 11:27:45 +01001068 Node* value = ProcessCallNewArguments(call, callee, new_target, first_arg,
1069 arg_count + 2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001070 environment()->BindAccumulator(value, &states);
1071}
1072
Ben Murdoch097c5b22016-05-18 11:27:45 +01001073void BytecodeGraphBuilder::BuildThrow() {
1074 FrameStateBeforeAndAfter states(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001075 Node* value = environment()->LookupAccumulator();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001076 Node* call = NewNode(javascript()->CallRuntime(Runtime::kThrow), value);
1077 environment()->BindAccumulator(call, &states);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001078}
1079
Ben Murdoch097c5b22016-05-18 11:27:45 +01001080void BytecodeGraphBuilder::VisitThrow() {
1081 BuildThrow();
1082 Node* call = environment()->LookupAccumulator();
1083 Node* control = NewNode(common()->Throw(), call);
1084 MergeControlToLeaveFunction(control);
1085}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001086
Ben Murdoch097c5b22016-05-18 11:27:45 +01001087void BytecodeGraphBuilder::VisitReThrow() {
1088 Node* value = environment()->LookupAccumulator();
1089 Node* call = NewNode(javascript()->CallRuntime(Runtime::kReThrow), value);
1090 Node* control = NewNode(common()->Throw(), call);
1091 MergeControlToLeaveFunction(control);
1092}
1093
1094void BytecodeGraphBuilder::BuildBinaryOp(const Operator* js_op) {
1095 FrameStateBeforeAndAfter states(this);
1096 Node* left =
1097 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001098 Node* right = environment()->LookupAccumulator();
1099 Node* node = NewNode(js_op, left, right);
1100 environment()->BindAccumulator(node, &states);
1101}
1102
Ben Murdoch097c5b22016-05-18 11:27:45 +01001103void BytecodeGraphBuilder::VisitAdd() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001104 BinaryOperationHints hints = BinaryOperationHints::Any();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001105 BuildBinaryOp(javascript()->Add(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001106}
1107
Ben Murdoch097c5b22016-05-18 11:27:45 +01001108void BytecodeGraphBuilder::VisitSub() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001109 BinaryOperationHints hints = BinaryOperationHints::Any();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001110 BuildBinaryOp(javascript()->Subtract(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001111}
1112
Ben Murdoch097c5b22016-05-18 11:27:45 +01001113void BytecodeGraphBuilder::VisitMul() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001114 BinaryOperationHints hints = BinaryOperationHints::Any();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001115 BuildBinaryOp(javascript()->Multiply(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001116}
1117
Ben Murdoch097c5b22016-05-18 11:27:45 +01001118void BytecodeGraphBuilder::VisitDiv() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001119 BinaryOperationHints hints = BinaryOperationHints::Any();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001120 BuildBinaryOp(javascript()->Divide(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001121}
1122
Ben Murdoch097c5b22016-05-18 11:27:45 +01001123void BytecodeGraphBuilder::VisitMod() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001124 BinaryOperationHints hints = BinaryOperationHints::Any();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001125 BuildBinaryOp(javascript()->Modulus(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001126}
1127
Ben Murdoch097c5b22016-05-18 11:27:45 +01001128void BytecodeGraphBuilder::VisitBitwiseOr() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001129 BinaryOperationHints hints = BinaryOperationHints::Any();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001130 BuildBinaryOp(javascript()->BitwiseOr(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001131}
1132
Ben Murdoch097c5b22016-05-18 11:27:45 +01001133void BytecodeGraphBuilder::VisitBitwiseXor() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001134 BinaryOperationHints hints = BinaryOperationHints::Any();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001135 BuildBinaryOp(javascript()->BitwiseXor(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001136}
1137
Ben Murdoch097c5b22016-05-18 11:27:45 +01001138void BytecodeGraphBuilder::VisitBitwiseAnd() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001139 BinaryOperationHints hints = BinaryOperationHints::Any();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001140 BuildBinaryOp(javascript()->BitwiseAnd(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001141}
1142
Ben Murdoch097c5b22016-05-18 11:27:45 +01001143void BytecodeGraphBuilder::VisitShiftLeft() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001144 BinaryOperationHints hints = BinaryOperationHints::Any();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001145 BuildBinaryOp(javascript()->ShiftLeft(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001146}
1147
Ben Murdoch097c5b22016-05-18 11:27:45 +01001148void BytecodeGraphBuilder::VisitShiftRight() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001149 BinaryOperationHints hints = BinaryOperationHints::Any();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001150 BuildBinaryOp(javascript()->ShiftRight(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001151}
1152
Ben Murdoch097c5b22016-05-18 11:27:45 +01001153void BytecodeGraphBuilder::VisitShiftRightLogical() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001154 BinaryOperationHints hints = BinaryOperationHints::Any();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001155 BuildBinaryOp(javascript()->ShiftRightLogical(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001156}
1157
Ben Murdoch097c5b22016-05-18 11:27:45 +01001158void BytecodeGraphBuilder::VisitInc() {
1159 FrameStateBeforeAndAfter states(this);
Ben Murdochc5610432016-08-08 18:44:38 +01001160 // Note: Use subtract -1 here instead of add 1 to ensure we always convert to
1161 // a number, not a string.
1162 const Operator* js_op = javascript()->Subtract(BinaryOperationHints::Any());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001163 Node* node = NewNode(js_op, environment()->LookupAccumulator(),
Ben Murdochc5610432016-08-08 18:44:38 +01001164 jsgraph()->Constant(-1.0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001165 environment()->BindAccumulator(node, &states);
1166}
1167
Ben Murdoch097c5b22016-05-18 11:27:45 +01001168void BytecodeGraphBuilder::VisitDec() {
1169 FrameStateBeforeAndAfter states(this);
1170 const Operator* js_op = javascript()->Subtract(BinaryOperationHints::Any());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001171 Node* node = NewNode(js_op, environment()->LookupAccumulator(),
1172 jsgraph()->OneConstant());
1173 environment()->BindAccumulator(node, &states);
1174}
1175
Ben Murdoch097c5b22016-05-18 11:27:45 +01001176void BytecodeGraphBuilder::VisitLogicalNot() {
Ben Murdochc5610432016-08-08 18:44:38 +01001177 Node* value = environment()->LookupAccumulator();
1178 Node* node = NewNode(common()->Select(MachineRepresentation::kTagged), value,
1179 jsgraph()->FalseConstant(), jsgraph()->TrueConstant());
1180 environment()->BindAccumulator(node);
1181}
1182
1183void BytecodeGraphBuilder::VisitToBooleanLogicalNot() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001184 Node* value = NewNode(javascript()->ToBoolean(ToBooleanHint::kAny),
1185 environment()->LookupAccumulator());
1186 Node* node = NewNode(common()->Select(MachineRepresentation::kTagged), value,
1187 jsgraph()->FalseConstant(), jsgraph()->TrueConstant());
1188 environment()->BindAccumulator(node);
1189}
1190
Ben Murdoch097c5b22016-05-18 11:27:45 +01001191void BytecodeGraphBuilder::VisitTypeOf() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001192 Node* node =
1193 NewNode(javascript()->TypeOf(), environment()->LookupAccumulator());
1194 environment()->BindAccumulator(node);
1195}
1196
Ben Murdoch097c5b22016-05-18 11:27:45 +01001197void BytecodeGraphBuilder::BuildDelete(LanguageMode language_mode) {
1198 FrameStateBeforeAndAfter states(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001199 Node* key = environment()->LookupAccumulator();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001200 Node* object =
1201 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001202 Node* node =
Ben Murdoch097c5b22016-05-18 11:27:45 +01001203 NewNode(javascript()->DeleteProperty(language_mode), object, key);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001204 environment()->BindAccumulator(node, &states);
1205}
1206
Ben Murdoch097c5b22016-05-18 11:27:45 +01001207void BytecodeGraphBuilder::VisitDeletePropertyStrict() {
1208 BuildDelete(LanguageMode::STRICT);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001209}
1210
Ben Murdoch097c5b22016-05-18 11:27:45 +01001211void BytecodeGraphBuilder::VisitDeletePropertySloppy() {
1212 BuildDelete(LanguageMode::SLOPPY);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001213}
1214
Ben Murdoch097c5b22016-05-18 11:27:45 +01001215void BytecodeGraphBuilder::BuildCompareOp(const Operator* js_op) {
1216 FrameStateBeforeAndAfter states(this);
1217 Node* left =
1218 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001219 Node* right = environment()->LookupAccumulator();
1220 Node* node = NewNode(js_op, left, right);
1221 environment()->BindAccumulator(node, &states);
1222}
1223
Ben Murdoch097c5b22016-05-18 11:27:45 +01001224void BytecodeGraphBuilder::VisitTestEqual() {
Ben Murdoch61f157c2016-09-16 13:49:30 +01001225 CompareOperationHints hints = CompareOperationHints::Any();
1226 BuildCompareOp(javascript()->Equal(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001227}
1228
Ben Murdoch097c5b22016-05-18 11:27:45 +01001229void BytecodeGraphBuilder::VisitTestNotEqual() {
Ben Murdoch61f157c2016-09-16 13:49:30 +01001230 CompareOperationHints hints = CompareOperationHints::Any();
1231 BuildCompareOp(javascript()->NotEqual(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001232}
1233
Ben Murdoch097c5b22016-05-18 11:27:45 +01001234void BytecodeGraphBuilder::VisitTestEqualStrict() {
Ben Murdoch61f157c2016-09-16 13:49:30 +01001235 CompareOperationHints hints = CompareOperationHints::Any();
1236 BuildCompareOp(javascript()->StrictEqual(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001237}
1238
Ben Murdoch097c5b22016-05-18 11:27:45 +01001239void BytecodeGraphBuilder::VisitTestLessThan() {
Ben Murdoch61f157c2016-09-16 13:49:30 +01001240 CompareOperationHints hints = CompareOperationHints::Any();
1241 BuildCompareOp(javascript()->LessThan(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001242}
1243
Ben Murdoch097c5b22016-05-18 11:27:45 +01001244void BytecodeGraphBuilder::VisitTestGreaterThan() {
Ben Murdoch61f157c2016-09-16 13:49:30 +01001245 CompareOperationHints hints = CompareOperationHints::Any();
1246 BuildCompareOp(javascript()->GreaterThan(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001247}
1248
Ben Murdoch097c5b22016-05-18 11:27:45 +01001249void BytecodeGraphBuilder::VisitTestLessThanOrEqual() {
Ben Murdoch61f157c2016-09-16 13:49:30 +01001250 CompareOperationHints hints = CompareOperationHints::Any();
1251 BuildCompareOp(javascript()->LessThanOrEqual(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001252}
1253
Ben Murdoch097c5b22016-05-18 11:27:45 +01001254void BytecodeGraphBuilder::VisitTestGreaterThanOrEqual() {
Ben Murdoch61f157c2016-09-16 13:49:30 +01001255 CompareOperationHints hints = CompareOperationHints::Any();
1256 BuildCompareOp(javascript()->GreaterThanOrEqual(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001257}
1258
Ben Murdoch097c5b22016-05-18 11:27:45 +01001259void BytecodeGraphBuilder::VisitTestIn() {
1260 BuildCompareOp(javascript()->HasProperty());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001261}
1262
Ben Murdoch097c5b22016-05-18 11:27:45 +01001263void BytecodeGraphBuilder::VisitTestInstanceOf() {
1264 BuildCompareOp(javascript()->InstanceOf());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001265}
1266
Ben Murdoch097c5b22016-05-18 11:27:45 +01001267void BytecodeGraphBuilder::BuildCastOperator(const Operator* js_op) {
1268 FrameStateBeforeAndAfter states(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001269 Node* node = NewNode(js_op, environment()->LookupAccumulator());
1270 environment()->BindAccumulator(node, &states);
1271}
1272
Ben Murdoch097c5b22016-05-18 11:27:45 +01001273void BytecodeGraphBuilder::VisitToName() {
1274 BuildCastOperator(javascript()->ToName());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001275}
1276
Ben Murdoch097c5b22016-05-18 11:27:45 +01001277void BytecodeGraphBuilder::VisitToObject() {
1278 BuildCastOperator(javascript()->ToObject());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001279}
1280
Ben Murdoch097c5b22016-05-18 11:27:45 +01001281void BytecodeGraphBuilder::VisitToNumber() {
1282 BuildCastOperator(javascript()->ToNumber());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001283}
1284
Ben Murdoch097c5b22016-05-18 11:27:45 +01001285void BytecodeGraphBuilder::VisitJump() { BuildJump(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001286
Ben Murdoch097c5b22016-05-18 11:27:45 +01001287void BytecodeGraphBuilder::VisitJumpConstant() { BuildJump(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001288
1289
Ben Murdoch097c5b22016-05-18 11:27:45 +01001290void BytecodeGraphBuilder::VisitJumpIfTrue() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001291 BuildJumpIfEqual(jsgraph()->TrueConstant());
1292}
1293
Ben Murdoch097c5b22016-05-18 11:27:45 +01001294void BytecodeGraphBuilder::VisitJumpIfTrueConstant() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001295 BuildJumpIfEqual(jsgraph()->TrueConstant());
1296}
1297
Ben Murdoch097c5b22016-05-18 11:27:45 +01001298void BytecodeGraphBuilder::VisitJumpIfFalse() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001299 BuildJumpIfEqual(jsgraph()->FalseConstant());
1300}
1301
Ben Murdoch097c5b22016-05-18 11:27:45 +01001302void BytecodeGraphBuilder::VisitJumpIfFalseConstant() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001303 BuildJumpIfEqual(jsgraph()->FalseConstant());
1304}
1305
Ben Murdoch097c5b22016-05-18 11:27:45 +01001306void BytecodeGraphBuilder::VisitJumpIfToBooleanTrue() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001307 BuildJumpIfToBooleanEqual(jsgraph()->TrueConstant());
1308}
1309
Ben Murdoch097c5b22016-05-18 11:27:45 +01001310void BytecodeGraphBuilder::VisitJumpIfToBooleanTrueConstant() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001311 BuildJumpIfToBooleanEqual(jsgraph()->TrueConstant());
1312}
1313
Ben Murdoch097c5b22016-05-18 11:27:45 +01001314void BytecodeGraphBuilder::VisitJumpIfToBooleanFalse() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001315 BuildJumpIfToBooleanEqual(jsgraph()->FalseConstant());
1316}
1317
Ben Murdoch097c5b22016-05-18 11:27:45 +01001318void BytecodeGraphBuilder::VisitJumpIfToBooleanFalseConstant() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001319 BuildJumpIfToBooleanEqual(jsgraph()->FalseConstant());
1320}
1321
Ben Murdoch097c5b22016-05-18 11:27:45 +01001322void BytecodeGraphBuilder::VisitJumpIfNotHole() { BuildJumpIfNotHole(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001323
Ben Murdoch097c5b22016-05-18 11:27:45 +01001324void BytecodeGraphBuilder::VisitJumpIfNotHoleConstant() {
1325 BuildJumpIfNotHole();
1326}
1327
Ben Murdoch097c5b22016-05-18 11:27:45 +01001328void BytecodeGraphBuilder::VisitJumpIfNull() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001329 BuildJumpIfEqual(jsgraph()->NullConstant());
1330}
1331
Ben Murdoch097c5b22016-05-18 11:27:45 +01001332void BytecodeGraphBuilder::VisitJumpIfNullConstant() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001333 BuildJumpIfEqual(jsgraph()->NullConstant());
1334}
1335
Ben Murdoch097c5b22016-05-18 11:27:45 +01001336void BytecodeGraphBuilder::VisitJumpIfUndefined() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001337 BuildJumpIfEqual(jsgraph()->UndefinedConstant());
1338}
1339
Ben Murdoch097c5b22016-05-18 11:27:45 +01001340void BytecodeGraphBuilder::VisitJumpIfUndefinedConstant() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001341 BuildJumpIfEqual(jsgraph()->UndefinedConstant());
1342}
1343
Ben Murdoch097c5b22016-05-18 11:27:45 +01001344void BytecodeGraphBuilder::VisitStackCheck() {
1345 FrameStateBeforeAndAfter states(this);
1346 Node* node = NewNode(javascript()->StackCheck());
1347 environment()->RecordAfterState(node, &states);
1348}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001349
Ben Murdoch097c5b22016-05-18 11:27:45 +01001350void BytecodeGraphBuilder::VisitReturn() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001351 Node* control =
1352 NewNode(common()->Return(), environment()->LookupAccumulator());
Ben Murdoch097c5b22016-05-18 11:27:45 +01001353 MergeControlToLeaveFunction(control);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001354}
1355
Ben Murdoch097c5b22016-05-18 11:27:45 +01001356void BytecodeGraphBuilder::VisitDebugger() {
1357 FrameStateBeforeAndAfter states(this);
1358 Node* call =
1359 NewNode(javascript()->CallRuntime(Runtime::kHandleDebuggerStatement));
1360 environment()->BindAccumulator(call, &states);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001361}
1362
Ben Murdoch097c5b22016-05-18 11:27:45 +01001363// We cannot create a graph from the debugger copy of the bytecode array.
1364#define DEBUG_BREAK(Name, ...) \
1365 void BytecodeGraphBuilder::Visit##Name() { UNREACHABLE(); }
1366DEBUG_BREAK_BYTECODE_LIST(DEBUG_BREAK);
1367#undef DEBUG_BREAK
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001368
Ben Murdoch097c5b22016-05-18 11:27:45 +01001369void BytecodeGraphBuilder::BuildForInPrepare() {
1370 FrameStateBeforeAndAfter states(this);
1371 Node* receiver = environment()->LookupAccumulator();
1372 Node* prepare = NewNode(javascript()->ForInPrepare(), receiver);
1373 environment()->BindRegistersToProjections(
1374 bytecode_iterator().GetRegisterOperand(0), prepare, &states);
1375}
1376
1377void BytecodeGraphBuilder::VisitForInPrepare() { BuildForInPrepare(); }
1378
Ben Murdoch097c5b22016-05-18 11:27:45 +01001379void BytecodeGraphBuilder::VisitForInDone() {
1380 FrameStateBeforeAndAfter states(this);
1381 Node* index =
1382 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001383 Node* cache_length =
Ben Murdoch097c5b22016-05-18 11:27:45 +01001384 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001385 Node* exit_cond = NewNode(javascript()->ForInDone(), index, cache_length);
1386 environment()->BindAccumulator(exit_cond, &states);
1387}
1388
Ben Murdoch097c5b22016-05-18 11:27:45 +01001389void BytecodeGraphBuilder::BuildForInNext() {
1390 FrameStateBeforeAndAfter states(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001391 Node* receiver =
Ben Murdoch097c5b22016-05-18 11:27:45 +01001392 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1393 Node* index =
1394 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
1395 int catch_reg_pair_index = bytecode_iterator().GetRegisterOperand(2).index();
1396 Node* cache_type = environment()->LookupRegister(
1397 interpreter::Register(catch_reg_pair_index));
1398 Node* cache_array = environment()->LookupRegister(
1399 interpreter::Register(catch_reg_pair_index + 1));
1400
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001401 Node* value = NewNode(javascript()->ForInNext(), receiver, cache_array,
1402 cache_type, index);
1403 environment()->BindAccumulator(value, &states);
1404}
1405
Ben Murdoch097c5b22016-05-18 11:27:45 +01001406void BytecodeGraphBuilder::VisitForInNext() { BuildForInNext(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001407
Ben Murdoch097c5b22016-05-18 11:27:45 +01001408void BytecodeGraphBuilder::VisitForInStep() {
1409 FrameStateBeforeAndAfter states(this);
1410 Node* index =
1411 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001412 index = NewNode(javascript()->ForInStep(), index);
1413 environment()->BindAccumulator(index, &states);
1414}
1415
Ben Murdochc5610432016-08-08 18:44:38 +01001416void BytecodeGraphBuilder::VisitSuspendGenerator() {
1417 Node* state = environment()->LookupAccumulator();
1418 Node* generator = environment()->LookupRegister(
1419 bytecode_iterator().GetRegisterOperand(0));
Ben Murdoch61f157c2016-09-16 13:49:30 +01001420 // The offsets used by the bytecode iterator are relative to a different base
1421 // than what is used in the interpreter, hence the addition.
1422 Node* offset =
1423 jsgraph()->Constant(bytecode_iterator().current_offset() +
1424 (BytecodeArray::kHeaderSize - kHeapObjectTag));
Ben Murdochc5610432016-08-08 18:44:38 +01001425
Ben Murdoch61f157c2016-09-16 13:49:30 +01001426 int register_count = environment()->register_count();
1427 int value_input_count = 3 + register_count;
1428
1429 Node** value_inputs = local_zone()->NewArray<Node*>(value_input_count);
1430 value_inputs[0] = generator;
1431 value_inputs[1] = state;
1432 value_inputs[2] = offset;
1433 for (int i = 0; i < register_count; ++i) {
1434 value_inputs[3 + i] =
1435 environment()->LookupRegister(interpreter::Register(i));
Ben Murdochc5610432016-08-08 18:44:38 +01001436 }
1437
Ben Murdoch61f157c2016-09-16 13:49:30 +01001438 MakeNode(javascript()->GeneratorStore(register_count), value_input_count,
1439 value_inputs, false);
Ben Murdochc5610432016-08-08 18:44:38 +01001440}
1441
1442void BytecodeGraphBuilder::VisitResumeGenerator() {
1443 FrameStateBeforeAndAfter states(this);
1444
1445 Node* generator = environment()->LookupRegister(
1446 bytecode_iterator().GetRegisterOperand(0));
Ben Murdochc5610432016-08-08 18:44:38 +01001447
1448 // Bijection between registers and array indices must match that used in
1449 // InterpreterAssembler::ExportRegisterFile.
1450 for (int i = 0; i < environment()->register_count(); ++i) {
Ben Murdoch61f157c2016-09-16 13:49:30 +01001451 Node* value = NewNode(javascript()->GeneratorRestoreRegister(i), generator);
Ben Murdochc5610432016-08-08 18:44:38 +01001452 environment()->BindRegister(interpreter::Register(i), value);
Ben Murdochc5610432016-08-08 18:44:38 +01001453 }
1454
Ben Murdoch61f157c2016-09-16 13:49:30 +01001455 Node* state =
1456 NewNode(javascript()->GeneratorRestoreContinuation(), generator);
Ben Murdochc5610432016-08-08 18:44:38 +01001457
1458 environment()->BindAccumulator(state, &states);
1459}
1460
Ben Murdochda12d292016-06-02 14:46:10 +01001461void BytecodeGraphBuilder::VisitWide() {
1462 // Consumed by the BytecodeArrayIterator.
1463 UNREACHABLE();
1464}
1465
1466void BytecodeGraphBuilder::VisitExtraWide() {
1467 // Consumed by the BytecodeArrayIterator.
1468 UNREACHABLE();
1469}
1470
1471void BytecodeGraphBuilder::VisitIllegal() {
Ben Murdochc5610432016-08-08 18:44:38 +01001472 // Not emitted in valid bytecode.
Ben Murdochda12d292016-06-02 14:46:10 +01001473 UNREACHABLE();
1474}
1475
Ben Murdochc5610432016-08-08 18:44:38 +01001476void BytecodeGraphBuilder::VisitNop() {}
1477
Ben Murdoch097c5b22016-05-18 11:27:45 +01001478void BytecodeGraphBuilder::SwitchToMergeEnvironment(int current_offset) {
1479 if (merge_environments_[current_offset] != nullptr) {
1480 if (environment() != nullptr) {
1481 merge_environments_[current_offset]->Merge(environment());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001482 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01001483 set_environment(merge_environments_[current_offset]);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001484 }
1485}
1486
Ben Murdoch097c5b22016-05-18 11:27:45 +01001487void BytecodeGraphBuilder::BuildLoopHeaderEnvironment(int current_offset) {
1488 if (branch_analysis()->backward_branches_target(current_offset)) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001489 // Add loop header and store a copy so we can connect merged back
1490 // edge inputs to the loop header.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001491 merge_environments_[current_offset] = environment()->CopyForLoop();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001492 }
1493}
1494
Ben Murdoch097c5b22016-05-18 11:27:45 +01001495void BytecodeGraphBuilder::MergeIntoSuccessorEnvironment(int target_offset) {
1496 if (merge_environments_[target_offset] == nullptr) {
1497 // Append merge nodes to the environment. We may merge here with another
1498 // environment. So add a place holder for merge nodes. We may add redundant
1499 // but will be eliminated in a later pass.
1500 // TODO(mstarzinger): Be smarter about this!
1501 NewMerge();
1502 merge_environments_[target_offset] = environment();
1503 } else {
1504 merge_environments_[target_offset]->Merge(environment());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001505 }
1506 set_environment(nullptr);
1507}
1508
Ben Murdoch097c5b22016-05-18 11:27:45 +01001509void BytecodeGraphBuilder::MergeControlToLeaveFunction(Node* exit) {
1510 exit_controls_.push_back(exit);
1511 set_environment(nullptr);
1512}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001513
1514void BytecodeGraphBuilder::BuildJump() {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001515 MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001516}
1517
1518
1519void BytecodeGraphBuilder::BuildConditionalJump(Node* condition) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001520 NewBranch(condition);
1521 Environment* if_false_environment = environment()->CopyForConditional();
1522 NewIfTrue();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001523 MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001524 set_environment(if_false_environment);
1525 NewIfFalse();
1526}
1527
1528
1529void BytecodeGraphBuilder::BuildJumpIfEqual(Node* comperand) {
1530 Node* accumulator = environment()->LookupAccumulator();
1531 Node* condition =
Ben Murdoch61f157c2016-09-16 13:49:30 +01001532 NewNode(javascript()->StrictEqual(CompareOperationHints::Any()),
1533 accumulator, comperand);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001534 BuildConditionalJump(condition);
1535}
1536
1537
1538void BytecodeGraphBuilder::BuildJumpIfToBooleanEqual(Node* comperand) {
1539 Node* accumulator = environment()->LookupAccumulator();
1540 Node* to_boolean =
1541 NewNode(javascript()->ToBoolean(ToBooleanHint::kAny), accumulator);
Ben Murdoch61f157c2016-09-16 13:49:30 +01001542 Node* condition =
1543 NewNode(javascript()->StrictEqual(CompareOperationHints::Any()),
1544 to_boolean, comperand);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001545 BuildConditionalJump(condition);
1546}
1547
Ben Murdoch097c5b22016-05-18 11:27:45 +01001548void BytecodeGraphBuilder::BuildJumpIfNotHole() {
1549 Node* accumulator = environment()->LookupAccumulator();
Ben Murdoch61f157c2016-09-16 13:49:30 +01001550 Node* condition =
1551 NewNode(javascript()->StrictEqual(CompareOperationHints::Any()),
1552 accumulator, jsgraph()->TheHoleConstant());
Ben Murdoch097c5b22016-05-18 11:27:45 +01001553 Node* node =
1554 NewNode(common()->Select(MachineRepresentation::kTagged), condition,
1555 jsgraph()->FalseConstant(), jsgraph()->TrueConstant());
1556 BuildConditionalJump(node);
1557}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001558
1559Node** BytecodeGraphBuilder::EnsureInputBufferSize(int size) {
1560 if (size > input_buffer_size_) {
1561 size = size + kInputBufferSizeIncrement + input_buffer_size_;
1562 input_buffer_ = local_zone()->NewArray<Node*>(size);
1563 input_buffer_size_ = size;
1564 }
1565 return input_buffer_;
1566}
1567
Ben Murdoch097c5b22016-05-18 11:27:45 +01001568void BytecodeGraphBuilder::EnterAndExitExceptionHandlers(int current_offset) {
1569 Handle<HandlerTable> table = exception_handler_table();
1570 int num_entries = table->NumberOfRangeEntries();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001571
Ben Murdoch097c5b22016-05-18 11:27:45 +01001572 // Potentially exit exception handlers.
1573 while (!exception_handlers_.empty()) {
1574 int current_end = exception_handlers_.top().end_offset_;
1575 if (current_offset < current_end) break; // Still covered by range.
1576 exception_handlers_.pop();
1577 }
1578
1579 // Potentially enter exception handlers.
1580 while (current_exception_handler_ < num_entries) {
1581 int next_start = table->GetRangeStart(current_exception_handler_);
1582 if (current_offset < next_start) break; // Not yet covered by range.
1583 int next_end = table->GetRangeEnd(current_exception_handler_);
1584 int next_handler = table->GetRangeHandler(current_exception_handler_);
1585 int context_register = table->GetRangeData(current_exception_handler_);
1586 CatchPrediction pred =
1587 table->GetRangePrediction(current_exception_handler_);
1588 exception_handlers_.push(
1589 {next_start, next_end, next_handler, context_register, pred});
1590 current_exception_handler_++;
1591 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001592}
1593
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001594Node* BytecodeGraphBuilder::MakeNode(const Operator* op, int value_input_count,
1595 Node** value_inputs, bool incomplete) {
1596 DCHECK_EQ(op->ValueInputCount(), value_input_count);
1597
1598 bool has_context = OperatorProperties::HasContextInput(op);
1599 int frame_state_count = OperatorProperties::GetFrameStateInputCount(op);
1600 bool has_control = op->ControlInputCount() == 1;
1601 bool has_effect = op->EffectInputCount() == 1;
1602
1603 DCHECK_LT(op->ControlInputCount(), 2);
1604 DCHECK_LT(op->EffectInputCount(), 2);
1605
1606 Node* result = nullptr;
1607 if (!has_context && frame_state_count == 0 && !has_control && !has_effect) {
1608 result = graph()->NewNode(op, value_input_count, value_inputs, incomplete);
1609 } else {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001610 bool inside_handler = !exception_handlers_.empty();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001611 int input_count_with_deps = value_input_count;
1612 if (has_context) ++input_count_with_deps;
1613 input_count_with_deps += frame_state_count;
1614 if (has_control) ++input_count_with_deps;
1615 if (has_effect) ++input_count_with_deps;
1616 Node** buffer = EnsureInputBufferSize(input_count_with_deps);
1617 memcpy(buffer, value_inputs, kPointerSize * value_input_count);
1618 Node** current_input = buffer + value_input_count;
1619 if (has_context) {
1620 *current_input++ = environment()->Context();
1621 }
1622 for (int i = 0; i < frame_state_count; i++) {
1623 // The frame state will be inserted later. Here we misuse
1624 // the {Dead} node as a sentinel to be later overwritten
1625 // with the real frame state.
1626 *current_input++ = jsgraph()->Dead();
1627 }
1628 if (has_effect) {
1629 *current_input++ = environment()->GetEffectDependency();
1630 }
1631 if (has_control) {
1632 *current_input++ = environment()->GetControlDependency();
1633 }
1634 result = graph()->NewNode(op, input_count_with_deps, buffer, incomplete);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001635 // Update the current control dependency for control-producing nodes.
1636 if (NodeProperties::IsControl(result)) {
1637 environment()->UpdateControlDependency(result);
1638 }
1639 // Update the current effect dependency for effect-producing nodes.
1640 if (result->op()->EffectOutputCount() > 0) {
1641 environment()->UpdateEffectDependency(result);
1642 }
1643 // Add implicit exception continuation for throwing nodes.
1644 if (!result->op()->HasProperty(Operator::kNoThrow) && inside_handler) {
1645 int handler_offset = exception_handlers_.top().handler_offset_;
1646 int context_index = exception_handlers_.top().context_register_;
1647 CatchPrediction prediction = exception_handlers_.top().pred_;
1648 interpreter::Register context_register(context_index);
1649 IfExceptionHint hint = prediction == CatchPrediction::CAUGHT
1650 ? IfExceptionHint::kLocallyCaught
1651 : IfExceptionHint::kLocallyUncaught;
1652 Environment* success_env = environment()->CopyForConditional();
1653 const Operator* op = common()->IfException(hint);
1654 Node* effect = environment()->GetEffectDependency();
1655 Node* on_exception = graph()->NewNode(op, effect, result);
1656 Node* context = environment()->LookupRegister(context_register);
1657 environment()->UpdateControlDependency(on_exception);
1658 environment()->UpdateEffectDependency(on_exception);
1659 environment()->BindAccumulator(on_exception);
1660 environment()->SetContext(context);
1661 MergeIntoSuccessorEnvironment(handler_offset);
1662 set_environment(success_env);
1663 }
1664 // Add implicit success continuation for throwing nodes.
1665 if (!result->op()->HasProperty(Operator::kNoThrow)) {
1666 const Operator* if_success = common()->IfSuccess();
1667 Node* on_success = graph()->NewNode(if_success, result);
1668 environment()->UpdateControlDependency(on_success);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001669 }
1670 }
1671
1672 return result;
1673}
1674
1675
1676Node* BytecodeGraphBuilder::NewPhi(int count, Node* input, Node* control) {
1677 const Operator* phi_op = common()->Phi(MachineRepresentation::kTagged, count);
1678 Node** buffer = EnsureInputBufferSize(count + 1);
1679 MemsetPointer(buffer, input, count);
1680 buffer[count] = control;
1681 return graph()->NewNode(phi_op, count + 1, buffer, true);
1682}
1683
1684
1685Node* BytecodeGraphBuilder::NewEffectPhi(int count, Node* input,
1686 Node* control) {
1687 const Operator* phi_op = common()->EffectPhi(count);
1688 Node** buffer = EnsureInputBufferSize(count + 1);
1689 MemsetPointer(buffer, input, count);
1690 buffer[count] = control;
1691 return graph()->NewNode(phi_op, count + 1, buffer, true);
1692}
1693
1694
1695Node* BytecodeGraphBuilder::MergeControl(Node* control, Node* other) {
1696 int inputs = control->op()->ControlInputCount() + 1;
1697 if (control->opcode() == IrOpcode::kLoop) {
1698 // Control node for loop exists, add input.
1699 const Operator* op = common()->Loop(inputs);
1700 control->AppendInput(graph_zone(), other);
1701 NodeProperties::ChangeOp(control, op);
1702 } else if (control->opcode() == IrOpcode::kMerge) {
1703 // Control node for merge exists, add input.
1704 const Operator* op = common()->Merge(inputs);
1705 control->AppendInput(graph_zone(), other);
1706 NodeProperties::ChangeOp(control, op);
1707 } else {
1708 // Control node is a singleton, introduce a merge.
1709 const Operator* op = common()->Merge(inputs);
1710 Node* merge_inputs[] = {control, other};
1711 control = graph()->NewNode(op, arraysize(merge_inputs), merge_inputs, true);
1712 }
1713 return control;
1714}
1715
1716
1717Node* BytecodeGraphBuilder::MergeEffect(Node* value, Node* other,
1718 Node* control) {
1719 int inputs = control->op()->ControlInputCount();
1720 if (value->opcode() == IrOpcode::kEffectPhi &&
1721 NodeProperties::GetControlInput(value) == control) {
1722 // Phi already exists, add input.
1723 value->InsertInput(graph_zone(), inputs - 1, other);
1724 NodeProperties::ChangeOp(value, common()->EffectPhi(inputs));
1725 } else if (value != other) {
1726 // Phi does not exist yet, introduce one.
1727 value = NewEffectPhi(inputs, value, control);
1728 value->ReplaceInput(inputs - 1, other);
1729 }
1730 return value;
1731}
1732
1733
1734Node* BytecodeGraphBuilder::MergeValue(Node* value, Node* other,
1735 Node* control) {
1736 int inputs = control->op()->ControlInputCount();
1737 if (value->opcode() == IrOpcode::kPhi &&
1738 NodeProperties::GetControlInput(value) == control) {
1739 // Phi already exists, add input.
1740 value->InsertInput(graph_zone(), inputs - 1, other);
1741 NodeProperties::ChangeOp(
1742 value, common()->Phi(MachineRepresentation::kTagged, inputs));
1743 } else if (value != other) {
1744 // Phi does not exist yet, introduce one.
1745 value = NewPhi(inputs, value, control);
1746 value->ReplaceInput(inputs - 1, other);
1747 }
1748 return value;
1749}
1750
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001751} // namespace compiler
1752} // namespace internal
1753} // namespace v8