• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // 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 
12 namespace v8 {
13 namespace internal {
14 namespace compiler {
15 
16 // 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.
19 class BytecodeGraphBuilder::Environment : public ZoneObject {
20  public:
21   Environment(BytecodeGraphBuilder* builder, int register_count,
22               int parameter_count, Node* control_dependency, Node* context);
23 
parameter_count() const24   int parameter_count() const { return parameter_count_; }
register_count() const25   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.
GetEffectDependency()38   Node* GetEffectDependency() { return effect_dependency_; }
UpdateEffectDependency(Node * 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.
GetControlDependency() const52   Node* GetControlDependency() const { return control_dependency_; }
UpdateControlDependency(Node * dependency)53   void UpdateControlDependency(Node* dependency) {
54     control_dependency_ = dependency;
55   }
56 
Context() const57   Node* Context() const { return context_; }
SetContext(Node * new_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 
zone() const74   Zone* zone() const { return builder_->local_zone(); }
graph() const75   Graph* graph() const { return builder_->graph(); }
common() const76   CommonOperatorBuilder* common() const { return builder_->common(); }
builder() const77   BytecodeGraphBuilder* builder() const { return builder_; }
values() const78   const NodeVector* values() const { return &values_; }
values()79   NodeVector* values() { return &values_; }
register_base() const80   int register_base() const { return register_base_; }
accumulator_base() const81   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 
97 // Helper for generating frame states for before and after a bytecode.
98 class BytecodeGraphBuilder::FrameStateBeforeAndAfter {
99  public:
FrameStateBeforeAndAfter(BytecodeGraphBuilder * builder)100   explicit FrameStateBeforeAndAfter(BytecodeGraphBuilder* builder)
101       : builder_(builder),
102         id_after_(BailoutId::None()),
103         added_to_node_(false),
104         frame_states_unused_(false),
105         output_poke_offset_(0),
106         output_poke_count_(0) {
107     BailoutId id_before(builder->bytecode_iterator().current_offset());
108     frame_state_before_ = builder_->environment()->Checkpoint(
109         id_before, OutputFrameStateCombine::Ignore());
110     id_after_ = BailoutId(id_before.ToInt() +
111                           builder->bytecode_iterator().current_bytecode_size());
112     // 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_);
117   }
118 
~FrameStateBeforeAndAfter()119   ~FrameStateBeforeAndAfter() {
120     DCHECK(added_to_node_);
121     DCHECK(frame_states_unused_ ||
122            builder_->environment()->StateValuesAreUpToDate(output_poke_offset_,
123                                                            output_poke_count_));
124   }
125 
126  private:
127   friend class Environment;
128 
AddToNode(Node * node,OutputFrameStateCombine combine)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.
144       // TODO(mstarzinger): Get rid of frame state input before!
145       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     }
154     frame_states_unused_ = count == 0;
155     added_to_node_ = true;
156   }
157 
158   BytecodeGraphBuilder* builder_;
159   Node* frame_state_before_;
160   BailoutId id_after_;
161 
162   bool added_to_node_;
163   bool frame_states_unused_;
164   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.
Environment(BytecodeGraphBuilder * builder,int register_count,int parameter_count,Node * control_dependency,Node * context)172 BytecodeGraphBuilder::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 
Environment(const BytecodeGraphBuilder::Environment * other)214 BytecodeGraphBuilder::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 
RegisterToValuesIndex(interpreter::Register the_register) const232 int 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 
LookupAccumulator() const242 Node* BytecodeGraphBuilder::Environment::LookupAccumulator() const {
243   return values()->at(accumulator_base_);
244 }
245 
246 
LookupRegister(interpreter::Register the_register) const247 Node* BytecodeGraphBuilder::Environment::LookupRegister(
248     interpreter::Register the_register) const {
249   if (the_register.is_current_context()) {
250     return Context();
251   } 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 
BindAccumulator(Node * node,FrameStateBeforeAndAfter * states)262 void 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 
BindRegister(interpreter::Register the_register,Node * node,FrameStateBeforeAndAfter * states)271 void 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 
BindRegistersToProjections(interpreter::Register first_reg,Node * node,FrameStateBeforeAndAfter * states)283 void 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 
RecordAfterState(Node * node,FrameStateBeforeAndAfter * states)298 void BytecodeGraphBuilder::Environment::RecordAfterState(
299     Node* node, FrameStateBeforeAndAfter* states) {
300   states->AddToNode(node, OutputFrameStateCombine::Ignore());
301 }
302 
303 
304 BytecodeGraphBuilder::Environment*
CopyForLoop()305 BytecodeGraphBuilder::Environment::CopyForLoop() {
306   PrepareForLoop();
307   return new (zone()) Environment(this);
308 }
309 
310 
311 BytecodeGraphBuilder::Environment*
CopyForConditional() const312 BytecodeGraphBuilder::Environment::CopyForConditional() const {
313   return new (zone()) Environment(this);
314 }
315 
316 
Merge(BytecodeGraphBuilder::Environment * other)317 void BytecodeGraphBuilder::Environment::Merge(
318     BytecodeGraphBuilder::Environment* other) {
319   // 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 
PrepareForLoop()340 void 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 
StateValuesRequireUpdate(Node ** state_values,int offset,int count)362 bool BytecodeGraphBuilder::Environment::StateValuesRequireUpdate(
363     Node** state_values, int offset, int count) {
364   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 
UpdateStateValues(Node ** state_values,int offset,int count)379 void 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 
Checkpoint(BailoutId bailout_id,OutputFrameStateCombine combine)389 Node* BytecodeGraphBuilder::Environment::Checkpoint(
390     BailoutId bailout_id, OutputFrameStateCombine combine) {
391   // 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 
StateValuesAreUpToDate(Node ** state_values,int offset,int count,int output_poke_start,int output_poke_end)408 bool 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 
StateValuesAreUpToDate(int output_poke_offset,int output_poke_count)423 bool 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 
BytecodeGraphBuilder(Zone * local_zone,CompilationInfo * info,JSGraph * jsgraph)437 BytecodeGraphBuilder::BytecodeGraphBuilder(Zone* local_zone,
438                                            CompilationInfo* info,
439                                            JSGraph* jsgraph)
440     : local_zone_(local_zone),
441       jsgraph_(jsgraph),
442       bytecode_array_(handle(info->shared_info()->bytecode_array())),
443       exception_handler_table_(
444           handle(HandlerTable::cast(bytecode_array()->handler_table()))),
445       feedback_vector_(handle(info->closure()->feedback_vector())),
446       frame_state_function_info_(common()->CreateFrameStateFunctionInfo(
447           FrameStateType::kInterpretedFunction,
448           bytecode_array()->parameter_count(),
449           bytecode_array()->register_count(), info->shared_info())),
450       merge_environments_(local_zone),
451       exception_handlers_(local_zone),
452       current_exception_handler_(0),
453       input_buffer_size_(0),
454       input_buffer_(nullptr),
455       exit_controls_(local_zone) {}
456 
GetNewTarget()457 Node* 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 
GetFunctionContext()469 Node* 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 
GetFunctionClosure()481 Node* 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 
BuildLoadNativeContextField(int index)492 Node* 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 
CreateVectorSlotPair(int slot_id)500 VectorSlotPair BytecodeGraphBuilder::CreateVectorSlotPair(int slot_id) {
501   FeedbackVectorSlot slot;
502   if (slot_id >= TypeFeedbackVector::kReservedIndexCount) {
503     slot = feedback_vector()->ToSlot(slot_id);
504   }
505   return VectorSlotPair(feedback_vector(), slot);
506 }
507 
CreateGraph()508 bool BytecodeGraphBuilder::CreateGraph() {
509   // 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 
524   VisitBytecodes();
525 
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 
VisitBytecodes()536 void 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();
544     EnterAndExitExceptionHandlers(current_offset);
545     SwitchToMergeEnvironment(current_offset);
546     if (environment() != nullptr) {
547       BuildLoopHeaderEnvironment(current_offset);
548 
549       switch (iterator.current_bytecode()) {
550 #define BYTECODE_CASE(name, ...)       \
551   case interpreter::Bytecode::k##name: \
552     Visit##name();                     \
553     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);
562   DCHECK(exception_handlers_.empty());
563 }
564 
VisitLdaZero()565 void BytecodeGraphBuilder::VisitLdaZero() {
566   Node* node = jsgraph()->ZeroConstant();
567   environment()->BindAccumulator(node);
568 }
569 
VisitLdaSmi()570 void BytecodeGraphBuilder::VisitLdaSmi() {
571   Node* node = jsgraph()->Constant(bytecode_iterator().GetImmediateOperand(0));
572   environment()->BindAccumulator(node);
573 }
574 
VisitLdaConstant()575 void BytecodeGraphBuilder::VisitLdaConstant() {
576   Node* node =
577       jsgraph()->Constant(bytecode_iterator().GetConstantForIndexOperand(0));
578   environment()->BindAccumulator(node);
579 }
580 
VisitLdaUndefined()581 void BytecodeGraphBuilder::VisitLdaUndefined() {
582   Node* node = jsgraph()->UndefinedConstant();
583   environment()->BindAccumulator(node);
584 }
585 
VisitLdrUndefined()586 void BytecodeGraphBuilder::VisitLdrUndefined() {
587   Node* node = jsgraph()->UndefinedConstant();
588   environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0), node);
589 }
590 
VisitLdaNull()591 void BytecodeGraphBuilder::VisitLdaNull() {
592   Node* node = jsgraph()->NullConstant();
593   environment()->BindAccumulator(node);
594 }
595 
VisitLdaTheHole()596 void BytecodeGraphBuilder::VisitLdaTheHole() {
597   Node* node = jsgraph()->TheHoleConstant();
598   environment()->BindAccumulator(node);
599 }
600 
VisitLdaTrue()601 void BytecodeGraphBuilder::VisitLdaTrue() {
602   Node* node = jsgraph()->TrueConstant();
603   environment()->BindAccumulator(node);
604 }
605 
VisitLdaFalse()606 void BytecodeGraphBuilder::VisitLdaFalse() {
607   Node* node = jsgraph()->FalseConstant();
608   environment()->BindAccumulator(node);
609 }
610 
VisitLdar()611 void BytecodeGraphBuilder::VisitLdar() {
612   Node* value =
613       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
614   environment()->BindAccumulator(value);
615 }
616 
VisitStar()617 void BytecodeGraphBuilder::VisitStar() {
618   Node* value = environment()->LookupAccumulator();
619   environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0), value);
620 }
621 
VisitMov()622 void BytecodeGraphBuilder::VisitMov() {
623   Node* value =
624       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
625   environment()->BindRegister(bytecode_iterator().GetRegisterOperand(1), value);
626 }
627 
BuildLoadGlobal(TypeofMode typeof_mode)628 Node* BytecodeGraphBuilder::BuildLoadGlobal(TypeofMode typeof_mode) {
629   VectorSlotPair feedback =
630       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()));
634   const Operator* op = javascript()->LoadGlobal(name, feedback, typeof_mode);
635   return NewNode(op, GetFunctionClosure());
636 }
637 
VisitLdaGlobal()638 void BytecodeGraphBuilder::VisitLdaGlobal() {
639   FrameStateBeforeAndAfter states(this);
640   Node* node = BuildLoadGlobal(TypeofMode::NOT_INSIDE_TYPEOF);
641   environment()->BindAccumulator(node, &states);
642 }
643 
VisitLdrGlobal()644 void BytecodeGraphBuilder::VisitLdrGlobal() {
645   FrameStateBeforeAndAfter states(this);
646   Node* node = BuildLoadGlobal(TypeofMode::NOT_INSIDE_TYPEOF);
647   environment()->BindRegister(bytecode_iterator().GetRegisterOperand(1), node,
648                               &states);
649 }
650 
VisitLdaGlobalInsideTypeof()651 void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeof() {
652   FrameStateBeforeAndAfter states(this);
653   Node* node = BuildLoadGlobal(TypeofMode::INSIDE_TYPEOF);
654   environment()->BindAccumulator(node, &states);
655 }
656 
BuildStoreGlobal(LanguageMode language_mode)657 void BytecodeGraphBuilder::BuildStoreGlobal(LanguageMode language_mode) {
658   FrameStateBeforeAndAfter states(this);
659   Handle<Name> name =
660       Handle<Name>::cast(bytecode_iterator().GetConstantForIndexOperand(0));
661   VectorSlotPair feedback =
662       CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(1));
663   Node* value = environment()->LookupAccumulator();
664 
665   const Operator* op = javascript()->StoreGlobal(language_mode, name, feedback);
666   Node* node = NewNode(op, value, GetFunctionClosure());
667   environment()->RecordAfterState(node, &states);
668 }
669 
VisitStaGlobalSloppy()670 void BytecodeGraphBuilder::VisitStaGlobalSloppy() {
671   BuildStoreGlobal(LanguageMode::SLOPPY);
672 }
673 
VisitStaGlobalStrict()674 void BytecodeGraphBuilder::VisitStaGlobalStrict() {
675   BuildStoreGlobal(LanguageMode::STRICT);
676 }
677 
BuildLoadContextSlot()678 Node* BytecodeGraphBuilder::BuildLoadContextSlot() {
679   // 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.
685   const Operator* op = javascript()->LoadContext(
686       0, bytecode_iterator().GetIndexOperand(1), false);
687   Node* context =
688       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
689   return NewNode(op, context);
690 }
691 
VisitLdaContextSlot()692 void BytecodeGraphBuilder::VisitLdaContextSlot() {
693   Node* node = BuildLoadContextSlot();
694   environment()->BindAccumulator(node);
695 }
696 
VisitLdrContextSlot()697 void BytecodeGraphBuilder::VisitLdrContextSlot() {
698   Node* node = BuildLoadContextSlot();
699   environment()->BindRegister(bytecode_iterator().GetRegisterOperand(2), node);
700 }
701 
VisitStaContextSlot()702 void BytecodeGraphBuilder::VisitStaContextSlot() {
703   // 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 =
707       javascript()->StoreContext(0, bytecode_iterator().GetIndexOperand(1));
708   Node* context =
709       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
710   Node* value = environment()->LookupAccumulator();
711   NewNode(op, context, value);
712 }
713 
BuildLdaLookupSlot(TypeofMode typeof_mode)714 void 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);
723   environment()->BindAccumulator(value, &states);
724 }
725 
VisitLdaLookupSlot()726 void BytecodeGraphBuilder::VisitLdaLookupSlot() {
727   BuildLdaLookupSlot(TypeofMode::NOT_INSIDE_TYPEOF);
728 }
729 
VisitLdaLookupSlotInsideTypeof()730 void BytecodeGraphBuilder::VisitLdaLookupSlotInsideTypeof() {
731   BuildLdaLookupSlot(TypeofMode::INSIDE_TYPEOF);
732 }
733 
BuildStaLookupSlot(LanguageMode language_mode)734 void BytecodeGraphBuilder::BuildStaLookupSlot(LanguageMode language_mode) {
735   FrameStateBeforeAndAfter states(this);
736   Node* value = environment()->LookupAccumulator();
737   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);
743   environment()->BindAccumulator(store, &states);
744 }
745 
VisitStaLookupSlotSloppy()746 void BytecodeGraphBuilder::VisitStaLookupSlotSloppy() {
747   BuildStaLookupSlot(LanguageMode::SLOPPY);
748 }
749 
VisitStaLookupSlotStrict()750 void BytecodeGraphBuilder::VisitStaLookupSlotStrict() {
751   BuildStaLookupSlot(LanguageMode::STRICT);
752 }
753 
BuildNamedLoad()754 Node* BytecodeGraphBuilder::BuildNamedLoad() {
755   Node* object =
756       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
757   Handle<Name> name =
758       Handle<Name>::cast(bytecode_iterator().GetConstantForIndexOperand(1));
759   VectorSlotPair feedback =
760       CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(2));
761 
762   const Operator* op = javascript()->LoadNamed(name, feedback);
763   return NewNode(op, object, GetFunctionClosure());
764 }
765 
VisitLdaNamedProperty()766 void BytecodeGraphBuilder::VisitLdaNamedProperty() {
767   FrameStateBeforeAndAfter states(this);
768   Node* node = BuildNamedLoad();
769   environment()->BindAccumulator(node, &states);
770 }
771 
VisitLdrNamedProperty()772 void BytecodeGraphBuilder::VisitLdrNamedProperty() {
773   FrameStateBeforeAndAfter states(this);
774   Node* node = BuildNamedLoad();
775   environment()->BindRegister(bytecode_iterator().GetRegisterOperand(3), node,
776                               &states);
777 }
778 
BuildKeyedLoad()779 Node* BytecodeGraphBuilder::BuildKeyedLoad() {
780   Node* key = environment()->LookupAccumulator();
781   Node* object =
782       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
783   VectorSlotPair feedback =
784       CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(1));
785 
786   const Operator* op = javascript()->LoadProperty(feedback);
787   return NewNode(op, object, key, GetFunctionClosure());
788 }
789 
VisitLdaKeyedProperty()790 void BytecodeGraphBuilder::VisitLdaKeyedProperty() {
791   FrameStateBeforeAndAfter states(this);
792   Node* node = BuildKeyedLoad();
793   environment()->BindAccumulator(node, &states);
794 }
795 
VisitLdrKeyedProperty()796 void BytecodeGraphBuilder::VisitLdrKeyedProperty() {
797   FrameStateBeforeAndAfter states(this);
798   Node* node = BuildKeyedLoad();
799   environment()->BindRegister(bytecode_iterator().GetRegisterOperand(2), node,
800                               &states);
801 }
802 
BuildNamedStore(LanguageMode language_mode)803 void BytecodeGraphBuilder::BuildNamedStore(LanguageMode language_mode) {
804   FrameStateBeforeAndAfter states(this);
805   Node* value = environment()->LookupAccumulator();
806   Node* object =
807       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
808   Handle<Name> name =
809       Handle<Name>::cast(bytecode_iterator().GetConstantForIndexOperand(1));
810   VectorSlotPair feedback =
811       CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(2));
812 
813   const Operator* op = javascript()->StoreNamed(language_mode, name, feedback);
814   Node* node = NewNode(op, object, value, GetFunctionClosure());
815   environment()->RecordAfterState(node, &states);
816 }
817 
VisitStaNamedPropertySloppy()818 void BytecodeGraphBuilder::VisitStaNamedPropertySloppy() {
819   BuildNamedStore(LanguageMode::SLOPPY);
820 }
821 
VisitStaNamedPropertyStrict()822 void BytecodeGraphBuilder::VisitStaNamedPropertyStrict() {
823   BuildNamedStore(LanguageMode::STRICT);
824 }
825 
BuildKeyedStore(LanguageMode language_mode)826 void BytecodeGraphBuilder::BuildKeyedStore(LanguageMode language_mode) {
827   FrameStateBeforeAndAfter states(this);
828   Node* value = environment()->LookupAccumulator();
829   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));
835 
836   const Operator* op = javascript()->StoreProperty(language_mode, feedback);
837   Node* node = NewNode(op, object, key, value, GetFunctionClosure());
838   environment()->RecordAfterState(node, &states);
839 }
840 
VisitStaKeyedPropertySloppy()841 void BytecodeGraphBuilder::VisitStaKeyedPropertySloppy() {
842   BuildKeyedStore(LanguageMode::SLOPPY);
843 }
844 
VisitStaKeyedPropertyStrict()845 void BytecodeGraphBuilder::VisitStaKeyedPropertyStrict() {
846   BuildKeyedStore(LanguageMode::STRICT);
847 }
848 
VisitPushContext()849 void BytecodeGraphBuilder::VisitPushContext() {
850   Node* new_context = environment()->LookupAccumulator();
851   environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0),
852                               environment()->Context());
853   environment()->SetContext(new_context);
854 }
855 
VisitPopContext()856 void BytecodeGraphBuilder::VisitPopContext() {
857   Node* context =
858       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
859   environment()->SetContext(context);
860 }
861 
VisitCreateClosure()862 void BytecodeGraphBuilder::VisitCreateClosure() {
863   Handle<SharedFunctionInfo> shared_info = Handle<SharedFunctionInfo>::cast(
864       bytecode_iterator().GetConstantForIndexOperand(0));
865   PretenureFlag tenured =
866       bytecode_iterator().GetFlagOperand(1) ? TENURED : NOT_TENURED;
867   const Operator* op = javascript()->CreateClosure(shared_info, tenured);
868   Node* closure = NewNode(op);
869   environment()->BindAccumulator(closure);
870 }
871 
BuildCreateArguments(CreateArgumentsType type)872 void BytecodeGraphBuilder::BuildCreateArguments(CreateArgumentsType type) {
873   FrameStateBeforeAndAfter states(this);
874   const Operator* op = javascript()->CreateArguments(type);
875   Node* object = NewNode(op, GetFunctionClosure());
876   environment()->BindAccumulator(object, &states);
877 }
878 
VisitCreateMappedArguments()879 void BytecodeGraphBuilder::VisitCreateMappedArguments() {
880   BuildCreateArguments(CreateArgumentsType::kMappedArguments);
881 }
882 
VisitCreateUnmappedArguments()883 void BytecodeGraphBuilder::VisitCreateUnmappedArguments() {
884   BuildCreateArguments(CreateArgumentsType::kUnmappedArguments);
885 }
886 
VisitCreateRestParameter()887 void BytecodeGraphBuilder::VisitCreateRestParameter() {
888   BuildCreateArguments(CreateArgumentsType::kRestParameter);
889 }
890 
BuildCreateLiteral(const Operator * op)891 void BytecodeGraphBuilder::BuildCreateLiteral(const Operator* op) {
892   FrameStateBeforeAndAfter states(this);
893   Node* literal = NewNode(op, GetFunctionClosure());
894   environment()->BindAccumulator(literal, &states);
895 }
896 
VisitCreateRegExpLiteral()897 void BytecodeGraphBuilder::VisitCreateRegExpLiteral() {
898   Handle<String> constant_pattern =
899       Handle<String>::cast(bytecode_iterator().GetConstantForIndexOperand(0));
900   int literal_index = bytecode_iterator().GetIndexOperand(1);
901   int literal_flags = bytecode_iterator().GetFlagOperand(2);
902   const Operator* op = javascript()->CreateLiteralRegExp(
903       constant_pattern, literal_flags, literal_index);
904   BuildCreateLiteral(op);
905 }
906 
VisitCreateArrayLiteral()907 void BytecodeGraphBuilder::VisitCreateArrayLiteral() {
908   Handle<FixedArray> constant_elements = Handle<FixedArray>::cast(
909       bytecode_iterator().GetConstantForIndexOperand(0));
910   int literal_index = bytecode_iterator().GetIndexOperand(1);
911   int literal_flags = bytecode_iterator().GetFlagOperand(2);
912   int number_of_elements = constant_elements->length();
913   const Operator* op = javascript()->CreateLiteralArray(
914       constant_elements, literal_flags, literal_index, number_of_elements);
915   BuildCreateLiteral(op);
916 }
917 
VisitCreateObjectLiteral()918 void BytecodeGraphBuilder::VisitCreateObjectLiteral() {
919   Handle<FixedArray> constant_properties = Handle<FixedArray>::cast(
920       bytecode_iterator().GetConstantForIndexOperand(0));
921   int literal_index = bytecode_iterator().GetIndexOperand(1);
922   int bytecode_flags = bytecode_iterator().GetFlagOperand(2);
923   int literal_flags =
924       interpreter::CreateObjectLiteralFlags::FlagsBits::decode(bytecode_flags);
925   // 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);
930 }
931 
ProcessCallArguments(const Operator * call_op,Node * callee,interpreter::Register receiver,size_t arity)932 Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op,
933                                                  Node* callee,
934                                                  interpreter::Register receiver,
935                                                  size_t arity) {
936   Node** all = local_zone()->NewArray<Node*>(static_cast<int>(arity));
937   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 
BuildCall(TailCallMode tail_call_mode)948 void BytecodeGraphBuilder::BuildCall(TailCallMode tail_call_mode) {
949   FrameStateBeforeAndAfter states(this);
950   // 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;
954   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));
960 
961   const Operator* call = javascript()->CallFunction(
962       arg_count + 1, feedback, receiver_hint, tail_call_mode);
963   Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 1);
964   environment()->BindAccumulator(value, &states);
965 }
966 
VisitCall()967 void BytecodeGraphBuilder::VisitCall() { BuildCall(TailCallMode::kDisallow); }
968 
VisitTailCall()969 void 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);
975 }
976 
VisitCallJSRuntime()977 void BytecodeGraphBuilder::VisitCallJSRuntime() {
978   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);
983 
984   // Create node to perform the JS runtime call.
985   const Operator* call = javascript()->CallFunction(arg_count + 1);
986   Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 1);
987   environment()->BindAccumulator(value, &states);
988 }
989 
ProcessCallRuntimeArguments(const Operator * call_runtime_op,interpreter::Register first_arg,size_t arity)990 Node* BytecodeGraphBuilder::ProcessCallRuntimeArguments(
991     const Operator* call_runtime_op, interpreter::Register first_arg,
992     size_t arity) {
993   Node** all = local_zone()->NewArray<Node*>(arity);
994   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 
VisitCallRuntime()1003 void BytecodeGraphBuilder::VisitCallRuntime() {
1004   FrameStateBeforeAndAfter states(this);
1005   Runtime::FunctionId functionId = bytecode_iterator().GetRuntimeIdOperand(0);
1006   interpreter::Register first_arg = bytecode_iterator().GetRegisterOperand(1);
1007   size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
1008 
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 
VisitCallRuntimeForPair()1015 void BytecodeGraphBuilder::VisitCallRuntimeForPair() {
1016   FrameStateBeforeAndAfter states(this);
1017   Runtime::FunctionId functionId = bytecode_iterator().GetRuntimeIdOperand(0);
1018   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);
1022 
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 
VisitInvokeIntrinsic()1029 void BytecodeGraphBuilder::VisitInvokeIntrinsic() {
1030   FrameStateBeforeAndAfter states(this);
1031   Runtime::FunctionId functionId = bytecode_iterator().GetIntrinsicIdOperand(0);
1032   interpreter::Register first_arg = bytecode_iterator().GetRegisterOperand(1);
1033   size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
1034 
1035   // 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);
1040 }
1041 
ProcessCallNewArguments(const Operator * call_new_op,Node * callee,Node * new_target,interpreter::Register first_arg,size_t arity)1042 Node* BytecodeGraphBuilder::ProcessCallNewArguments(
1043     const Operator* call_new_op, Node* callee, Node* new_target,
1044     interpreter::Register first_arg, size_t arity) {
1045   Node** all = local_zone()->NewArray<Node*>(arity);
1046   all[0] = new_target;
1047   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   }
1052   all[arity - 1] = callee;
1053   Node* value = MakeNode(call_new_op, static_cast<int>(arity), all, false);
1054   return value;
1055 }
1056 
VisitNew()1057 void BytecodeGraphBuilder::VisitNew() {
1058   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);
1062 
1063   Node* new_target = environment()->LookupAccumulator();
1064   Node* callee = environment()->LookupRegister(callee_reg);
1065   // TODO(turbofan): Pass the feedback here.
1066   const Operator* call = javascript()->CallConstruct(
1067       static_cast<int>(arg_count) + 2, VectorSlotPair());
1068   Node* value = ProcessCallNewArguments(call, callee, new_target, first_arg,
1069                                         arg_count + 2);
1070   environment()->BindAccumulator(value, &states);
1071 }
1072 
BuildThrow()1073 void BytecodeGraphBuilder::BuildThrow() {
1074   FrameStateBeforeAndAfter states(this);
1075   Node* value = environment()->LookupAccumulator();
1076   Node* call = NewNode(javascript()->CallRuntime(Runtime::kThrow), value);
1077   environment()->BindAccumulator(call, &states);
1078 }
1079 
VisitThrow()1080 void BytecodeGraphBuilder::VisitThrow() {
1081   BuildThrow();
1082   Node* call = environment()->LookupAccumulator();
1083   Node* control = NewNode(common()->Throw(), call);
1084   MergeControlToLeaveFunction(control);
1085 }
1086 
VisitReThrow()1087 void 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 
BuildBinaryOp(const Operator * js_op)1094 void BytecodeGraphBuilder::BuildBinaryOp(const Operator* js_op) {
1095   FrameStateBeforeAndAfter states(this);
1096   Node* left =
1097       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1098   Node* right = environment()->LookupAccumulator();
1099   Node* node = NewNode(js_op, left, right);
1100   environment()->BindAccumulator(node, &states);
1101 }
1102 
VisitAdd()1103 void BytecodeGraphBuilder::VisitAdd() {
1104   BinaryOperationHints hints = BinaryOperationHints::Any();
1105   BuildBinaryOp(javascript()->Add(hints));
1106 }
1107 
VisitSub()1108 void BytecodeGraphBuilder::VisitSub() {
1109   BinaryOperationHints hints = BinaryOperationHints::Any();
1110   BuildBinaryOp(javascript()->Subtract(hints));
1111 }
1112 
VisitMul()1113 void BytecodeGraphBuilder::VisitMul() {
1114   BinaryOperationHints hints = BinaryOperationHints::Any();
1115   BuildBinaryOp(javascript()->Multiply(hints));
1116 }
1117 
VisitDiv()1118 void BytecodeGraphBuilder::VisitDiv() {
1119   BinaryOperationHints hints = BinaryOperationHints::Any();
1120   BuildBinaryOp(javascript()->Divide(hints));
1121 }
1122 
VisitMod()1123 void BytecodeGraphBuilder::VisitMod() {
1124   BinaryOperationHints hints = BinaryOperationHints::Any();
1125   BuildBinaryOp(javascript()->Modulus(hints));
1126 }
1127 
VisitBitwiseOr()1128 void BytecodeGraphBuilder::VisitBitwiseOr() {
1129   BinaryOperationHints hints = BinaryOperationHints::Any();
1130   BuildBinaryOp(javascript()->BitwiseOr(hints));
1131 }
1132 
VisitBitwiseXor()1133 void BytecodeGraphBuilder::VisitBitwiseXor() {
1134   BinaryOperationHints hints = BinaryOperationHints::Any();
1135   BuildBinaryOp(javascript()->BitwiseXor(hints));
1136 }
1137 
VisitBitwiseAnd()1138 void BytecodeGraphBuilder::VisitBitwiseAnd() {
1139   BinaryOperationHints hints = BinaryOperationHints::Any();
1140   BuildBinaryOp(javascript()->BitwiseAnd(hints));
1141 }
1142 
VisitShiftLeft()1143 void BytecodeGraphBuilder::VisitShiftLeft() {
1144   BinaryOperationHints hints = BinaryOperationHints::Any();
1145   BuildBinaryOp(javascript()->ShiftLeft(hints));
1146 }
1147 
VisitShiftRight()1148 void BytecodeGraphBuilder::VisitShiftRight() {
1149   BinaryOperationHints hints = BinaryOperationHints::Any();
1150   BuildBinaryOp(javascript()->ShiftRight(hints));
1151 }
1152 
VisitShiftRightLogical()1153 void BytecodeGraphBuilder::VisitShiftRightLogical() {
1154   BinaryOperationHints hints = BinaryOperationHints::Any();
1155   BuildBinaryOp(javascript()->ShiftRightLogical(hints));
1156 }
1157 
VisitInc()1158 void BytecodeGraphBuilder::VisitInc() {
1159   FrameStateBeforeAndAfter states(this);
1160   // 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());
1163   Node* node = NewNode(js_op, environment()->LookupAccumulator(),
1164                        jsgraph()->Constant(-1.0));
1165   environment()->BindAccumulator(node, &states);
1166 }
1167 
VisitDec()1168 void BytecodeGraphBuilder::VisitDec() {
1169   FrameStateBeforeAndAfter states(this);
1170   const Operator* js_op = javascript()->Subtract(BinaryOperationHints::Any());
1171   Node* node = NewNode(js_op, environment()->LookupAccumulator(),
1172                        jsgraph()->OneConstant());
1173   environment()->BindAccumulator(node, &states);
1174 }
1175 
VisitLogicalNot()1176 void BytecodeGraphBuilder::VisitLogicalNot() {
1177   Node* value = environment()->LookupAccumulator();
1178   Node* node = NewNode(common()->Select(MachineRepresentation::kTagged), value,
1179                        jsgraph()->FalseConstant(), jsgraph()->TrueConstant());
1180   environment()->BindAccumulator(node);
1181 }
1182 
VisitToBooleanLogicalNot()1183 void BytecodeGraphBuilder::VisitToBooleanLogicalNot() {
1184   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 
VisitTypeOf()1191 void BytecodeGraphBuilder::VisitTypeOf() {
1192   Node* node =
1193       NewNode(javascript()->TypeOf(), environment()->LookupAccumulator());
1194   environment()->BindAccumulator(node);
1195 }
1196 
BuildDelete(LanguageMode language_mode)1197 void BytecodeGraphBuilder::BuildDelete(LanguageMode language_mode) {
1198   FrameStateBeforeAndAfter states(this);
1199   Node* key = environment()->LookupAccumulator();
1200   Node* object =
1201       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1202   Node* node =
1203       NewNode(javascript()->DeleteProperty(language_mode), object, key);
1204   environment()->BindAccumulator(node, &states);
1205 }
1206 
VisitDeletePropertyStrict()1207 void BytecodeGraphBuilder::VisitDeletePropertyStrict() {
1208   BuildDelete(LanguageMode::STRICT);
1209 }
1210 
VisitDeletePropertySloppy()1211 void BytecodeGraphBuilder::VisitDeletePropertySloppy() {
1212   BuildDelete(LanguageMode::SLOPPY);
1213 }
1214 
BuildCompareOp(const Operator * js_op)1215 void BytecodeGraphBuilder::BuildCompareOp(const Operator* js_op) {
1216   FrameStateBeforeAndAfter states(this);
1217   Node* left =
1218       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1219   Node* right = environment()->LookupAccumulator();
1220   Node* node = NewNode(js_op, left, right);
1221   environment()->BindAccumulator(node, &states);
1222 }
1223 
VisitTestEqual()1224 void BytecodeGraphBuilder::VisitTestEqual() {
1225   CompareOperationHints hints = CompareOperationHints::Any();
1226   BuildCompareOp(javascript()->Equal(hints));
1227 }
1228 
VisitTestNotEqual()1229 void BytecodeGraphBuilder::VisitTestNotEqual() {
1230   CompareOperationHints hints = CompareOperationHints::Any();
1231   BuildCompareOp(javascript()->NotEqual(hints));
1232 }
1233 
VisitTestEqualStrict()1234 void BytecodeGraphBuilder::VisitTestEqualStrict() {
1235   CompareOperationHints hints = CompareOperationHints::Any();
1236   BuildCompareOp(javascript()->StrictEqual(hints));
1237 }
1238 
VisitTestLessThan()1239 void BytecodeGraphBuilder::VisitTestLessThan() {
1240   CompareOperationHints hints = CompareOperationHints::Any();
1241   BuildCompareOp(javascript()->LessThan(hints));
1242 }
1243 
VisitTestGreaterThan()1244 void BytecodeGraphBuilder::VisitTestGreaterThan() {
1245   CompareOperationHints hints = CompareOperationHints::Any();
1246   BuildCompareOp(javascript()->GreaterThan(hints));
1247 }
1248 
VisitTestLessThanOrEqual()1249 void BytecodeGraphBuilder::VisitTestLessThanOrEqual() {
1250   CompareOperationHints hints = CompareOperationHints::Any();
1251   BuildCompareOp(javascript()->LessThanOrEqual(hints));
1252 }
1253 
VisitTestGreaterThanOrEqual()1254 void BytecodeGraphBuilder::VisitTestGreaterThanOrEqual() {
1255   CompareOperationHints hints = CompareOperationHints::Any();
1256   BuildCompareOp(javascript()->GreaterThanOrEqual(hints));
1257 }
1258 
VisitTestIn()1259 void BytecodeGraphBuilder::VisitTestIn() {
1260   BuildCompareOp(javascript()->HasProperty());
1261 }
1262 
VisitTestInstanceOf()1263 void BytecodeGraphBuilder::VisitTestInstanceOf() {
1264   BuildCompareOp(javascript()->InstanceOf());
1265 }
1266 
BuildCastOperator(const Operator * js_op)1267 void BytecodeGraphBuilder::BuildCastOperator(const Operator* js_op) {
1268   FrameStateBeforeAndAfter states(this);
1269   Node* node = NewNode(js_op, environment()->LookupAccumulator());
1270   environment()->BindAccumulator(node, &states);
1271 }
1272 
VisitToName()1273 void BytecodeGraphBuilder::VisitToName() {
1274   BuildCastOperator(javascript()->ToName());
1275 }
1276 
VisitToObject()1277 void BytecodeGraphBuilder::VisitToObject() {
1278   BuildCastOperator(javascript()->ToObject());
1279 }
1280 
VisitToNumber()1281 void BytecodeGraphBuilder::VisitToNumber() {
1282   BuildCastOperator(javascript()->ToNumber());
1283 }
1284 
VisitJump()1285 void BytecodeGraphBuilder::VisitJump() { BuildJump(); }
1286 
VisitJumpConstant()1287 void BytecodeGraphBuilder::VisitJumpConstant() { BuildJump(); }
1288 
1289 
VisitJumpIfTrue()1290 void BytecodeGraphBuilder::VisitJumpIfTrue() {
1291   BuildJumpIfEqual(jsgraph()->TrueConstant());
1292 }
1293 
VisitJumpIfTrueConstant()1294 void BytecodeGraphBuilder::VisitJumpIfTrueConstant() {
1295   BuildJumpIfEqual(jsgraph()->TrueConstant());
1296 }
1297 
VisitJumpIfFalse()1298 void BytecodeGraphBuilder::VisitJumpIfFalse() {
1299   BuildJumpIfEqual(jsgraph()->FalseConstant());
1300 }
1301 
VisitJumpIfFalseConstant()1302 void BytecodeGraphBuilder::VisitJumpIfFalseConstant() {
1303   BuildJumpIfEqual(jsgraph()->FalseConstant());
1304 }
1305 
VisitJumpIfToBooleanTrue()1306 void BytecodeGraphBuilder::VisitJumpIfToBooleanTrue() {
1307   BuildJumpIfToBooleanEqual(jsgraph()->TrueConstant());
1308 }
1309 
VisitJumpIfToBooleanTrueConstant()1310 void BytecodeGraphBuilder::VisitJumpIfToBooleanTrueConstant() {
1311   BuildJumpIfToBooleanEqual(jsgraph()->TrueConstant());
1312 }
1313 
VisitJumpIfToBooleanFalse()1314 void BytecodeGraphBuilder::VisitJumpIfToBooleanFalse() {
1315   BuildJumpIfToBooleanEqual(jsgraph()->FalseConstant());
1316 }
1317 
VisitJumpIfToBooleanFalseConstant()1318 void BytecodeGraphBuilder::VisitJumpIfToBooleanFalseConstant() {
1319   BuildJumpIfToBooleanEqual(jsgraph()->FalseConstant());
1320 }
1321 
VisitJumpIfNotHole()1322 void BytecodeGraphBuilder::VisitJumpIfNotHole() { BuildJumpIfNotHole(); }
1323 
VisitJumpIfNotHoleConstant()1324 void BytecodeGraphBuilder::VisitJumpIfNotHoleConstant() {
1325   BuildJumpIfNotHole();
1326 }
1327 
VisitJumpIfNull()1328 void BytecodeGraphBuilder::VisitJumpIfNull() {
1329   BuildJumpIfEqual(jsgraph()->NullConstant());
1330 }
1331 
VisitJumpIfNullConstant()1332 void BytecodeGraphBuilder::VisitJumpIfNullConstant() {
1333   BuildJumpIfEqual(jsgraph()->NullConstant());
1334 }
1335 
VisitJumpIfUndefined()1336 void BytecodeGraphBuilder::VisitJumpIfUndefined() {
1337   BuildJumpIfEqual(jsgraph()->UndefinedConstant());
1338 }
1339 
VisitJumpIfUndefinedConstant()1340 void BytecodeGraphBuilder::VisitJumpIfUndefinedConstant() {
1341   BuildJumpIfEqual(jsgraph()->UndefinedConstant());
1342 }
1343 
VisitStackCheck()1344 void BytecodeGraphBuilder::VisitStackCheck() {
1345   FrameStateBeforeAndAfter states(this);
1346   Node* node = NewNode(javascript()->StackCheck());
1347   environment()->RecordAfterState(node, &states);
1348 }
1349 
VisitReturn()1350 void BytecodeGraphBuilder::VisitReturn() {
1351   Node* control =
1352       NewNode(common()->Return(), environment()->LookupAccumulator());
1353   MergeControlToLeaveFunction(control);
1354 }
1355 
VisitDebugger()1356 void BytecodeGraphBuilder::VisitDebugger() {
1357   FrameStateBeforeAndAfter states(this);
1358   Node* call =
1359       NewNode(javascript()->CallRuntime(Runtime::kHandleDebuggerStatement));
1360   environment()->BindAccumulator(call, &states);
1361 }
1362 
1363 // We cannot create a graph from the debugger copy of the bytecode array.
1364 #define DEBUG_BREAK(Name, ...) \
1365   void BytecodeGraphBuilder::Visit##Name() { UNREACHABLE(); }
1366 DEBUG_BREAK_BYTECODE_LIST(DEBUG_BREAK);
1367 #undef DEBUG_BREAK
1368 
BuildForInPrepare()1369 void 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 
VisitForInPrepare()1377 void BytecodeGraphBuilder::VisitForInPrepare() { BuildForInPrepare(); }
1378 
VisitForInDone()1379 void BytecodeGraphBuilder::VisitForInDone() {
1380   FrameStateBeforeAndAfter states(this);
1381   Node* index =
1382       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1383   Node* cache_length =
1384       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
1385   Node* exit_cond = NewNode(javascript()->ForInDone(), index, cache_length);
1386   environment()->BindAccumulator(exit_cond, &states);
1387 }
1388 
BuildForInNext()1389 void BytecodeGraphBuilder::BuildForInNext() {
1390   FrameStateBeforeAndAfter states(this);
1391   Node* receiver =
1392       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 
1401   Node* value = NewNode(javascript()->ForInNext(), receiver, cache_array,
1402                         cache_type, index);
1403   environment()->BindAccumulator(value, &states);
1404 }
1405 
VisitForInNext()1406 void BytecodeGraphBuilder::VisitForInNext() { BuildForInNext(); }
1407 
VisitForInStep()1408 void BytecodeGraphBuilder::VisitForInStep() {
1409   FrameStateBeforeAndAfter states(this);
1410   Node* index =
1411       environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1412   index = NewNode(javascript()->ForInStep(), index);
1413   environment()->BindAccumulator(index, &states);
1414 }
1415 
VisitSuspendGenerator()1416 void BytecodeGraphBuilder::VisitSuspendGenerator() {
1417   Node* state = environment()->LookupAccumulator();
1418   Node* generator = environment()->LookupRegister(
1419       bytecode_iterator().GetRegisterOperand(0));
1420   // 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));
1425 
1426   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));
1436   }
1437 
1438   MakeNode(javascript()->GeneratorStore(register_count), value_input_count,
1439            value_inputs, false);
1440 }
1441 
VisitResumeGenerator()1442 void BytecodeGraphBuilder::VisitResumeGenerator() {
1443   FrameStateBeforeAndAfter states(this);
1444 
1445   Node* generator = environment()->LookupRegister(
1446       bytecode_iterator().GetRegisterOperand(0));
1447 
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) {
1451     Node* value = NewNode(javascript()->GeneratorRestoreRegister(i), generator);
1452     environment()->BindRegister(interpreter::Register(i), value);
1453   }
1454 
1455   Node* state =
1456       NewNode(javascript()->GeneratorRestoreContinuation(), generator);
1457 
1458   environment()->BindAccumulator(state, &states);
1459 }
1460 
VisitWide()1461 void BytecodeGraphBuilder::VisitWide() {
1462   // Consumed by the BytecodeArrayIterator.
1463   UNREACHABLE();
1464 }
1465 
VisitExtraWide()1466 void BytecodeGraphBuilder::VisitExtraWide() {
1467   // Consumed by the BytecodeArrayIterator.
1468   UNREACHABLE();
1469 }
1470 
VisitIllegal()1471 void BytecodeGraphBuilder::VisitIllegal() {
1472   // Not emitted in valid bytecode.
1473   UNREACHABLE();
1474 }
1475 
VisitNop()1476 void BytecodeGraphBuilder::VisitNop() {}
1477 
SwitchToMergeEnvironment(int current_offset)1478 void BytecodeGraphBuilder::SwitchToMergeEnvironment(int current_offset) {
1479   if (merge_environments_[current_offset] != nullptr) {
1480     if (environment() != nullptr) {
1481       merge_environments_[current_offset]->Merge(environment());
1482     }
1483     set_environment(merge_environments_[current_offset]);
1484   }
1485 }
1486 
BuildLoopHeaderEnvironment(int current_offset)1487 void BytecodeGraphBuilder::BuildLoopHeaderEnvironment(int current_offset) {
1488   if (branch_analysis()->backward_branches_target(current_offset)) {
1489     // Add loop header and store a copy so we can connect merged back
1490     // edge inputs to the loop header.
1491     merge_environments_[current_offset] = environment()->CopyForLoop();
1492   }
1493 }
1494 
MergeIntoSuccessorEnvironment(int target_offset)1495 void 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());
1505   }
1506   set_environment(nullptr);
1507 }
1508 
MergeControlToLeaveFunction(Node * exit)1509 void BytecodeGraphBuilder::MergeControlToLeaveFunction(Node* exit) {
1510   exit_controls_.push_back(exit);
1511   set_environment(nullptr);
1512 }
1513 
BuildJump()1514 void BytecodeGraphBuilder::BuildJump() {
1515   MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
1516 }
1517 
1518 
BuildConditionalJump(Node * condition)1519 void BytecodeGraphBuilder::BuildConditionalJump(Node* condition) {
1520   NewBranch(condition);
1521   Environment* if_false_environment = environment()->CopyForConditional();
1522   NewIfTrue();
1523   MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
1524   set_environment(if_false_environment);
1525   NewIfFalse();
1526 }
1527 
1528 
BuildJumpIfEqual(Node * comperand)1529 void BytecodeGraphBuilder::BuildJumpIfEqual(Node* comperand) {
1530   Node* accumulator = environment()->LookupAccumulator();
1531   Node* condition =
1532       NewNode(javascript()->StrictEqual(CompareOperationHints::Any()),
1533               accumulator, comperand);
1534   BuildConditionalJump(condition);
1535 }
1536 
1537 
BuildJumpIfToBooleanEqual(Node * comperand)1538 void BytecodeGraphBuilder::BuildJumpIfToBooleanEqual(Node* comperand) {
1539   Node* accumulator = environment()->LookupAccumulator();
1540   Node* to_boolean =
1541       NewNode(javascript()->ToBoolean(ToBooleanHint::kAny), accumulator);
1542   Node* condition =
1543       NewNode(javascript()->StrictEqual(CompareOperationHints::Any()),
1544               to_boolean, comperand);
1545   BuildConditionalJump(condition);
1546 }
1547 
BuildJumpIfNotHole()1548 void BytecodeGraphBuilder::BuildJumpIfNotHole() {
1549   Node* accumulator = environment()->LookupAccumulator();
1550   Node* condition =
1551       NewNode(javascript()->StrictEqual(CompareOperationHints::Any()),
1552               accumulator, jsgraph()->TheHoleConstant());
1553   Node* node =
1554       NewNode(common()->Select(MachineRepresentation::kTagged), condition,
1555               jsgraph()->FalseConstant(), jsgraph()->TrueConstant());
1556   BuildConditionalJump(node);
1557 }
1558 
EnsureInputBufferSize(int size)1559 Node** 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 
EnterAndExitExceptionHandlers(int current_offset)1568 void BytecodeGraphBuilder::EnterAndExitExceptionHandlers(int current_offset) {
1569   Handle<HandlerTable> table = exception_handler_table();
1570   int num_entries = table->NumberOfRangeEntries();
1571 
1572   // 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   }
1592 }
1593 
MakeNode(const Operator * op,int value_input_count,Node ** value_inputs,bool incomplete)1594 Node* 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 {
1610     bool inside_handler = !exception_handlers_.empty();
1611     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);
1635     // 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);
1669     }
1670   }
1671 
1672   return result;
1673 }
1674 
1675 
NewPhi(int count,Node * input,Node * control)1676 Node* 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 
NewEffectPhi(int count,Node * input,Node * control)1685 Node* 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 
MergeControl(Node * control,Node * other)1695 Node* 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 
MergeEffect(Node * value,Node * other,Node * control)1717 Node* 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 
MergeValue(Node * value,Node * other,Node * control)1734 Node* 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 
1751 }  // namespace compiler
1752 }  // namespace internal
1753 }  // namespace v8
1754