5 #include "src/compiler/bytecode-graph-builder.h" 7 #include "src/ast/ast.h" 8 #include "src/ast/scopes.h" 9 #include "src/compiler/access-builder.h" 10 #include "src/compiler/compiler-source-position-table.h" 11 #include "src/compiler/linkage.h" 12 #include "src/compiler/node-matchers.h" 13 #include "src/compiler/operator-properties.h" 14 #include "src/compiler/simplified-operator.h" 15 #include "src/interpreter/bytecodes.h" 16 #include "src/objects-inl.h" 17 #include "src/objects/js-array-inl.h" 18 #include "src/objects/js-generator.h" 19 #include "src/objects/literal-objects-inl.h" 20 #include "src/objects/smi.h" 21 #include "src/vector-slot-pair.h" 35 Node* control_dependency);
40 enum FrameStateAttachmentMode { kAttachFrameState, kDontAttachFrameState };
42 int parameter_count()
const {
return parameter_count_; }
43 int register_count()
const {
return register_count_; }
45 Node* LookupAccumulator()
const;
47 Node* LookupGeneratorState()
const;
49 void BindAccumulator(
Node* node,
50 FrameStateAttachmentMode mode = kDontAttachFrameState);
52 FrameStateAttachmentMode mode = kDontAttachFrameState);
53 void BindRegistersToProjections(
55 FrameStateAttachmentMode mode = kDontAttachFrameState);
56 void BindGeneratorState(
Node* node);
57 void RecordAfterState(
Node* node,
58 FrameStateAttachmentMode mode = kDontAttachFrameState);
61 Node* GetEffectDependency() {
return effect_dependency_; }
62 void UpdateEffectDependency(
Node* dependency) {
63 effect_dependency_ = dependency;
72 Node* GetControlDependency()
const {
return control_dependency_; }
73 void UpdateControlDependency(
Node* dependency) {
74 control_dependency_ = dependency;
78 void SetContext(
Node* new_context) { context_ = new_context; }
83 void FillWithOsrValues();
86 void PrepareForLoopExit(
Node* loop,
93 bool StateValuesRequireUpdate(
Node** state_values,
Node** values,
int count);
94 void UpdateStateValues(
Node** state_values,
Node** values,
int count);
95 Node* GetStateValuesFromCache(
Node** values,
int count,
96 const BitVector* liveness,
int liveness_offset);
100 Zone* zone()
const {
return builder_->local_zone(); }
101 Graph* graph()
const {
return builder_->graph(); }
104 const NodeVector* values()
const {
return &values_; }
106 int register_base()
const {
return register_base_; }
107 int accumulator_base()
const {
return accumulator_base_; }
111 int parameter_count_;
113 Node* control_dependency_;
114 Node* effect_dependency_;
116 Node* parameters_state_values_;
117 Node* generator_state_;
119 int accumulator_base_;
126 : builder_(builder), parent_(builder->environment()->Copy()) {}
138 BytecodeGraphBuilder::Environment::Environment(
141 Node* control_dependency)
143 register_count_(register_count),
144 parameter_count_(parameter_count),
145 control_dependency_(control_dependency),
146 effect_dependency_(control_dependency),
147 values_(builder->local_zone()),
148 parameters_state_values_(nullptr),
149 generator_state_(nullptr) {
159 for (
int i = 0;
i < parameter_count;
i++) {
160 const char* debug_name = (
i == 0) ?
"%this" :
nullptr;
161 const Operator* op = common()->Parameter(
i, debug_name);
162 Node* parameter = builder->graph()->NewNode(op, graph()->start());
163 values()->push_back(parameter);
167 register_base_ =
static_cast<int>(values()->size());
168 Node* undefined_constant = builder->jsgraph()->UndefinedConstant();
169 values()->insert(values()->end(), register_count, undefined_constant);
172 accumulator_base_ =
static_cast<int>(values()->size());
173 values()->push_back(undefined_constant);
176 int context_index = Linkage::GetJSCallContextParamIndex(parameter_count);
177 const Operator* op = common()->Parameter(context_index,
"%context");
178 context_ = builder->graph()->NewNode(op, graph()->start());
181 if (incoming_new_target_or_generator.is_valid()) {
182 int new_target_index =
183 Linkage::GetJSCallNewTargetParamIndex(parameter_count);
184 const Operator* op = common()->Parameter(new_target_index,
"%new.target");
185 Node* new_target_node = builder->graph()->NewNode(op, graph()->start());
187 int values_index = RegisterToValuesIndex(incoming_new_target_or_generator);
188 values()->at(values_index) = new_target_node;
192 BytecodeGraphBuilder::Environment::Environment(
193 const BytecodeGraphBuilder::Environment* other)
194 : builder_(other->builder_),
195 register_count_(other->register_count_),
196 parameter_count_(other->parameter_count_),
197 context_(other->context_),
198 control_dependency_(other->control_dependency_),
199 effect_dependency_(other->effect_dependency_),
200 values_(other->zone()),
201 parameters_state_values_(other->parameters_state_values_),
202 generator_state_(other->generator_state_),
203 register_base_(other->register_base_),
204 accumulator_base_(other->accumulator_base_) {
205 values_ = other->values_;
209 int BytecodeGraphBuilder::Environment::RegisterToValuesIndex(
210 interpreter::Register the_register)
const {
211 if (the_register.is_parameter()) {
212 return the_register.ToParameterIndex(parameter_count());
214 return the_register.index() + register_base();
218 Node* BytecodeGraphBuilder::Environment::LookupAccumulator()
const {
219 return values()->at(accumulator_base_);
222 Node* BytecodeGraphBuilder::Environment::LookupGeneratorState()
const {
223 DCHECK_NOT_NULL(generator_state_);
224 return generator_state_;
227 Node* BytecodeGraphBuilder::Environment::LookupRegister(
228 interpreter::Register the_register)
const {
229 if (the_register.is_current_context()) {
231 }
else if (the_register.is_function_closure()) {
232 return builder()->GetFunctionClosure();
234 int values_index = RegisterToValuesIndex(the_register);
235 return values()->at(values_index);
239 void BytecodeGraphBuilder::Environment::BindAccumulator(
240 Node* node, FrameStateAttachmentMode mode) {
241 if (mode == FrameStateAttachmentMode::kAttachFrameState) {
242 builder()->PrepareFrameState(node, OutputFrameStateCombine::PokeAt(0));
244 values()->at(accumulator_base_) = node;
247 void BytecodeGraphBuilder::Environment::BindGeneratorState(Node* node) {
248 generator_state_ = node;
251 void BytecodeGraphBuilder::Environment::BindRegister(
252 interpreter::Register the_register, Node* node,
253 FrameStateAttachmentMode mode) {
254 int values_index = RegisterToValuesIndex(the_register);
255 if (mode == FrameStateAttachmentMode::kAttachFrameState) {
256 builder()->PrepareFrameState(node, OutputFrameStateCombine::PokeAt(
257 accumulator_base_ - values_index));
259 values()->at(values_index) = node;
262 void BytecodeGraphBuilder::Environment::BindRegistersToProjections(
263 interpreter::Register first_reg, Node* node,
264 FrameStateAttachmentMode mode) {
265 int values_index = RegisterToValuesIndex(first_reg);
266 if (mode == FrameStateAttachmentMode::kAttachFrameState) {
267 builder()->PrepareFrameState(node, OutputFrameStateCombine::PokeAt(
268 accumulator_base_ - values_index));
270 for (
int i = 0;
i < node->op()->ValueOutputCount();
i++) {
271 values()->at(values_index +
i) =
272 builder()->NewNode(common()->Projection(
i), node);
276 void BytecodeGraphBuilder::Environment::RecordAfterState(
277 Node* node, FrameStateAttachmentMode mode) {
278 if (mode == FrameStateAttachmentMode::kAttachFrameState) {
279 builder()->PrepareFrameState(node, OutputFrameStateCombine::Ignore());
283 BytecodeGraphBuilder::Environment* BytecodeGraphBuilder::Environment::Copy() {
284 return new (zone()) Environment(
this);
287 void BytecodeGraphBuilder::Environment::Merge(
288 BytecodeGraphBuilder::Environment* other,
289 const BytecodeLivenessState* liveness) {
292 Node* control = builder()->MergeControl(GetControlDependency(),
293 other->GetControlDependency());
294 UpdateControlDependency(control);
298 Node* effect = builder()->MergeEffect(GetEffectDependency(),
299 other->GetEffectDependency(), control);
300 UpdateEffectDependency(effect);
304 context_ = builder()->MergeValue(context_, other->context_, control);
305 for (
int i = 0;
i < parameter_count();
i++) {
306 values_[
i] = builder()->MergeValue(values_[
i], other->values_[
i], control);
308 for (
int i = 0;
i < register_count();
i++) {
309 int index = register_base() +
i;
310 if (liveness ==
nullptr || liveness->RegisterIsLive(
i)) {
315 if (generator_state_ ==
nullptr ||
316 NumberMatcher(generator_state_)
317 .Is(JSGeneratorObject::kGeneratorExecuting)) {
318 DCHECK_NE(values_[index], builder()->jsgraph()->OptimizedOutConstant());
319 DCHECK_NE(other->values_[index],
320 builder()->jsgraph()->OptimizedOutConstant());
325 builder()->MergeValue(values_[index], other->values_[index], control);
328 values_[index] = builder()->jsgraph()->OptimizedOutConstant();
332 if (liveness ==
nullptr || liveness->AccumulatorIsLive()) {
333 DCHECK_NE(values_[accumulator_base()],
334 builder()->jsgraph()->OptimizedOutConstant());
335 DCHECK_NE(other->values_[accumulator_base()],
336 builder()->jsgraph()->OptimizedOutConstant());
338 values_[accumulator_base()] =
339 builder()->MergeValue(values_[accumulator_base()],
340 other->values_[accumulator_base()], control);
342 values_[accumulator_base()] = builder()->jsgraph()->OptimizedOutConstant();
345 if (generator_state_ !=
nullptr) {
346 DCHECK_NOT_NULL(other->generator_state_);
347 generator_state_ = builder()->MergeValue(generator_state_,
348 other->generator_state_, control);
352 void BytecodeGraphBuilder::Environment::PrepareForLoop(
353 const BytecodeLoopAssignments& assignments,
354 const BytecodeLivenessState* liveness) {
356 Node* control = builder()->NewLoop();
359 Node* effect = builder()->NewEffectPhi(1, GetEffectDependency(), control);
360 UpdateEffectDependency(effect);
364 context_ = builder()->NewPhi(1, context_, control);
365 for (
int i = 0;
i < parameter_count();
i++) {
366 if (assignments.ContainsParameter(
i)) {
367 values_[
i] = builder()->NewPhi(1, values_[
i], control);
370 for (
int i = 0;
i < register_count();
i++) {
371 if (assignments.ContainsLocal(
i) &&
372 (liveness ==
nullptr || liveness->RegisterIsLive(
i))) {
373 int index = register_base() +
i;
374 values_[index] = builder()->NewPhi(1, values_[index], control);
378 DCHECK_IMPLIES(liveness !=
nullptr, !liveness->AccumulatorIsLive());
380 if (generator_state_ !=
nullptr) {
381 generator_state_ = builder()->NewPhi(1, generator_state_, control);
385 Node* terminate = builder()->graph()->NewNode(
386 builder()->common()->Terminate(), effect, control);
387 builder()->exit_controls_.push_back(terminate);
390 void BytecodeGraphBuilder::Environment::FillWithOsrValues() {
391 Node* start = graph()->start();
394 SetContext(graph()->NewNode(
395 common()->OsrValue(Linkage::kOsrContextSpillSlotIndex), start));
396 int size =
static_cast<int>(values()->size());
397 for (
int i = 0;
i < size;
i++) {
399 if (
i >= register_base()) idx += InterpreterFrameConstants::kExtraSlotCount;
400 if (
i >= accumulator_base()) idx = Linkage::kOsrAccumulatorRegisterIndex;
401 values()->at(
i) = graph()->NewNode(common()->OsrValue(idx), start);
405 bool BytecodeGraphBuilder::Environment::StateValuesRequireUpdate(
406 Node** state_values, Node** values,
int count) {
407 if (*state_values ==
nullptr) {
410 Node::Inputs inputs = (*state_values)->inputs();
411 if (inputs.count() != count)
return true;
412 for (
int i = 0;
i < count;
i++) {
413 if (inputs[
i] != values[
i]) {
420 void BytecodeGraphBuilder::Environment::PrepareForLoopExit(
421 Node* loop,
const BytecodeLoopAssignments& assignments,
422 const BytecodeLivenessState* liveness) {
423 DCHECK_EQ(loop->opcode(), IrOpcode::kLoop);
425 Node* control = GetControlDependency();
428 Node* loop_exit = graph()->NewNode(common()->LoopExit(), control, loop);
429 UpdateControlDependency(loop_exit);
432 Node* effect_rename = graph()->NewNode(common()->LoopExitEffect(),
433 GetEffectDependency(), loop_exit);
434 UpdateEffectDependency(effect_rename);
442 for (
int i = 0;
i < parameter_count();
i++) {
443 if (assignments.ContainsParameter(
i)) {
445 graph()->NewNode(common()->LoopExitValue(), values_[
i], loop_exit);
449 for (
int i = 0;
i < register_count();
i++) {
450 if (assignments.ContainsLocal(
i) &&
451 (liveness ==
nullptr || liveness->RegisterIsLive(
i))) {
452 Node* rename = graph()->NewNode(common()->LoopExitValue(),
453 values_[register_base() +
i], loop_exit);
454 values_[register_base() +
i] = rename;
457 if (liveness ==
nullptr || liveness->AccumulatorIsLive()) {
458 Node* rename = graph()->NewNode(common()->LoopExitValue(),
459 values_[accumulator_base()], loop_exit);
460 values_[accumulator_base()] = rename;
463 if (generator_state_ !=
nullptr) {
464 generator_state_ = graph()->NewNode(common()->LoopExitValue(),
465 generator_state_, loop_exit);
469 void BytecodeGraphBuilder::Environment::UpdateStateValues(Node** state_values,
472 if (StateValuesRequireUpdate(state_values, values, count)) {
473 const Operator* op = common()->StateValues(count, SparseInputMask::Dense());
474 (*state_values) = graph()->NewNode(op, count, values);
478 Node* BytecodeGraphBuilder::Environment::GetStateValuesFromCache(
479 Node** values,
int count,
const BitVector* liveness,
int liveness_offset) {
480 return builder_->state_values_cache_.GetNodeForValues(
481 values, static_cast<size_t>(count), liveness, liveness_offset);
484 Node* BytecodeGraphBuilder::Environment::Checkpoint(
485 BailoutId bailout_id, OutputFrameStateCombine combine,
486 const BytecodeLivenessState* liveness) {
487 if (parameter_count() == register_count()) {
490 parameters_state_values_ = GetStateValuesFromCache(
491 &values()->at(0), parameter_count(),
nullptr, 0);
493 UpdateStateValues(¶meters_state_values_, &values()->at(0),
497 Node* registers_state_values =
498 GetStateValuesFromCache(&values()->at(register_base()), register_count(),
499 liveness ? &liveness->bit_vector() :
nullptr, 0);
501 bool accumulator_is_live = !liveness || liveness->AccumulatorIsLive();
502 Node* accumulator_state_value =
503 accumulator_is_live && combine != OutputFrameStateCombine::PokeAt(0)
504 ? values()->at(accumulator_base())
505 : builder()->jsgraph()->OptimizedOutConstant();
507 const Operator* op = common()->FrameState(
508 bailout_id, combine, builder()->frame_state_function_info());
509 Node* result = graph()->NewNode(
510 op, parameters_state_values_, registers_state_values,
511 accumulator_state_value, Context(), builder()->GetFunctionClosure(),
512 builder()->graph()->start());
517 BytecodeGraphBuilder::BytecodeGraphBuilder(
518 Zone* local_zone, Handle<BytecodeArray> bytecode_array,
519 Handle<SharedFunctionInfo> shared_info,
520 Handle<FeedbackVector> feedback_vector, BailoutId osr_offset,
521 JSGraph* jsgraph, CallFrequency& invocation_frequency,
522 SourcePositionTable* source_positions, Handle<Context> native_context,
523 int inlining_id, JSTypeHintLowering::Flags flags,
bool stack_check,
524 bool analyze_environment_liveness)
525 : local_zone_(local_zone),
527 invocation_frequency_(invocation_frequency),
528 bytecode_array_(bytecode_array),
529 feedback_vector_(feedback_vector),
530 type_hint_lowering_(jsgraph, feedback_vector, flags),
531 frame_state_function_info_(common()->CreateFrameStateFunctionInfo(
532 FrameStateType::kInterpretedFunction,
533 bytecode_array->parameter_count(), bytecode_array->register_count(),
535 bytecode_iterator_(nullptr),
536 bytecode_analysis_(nullptr),
537 environment_(nullptr),
538 osr_offset_(osr_offset),
539 currently_peeled_loop_offset_(-1),
540 stack_check_(stack_check),
541 analyze_environment_liveness_(analyze_environment_liveness),
542 merge_environments_(local_zone),
543 generator_merge_environments_(local_zone),
544 exception_handlers_(local_zone),
545 current_exception_handler_(0),
546 input_buffer_size_(0),
547 input_buffer_(nullptr),
548 needs_eager_checkpoint_(true),
549 exit_controls_(local_zone),
550 state_values_cache_(jsgraph),
551 source_positions_(source_positions),
552 start_position_(shared_info->StartPosition(), inlining_id),
553 native_context_(native_context) {}
555 Node* BytecodeGraphBuilder::GetFunctionClosure() {
556 if (!function_closure_.is_set()) {
557 int index = Linkage::kJSCallClosureParamIndex;
558 const Operator* op = common()->Parameter(index,
"%closure");
559 Node* node = NewNode(op, graph()->start());
560 function_closure_.set(node);
562 return function_closure_.get();
565 Node* BytecodeGraphBuilder::BuildLoadNativeContextField(
int index) {
567 javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX,
true);
568 Node* native_context = NewNode(op);
569 Node* result = NewNode(javascript()->LoadContext(0, index,
true));
570 NodeProperties::ReplaceContextInput(result, native_context);
574 VectorSlotPair BytecodeGraphBuilder::CreateVectorSlotPair(
int slot_id) {
575 FeedbackSlot slot = FeedbackVector::ToSlot(slot_id);
576 FeedbackNexus nexus(feedback_vector(), slot);
577 return VectorSlotPair(feedback_vector(), slot, nexus.ic_state());
580 void BytecodeGraphBuilder::CreateGraph() {
581 SourcePositionTable::Scope pos_scope(source_positions_, start_position_);
586 int actual_parameter_count = bytecode_array()->parameter_count() + 4;
587 graph()->SetStart(graph()->NewNode(common()->Start(actual_parameter_count)));
589 Environment env(
this, bytecode_array()->register_count(),
590 bytecode_array()->parameter_count(),
591 bytecode_array()->incoming_new_target_or_generator_register(),
593 set_environment(&env);
598 DCHECK_NE(0u, exit_controls_.size());
599 int const input_count =
static_cast<int>(exit_controls_.size());
600 Node**
const inputs = &exit_controls_.front();
601 Node* end = graph()->NewNode(common()->End(input_count), input_count, inputs);
602 graph()->SetEnd(end);
605 void BytecodeGraphBuilder::PrepareEagerCheckpoint() {
606 if (needs_eager_checkpoint()) {
609 mark_as_needing_eager_checkpoint(
false);
610 Node* node = NewNode(common()->Checkpoint());
611 DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
612 DCHECK_EQ(IrOpcode::kDead,
613 NodeProperties::GetFrameStateInput(node)->opcode());
614 BailoutId bailout_id(bytecode_iterator().current_offset());
616 const BytecodeLivenessState* liveness_before =
617 bytecode_analysis()->GetInLivenessFor(
618 bytecode_iterator().current_offset());
620 Node* frame_state_before = environment()->Checkpoint(
621 bailout_id, OutputFrameStateCombine::Ignore(), liveness_before);
622 NodeProperties::ReplaceFrameStateInput(node, frame_state_before);
628 Node* effect = environment()->GetEffectDependency();
629 while (effect->opcode() != IrOpcode::kCheckpoint) {
630 DCHECK(effect->op()->HasProperty(Operator::kNoWrite));
631 DCHECK_EQ(1, effect->op()->EffectInputCount());
632 effect = NodeProperties::GetEffectInput(effect);
640 void BytecodeGraphBuilder::PrepareFrameState(Node* node,
641 OutputFrameStateCombine combine) {
642 if (OperatorProperties::HasFrameStateInput(node->op())) {
645 DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
646 DCHECK_EQ(IrOpcode::kDead,
647 NodeProperties::GetFrameStateInput(node)->opcode());
648 BailoutId bailout_id(bytecode_iterator().current_offset());
650 const BytecodeLivenessState* liveness_after =
651 bytecode_analysis()->GetOutLivenessFor(
652 bytecode_iterator().current_offset());
654 Node* frame_state_after =
655 environment()->Checkpoint(bailout_id, combine, liveness_after);
656 NodeProperties::ReplaceFrameStateInput(node, frame_state_after);
671 : iterator_(iterator),
672 source_position_iterator_(source_position_iterator),
673 graph_builder_(graph_builder),
674 saved_states_(graph_builder->local_zone()) {}
676 void ProcessOsrPrelude() {
680 *(graph_builder_->bytecode_analysis());
681 int osr_offset = bytecode_analysis.osr_entry_point();
684 int outermost_loop_offset = osr_offset;
685 while ((outermost_loop_offset =
686 bytecode_analysis.GetLoopInfoFor(outermost_loop_offset)
687 .parent_offset()) != -1) {
688 outer_loop_offsets.push_back(outermost_loop_offset);
690 outermost_loop_offset =
691 outer_loop_offsets.empty() ? osr_offset : outer_loop_offsets.back();
696 for (; iterator_->current_offset() != outermost_loop_offset;
697 iterator_->Advance()) {
698 graph_builder_->UpdateSourcePosition(source_position_iterator_,
699 iterator_->current_offset());
706 outer_loop_offsets.crbegin();
707 it != outer_loop_offsets.crend(); ++it) {
708 int next_loop_offset = *it;
709 for (; iterator_->current_offset() != next_loop_offset;
710 iterator_->Advance()) {
711 graph_builder_->UpdateSourcePosition(source_position_iterator_,
712 iterator_->current_offset());
714 graph_builder_->ExitThenEnterExceptionHandlers(
715 iterator_->current_offset());
717 IteratorsStates(graph_builder_->current_exception_handler(),
718 source_position_iterator_->GetState()));
722 for (; iterator_->current_offset() != osr_offset; iterator_->Advance()) {
723 graph_builder_->UpdateSourcePosition(source_position_iterator_,
724 iterator_->current_offset());
730 graph_builder_->ExitThenEnterExceptionHandlers(osr_offset);
731 graph_builder_->set_currently_peeled_loop_offset(
732 bytecode_analysis.GetLoopInfoFor(osr_offset).parent_offset());
735 void RestoreState(
int target_offset,
int new_parent_offset) {
736 iterator_->SetOffset(target_offset);
739 graph_builder_->set_currently_peeled_loop_offset(new_parent_offset);
740 IteratorsStates saved_state = saved_states_.top();
741 source_position_iterator_->RestoreState(saved_state.source_iterator_state_);
742 graph_builder_->set_current_exception_handler(
743 saved_state.exception_handler_index_);
748 struct IteratorsStates {
749 int exception_handler_index_;
753 int exception_handler_index,
755 : exception_handler_index_(exception_handler_index),
756 source_iterator_state_(source_iterator_state) {}
765 void BytecodeGraphBuilder::RemoveMergeEnvironmentsBeforeOffset(
767 if (!merge_environments_.empty()) {
770 while (it != stop_it && it->first <= limit_offset) {
771 it = merge_environments_.erase(it);
779 void BytecodeGraphBuilder::AdvanceToOsrEntryAndPeelLoops(
780 interpreter::BytecodeArrayIterator* iterator,
781 SourcePositionTableIterator* source_position_iterator) {
782 const BytecodeAnalysis& analysis = *(bytecode_analysis());
783 int osr_offset = analysis.osr_entry_point();
784 OsrIteratorState iterator_states(iterator, source_position_iterator,
this);
786 iterator_states.ProcessOsrPrelude();
787 DCHECK_EQ(iterator->current_offset(), osr_offset);
789 environment()->FillWithOsrValues();
804 int current_parent_offset =
805 analysis.GetLoopInfoFor(osr_offset).parent_offset();
806 while (current_parent_offset != -1) {
807 const LoopInfo& current_parent_loop =
808 analysis.GetLoopInfoFor(current_parent_offset);
811 for (; !iterator->done(); iterator->Advance()) {
812 if (iterator->current_bytecode() == interpreter::Bytecode::kJumpLoop &&
813 iterator->GetJumpTargetOffset() == current_parent_offset) {
817 VisitSingleBytecode(source_position_iterator);
819 DCHECK(!iterator->done());
824 ExitThenEnterExceptionHandlers(iterator->current_offset());
825 SwitchToMergeEnvironment(iterator->current_offset());
839 RemoveMergeEnvironmentsBeforeOffset(iterator->current_offset());
840 iterator_states.RestoreState(current_parent_offset,
841 current_parent_loop.parent_offset());
842 current_parent_offset = current_parent_loop.parent_offset();
846 void BytecodeGraphBuilder::VisitSingleBytecode(
847 SourcePositionTableIterator* source_position_iterator) {
848 const interpreter::BytecodeArrayIterator& iterator = bytecode_iterator();
849 int current_offset = iterator.current_offset();
850 UpdateSourcePosition(source_position_iterator, current_offset);
851 ExitThenEnterExceptionHandlers(current_offset);
852 DCHECK_GE(exception_handlers_.empty() ? current_offset
853 : exception_handlers_.top().end_offset_,
855 SwitchToMergeEnvironment(current_offset);
857 if (environment() !=
nullptr) {
858 BuildLoopHeaderEnvironment(current_offset);
861 if (!stack_check() &&
862 iterator.current_bytecode() == interpreter::Bytecode::kStackCheck) {
863 set_stack_check(
true);
867 switch (iterator.current_bytecode()) {
868 #define BYTECODE_CASE(name, ...) \ 869 case interpreter::Bytecode::k##name: \ 872 BYTECODE_LIST(BYTECODE_CASE)
878 void BytecodeGraphBuilder::VisitBytecodes() {
879 BytecodeAnalysis bytecode_analysis(bytecode_array(), local_zone(),
880 analyze_environment_liveness());
881 bytecode_analysis.Analyze(osr_offset_);
882 set_bytecode_analysis(&bytecode_analysis);
884 interpreter::BytecodeArrayIterator iterator(bytecode_array());
885 set_bytecode_iterator(&iterator);
886 SourcePositionTableIterator source_position_iterator(
887 handle(bytecode_array()->SourcePositionTable(), isolate()));
889 if (analyze_environment_liveness() && FLAG_trace_environment_liveness) {
891 bytecode_analysis.PrintLivenessTo(of);
894 if (!bytecode_analysis.resume_jump_targets().empty()) {
895 environment()->BindGeneratorState(
896 jsgraph()->SmiConstant(JSGeneratorObject::kGeneratorExecuting));
899 if (bytecode_analysis.HasOsrEntryPoint()) {
904 AdvanceToOsrEntryAndPeelLoops(&iterator, &source_position_iterator);
907 bool has_one_shot_bytecode =
false;
908 for (; !iterator.done(); iterator.Advance()) {
909 if (interpreter::Bytecodes::IsOneShotBytecode(
910 iterator.current_bytecode())) {
911 has_one_shot_bytecode =
true;
913 VisitSingleBytecode(&source_position_iterator);
916 if (has_one_shot_bytecode) {
917 isolate()->CountUsage(
918 v8::Isolate::UseCounterFeature::kOptimizedFunctionWithOneShotBytecode);
921 set_bytecode_analysis(
nullptr);
922 set_bytecode_iterator(
nullptr);
923 DCHECK(exception_handlers_.empty());
926 void BytecodeGraphBuilder::VisitLdaZero() {
927 Node* node = jsgraph()->ZeroConstant();
928 environment()->BindAccumulator(node);
931 void BytecodeGraphBuilder::VisitLdaSmi() {
932 Node* node = jsgraph()->Constant(bytecode_iterator().GetImmediateOperand(0));
933 environment()->BindAccumulator(node);
936 void BytecodeGraphBuilder::VisitLdaConstant() {
937 Node* node = jsgraph()->Constant(
938 handle(bytecode_iterator().GetConstantForIndexOperand(0), isolate()));
939 environment()->BindAccumulator(node);
942 void BytecodeGraphBuilder::VisitLdaUndefined() {
943 Node* node = jsgraph()->UndefinedConstant();
944 environment()->BindAccumulator(node);
947 void BytecodeGraphBuilder::VisitLdaNull() {
948 Node* node = jsgraph()->NullConstant();
949 environment()->BindAccumulator(node);
952 void BytecodeGraphBuilder::VisitLdaTheHole() {
953 Node* node = jsgraph()->TheHoleConstant();
954 environment()->BindAccumulator(node);
957 void BytecodeGraphBuilder::VisitLdaTrue() {
958 Node* node = jsgraph()->TrueConstant();
959 environment()->BindAccumulator(node);
962 void BytecodeGraphBuilder::VisitLdaFalse() {
963 Node* node = jsgraph()->FalseConstant();
964 environment()->BindAccumulator(node);
967 void BytecodeGraphBuilder::VisitLdar() {
969 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
970 environment()->BindAccumulator(value);
973 void BytecodeGraphBuilder::VisitStar() {
974 Node* value = environment()->LookupAccumulator();
975 environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0), value);
978 void BytecodeGraphBuilder::VisitMov() {
980 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
981 environment()->BindRegister(bytecode_iterator().GetRegisterOperand(1), value);
984 Node* BytecodeGraphBuilder::BuildLoadGlobal(Handle<Name> name,
986 TypeofMode typeof_mode) {
987 VectorSlotPair feedback = CreateVectorSlotPair(feedback_slot_index);
988 DCHECK(IsLoadGlobalICKind(feedback_vector()->GetKind(feedback.slot())));
989 const Operator* op = javascript()->LoadGlobal(name, feedback, typeof_mode);
993 void BytecodeGraphBuilder::VisitLdaGlobal() {
994 PrepareEagerCheckpoint();
996 Name::cast(bytecode_iterator().GetConstantForIndexOperand(0)), isolate());
997 uint32_t feedback_slot_index = bytecode_iterator().GetIndexOperand(1);
999 BuildLoadGlobal(name, feedback_slot_index, TypeofMode::NOT_INSIDE_TYPEOF);
1000 environment()->BindAccumulator(node, Environment::kAttachFrameState);
1003 void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeof() {
1004 PrepareEagerCheckpoint();
1006 Name::cast(bytecode_iterator().GetConstantForIndexOperand(0)), isolate());
1007 uint32_t feedback_slot_index = bytecode_iterator().GetIndexOperand(1);
1009 BuildLoadGlobal(name, feedback_slot_index, TypeofMode::INSIDE_TYPEOF);
1010 environment()->BindAccumulator(node, Environment::kAttachFrameState);
1013 void BytecodeGraphBuilder::VisitStaGlobal() {
1014 PrepareEagerCheckpoint();
1016 Name::cast(bytecode_iterator().GetConstantForIndexOperand(0)), isolate());
1017 VectorSlotPair feedback =
1018 CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(1));
1019 Node* value = environment()->LookupAccumulator();
1021 LanguageMode language_mode =
1022 feedback.vector()->GetLanguageMode(feedback.slot());
1023 const Operator* op = javascript()->StoreGlobal(language_mode, name, feedback);
1024 Node* node = NewNode(op, value);
1025 environment()->RecordAfterState(node, Environment::kAttachFrameState);
1028 void BytecodeGraphBuilder::VisitStaInArrayLiteral() {
1029 PrepareEagerCheckpoint();
1030 Node* value = environment()->LookupAccumulator();
1032 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1034 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
1035 VectorSlotPair feedback =
1036 CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(2));
1037 const Operator* op = javascript()->StoreInArrayLiteral(feedback);
1039 JSTypeHintLowering::LoweringResult lowering =
1040 TryBuildSimplifiedStoreKeyed(op, array, index, value, feedback.slot());
1041 if (lowering.IsExit())
return;
1043 Node* node =
nullptr;
1044 if (lowering.IsSideEffectFree()) {
1045 node = lowering.value();
1047 DCHECK(!lowering.Changed());
1048 node = NewNode(op, array, index, value);
1051 environment()->RecordAfterState(node, Environment::kAttachFrameState);
1054 void BytecodeGraphBuilder::VisitStaDataPropertyInLiteral() {
1055 PrepareEagerCheckpoint();
1058 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1060 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
1061 Node* value = environment()->LookupAccumulator();
1062 int flags = bytecode_iterator().GetFlagOperand(2);
1063 VectorSlotPair feedback =
1064 CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(3));
1066 const Operator* op = javascript()->StoreDataPropertyInLiteral(feedback);
1067 Node* node = NewNode(op,
object, name, value, jsgraph()->Constant(flags));
1068 environment()->RecordAfterState(node, Environment::kAttachFrameState);
1071 void BytecodeGraphBuilder::VisitCollectTypeProfile() {
1072 PrepareEagerCheckpoint();
1075 jsgraph()->Constant(bytecode_iterator().GetImmediateOperand(0));
1076 Node* value = environment()->LookupAccumulator();
1077 Node* vector = jsgraph()->Constant(feedback_vector());
1079 const Operator* op = javascript()->CallRuntime(Runtime::kCollectTypeProfile);
1081 Node* node = NewNode(op, position, value, vector);
1082 environment()->RecordAfterState(node, Environment::kAttachFrameState);
1085 void BytecodeGraphBuilder::VisitLdaContextSlot() {
1086 const Operator* op = javascript()->LoadContext(
1087 bytecode_iterator().GetUnsignedImmediateOperand(2),
1088 bytecode_iterator().GetIndexOperand(1),
false);
1089 Node* node = NewNode(op);
1091 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1092 NodeProperties::ReplaceContextInput(node, context);
1093 environment()->BindAccumulator(node);
1096 void BytecodeGraphBuilder::VisitLdaImmutableContextSlot() {
1097 const Operator* op = javascript()->LoadContext(
1098 bytecode_iterator().GetUnsignedImmediateOperand(2),
1099 bytecode_iterator().GetIndexOperand(1),
true);
1100 Node* node = NewNode(op);
1102 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1103 NodeProperties::ReplaceContextInput(node, context);
1104 environment()->BindAccumulator(node);
1107 void BytecodeGraphBuilder::VisitLdaCurrentContextSlot() {
1108 const Operator* op = javascript()->LoadContext(
1109 0, bytecode_iterator().GetIndexOperand(0),
false);
1110 Node* node = NewNode(op);
1111 environment()->BindAccumulator(node);
1114 void BytecodeGraphBuilder::VisitLdaImmutableCurrentContextSlot() {
1115 const Operator* op = javascript()->LoadContext(
1116 0, bytecode_iterator().GetIndexOperand(0),
true);
1117 Node* node = NewNode(op);
1118 environment()->BindAccumulator(node);
1121 void BytecodeGraphBuilder::VisitStaContextSlot() {
1122 const Operator* op = javascript()->StoreContext(
1123 bytecode_iterator().GetUnsignedImmediateOperand(2),
1124 bytecode_iterator().GetIndexOperand(1));
1125 Node* value = environment()->LookupAccumulator();
1126 Node* node = NewNode(op, value);
1128 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1129 NodeProperties::ReplaceContextInput(node, context);
1132 void BytecodeGraphBuilder::VisitStaCurrentContextSlot() {
1133 const Operator* op =
1134 javascript()->StoreContext(0, bytecode_iterator().GetIndexOperand(0));
1135 Node* value = environment()->LookupAccumulator();
1139 void BytecodeGraphBuilder::BuildLdaLookupSlot(TypeofMode typeof_mode) {
1140 PrepareEagerCheckpoint();
1141 Node* name = jsgraph()->Constant(
1142 handle(bytecode_iterator().GetConstantForIndexOperand(0), isolate()));
1143 const Operator* op =
1144 javascript()->CallRuntime(typeof_mode == TypeofMode::NOT_INSIDE_TYPEOF
1145 ? Runtime::kLoadLookupSlot
1146 : Runtime::kLoadLookupSlotInsideTypeof);
1147 Node* value = NewNode(op, name);
1148 environment()->BindAccumulator(value, Environment::kAttachFrameState);
1151 void BytecodeGraphBuilder::VisitLdaLookupSlot() {
1152 BuildLdaLookupSlot(TypeofMode::NOT_INSIDE_TYPEOF);
1155 void BytecodeGraphBuilder::VisitLdaLookupSlotInsideTypeof() {
1156 BuildLdaLookupSlot(TypeofMode::INSIDE_TYPEOF);
1159 BytecodeGraphBuilder::Environment* BytecodeGraphBuilder::CheckContextExtensions(
1162 Environment* slow_environment =
nullptr;
1166 for (
uint32_t d = 0; d < depth; d++) {
1167 Node* extension_slot =
1168 NewNode(javascript()->LoadContext(d, Context::EXTENSION_INDEX,
false));
1170 Node* check_no_extension =
1171 NewNode(simplified()->ReferenceEqual(), extension_slot,
1172 jsgraph()->TheHoleConstant());
1174 NewBranch(check_no_extension);
1177 SubEnvironment sub_environment(
this);
1181 if (slow_environment ==
nullptr) {
1182 slow_environment = environment();
1185 slow_environment->Merge(environment(),
1186 bytecode_analysis()->GetInLivenessFor(
1187 bytecode_iterator().current_offset()));
1198 DCHECK(depth == 0 || slow_environment !=
nullptr);
1200 return slow_environment;
1203 void BytecodeGraphBuilder::BuildLdaLookupContextSlot(TypeofMode typeof_mode) {
1204 uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(2);
1207 Environment* slow_environment = CheckContextExtensions(depth);
1211 uint32_t slot_index = bytecode_iterator().GetIndexOperand(1);
1213 const Operator* op = javascript()->LoadContext(depth, slot_index,
false);
1214 environment()->BindAccumulator(NewNode(op));
1218 if (slow_environment !=
nullptr) {
1221 Environment* fast_environment = environment();
1224 set_environment(slow_environment);
1226 Node* name = jsgraph()->Constant(
1227 handle(bytecode_iterator().GetConstantForIndexOperand(0), isolate()));
1229 const Operator* op =
1230 javascript()->CallRuntime(typeof_mode == TypeofMode::NOT_INSIDE_TYPEOF
1231 ? Runtime::kLoadLookupSlot
1232 : Runtime::kLoadLookupSlotInsideTypeof);
1233 Node* value = NewNode(op, name);
1234 environment()->BindAccumulator(value, Environment::kAttachFrameState);
1237 fast_environment->Merge(environment(),
1238 bytecode_analysis()->GetOutLivenessFor(
1239 bytecode_iterator().current_offset()));
1240 set_environment(fast_environment);
1241 mark_as_needing_eager_checkpoint(
true);
1245 void BytecodeGraphBuilder::VisitLdaLookupContextSlot() {
1246 BuildLdaLookupContextSlot(TypeofMode::NOT_INSIDE_TYPEOF);
1249 void BytecodeGraphBuilder::VisitLdaLookupContextSlotInsideTypeof() {
1250 BuildLdaLookupContextSlot(TypeofMode::INSIDE_TYPEOF);
1253 void BytecodeGraphBuilder::BuildLdaLookupGlobalSlot(TypeofMode typeof_mode) {
1254 uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(2);
1257 Environment* slow_environment = CheckContextExtensions(depth);
1261 PrepareEagerCheckpoint();
1263 Name::cast(bytecode_iterator().GetConstantForIndexOperand(0)),
1265 uint32_t feedback_slot_index = bytecode_iterator().GetIndexOperand(1);
1266 Node* node = BuildLoadGlobal(name, feedback_slot_index, typeof_mode);
1267 environment()->BindAccumulator(node, Environment::kAttachFrameState);
1271 if (slow_environment !=
nullptr) {
1274 Environment* fast_environment = environment();
1277 set_environment(slow_environment);
1279 Node* name = jsgraph()->Constant(
1280 handle(bytecode_iterator().GetConstantForIndexOperand(0), isolate()));
1282 const Operator* op =
1283 javascript()->CallRuntime(typeof_mode == TypeofMode::NOT_INSIDE_TYPEOF
1284 ? Runtime::kLoadLookupSlot
1285 : Runtime::kLoadLookupSlotInsideTypeof);
1286 Node* value = NewNode(op, name);
1287 environment()->BindAccumulator(value, Environment::kAttachFrameState);
1290 fast_environment->Merge(environment(),
1291 bytecode_analysis()->GetOutLivenessFor(
1292 bytecode_iterator().current_offset()));
1293 set_environment(fast_environment);
1294 mark_as_needing_eager_checkpoint(
true);
1298 void BytecodeGraphBuilder::VisitLdaLookupGlobalSlot() {
1299 BuildLdaLookupGlobalSlot(TypeofMode::NOT_INSIDE_TYPEOF);
1302 void BytecodeGraphBuilder::VisitLdaLookupGlobalSlotInsideTypeof() {
1303 BuildLdaLookupGlobalSlot(TypeofMode::INSIDE_TYPEOF);
1306 void BytecodeGraphBuilder::VisitStaLookupSlot() {
1307 PrepareEagerCheckpoint();
1308 Node* value = environment()->LookupAccumulator();
1309 Node* name = jsgraph()->Constant(
1310 handle(bytecode_iterator().GetConstantForIndexOperand(0), isolate()));
1311 int bytecode_flags = bytecode_iterator().GetFlagOperand(1);
1312 LanguageMode language_mode =
static_cast<LanguageMode
>(
1313 interpreter::StoreLookupSlotFlags::LanguageModeBit::decode(
1315 LookupHoistingMode lookup_hoisting_mode =
static_cast<LookupHoistingMode
>(
1316 interpreter::StoreLookupSlotFlags::LookupHoistingModeBit::decode(
1318 DCHECK_IMPLIES(lookup_hoisting_mode == LookupHoistingMode::kLegacySloppy,
1319 is_sloppy(language_mode));
1320 const Operator* op = javascript()->CallRuntime(
1321 is_strict(language_mode)
1322 ? Runtime::kStoreLookupSlot_Strict
1323 : lookup_hoisting_mode == LookupHoistingMode::kLegacySloppy
1324 ? Runtime::kStoreLookupSlot_SloppyHoisting
1325 : Runtime::kStoreLookupSlot_Sloppy);
1326 Node* store = NewNode(op, name, value);
1327 environment()->BindAccumulator(store, Environment::kAttachFrameState);
1330 void BytecodeGraphBuilder::VisitLdaNamedProperty() {
1331 PrepareEagerCheckpoint();
1333 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1335 Name::cast(bytecode_iterator().GetConstantForIndexOperand(1)), isolate());
1336 VectorSlotPair feedback =
1337 CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(2));
1338 const Operator* op = javascript()->LoadNamed(name, feedback);
1340 JSTypeHintLowering::LoweringResult lowering =
1341 TryBuildSimplifiedLoadNamed(op,
object, feedback.slot());
1342 if (lowering.IsExit())
return;
1344 Node* node =
nullptr;
1345 if (lowering.IsSideEffectFree()) {
1346 node = lowering.value();
1348 DCHECK(!lowering.Changed());
1349 node = NewNode(op,
object);
1351 environment()->BindAccumulator(node, Environment::kAttachFrameState);
1354 void BytecodeGraphBuilder::VisitLdaNamedPropertyNoFeedback() {
1355 PrepareEagerCheckpoint();
1357 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1359 Name::cast(bytecode_iterator().GetConstantForIndexOperand(1)), isolate());
1360 const Operator* op = javascript()->LoadNamed(name, VectorSlotPair());
1361 Node* node = NewNode(op,
object);
1362 environment()->BindAccumulator(node, Environment::kAttachFrameState);
1365 void BytecodeGraphBuilder::VisitLdaKeyedProperty() {
1366 PrepareEagerCheckpoint();
1367 Node* key = environment()->LookupAccumulator();
1369 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1370 VectorSlotPair feedback =
1371 CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(1));
1372 const Operator* op = javascript()->LoadProperty(feedback);
1374 JSTypeHintLowering::LoweringResult lowering =
1375 TryBuildSimplifiedLoadKeyed(op,
object, key, feedback.slot());
1376 if (lowering.IsExit())
return;
1378 Node* node =
nullptr;
1379 if (lowering.IsSideEffectFree()) {
1380 node = lowering.value();
1382 DCHECK(!lowering.Changed());
1383 node = NewNode(op,
object, key);
1385 environment()->BindAccumulator(node, Environment::kAttachFrameState);
1388 void BytecodeGraphBuilder::BuildNamedStore(StoreMode store_mode) {
1389 PrepareEagerCheckpoint();
1390 Node* value = environment()->LookupAccumulator();
1392 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1394 Name::cast(bytecode_iterator().GetConstantForIndexOperand(1)), isolate());
1395 VectorSlotPair feedback =
1396 CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(2));
1399 if (store_mode == StoreMode::kOwn) {
1400 DCHECK_EQ(FeedbackSlotKind::kStoreOwnNamed,
1401 feedback.vector()->GetKind(feedback.slot()));
1402 op = javascript()->StoreNamedOwn(name, feedback);
1404 DCHECK_EQ(StoreMode::kNormal, store_mode);
1405 LanguageMode language_mode =
1406 feedback.vector()->GetLanguageMode(feedback.slot());
1407 op = javascript()->StoreNamed(language_mode, name, feedback);
1410 JSTypeHintLowering::LoweringResult lowering =
1411 TryBuildSimplifiedStoreNamed(op,
object, value, feedback.slot());
1412 if (lowering.IsExit())
return;
1414 Node* node =
nullptr;
1415 if (lowering.IsSideEffectFree()) {
1416 node = lowering.value();
1418 DCHECK(!lowering.Changed());
1419 node = NewNode(op,
object, value);
1421 environment()->RecordAfterState(node, Environment::kAttachFrameState);
1424 void BytecodeGraphBuilder::VisitStaNamedProperty() {
1425 BuildNamedStore(StoreMode::kNormal);
1428 void BytecodeGraphBuilder::VisitStaNamedPropertyNoFeedback() {
1429 PrepareEagerCheckpoint();
1430 Node* value = environment()->LookupAccumulator();
1432 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1434 Name::cast(bytecode_iterator().GetConstantForIndexOperand(1)), isolate());
1435 LanguageMode language_mode =
1436 static_cast<LanguageMode
>(bytecode_iterator().GetFlagOperand(2));
1437 const Operator* op =
1438 javascript()->StoreNamed(language_mode, name, VectorSlotPair());
1439 Node* node = NewNode(op,
object, value);
1440 environment()->RecordAfterState(node, Environment::kAttachFrameState);
1443 void BytecodeGraphBuilder::VisitStaNamedOwnProperty() {
1444 BuildNamedStore(StoreMode::kOwn);
1447 void BytecodeGraphBuilder::VisitStaKeyedProperty() {
1448 PrepareEagerCheckpoint();
1449 Node* value = environment()->LookupAccumulator();
1451 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1453 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
1454 VectorSlotPair feedback =
1455 CreateVectorSlotPair(bytecode_iterator().GetIndexOperand(2));
1456 LanguageMode language_mode =
1457 feedback.vector()->GetLanguageMode(feedback.slot());
1458 const Operator* op = javascript()->StoreProperty(language_mode, feedback);
1460 JSTypeHintLowering::LoweringResult lowering =
1461 TryBuildSimplifiedStoreKeyed(op,
object, key, value, feedback.slot());
1462 if (lowering.IsExit())
return;
1464 Node* node =
nullptr;
1465 if (lowering.IsSideEffectFree()) {
1466 node = lowering.value();
1468 DCHECK(!lowering.Changed());
1469 node = NewNode(op,
object, key, value);
1472 environment()->RecordAfterState(node, Environment::kAttachFrameState);
1475 void BytecodeGraphBuilder::VisitLdaModuleVariable() {
1476 int32_t cell_index = bytecode_iterator().GetImmediateOperand(0);
1477 uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(1);
1479 NewNode(javascript()->LoadContext(depth, Context::EXTENSION_INDEX,
true));
1480 Node* value = NewNode(javascript()->LoadModule(cell_index), module);
1481 environment()->BindAccumulator(value);
1484 void BytecodeGraphBuilder::VisitStaModuleVariable() {
1485 int32_t cell_index = bytecode_iterator().GetImmediateOperand(0);
1486 uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(1);
1488 NewNode(javascript()->LoadContext(depth, Context::EXTENSION_INDEX,
true));
1489 Node* value = environment()->LookupAccumulator();
1490 NewNode(javascript()->StoreModule(cell_index), module, value);
1493 void BytecodeGraphBuilder::VisitPushContext() {
1494 Node* new_context = environment()->LookupAccumulator();
1495 environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0),
1496 environment()->Context());
1497 environment()->SetContext(new_context);
1500 void BytecodeGraphBuilder::VisitPopContext() {
1502 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1503 environment()->SetContext(context);
1506 void BytecodeGraphBuilder::VisitCreateClosure() {
1507 Handle<SharedFunctionInfo> shared_info(
1508 SharedFunctionInfo::cast(
1509 bytecode_iterator().GetConstantForIndexOperand(0)),
1511 FeedbackSlot slot = bytecode_iterator().GetSlotOperand(1);
1512 FeedbackNexus nexus(feedback_vector(), slot);
1513 PretenureFlag tenured =
1514 interpreter::CreateClosureFlags::PretenuredBit::decode(
1515 bytecode_iterator().GetFlagOperand(2))
1518 const Operator* op = javascript()->CreateClosure(
1519 shared_info, nexus.GetFeedbackCell(),
1520 handle(jsgraph()->isolate()->builtins()->builtin(Builtins::kCompileLazy),
1523 Node* closure = NewNode(op);
1524 environment()->BindAccumulator(closure);
1527 void BytecodeGraphBuilder::VisitCreateBlockContext() {
1528 Handle<ScopeInfo> scope_info(
1529 ScopeInfo::cast(bytecode_iterator().GetConstantForIndexOperand(0)),
1532 const Operator* op = javascript()->CreateBlockContext(scope_info);
1533 Node* context = NewNode(op);
1534 environment()->BindAccumulator(context);
1537 void BytecodeGraphBuilder::VisitCreateFunctionContext() {
1538 Handle<ScopeInfo> scope_info(
1539 ScopeInfo::cast(bytecode_iterator().GetConstantForIndexOperand(0)),
1541 uint32_t slots = bytecode_iterator().GetUnsignedImmediateOperand(1);
1542 const Operator* op =
1543 javascript()->CreateFunctionContext(scope_info, slots, FUNCTION_SCOPE);
1544 Node* context = NewNode(op);
1545 environment()->BindAccumulator(context);
1548 void BytecodeGraphBuilder::VisitCreateEvalContext() {
1549 Handle<ScopeInfo> scope_info(
1550 ScopeInfo::cast(bytecode_iterator().GetConstantForIndexOperand(0)),
1552 uint32_t slots = bytecode_iterator().GetUnsignedImmediateOperand(1);
1553 const Operator* op =
1554 javascript()->CreateFunctionContext(scope_info, slots, EVAL_SCOPE);
1555 Node* context = NewNode(op);
1556 environment()->BindAccumulator(context);
1559 void BytecodeGraphBuilder::VisitCreateCatchContext() {
1560 interpreter::Register reg = bytecode_iterator().GetRegisterOperand(0);
1561 Node* exception = environment()->LookupRegister(reg);
1562 Handle<ScopeInfo> scope_info(
1563 ScopeInfo::cast(bytecode_iterator().GetConstantForIndexOperand(1)),
1566 const Operator* op = javascript()->CreateCatchContext(scope_info);
1567 Node* context = NewNode(op, exception);
1568 environment()->BindAccumulator(context);
1571 void BytecodeGraphBuilder::VisitCreateWithContext() {
1573 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1574 Handle<ScopeInfo> scope_info(
1575 ScopeInfo::cast(bytecode_iterator().GetConstantForIndexOperand(1)),
1578 const Operator* op = javascript()->CreateWithContext(scope_info);
1579 Node* context = NewNode(op,
object);
1580 environment()->BindAccumulator(context);
1583 void BytecodeGraphBuilder::BuildCreateArguments(CreateArgumentsType type) {
1584 const Operator* op = javascript()->CreateArguments(type);
1585 Node*
object = NewNode(op, GetFunctionClosure());
1586 environment()->BindAccumulator(
object, Environment::kAttachFrameState);
1589 void BytecodeGraphBuilder::VisitCreateMappedArguments() {
1590 BuildCreateArguments(CreateArgumentsType::kMappedArguments);
1593 void BytecodeGraphBuilder::VisitCreateUnmappedArguments() {
1594 BuildCreateArguments(CreateArgumentsType::kUnmappedArguments);
1597 void BytecodeGraphBuilder::VisitCreateRestParameter() {
1598 BuildCreateArguments(CreateArgumentsType::kRestParameter);
1601 void BytecodeGraphBuilder::VisitCreateRegExpLiteral() {
1602 Handle<String> constant_pattern(
1603 String::cast(bytecode_iterator().GetConstantForIndexOperand(0)),
1605 int const slot_id = bytecode_iterator().GetIndexOperand(1);
1606 VectorSlotPair pair = CreateVectorSlotPair(slot_id);
1607 int literal_flags = bytecode_iterator().GetFlagOperand(2);
1608 Node* literal = NewNode(
1609 javascript()->CreateLiteralRegExp(constant_pattern, pair, literal_flags));
1610 environment()->BindAccumulator(literal, Environment::kAttachFrameState);
1613 void BytecodeGraphBuilder::VisitCreateArrayLiteral() {
1614 Handle<ArrayBoilerplateDescription> array_boilerplate_description(
1615 ArrayBoilerplateDescription::cast(
1616 bytecode_iterator().GetConstantForIndexOperand(0)),
1618 int const slot_id = bytecode_iterator().GetIndexOperand(1);
1619 VectorSlotPair pair = CreateVectorSlotPair(slot_id);
1620 int bytecode_flags = bytecode_iterator().GetFlagOperand(2);
1622 interpreter::CreateArrayLiteralFlags::FlagsBits::decode(bytecode_flags);
1627 literal_flags |= ArrayLiteral::kDisableMementos;
1630 int number_of_elements =
1631 array_boilerplate_description->constant_elements()->length();
1632 Node* literal = NewNode(javascript()->CreateLiteralArray(
1633 array_boilerplate_description, pair, literal_flags, number_of_elements));
1634 environment()->BindAccumulator(literal, Environment::kAttachFrameState);
1637 void BytecodeGraphBuilder::VisitCreateEmptyArrayLiteral() {
1638 int const slot_id = bytecode_iterator().GetIndexOperand(0);
1639 VectorSlotPair pair = CreateVectorSlotPair(slot_id);
1640 Node* literal = NewNode(javascript()->CreateEmptyLiteralArray(pair));
1641 environment()->BindAccumulator(literal);
1644 void BytecodeGraphBuilder::VisitCreateArrayFromIterable() {
1645 Node* iterable = NewNode(javascript()->CreateArrayFromIterable(),
1646 environment()->LookupAccumulator());
1647 environment()->BindAccumulator(iterable, Environment::kAttachFrameState);
1650 void BytecodeGraphBuilder::VisitCreateObjectLiteral() {
1651 Handle<ObjectBoilerplateDescription> constant_properties(
1652 ObjectBoilerplateDescription::cast(
1653 bytecode_iterator().GetConstantForIndexOperand(0)),
1655 int const slot_id = bytecode_iterator().GetIndexOperand(1);
1656 VectorSlotPair pair = CreateVectorSlotPair(slot_id);
1657 int bytecode_flags = bytecode_iterator().GetFlagOperand(2);
1659 interpreter::CreateObjectLiteralFlags::FlagsBits::decode(bytecode_flags);
1662 int number_of_properties = constant_properties->size();
1663 Node* literal = NewNode(javascript()->CreateLiteralObject(
1664 constant_properties, pair, literal_flags, number_of_properties));
1665 environment()->BindAccumulator(literal, Environment::kAttachFrameState);
1668 void BytecodeGraphBuilder::VisitCreateEmptyObjectLiteral() {
1670 NewNode(javascript()->CreateEmptyLiteralObject(), GetFunctionClosure());
1671 environment()->BindAccumulator(literal);
1674 void BytecodeGraphBuilder::VisitCloneObject() {
1675 PrepareEagerCheckpoint();
1677 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1678 int flags = bytecode_iterator().GetFlagOperand(1);
1679 int slot = bytecode_iterator().GetIndexOperand(2);
1680 const Operator* op =
1681 javascript()->CloneObject(CreateVectorSlotPair(slot), flags);
1682 Node* value = NewNode(op, source);
1683 environment()->BindAccumulator(value, Environment::kAttachFrameState);
1686 void BytecodeGraphBuilder::VisitGetTemplateObject() {
1687 Handle<TemplateObjectDescription> description(
1688 TemplateObjectDescription::cast(
1689 bytecode_iterator().GetConstantForIndexOperand(0)),
1691 FeedbackSlot slot = bytecode_iterator().GetSlotOperand(1);
1692 FeedbackNexus nexus(feedback_vector(), slot);
1694 Handle<JSArray> cached_value;
1695 if (nexus.GetFeedback() == MaybeObject::FromSmi(Smi::zero())) {
1700 TemplateObjectDescription::CreateTemplateObject(isolate(), description);
1701 nexus.vector()->Set(slot, *cached_value);
1704 handle(JSArray::cast(nexus.GetFeedback()->GetHeapObjectAssumeStrong()),
1708 Node* template_object = jsgraph()->HeapConstant(cached_value);
1709 environment()->BindAccumulator(template_object);
1712 Node*
const* BytecodeGraphBuilder::GetCallArgumentsFromRegisters(
1713 Node* callee, Node* receiver, interpreter::Register first_arg,
1717 int arity = 2 + arg_count;
1719 Node** all = local_zone()->NewArray<Node*>(
static_cast<size_t>(arity));
1725 int arg_base = first_arg.index();
1726 for (
int i = 0;
i < arg_count; ++
i) {
1728 environment()->LookupRegister(interpreter::Register(arg_base +
i));
1734 Node* BytecodeGraphBuilder::ProcessCallArguments(
const Operator* call_op,
1737 return MakeNode(call_op, arg_count, args,
false);
1740 Node* BytecodeGraphBuilder::ProcessCallArguments(
const Operator* call_op,
1742 interpreter::Register receiver,
1744 Node* receiver_node = environment()->LookupRegister(receiver);
1746 DCHECK_GE(reg_count, 1);
1747 interpreter::Register first_arg = interpreter::Register(receiver.index() + 1);
1748 int arg_count =
static_cast<int>(reg_count) - 1;
1750 Node*
const* call_args = GetCallArgumentsFromRegisters(callee, receiver_node,
1751 first_arg, arg_count);
1752 return ProcessCallArguments(call_op, call_args, 2 + arg_count);
1755 void BytecodeGraphBuilder::BuildCall(ConvertReceiverMode receiver_mode,
1756 Node*
const* args,
size_t arg_count,
1758 DCHECK_EQ(interpreter::Bytecodes::GetReceiverMode(
1759 bytecode_iterator().current_bytecode()),
1761 PrepareEagerCheckpoint();
1763 VectorSlotPair feedback = CreateVectorSlotPair(slot_id);
1765 CallFrequency frequency = ComputeCallFrequency(slot_id);
1766 const Operator* op =
1767 javascript()->Call(arg_count, frequency, feedback, receiver_mode,
1768 GetSpeculationMode(slot_id));
1769 JSTypeHintLowering::LoweringResult lowering = TryBuildSimplifiedCall(
1770 op, args, static_cast<int>(arg_count), feedback.slot());
1771 if (lowering.IsExit())
return;
1773 Node* node =
nullptr;
1774 if (lowering.IsSideEffectFree()) {
1775 node = lowering.value();
1777 DCHECK(!lowering.Changed());
1778 node = ProcessCallArguments(op, args, static_cast<int>(arg_count));
1780 environment()->BindAccumulator(node, Environment::kAttachFrameState);
1783 Node*
const* BytecodeGraphBuilder::ProcessCallVarArgs(
1784 ConvertReceiverMode receiver_mode, Node* callee,
1785 interpreter::Register first_reg,
int arg_count) {
1786 DCHECK_GE(arg_count, 0);
1787 Node* receiver_node;
1788 interpreter::Register first_arg;
1790 if (receiver_mode == ConvertReceiverMode::kNullOrUndefined) {
1793 receiver_node = jsgraph()->UndefinedConstant();
1794 first_arg = first_reg;
1798 receiver_node = environment()->LookupRegister(first_reg);
1799 first_arg = interpreter::Register(first_reg.index() + 1);
1802 Node*
const* call_args = GetCallArgumentsFromRegisters(callee, receiver_node,
1803 first_arg, arg_count);
1807 void BytecodeGraphBuilder::BuildCallVarArgs(ConvertReceiverMode receiver_mode) {
1808 DCHECK_EQ(interpreter::Bytecodes::GetReceiverMode(
1809 bytecode_iterator().current_bytecode()),
1812 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1813 interpreter::Register first_reg = bytecode_iterator().GetRegisterOperand(1);
1814 size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
1815 int const slot_id = bytecode_iterator().GetIndexOperand(3);
1817 int arg_count = receiver_mode == ConvertReceiverMode::kNullOrUndefined
1818 ?
static_cast<int>(reg_count)
1819 : static_cast<int>(reg_count) - 1;
1820 Node*
const* call_args =
1821 ProcessCallVarArgs(receiver_mode, callee, first_reg, arg_count);
1822 BuildCall(receiver_mode, call_args, static_cast<size_t>(2 + arg_count),
1826 void BytecodeGraphBuilder::VisitCallAnyReceiver() {
1827 BuildCallVarArgs(ConvertReceiverMode::kAny);
1830 void BytecodeGraphBuilder::VisitCallNoFeedback() {
1831 DCHECK_EQ(interpreter::Bytecodes::GetReceiverMode(
1832 bytecode_iterator().current_bytecode()),
1833 ConvertReceiverMode::kAny);
1835 PrepareEagerCheckpoint();
1837 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1839 interpreter::Register first_reg = bytecode_iterator().GetRegisterOperand(1);
1840 size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
1844 int arg_count =
static_cast<int>(reg_count) - 1;
1847 int arity = 2 + arg_count;
1851 DCHECK(CallFrequency::kNoFeedbackCallFrequency < FLAG_min_inlining_frequency);
1852 const Operator* call = javascript()->Call(
1853 arity, CallFrequency(CallFrequency::kNoFeedbackCallFrequency));
1854 Node*
const* call_args = ProcessCallVarArgs(ConvertReceiverMode::kAny, callee,
1855 first_reg, arg_count);
1856 Node* value = ProcessCallArguments(call, call_args, arity);
1857 environment()->BindAccumulator(value, Environment::kAttachFrameState);
1860 void BytecodeGraphBuilder::VisitCallProperty() {
1861 BuildCallVarArgs(ConvertReceiverMode::kNotNullOrUndefined);
1864 void BytecodeGraphBuilder::VisitCallProperty0() {
1866 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1868 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
1869 int const slot_id = bytecode_iterator().GetIndexOperand(2);
1870 BuildCall(ConvertReceiverMode::kNotNullOrUndefined, {callee, receiver},
1874 void BytecodeGraphBuilder::VisitCallProperty1() {
1876 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1878 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
1880 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2));
1881 int const slot_id = bytecode_iterator().GetIndexOperand(3);
1882 BuildCall(ConvertReceiverMode::kNotNullOrUndefined, {callee, receiver, arg0},
1886 void BytecodeGraphBuilder::VisitCallProperty2() {
1888 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1890 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
1892 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2));
1894 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(3));
1895 int const slot_id = bytecode_iterator().GetIndexOperand(4);
1896 BuildCall(ConvertReceiverMode::kNotNullOrUndefined,
1897 {callee, receiver, arg0, arg1}, slot_id);
1900 void BytecodeGraphBuilder::VisitCallUndefinedReceiver() {
1901 BuildCallVarArgs(ConvertReceiverMode::kNullOrUndefined);
1904 void BytecodeGraphBuilder::VisitCallUndefinedReceiver0() {
1906 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1907 Node* receiver = jsgraph()->UndefinedConstant();
1908 int const slot_id = bytecode_iterator().GetIndexOperand(1);
1909 BuildCall(ConvertReceiverMode::kNullOrUndefined, {callee, receiver}, slot_id);
1912 void BytecodeGraphBuilder::VisitCallUndefinedReceiver1() {
1914 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1915 Node* receiver = jsgraph()->UndefinedConstant();
1917 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
1918 int const slot_id = bytecode_iterator().GetIndexOperand(2);
1919 BuildCall(ConvertReceiverMode::kNullOrUndefined, {callee, receiver, arg0},
1923 void BytecodeGraphBuilder::VisitCallUndefinedReceiver2() {
1925 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1926 Node* receiver = jsgraph()->UndefinedConstant();
1928 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
1930 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2));
1931 int const slot_id = bytecode_iterator().GetIndexOperand(3);
1932 BuildCall(ConvertReceiverMode::kNullOrUndefined,
1933 {callee, receiver, arg0, arg1}, slot_id);
1936 void BytecodeGraphBuilder::VisitCallWithSpread() {
1937 PrepareEagerCheckpoint();
1939 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1940 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
1941 Node* receiver_node = environment()->LookupRegister(receiver);
1942 size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
1943 interpreter::Register first_arg = interpreter::Register(receiver.index() + 1);
1944 int arg_count =
static_cast<int>(reg_count) - 1;
1945 Node*
const* args = GetCallArgumentsFromRegisters(callee, receiver_node,
1946 first_arg, arg_count);
1947 int const slot_id = bytecode_iterator().GetIndexOperand(3);
1948 VectorSlotPair feedback = CreateVectorSlotPair(slot_id);
1950 CallFrequency frequency = ComputeCallFrequency(slot_id);
1951 const Operator* op = javascript()->CallWithSpread(
1952 static_cast<int>(reg_count + 1), frequency, feedback);
1954 JSTypeHintLowering::LoweringResult lowering = TryBuildSimplifiedCall(
1955 op, args, static_cast<int>(arg_count), feedback.slot());
1956 if (lowering.IsExit())
return;
1958 Node* node =
nullptr;
1959 if (lowering.IsSideEffectFree()) {
1960 node = lowering.value();
1962 DCHECK(!lowering.Changed());
1963 node = ProcessCallArguments(op, args, 2 + arg_count);
1965 environment()->BindAccumulator(node, Environment::kAttachFrameState);
1968 void BytecodeGraphBuilder::VisitCallJSRuntime() {
1969 PrepareEagerCheckpoint();
1970 Node* callee = BuildLoadNativeContextField(
1971 bytecode_iterator().GetNativeContextIndexOperand(0));
1972 interpreter::Register first_reg = bytecode_iterator().GetRegisterOperand(1);
1973 size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
1974 int arg_count =
static_cast<int>(reg_count);
1976 const Operator* call = javascript()->Call(2 + arg_count);
1977 Node*
const* call_args = ProcessCallVarArgs(
1978 ConvertReceiverMode::kNullOrUndefined, callee, first_reg, arg_count);
1979 Node* value = ProcessCallArguments(call, call_args, 2 + arg_count);
1980 environment()->BindAccumulator(value, Environment::kAttachFrameState);
1983 Node* BytecodeGraphBuilder::ProcessCallRuntimeArguments(
1984 const Operator* call_runtime_op, interpreter::Register receiver,
1986 int arg_count =
static_cast<int>(reg_count);
1988 int arity = arg_count;
1989 Node** all = local_zone()->NewArray<Node*>(
static_cast<size_t>(arity));
1990 int first_arg_index = receiver.index();
1991 for (
int i = 0; i < static_cast<int>(reg_count); ++
i) {
1992 all[
i] = environment()->LookupRegister(
1993 interpreter::Register(first_arg_index +
i));
1995 Node* value = MakeNode(call_runtime_op, arity, all,
false);
1999 void BytecodeGraphBuilder::VisitCallRuntime() {
2000 PrepareEagerCheckpoint();
2001 Runtime::FunctionId function_id = bytecode_iterator().GetRuntimeIdOperand(0);
2002 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
2003 size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
2006 const Operator* call = javascript()->CallRuntime(function_id, reg_count);
2007 Node* value = ProcessCallRuntimeArguments(call, receiver, reg_count);
2008 environment()->BindAccumulator(value, Environment::kAttachFrameState);
2011 if (Runtime::IsNonReturning(function_id)) {
2013 Node* control = NewNode(common()->Throw());
2014 MergeControlToLeaveFunction(control);
2018 void BytecodeGraphBuilder::VisitCallRuntimeForPair() {
2019 PrepareEagerCheckpoint();
2020 Runtime::FunctionId functionId = bytecode_iterator().GetRuntimeIdOperand(0);
2021 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
2022 size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
2023 interpreter::Register first_return =
2024 bytecode_iterator().GetRegisterOperand(3);
2027 const Operator* call = javascript()->CallRuntime(functionId, reg_count);
2028 Node* return_pair = ProcessCallRuntimeArguments(call, receiver, reg_count);
2029 environment()->BindRegistersToProjections(first_return, return_pair,
2030 Environment::kAttachFrameState);
2033 Node*
const* BytecodeGraphBuilder::GetConstructArgumentsFromRegister(
2034 Node* target, Node* new_target, interpreter::Register first_arg,
2037 int arity = arg_count + 2;
2038 Node** all = local_zone()->NewArray<Node*>(
static_cast<size_t>(arity));
2040 int first_arg_index = first_arg.index();
2041 for (
int i = 0;
i < arg_count; ++
i) {
2042 all[1 +
i] = environment()->LookupRegister(
2043 interpreter::Register(first_arg_index +
i));
2045 all[arity - 1] = new_target;
2049 Node* BytecodeGraphBuilder::ProcessConstructArguments(
const Operator* op,
2052 return MakeNode(op, arg_count, args,
false);
2055 void BytecodeGraphBuilder::VisitConstruct() {
2056 PrepareEagerCheckpoint();
2057 interpreter::Register callee_reg = bytecode_iterator().GetRegisterOperand(0);
2058 interpreter::Register first_reg = bytecode_iterator().GetRegisterOperand(1);
2059 size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
2060 int const slot_id = bytecode_iterator().GetIndexOperand(3);
2061 VectorSlotPair feedback = CreateVectorSlotPair(slot_id);
2063 Node* new_target = environment()->LookupAccumulator();
2064 Node* callee = environment()->LookupRegister(callee_reg);
2066 CallFrequency frequency = ComputeCallFrequency(slot_id);
2067 const Operator* op = javascript()->Construct(
2068 static_cast<uint32_t>(reg_count + 2), frequency, feedback);
2069 int arg_count =
static_cast<int>(reg_count);
2070 Node*
const* args = GetConstructArgumentsFromRegister(callee, new_target,
2071 first_reg, arg_count);
2072 JSTypeHintLowering::LoweringResult lowering = TryBuildSimplifiedConstruct(
2073 op, args, static_cast<int>(arg_count), feedback.slot());
2074 if (lowering.IsExit())
return;
2076 Node* node =
nullptr;
2077 if (lowering.IsSideEffectFree()) {
2078 node = lowering.value();
2080 DCHECK(!lowering.Changed());
2081 node = ProcessConstructArguments(op, args, 2 + arg_count);
2083 environment()->BindAccumulator(node, Environment::kAttachFrameState);
2086 void BytecodeGraphBuilder::VisitConstructWithSpread() {
2087 PrepareEagerCheckpoint();
2088 interpreter::Register callee_reg = bytecode_iterator().GetRegisterOperand(0);
2089 interpreter::Register first_reg = bytecode_iterator().GetRegisterOperand(1);
2090 size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
2091 int const slot_id = bytecode_iterator().GetIndexOperand(3);
2092 VectorSlotPair feedback = CreateVectorSlotPair(slot_id);
2094 Node* new_target = environment()->LookupAccumulator();
2095 Node* callee = environment()->LookupRegister(callee_reg);
2097 CallFrequency frequency = ComputeCallFrequency(slot_id);
2098 const Operator* op = javascript()->ConstructWithSpread(
2099 static_cast<uint32_t>(reg_count + 2), frequency, feedback);
2100 int arg_count =
static_cast<int>(reg_count);
2101 Node*
const* args = GetConstructArgumentsFromRegister(callee, new_target,
2102 first_reg, arg_count);
2103 JSTypeHintLowering::LoweringResult lowering = TryBuildSimplifiedConstruct(
2104 op, args, static_cast<int>(arg_count), feedback.slot());
2105 if (lowering.IsExit())
return;
2107 Node* node =
nullptr;
2108 if (lowering.IsSideEffectFree()) {
2109 node = lowering.value();
2111 DCHECK(!lowering.Changed());
2112 node = ProcessConstructArguments(op, args, 2 + arg_count);
2114 environment()->BindAccumulator(node, Environment::kAttachFrameState);
2117 void BytecodeGraphBuilder::VisitInvokeIntrinsic() {
2118 PrepareEagerCheckpoint();
2119 Runtime::FunctionId functionId = bytecode_iterator().GetIntrinsicIdOperand(0);
2120 interpreter::Register receiver = bytecode_iterator().GetRegisterOperand(1);
2121 size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
2125 const Operator* call = javascript()->CallRuntime(functionId, reg_count);
2126 Node* value = ProcessCallRuntimeArguments(call, receiver, reg_count);
2127 environment()->BindAccumulator(value, Environment::kAttachFrameState);
2130 void BytecodeGraphBuilder::VisitThrow() {
2131 BuildLoopExitsForFunctionExit(bytecode_analysis()->GetInLivenessFor(
2132 bytecode_iterator().current_offset()));
2133 Node* value = environment()->LookupAccumulator();
2134 Node* call = NewNode(javascript()->CallRuntime(Runtime::kThrow), value);
2135 environment()->BindAccumulator(call, Environment::kAttachFrameState);
2136 Node* control = NewNode(common()->Throw());
2137 MergeControlToLeaveFunction(control);
2140 void BytecodeGraphBuilder::VisitAbort() {
2141 BuildLoopExitsForFunctionExit(bytecode_analysis()->GetInLivenessFor(
2142 bytecode_iterator().current_offset()));
2143 AbortReason reason =
2144 static_cast<AbortReason
>(bytecode_iterator().GetIndexOperand(0));
2145 NewNode(simplified()->RuntimeAbort(reason));
2146 Node* control = NewNode(common()->Throw());
2147 MergeControlToLeaveFunction(control);
2150 void BytecodeGraphBuilder::VisitReThrow() {
2151 BuildLoopExitsForFunctionExit(bytecode_analysis()->GetInLivenessFor(
2152 bytecode_iterator().current_offset()));
2153 Node* value = environment()->LookupAccumulator();
2154 NewNode(javascript()->CallRuntime(Runtime::kReThrow), value);
2155 Node* control = NewNode(common()->Throw());
2156 MergeControlToLeaveFunction(control);
2159 void BytecodeGraphBuilder::BuildHoleCheckAndThrow(
2160 Node* condition, Runtime::FunctionId runtime_id, Node* name) {
2161 Node* accumulator = environment()->LookupAccumulator();
2162 NewBranch(condition, BranchHint::kFalse);
2164 SubEnvironment sub_environment(
this);
2167 BuildLoopExitsForFunctionExit(bytecode_analysis()->GetInLivenessFor(
2168 bytecode_iterator().current_offset()));
2170 const Operator* op = javascript()->CallRuntime(runtime_id);
2171 if (runtime_id == Runtime::kThrowReferenceError) {
2172 DCHECK_NOT_NULL(name);
2173 node = NewNode(op, name);
2175 DCHECK(runtime_id == Runtime::kThrowSuperAlreadyCalledError ||
2176 runtime_id == Runtime::kThrowSuperNotCalled);
2179 environment()->RecordAfterState(node, Environment::kAttachFrameState);
2180 Node* control = NewNode(common()->Throw());
2181 MergeControlToLeaveFunction(control);
2184 environment()->BindAccumulator(accumulator);
2187 void BytecodeGraphBuilder::VisitThrowReferenceErrorIfHole() {
2188 Node* accumulator = environment()->LookupAccumulator();
2189 Node* check_for_hole = NewNode(simplified()->ReferenceEqual(), accumulator,
2190 jsgraph()->TheHoleConstant());
2191 Node* name = jsgraph()->Constant(
2192 handle(bytecode_iterator().GetConstantForIndexOperand(0), isolate()));
2193 BuildHoleCheckAndThrow(check_for_hole, Runtime::kThrowReferenceError, name);
2196 void BytecodeGraphBuilder::VisitThrowSuperNotCalledIfHole() {
2197 Node* accumulator = environment()->LookupAccumulator();
2198 Node* check_for_hole = NewNode(simplified()->ReferenceEqual(), accumulator,
2199 jsgraph()->TheHoleConstant());
2200 BuildHoleCheckAndThrow(check_for_hole, Runtime::kThrowSuperNotCalled);
2203 void BytecodeGraphBuilder::VisitThrowSuperAlreadyCalledIfNotHole() {
2204 Node* accumulator = environment()->LookupAccumulator();
2205 Node* check_for_hole = NewNode(simplified()->ReferenceEqual(), accumulator,
2206 jsgraph()->TheHoleConstant());
2207 Node* check_for_not_hole =
2208 NewNode(simplified()->BooleanNot(), check_for_hole);
2209 BuildHoleCheckAndThrow(check_for_not_hole,
2210 Runtime::kThrowSuperAlreadyCalledError);
2213 void BytecodeGraphBuilder::BuildUnaryOp(
const Operator* op) {
2214 PrepareEagerCheckpoint();
2215 Node* operand = environment()->LookupAccumulator();
2218 bytecode_iterator().GetSlotOperand(kUnaryOperationHintIndex);
2219 JSTypeHintLowering::LoweringResult lowering =
2220 TryBuildSimplifiedUnaryOp(op, operand, slot);
2221 if (lowering.IsExit())
return;
2223 Node* node =
nullptr;
2224 if (lowering.IsSideEffectFree()) {
2225 node = lowering.value();
2227 DCHECK(!lowering.Changed());
2228 node = NewNode(op, operand);
2231 environment()->BindAccumulator(node, Environment::kAttachFrameState);
2234 void BytecodeGraphBuilder::BuildBinaryOp(
const Operator* op) {
2235 PrepareEagerCheckpoint();
2237 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2238 Node* right = environment()->LookupAccumulator();
2241 bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex);
2242 JSTypeHintLowering::LoweringResult lowering =
2243 TryBuildSimplifiedBinaryOp(op, left, right, slot);
2244 if (lowering.IsExit())
return;
2246 Node* node =
nullptr;
2247 if (lowering.IsSideEffectFree()) {
2248 node = lowering.value();
2250 DCHECK(!lowering.Changed());
2251 node = NewNode(op, left, right);
2254 environment()->BindAccumulator(node, Environment::kAttachFrameState);
2259 BinaryOperationHint BytecodeGraphBuilder::GetBinaryOperationHint(
2260 int operand_index) {
2261 FeedbackSlot slot = bytecode_iterator().GetSlotOperand(operand_index);
2262 FeedbackNexus nexus(feedback_vector(), slot);
2263 return nexus.GetBinaryOperationFeedback();
2268 CompareOperationHint BytecodeGraphBuilder::GetCompareOperationHint() {
2269 FeedbackSlot slot = bytecode_iterator().GetSlotOperand(1);
2270 FeedbackNexus nexus(feedback_vector(), slot);
2271 return nexus.GetCompareOperationFeedback();
2275 ForInMode BytecodeGraphBuilder::GetForInMode(
int operand_index) {
2276 FeedbackSlot slot = bytecode_iterator().GetSlotOperand(operand_index);
2277 FeedbackNexus nexus(feedback_vector(), slot);
2278 switch (nexus.GetForInFeedback()) {
2279 case ForInHint::kNone:
2280 case ForInHint::kEnumCacheKeysAndIndices:
2281 return ForInMode::kUseEnumCacheKeysAndIndices;
2282 case ForInHint::kEnumCacheKeys:
2283 return ForInMode::kUseEnumCacheKeys;
2284 case ForInHint::kAny:
2285 return ForInMode::kGeneric;
2290 CallFrequency BytecodeGraphBuilder::ComputeCallFrequency(
int slot_id)
const {
2291 if (invocation_frequency_.IsUnknown())
return CallFrequency();
2292 FeedbackNexus nexus(feedback_vector(), FeedbackVector::ToSlot(slot_id));
2293 return CallFrequency(nexus.ComputeCallFrequency() *
2294 invocation_frequency_.value());
2297 SpeculationMode BytecodeGraphBuilder::GetSpeculationMode(
int slot_id)
const {
2298 FeedbackNexus nexus(feedback_vector(), FeedbackVector::ToSlot(slot_id));
2299 return nexus.GetSpeculationMode();
2302 void BytecodeGraphBuilder::VisitBitwiseNot() {
2303 BuildUnaryOp(javascript()->BitwiseNot());
2306 void BytecodeGraphBuilder::VisitDec() {
2307 BuildUnaryOp(javascript()->Decrement());
2310 void BytecodeGraphBuilder::VisitInc() {
2311 BuildUnaryOp(javascript()->Increment());
2314 void BytecodeGraphBuilder::VisitNegate() {
2315 BuildUnaryOp(javascript()->Negate());
2318 void BytecodeGraphBuilder::VisitAdd() {
2320 javascript()->Add(GetBinaryOperationHint(kBinaryOperationHintIndex)));
2323 void BytecodeGraphBuilder::VisitSub() {
2324 BuildBinaryOp(javascript()->Subtract());
2327 void BytecodeGraphBuilder::VisitMul() {
2328 BuildBinaryOp(javascript()->Multiply());
2331 void BytecodeGraphBuilder::VisitDiv() { BuildBinaryOp(javascript()->Divide()); }
2333 void BytecodeGraphBuilder::VisitMod() {
2334 BuildBinaryOp(javascript()->Modulus());
2337 void BytecodeGraphBuilder::VisitExp() {
2338 BuildBinaryOp(javascript()->Exponentiate());
2341 void BytecodeGraphBuilder::VisitBitwiseOr() {
2342 BuildBinaryOp(javascript()->BitwiseOr());
2345 void BytecodeGraphBuilder::VisitBitwiseXor() {
2346 BuildBinaryOp(javascript()->BitwiseXor());
2349 void BytecodeGraphBuilder::VisitBitwiseAnd() {
2350 BuildBinaryOp(javascript()->BitwiseAnd());
2353 void BytecodeGraphBuilder::VisitShiftLeft() {
2354 BuildBinaryOp(javascript()->ShiftLeft());
2357 void BytecodeGraphBuilder::VisitShiftRight() {
2358 BuildBinaryOp(javascript()->ShiftRight());
2361 void BytecodeGraphBuilder::VisitShiftRightLogical() {
2362 BuildBinaryOp(javascript()->ShiftRightLogical());
2365 void BytecodeGraphBuilder::BuildBinaryOpWithImmediate(
const Operator* op) {
2366 PrepareEagerCheckpoint();
2367 Node* left = environment()->LookupAccumulator();
2368 Node* right = jsgraph()->Constant(bytecode_iterator().GetImmediateOperand(0));
2371 bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex);
2372 JSTypeHintLowering::LoweringResult lowering =
2373 TryBuildSimplifiedBinaryOp(op, left, right, slot);
2374 if (lowering.IsExit())
return;
2376 Node* node =
nullptr;
2377 if (lowering.IsSideEffectFree()) {
2378 node = lowering.value();
2380 DCHECK(!lowering.Changed());
2381 node = NewNode(op, left, right);
2383 environment()->BindAccumulator(node, Environment::kAttachFrameState);
2386 void BytecodeGraphBuilder::VisitAddSmi() {
2387 BuildBinaryOpWithImmediate(
2388 javascript()->Add(GetBinaryOperationHint(kBinaryOperationSmiHintIndex)));
2391 void BytecodeGraphBuilder::VisitSubSmi() {
2392 BuildBinaryOpWithImmediate(javascript()->Subtract());
2395 void BytecodeGraphBuilder::VisitMulSmi() {
2396 BuildBinaryOpWithImmediate(javascript()->Multiply());
2399 void BytecodeGraphBuilder::VisitDivSmi() {
2400 BuildBinaryOpWithImmediate(javascript()->Divide());
2403 void BytecodeGraphBuilder::VisitModSmi() {
2404 BuildBinaryOpWithImmediate(javascript()->Modulus());
2407 void BytecodeGraphBuilder::VisitExpSmi() {
2408 BuildBinaryOpWithImmediate(javascript()->Exponentiate());
2411 void BytecodeGraphBuilder::VisitBitwiseOrSmi() {
2412 BuildBinaryOpWithImmediate(javascript()->BitwiseOr());
2415 void BytecodeGraphBuilder::VisitBitwiseXorSmi() {
2416 BuildBinaryOpWithImmediate(javascript()->BitwiseXor());
2419 void BytecodeGraphBuilder::VisitBitwiseAndSmi() {
2420 BuildBinaryOpWithImmediate(javascript()->BitwiseAnd());
2423 void BytecodeGraphBuilder::VisitShiftLeftSmi() {
2424 BuildBinaryOpWithImmediate(javascript()->ShiftLeft());
2427 void BytecodeGraphBuilder::VisitShiftRightSmi() {
2428 BuildBinaryOpWithImmediate(javascript()->ShiftRight());
2431 void BytecodeGraphBuilder::VisitShiftRightLogicalSmi() {
2432 BuildBinaryOpWithImmediate(javascript()->ShiftRightLogical());
2435 void BytecodeGraphBuilder::VisitLogicalNot() {
2436 Node* value = environment()->LookupAccumulator();
2437 Node* node = NewNode(simplified()->BooleanNot(), value);
2438 environment()->BindAccumulator(node);
2441 void BytecodeGraphBuilder::VisitToBooleanLogicalNot() {
2443 NewNode(simplified()->ToBoolean(), environment()->LookupAccumulator());
2444 Node* node = NewNode(simplified()->BooleanNot(), value);
2445 environment()->BindAccumulator(node);
2448 void BytecodeGraphBuilder::VisitTypeOf() {
2450 NewNode(simplified()->TypeOf(), environment()->LookupAccumulator());
2451 environment()->BindAccumulator(node);
2454 void BytecodeGraphBuilder::BuildDelete(LanguageMode language_mode) {
2455 PrepareEagerCheckpoint();
2456 Node* key = environment()->LookupAccumulator();
2458 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2459 Node* mode = jsgraph()->Constant(static_cast<int32_t>(language_mode));
2460 Node* node = NewNode(javascript()->DeleteProperty(),
object, key, mode);
2461 environment()->BindAccumulator(node, Environment::kAttachFrameState);
2464 void BytecodeGraphBuilder::VisitDeletePropertyStrict() {
2465 BuildDelete(LanguageMode::kStrict);
2468 void BytecodeGraphBuilder::VisitDeletePropertySloppy() {
2469 BuildDelete(LanguageMode::kSloppy);
2472 void BytecodeGraphBuilder::VisitGetSuperConstructor() {
2473 Node* node = NewNode(javascript()->GetSuperConstructor(),
2474 environment()->LookupAccumulator());
2475 environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0), node,
2476 Environment::kAttachFrameState);
2479 void BytecodeGraphBuilder::BuildCompareOp(
const Operator* op) {
2480 PrepareEagerCheckpoint();
2482 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2483 Node* right = environment()->LookupAccumulator();
2485 FeedbackSlot slot = bytecode_iterator().GetSlotOperand(1);
2486 JSTypeHintLowering::LoweringResult lowering =
2487 TryBuildSimplifiedBinaryOp(op, left, right, slot);
2488 if (lowering.IsExit())
return;
2490 Node* node =
nullptr;
2491 if (lowering.IsSideEffectFree()) {
2492 node = lowering.value();
2494 DCHECK(!lowering.Changed());
2495 node = NewNode(op, left, right);
2497 environment()->BindAccumulator(node, Environment::kAttachFrameState);
2500 void BytecodeGraphBuilder::VisitTestEqual() {
2501 BuildCompareOp(javascript()->Equal(GetCompareOperationHint()));
2504 void BytecodeGraphBuilder::VisitTestEqualStrict() {
2505 BuildCompareOp(javascript()->StrictEqual(GetCompareOperationHint()));
2508 void BytecodeGraphBuilder::VisitTestLessThan() {
2509 BuildCompareOp(javascript()->LessThan(GetCompareOperationHint()));
2512 void BytecodeGraphBuilder::VisitTestGreaterThan() {
2513 BuildCompareOp(javascript()->GreaterThan(GetCompareOperationHint()));
2516 void BytecodeGraphBuilder::VisitTestLessThanOrEqual() {
2517 BuildCompareOp(javascript()->LessThanOrEqual(GetCompareOperationHint()));
2520 void BytecodeGraphBuilder::VisitTestGreaterThanOrEqual() {
2521 BuildCompareOp(javascript()->GreaterThanOrEqual(GetCompareOperationHint()));
2524 void BytecodeGraphBuilder::VisitTestReferenceEqual() {
2526 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2527 Node* right = environment()->LookupAccumulator();
2528 Node* result = NewNode(simplified()->ReferenceEqual(), left, right);
2529 environment()->BindAccumulator(result);
2532 void BytecodeGraphBuilder::VisitTestIn() {
2533 PrepareEagerCheckpoint();
2534 Node*
object = environment()->LookupAccumulator();
2536 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2537 Node* node = NewNode(javascript()->HasProperty(),
object, key);
2538 environment()->BindAccumulator(node, Environment::kAttachFrameState);
2541 void BytecodeGraphBuilder::VisitTestInstanceOf() {
2542 int const slot_index = bytecode_iterator().GetIndexOperand(1);
2543 BuildCompareOp(javascript()->InstanceOf(CreateVectorSlotPair(slot_index)));
2546 void BytecodeGraphBuilder::VisitTestUndetectable() {
2547 Node*
object = environment()->LookupAccumulator();
2548 Node* node = NewNode(jsgraph()->simplified()->ObjectIsUndetectable(),
object);
2549 environment()->BindAccumulator(node);
2552 void BytecodeGraphBuilder::VisitTestNull() {
2553 Node*
object = environment()->LookupAccumulator();
2554 Node* result = NewNode(simplified()->ReferenceEqual(),
object,
2555 jsgraph()->NullConstant());
2556 environment()->BindAccumulator(result);
2559 void BytecodeGraphBuilder::VisitTestUndefined() {
2560 Node*
object = environment()->LookupAccumulator();
2561 Node* result = NewNode(simplified()->ReferenceEqual(),
object,
2562 jsgraph()->UndefinedConstant());
2563 environment()->BindAccumulator(result);
2566 void BytecodeGraphBuilder::VisitTestTypeOf() {
2567 Node*
object = environment()->LookupAccumulator();
2568 auto literal_flag = interpreter::TestTypeOfFlags::Decode(
2569 bytecode_iterator().GetFlagOperand(0));
2571 switch (literal_flag) {
2572 case interpreter::TestTypeOfFlags::LiteralFlag::kNumber:
2573 result = NewNode(simplified()->ObjectIsNumber(),
object);
2575 case interpreter::TestTypeOfFlags::LiteralFlag::kString:
2576 result = NewNode(simplified()->ObjectIsString(),
object);
2578 case interpreter::TestTypeOfFlags::LiteralFlag::kSymbol:
2579 result = NewNode(simplified()->ObjectIsSymbol(),
object);
2581 case interpreter::TestTypeOfFlags::LiteralFlag::kBigInt:
2582 result = NewNode(simplified()->ObjectIsBigInt(),
object);
2584 case interpreter::TestTypeOfFlags::LiteralFlag::kBoolean:
2585 result = NewNode(common()->Select(MachineRepresentation::kTagged),
2586 NewNode(simplified()->ReferenceEqual(),
object,
2587 jsgraph()->TrueConstant()),
2588 jsgraph()->TrueConstant(),
2589 NewNode(simplified()->ReferenceEqual(),
object,
2590 jsgraph()->FalseConstant()));
2592 case interpreter::TestTypeOfFlags::LiteralFlag::kUndefined:
2593 result = graph()->NewNode(
2594 common()->Select(MachineRepresentation::kTagged),
2595 graph()->NewNode(simplified()->ReferenceEqual(),
object,
2596 jsgraph()->NullConstant()),
2597 jsgraph()->FalseConstant(),
2598 graph()->NewNode(simplified()->ObjectIsUndetectable(),
object));
2600 case interpreter::TestTypeOfFlags::LiteralFlag::kFunction:
2602 graph()->NewNode(simplified()->ObjectIsDetectableCallable(),
object);
2604 case interpreter::TestTypeOfFlags::LiteralFlag::kObject:
2605 result = graph()->NewNode(
2606 common()->Select(MachineRepresentation::kTagged),
2607 graph()->NewNode(simplified()->ObjectIsNonCallable(),
object),
2608 jsgraph()->TrueConstant(),
2609 graph()->NewNode(simplified()->ReferenceEqual(),
object,
2610 jsgraph()->NullConstant()));
2612 case interpreter::TestTypeOfFlags::LiteralFlag::kOther:
2616 environment()->BindAccumulator(result);
2619 void BytecodeGraphBuilder::BuildCastOperator(
const Operator* js_op) {
2620 Node* value = NewNode(js_op, environment()->LookupAccumulator());
2621 environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0), value,
2622 Environment::kAttachFrameState);
2625 void BytecodeGraphBuilder::VisitToName() {
2626 BuildCastOperator(javascript()->ToName());
2629 void BytecodeGraphBuilder::VisitToObject() {
2630 BuildCastOperator(javascript()->ToObject());
2633 void BytecodeGraphBuilder::VisitToString() {
2635 NewNode(javascript()->ToString(), environment()->LookupAccumulator());
2636 environment()->BindAccumulator(value, Environment::kAttachFrameState);
2639 void BytecodeGraphBuilder::VisitToNumber() {
2640 PrepareEagerCheckpoint();
2641 Node*
object = environment()->LookupAccumulator();
2643 FeedbackSlot slot = bytecode_iterator().GetSlotOperand(0);
2644 JSTypeHintLowering::LoweringResult lowering =
2645 TryBuildSimplifiedToNumber(
object, slot);
2647 Node* node =
nullptr;
2648 if (lowering.IsSideEffectFree()) {
2649 node = lowering.value();
2651 DCHECK(!lowering.Changed());
2652 node = NewNode(javascript()->ToNumber(),
object);
2655 environment()->BindAccumulator(node, Environment::kAttachFrameState);
2658 void BytecodeGraphBuilder::VisitToNumeric() {
2659 PrepareEagerCheckpoint();
2660 Node*
object = environment()->LookupAccumulator();
2664 FeedbackSlot slot = bytecode_iterator().GetSlotOperand(0);
2665 JSTypeHintLowering::LoweringResult lowering =
2666 TryBuildSimplifiedToNumber(
object, slot);
2668 Node* node =
nullptr;
2669 if (lowering.IsSideEffectFree()) {
2670 node = lowering.value();
2672 DCHECK(!lowering.Changed());
2673 node = NewNode(javascript()->ToNumeric(),
object);
2676 environment()->BindAccumulator(node, Environment::kAttachFrameState);
2679 void BytecodeGraphBuilder::VisitJump() { BuildJump(); }
2681 void BytecodeGraphBuilder::VisitJumpConstant() { BuildJump(); }
2683 void BytecodeGraphBuilder::VisitJumpIfTrue() { BuildJumpIfTrue(); }
2685 void BytecodeGraphBuilder::VisitJumpIfTrueConstant() { BuildJumpIfTrue(); }
2687 void BytecodeGraphBuilder::VisitJumpIfFalse() { BuildJumpIfFalse(); }
2689 void BytecodeGraphBuilder::VisitJumpIfFalseConstant() { BuildJumpIfFalse(); }
2691 void BytecodeGraphBuilder::VisitJumpIfToBooleanTrue() {
2692 BuildJumpIfToBooleanTrue();
2695 void BytecodeGraphBuilder::VisitJumpIfToBooleanTrueConstant() {
2696 BuildJumpIfToBooleanTrue();
2699 void BytecodeGraphBuilder::VisitJumpIfToBooleanFalse() {
2700 BuildJumpIfToBooleanFalse();
2703 void BytecodeGraphBuilder::VisitJumpIfToBooleanFalseConstant() {
2704 BuildJumpIfToBooleanFalse();
2707 void BytecodeGraphBuilder::VisitJumpIfJSReceiver() { BuildJumpIfJSReceiver(); }
2709 void BytecodeGraphBuilder::VisitJumpIfJSReceiverConstant() {
2710 BuildJumpIfJSReceiver();
2713 void BytecodeGraphBuilder::VisitJumpIfNull() {
2714 BuildJumpIfEqual(jsgraph()->NullConstant());
2717 void BytecodeGraphBuilder::VisitJumpIfNullConstant() {
2718 BuildJumpIfEqual(jsgraph()->NullConstant());
2721 void BytecodeGraphBuilder::VisitJumpIfNotNull() {
2722 BuildJumpIfNotEqual(jsgraph()->NullConstant());
2725 void BytecodeGraphBuilder::VisitJumpIfNotNullConstant() {
2726 BuildJumpIfNotEqual(jsgraph()->NullConstant());
2729 void BytecodeGraphBuilder::VisitJumpIfUndefined() {
2730 BuildJumpIfEqual(jsgraph()->UndefinedConstant());
2733 void BytecodeGraphBuilder::VisitJumpIfUndefinedConstant() {
2734 BuildJumpIfEqual(jsgraph()->UndefinedConstant());
2737 void BytecodeGraphBuilder::VisitJumpIfNotUndefined() {
2738 BuildJumpIfNotEqual(jsgraph()->UndefinedConstant());
2741 void BytecodeGraphBuilder::VisitJumpIfNotUndefinedConstant() {
2742 BuildJumpIfNotEqual(jsgraph()->UndefinedConstant());
2745 void BytecodeGraphBuilder::VisitJumpLoop() { BuildJump(); }
2747 void BytecodeGraphBuilder::BuildSwitchOnSmi(Node* condition) {
2748 interpreter::JumpTableTargetOffsets offsets =
2749 bytecode_iterator().GetJumpTableTargetOffsets();
2751 NewSwitch(condition, offsets.size() + 1);
2752 for (
const auto& entry : offsets) {
2753 SubEnvironment sub_environment(
this);
2754 NewIfValue(entry.case_value);
2755 MergeIntoSuccessorEnvironment(entry.target_offset);
2760 void BytecodeGraphBuilder::VisitSwitchOnSmiNoFeedback() {
2761 PrepareEagerCheckpoint();
2763 Node* acc = environment()->LookupAccumulator();
2764 Node* acc_smi = NewNode(simplified()->CheckSmi(VectorSlotPair()), acc);
2765 BuildSwitchOnSmi(acc_smi);
2768 void BytecodeGraphBuilder::VisitStackCheck() {
2769 PrepareEagerCheckpoint();
2770 Node* node = NewNode(javascript()->StackCheck());
2771 environment()->RecordAfterState(node, Environment::kAttachFrameState);
2774 void BytecodeGraphBuilder::VisitSetPendingMessage() {
2775 Node* previous_message = NewNode(javascript()->LoadMessage());
2776 NewNode(javascript()->StoreMessage(), environment()->LookupAccumulator());
2777 environment()->BindAccumulator(previous_message);
2780 void BytecodeGraphBuilder::BuildReturn(
const BytecodeLivenessState* liveness) {
2781 BuildLoopExitsForFunctionExit(liveness);
2782 Node* pop_node = jsgraph()->ZeroConstant();
2784 NewNode(common()->Return(), pop_node, environment()->LookupAccumulator());
2785 MergeControlToLeaveFunction(control);
2788 void BytecodeGraphBuilder::VisitReturn() {
2789 BuildReturn(bytecode_analysis()->GetInLivenessFor(
2790 bytecode_iterator().current_offset()));
2793 void BytecodeGraphBuilder::VisitDebugger() {
2794 PrepareEagerCheckpoint();
2795 Node* call = NewNode(javascript()->Debugger());
2796 environment()->RecordAfterState(call, Environment::kAttachFrameState);
2800 #define DEBUG_BREAK(Name, ...) \ 2801 void BytecodeGraphBuilder::Visit##Name() { UNREACHABLE(); } 2802 DEBUG_BREAK_BYTECODE_LIST(DEBUG_BREAK);
2805 void BytecodeGraphBuilder::VisitIncBlockCounter() {
2806 Node* closure = GetFunctionClosure();
2807 Node* coverage_array_slot =
2808 jsgraph()->Constant(bytecode_iterator().GetIndexOperand(0));
2810 const Operator* op = javascript()->CallRuntime(Runtime::kIncBlockCounter);
2812 NewNode(op, closure, coverage_array_slot);
2815 void BytecodeGraphBuilder::VisitForInEnumerate() {
2817 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2818 Node* enumerator = NewNode(javascript()->ForInEnumerate(), receiver);
2819 environment()->BindAccumulator(enumerator, Environment::kAttachFrameState);
2822 void BytecodeGraphBuilder::VisitForInPrepare() {
2823 PrepareEagerCheckpoint();
2824 Node* enumerator = environment()->LookupAccumulator();
2826 FeedbackSlot slot = bytecode_iterator().GetSlotOperand(1);
2827 JSTypeHintLowering::LoweringResult lowering =
2828 TryBuildSimplifiedForInPrepare(enumerator, slot);
2829 if (lowering.IsExit())
return;
2830 DCHECK(!lowering.Changed());
2831 Node* node = NewNode(javascript()->ForInPrepare(GetForInMode(1)), enumerator);
2832 environment()->BindRegistersToProjections(
2833 bytecode_iterator().GetRegisterOperand(0), node);
2836 void BytecodeGraphBuilder::VisitForInContinue() {
2837 PrepareEagerCheckpoint();
2839 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2840 Node* cache_length =
2841 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
2842 Node* exit_cond = NewNode(simplified()->SpeculativeNumberLessThan(
2843 NumberOperationHint::kSignedSmall),
2844 index, cache_length);
2845 environment()->BindAccumulator(exit_cond);
2848 void BytecodeGraphBuilder::VisitForInNext() {
2849 PrepareEagerCheckpoint();
2851 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2853 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
2854 int catch_reg_pair_index = bytecode_iterator().GetRegisterOperand(2).index();
2855 Node* cache_type = environment()->LookupRegister(
2856 interpreter::Register(catch_reg_pair_index));
2857 Node* cache_array = environment()->LookupRegister(
2858 interpreter::Register(catch_reg_pair_index + 1));
2862 index = graph()->NewNode(common()->TypeGuard(Type::UnsignedSmall()), index,
2863 environment()->GetEffectDependency(),
2864 environment()->GetControlDependency());
2865 environment()->UpdateEffectDependency(index);
2867 FeedbackSlot slot = bytecode_iterator().GetSlotOperand(3);
2868 JSTypeHintLowering::LoweringResult lowering = TryBuildSimplifiedForInNext(
2869 receiver, cache_array, cache_type, index, slot);
2870 if (lowering.IsExit())
return;
2872 DCHECK(!lowering.Changed());
2873 Node* node = NewNode(javascript()->ForInNext(GetForInMode(3)), receiver,
2874 cache_array, cache_type, index);
2875 environment()->BindAccumulator(node, Environment::kAttachFrameState);
2878 void BytecodeGraphBuilder::VisitForInStep() {
2879 PrepareEagerCheckpoint();
2881 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2882 index = NewNode(simplified()->SpeculativeSafeIntegerAdd(
2883 NumberOperationHint::kSignedSmall),
2884 index, jsgraph()->OneConstant());
2885 environment()->BindAccumulator(index, Environment::kAttachFrameState);
2888 void BytecodeGraphBuilder::VisitSuspendGenerator() {
2889 Node* generator = environment()->LookupRegister(
2890 bytecode_iterator().GetRegisterOperand(0));
2891 interpreter::Register first_reg = bytecode_iterator().GetRegisterOperand(1);
2893 CHECK_EQ(0, first_reg.index());
2894 int register_count =
2895 static_cast<int>(bytecode_iterator().GetRegisterCountOperand(2));
2896 int parameter_count_without_receiver =
2897 bytecode_array()->parameter_count() - 1;
2899 Node* suspend_id = jsgraph()->SmiConstant(
2900 bytecode_iterator().GetUnsignedImmediateOperand(3));
2905 jsgraph()->Constant(bytecode_iterator().current_offset() +
2906 (BytecodeArray::kHeaderSize - kHeapObjectTag));
2908 const BytecodeLivenessState* liveness = bytecode_analysis()->GetInLivenessFor(
2909 bytecode_iterator().current_offset());
2915 int value_input_count = 3 + parameter_count_without_receiver + register_count;
2917 Node** value_inputs = local_zone()->NewArray<Node*>(value_input_count);
2918 value_inputs[0] = generator;
2919 value_inputs[1] = suspend_id;
2920 value_inputs[2] = offset;
2922 int count_written = 0;
2924 for (
int i = 0;
i < parameter_count_without_receiver;
i++) {
2925 value_inputs[3 + count_written++] =
2926 environment()->LookupRegister(interpreter::Register::FromParameterIndex(
2927 i, parameter_count_without_receiver));
2931 for (
int i = 0;
i < register_count; ++
i) {
2932 if (liveness ==
nullptr || liveness->RegisterIsLive(
i)) {
2933 int index_in_parameters_and_registers =
2934 parameter_count_without_receiver +
i;
2935 while (count_written < index_in_parameters_and_registers) {
2936 value_inputs[3 + count_written++] = jsgraph()->OptimizedOutConstant();
2938 value_inputs[3 + count_written++] =
2939 environment()->LookupRegister(interpreter::Register(
i));
2940 DCHECK_EQ(count_written, index_in_parameters_and_registers + 1);
2946 MakeNode(javascript()->GeneratorStore(count_written), 3 + count_written,
2947 value_inputs,
false);
2951 BuildReturn(bytecode_analysis()->GetInLivenessFor(
2952 bytecode_iterator().current_offset()));
2955 void BytecodeGraphBuilder::BuildSwitchOnGeneratorState(
2956 const ZoneVector<ResumeJumpTarget>& resume_jump_targets,
2957 bool allow_fallthrough_on_executing) {
2958 Node* generator_state = environment()->LookupGeneratorState();
2960 int extra_cases = allow_fallthrough_on_executing ? 2 : 1;
2961 NewSwitch(generator_state,
2962 static_cast<int>(resume_jump_targets.size() + extra_cases));
2963 for (
const ResumeJumpTarget& target : resume_jump_targets) {
2964 SubEnvironment sub_environment(
this);
2965 NewIfValue(target.suspend_id());
2966 if (target.is_leaf()) {
2968 environment()->BindGeneratorState(
2969 jsgraph()->SmiConstant(JSGeneratorObject::kGeneratorExecuting));
2972 MergeIntoSuccessorEnvironment(target.target_offset());
2976 SubEnvironment sub_environment(
this);
2982 NewNode(simplified()->RuntimeAbort(AbortReason::kInvalidJumpTableIndex));
2984 Node* control = NewNode(common()->Throw());
2985 MergeControlToLeaveFunction(control);
2988 if (allow_fallthrough_on_executing) {
2991 NewIfValue(JSGeneratorObject::kGeneratorExecuting);
2994 set_environment(
nullptr);
2998 void BytecodeGraphBuilder::VisitSwitchOnGeneratorState() {
3000 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
3002 Node* generator_is_undefined =
3003 NewNode(simplified()->ReferenceEqual(), generator,
3004 jsgraph()->UndefinedConstant());
3006 NewBranch(generator_is_undefined);
3008 SubEnvironment resume_env(
this);
3011 Node* generator_state =
3012 NewNode(javascript()->GeneratorRestoreContinuation(), generator);
3013 environment()->BindGeneratorState(generator_state);
3015 Node* generator_context =
3016 NewNode(javascript()->GeneratorRestoreContext(), generator);
3017 environment()->SetContext(generator_context);
3019 BuildSwitchOnGeneratorState(bytecode_analysis()->resume_jump_targets(),
3027 void BytecodeGraphBuilder::VisitResumeGenerator() {
3029 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
3030 interpreter::Register first_reg = bytecode_iterator().GetRegisterOperand(1);
3032 CHECK_EQ(0, first_reg.index());
3034 const BytecodeLivenessState* liveness =
3035 bytecode_analysis()->GetOutLivenessFor(
3036 bytecode_iterator().current_offset());
3038 int parameter_count_without_receiver =
3039 bytecode_array()->parameter_count() - 1;
3043 for (
int i = 0;
i < environment()->register_count(); ++
i) {
3044 if (liveness ==
nullptr || liveness->RegisterIsLive(
i)) {
3045 Node* value = NewNode(javascript()->GeneratorRestoreRegister(
3046 parameter_count_without_receiver +
i),
3048 environment()->BindRegister(interpreter::Register(
i), value);
3053 Node* input_or_debug_pos =
3054 NewNode(javascript()->GeneratorRestoreInputOrDebugPos(), generator);
3055 environment()->BindAccumulator(input_or_debug_pos);
3058 void BytecodeGraphBuilder::VisitWide() {
3063 void BytecodeGraphBuilder::VisitExtraWide() {
3068 void BytecodeGraphBuilder::VisitIllegal() {
3073 void BytecodeGraphBuilder::SwitchToMergeEnvironment(
int current_offset) {
3074 auto it = merge_environments_.find(current_offset);
3075 if (it != merge_environments_.end()) {
3076 mark_as_needing_eager_checkpoint(
true);
3077 if (environment() !=
nullptr) {
3078 it->second->Merge(environment(),
3079 bytecode_analysis()->GetInLivenessFor(current_offset));
3081 set_environment(it->second);
3085 void BytecodeGraphBuilder::BuildLoopHeaderEnvironment(
int current_offset) {
3086 if (bytecode_analysis()->IsLoopHeader(current_offset)) {
3087 mark_as_needing_eager_checkpoint(
true);
3088 const LoopInfo& loop_info =
3089 bytecode_analysis()->GetLoopInfoFor(current_offset);
3090 const BytecodeLivenessState* liveness =
3091 bytecode_analysis()->GetInLivenessFor(current_offset);
3093 const auto& resume_jump_targets = loop_info.resume_jump_targets();
3094 bool generate_suspend_switch = !resume_jump_targets.empty();
3097 environment()->PrepareForLoop(loop_info.assignments(), liveness);
3101 merge_environments_[current_offset] = environment()->Copy();
3105 if (generate_suspend_switch) {
3106 BuildSwitchOnGeneratorState(loop_info.resume_jump_targets(),
true);
3113 environment()->BindGeneratorState(
3114 jsgraph()->SmiConstant(JSGeneratorObject::kGeneratorExecuting));
3119 void BytecodeGraphBuilder::MergeIntoSuccessorEnvironment(
int target_offset) {
3120 BuildLoopExitsForBranch(target_offset);
3121 Environment*& merge_environment = merge_environments_[target_offset];
3123 if (merge_environment ==
nullptr) {
3129 merge_environment = environment();
3132 merge_environment->Merge(
3133 environment(), bytecode_analysis()->GetInLivenessFor(target_offset));
3135 set_environment(
nullptr);
3138 void BytecodeGraphBuilder::MergeControlToLeaveFunction(Node* exit) {
3139 exit_controls_.push_back(exit);
3140 set_environment(
nullptr);
3143 void BytecodeGraphBuilder::BuildLoopExitsForBranch(
int target_offset) {
3144 int origin_offset = bytecode_iterator().current_offset();
3146 if (target_offset > origin_offset) {
3147 BuildLoopExitsUntilLoop(
3148 bytecode_analysis()->GetLoopOffsetFor(target_offset),
3149 bytecode_analysis()->GetInLivenessFor(target_offset));
3153 void BytecodeGraphBuilder::BuildLoopExitsUntilLoop(
3154 int loop_offset,
const BytecodeLivenessState* liveness) {
3155 int origin_offset = bytecode_iterator().current_offset();
3156 int current_loop = bytecode_analysis()->GetLoopOffsetFor(origin_offset);
3159 loop_offset = std::max(loop_offset, currently_peeled_loop_offset_);
3161 while (loop_offset < current_loop) {
3162 Node* loop_node = merge_environments_[current_loop]->GetControlDependency();
3163 const LoopInfo& loop_info =
3164 bytecode_analysis()->GetLoopInfoFor(current_loop);
3165 environment()->PrepareForLoopExit(loop_node, loop_info.assignments(),
3167 current_loop = loop_info.parent_offset();
3171 void BytecodeGraphBuilder::BuildLoopExitsForFunctionExit(
3172 const BytecodeLivenessState* liveness) {
3173 BuildLoopExitsUntilLoop(-1, liveness);
3176 void BytecodeGraphBuilder::BuildJump() {
3177 MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
3180 void BytecodeGraphBuilder::BuildJumpIf(Node* condition) {
3181 NewBranch(condition, BranchHint::kNone, IsSafetyCheck::kNoSafetyCheck);
3183 SubEnvironment sub_environment(
this);
3185 MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
3190 void BytecodeGraphBuilder::BuildJumpIfNot(Node* condition) {
3191 NewBranch(condition, BranchHint::kNone, IsSafetyCheck::kNoSafetyCheck);
3193 SubEnvironment sub_environment(
this);
3195 MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
3200 void BytecodeGraphBuilder::BuildJumpIfEqual(Node* comperand) {
3201 Node* accumulator = environment()->LookupAccumulator();
3203 NewNode(simplified()->ReferenceEqual(), accumulator, comperand);
3204 BuildJumpIf(condition);
3207 void BytecodeGraphBuilder::BuildJumpIfNotEqual(Node* comperand) {
3208 Node* accumulator = environment()->LookupAccumulator();
3210 NewNode(simplified()->ReferenceEqual(), accumulator, comperand);
3211 BuildJumpIfNot(condition);
3214 void BytecodeGraphBuilder::BuildJumpIfFalse() {
3215 NewBranch(environment()->LookupAccumulator(), BranchHint::kNone,
3216 IsSafetyCheck::kNoSafetyCheck);
3218 SubEnvironment sub_environment(
this);
3220 environment()->BindAccumulator(jsgraph()->FalseConstant());
3221 MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
3224 environment()->BindAccumulator(jsgraph()->TrueConstant());
3227 void BytecodeGraphBuilder::BuildJumpIfTrue() {
3228 NewBranch(environment()->LookupAccumulator(), BranchHint::kNone,
3229 IsSafetyCheck::kNoSafetyCheck);
3231 SubEnvironment sub_environment(
this);
3233 environment()->BindAccumulator(jsgraph()->TrueConstant());
3234 MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
3237 environment()->BindAccumulator(jsgraph()->FalseConstant());
3240 void BytecodeGraphBuilder::BuildJumpIfToBooleanTrue() {
3241 Node* accumulator = environment()->LookupAccumulator();
3242 Node* condition = NewNode(simplified()->ToBoolean(), accumulator);
3243 BuildJumpIf(condition);
3246 void BytecodeGraphBuilder::BuildJumpIfToBooleanFalse() {
3247 Node* accumulator = environment()->LookupAccumulator();
3248 Node* condition = NewNode(simplified()->ToBoolean(), accumulator);
3249 BuildJumpIfNot(condition);
3252 void BytecodeGraphBuilder::BuildJumpIfNotHole() {
3253 Node* accumulator = environment()->LookupAccumulator();
3254 Node* condition = NewNode(simplified()->ReferenceEqual(), accumulator,
3255 jsgraph()->TheHoleConstant());
3256 BuildJumpIfNot(condition);
3259 void BytecodeGraphBuilder::BuildJumpIfJSReceiver() {
3260 Node* accumulator = environment()->LookupAccumulator();
3261 Node* condition = NewNode(simplified()->ObjectIsReceiver(), accumulator);
3262 BuildJumpIf(condition);
3265 JSTypeHintLowering::LoweringResult
3266 BytecodeGraphBuilder::TryBuildSimplifiedUnaryOp(
const Operator* op,
3268 FeedbackSlot slot) {
3269 Node* effect = environment()->GetEffectDependency();
3270 Node* control = environment()->GetControlDependency();
3271 JSTypeHintLowering::LoweringResult result =
3272 type_hint_lowering().ReduceUnaryOperation(op, operand, effect, control,
3274 ApplyEarlyReduction(result);
3278 JSTypeHintLowering::LoweringResult
3279 BytecodeGraphBuilder::TryBuildSimplifiedBinaryOp(
const Operator* op, Node* left,
3281 FeedbackSlot slot) {
3282 Node* effect = environment()->GetEffectDependency();
3283 Node* control = environment()->GetControlDependency();
3284 JSTypeHintLowering::LoweringResult result =
3285 type_hint_lowering().ReduceBinaryOperation(op, left, right, effect,
3287 ApplyEarlyReduction(result);
3291 JSTypeHintLowering::LoweringResult
3292 BytecodeGraphBuilder::TryBuildSimplifiedForInNext(Node* receiver,
3294 Node* cache_type, Node* index,
3295 FeedbackSlot slot) {
3296 Node* effect = environment()->GetEffectDependency();
3297 Node* control = environment()->GetControlDependency();
3298 JSTypeHintLowering::LoweringResult result =
3299 type_hint_lowering().ReduceForInNextOperation(
3300 receiver, cache_array, cache_type, index, effect, control, slot);
3301 ApplyEarlyReduction(result);
3305 JSTypeHintLowering::LoweringResult
3306 BytecodeGraphBuilder::TryBuildSimplifiedForInPrepare(Node* enumerator,
3307 FeedbackSlot slot) {
3308 Node* effect = environment()->GetEffectDependency();
3309 Node* control = environment()->GetControlDependency();
3310 JSTypeHintLowering::LoweringResult result =
3311 type_hint_lowering().ReduceForInPrepareOperation(enumerator, effect,
3313 ApplyEarlyReduction(result);
3317 JSTypeHintLowering::LoweringResult
3318 BytecodeGraphBuilder::TryBuildSimplifiedToNumber(Node* value,
3319 FeedbackSlot slot) {
3320 Node* effect = environment()->GetEffectDependency();
3321 Node* control = environment()->GetControlDependency();
3322 JSTypeHintLowering::LoweringResult result =
3323 type_hint_lowering().ReduceToNumberOperation(value, effect, control,
3325 ApplyEarlyReduction(result);
3329 JSTypeHintLowering::LoweringResult BytecodeGraphBuilder::TryBuildSimplifiedCall(
3330 const Operator* op, Node*
const* args,
int arg_count, FeedbackSlot slot) {
3331 Node* effect = environment()->GetEffectDependency();
3332 Node* control = environment()->GetControlDependency();
3333 JSTypeHintLowering::LoweringResult result =
3334 type_hint_lowering().ReduceCallOperation(op, args, arg_count, effect,
3336 ApplyEarlyReduction(result);
3340 JSTypeHintLowering::LoweringResult
3341 BytecodeGraphBuilder::TryBuildSimplifiedConstruct(
const Operator* op,
3344 FeedbackSlot slot) {
3345 Node* effect = environment()->GetEffectDependency();
3346 Node* control = environment()->GetControlDependency();
3347 JSTypeHintLowering::LoweringResult result =
3348 type_hint_lowering().ReduceConstructOperation(op, args, arg_count, effect,
3350 ApplyEarlyReduction(result);
3354 JSTypeHintLowering::LoweringResult
3355 BytecodeGraphBuilder::TryBuildSimplifiedLoadNamed(
const Operator* op,
3357 FeedbackSlot slot) {
3358 Node* effect = environment()->GetEffectDependency();
3359 Node* control = environment()->GetControlDependency();
3360 JSTypeHintLowering::LoweringResult early_reduction =
3361 type_hint_lowering().ReduceLoadNamedOperation(op, receiver, effect,
3363 ApplyEarlyReduction(early_reduction);
3364 return early_reduction;
3367 JSTypeHintLowering::LoweringResult
3368 BytecodeGraphBuilder::TryBuildSimplifiedLoadKeyed(
const Operator* op,
3369 Node* receiver, Node* key,
3370 FeedbackSlot slot) {
3371 Node* effect = environment()->GetEffectDependency();
3372 Node* control = environment()->GetControlDependency();
3373 JSTypeHintLowering::LoweringResult result =
3374 type_hint_lowering().ReduceLoadKeyedOperation(op, receiver, key, effect,
3376 ApplyEarlyReduction(result);
3380 JSTypeHintLowering::LoweringResult
3381 BytecodeGraphBuilder::TryBuildSimplifiedStoreNamed(
const Operator* op,
3382 Node* receiver, Node* value,
3383 FeedbackSlot slot) {
3384 Node* effect = environment()->GetEffectDependency();
3385 Node* control = environment()->GetControlDependency();
3386 JSTypeHintLowering::LoweringResult result =
3387 type_hint_lowering().ReduceStoreNamedOperation(op, receiver, value,
3388 effect, control, slot);
3389 ApplyEarlyReduction(result);
3393 JSTypeHintLowering::LoweringResult
3394 BytecodeGraphBuilder::TryBuildSimplifiedStoreKeyed(
const Operator* op,
3395 Node* receiver, Node* key,
3397 FeedbackSlot slot) {
3398 Node* effect = environment()->GetEffectDependency();
3399 Node* control = environment()->GetControlDependency();
3400 JSTypeHintLowering::LoweringResult result =
3401 type_hint_lowering().ReduceStoreKeyedOperation(op, receiver, key, value,
3402 effect, control, slot);
3403 ApplyEarlyReduction(result);
3407 void BytecodeGraphBuilder::ApplyEarlyReduction(
3408 JSTypeHintLowering::LoweringResult reduction) {
3409 if (reduction.IsExit()) {
3410 MergeControlToLeaveFunction(reduction.control());
3411 }
else if (reduction.IsSideEffectFree()) {
3412 environment()->UpdateEffectDependency(reduction.effect());
3413 environment()->UpdateControlDependency(reduction.control());
3415 DCHECK(!reduction.Changed());
3422 Node** BytecodeGraphBuilder::EnsureInputBufferSize(
int size) {
3423 if (size > input_buffer_size_) {
3424 size = size + kInputBufferSizeIncrement + input_buffer_size_;
3425 input_buffer_ = local_zone()->NewArray<Node*>(size);
3426 input_buffer_size_ = size;
3428 return input_buffer_;
3431 void BytecodeGraphBuilder::ExitThenEnterExceptionHandlers(
int current_offset) {
3432 HandlerTable table(*bytecode_array());
3435 while (!exception_handlers_.empty()) {
3436 int current_end = exception_handlers_.top().end_offset_;
3437 if (current_offset < current_end)
break;
3438 exception_handlers_.pop();
3442 int num_entries = table.NumberOfRangeEntries();
3443 while (current_exception_handler_ < num_entries) {
3444 int next_start = table.GetRangeStart(current_exception_handler_);
3445 if (current_offset < next_start)
break;
3446 int next_end = table.GetRangeEnd(current_exception_handler_);
3447 int next_handler = table.GetRangeHandler(current_exception_handler_);
3448 int context_register = table.GetRangeData(current_exception_handler_);
3449 exception_handlers_.push(
3450 {next_start, next_end, next_handler, context_register});
3451 current_exception_handler_++;
3455 Node* BytecodeGraphBuilder::MakeNode(
const Operator* op,
int value_input_count,
3456 Node*
const* value_inputs,
3458 DCHECK_EQ(op->ValueInputCount(), value_input_count);
3460 bool has_context = OperatorProperties::HasContextInput(op);
3461 bool has_frame_state = OperatorProperties::HasFrameStateInput(op);
3462 bool has_control = op->ControlInputCount() == 1;
3463 bool has_effect = op->EffectInputCount() == 1;
3465 DCHECK_LT(op->ControlInputCount(), 2);
3466 DCHECK_LT(op->EffectInputCount(), 2);
3468 Node* result =
nullptr;
3469 if (!has_context && !has_frame_state && !has_control && !has_effect) {
3470 result = graph()->NewNode(op, value_input_count, value_inputs, incomplete);
3472 bool inside_handler = !exception_handlers_.empty();
3473 int input_count_with_deps = value_input_count;
3474 if (has_context) ++input_count_with_deps;
3475 if (has_frame_state) ++input_count_with_deps;
3476 if (has_control) ++input_count_with_deps;
3477 if (has_effect) ++input_count_with_deps;
3478 Node** buffer = EnsureInputBufferSize(input_count_with_deps);
3479 memcpy(buffer, value_inputs, kPointerSize * value_input_count);
3480 Node** current_input = buffer + value_input_count;
3482 *current_input++ = OperatorProperties::NeedsExactContext(op)
3483 ? environment()->Context()
3484 : jsgraph()->HeapConstant(native_context());
3486 if (has_frame_state) {
3490 *current_input++ = jsgraph()->Dead();
3493 *current_input++ = environment()->GetEffectDependency();
3496 *current_input++ = environment()->GetControlDependency();
3498 result = graph()->NewNode(op, input_count_with_deps, buffer, incomplete);
3500 if (result->op()->ControlOutputCount() > 0) {
3501 environment()->UpdateControlDependency(result);
3504 if (result->op()->EffectOutputCount() > 0) {
3505 environment()->UpdateEffectDependency(result);
3508 if (!result->op()->HasProperty(Operator::kNoThrow) && inside_handler) {
3509 int handler_offset = exception_handlers_.top().handler_offset_;
3510 int context_index = exception_handlers_.top().context_register_;
3511 interpreter::Register context_register(context_index);
3512 Environment* success_env = environment()->Copy();
3513 const Operator* op = common()->IfException();
3514 Node* effect = environment()->GetEffectDependency();
3515 Node* on_exception = graph()->NewNode(op, effect, result);
3516 Node* context = environment()->LookupRegister(context_register);
3517 environment()->UpdateControlDependency(on_exception);
3518 environment()->UpdateEffectDependency(on_exception);
3519 environment()->BindAccumulator(on_exception);
3520 environment()->SetContext(context);
3521 MergeIntoSuccessorEnvironment(handler_offset);
3522 set_environment(success_env);
3525 if (!result->op()->HasProperty(Operator::kNoThrow) && inside_handler) {
3526 const Operator* if_success = common()->IfSuccess();
3527 Node* on_success = graph()->NewNode(if_success, result);
3528 environment()->UpdateControlDependency(on_success);
3531 if (has_effect && !result->op()->HasProperty(Operator::kNoWrite)) {
3532 mark_as_needing_eager_checkpoint(
true);
3540 Node* BytecodeGraphBuilder::NewPhi(
int count, Node* input, Node* control) {
3541 const Operator* phi_op = common()->Phi(MachineRepresentation::kTagged, count);
3542 Node** buffer = EnsureInputBufferSize(count + 1);
3543 MemsetPointer(buffer, input, count);
3544 buffer[count] = control;
3545 return graph()->NewNode(phi_op, count + 1, buffer,
true);
3548 Node* BytecodeGraphBuilder::NewEffectPhi(
int count, Node* input,
3550 const Operator* phi_op = common()->EffectPhi(count);
3551 Node** buffer = EnsureInputBufferSize(count + 1);
3552 MemsetPointer(buffer, input, count);
3553 buffer[count] = control;
3554 return graph()->NewNode(phi_op, count + 1, buffer,
true);
3558 Node* BytecodeGraphBuilder::MergeControl(Node* control, Node* other) {
3559 int inputs = control->op()->ControlInputCount() + 1;
3560 if (control->opcode() == IrOpcode::kLoop) {
3562 const Operator* op = common()->Loop(inputs);
3563 control->AppendInput(graph_zone(), other);
3564 NodeProperties::ChangeOp(control, op);
3565 }
else if (control->opcode() == IrOpcode::kMerge) {
3567 const Operator* op = common()->Merge(inputs);
3568 control->AppendInput(graph_zone(), other);
3569 NodeProperties::ChangeOp(control, op);
3572 const Operator* op = common()->Merge(inputs);
3573 Node* merge_inputs[] = {control, other};
3574 control = graph()->NewNode(op, arraysize(merge_inputs), merge_inputs,
true);
3579 Node* BytecodeGraphBuilder::MergeEffect(Node* value, Node* other,
3581 int inputs = control->op()->ControlInputCount();
3582 if (value->opcode() == IrOpcode::kEffectPhi &&
3583 NodeProperties::GetControlInput(value) == control) {
3585 value->InsertInput(graph_zone(), inputs - 1, other);
3586 NodeProperties::ChangeOp(value, common()->EffectPhi(inputs));
3587 }
else if (value != other) {
3589 value = NewEffectPhi(inputs, value, control);
3590 value->ReplaceInput(inputs - 1, other);
3595 Node* BytecodeGraphBuilder::MergeValue(Node* value, Node* other,
3597 int inputs = control->op()->ControlInputCount();
3598 if (value->opcode() == IrOpcode::kPhi &&
3599 NodeProperties::GetControlInput(value) == control) {
3601 value->InsertInput(graph_zone(), inputs - 1, other);
3602 NodeProperties::ChangeOp(
3603 value, common()->Phi(MachineRepresentation::kTagged, inputs));
3604 }
else if (value != other) {
3606 value = NewPhi(inputs, value, control);
3607 value->ReplaceInput(inputs - 1, other);
3612 void BytecodeGraphBuilder::UpdateSourcePosition(SourcePositionTableIterator* it,
3614 if (it->done())
return;
3615 if (it->code_offset() == offset) {
3616 source_positions_->SetCurrentPosition(SourcePosition(
3617 it->source_position().ScriptOffset(), start_position_.InliningId()));
3620 DCHECK_GT(it->code_offset(), offset);