blob: e28c19d84426d1932c04fca02ca829a808102fc0 [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// Copyright 2015 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "src/compiler/bytecode-graph-builder.h"
6
7#include "src/compiler/bytecode-branch-analysis.h"
8#include "src/compiler/linkage.h"
9#include "src/compiler/operator-properties.h"
10#include "src/interpreter/bytecodes.h"
11
12namespace v8 {
13namespace internal {
14namespace compiler {
15
Ben Murdoch097c5b22016-05-18 11:27:45 +010016// The abstract execution environment simulates the content of the interpreter
17// register file. The environment performs SSA-renaming of all tracked nodes at
18// split and merge points in the control flow.
19class BytecodeGraphBuilder::Environment : public ZoneObject {
20 public:
21 Environment(BytecodeGraphBuilder* builder, int register_count,
22 int parameter_count, Node* control_dependency, Node* context);
23
24 int parameter_count() const { return parameter_count_; }
25 int register_count() const { return register_count_; }
26
27 Node* LookupAccumulator() const;
28 Node* LookupRegister(interpreter::Register the_register) const;
29
30 void BindAccumulator(Node* node, FrameStateBeforeAndAfter* states = nullptr);
31 void BindRegister(interpreter::Register the_register, Node* node,
32 FrameStateBeforeAndAfter* states = nullptr);
33 void BindRegistersToProjections(interpreter::Register first_reg, Node* node,
34 FrameStateBeforeAndAfter* states = nullptr);
35 void RecordAfterState(Node* node, FrameStateBeforeAndAfter* states);
36
37 // Effect dependency tracked by this environment.
38 Node* GetEffectDependency() { return effect_dependency_; }
39 void UpdateEffectDependency(Node* dependency) {
40 effect_dependency_ = dependency;
41 }
42
43 // Preserve a checkpoint of the environment for the IR graph. Any
44 // further mutation of the environment will not affect checkpoints.
45 Node* Checkpoint(BailoutId bytecode_offset, OutputFrameStateCombine combine);
46
47 // Returns true if the state values are up to date with the current
48 // environment.
49 bool StateValuesAreUpToDate(int output_poke_offset, int output_poke_count);
50
51 // Control dependency tracked by this environment.
52 Node* GetControlDependency() const { return control_dependency_; }
53 void UpdateControlDependency(Node* dependency) {
54 control_dependency_ = dependency;
55 }
56
57 Node* Context() const { return context_; }
58 void SetContext(Node* new_context) { context_ = new_context; }
59
60 Environment* CopyForConditional() const;
61 Environment* CopyForLoop();
62 void Merge(Environment* other);
63
64 private:
65 explicit Environment(const Environment* copy);
66 void PrepareForLoop();
67 bool StateValuesAreUpToDate(Node** state_values, int offset, int count,
68 int output_poke_start, int output_poke_end);
69 bool StateValuesRequireUpdate(Node** state_values, int offset, int count);
70 void UpdateStateValues(Node** state_values, int offset, int count);
71
72 int RegisterToValuesIndex(interpreter::Register the_register) const;
73
74 Zone* zone() const { return builder_->local_zone(); }
75 Graph* graph() const { return builder_->graph(); }
76 CommonOperatorBuilder* common() const { return builder_->common(); }
77 BytecodeGraphBuilder* builder() const { return builder_; }
78 const NodeVector* values() const { return &values_; }
79 NodeVector* values() { return &values_; }
80 int register_base() const { return register_base_; }
81 int accumulator_base() const { return accumulator_base_; }
82
83 BytecodeGraphBuilder* builder_;
84 int register_count_;
85 int parameter_count_;
86 Node* context_;
87 Node* control_dependency_;
88 Node* effect_dependency_;
89 NodeVector values_;
90 Node* parameters_state_values_;
91 Node* registers_state_values_;
92 Node* accumulator_state_values_;
93 int register_base_;
94 int accumulator_base_;
95};
96
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000097// Helper for generating frame states for before and after a bytecode.
98class BytecodeGraphBuilder::FrameStateBeforeAndAfter {
99 public:
Ben Murdoch097c5b22016-05-18 11:27:45 +0100100 explicit FrameStateBeforeAndAfter(BytecodeGraphBuilder* builder)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000101 : builder_(builder),
102 id_after_(BailoutId::None()),
103 added_to_node_(false),
Ben Murdoch097c5b22016-05-18 11:27:45 +0100104 frame_states_unused_(false),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000105 output_poke_offset_(0),
106 output_poke_count_(0) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100107 BailoutId id_before(builder->bytecode_iterator().current_offset());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000108 frame_state_before_ = builder_->environment()->Checkpoint(
109 id_before, OutputFrameStateCombine::Ignore());
Ben Murdoch097c5b22016-05-18 11:27:45 +0100110 id_after_ = BailoutId(id_before.ToInt() +
111 builder->bytecode_iterator().current_bytecode_size());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000112 }
113
114 ~FrameStateBeforeAndAfter() {
115 DCHECK(added_to_node_);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100116 DCHECK(frame_states_unused_ ||
117 builder_->environment()->StateValuesAreUpToDate(output_poke_offset_,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000118 output_poke_count_));
119 }
120
121 private:
122 friend class Environment;
123
124 void AddToNode(Node* node, OutputFrameStateCombine combine) {
125 DCHECK(!added_to_node_);
126 int count = OperatorProperties::GetFrameStateInputCount(node->op());
127 DCHECK_LE(count, 2);
128 if (count >= 1) {
129 // Add the frame state for after the operation.
130 DCHECK_EQ(IrOpcode::kDead,
131 NodeProperties::GetFrameStateInput(node, 0)->opcode());
132 Node* frame_state_after =
133 builder_->environment()->Checkpoint(id_after_, combine);
134 NodeProperties::ReplaceFrameStateInput(node, 0, frame_state_after);
135 }
136
137 if (count >= 2) {
138 // Add the frame state for before the operation.
139 DCHECK_EQ(IrOpcode::kDead,
140 NodeProperties::GetFrameStateInput(node, 1)->opcode());
141 NodeProperties::ReplaceFrameStateInput(node, 1, frame_state_before_);
142 }
143
144 if (!combine.IsOutputIgnored()) {
145 output_poke_offset_ = static_cast<int>(combine.GetOffsetToPokeAt());
146 output_poke_count_ = node->op()->ValueOutputCount();
147 }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100148 frame_states_unused_ = count == 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000149 added_to_node_ = true;
150 }
151
152 BytecodeGraphBuilder* builder_;
153 Node* frame_state_before_;
154 BailoutId id_after_;
155
156 bool added_to_node_;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100157 bool frame_states_unused_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000158 int output_poke_offset_;
159 int output_poke_count_;
160};
161
162
163// Issues:
164// - Scopes - intimately tied to AST. Need to eval what is needed.
165// - Need to resolve closure parameter treatment.
166BytecodeGraphBuilder::Environment::Environment(BytecodeGraphBuilder* builder,
167 int register_count,
168 int parameter_count,
169 Node* control_dependency,
170 Node* context)
171 : builder_(builder),
172 register_count_(register_count),
173 parameter_count_(parameter_count),
174 context_(context),
175 control_dependency_(control_dependency),
176 effect_dependency_(control_dependency),
177 values_(builder->local_zone()),
178 parameters_state_values_(nullptr),
179 registers_state_values_(nullptr),
180 accumulator_state_values_(nullptr) {
181 // The layout of values_ is:
182 //
183 // [receiver] [parameters] [registers] [accumulator]
184 //
185 // parameter[0] is the receiver (this), parameters 1..N are the
186 // parameters supplied to the method (arg0..argN-1). The accumulator
187 // is stored separately.
188
189 // Parameters including the receiver
190 for (int i = 0; i < parameter_count; i++) {
191 const char* debug_name = (i == 0) ? "%this" : nullptr;
192 const Operator* op = common()->Parameter(i, debug_name);
193 Node* parameter = builder->graph()->NewNode(op, graph()->start());
194 values()->push_back(parameter);
195 }
196
197 // Registers
198 register_base_ = static_cast<int>(values()->size());
199 Node* undefined_constant = builder->jsgraph()->UndefinedConstant();
200 values()->insert(values()->end(), register_count, undefined_constant);
201
202 // Accumulator
203 accumulator_base_ = static_cast<int>(values()->size());
204 values()->push_back(undefined_constant);
205}
206
207
208BytecodeGraphBuilder::Environment::Environment(
209 const BytecodeGraphBuilder::Environment* other)
210 : builder_(other->builder_),
211 register_count_(other->register_count_),
212 parameter_count_(other->parameter_count_),
213 context_(other->context_),
214 control_dependency_(other->control_dependency_),
215 effect_dependency_(other->effect_dependency_),
216 values_(other->zone()),
217 parameters_state_values_(nullptr),
218 registers_state_values_(nullptr),
219 accumulator_state_values_(nullptr),
220 register_base_(other->register_base_),
221 accumulator_base_(other->accumulator_base_) {
222 values_ = other->values_;
223}
224
225
226int BytecodeGraphBuilder::Environment::RegisterToValuesIndex(
227 interpreter::Register the_register) const {
228 if (the_register.is_parameter()) {
229 return the_register.ToParameterIndex(parameter_count());
230 } else {
231 return the_register.index() + register_base();
232 }
233}
234
235
236Node* BytecodeGraphBuilder::Environment::LookupAccumulator() const {
237 return values()->at(accumulator_base_);
238}
239
240
241Node* BytecodeGraphBuilder::Environment::LookupRegister(
242 interpreter::Register the_register) const {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100243 if (the_register.is_current_context()) {
244 return Context();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000245 } else if (the_register.is_function_closure()) {
246 return builder()->GetFunctionClosure();
247 } else if (the_register.is_new_target()) {
248 return builder()->GetNewTarget();
249 } else {
250 int values_index = RegisterToValuesIndex(the_register);
251 return values()->at(values_index);
252 }
253}
254
255
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000256void BytecodeGraphBuilder::Environment::BindAccumulator(
257 Node* node, FrameStateBeforeAndAfter* states) {
258 if (states) {
259 states->AddToNode(node, OutputFrameStateCombine::PokeAt(0));
260 }
261 values()->at(accumulator_base_) = node;
262}
263
264
265void BytecodeGraphBuilder::Environment::BindRegister(
266 interpreter::Register the_register, Node* node,
267 FrameStateBeforeAndAfter* states) {
268 int values_index = RegisterToValuesIndex(the_register);
269 if (states) {
270 states->AddToNode(node, OutputFrameStateCombine::PokeAt(accumulator_base_ -
271 values_index));
272 }
273 values()->at(values_index) = node;
274}
275
276
277void BytecodeGraphBuilder::Environment::BindRegistersToProjections(
278 interpreter::Register first_reg, Node* node,
279 FrameStateBeforeAndAfter* states) {
280 int values_index = RegisterToValuesIndex(first_reg);
281 if (states) {
282 states->AddToNode(node, OutputFrameStateCombine::PokeAt(accumulator_base_ -
283 values_index));
284 }
285 for (int i = 0; i < node->op()->ValueOutputCount(); i++) {
286 values()->at(values_index + i) =
287 builder()->NewNode(common()->Projection(i), node);
288 }
289}
290
291
292void BytecodeGraphBuilder::Environment::RecordAfterState(
293 Node* node, FrameStateBeforeAndAfter* states) {
294 states->AddToNode(node, OutputFrameStateCombine::Ignore());
295}
296
297
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000298BytecodeGraphBuilder::Environment*
299BytecodeGraphBuilder::Environment::CopyForLoop() {
300 PrepareForLoop();
301 return new (zone()) Environment(this);
302}
303
304
305BytecodeGraphBuilder::Environment*
306BytecodeGraphBuilder::Environment::CopyForConditional() const {
307 return new (zone()) Environment(this);
308}
309
310
311void BytecodeGraphBuilder::Environment::Merge(
312 BytecodeGraphBuilder::Environment* other) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000313 // Create a merge of the control dependencies of both environments and update
314 // the current environment's control dependency accordingly.
315 Node* control = builder()->MergeControl(GetControlDependency(),
316 other->GetControlDependency());
317 UpdateControlDependency(control);
318
319 // Create a merge of the effect dependencies of both environments and update
320 // the current environment's effect dependency accordingly.
321 Node* effect = builder()->MergeEffect(GetEffectDependency(),
322 other->GetEffectDependency(), control);
323 UpdateEffectDependency(effect);
324
325 // Introduce Phi nodes for values that have differing input at merge points,
326 // potentially extending an existing Phi node if possible.
327 context_ = builder()->MergeValue(context_, other->context_, control);
328 for (size_t i = 0; i < values_.size(); i++) {
329 values_[i] = builder()->MergeValue(values_[i], other->values_[i], control);
330 }
331}
332
333
334void BytecodeGraphBuilder::Environment::PrepareForLoop() {
335 // Create a control node for the loop header.
336 Node* control = builder()->NewLoop();
337
338 // Create a Phi for external effects.
339 Node* effect = builder()->NewEffectPhi(1, GetEffectDependency(), control);
340 UpdateEffectDependency(effect);
341
342 // Assume everything in the loop is updated.
343 context_ = builder()->NewPhi(1, context_, control);
344 int size = static_cast<int>(values()->size());
345 for (int i = 0; i < size; i++) {
346 values()->at(i) = builder()->NewPhi(1, values()->at(i), control);
347 }
348
349 // Connect to the loop end.
350 Node* terminate = builder()->graph()->NewNode(
351 builder()->common()->Terminate(), effect, control);
352 builder()->exit_controls_.push_back(terminate);
353}
354
355
356bool BytecodeGraphBuilder::Environment::StateValuesRequireUpdate(
357 Node** state_values, int offset, int count) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100358 if (!builder()->deoptimization_enabled_) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000359 return false;
360 }
361 if (*state_values == nullptr) {
362 return true;
363 }
364 DCHECK_EQ((*state_values)->InputCount(), count);
365 DCHECK_LE(static_cast<size_t>(offset + count), values()->size());
366 Node** env_values = (count == 0) ? nullptr : &values()->at(offset);
367 for (int i = 0; i < count; i++) {
368 if ((*state_values)->InputAt(i) != env_values[i]) {
369 return true;
370 }
371 }
372 return false;
373}
374
375
376void BytecodeGraphBuilder::Environment::UpdateStateValues(Node** state_values,
377 int offset,
378 int count) {
379 if (StateValuesRequireUpdate(state_values, offset, count)) {
380 const Operator* op = common()->StateValues(count);
381 (*state_values) = graph()->NewNode(op, count, &values()->at(offset));
382 }
383}
384
385
386Node* BytecodeGraphBuilder::Environment::Checkpoint(
387 BailoutId bailout_id, OutputFrameStateCombine combine) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100388 if (!builder()->deoptimization_enabled_) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000389 return builder()->jsgraph()->EmptyFrameState();
390 }
391
392 // TODO(rmcilroy): Consider using StateValuesCache for some state values.
393 UpdateStateValues(&parameters_state_values_, 0, parameter_count());
394 UpdateStateValues(&registers_state_values_, register_base(),
395 register_count());
396 UpdateStateValues(&accumulator_state_values_, accumulator_base(), 1);
397
398 const Operator* op = common()->FrameState(
399 bailout_id, combine, builder()->frame_state_function_info());
400 Node* result = graph()->NewNode(
401 op, parameters_state_values_, registers_state_values_,
402 accumulator_state_values_, Context(), builder()->GetFunctionClosure(),
403 builder()->graph()->start());
404
405 return result;
406}
407
408
409bool BytecodeGraphBuilder::Environment::StateValuesAreUpToDate(
410 Node** state_values, int offset, int count, int output_poke_start,
411 int output_poke_end) {
412 DCHECK_LE(static_cast<size_t>(offset + count), values()->size());
413 for (int i = 0; i < count; i++, offset++) {
414 if (offset < output_poke_start || offset >= output_poke_end) {
415 if ((*state_values)->InputAt(i) != values()->at(offset)) {
416 return false;
417 }
418 }
419 }
420 return true;
421}
422
423
424bool BytecodeGraphBuilder::Environment::StateValuesAreUpToDate(
425 int output_poke_offset, int output_poke_count) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100426 if (!builder()->deoptimization_enabled_) return true;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000427 // Poke offset is relative to the top of the stack (i.e., the accumulator).
428 int output_poke_start = accumulator_base() - output_poke_offset;
429 int output_poke_end = output_poke_start + output_poke_count;
430 return StateValuesAreUpToDate(&parameters_state_values_, 0, parameter_count(),
431 output_poke_start, output_poke_end) &&
432 StateValuesAreUpToDate(&registers_state_values_, register_base(),
433 register_count(), output_poke_start,
434 output_poke_end) &&
435 StateValuesAreUpToDate(&accumulator_state_values_, accumulator_base(),
436 1, output_poke_start, output_poke_end);
437}
438
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000439BytecodeGraphBuilder::BytecodeGraphBuilder(Zone* local_zone,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100440 CompilationInfo* info,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000441 JSGraph* jsgraph)
442 : local_zone_(local_zone),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000443 jsgraph_(jsgraph),
Ben Murdoch097c5b22016-05-18 11:27:45 +0100444 bytecode_array_(handle(info->shared_info()->bytecode_array())),
445 exception_handler_table_(
446 handle(HandlerTable::cast(bytecode_array()->handler_table()))),
447 feedback_vector_(info->feedback_vector()),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000448 frame_state_function_info_(common()->CreateFrameStateFunctionInfo(
449 FrameStateType::kInterpretedFunction,
450 bytecode_array()->parameter_count(),
Ben Murdoch097c5b22016-05-18 11:27:45 +0100451 bytecode_array()->register_count(), info->shared_info())),
452 deoptimization_enabled_(info->is_deoptimization_enabled()),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000453 merge_environments_(local_zone),
Ben Murdoch097c5b22016-05-18 11:27:45 +0100454 exception_handlers_(local_zone),
455 current_exception_handler_(0),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000456 input_buffer_size_(0),
457 input_buffer_(nullptr),
458 exit_controls_(local_zone) {}
459
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000460Node* BytecodeGraphBuilder::GetNewTarget() {
461 if (!new_target_.is_set()) {
462 int params = bytecode_array()->parameter_count();
463 int index = Linkage::GetJSCallNewTargetParamIndex(params);
464 const Operator* op = common()->Parameter(index, "%new.target");
465 Node* node = NewNode(op, graph()->start());
466 new_target_.set(node);
467 }
468 return new_target_.get();
469}
470
471
472Node* BytecodeGraphBuilder::GetFunctionContext() {
473 if (!function_context_.is_set()) {
474 int params = bytecode_array()->parameter_count();
475 int index = Linkage::GetJSCallContextParamIndex(params);
476 const Operator* op = common()->Parameter(index, "%context");
477 Node* node = NewNode(op, graph()->start());
478 function_context_.set(node);
479 }
480 return function_context_.get();
481}
482
483
484Node* BytecodeGraphBuilder::GetFunctionClosure() {
485 if (!function_closure_.is_set()) {
486 int index = Linkage::kJSCallClosureParamIndex;
487 const Operator* op = common()->Parameter(index, "%closure");
488 Node* node = NewNode(op, graph()->start());
489 function_closure_.set(node);
490 }
491 return function_closure_.get();
492}
493
494
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000495Node* BytecodeGraphBuilder::BuildLoadNativeContextField(int index) {
496 const Operator* op =
497 javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true);
498 Node* native_context = NewNode(op, environment()->Context());
499 return NewNode(javascript()->LoadContext(0, index, true), native_context);
500}
501
502
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000503VectorSlotPair BytecodeGraphBuilder::CreateVectorSlotPair(int slot_id) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000504 FeedbackVectorSlot slot;
505 if (slot_id >= TypeFeedbackVector::kReservedIndexCount) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100506 slot = feedback_vector()->ToSlot(slot_id);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000507 }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100508 return VectorSlotPair(feedback_vector(), slot);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000509}
510
Ben Murdoch097c5b22016-05-18 11:27:45 +0100511bool BytecodeGraphBuilder::CreateGraph() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000512 // Set up the basic structure of the graph. Outputs for {Start} are
513 // the formal parameters (including the receiver) plus context and
514 // closure.
515
516 // Set up the basic structure of the graph. Outputs for {Start} are the formal
517 // parameters (including the receiver) plus new target, number of arguments,
518 // context and closure.
519 int actual_parameter_count = bytecode_array()->parameter_count() + 4;
520 graph()->SetStart(graph()->NewNode(common()->Start(actual_parameter_count)));
521
522 Environment env(this, bytecode_array()->register_count(),
523 bytecode_array()->parameter_count(), graph()->start(),
524 GetFunctionContext());
525 set_environment(&env);
526
Ben Murdoch097c5b22016-05-18 11:27:45 +0100527 VisitBytecodes();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000528
529 // Finish the basic structure of the graph.
530 DCHECK_NE(0u, exit_controls_.size());
531 int const input_count = static_cast<int>(exit_controls_.size());
532 Node** const inputs = &exit_controls_.front();
533 Node* end = graph()->NewNode(common()->End(input_count), input_count, inputs);
534 graph()->SetEnd(end);
535
536 return true;
537}
538
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000539void BytecodeGraphBuilder::VisitBytecodes() {
540 BytecodeBranchAnalysis analysis(bytecode_array(), local_zone());
541 analysis.Analyze();
542 set_branch_analysis(&analysis);
543 interpreter::BytecodeArrayIterator iterator(bytecode_array());
544 set_bytecode_iterator(&iterator);
545 while (!iterator.done()) {
546 int current_offset = iterator.current_offset();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100547 EnterAndExitExceptionHandlers(current_offset);
548 SwitchToMergeEnvironment(current_offset);
549 if (environment() != nullptr) {
550 BuildLoopHeaderEnvironment(current_offset);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000551
552 switch (iterator.current_bytecode()) {
553#define BYTECODE_CASE(name, ...) \
554 case interpreter::Bytecode::k##name: \
Ben Murdoch097c5b22016-05-18 11:27:45 +0100555 Visit##name(); \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000556 break;
557 BYTECODE_LIST(BYTECODE_CASE)
558#undef BYTECODE_CODE
559 }
560 }
561 iterator.Advance();
562 }
563 set_branch_analysis(nullptr);
564 set_bytecode_iterator(nullptr);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100565 DCHECK(exception_handlers_.empty());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000566}
567
Ben Murdoch097c5b22016-05-18 11:27:45 +0100568void BytecodeGraphBuilder::VisitLdaZero() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000569 Node* node = jsgraph()->ZeroConstant();
570 environment()->BindAccumulator(node);
571}
572
Ben Murdoch097c5b22016-05-18 11:27:45 +0100573void BytecodeGraphBuilder::VisitLdaSmi8() {
574 Node* node = jsgraph()->Constant(bytecode_iterator().GetImmediateOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000575 environment()->BindAccumulator(node);
576}
577
Ben Murdoch097c5b22016-05-18 11:27:45 +0100578void BytecodeGraphBuilder::VisitLdaConstantWide() {
579 Node* node =
580 jsgraph()->Constant(bytecode_iterator().GetConstantForIndexOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000581 environment()->BindAccumulator(node);
582}
583
Ben Murdoch097c5b22016-05-18 11:27:45 +0100584void BytecodeGraphBuilder::VisitLdaConstant() {
585 Node* node =
586 jsgraph()->Constant(bytecode_iterator().GetConstantForIndexOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000587 environment()->BindAccumulator(node);
588}
589
Ben Murdoch097c5b22016-05-18 11:27:45 +0100590void BytecodeGraphBuilder::VisitLdaUndefined() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000591 Node* node = jsgraph()->UndefinedConstant();
592 environment()->BindAccumulator(node);
593}
594
Ben Murdoch097c5b22016-05-18 11:27:45 +0100595void BytecodeGraphBuilder::VisitLdaNull() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000596 Node* node = jsgraph()->NullConstant();
597 environment()->BindAccumulator(node);
598}
599
Ben Murdoch097c5b22016-05-18 11:27:45 +0100600void BytecodeGraphBuilder::VisitLdaTheHole() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000601 Node* node = jsgraph()->TheHoleConstant();
602 environment()->BindAccumulator(node);
603}
604
Ben Murdoch097c5b22016-05-18 11:27:45 +0100605void BytecodeGraphBuilder::VisitLdaTrue() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000606 Node* node = jsgraph()->TrueConstant();
607 environment()->BindAccumulator(node);
608}
609
Ben Murdoch097c5b22016-05-18 11:27:45 +0100610void BytecodeGraphBuilder::VisitLdaFalse() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000611 Node* node = jsgraph()->FalseConstant();
612 environment()->BindAccumulator(node);
613}
614
Ben Murdoch097c5b22016-05-18 11:27:45 +0100615void BytecodeGraphBuilder::VisitLdar() {
616 Node* value =
617 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000618 environment()->BindAccumulator(value);
619}
620
Ben Murdoch097c5b22016-05-18 11:27:45 +0100621void BytecodeGraphBuilder::VisitStar() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000622 Node* value = environment()->LookupAccumulator();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100623 environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0), value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000624}
625
Ben Murdoch097c5b22016-05-18 11:27:45 +0100626void BytecodeGraphBuilder::VisitMov() {
627 Node* value =
628 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
629 environment()->BindRegister(bytecode_iterator().GetRegisterOperand(1), value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000630}
631
Ben Murdoch097c5b22016-05-18 11:27:45 +0100632void BytecodeGraphBuilder::VisitMovWide() { VisitMov(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000633
634void BytecodeGraphBuilder::BuildLoadGlobal(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000635 TypeofMode typeof_mode) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100636 FrameStateBeforeAndAfter states(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000637 Handle<Name> name =
Ben Murdoch097c5b22016-05-18 11:27:45 +0100638 Handle<Name>::cast(bytecode_iterator().GetConstantForIndexOperand(0));
639 VectorSlotPair feedback =
640 CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(1));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000641
642 const Operator* op = javascript()->LoadGlobal(name, feedback, typeof_mode);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100643 Node* node = NewNode(op, GetFunctionClosure());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000644 environment()->BindAccumulator(node, &states);
645}
646
Ben Murdoch097c5b22016-05-18 11:27:45 +0100647void BytecodeGraphBuilder::VisitLdaGlobal() {
648 BuildLoadGlobal(TypeofMode::NOT_INSIDE_TYPEOF);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000649}
650
Ben Murdoch097c5b22016-05-18 11:27:45 +0100651void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeof() {
652 BuildLoadGlobal(TypeofMode::INSIDE_TYPEOF);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000653}
654
Ben Murdoch097c5b22016-05-18 11:27:45 +0100655void BytecodeGraphBuilder::VisitLdaGlobalWide() {
656 BuildLoadGlobal(TypeofMode::NOT_INSIDE_TYPEOF);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000657}
658
Ben Murdoch097c5b22016-05-18 11:27:45 +0100659void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeofWide() {
660 BuildLoadGlobal(TypeofMode::INSIDE_TYPEOF);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000661}
662
Ben Murdoch097c5b22016-05-18 11:27:45 +0100663void BytecodeGraphBuilder::BuildStoreGlobal(LanguageMode language_mode) {
664 FrameStateBeforeAndAfter states(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000665 Handle<Name> name =
Ben Murdoch097c5b22016-05-18 11:27:45 +0100666 Handle<Name>::cast(bytecode_iterator().GetConstantForIndexOperand(0));
667 VectorSlotPair feedback =
668 CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(1));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000669 Node* value = environment()->LookupAccumulator();
670
Ben Murdoch097c5b22016-05-18 11:27:45 +0100671 const Operator* op = javascript()->StoreGlobal(language_mode, name, feedback);
672 Node* node = NewNode(op, value, GetFunctionClosure());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000673 environment()->RecordAfterState(node, &states);
674}
675
Ben Murdoch097c5b22016-05-18 11:27:45 +0100676void BytecodeGraphBuilder::VisitStaGlobalSloppy() {
677 BuildStoreGlobal(LanguageMode::SLOPPY);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000678}
679
Ben Murdoch097c5b22016-05-18 11:27:45 +0100680void BytecodeGraphBuilder::VisitStaGlobalStrict() {
681 BuildStoreGlobal(LanguageMode::STRICT);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000682}
683
Ben Murdoch097c5b22016-05-18 11:27:45 +0100684void BytecodeGraphBuilder::VisitStaGlobalSloppyWide() {
685 BuildStoreGlobal(LanguageMode::SLOPPY);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000686}
687
Ben Murdoch097c5b22016-05-18 11:27:45 +0100688void BytecodeGraphBuilder::VisitStaGlobalStrictWide() {
689 BuildStoreGlobal(LanguageMode::STRICT);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000690}
691
Ben Murdoch097c5b22016-05-18 11:27:45 +0100692void BytecodeGraphBuilder::VisitLdaContextSlot() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000693 // TODO(mythria): LoadContextSlots are unrolled by the required depth when
694 // generating bytecode. Hence the value of depth is always 0. Update this
695 // code, when the implementation changes.
696 // TODO(mythria): immutable flag is also set to false. This information is not
697 // available in bytecode array. update this code when the implementation
698 // changes.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100699 const Operator* op = javascript()->LoadContext(
700 0, bytecode_iterator().GetIndexOperand(1), false);
701 Node* context =
702 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000703 Node* node = NewNode(op, context);
704 environment()->BindAccumulator(node);
705}
706
Ben Murdoch097c5b22016-05-18 11:27:45 +0100707void BytecodeGraphBuilder::VisitLdaContextSlotWide() { VisitLdaContextSlot(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000708
Ben Murdoch097c5b22016-05-18 11:27:45 +0100709void BytecodeGraphBuilder::VisitStaContextSlot() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000710 // TODO(mythria): LoadContextSlots are unrolled by the required depth when
711 // generating bytecode. Hence the value of depth is always 0. Update this
712 // code, when the implementation changes.
713 const Operator* op =
Ben Murdoch097c5b22016-05-18 11:27:45 +0100714 javascript()->StoreContext(0, bytecode_iterator().GetIndexOperand(1));
715 Node* context =
716 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000717 Node* value = environment()->LookupAccumulator();
718 NewNode(op, context, value);
719}
720
Ben Murdoch097c5b22016-05-18 11:27:45 +0100721void BytecodeGraphBuilder::VisitStaContextSlotWide() { VisitStaContextSlot(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000722
Ben Murdoch097c5b22016-05-18 11:27:45 +0100723void BytecodeGraphBuilder::BuildLdaLookupSlot(TypeofMode typeof_mode) {
724 FrameStateBeforeAndAfter states(this);
725 Node* name =
726 jsgraph()->Constant(bytecode_iterator().GetConstantForIndexOperand(0));
727 const Operator* op =
728 javascript()->CallRuntime(typeof_mode == TypeofMode::NOT_INSIDE_TYPEOF
729 ? Runtime::kLoadLookupSlot
730 : Runtime::kLoadLookupSlotInsideTypeof);
731 Node* value = NewNode(op, name);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000732 environment()->BindAccumulator(value, &states);
733}
734
Ben Murdoch097c5b22016-05-18 11:27:45 +0100735void BytecodeGraphBuilder::VisitLdaLookupSlot() {
736 BuildLdaLookupSlot(TypeofMode::NOT_INSIDE_TYPEOF);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000737}
738
Ben Murdoch097c5b22016-05-18 11:27:45 +0100739void BytecodeGraphBuilder::VisitLdaLookupSlotInsideTypeof() {
740 BuildLdaLookupSlot(TypeofMode::INSIDE_TYPEOF);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000741}
742
Ben Murdoch097c5b22016-05-18 11:27:45 +0100743void BytecodeGraphBuilder::BuildStaLookupSlot(LanguageMode language_mode) {
744 FrameStateBeforeAndAfter states(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000745 Node* value = environment()->LookupAccumulator();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100746 Node* name =
747 jsgraph()->Constant(bytecode_iterator().GetConstantForIndexOperand(0));
748 const Operator* op = javascript()->CallRuntime(
749 is_strict(language_mode) ? Runtime::kStoreLookupSlot_Strict
750 : Runtime::kStoreLookupSlot_Sloppy);
751 Node* store = NewNode(op, name, value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000752 environment()->BindAccumulator(store, &states);
753}
754
Ben Murdoch097c5b22016-05-18 11:27:45 +0100755void BytecodeGraphBuilder::VisitLdaLookupSlotWide() { VisitLdaLookupSlot(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000756
Ben Murdoch097c5b22016-05-18 11:27:45 +0100757void BytecodeGraphBuilder::VisitLdaLookupSlotInsideTypeofWide() {
758 VisitLdaLookupSlotInsideTypeof();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000759}
760
Ben Murdoch097c5b22016-05-18 11:27:45 +0100761void BytecodeGraphBuilder::VisitStaLookupSlotSloppy() {
762 BuildStaLookupSlot(LanguageMode::SLOPPY);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000763}
764
Ben Murdoch097c5b22016-05-18 11:27:45 +0100765void BytecodeGraphBuilder::VisitStaLookupSlotStrict() {
766 BuildStaLookupSlot(LanguageMode::STRICT);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000767}
768
Ben Murdoch097c5b22016-05-18 11:27:45 +0100769void BytecodeGraphBuilder::VisitStaLookupSlotSloppyWide() {
770 VisitStaLookupSlotSloppy();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000771}
772
Ben Murdoch097c5b22016-05-18 11:27:45 +0100773void BytecodeGraphBuilder::VisitStaLookupSlotStrictWide() {
774 VisitStaLookupSlotStrict();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000775}
776
Ben Murdoch097c5b22016-05-18 11:27:45 +0100777void BytecodeGraphBuilder::BuildNamedLoad() {
778 FrameStateBeforeAndAfter states(this);
779 Node* object =
780 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000781 Handle<Name> name =
Ben Murdoch097c5b22016-05-18 11:27:45 +0100782 Handle<Name>::cast(bytecode_iterator().GetConstantForIndexOperand(1));
783 VectorSlotPair feedback =
784 CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(2));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000785
Ben Murdoch097c5b22016-05-18 11:27:45 +0100786 const Operator* op = javascript()->LoadNamed(name, feedback);
787 Node* node = NewNode(op, object, GetFunctionClosure());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000788 environment()->BindAccumulator(node, &states);
789}
790
Ben Murdoch097c5b22016-05-18 11:27:45 +0100791void BytecodeGraphBuilder::VisitLoadIC() { BuildNamedLoad(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000792
Ben Murdoch097c5b22016-05-18 11:27:45 +0100793void BytecodeGraphBuilder::VisitLoadICWide() { BuildNamedLoad(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000794
Ben Murdoch097c5b22016-05-18 11:27:45 +0100795void BytecodeGraphBuilder::BuildKeyedLoad() {
796 FrameStateBeforeAndAfter states(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000797 Node* key = environment()->LookupAccumulator();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100798 Node* object =
799 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
800 VectorSlotPair feedback =
801 CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(1));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000802
Ben Murdoch097c5b22016-05-18 11:27:45 +0100803 const Operator* op = javascript()->LoadProperty(feedback);
804 Node* node = NewNode(op, object, key, GetFunctionClosure());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000805 environment()->BindAccumulator(node, &states);
806}
807
Ben Murdoch097c5b22016-05-18 11:27:45 +0100808void BytecodeGraphBuilder::VisitKeyedLoadIC() { BuildKeyedLoad(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000809
Ben Murdoch097c5b22016-05-18 11:27:45 +0100810void BytecodeGraphBuilder::VisitKeyedLoadICWide() { BuildKeyedLoad(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000811
Ben Murdoch097c5b22016-05-18 11:27:45 +0100812void BytecodeGraphBuilder::BuildNamedStore(LanguageMode language_mode) {
813 FrameStateBeforeAndAfter states(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000814 Node* value = environment()->LookupAccumulator();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100815 Node* object =
816 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000817 Handle<Name> name =
Ben Murdoch097c5b22016-05-18 11:27:45 +0100818 Handle<Name>::cast(bytecode_iterator().GetConstantForIndexOperand(1));
819 VectorSlotPair feedback =
820 CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(2));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000821
Ben Murdoch097c5b22016-05-18 11:27:45 +0100822 const Operator* op = javascript()->StoreNamed(language_mode, name, feedback);
823 Node* node = NewNode(op, object, value, GetFunctionClosure());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000824 environment()->RecordAfterState(node, &states);
825}
826
Ben Murdoch097c5b22016-05-18 11:27:45 +0100827void BytecodeGraphBuilder::VisitStoreICSloppy() {
828 BuildNamedStore(LanguageMode::SLOPPY);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000829}
830
Ben Murdoch097c5b22016-05-18 11:27:45 +0100831void BytecodeGraphBuilder::VisitStoreICStrict() {
832 BuildNamedStore(LanguageMode::STRICT);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000833}
834
Ben Murdoch097c5b22016-05-18 11:27:45 +0100835void BytecodeGraphBuilder::VisitStoreICSloppyWide() {
836 BuildNamedStore(LanguageMode::SLOPPY);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000837}
838
Ben Murdoch097c5b22016-05-18 11:27:45 +0100839void BytecodeGraphBuilder::VisitStoreICStrictWide() {
840 BuildNamedStore(LanguageMode::STRICT);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000841}
842
Ben Murdoch097c5b22016-05-18 11:27:45 +0100843void BytecodeGraphBuilder::BuildKeyedStore(LanguageMode language_mode) {
844 FrameStateBeforeAndAfter states(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000845 Node* value = environment()->LookupAccumulator();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100846 Node* object =
847 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
848 Node* key =
849 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
850 VectorSlotPair feedback =
851 CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(2));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000852
Ben Murdoch097c5b22016-05-18 11:27:45 +0100853 const Operator* op = javascript()->StoreProperty(language_mode, feedback);
854 Node* node = NewNode(op, object, key, value, GetFunctionClosure());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000855 environment()->RecordAfterState(node, &states);
856}
857
Ben Murdoch097c5b22016-05-18 11:27:45 +0100858void BytecodeGraphBuilder::VisitKeyedStoreICSloppy() {
859 BuildKeyedStore(LanguageMode::SLOPPY);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000860}
861
Ben Murdoch097c5b22016-05-18 11:27:45 +0100862void BytecodeGraphBuilder::VisitKeyedStoreICStrict() {
863 BuildKeyedStore(LanguageMode::STRICT);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000864}
865
Ben Murdoch097c5b22016-05-18 11:27:45 +0100866void BytecodeGraphBuilder::VisitKeyedStoreICSloppyWide() {
867 BuildKeyedStore(LanguageMode::SLOPPY);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000868}
869
Ben Murdoch097c5b22016-05-18 11:27:45 +0100870void BytecodeGraphBuilder::VisitKeyedStoreICStrictWide() {
871 BuildKeyedStore(LanguageMode::STRICT);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000872}
873
Ben Murdoch097c5b22016-05-18 11:27:45 +0100874void BytecodeGraphBuilder::VisitPushContext() {
875 Node* new_context = environment()->LookupAccumulator();
876 environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0),
877 environment()->Context());
878 environment()->SetContext(new_context);
879}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000880
Ben Murdoch097c5b22016-05-18 11:27:45 +0100881void BytecodeGraphBuilder::VisitPopContext() {
882 Node* context =
883 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000884 environment()->SetContext(context);
885}
886
Ben Murdoch097c5b22016-05-18 11:27:45 +0100887void BytecodeGraphBuilder::VisitCreateClosure() {
888 Handle<SharedFunctionInfo> shared_info = Handle<SharedFunctionInfo>::cast(
889 bytecode_iterator().GetConstantForIndexOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000890 PretenureFlag tenured =
Ben Murdoch097c5b22016-05-18 11:27:45 +0100891 bytecode_iterator().GetImmediateOperand(1) ? TENURED : NOT_TENURED;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000892 const Operator* op = javascript()->CreateClosure(shared_info, tenured);
893 Node* closure = NewNode(op);
894 environment()->BindAccumulator(closure);
895}
896
Ben Murdoch097c5b22016-05-18 11:27:45 +0100897void BytecodeGraphBuilder::VisitCreateClosureWide() { VisitCreateClosure(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000898
Ben Murdoch097c5b22016-05-18 11:27:45 +0100899void BytecodeGraphBuilder::BuildCreateArguments(CreateArgumentsType type) {
900 FrameStateBeforeAndAfter states(this);
901 const Operator* op = javascript()->CreateArguments(type);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000902 Node* object = NewNode(op, GetFunctionClosure());
903 environment()->BindAccumulator(object, &states);
904}
905
Ben Murdoch097c5b22016-05-18 11:27:45 +0100906void BytecodeGraphBuilder::VisitCreateMappedArguments() {
907 BuildCreateArguments(CreateArgumentsType::kMappedArguments);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000908}
909
Ben Murdoch097c5b22016-05-18 11:27:45 +0100910void BytecodeGraphBuilder::VisitCreateUnmappedArguments() {
911 BuildCreateArguments(CreateArgumentsType::kUnmappedArguments);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000912}
913
Ben Murdoch097c5b22016-05-18 11:27:45 +0100914void BytecodeGraphBuilder::VisitCreateRestParameter() {
915 BuildCreateArguments(CreateArgumentsType::kRestParameter);
916}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000917
Ben Murdoch097c5b22016-05-18 11:27:45 +0100918void BytecodeGraphBuilder::BuildCreateLiteral(const Operator* op) {
919 FrameStateBeforeAndAfter states(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000920 Node* literal = NewNode(op, GetFunctionClosure());
921 environment()->BindAccumulator(literal, &states);
922}
923
Ben Murdoch097c5b22016-05-18 11:27:45 +0100924void BytecodeGraphBuilder::BuildCreateRegExpLiteral() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000925 Handle<String> constant_pattern =
Ben Murdoch097c5b22016-05-18 11:27:45 +0100926 Handle<String>::cast(bytecode_iterator().GetConstantForIndexOperand(0));
927 int literal_index = bytecode_iterator().GetIndexOperand(1);
928 int literal_flags = bytecode_iterator().GetImmediateOperand(2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000929 const Operator* op = javascript()->CreateLiteralRegExp(
930 constant_pattern, literal_flags, literal_index);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100931 BuildCreateLiteral(op);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000932}
933
Ben Murdoch097c5b22016-05-18 11:27:45 +0100934void BytecodeGraphBuilder::VisitCreateRegExpLiteral() {
935 BuildCreateRegExpLiteral();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000936}
937
Ben Murdoch097c5b22016-05-18 11:27:45 +0100938void BytecodeGraphBuilder::VisitCreateRegExpLiteralWide() {
939 BuildCreateRegExpLiteral();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000940}
941
Ben Murdoch097c5b22016-05-18 11:27:45 +0100942void BytecodeGraphBuilder::BuildCreateArrayLiteral() {
943 Handle<FixedArray> constant_elements = Handle<FixedArray>::cast(
944 bytecode_iterator().GetConstantForIndexOperand(0));
945 int literal_index = bytecode_iterator().GetIndexOperand(1);
946 int literal_flags = bytecode_iterator().GetImmediateOperand(2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000947 const Operator* op = javascript()->CreateLiteralArray(
948 constant_elements, literal_flags, literal_index);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100949 BuildCreateLiteral(op);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000950}
951
Ben Murdoch097c5b22016-05-18 11:27:45 +0100952void BytecodeGraphBuilder::VisitCreateArrayLiteral() {
953 BuildCreateArrayLiteral();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000954}
955
Ben Murdoch097c5b22016-05-18 11:27:45 +0100956void BytecodeGraphBuilder::VisitCreateArrayLiteralWide() {
957 BuildCreateArrayLiteral();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000958}
959
Ben Murdoch097c5b22016-05-18 11:27:45 +0100960void BytecodeGraphBuilder::BuildCreateObjectLiteral() {
961 Handle<FixedArray> constant_properties = Handle<FixedArray>::cast(
962 bytecode_iterator().GetConstantForIndexOperand(0));
963 int literal_index = bytecode_iterator().GetIndexOperand(1);
964 int literal_flags = bytecode_iterator().GetImmediateOperand(2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000965 const Operator* op = javascript()->CreateLiteralObject(
966 constant_properties, literal_flags, literal_index);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100967 BuildCreateLiteral(op);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000968}
969
Ben Murdoch097c5b22016-05-18 11:27:45 +0100970void BytecodeGraphBuilder::VisitCreateObjectLiteral() {
971 BuildCreateObjectLiteral();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000972}
973
Ben Murdoch097c5b22016-05-18 11:27:45 +0100974void BytecodeGraphBuilder::VisitCreateObjectLiteralWide() {
975 BuildCreateObjectLiteral();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000976}
977
978
979Node* BytecodeGraphBuilder::ProcessCallArguments(const Operator* call_op,
980 Node* callee,
981 interpreter::Register receiver,
982 size_t arity) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100983 Node** all = local_zone()->NewArray<Node*>(static_cast<int>(arity));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000984 all[0] = callee;
985 all[1] = environment()->LookupRegister(receiver);
986 int receiver_index = receiver.index();
987 for (int i = 2; i < static_cast<int>(arity); ++i) {
988 all[i] = environment()->LookupRegister(
989 interpreter::Register(receiver_index + i - 1));
990 }
991 Node* value = MakeNode(call_op, static_cast<int>(arity), all, false);
992 return value;
993}
994
Ben Murdoch097c5b22016-05-18 11:27:45 +0100995void BytecodeGraphBuilder::BuildCall(TailCallMode tail_call_mode) {
996 FrameStateBeforeAndAfter states(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000997 // TODO(rmcilroy): Set receiver_hint correctly based on whether the receiver
998 // register has been loaded with null / undefined explicitly or we are sure it
999 // is not null / undefined.
1000 ConvertReceiverMode receiver_hint = ConvertReceiverMode::kAny;
Ben Murdoch097c5b22016-05-18 11:27:45 +01001001 Node* callee =
1002 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1003 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
1004 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
1005 VectorSlotPair feedback =
1006 CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(3));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001007
1008 const Operator* call = javascript()->CallFunction(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001009 arg_count + 1, feedback, receiver_hint, tail_call_mode);
1010 Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001011 environment()->BindAccumulator(value, &states);
1012}
1013
Ben Murdoch097c5b22016-05-18 11:27:45 +01001014void BytecodeGraphBuilder::VisitCall() { BuildCall(TailCallMode::kDisallow); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001015
Ben Murdoch097c5b22016-05-18 11:27:45 +01001016void BytecodeGraphBuilder::VisitCallWide() {
1017 BuildCall(TailCallMode::kDisallow);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001018}
1019
Ben Murdoch097c5b22016-05-18 11:27:45 +01001020void BytecodeGraphBuilder::VisitTailCall() { BuildCall(TailCallMode::kAllow); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001021
Ben Murdoch097c5b22016-05-18 11:27:45 +01001022void BytecodeGraphBuilder::VisitTailCallWide() {
1023 BuildCall(TailCallMode::kAllow);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001024}
1025
Ben Murdoch097c5b22016-05-18 11:27:45 +01001026void BytecodeGraphBuilder::BuildCallJSRuntime() {
1027 FrameStateBeforeAndAfter states(this);
1028 Node* callee =
1029 BuildLoadNativeContextField(bytecode_iterator().GetIndexOperand(0));
1030 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
1031 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001032
1033 // Create node to perform the JS runtime call.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001034 const Operator* call = javascript()->CallFunction(arg_count + 1);
1035 Node* value = ProcessCallArguments(call, callee, receiver, arg_count + 1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001036 environment()->BindAccumulator(value, &states);
1037}
1038
Ben Murdoch097c5b22016-05-18 11:27:45 +01001039void BytecodeGraphBuilder::VisitCallJSRuntime() { BuildCallJSRuntime(); }
1040
1041void BytecodeGraphBuilder::VisitCallJSRuntimeWide() { BuildCallJSRuntime(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001042
1043Node* BytecodeGraphBuilder::ProcessCallRuntimeArguments(
1044 const Operator* call_runtime_op, interpreter::Register first_arg,
1045 size_t arity) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001046 Node** all = local_zone()->NewArray<Node*>(arity);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001047 int first_arg_index = first_arg.index();
1048 for (int i = 0; i < static_cast<int>(arity); ++i) {
1049 all[i] = environment()->LookupRegister(
1050 interpreter::Register(first_arg_index + i));
1051 }
1052 Node* value = MakeNode(call_runtime_op, static_cast<int>(arity), all, false);
1053 return value;
1054}
1055
Ben Murdoch097c5b22016-05-18 11:27:45 +01001056void BytecodeGraphBuilder::BuildCallRuntime() {
1057 FrameStateBeforeAndAfter states(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001058 Runtime::FunctionId functionId =
Ben Murdoch097c5b22016-05-18 11:27:45 +01001059 static_cast<Runtime::FunctionId>(bytecode_iterator().GetIndexOperand(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
1063 // Create node to perform the runtime call.
1064 const Operator* call = javascript()->CallRuntime(functionId, arg_count);
1065 Node* value = ProcessCallRuntimeArguments(call, first_arg, arg_count);
1066 environment()->BindAccumulator(value, &states);
1067}
1068
Ben Murdoch097c5b22016-05-18 11:27:45 +01001069void BytecodeGraphBuilder::VisitCallRuntime() { BuildCallRuntime(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001070
Ben Murdoch097c5b22016-05-18 11:27:45 +01001071void BytecodeGraphBuilder::VisitCallRuntimeWide() { BuildCallRuntime(); }
1072
1073void BytecodeGraphBuilder::BuildCallRuntimeForPair() {
1074 FrameStateBeforeAndAfter states(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001075 Runtime::FunctionId functionId =
Ben Murdoch097c5b22016-05-18 11:27:45 +01001076 static_cast<Runtime::FunctionId>(bytecode_iterator().GetIndexOperand(0));
1077 interpreter::Register first_arg = bytecode_iterator().GetRegisterOperand(1);
1078 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
1079 interpreter::Register first_return =
1080 bytecode_iterator().GetRegisterOperand(3);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001081
1082 // Create node to perform the runtime call.
1083 const Operator* call = javascript()->CallRuntime(functionId, arg_count);
1084 Node* return_pair = ProcessCallRuntimeArguments(call, first_arg, arg_count);
1085 environment()->BindRegistersToProjections(first_return, return_pair, &states);
1086}
1087
Ben Murdoch097c5b22016-05-18 11:27:45 +01001088void BytecodeGraphBuilder::VisitCallRuntimeForPair() {
1089 BuildCallRuntimeForPair();
1090}
1091
1092void BytecodeGraphBuilder::VisitCallRuntimeForPairWide() {
1093 BuildCallRuntimeForPair();
1094}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001095
1096Node* BytecodeGraphBuilder::ProcessCallNewArguments(
Ben Murdoch097c5b22016-05-18 11:27:45 +01001097 const Operator* call_new_op, Node* callee, Node* new_target,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001098 interpreter::Register first_arg, size_t arity) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001099 Node** all = local_zone()->NewArray<Node*>(arity);
1100 all[0] = new_target;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001101 int first_arg_index = first_arg.index();
1102 for (int i = 1; i < static_cast<int>(arity) - 1; ++i) {
1103 all[i] = environment()->LookupRegister(
1104 interpreter::Register(first_arg_index + i - 1));
1105 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01001106 all[arity - 1] = callee;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001107 Node* value = MakeNode(call_new_op, static_cast<int>(arity), all, false);
1108 return value;
1109}
1110
Ben Murdoch097c5b22016-05-18 11:27:45 +01001111void BytecodeGraphBuilder::BuildCallConstruct() {
1112 FrameStateBeforeAndAfter states(this);
1113 interpreter::Register callee_reg = bytecode_iterator().GetRegisterOperand(0);
1114 interpreter::Register first_arg = bytecode_iterator().GetRegisterOperand(1);
1115 size_t arg_count = bytecode_iterator().GetRegisterCountOperand(2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001116
Ben Murdoch097c5b22016-05-18 11:27:45 +01001117 Node* new_target = environment()->LookupAccumulator();
1118 Node* callee = environment()->LookupRegister(callee_reg);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001119 // TODO(turbofan): Pass the feedback here.
1120 const Operator* call = javascript()->CallConstruct(
1121 static_cast<int>(arg_count) + 2, VectorSlotPair());
Ben Murdoch097c5b22016-05-18 11:27:45 +01001122 Node* value = ProcessCallNewArguments(call, callee, new_target, first_arg,
1123 arg_count + 2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001124 environment()->BindAccumulator(value, &states);
1125}
1126
Ben Murdoch097c5b22016-05-18 11:27:45 +01001127void BytecodeGraphBuilder::VisitNew() { BuildCallConstruct(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001128
Ben Murdoch097c5b22016-05-18 11:27:45 +01001129void BytecodeGraphBuilder::VisitNewWide() { BuildCallConstruct(); }
1130
1131void BytecodeGraphBuilder::BuildThrow() {
1132 FrameStateBeforeAndAfter states(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001133 Node* value = environment()->LookupAccumulator();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001134 Node* call = NewNode(javascript()->CallRuntime(Runtime::kThrow), value);
1135 environment()->BindAccumulator(call, &states);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001136}
1137
Ben Murdoch097c5b22016-05-18 11:27:45 +01001138void BytecodeGraphBuilder::VisitThrow() {
1139 BuildThrow();
1140 Node* call = environment()->LookupAccumulator();
1141 Node* control = NewNode(common()->Throw(), call);
1142 MergeControlToLeaveFunction(control);
1143}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001144
Ben Murdoch097c5b22016-05-18 11:27:45 +01001145void BytecodeGraphBuilder::VisitReThrow() {
1146 Node* value = environment()->LookupAccumulator();
1147 Node* call = NewNode(javascript()->CallRuntime(Runtime::kReThrow), value);
1148 Node* control = NewNode(common()->Throw(), call);
1149 MergeControlToLeaveFunction(control);
1150}
1151
1152void BytecodeGraphBuilder::BuildBinaryOp(const Operator* js_op) {
1153 FrameStateBeforeAndAfter states(this);
1154 Node* left =
1155 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001156 Node* right = environment()->LookupAccumulator();
1157 Node* node = NewNode(js_op, left, right);
1158 environment()->BindAccumulator(node, &states);
1159}
1160
Ben Murdoch097c5b22016-05-18 11:27:45 +01001161void BytecodeGraphBuilder::VisitAdd() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001162 BinaryOperationHints hints = BinaryOperationHints::Any();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001163 BuildBinaryOp(javascript()->Add(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001164}
1165
Ben Murdoch097c5b22016-05-18 11:27:45 +01001166void BytecodeGraphBuilder::VisitSub() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001167 BinaryOperationHints hints = BinaryOperationHints::Any();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001168 BuildBinaryOp(javascript()->Subtract(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001169}
1170
Ben Murdoch097c5b22016-05-18 11:27:45 +01001171void BytecodeGraphBuilder::VisitMul() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001172 BinaryOperationHints hints = BinaryOperationHints::Any();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001173 BuildBinaryOp(javascript()->Multiply(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001174}
1175
Ben Murdoch097c5b22016-05-18 11:27:45 +01001176void BytecodeGraphBuilder::VisitDiv() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001177 BinaryOperationHints hints = BinaryOperationHints::Any();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001178 BuildBinaryOp(javascript()->Divide(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001179}
1180
Ben Murdoch097c5b22016-05-18 11:27:45 +01001181void BytecodeGraphBuilder::VisitMod() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001182 BinaryOperationHints hints = BinaryOperationHints::Any();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001183 BuildBinaryOp(javascript()->Modulus(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001184}
1185
Ben Murdoch097c5b22016-05-18 11:27:45 +01001186void BytecodeGraphBuilder::VisitBitwiseOr() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001187 BinaryOperationHints hints = BinaryOperationHints::Any();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001188 BuildBinaryOp(javascript()->BitwiseOr(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001189}
1190
Ben Murdoch097c5b22016-05-18 11:27:45 +01001191void BytecodeGraphBuilder::VisitBitwiseXor() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001192 BinaryOperationHints hints = BinaryOperationHints::Any();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001193 BuildBinaryOp(javascript()->BitwiseXor(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001194}
1195
Ben Murdoch097c5b22016-05-18 11:27:45 +01001196void BytecodeGraphBuilder::VisitBitwiseAnd() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001197 BinaryOperationHints hints = BinaryOperationHints::Any();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001198 BuildBinaryOp(javascript()->BitwiseAnd(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001199}
1200
Ben Murdoch097c5b22016-05-18 11:27:45 +01001201void BytecodeGraphBuilder::VisitShiftLeft() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001202 BinaryOperationHints hints = BinaryOperationHints::Any();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001203 BuildBinaryOp(javascript()->ShiftLeft(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001204}
1205
Ben Murdoch097c5b22016-05-18 11:27:45 +01001206void BytecodeGraphBuilder::VisitShiftRight() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001207 BinaryOperationHints hints = BinaryOperationHints::Any();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001208 BuildBinaryOp(javascript()->ShiftRight(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001209}
1210
Ben Murdoch097c5b22016-05-18 11:27:45 +01001211void BytecodeGraphBuilder::VisitShiftRightLogical() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001212 BinaryOperationHints hints = BinaryOperationHints::Any();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001213 BuildBinaryOp(javascript()->ShiftRightLogical(hints));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001214}
1215
Ben Murdoch097c5b22016-05-18 11:27:45 +01001216void BytecodeGraphBuilder::VisitInc() {
1217 FrameStateBeforeAndAfter states(this);
1218 const Operator* js_op = javascript()->Add(BinaryOperationHints::Any());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001219 Node* node = NewNode(js_op, environment()->LookupAccumulator(),
1220 jsgraph()->OneConstant());
1221 environment()->BindAccumulator(node, &states);
1222}
1223
Ben Murdoch097c5b22016-05-18 11:27:45 +01001224void BytecodeGraphBuilder::VisitDec() {
1225 FrameStateBeforeAndAfter states(this);
1226 const Operator* js_op = javascript()->Subtract(BinaryOperationHints::Any());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001227 Node* node = NewNode(js_op, environment()->LookupAccumulator(),
1228 jsgraph()->OneConstant());
1229 environment()->BindAccumulator(node, &states);
1230}
1231
Ben Murdoch097c5b22016-05-18 11:27:45 +01001232void BytecodeGraphBuilder::VisitLogicalNot() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001233 Node* value = NewNode(javascript()->ToBoolean(ToBooleanHint::kAny),
1234 environment()->LookupAccumulator());
1235 Node* node = NewNode(common()->Select(MachineRepresentation::kTagged), value,
1236 jsgraph()->FalseConstant(), jsgraph()->TrueConstant());
1237 environment()->BindAccumulator(node);
1238}
1239
Ben Murdoch097c5b22016-05-18 11:27:45 +01001240void BytecodeGraphBuilder::VisitTypeOf() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001241 Node* node =
1242 NewNode(javascript()->TypeOf(), environment()->LookupAccumulator());
1243 environment()->BindAccumulator(node);
1244}
1245
Ben Murdoch097c5b22016-05-18 11:27:45 +01001246void BytecodeGraphBuilder::BuildDelete(LanguageMode language_mode) {
1247 FrameStateBeforeAndAfter states(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001248 Node* key = environment()->LookupAccumulator();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001249 Node* object =
1250 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001251 Node* node =
Ben Murdoch097c5b22016-05-18 11:27:45 +01001252 NewNode(javascript()->DeleteProperty(language_mode), object, key);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001253 environment()->BindAccumulator(node, &states);
1254}
1255
Ben Murdoch097c5b22016-05-18 11:27:45 +01001256void BytecodeGraphBuilder::VisitDeletePropertyStrict() {
1257 BuildDelete(LanguageMode::STRICT);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001258}
1259
Ben Murdoch097c5b22016-05-18 11:27:45 +01001260void BytecodeGraphBuilder::VisitDeletePropertySloppy() {
1261 BuildDelete(LanguageMode::SLOPPY);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001262}
1263
Ben Murdoch097c5b22016-05-18 11:27:45 +01001264void BytecodeGraphBuilder::BuildCompareOp(const Operator* js_op) {
1265 FrameStateBeforeAndAfter states(this);
1266 Node* left =
1267 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001268 Node* right = environment()->LookupAccumulator();
1269 Node* node = NewNode(js_op, left, right);
1270 environment()->BindAccumulator(node, &states);
1271}
1272
Ben Murdoch097c5b22016-05-18 11:27:45 +01001273void BytecodeGraphBuilder::VisitTestEqual() {
1274 BuildCompareOp(javascript()->Equal());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001275}
1276
Ben Murdoch097c5b22016-05-18 11:27:45 +01001277void BytecodeGraphBuilder::VisitTestNotEqual() {
1278 BuildCompareOp(javascript()->NotEqual());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001279}
1280
Ben Murdoch097c5b22016-05-18 11:27:45 +01001281void BytecodeGraphBuilder::VisitTestEqualStrict() {
1282 BuildCompareOp(javascript()->StrictEqual());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001283}
1284
Ben Murdoch097c5b22016-05-18 11:27:45 +01001285void BytecodeGraphBuilder::VisitTestNotEqualStrict() {
1286 BuildCompareOp(javascript()->StrictNotEqual());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001287}
1288
Ben Murdoch097c5b22016-05-18 11:27:45 +01001289void BytecodeGraphBuilder::VisitTestLessThan() {
1290 BuildCompareOp(javascript()->LessThan());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001291}
1292
Ben Murdoch097c5b22016-05-18 11:27:45 +01001293void BytecodeGraphBuilder::VisitTestGreaterThan() {
1294 BuildCompareOp(javascript()->GreaterThan());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001295}
1296
Ben Murdoch097c5b22016-05-18 11:27:45 +01001297void BytecodeGraphBuilder::VisitTestLessThanOrEqual() {
1298 BuildCompareOp(javascript()->LessThanOrEqual());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001299}
1300
Ben Murdoch097c5b22016-05-18 11:27:45 +01001301void BytecodeGraphBuilder::VisitTestGreaterThanOrEqual() {
1302 BuildCompareOp(javascript()->GreaterThanOrEqual());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001303}
1304
Ben Murdoch097c5b22016-05-18 11:27:45 +01001305void BytecodeGraphBuilder::VisitTestIn() {
1306 BuildCompareOp(javascript()->HasProperty());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001307}
1308
Ben Murdoch097c5b22016-05-18 11:27:45 +01001309void BytecodeGraphBuilder::VisitTestInstanceOf() {
1310 BuildCompareOp(javascript()->InstanceOf());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001311}
1312
Ben Murdoch097c5b22016-05-18 11:27:45 +01001313void BytecodeGraphBuilder::BuildCastOperator(const Operator* js_op) {
1314 FrameStateBeforeAndAfter states(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001315 Node* node = NewNode(js_op, environment()->LookupAccumulator());
1316 environment()->BindAccumulator(node, &states);
1317}
1318
Ben Murdoch097c5b22016-05-18 11:27:45 +01001319void BytecodeGraphBuilder::VisitToName() {
1320 BuildCastOperator(javascript()->ToName());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001321}
1322
Ben Murdoch097c5b22016-05-18 11:27:45 +01001323void BytecodeGraphBuilder::VisitToObject() {
1324 BuildCastOperator(javascript()->ToObject());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001325}
1326
Ben Murdoch097c5b22016-05-18 11:27:45 +01001327void BytecodeGraphBuilder::VisitToNumber() {
1328 BuildCastOperator(javascript()->ToNumber());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001329}
1330
Ben Murdoch097c5b22016-05-18 11:27:45 +01001331void BytecodeGraphBuilder::VisitJump() { BuildJump(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001332
Ben Murdoch097c5b22016-05-18 11:27:45 +01001333void BytecodeGraphBuilder::VisitJumpConstant() { BuildJump(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001334
Ben Murdoch097c5b22016-05-18 11:27:45 +01001335void BytecodeGraphBuilder::VisitJumpConstantWide() { BuildJump(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001336
Ben Murdoch097c5b22016-05-18 11:27:45 +01001337void BytecodeGraphBuilder::VisitJumpIfTrue() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001338 BuildJumpIfEqual(jsgraph()->TrueConstant());
1339}
1340
Ben Murdoch097c5b22016-05-18 11:27:45 +01001341void BytecodeGraphBuilder::VisitJumpIfTrueConstant() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001342 BuildJumpIfEqual(jsgraph()->TrueConstant());
1343}
1344
Ben Murdoch097c5b22016-05-18 11:27:45 +01001345void BytecodeGraphBuilder::VisitJumpIfTrueConstantWide() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001346 BuildJumpIfEqual(jsgraph()->TrueConstant());
1347}
1348
Ben Murdoch097c5b22016-05-18 11:27:45 +01001349void BytecodeGraphBuilder::VisitJumpIfFalse() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001350 BuildJumpIfEqual(jsgraph()->FalseConstant());
1351}
1352
Ben Murdoch097c5b22016-05-18 11:27:45 +01001353void BytecodeGraphBuilder::VisitJumpIfFalseConstant() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001354 BuildJumpIfEqual(jsgraph()->FalseConstant());
1355}
1356
Ben Murdoch097c5b22016-05-18 11:27:45 +01001357void BytecodeGraphBuilder::VisitJumpIfFalseConstantWide() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001358 BuildJumpIfEqual(jsgraph()->FalseConstant());
1359}
1360
Ben Murdoch097c5b22016-05-18 11:27:45 +01001361void BytecodeGraphBuilder::VisitJumpIfToBooleanTrue() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001362 BuildJumpIfToBooleanEqual(jsgraph()->TrueConstant());
1363}
1364
Ben Murdoch097c5b22016-05-18 11:27:45 +01001365void BytecodeGraphBuilder::VisitJumpIfToBooleanTrueConstant() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001366 BuildJumpIfToBooleanEqual(jsgraph()->TrueConstant());
1367}
1368
Ben Murdoch097c5b22016-05-18 11:27:45 +01001369void BytecodeGraphBuilder::VisitJumpIfToBooleanTrueConstantWide() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001370 BuildJumpIfToBooleanEqual(jsgraph()->TrueConstant());
1371}
1372
Ben Murdoch097c5b22016-05-18 11:27:45 +01001373void BytecodeGraphBuilder::VisitJumpIfToBooleanFalse() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001374 BuildJumpIfToBooleanEqual(jsgraph()->FalseConstant());
1375}
1376
Ben Murdoch097c5b22016-05-18 11:27:45 +01001377void BytecodeGraphBuilder::VisitJumpIfToBooleanFalseConstant() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001378 BuildJumpIfToBooleanEqual(jsgraph()->FalseConstant());
1379}
1380
Ben Murdoch097c5b22016-05-18 11:27:45 +01001381void BytecodeGraphBuilder::VisitJumpIfToBooleanFalseConstantWide() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001382 BuildJumpIfToBooleanEqual(jsgraph()->FalseConstant());
1383}
1384
Ben Murdoch097c5b22016-05-18 11:27:45 +01001385void BytecodeGraphBuilder::VisitJumpIfNotHole() { BuildJumpIfNotHole(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001386
Ben Murdoch097c5b22016-05-18 11:27:45 +01001387void BytecodeGraphBuilder::VisitJumpIfNotHoleConstant() {
1388 BuildJumpIfNotHole();
1389}
1390
1391void BytecodeGraphBuilder::VisitJumpIfNotHoleConstantWide() {
1392 BuildJumpIfNotHole();
1393}
1394
1395void BytecodeGraphBuilder::VisitJumpIfNull() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001396 BuildJumpIfEqual(jsgraph()->NullConstant());
1397}
1398
Ben Murdoch097c5b22016-05-18 11:27:45 +01001399void BytecodeGraphBuilder::VisitJumpIfNullConstant() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001400 BuildJumpIfEqual(jsgraph()->NullConstant());
1401}
1402
Ben Murdoch097c5b22016-05-18 11:27:45 +01001403void BytecodeGraphBuilder::VisitJumpIfNullConstantWide() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001404 BuildJumpIfEqual(jsgraph()->NullConstant());
1405}
1406
Ben Murdoch097c5b22016-05-18 11:27:45 +01001407void BytecodeGraphBuilder::VisitJumpIfUndefined() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001408 BuildJumpIfEqual(jsgraph()->UndefinedConstant());
1409}
1410
Ben Murdoch097c5b22016-05-18 11:27:45 +01001411void BytecodeGraphBuilder::VisitJumpIfUndefinedConstant() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001412 BuildJumpIfEqual(jsgraph()->UndefinedConstant());
1413}
1414
Ben Murdoch097c5b22016-05-18 11:27:45 +01001415void BytecodeGraphBuilder::VisitJumpIfUndefinedConstantWide() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001416 BuildJumpIfEqual(jsgraph()->UndefinedConstant());
1417}
1418
Ben Murdoch097c5b22016-05-18 11:27:45 +01001419void BytecodeGraphBuilder::VisitStackCheck() {
1420 FrameStateBeforeAndAfter states(this);
1421 Node* node = NewNode(javascript()->StackCheck());
1422 environment()->RecordAfterState(node, &states);
1423}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001424
Ben Murdoch097c5b22016-05-18 11:27:45 +01001425void BytecodeGraphBuilder::VisitReturn() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001426 Node* control =
1427 NewNode(common()->Return(), environment()->LookupAccumulator());
Ben Murdoch097c5b22016-05-18 11:27:45 +01001428 MergeControlToLeaveFunction(control);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001429}
1430
Ben Murdoch097c5b22016-05-18 11:27:45 +01001431void BytecodeGraphBuilder::VisitDebugger() {
1432 FrameStateBeforeAndAfter states(this);
1433 Node* call =
1434 NewNode(javascript()->CallRuntime(Runtime::kHandleDebuggerStatement));
1435 environment()->BindAccumulator(call, &states);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001436}
1437
Ben Murdoch097c5b22016-05-18 11:27:45 +01001438// We cannot create a graph from the debugger copy of the bytecode array.
1439#define DEBUG_BREAK(Name, ...) \
1440 void BytecodeGraphBuilder::Visit##Name() { UNREACHABLE(); }
1441DEBUG_BREAK_BYTECODE_LIST(DEBUG_BREAK);
1442#undef DEBUG_BREAK
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001443
Ben Murdoch097c5b22016-05-18 11:27:45 +01001444void BytecodeGraphBuilder::BuildForInPrepare() {
1445 FrameStateBeforeAndAfter states(this);
1446 Node* receiver = environment()->LookupAccumulator();
1447 Node* prepare = NewNode(javascript()->ForInPrepare(), receiver);
1448 environment()->BindRegistersToProjections(
1449 bytecode_iterator().GetRegisterOperand(0), prepare, &states);
1450}
1451
1452void BytecodeGraphBuilder::VisitForInPrepare() { BuildForInPrepare(); }
1453
1454void BytecodeGraphBuilder::VisitForInPrepareWide() { BuildForInPrepare(); }
1455
1456void BytecodeGraphBuilder::VisitForInDone() {
1457 FrameStateBeforeAndAfter states(this);
1458 Node* index =
1459 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001460 Node* cache_length =
Ben Murdoch097c5b22016-05-18 11:27:45 +01001461 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001462 Node* exit_cond = NewNode(javascript()->ForInDone(), index, cache_length);
1463 environment()->BindAccumulator(exit_cond, &states);
1464}
1465
Ben Murdoch097c5b22016-05-18 11:27:45 +01001466void BytecodeGraphBuilder::BuildForInNext() {
1467 FrameStateBeforeAndAfter states(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001468 Node* receiver =
Ben Murdoch097c5b22016-05-18 11:27:45 +01001469 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1470 Node* index =
1471 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
1472 int catch_reg_pair_index = bytecode_iterator().GetRegisterOperand(2).index();
1473 Node* cache_type = environment()->LookupRegister(
1474 interpreter::Register(catch_reg_pair_index));
1475 Node* cache_array = environment()->LookupRegister(
1476 interpreter::Register(catch_reg_pair_index + 1));
1477
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001478 Node* value = NewNode(javascript()->ForInNext(), receiver, cache_array,
1479 cache_type, index);
1480 environment()->BindAccumulator(value, &states);
1481}
1482
Ben Murdoch097c5b22016-05-18 11:27:45 +01001483void BytecodeGraphBuilder::VisitForInNext() { BuildForInNext(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001484
Ben Murdoch097c5b22016-05-18 11:27:45 +01001485void BytecodeGraphBuilder::VisitForInNextWide() { BuildForInNext(); }
1486
1487void BytecodeGraphBuilder::VisitForInStep() {
1488 FrameStateBeforeAndAfter states(this);
1489 Node* index =
1490 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001491 index = NewNode(javascript()->ForInStep(), index);
1492 environment()->BindAccumulator(index, &states);
1493}
1494
Ben Murdoch097c5b22016-05-18 11:27:45 +01001495void BytecodeGraphBuilder::SwitchToMergeEnvironment(int current_offset) {
1496 if (merge_environments_[current_offset] != nullptr) {
1497 if (environment() != nullptr) {
1498 merge_environments_[current_offset]->Merge(environment());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001499 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01001500 set_environment(merge_environments_[current_offset]);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001501 }
1502}
1503
Ben Murdoch097c5b22016-05-18 11:27:45 +01001504void BytecodeGraphBuilder::BuildLoopHeaderEnvironment(int current_offset) {
1505 if (branch_analysis()->backward_branches_target(current_offset)) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001506 // Add loop header and store a copy so we can connect merged back
1507 // edge inputs to the loop header.
Ben Murdoch097c5b22016-05-18 11:27:45 +01001508 merge_environments_[current_offset] = environment()->CopyForLoop();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001509 }
1510}
1511
Ben Murdoch097c5b22016-05-18 11:27:45 +01001512void BytecodeGraphBuilder::MergeIntoSuccessorEnvironment(int target_offset) {
1513 if (merge_environments_[target_offset] == nullptr) {
1514 // Append merge nodes to the environment. We may merge here with another
1515 // environment. So add a place holder for merge nodes. We may add redundant
1516 // but will be eliminated in a later pass.
1517 // TODO(mstarzinger): Be smarter about this!
1518 NewMerge();
1519 merge_environments_[target_offset] = environment();
1520 } else {
1521 merge_environments_[target_offset]->Merge(environment());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001522 }
1523 set_environment(nullptr);
1524}
1525
Ben Murdoch097c5b22016-05-18 11:27:45 +01001526void BytecodeGraphBuilder::MergeControlToLeaveFunction(Node* exit) {
1527 exit_controls_.push_back(exit);
1528 set_environment(nullptr);
1529}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001530
1531void BytecodeGraphBuilder::BuildJump() {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001532 MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001533}
1534
1535
1536void BytecodeGraphBuilder::BuildConditionalJump(Node* condition) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001537 NewBranch(condition);
1538 Environment* if_false_environment = environment()->CopyForConditional();
1539 NewIfTrue();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001540 MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001541 set_environment(if_false_environment);
1542 NewIfFalse();
1543}
1544
1545
1546void BytecodeGraphBuilder::BuildJumpIfEqual(Node* comperand) {
1547 Node* accumulator = environment()->LookupAccumulator();
1548 Node* condition =
1549 NewNode(javascript()->StrictEqual(), accumulator, comperand);
1550 BuildConditionalJump(condition);
1551}
1552
1553
1554void BytecodeGraphBuilder::BuildJumpIfToBooleanEqual(Node* comperand) {
1555 Node* accumulator = environment()->LookupAccumulator();
1556 Node* to_boolean =
1557 NewNode(javascript()->ToBoolean(ToBooleanHint::kAny), accumulator);
1558 Node* condition = NewNode(javascript()->StrictEqual(), to_boolean, comperand);
1559 BuildConditionalJump(condition);
1560}
1561
Ben Murdoch097c5b22016-05-18 11:27:45 +01001562void BytecodeGraphBuilder::BuildJumpIfNotHole() {
1563 Node* accumulator = environment()->LookupAccumulator();
1564 Node* condition = NewNode(javascript()->StrictEqual(), accumulator,
1565 jsgraph()->TheHoleConstant());
1566 Node* node =
1567 NewNode(common()->Select(MachineRepresentation::kTagged), condition,
1568 jsgraph()->FalseConstant(), jsgraph()->TrueConstant());
1569 BuildConditionalJump(node);
1570}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001571
1572Node** BytecodeGraphBuilder::EnsureInputBufferSize(int size) {
1573 if (size > input_buffer_size_) {
1574 size = size + kInputBufferSizeIncrement + input_buffer_size_;
1575 input_buffer_ = local_zone()->NewArray<Node*>(size);
1576 input_buffer_size_ = size;
1577 }
1578 return input_buffer_;
1579}
1580
Ben Murdoch097c5b22016-05-18 11:27:45 +01001581void BytecodeGraphBuilder::EnterAndExitExceptionHandlers(int current_offset) {
1582 Handle<HandlerTable> table = exception_handler_table();
1583 int num_entries = table->NumberOfRangeEntries();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001584
Ben Murdoch097c5b22016-05-18 11:27:45 +01001585 // Potentially exit exception handlers.
1586 while (!exception_handlers_.empty()) {
1587 int current_end = exception_handlers_.top().end_offset_;
1588 if (current_offset < current_end) break; // Still covered by range.
1589 exception_handlers_.pop();
1590 }
1591
1592 // Potentially enter exception handlers.
1593 while (current_exception_handler_ < num_entries) {
1594 int next_start = table->GetRangeStart(current_exception_handler_);
1595 if (current_offset < next_start) break; // Not yet covered by range.
1596 int next_end = table->GetRangeEnd(current_exception_handler_);
1597 int next_handler = table->GetRangeHandler(current_exception_handler_);
1598 int context_register = table->GetRangeData(current_exception_handler_);
1599 CatchPrediction pred =
1600 table->GetRangePrediction(current_exception_handler_);
1601 exception_handlers_.push(
1602 {next_start, next_end, next_handler, context_register, pred});
1603 current_exception_handler_++;
1604 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001605}
1606
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001607Node* BytecodeGraphBuilder::MakeNode(const Operator* op, int value_input_count,
1608 Node** value_inputs, bool incomplete) {
1609 DCHECK_EQ(op->ValueInputCount(), value_input_count);
1610
1611 bool has_context = OperatorProperties::HasContextInput(op);
1612 int frame_state_count = OperatorProperties::GetFrameStateInputCount(op);
1613 bool has_control = op->ControlInputCount() == 1;
1614 bool has_effect = op->EffectInputCount() == 1;
1615
1616 DCHECK_LT(op->ControlInputCount(), 2);
1617 DCHECK_LT(op->EffectInputCount(), 2);
1618
1619 Node* result = nullptr;
1620 if (!has_context && frame_state_count == 0 && !has_control && !has_effect) {
1621 result = graph()->NewNode(op, value_input_count, value_inputs, incomplete);
1622 } else {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001623 bool inside_handler = !exception_handlers_.empty();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001624 int input_count_with_deps = value_input_count;
1625 if (has_context) ++input_count_with_deps;
1626 input_count_with_deps += frame_state_count;
1627 if (has_control) ++input_count_with_deps;
1628 if (has_effect) ++input_count_with_deps;
1629 Node** buffer = EnsureInputBufferSize(input_count_with_deps);
1630 memcpy(buffer, value_inputs, kPointerSize * value_input_count);
1631 Node** current_input = buffer + value_input_count;
1632 if (has_context) {
1633 *current_input++ = environment()->Context();
1634 }
1635 for (int i = 0; i < frame_state_count; i++) {
1636 // The frame state will be inserted later. Here we misuse
1637 // the {Dead} node as a sentinel to be later overwritten
1638 // with the real frame state.
1639 *current_input++ = jsgraph()->Dead();
1640 }
1641 if (has_effect) {
1642 *current_input++ = environment()->GetEffectDependency();
1643 }
1644 if (has_control) {
1645 *current_input++ = environment()->GetControlDependency();
1646 }
1647 result = graph()->NewNode(op, input_count_with_deps, buffer, incomplete);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001648 // Update the current control dependency for control-producing nodes.
1649 if (NodeProperties::IsControl(result)) {
1650 environment()->UpdateControlDependency(result);
1651 }
1652 // Update the current effect dependency for effect-producing nodes.
1653 if (result->op()->EffectOutputCount() > 0) {
1654 environment()->UpdateEffectDependency(result);
1655 }
1656 // Add implicit exception continuation for throwing nodes.
1657 if (!result->op()->HasProperty(Operator::kNoThrow) && inside_handler) {
1658 int handler_offset = exception_handlers_.top().handler_offset_;
1659 int context_index = exception_handlers_.top().context_register_;
1660 CatchPrediction prediction = exception_handlers_.top().pred_;
1661 interpreter::Register context_register(context_index);
1662 IfExceptionHint hint = prediction == CatchPrediction::CAUGHT
1663 ? IfExceptionHint::kLocallyCaught
1664 : IfExceptionHint::kLocallyUncaught;
1665 Environment* success_env = environment()->CopyForConditional();
1666 const Operator* op = common()->IfException(hint);
1667 Node* effect = environment()->GetEffectDependency();
1668 Node* on_exception = graph()->NewNode(op, effect, result);
1669 Node* context = environment()->LookupRegister(context_register);
1670 environment()->UpdateControlDependency(on_exception);
1671 environment()->UpdateEffectDependency(on_exception);
1672 environment()->BindAccumulator(on_exception);
1673 environment()->SetContext(context);
1674 MergeIntoSuccessorEnvironment(handler_offset);
1675 set_environment(success_env);
1676 }
1677 // Add implicit success continuation for throwing nodes.
1678 if (!result->op()->HasProperty(Operator::kNoThrow)) {
1679 const Operator* if_success = common()->IfSuccess();
1680 Node* on_success = graph()->NewNode(if_success, result);
1681 environment()->UpdateControlDependency(on_success);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001682 }
1683 }
1684
1685 return result;
1686}
1687
1688
1689Node* BytecodeGraphBuilder::NewPhi(int count, Node* input, Node* control) {
1690 const Operator* phi_op = common()->Phi(MachineRepresentation::kTagged, count);
1691 Node** buffer = EnsureInputBufferSize(count + 1);
1692 MemsetPointer(buffer, input, count);
1693 buffer[count] = control;
1694 return graph()->NewNode(phi_op, count + 1, buffer, true);
1695}
1696
1697
1698Node* BytecodeGraphBuilder::NewEffectPhi(int count, Node* input,
1699 Node* control) {
1700 const Operator* phi_op = common()->EffectPhi(count);
1701 Node** buffer = EnsureInputBufferSize(count + 1);
1702 MemsetPointer(buffer, input, count);
1703 buffer[count] = control;
1704 return graph()->NewNode(phi_op, count + 1, buffer, true);
1705}
1706
1707
1708Node* BytecodeGraphBuilder::MergeControl(Node* control, Node* other) {
1709 int inputs = control->op()->ControlInputCount() + 1;
1710 if (control->opcode() == IrOpcode::kLoop) {
1711 // Control node for loop exists, add input.
1712 const Operator* op = common()->Loop(inputs);
1713 control->AppendInput(graph_zone(), other);
1714 NodeProperties::ChangeOp(control, op);
1715 } else if (control->opcode() == IrOpcode::kMerge) {
1716 // Control node for merge exists, add input.
1717 const Operator* op = common()->Merge(inputs);
1718 control->AppendInput(graph_zone(), other);
1719 NodeProperties::ChangeOp(control, op);
1720 } else {
1721 // Control node is a singleton, introduce a merge.
1722 const Operator* op = common()->Merge(inputs);
1723 Node* merge_inputs[] = {control, other};
1724 control = graph()->NewNode(op, arraysize(merge_inputs), merge_inputs, true);
1725 }
1726 return control;
1727}
1728
1729
1730Node* BytecodeGraphBuilder::MergeEffect(Node* value, Node* other,
1731 Node* control) {
1732 int inputs = control->op()->ControlInputCount();
1733 if (value->opcode() == IrOpcode::kEffectPhi &&
1734 NodeProperties::GetControlInput(value) == control) {
1735 // Phi already exists, add input.
1736 value->InsertInput(graph_zone(), inputs - 1, other);
1737 NodeProperties::ChangeOp(value, common()->EffectPhi(inputs));
1738 } else if (value != other) {
1739 // Phi does not exist yet, introduce one.
1740 value = NewEffectPhi(inputs, value, control);
1741 value->ReplaceInput(inputs - 1, other);
1742 }
1743 return value;
1744}
1745
1746
1747Node* BytecodeGraphBuilder::MergeValue(Node* value, Node* other,
1748 Node* control) {
1749 int inputs = control->op()->ControlInputCount();
1750 if (value->opcode() == IrOpcode::kPhi &&
1751 NodeProperties::GetControlInput(value) == control) {
1752 // Phi already exists, add input.
1753 value->InsertInput(graph_zone(), inputs - 1, other);
1754 NodeProperties::ChangeOp(
1755 value, common()->Phi(MachineRepresentation::kTagged, inputs));
1756 } else if (value != other) {
1757 // Phi does not exist yet, introduce one.
1758 value = NewPhi(inputs, value, control);
1759 value->ReplaceInput(inputs - 1, other);
1760 }
1761 return value;
1762}
1763
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001764} // namespace compiler
1765} // namespace internal
1766} // namespace v8