121 return MakeNode(op, 0,
static_cast<Node**
>(
nullptr), incomplete);
124 template <
class... Args>
126 Node* buffer[] = {n0, nodes...};
156 Node*
const* value_inputs,
bool incomplete =
false);
203 DCHECK(node->opcode() == IrOpcode::kJSStackCheck);
220 DCHECK(node->opcode() == IrOpcode::kJSStackCheck);
244 size_t arg_count,
int slot_id);
246 std::initializer_list<Node*>
args,
int slot_id) {
256 Node* name =
nullptr);
343 bool allow_fallthrough_on_executing);
385 template <
class T = Object>
450#define DECLARE_VISIT_BYTECODE(name, ...) void Visit##name();
452#undef DECLARE_VISIT_BYTECODE
545 Node* control_dependency);
654 Node* control_dependency)
656 register_count_(register_count),
658 control_dependency_(control_dependency),
659 effect_dependency_(control_dependency),
660 values_(builder->local_zone()),
661 parameters_state_values_(nullptr),
662 generator_state_(nullptr) {
673 const char* debug_name = (
i == 0) ?
"%this" :
nullptr;
675 values()->push_back(parameter);
685 values()->push_back(undefined_constant);
692 if (incoming_new_target_or_generator.
is_valid()) {
693 int new_target_index =
695 Node* new_target_node =
699 values()->at(values_index) = new_target_node;
706 register_count_(other->register_count_),
707 parameter_count_(other->parameter_count_),
709 control_dependency_(other->control_dependency_),
710 effect_dependency_(other->effect_dependency_),
711 values_(other->zone()),
712 parameters_state_values_(other->parameters_state_values_),
713 generator_state_(other->generator_state_),
714 register_base_(other->register_base_),
715 accumulator_base_(other->accumulator_base_) {
725 return the_register.
index() + register_base();
730 return values()->at(accumulator_base_);
735 return generator_state_;
743 return builder()->GetFunctionClosure();
745 int values_index = RegisterToValuesIndex(the_register);
746 return values()->at(values_index);
752 if (mode == FrameStateAttachmentMode::kAttachFrameState) {
755 values()->at(accumulator_base_) =
node;
759 generator_state_ =
node;
765 int values_index = RegisterToValuesIndex(the_register);
766 if (mode == FrameStateAttachmentMode::kAttachFrameState) {
768 accumulator_base_ - values_index));
770 values()->at(values_index) =
node;
776 int values_index = RegisterToValuesIndex(first_reg);
777 if (mode == FrameStateAttachmentMode::kAttachFrameState) {
779 accumulator_base_ - values_index));
781 for (
int i = 0;
i < node->op()->ValueOutputCount();
i++) {
782 values()->at(values_index +
i) =
783 builder()->NewNode(
common()->Projection(
i), node);
789 if (mode == FrameStateAttachmentMode::kAttachFrameState) {
803 Node* control = builder()->MergeControl(GetControlDependency(),
804 other->GetControlDependency());
805 UpdateControlDependency(control);
809 Node* effect = builder()->MergeEffect(GetEffectDependency(),
810 other->GetEffectDependency(), control);
811 UpdateEffectDependency(effect);
817 values_[
i] = builder()->MergeValue(values_[
i], other->values_[
i], control);
819 for (
int i = 0;
i < register_count();
i++) {
820 int index = register_base() +
i;
826 if (generator_state_ ==
nullptr ||
831 builder()->
jsgraph()->OptimizedOutConstant());
836 builder()->MergeValue(values_[index], other->values_[index], control);
839 values_[
index] = builder()->jsgraph()->OptimizedOutConstant();
845 builder()->
jsgraph()->OptimizedOutConstant());
846 DCHECK_NE(other->values_[accumulator_base()],
847 builder()->
jsgraph()->OptimizedOutConstant());
849 values_[accumulator_base()] =
850 builder()->MergeValue(values_[accumulator_base()],
851 other->values_[accumulator_base()], control);
853 values_[accumulator_base()] = builder()->jsgraph()->OptimizedOutConstant();
856 if (generator_state_ !=
nullptr) {
858 generator_state_ = builder()->MergeValue(generator_state_,
859 other->generator_state_, control);
867 Node* control = builder()->NewLoop();
870 Node* effect = builder()->NewEffectPhi(1, GetEffectDependency(), control);
871 UpdateEffectDependency(effect);
878 values_[
i] = builder()->NewPhi(1, values_[
i], control);
881 for (
int i = 0;
i < register_count();
i++) {
884 int index = register_base() +
i;
885 values_[
index] = builder()->NewPhi(1, values_[index], control);
891 if (generator_state_ !=
nullptr) {
892 generator_state_ = builder()->NewPhi(1, generator_state_, control);
896 Node* terminate = builder()->graph()->NewNode(
898 builder()->exit_controls_.push_back(terminate);
907 int size =
static_cast<int>(values()->size());
908 for (
int i = 0;
i <
size;
i++) {
910 if (
i >= register_base()) idx += InterpreterFrameConstants::kExtraSlotCount;
918 if (*state_values ==
nullptr) {
924 if (inputs[
i] != values[
i]) {
936 Node* control = GetControlDependency();
940 UpdateControlDependency(loop_exit);
944 GetEffectDependency(), loop_exit);
945 UpdateEffectDependency(effect_rename);
961 for (
int i = 0;
i < register_count();
i++) {
966 values_[register_base() +
i], loop_exit);
967 values_[register_base() +
i] = rename;
973 values_[accumulator_base()], loop_exit);
974 values_[accumulator_base()] = rename;
977 if (generator_state_ !=
nullptr) {
980 generator_state_, loop_exit);
987 if (StateValuesRequireUpdate(state_values, values,
count)) {
995 return builder_->state_values_cache_.GetNodeForValues(
996 values,
static_cast<size_t>(
count), liveness);
1005 parameters_state_values_ =
1006 GetStateValuesFromCache(&values()->at(0),
parameter_count(),
nullptr);
1008 UpdateStateValues(¶meters_state_values_, &values()->at(0),
1012 Node* registers_state_values = GetStateValuesFromCache(
1013 &values()->at(register_base()), register_count(), liveness);
1016 Node* accumulator_state_value =
1018 ? values()->at(accumulator_base())
1019 : builder()->jsgraph()->OptimizedOutConstant();
1024 op, parameters_state_values_, registers_state_values,
1035 : node_origins_(node_origins) {}
1038 node_origins_->SetNodeOrigin(node->id(), NodeOrigin::kJSBytecode,
1039 node_origins_->GetCurrentBytecodePosition());
1057 :
broker_->isolate()->AsLocalIsolate()),
1116 const char* debug_name_hint) {
1119 const size_t index =
1128 NewNode(
common()->Parameter(parameter_index, debug_name_hint),
1223 while (effect->opcode() != IrOpcode::kCheckpoint) {
1225 DCHECK_EQ(1, effect->op()->EffectInputCount());
1234void BytecodeGraphBuilder::PrepareFrameState(
1237 if (OperatorProperties::HasFrameStateInput(node->op())) {
1240 DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
1242 NodeProperties::GetFrameStateInput(node)->opcode());
1244 Node* frame_state_after =
1245 environment()->Checkpoint(bailout_id, combine, liveness);
1246 NodeProperties::ReplaceFrameStateInput(node, frame_state_after);
1250void BytecodeGraphBuilder::AdvanceIteratorsTo(
int bytecode_offset) {
1251 for (; bytecode_iterator().current_offset() != bytecode_offset;
1252 bytecode_iterator().Advance()) {
1253 int current_offset = bytecode_iterator().current_offset();
1254 UpdateSourceAndBytecodePosition(current_offset);
1268 saved_states_(graph_builder->local_zone()) {}
1272 int osr_entry =
graph_builder_->bytecode_analysis().osr_entry_point();
1275 int outermost_loop_offset = osr_entry;
1276 while ((outermost_loop_offset =
graph_builder_->bytecode_analysis()
1277 .GetLoopInfoFor(outermost_loop_offset)
1278 .parent_offset()) != -1) {
1279 outer_loop_offsets.
push_back(outermost_loop_offset);
1281 outermost_loop_offset =
1282 outer_loop_offsets.
empty() ? osr_entry : outer_loop_offsets.
back();
1290 it != outer_loop_offsets.
crend(); ++it) {
1308 .GetLoopInfoFor(osr_entry)
1316 graph_builder_->set_currently_peeled_loop_offset(new_parent_offset);
1322 saved_states_.pop();
1332 source_iterator_state)
1333 : exception_handler_index_(exception_handler_index),
1334 source_iterator_state_(source_iterator_state) {}
1341void BytecodeGraphBuilder::RemoveMergeEnvironmentsBeforeOffset(
1343 if (!merge_environments_.empty()) {
1344 ZoneMap<int, Environment*>::iterator it = merge_environments_.begin();
1345 ZoneMap<int, Environment*>::iterator stop_it = merge_environments_.end();
1346 while (it != stop_it && it->first <= limit_offset) {
1347 it = merge_environments_.erase(it);
1352void BytecodeGraphBuilder::BuildFunctionEntryStackCheck() {
1353 if (!skip_first_stack_check()) {
1354 DCHECK(exception_handlers_.empty());
1356 NewNode(javascript()->StackCheck(StackCheckKind::kJSFunctionEntry));
1357 PrepareFrameStateForFunctionEntryStackCheck(node);
1361void BytecodeGraphBuilder::BuildIterationBodyStackCheck() {
1363 NewNode(javascript()->StackCheck(StackCheckKind::kJSIterationBody));
1364 environment()->RecordAfterState(node, Environment::kAttachFrameState);
1367void BytecodeGraphBuilder::BuildOSREntryStackCheck() {
1368 DCHECK(exception_handlers_.empty());
1370 NewNode(javascript()->StackCheck(StackCheckKind::kJSFunctionEntry));
1371 PrepareFrameStateForOSREntryStackCheck(node);
1377void BytecodeGraphBuilder::AdvanceToOsrEntryAndPeelLoops() {
1378 environment()->FillWithOsrValues();
1390 BuildOSREntryStackCheck();
1394 int osr_entry = bytecode_analysis().osr_entry_point();
1395 CHECK_EQ(bytecode_iterator().current_offset(), osr_entry);
1410 int current_parent_offset =
1411 bytecode_analysis().GetLoopInfoFor(osr_entry).parent_offset();
1412 while (current_parent_offset != -1) {
1413 const LoopInfo& current_parent_loop =
1414 bytecode_analysis().GetLoopInfoFor(current_parent_offset);
1417 for (; !bytecode_iterator().done(); bytecode_iterator().Advance()) {
1418 if (bytecode_iterator().current_bytecode() ==
1419 interpreter::Bytecode::kJumpLoop &&
1420 bytecode_iterator().GetJumpTargetOffset() == current_parent_offset) {
1424 VisitSingleBytecode();
1426 DCHECK(!bytecode_iterator()
1432 ExitThenEnterExceptionHandlers(bytecode_iterator().current_offset());
1433 SwitchToMergeEnvironment(bytecode_iterator().current_offset());
1447 RemoveMergeEnvironmentsBeforeOffset(bytecode_iterator().current_offset());
1450 current_parent_offset = current_parent_loop.
parent_offset();
1454void BytecodeGraphBuilder::VisitSingleBytecode() {
1455 tick_counter_->TickAndMaybeEnterSafepoint();
1456 int current_offset = bytecode_iterator().current_offset();
1457 UpdateSourceAndBytecodePosition(current_offset);
1458 ExitThenEnterExceptionHandlers(current_offset);
1459 DCHECK_GE(exception_handlers_.empty() ? current_offset
1460 : exception_handlers_.top().end_offset_,
1462 SwitchToMergeEnvironment(current_offset);
1464 if (environment() !=
nullptr) {
1465 BuildLoopHeaderEnvironment(current_offset);
1467 switch (bytecode_iterator().current_bytecode()) {
1468#define BYTECODE_CASE(name, ...) \
1469 case interpreter::Bytecode::k##name: \
1478void BytecodeGraphBuilder::VisitBytecodes() {
1479 if (!bytecode_analysis().resume_jump_targets().empty()) {
1480 environment()->BindGeneratorState(
1489 int osr_offset = bytecode_analysis().osr_bailout_id().ToInt();
1490 int osr_entry = bytecode_analysis().osr_entry_point();
1492 it.AdvanceTo(osr_offset);
1493 CHECK(it.CurrentBytecodeIsValidOSREntry());
1494 CHECK_EQ(osr_entry, it.GetJumpTargetOffset());
1500 AdvanceToOsrEntryAndPeelLoops();
1502 BuildFunctionEntryStackCheck();
1505 for (; !bytecode_iterator().done(); bytecode_iterator().Advance()) {
1506 VisitSingleBytecode();
1509 DCHECK(exception_handlers_.empty());
1512void BytecodeGraphBuilder::AddBytecodePositionDecorator() {
1515 graph()->AddDecorator(decorator_);
1518void BytecodeGraphBuilder::RemoveBytecodePositionDecorator() {
1520 graph()->RemoveDecorator(decorator_);
1521 decorator_ =
nullptr;
1524void BytecodeGraphBuilder::VisitLdaZero() {
1526 environment()->BindAccumulator(node);
1529void BytecodeGraphBuilder::VisitLdaSmi() {
1531 jsgraph()->ConstantNoHole(bytecode_iterator().GetImmediateOperand(0));
1532 environment()->BindAccumulator(node);
1535void BytecodeGraphBuilder::VisitLdaConstant() {
1536 ObjectRef
object = MakeRefForConstantForIndexOperand(0);
1538 environment()->BindAccumulator(node);
1541void BytecodeGraphBuilder::VisitLdaUndefined() {
1542 Node* node =
jsgraph()->UndefinedConstant();
1543 environment()->BindAccumulator(node);
1546void BytecodeGraphBuilder::VisitLdaNull() {
1547 Node* node =
jsgraph()->NullConstant();
1548 environment()->BindAccumulator(node);
1551void BytecodeGraphBuilder::VisitLdaTheHole() {
1552 Node* node =
jsgraph()->TheHoleConstant();
1553 environment()->BindAccumulator(node);
1556void BytecodeGraphBuilder::VisitLdaTrue() {
1557 Node* node =
jsgraph()->TrueConstant();
1558 environment()->BindAccumulator(node);
1561void BytecodeGraphBuilder::VisitLdaFalse() {
1562 Node* node =
jsgraph()->FalseConstant();
1563 environment()->BindAccumulator(node);
1566void BytecodeGraphBuilder::VisitLdar() {
1568 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1569 environment()->BindAccumulator(value);
1572void BytecodeGraphBuilder::VisitStar() {
1573 Node* value = environment()->LookupAccumulator();
1574 environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0), value);
1577#define SHORT_STAR_VISITOR(Name, ...) \
1578 void BytecodeGraphBuilder::Visit##Name() { \
1579 Node* value = environment()->LookupAccumulator(); \
1580 environment()->BindRegister( \
1581 interpreter::Register::FromShortStar(interpreter::Bytecode::k##Name), \
1585#undef SHORT_STAR_VISITOR
1587void BytecodeGraphBuilder::VisitMov() {
1589 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1590 environment()->BindRegister(bytecode_iterator().GetRegisterOperand(1), value);
1594 uint32_t feedback_slot_index,
1596 FeedbackSource feedback = CreateFeedbackSource(feedback_slot_index);
1598 const Operator* op = javascript()->LoadGlobal(name, feedback, typeof_mode);
1599 DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->
opcode()));
1600 return NewNode(op, feedback_vector_node());
1603void BytecodeGraphBuilder::VisitLdaGlobal() {
1604 PrepareEagerCheckpoint();
1605 NameRef name = MakeRefForConstantForIndexOperand<Name>(0);
1606 uint32_t feedback_slot_index = bytecode_iterator().GetIndexOperand(1);
1609 environment()->BindAccumulator(node, Environment::kAttachFrameState);
1612void BytecodeGraphBuilder::VisitLdaGlobalInsideTypeof() {
1613 PrepareEagerCheckpoint();
1614 NameRef name = MakeRefForConstantForIndexOperand<Name>(0);
1615 uint32_t feedback_slot_index = bytecode_iterator().GetIndexOperand(1);
1617 environment()->BindAccumulator(node, Environment::kAttachFrameState);
1620void BytecodeGraphBuilder::VisitStaGlobal() {
1621 PrepareEagerCheckpoint();
1622 NameRef name = MakeRefForConstantForIndexOperand<Name>(0);
1623 FeedbackSource feedback =
1624 CreateFeedbackSource(bytecode_iterator().GetIndexOperand(1));
1625 Node* value = environment()->LookupAccumulator();
1629 const Operator* op = javascript()->StoreGlobal(language_mode, name, feedback);
1630 DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
1631 Node* node = NewNode(op, value, feedback_vector_node());
1632 environment()->RecordAfterState(node, Environment::kAttachFrameState);
1635void BytecodeGraphBuilder::VisitStaInArrayLiteral() {
1636 PrepareEagerCheckpoint();
1637 Node* value = environment()->LookupAccumulator();
1639 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1641 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
1642 FeedbackSource feedback =
1643 CreateFeedbackSource(bytecode_iterator().GetIndexOperand(2));
1644 const Operator* op = javascript()->StoreInArrayLiteral(feedback);
1646 JSTypeHintLowering::LoweringResult lowering =
1647 TryBuildSimplifiedStoreKeyed(op, array, index, value, feedback.slot);
1648 if (lowering.IsExit())
return;
1650 Node* node =
nullptr;
1651 if (lowering.IsSideEffectFree()) {
1652 node = lowering.value();
1654 DCHECK(!lowering.Changed());
1655 DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
1656 node = NewNode(op, array, index, value, feedback_vector_node());
1659 environment()->RecordAfterState(node, Environment::kAttachFrameState);
1662void BytecodeGraphBuilder::VisitDefineKeyedOwnPropertyInLiteral() {
1663 PrepareEagerCheckpoint();
1666 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1668 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
1669 Node* value = environment()->LookupAccumulator();
1670 int flags = bytecode_iterator().GetFlag8Operand(2);
1671 FeedbackSource feedback =
1672 CreateFeedbackSource(bytecode_iterator().GetIndexOperand(3));
1673 const Operator* op = javascript()->DefineKeyedOwnPropertyInLiteral(feedback);
1675 JSTypeHintLowering::LoweringResult lowering =
1676 TryBuildSimplifiedStoreKeyed(op,
object, name, value, feedback.slot);
1677 if (lowering.IsExit())
return;
1679 Node* node =
nullptr;
1680 if (lowering.IsSideEffectFree()) {
1681 node = lowering.value();
1683 DCHECK(!lowering.Changed());
1684 DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
1685 node = NewNode(op,
object, name, value,
jsgraph()->ConstantNoHole(flags),
1686 feedback_vector_node());
1689 environment()->RecordAfterState(node, Environment::kAttachFrameState);
1692void BytecodeGraphBuilder::VisitLdaContextSlot() {
1693 const Operator* op = javascript()->LoadContext(
1694 bytecode_iterator().GetUnsignedImmediateOperand(2),
1695 bytecode_iterator().GetIndexOperand(1),
false);
1696 Node* node = NewNode(op);
1698 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1699 NodeProperties::ReplaceContextInput(node, context);
1700 environment()->BindAccumulator(node);
1703void BytecodeGraphBuilder::VisitLdaScriptContextSlot() {
1704 const Operator* op = javascript()->LoadScriptContext(
1705 bytecode_iterator().GetUnsignedImmediateOperand(2),
1706 bytecode_iterator().GetIndexOperand(1));
1707 Node* node = NewNode(op);
1709 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1710 NodeProperties::ReplaceContextInput(node, context);
1711 environment()->BindAccumulator(node);
1714void BytecodeGraphBuilder::VisitLdaImmutableContextSlot() {
1715 const Operator* op = javascript()->LoadContext(
1716 bytecode_iterator().GetUnsignedImmediateOperand(2),
1717 bytecode_iterator().GetIndexOperand(1),
true);
1718 Node* node = NewNode(op);
1720 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1721 NodeProperties::ReplaceContextInput(node, context);
1722 environment()->BindAccumulator(node);
1725void BytecodeGraphBuilder::VisitLdaCurrentContextSlot() {
1726 const Operator* op = javascript()->LoadContext(
1727 0, bytecode_iterator().GetIndexOperand(0),
false);
1728 Node* node = NewNode(op);
1729 environment()->BindAccumulator(node);
1732void BytecodeGraphBuilder::VisitLdaCurrentScriptContextSlot() {
1733 const Operator* op = javascript()->LoadScriptContext(
1734 0, bytecode_iterator().GetIndexOperand(0));
1735 Node* node = NewNode(op);
1736 environment()->BindAccumulator(node);
1739void BytecodeGraphBuilder::VisitLdaImmutableCurrentContextSlot() {
1740 const Operator* op = javascript()->LoadContext(
1741 0, bytecode_iterator().GetIndexOperand(0),
true);
1742 Node* node = NewNode(op);
1743 environment()->BindAccumulator(node);
1746void BytecodeGraphBuilder::VisitStaContextSlot() {
1747 const Operator* op = javascript()->StoreContext(
1748 bytecode_iterator().GetUnsignedImmediateOperand(2),
1749 bytecode_iterator().GetIndexOperand(1));
1750 Node* value = environment()->LookupAccumulator();
1751 Node* node = NewNode(op, value);
1753 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1754 NodeProperties::ReplaceContextInput(node, context);
1757void BytecodeGraphBuilder::VisitStaCurrentContextSlot() {
1758 const Operator* op =
1759 javascript()->StoreContext(0, bytecode_iterator().GetIndexOperand(0));
1760 Node* value = environment()->LookupAccumulator();
1764void BytecodeGraphBuilder::VisitStaScriptContextSlot() {
1765 PrepareEagerCheckpoint();
1766 const Operator* op = javascript()->StoreScriptContext(
1767 bytecode_iterator().GetUnsignedImmediateOperand(2),
1768 bytecode_iterator().GetIndexOperand(1));
1769 Node* value = environment()->LookupAccumulator();
1770 Node* node = NewNode(op, value);
1772 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
1773 NodeProperties::ReplaceContextInput(node, context);
1776void BytecodeGraphBuilder::VisitStaCurrentScriptContextSlot() {
1777 PrepareEagerCheckpoint();
1778 const Operator* op = javascript()->StoreScriptContext(
1779 0, bytecode_iterator().GetIndexOperand(0));
1780 Node* value = environment()->LookupAccumulator();
1784void BytecodeGraphBuilder::BuildLdaLookupSlot(
TypeofMode typeof_mode) {
1785 PrepareEagerCheckpoint();
1787 jsgraph()->ConstantNoHole(MakeRefForConstantForIndexOperand(0),
broker());
1790 ? Runtime::kLoadLookupSlot
1791 : Runtime::kLoadLookupSlotInsideTypeof);
1792 Node* value = NewNode(op, name);
1793 environment()->BindAccumulator(value, Environment::kAttachFrameState);
1796void BytecodeGraphBuilder::VisitLdaLookupSlot() {
1800void BytecodeGraphBuilder::VisitLdaLookupSlotInsideTypeof() {
1804BytecodeGraphBuilder::Environment*
1805BytecodeGraphBuilder::CheckContextExtensionAtDepth(
1807 Node* extension_slot = NewNode(
1809 Node* check_no_extension =
1810 NewNode(
simplified()->ReferenceEqual(), extension_slot,
1811 jsgraph()->UndefinedConstant());
1812 NewBranch(check_no_extension);
1817 if (slow_environment ==
nullptr) {
1818 slow_environment = environment();
1821 slow_environment->
Merge(environment(),
1822 bytecode_analysis().GetInLivenessFor(
1823 bytecode_iterator().current_offset()));
1830 return slow_environment;
1833OptionalScopeInfoRef BytecodeGraphBuilder::TryGetScopeInfo() {
1834 Node* context = environment()->Context();
1835 switch (context->opcode()) {
1836 case IrOpcode::kJSCreateFunctionContext:
1838 case IrOpcode::kJSCreateBlockContext:
1839 case IrOpcode::kJSCreateCatchContext:
1840 case IrOpcode::kJSCreateWithContext:
1842 case IrOpcode::kParameter: {
1850 return std::nullopt;
1856 OptionalScopeInfoRef maybe_scope_info = TryGetScopeInfo();
1857 if (!maybe_scope_info.has_value()) {
1858 return CheckContextExtensionsSlowPath(depth);
1865 for (uint32_t d = 0; d < depth; d++) {
1873 !
broker()->dependencies()->DependOnEmptyContextExtension(scope_info)) {
1876 slow_environment = CheckContextExtensionAtDepth(slow_environment, d);
1888 slow_environment !=
nullptr);
1889 return slow_environment;
1893BytecodeGraphBuilder::CheckContextExtensionsSlowPath(uint32_t depth) {
1899 for (uint32_t d = 0; d < depth; d++) {
1900 Node* has_extension = NewNode(javascript()->HasContextExtension(d));
1903 NewBranch(has_extension);
1907 slow_environment = CheckContextExtensionAtDepth(slow_environment, d);
1908 undefined_extension_env = environment();
1911 environment()->Merge(undefined_extension_env,
1912 bytecode_analysis().GetInLivenessFor(
1913 bytecode_iterator().current_offset()));
1914 mark_as_needing_eager_checkpoint(
true);
1922 return slow_environment;
1925void BytecodeGraphBuilder::BuildLdaLookupContextSlot(
ContextKind context_kind,
1927 uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(2);
1930 Environment* slow_environment = CheckContextExtensions(depth);
1934 uint32_t slot_index = bytecode_iterator().GetIndexOperand(1);
1938 ? javascript()->LoadScriptContext(depth, slot_index)
1939 : javascript()->LoadContext(depth, slot_index,
false);
1940 environment()->BindAccumulator(NewNode(op));
1942 if (!slow_environment) {
1952 set_environment(slow_environment);
1954 Node* name =
jsgraph()->ConstantNoHole(MakeRefForConstantForIndexOperand(0),
1959 ? Runtime::kLoadLookupSlot
1960 : Runtime::kLoadLookupSlotInsideTypeof);
1961 Node* value = NewNode(op, name);
1962 environment()->BindAccumulator(value, Environment::kAttachFrameState);
1965 fast_environment->
Merge(environment(),
1966 bytecode_analysis().GetOutLivenessFor(
1967 bytecode_iterator().current_offset()));
1968 set_environment(fast_environment);
1969 mark_as_needing_eager_checkpoint(
true);
1972void BytecodeGraphBuilder::VisitLdaLookupContextSlot() {
1976void BytecodeGraphBuilder::VisitLdaLookupScriptContextSlot() {
1981void BytecodeGraphBuilder::VisitLdaLookupContextSlotInsideTypeof() {
1985void BytecodeGraphBuilder::VisitLdaLookupScriptContextSlotInsideTypeof() {
1989void BytecodeGraphBuilder::BuildLdaLookupGlobalSlot(
TypeofMode typeof_mode) {
1990 uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(2);
1993 Environment* slow_environment = CheckContextExtensions(depth);
1997 PrepareEagerCheckpoint();
1998 NameRef name = MakeRefForConstantForIndexOperand<Name>(0);
1999 uint32_t feedback_slot_index = bytecode_iterator().GetIndexOperand(1);
2000 Node* node = BuildLoadGlobal(name, feedback_slot_index, typeof_mode);
2001 environment()->BindAccumulator(node, Environment::kAttachFrameState);
2003 if (!slow_environment) {
2013 set_environment(slow_environment);
2016 MakeRefForConstantForIndexOperand<Name>(0),
broker());
2020 ? Runtime::kLoadLookupSlot
2021 : Runtime::kLoadLookupSlotInsideTypeof);
2022 Node* value = NewNode(op, name);
2023 environment()->BindAccumulator(value, Environment::kAttachFrameState);
2026 fast_environment->
Merge(environment(),
2027 bytecode_analysis().GetOutLivenessFor(
2028 bytecode_iterator().current_offset()));
2029 set_environment(fast_environment);
2030 mark_as_needing_eager_checkpoint(
true);
2033void BytecodeGraphBuilder::VisitLdaLookupGlobalSlot() {
2037void BytecodeGraphBuilder::VisitLdaLookupGlobalSlotInsideTypeof() {
2041void BytecodeGraphBuilder::VisitStaLookupSlot() {
2042 PrepareEagerCheckpoint();
2043 Node* value = environment()->LookupAccumulator();
2045 jsgraph()->ConstantNoHole(MakeRefForConstantForIndexOperand(0),
broker());
2046 int bytecode_flags = bytecode_iterator().GetFlag8Operand(1);
2055 const Operator* op = javascript()->CallRuntime(
2057 ? Runtime::kStoreLookupSlot_Strict
2059 ? Runtime::kStoreLookupSlot_SloppyHoisting
2060 : Runtime::kStoreLookupSlot_Sloppy);
2061 Node* store = NewNode(op, name, value);
2062 environment()->BindAccumulator(store, Environment::kAttachFrameState);
2065void BytecodeGraphBuilder::VisitGetNamedProperty() {
2066 PrepareEagerCheckpoint();
2068 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2069 NameRef name = MakeRefForConstantForIndexOperand<Name>(1);
2070 FeedbackSource feedback =
2071 CreateFeedbackSource(bytecode_iterator().GetIndexOperand(2));
2072 const Operator* op = javascript()->LoadNamed(name, feedback);
2074 JSTypeHintLowering::LoweringResult lowering =
2075 TryBuildSimplifiedLoadNamed(op, feedback.slot);
2076 if (lowering.IsExit())
return;
2078 Node* node =
nullptr;
2079 if (lowering.IsSideEffectFree()) {
2080 node = lowering.value();
2082 DCHECK(!lowering.Changed());
2083 DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
2084 node = NewNode(op,
object, feedback_vector_node());
2086 environment()->BindAccumulator(node, Environment::kAttachFrameState);
2089void BytecodeGraphBuilder::VisitGetNamedPropertyFromSuper() {
2090 PrepareEagerCheckpoint();
2092 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2093 Node* home_object = environment()->LookupAccumulator();
2094 NameRef name = MakeRefForConstantForIndexOperand<Name>(1);
2096 FeedbackSource feedback =
2097 CreateFeedbackSource(bytecode_iterator().GetIndexOperand(2));
2098 const Operator* op = javascript()->LoadNamedFromSuper(name, feedback);
2100 JSTypeHintLowering::LoweringResult lowering =
2101 TryBuildSimplifiedLoadNamed(op, feedback.slot);
2102 if (lowering.IsExit())
return;
2104 Node* node =
nullptr;
2105 if (lowering.IsSideEffectFree()) {
2106 node = lowering.value();
2108 DCHECK(!lowering.Changed());
2109 DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
2110 node = NewNode(op,
receiver, home_object, feedback_vector_node());
2112 environment()->BindAccumulator(node, Environment::kAttachFrameState);
2115void BytecodeGraphBuilder::VisitGetKeyedProperty() {
2116 PrepareEagerCheckpoint();
2117 Node*
key = environment()->LookupAccumulator();
2119 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2120 FeedbackSource feedback =
2121 CreateFeedbackSource(bytecode_iterator().GetIndexOperand(1));
2122 const Operator* op = javascript()->LoadProperty(feedback);
2124 JSTypeHintLowering::LoweringResult lowering =
2125 TryBuildSimplifiedLoadKeyed(op,
object,
key, feedback.slot);
2126 if (lowering.IsExit())
return;
2128 Node* node =
nullptr;
2129 if (lowering.IsSideEffectFree()) {
2130 node = lowering.value();
2132 DCHECK(!lowering.Changed());
2133 static_assert(JSLoadPropertyNode::ObjectIndex() == 0);
2134 static_assert(JSLoadPropertyNode::KeyIndex() == 1);
2135 static_assert(JSLoadPropertyNode::FeedbackVectorIndex() == 2);
2136 DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
2137 node = NewNode(op,
object,
key, feedback_vector_node());
2139 environment()->BindAccumulator(node, Environment::kAttachFrameState);
2142void BytecodeGraphBuilder::VisitGetEnumeratedKeyedProperty() {
2144 PrepareEagerCheckpoint();
2145 Node*
key = environment()->LookupAccumulator();
2147 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2148 FeedbackSource feedback =
2149 CreateFeedbackSource(bytecode_iterator().GetIndexOperand(3));
2150 const Operator* op = javascript()->LoadProperty(feedback);
2152 static_assert(JSLoadPropertyNode::ObjectIndex() == 0);
2153 static_assert(JSLoadPropertyNode::KeyIndex() == 1);
2154 static_assert(JSLoadPropertyNode::FeedbackVectorIndex() == 2);
2155 DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
2156 Node* node = NewNode(op,
object,
key, feedback_vector_node());
2157 environment()->BindAccumulator(node, Environment::kAttachFrameState);
2161 PrepareEagerCheckpoint();
2162 Node* value = environment()->LookupAccumulator();
2164 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2165 NameRef name = MakeRefForConstantForIndexOperand<Name>(1);
2167 CreateFeedbackSource(bytecode_iterator().GetIndexOperand(2));
2170 if (store_mode == NamedStoreMode::kDefineOwn) {
2172 broker()->GetFeedbackSlotKind(feedback));
2174 op = javascript()->DefineNamedOwnProperty(name, feedback);
2176 DCHECK_EQ(NamedStoreMode::kSet, store_mode);
2179 op = javascript()->SetNamedProperty(language_mode, name, feedback);
2183 TryBuildSimplifiedStoreNamed(op,
object, value, feedback.slot);
2184 if (lowering.IsExit())
return;
2186 Node* node =
nullptr;
2187 if (lowering.IsSideEffectFree()) {
2188 node = lowering.value();
2190 DCHECK(!lowering.Changed());
2191 DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->
opcode()));
2192 node = NewNode(op,
object, value, feedback_vector_node());
2194 environment()->RecordAfterState(node, Environment::kAttachFrameState);
2197void BytecodeGraphBuilder::VisitSetNamedProperty() {
2198 BuildNamedStore(NamedStoreMode::kSet);
2201void BytecodeGraphBuilder::VisitDefineNamedOwnProperty() {
2202 BuildNamedStore(NamedStoreMode::kDefineOwn);
2205void BytecodeGraphBuilder::VisitSetKeyedProperty() {
2206 PrepareEagerCheckpoint();
2207 Node* value = environment()->LookupAccumulator();
2209 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2211 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
2212 FeedbackSource source =
2213 CreateFeedbackSource(bytecode_iterator().GetIndexOperand(2));
2216 const Operator* op = javascript()->SetKeyedProperty(language_mode, source);
2218 JSTypeHintLowering::LoweringResult lowering =
2219 TryBuildSimplifiedStoreKeyed(op,
object,
key, value, source.slot);
2220 if (lowering.IsExit())
return;
2222 Node* node =
nullptr;
2223 if (lowering.IsSideEffectFree()) {
2224 node = lowering.value();
2226 DCHECK(!lowering.Changed());
2227 static_assert(JSSetKeyedPropertyNode::ObjectIndex() == 0);
2228 static_assert(JSSetKeyedPropertyNode::KeyIndex() == 1);
2229 static_assert(JSSetKeyedPropertyNode::ValueIndex() == 2);
2230 static_assert(JSSetKeyedPropertyNode::FeedbackVectorIndex() == 3);
2231 DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
2232 node = NewNode(op,
object,
key, value, feedback_vector_node());
2235 environment()->RecordAfterState(node, Environment::kAttachFrameState);
2238void BytecodeGraphBuilder::VisitDefineKeyedOwnProperty() {
2239 PrepareEagerCheckpoint();
2240 Node* value = environment()->LookupAccumulator();
2242 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2244 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
2245 int flags = bytecode_iterator().GetFlag8Operand(2);
2246 FeedbackSource source =
2247 CreateFeedbackSource(bytecode_iterator().GetIndexOperand(3));
2251 const Operator* op =
2252 javascript()->DefineKeyedOwnProperty(language_mode, source);
2254 JSTypeHintLowering::LoweringResult lowering =
2255 TryBuildSimplifiedStoreKeyed(op,
object,
key, value, source.slot);
2256 if (lowering.IsExit())
return;
2258 Node* node =
nullptr;
2259 if (lowering.IsSideEffectFree()) {
2260 node = lowering.value();
2262 DCHECK(!lowering.Changed());
2263 static_assert(JSDefineKeyedOwnPropertyNode::ObjectIndex() == 0);
2264 static_assert(JSDefineKeyedOwnPropertyNode::KeyIndex() == 1);
2265 static_assert(JSDefineKeyedOwnPropertyNode::ValueIndex() == 2);
2266 static_assert(JSDefineKeyedOwnPropertyNode::FlagsIndex() == 3);
2267 static_assert(JSDefineKeyedOwnPropertyNode::FeedbackVectorIndex() == 4);
2268 DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
2269 node = NewNode(op,
object,
key, value,
jsgraph()->ConstantNoHole(flags),
2270 feedback_vector_node());
2273 environment()->RecordAfterState(node, Environment::kAttachFrameState);
2276void BytecodeGraphBuilder::VisitLdaModuleVariable() {
2277 int32_t cell_index = bytecode_iterator().GetImmediateOperand(0);
2278 uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(1);
2281 Node* value = NewNode(javascript()->LoadModule(cell_index), module);
2282 environment()->BindAccumulator(value);
2285void BytecodeGraphBuilder::VisitStaModuleVariable() {
2286 int32_t cell_index = bytecode_iterator().GetImmediateOperand(0);
2287 uint32_t depth = bytecode_iterator().GetUnsignedImmediateOperand(1);
2290 Node* value = environment()->LookupAccumulator();
2291 NewNode(javascript()->StoreModule(cell_index), module, value);
2294void BytecodeGraphBuilder::VisitPushContext() {
2295 Node* new_context = environment()->LookupAccumulator();
2296 environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0),
2297 environment()->Context());
2298 environment()->SetContext(new_context);
2301void BytecodeGraphBuilder::VisitPopContext() {
2303 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2304 environment()->SetContext(context);
2307void BytecodeGraphBuilder::VisitCreateClosure() {
2308 SharedFunctionInfoRef shared_info =
2309 MakeRefForConstantForIndexOperand<SharedFunctionInfo>(0);
2312 bytecode_iterator().GetFlag8Operand(2))
2315 CodeRef compile_lazy =
2317 const Operator* op =
2318 javascript()->CreateClosure(shared_info, compile_lazy, allocation);
2319 Node* closure = NewNode(
2320 op, BuildLoadFeedbackCell(bytecode_iterator().GetIndexOperand(1)));
2321 environment()->BindAccumulator(closure);
2324void BytecodeGraphBuilder::VisitCreateBlockContext() {
2325 ScopeInfoRef scope_info = MakeRefForConstantForIndexOperand<ScopeInfo>(0);
2326 const Operator* op = javascript()->CreateBlockContext(scope_info);
2327 Node* context = NewNode(op);
2328 environment()->BindAccumulator(context);
2331void BytecodeGraphBuilder::VisitCreateFunctionContext() {
2332 ScopeInfoRef scope_info = MakeRefForConstantForIndexOperand<ScopeInfo>(0);
2333 uint32_t slots = bytecode_iterator().GetUnsignedImmediateOperand(1);
2334 const Operator* op =
2335 javascript()->CreateFunctionContext(scope_info, slots,
FUNCTION_SCOPE);
2336 Node* context = NewNode(op);
2337 environment()->BindAccumulator(context);
2340void BytecodeGraphBuilder::VisitCreateEvalContext() {
2341 ScopeInfoRef scope_info = MakeRefForConstantForIndexOperand<ScopeInfo>(0);
2342 uint32_t slots = bytecode_iterator().GetUnsignedImmediateOperand(1);
2343 const Operator* op =
2344 javascript()->CreateFunctionContext(scope_info, slots,
EVAL_SCOPE);
2345 Node* context = NewNode(op);
2346 environment()->BindAccumulator(context);
2349void BytecodeGraphBuilder::VisitCreateCatchContext() {
2350 interpreter::Register
reg = bytecode_iterator().GetRegisterOperand(0);
2351 Node* exception = environment()->LookupRegister(
reg);
2352 ScopeInfoRef scope_info = MakeRefForConstantForIndexOperand<ScopeInfo>(1);
2354 const Operator* op = javascript()->CreateCatchContext(scope_info);
2355 Node* context = NewNode(op, exception);
2356 environment()->BindAccumulator(context);
2359void BytecodeGraphBuilder::VisitCreateWithContext() {
2361 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2362 ScopeInfoRef scope_info = MakeRefForConstantForIndexOperand<ScopeInfo>(1);
2364 const Operator* op = javascript()->CreateWithContext(scope_info);
2365 Node* context = NewNode(op,
object);
2366 environment()->BindAccumulator(context);
2370 const Operator* op = javascript()->CreateArguments(type);
2371 Node*
object = NewNode(op, GetFunctionClosure());
2372 environment()->BindAccumulator(
object, Environment::kAttachFrameState);
2375void BytecodeGraphBuilder::VisitCreateMappedArguments() {
2379void BytecodeGraphBuilder::VisitCreateUnmappedArguments() {
2383void BytecodeGraphBuilder::VisitCreateRestParameter() {
2387void BytecodeGraphBuilder::VisitCreateRegExpLiteral() {
2388 StringRef constant_pattern = MakeRefForConstantForIndexOperand<String>(0);
2389 int const slot_id = bytecode_iterator().GetIndexOperand(1);
2390 FeedbackSource pair = CreateFeedbackSource(slot_id);
2391 int literal_flags = bytecode_iterator().GetFlag16Operand(2);
2392 static_assert(JSCreateLiteralRegExpNode::FeedbackVectorIndex() == 0);
2393 const Operator* op =
2394 javascript()->CreateLiteralRegExp(constant_pattern, pair, literal_flags);
2395 DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
2396 Node*
literal = NewNode(op, feedback_vector_node());
2397 environment()->BindAccumulator(
literal, Environment::kAttachFrameState);
2400void BytecodeGraphBuilder::VisitCreateArrayLiteral() {
2401 ArrayBoilerplateDescriptionRef array_boilerplate_description =
2402 MakeRefForConstantForIndexOperand<ArrayBoilerplateDescription>(0);
2403 int const slot_id = bytecode_iterator().GetIndexOperand(1);
2404 FeedbackSource pair = CreateFeedbackSource(slot_id);
2405 int bytecode_flags = bytecode_iterator().GetFlag8Operand(2);
2413 int number_of_elements =
2414 array_boilerplate_description.constants_elements_length();
2415 static_assert(JSCreateLiteralArrayNode::FeedbackVectorIndex() == 0);
2416 const Operator* op = javascript()->CreateLiteralArray(
2417 array_boilerplate_description, pair, literal_flags, number_of_elements);
2418 DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
2419 Node*
literal = NewNode(op, feedback_vector_node());
2420 environment()->BindAccumulator(
literal, Environment::kAttachFrameState);
2423void BytecodeGraphBuilder::VisitCreateEmptyArrayLiteral() {
2424 int const slot_id = bytecode_iterator().GetIndexOperand(0);
2425 FeedbackSource pair = CreateFeedbackSource(slot_id);
2426 const Operator* op = javascript()->CreateEmptyLiteralArray(pair);
2427 DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
2428 Node*
literal = NewNode(op, feedback_vector_node());
2429 environment()->BindAccumulator(
literal);
2432void BytecodeGraphBuilder::VisitCreateArrayFromIterable() {
2433 Node* iterable = NewNode(javascript()->CreateArrayFromIterable(),
2434 environment()->LookupAccumulator());
2435 environment()->BindAccumulator(iterable, Environment::kAttachFrameState);
2438void BytecodeGraphBuilder::VisitCreateObjectLiteral() {
2439 ObjectBoilerplateDescriptionRef constant_properties =
2440 MakeRefForConstantForIndexOperand<ObjectBoilerplateDescription>(0);
2441 int const slot_id = bytecode_iterator().GetIndexOperand(1);
2442 FeedbackSource pair = CreateFeedbackSource(slot_id);
2443 int bytecode_flags = bytecode_iterator().GetFlag8Operand(2);
2446 int number_of_properties = constant_properties.boilerplate_properties_count();
2447 static_assert(JSCreateLiteralObjectNode::FeedbackVectorIndex() == 0);
2448 const Operator* op = javascript()->CreateLiteralObject(
2449 constant_properties, pair, literal_flags, number_of_properties);
2450 DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
2451 Node*
literal = NewNode(op, feedback_vector_node());
2452 environment()->BindAccumulator(
literal, Environment::kAttachFrameState);
2455void BytecodeGraphBuilder::VisitCreateEmptyObjectLiteral() {
2456 Node*
literal = NewNode(javascript()->CreateEmptyLiteralObject());
2457 environment()->BindAccumulator(
literal);
2460void BytecodeGraphBuilder::VisitCloneObject() {
2461 PrepareEagerCheckpoint();
2463 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2464 int flags = bytecode_iterator().GetFlag8Operand(1);
2465 int slot = bytecode_iterator().GetIndexOperand(2);
2466 const Operator* op =
2467 javascript()->CloneObject(CreateFeedbackSource(slot), flags);
2468 static_assert(JSCloneObjectNode::SourceIndex() == 0);
2469 static_assert(JSCloneObjectNode::FeedbackVectorIndex() == 1);
2470 DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
2471 Node* value = NewNode(op, source, feedback_vector_node());
2472 environment()->BindAccumulator(value, Environment::kAttachFrameState);
2475void BytecodeGraphBuilder::VisitGetTemplateObject() {
2476 FeedbackSource source =
2477 CreateFeedbackSource(bytecode_iterator().GetIndexOperand(1));
2478 TemplateObjectDescriptionRef description =
2479 MakeRefForConstantForIndexOperand<TemplateObjectDescription>(0);
2480 static_assert(JSGetTemplateObjectNode::FeedbackVectorIndex() == 0);
2481 const Operator* op =
2482 javascript()->GetTemplateObject(description, shared_info(), source);
2483 DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
2484 Node* template_object = NewNode(op, feedback_vector_node());
2485 environment()->BindAccumulator(template_object);
2488Node*
const* BytecodeGraphBuilder::GetCallArgumentsFromRegisters(
2491 const int arity = JSCallNode::ArityForArgc(arg_count);
2492 Node** all = local_zone()->AllocateArray<
Node*>(
static_cast<size_t>(arity));
2495 static_assert(JSCallNode::TargetIndex() == 0);
2496 static_assert(JSCallNode::ReceiverIndex() == 1);
2497 static_assert(JSCallNode::FirstArgumentIndex() == 2);
2498 static_assert(JSCallNode::kFeedbackVectorIsLastInput);
2500 all[cursor++] = callee;
2505 for (
int i = 0;
i < arg_count; ++
i) {
2510 all[cursor++] = feedback_vector_node();
2517 Node*
const*
args,
size_t arg_count,
2520 bytecode_iterator().current_bytecode()),
2522 PrepareEagerCheckpoint();
2528 ComputeCallFeedbackRelation(slot_id);
2530 javascript()->Call(arg_count, frequency, feedback, receiver_mode,
2531 speculation_mode, call_feedback_relation);
2532 DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->
opcode()));
2535 op,
args,
static_cast<int>(arg_count), feedback.slot);
2536 if (lowering.IsExit())
return;
2538 Node* node =
nullptr;
2539 if (lowering.IsSideEffectFree()) {
2540 node = lowering.value();
2542 DCHECK(!lowering.Changed());
2543 node = MakeNode(op,
static_cast<int>(arg_count),
args);
2545 environment()->BindAccumulator(node, Environment::kAttachFrameState);
2548Node*
const* BytecodeGraphBuilder::ProcessCallVarArgs(
2552 Node* receiver_node;
2558 receiver_node =
jsgraph()->UndefinedConstant();
2563 receiver_node = environment()->LookupRegister(first_reg);
2567 Node*
const* call_args = GetCallArgumentsFromRegisters(callee, receiver_node,
2574 bytecode_iterator().current_bytecode()),
2577 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2579 size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
2580 int const slot_id = bytecode_iterator().GetIndexOperand(3);
2583 ?
static_cast<int>(reg_count)
2584 :
static_cast<int>(reg_count) - 1;
2585 Node*
const* call_args =
2586 ProcessCallVarArgs(receiver_mode, callee, first_reg, arg_count);
2587 BuildCall(receiver_mode, call_args, JSCallNode::ArityForArgc(arg_count),
2591void BytecodeGraphBuilder::VisitCallAnyReceiver() {
2595void BytecodeGraphBuilder::VisitCallProperty() {
2599void BytecodeGraphBuilder::VisitCallProperty0() {
2601 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2603 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
2604 int const slot_id = bytecode_iterator().GetIndexOperand(2);
2606 {callee,
receiver, feedback_vector_node()}, slot_id);
2609void BytecodeGraphBuilder::VisitCallProperty1() {
2611 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2613 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
2615 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2));
2616 int const slot_id = bytecode_iterator().GetIndexOperand(3);
2618 {callee,
receiver, arg0, feedback_vector_node()}, slot_id);
2621void BytecodeGraphBuilder::VisitCallProperty2() {
2623 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2625 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
2627 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2));
2629 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(3));
2630 int const slot_id = bytecode_iterator().GetIndexOperand(4);
2632 {callee,
receiver, arg0, arg1, feedback_vector_node()}, slot_id);
2635void BytecodeGraphBuilder::VisitCallUndefinedReceiver() {
2639void BytecodeGraphBuilder::VisitCallUndefinedReceiver0() {
2641 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2643 int const slot_id = bytecode_iterator().GetIndexOperand(1);
2645 {callee,
receiver, feedback_vector_node()}, slot_id);
2648void BytecodeGraphBuilder::VisitCallUndefinedReceiver1() {
2650 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2653 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
2654 int const slot_id = bytecode_iterator().GetIndexOperand(2);
2656 {callee,
receiver, arg0, feedback_vector_node()}, slot_id);
2659void BytecodeGraphBuilder::VisitCallUndefinedReceiver2() {
2661 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2664 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
2666 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2));
2667 int const slot_id = bytecode_iterator().GetIndexOperand(3);
2669 {callee,
receiver, arg0, arg1, feedback_vector_node()}, slot_id);
2672void BytecodeGraphBuilder::VisitCallWithSpread() {
2673 PrepareEagerCheckpoint();
2675 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
2676 interpreter::Register
receiver = bytecode_iterator().GetRegisterOperand(1);
2677 Node* receiver_node = environment()->LookupRegister(
receiver);
2678 size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
2680 int arg_count =
static_cast<int>(reg_count) - 1;
2681 Node*
const*
args = GetCallArgumentsFromRegisters(callee, receiver_node,
2683 int const slot_id = bytecode_iterator().GetIndexOperand(3);
2684 FeedbackSource feedback = CreateFeedbackSource(slot_id);
2685 CallFrequency frequency = ComputeCallFrequency(slot_id);
2687 const Operator* op = javascript()->CallWithSpread(
2688 JSCallWithSpreadNode::ArityForArgc(arg_count), frequency, feedback,
2690 DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
2692 JSTypeHintLowering::LoweringResult lowering = TryBuildSimplifiedCall(
2693 op,
args,
static_cast<int>(arg_count), feedback.slot);
2694 if (lowering.IsExit())
return;
2696 Node* node =
nullptr;
2697 if (lowering.IsSideEffectFree()) {
2698 node = lowering.value();
2700 DCHECK(!lowering.Changed());
2701 node =
MakeNode(op, JSCallWithSpreadNode::ArityForArgc(arg_count),
args);
2703 environment()->BindAccumulator(node, Environment::kAttachFrameState);
2706void BytecodeGraphBuilder::VisitCallJSRuntime() {
2707 PrepareEagerCheckpoint();
2708 Node* callee = BuildLoadNativeContextField(
2709 bytecode_iterator().GetNativeContextIndexOperand(0));
2710 interpreter::Register first_reg = bytecode_iterator().GetRegisterOperand(1);
2711 size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
2712 int arg_count =
static_cast<int>(reg_count);
2713 int arity = JSCallNode::ArityForArgc(arg_count);
2715 const Operator* call = javascript()->Call(arity);
2716 Node*
const* call_args = ProcessCallVarArgs(
2718 Node* value =
MakeNode(call, arity, call_args);
2719 environment()->BindAccumulator(value, Environment::kAttachFrameState);
2722Node* BytecodeGraphBuilder::ProcessCallRuntimeArguments(
2725 int arg_count =
static_cast<int>(reg_count);
2727 int arity = arg_count;
2728 Node** all = local_zone()->AllocateArray<
Node*>(
static_cast<size_t>(arity));
2729 int first_arg_index =
receiver.index();
2730 for (
int i = 0; i < static_cast<int>(reg_count); ++
i) {
2731 all[
i] = environment()->LookupRegister(
2734 Node* value = MakeNode(call_runtime_op, arity, all);
2738void BytecodeGraphBuilder::VisitCallRuntime() {
2739 PrepareEagerCheckpoint();
2742 size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
2746 if (function_id == Runtime::FunctionId::kObserveNode) {
2749 observe_node_info_.StartObserving(value);
2750 environment()->BindAccumulator(value);
2753 const Operator* call = javascript()->CallRuntime(function_id, reg_count);
2754 Node* value = ProcessCallRuntimeArguments(call,
receiver, reg_count);
2755 environment()->BindAccumulator(value, Environment::kAttachFrameState);
2760 Node* control = NewNode(common()->
Throw());
2761 MergeControlToLeaveFunction(control);
2766void BytecodeGraphBuilder::VisitCallRuntimeForPair() {
2767 PrepareEagerCheckpoint();
2769 interpreter::Register
receiver = bytecode_iterator().GetRegisterOperand(1);
2770 size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
2771 interpreter::Register first_return =
2772 bytecode_iterator().GetRegisterOperand(3);
2775 const Operator* call = javascript()->CallRuntime(functionId, reg_count);
2776 Node* return_pair = ProcessCallRuntimeArguments(call,
receiver, reg_count);
2777 environment()->BindRegistersToProjections(first_return, return_pair,
2778 Environment::kAttachFrameState);
2781Node*
const* BytecodeGraphBuilder::GetConstructArgumentsFromRegister(
2784 const int arity = JSConstructNode::ArityForArgc(arg_count);
2785 Node** all = local_zone()->AllocateArray<
Node*>(
static_cast<size_t>(arity));
2788 static_assert(JSConstructNode::TargetIndex() == 0);
2789 static_assert(JSConstructNode::NewTargetIndex() == 1);
2790 static_assert(JSConstructNode::FirstArgumentIndex() == 2);
2791 static_assert(JSConstructNode::kFeedbackVectorIsLastInput);
2798 for (
int i = 0;
i < arg_count; ++
i) {
2803 all[cursor++] = feedback_vector_node();
2809void BytecodeGraphBuilder::VisitConstruct() {
2810 PrepareEagerCheckpoint();
2813 size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
2814 int const slot_id = bytecode_iterator().GetIndexOperand(3);
2818 Node* callee = environment()->LookupRegister(callee_reg);
2821 const uint32_t arg_count =
static_cast<uint32_t
>(reg_count);
2822 const uint32_t arity = JSConstructNode::ArityForArgc(arg_count);
2823 const Operator* op = javascript()->Construct(arity, frequency, feedback);
2824 DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->
opcode()));
2826 first_reg, arg_count);
2828 op,
args,
static_cast<int>(arg_count), feedback.slot);
2829 if (lowering.IsExit())
return;
2831 Node* node =
nullptr;
2832 if (lowering.IsSideEffectFree()) {
2833 node = lowering.value();
2835 DCHECK(!lowering.Changed());
2836 node = MakeNode(op, arity,
args);
2838 environment()->BindAccumulator(node, Environment::kAttachFrameState);
2841void BytecodeGraphBuilder::VisitConstructWithSpread() {
2842 PrepareEagerCheckpoint();
2843 interpreter::Register callee_reg = bytecode_iterator().GetRegisterOperand(0);
2844 interpreter::Register first_reg = bytecode_iterator().GetRegisterOperand(1);
2845 size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
2846 int const slot_id = bytecode_iterator().GetIndexOperand(3);
2847 FeedbackSource feedback = CreateFeedbackSource(slot_id);
2849 Node*
new_target = environment()->LookupAccumulator();
2850 Node* callee = environment()->LookupRegister(callee_reg);
2852 CallFrequency frequency = ComputeCallFrequency(slot_id);
2853 const uint32_t arg_count =
static_cast<uint32_t
>(reg_count);
2854 const uint32_t arity = JSConstructNode::ArityForArgc(arg_count);
2855 const Operator* op =
2856 javascript()->ConstructWithSpread(arity, frequency, feedback);
2857 DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
2858 Node*
const*
args = GetConstructArgumentsFromRegister(callee,
new_target,
2859 first_reg, arg_count);
2860 JSTypeHintLowering::LoweringResult lowering = TryBuildSimplifiedConstruct(
2861 op,
args,
static_cast<int>(arg_count), feedback.slot);
2862 if (lowering.IsExit())
return;
2864 Node* node =
nullptr;
2865 if (lowering.IsSideEffectFree()) {
2866 node = lowering.value();
2868 DCHECK(!lowering.Changed());
2871 environment()->BindAccumulator(node, Environment::kAttachFrameState);
2874void BytecodeGraphBuilder::VisitConstructForwardAllArgs() {
2875 PrepareEagerCheckpoint();
2876 interpreter::Register callee_reg = bytecode_iterator().GetRegisterOperand(0);
2877 int const slot_id = bytecode_iterator().GetIndexOperand(1);
2878 FeedbackSource feedback = CreateFeedbackSource(slot_id);
2879 Node*
new_target = environment()->LookupAccumulator();
2880 Node* callee = environment()->LookupRegister(callee_reg);
2881 CallFrequency frequency = ComputeCallFrequency(slot_id);
2888 constexpr int arg_count = 0;
2889 const int arity = JSConstructForwardAllArgsNode::ArityForArgc(arg_count);
2890 Node** construct_args =
2891 local_zone()->AllocateArray<Node*>(
static_cast<size_t>(arity));
2892 static_assert(JSConstructForwardAllArgsNode::TargetIndex() == 0);
2893 static_assert(JSConstructForwardAllArgsNode::NewTargetIndex() == 1);
2894 static_assert(JSConstructNode::kFeedbackVectorIsLastInput);
2895 DCHECK_LT(JSConstructForwardAllArgsNode::NewTargetIndex(), arity);
2897 construct_args[cursor++] = callee;
2899 construct_args[cursor++] = feedback_vector_node();
2901 const Operator* op =
2902 javascript()->ConstructForwardAllArgs(frequency, feedback);
2903 JSTypeHintLowering::LoweringResult lowering =
2904 TryBuildSimplifiedConstruct(op, construct_args, arg_count, feedback.slot);
2905 if (lowering.IsExit())
return;
2908 if (lowering.IsSideEffectFree()) {
2909 node = lowering.value();
2911 DCHECK(!lowering.Changed());
2912 node =
MakeNode(op, arity, construct_args);
2915 environment()->BindAccumulator(node, Environment::kAttachFrameState);
2918void BytecodeGraphBuilder::VisitInvokeIntrinsic() {
2919 PrepareEagerCheckpoint();
2921 interpreter::Register
receiver = bytecode_iterator().GetRegisterOperand(1);
2922 size_t reg_count = bytecode_iterator().GetRegisterCountOperand(2);
2926 const Operator* call = javascript()->CallRuntime(functionId, reg_count);
2927 Node* value = ProcessCallRuntimeArguments(call,
receiver, reg_count);
2928 environment()->BindAccumulator(value, Environment::kAttachFrameState);
2931void BytecodeGraphBuilder::VisitThrow() {
2932 BuildLoopExitsForFunctionExit(bytecode_analysis().GetInLivenessFor(
2933 bytecode_iterator().current_offset()));
2934 Node* value = environment()->LookupAccumulator();
2935 Node* call = NewNode(javascript()->CallRuntime(Runtime::kThrow), value);
2936 environment()->BindAccumulator(call, Environment::kAttachFrameState);
2937 Node* control = NewNode(common()->Throw());
2938 MergeControlToLeaveFunction(control);
2941void BytecodeGraphBuilder::VisitAbort() {
2942 BuildLoopExitsForFunctionExit(bytecode_analysis().GetInLivenessFor(
2943 bytecode_iterator().current_offset()));
2945 static_cast<AbortReason>(bytecode_iterator().GetIndexOperand(0));
2947 Node* control = NewNode(common()->Throw());
2948 MergeControlToLeaveFunction(control);
2951void BytecodeGraphBuilder::VisitReThrow() {
2952 BuildLoopExitsForFunctionExit(bytecode_analysis().GetInLivenessFor(
2953 bytecode_iterator().current_offset()));
2954 Node* value = environment()->LookupAccumulator();
2955 Node* rethrow = NewNode(javascript()->CallRuntime(Runtime::kReThrow), value);
2956 environment()->RecordAfterState(rethrow, Environment::kAttachFrameState);
2957 Node* control = NewNode(common()->Throw());
2958 MergeControlToLeaveFunction(control);
2961void BytecodeGraphBuilder::BuildHoleCheckAndThrow(
2963 Node* accumulator = environment()->LookupAccumulator();
2969 BuildLoopExitsForFunctionExit(bytecode_analysis().GetInLivenessFor(
2970 bytecode_iterator().current_offset()));
2972 const Operator* op = javascript()->CallRuntime(runtime_id);
2973 if (runtime_id == Runtime::kThrowAccessedUninitializedVariable) {
2975 node = NewNode(op, name);
2977 DCHECK(runtime_id == Runtime::kThrowSuperAlreadyCalledError ||
2978 runtime_id == Runtime::kThrowSuperNotCalled);
2981 environment()->RecordAfterState(node, Environment::kAttachFrameState);
2982 Node* control = NewNode(common()->
Throw());
2983 MergeControlToLeaveFunction(control);
2986 environment()->BindAccumulator(accumulator);
2989void BytecodeGraphBuilder::VisitThrowReferenceErrorIfHole() {
2990 Node* accumulator = environment()->LookupAccumulator();
2991 Node* check_for_hole = NewNode(
simplified()->ReferenceEqual(), accumulator,
2992 jsgraph()->TheHoleConstant());
2994 jsgraph()->ConstantNoHole(MakeRefForConstantForIndexOperand(0),
broker());
2995 BuildHoleCheckAndThrow(check_for_hole,
2996 Runtime::kThrowAccessedUninitializedVariable, name);
2999void BytecodeGraphBuilder::VisitThrowSuperNotCalledIfHole() {
3000 Node* accumulator = environment()->LookupAccumulator();
3001 Node* check_for_hole = NewNode(
simplified()->ReferenceEqual(), accumulator,
3002 jsgraph()->TheHoleConstant());
3003 BuildHoleCheckAndThrow(check_for_hole, Runtime::kThrowSuperNotCalled);
3006void BytecodeGraphBuilder::VisitThrowSuperAlreadyCalledIfNotHole() {
3007 Node* accumulator = environment()->LookupAccumulator();
3008 Node* check_for_hole = NewNode(
simplified()->ReferenceEqual(), accumulator,
3009 jsgraph()->TheHoleConstant());
3010 Node* check_for_not_hole =
3011 NewNode(
simplified()->BooleanNot(), check_for_hole);
3012 BuildHoleCheckAndThrow(check_for_not_hole,
3013 Runtime::kThrowSuperAlreadyCalledError);
3016void BytecodeGraphBuilder::VisitThrowIfNotSuperConstructor() {
3018 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
3019 Node* check_is_constructor =
3020 NewNode(
simplified()->ObjectIsConstructor(), constructor);
3023 SubEnvironment sub_environment(
this);
3025 BuildLoopExitsForFunctionExit(bytecode_analysis().GetInLivenessFor(
3026 bytecode_iterator().current_offset()));
3028 NewNode(javascript()->CallRuntime(Runtime::kThrowNotSuperConstructor),
3029 constructor, GetFunctionClosure());
3030 environment()->RecordAfterState(node, Environment::kAttachFrameState);
3031 Node* control = NewNode(common()->Throw());
3032 MergeControlToLeaveFunction(control);
3036 constructor = NewNode(common()->TypeGuard(Type::Callable()), constructor);
3037 environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0),
3041void BytecodeGraphBuilder::BuildUnaryOp(
const Operator* op) {
3043 PrepareEagerCheckpoint();
3044 Node* operand = environment()->LookupAccumulator();
3047 bytecode_iterator().GetSlotOperand(kUnaryOperationHintIndex);
3049 TryBuildSimplifiedUnaryOp(op, operand, slot);
3050 if (lowering.IsExit())
return;
3052 Node* node =
nullptr;
3053 if (lowering.IsSideEffectFree()) {
3054 node = lowering.value();
3056 DCHECK(!lowering.Changed());
3057 DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->
opcode()));
3058 node = NewNode(op, operand, feedback_vector_node());
3061 environment()->BindAccumulator(node, Environment::kAttachFrameState);
3064void BytecodeGraphBuilder::BuildBinaryOp(
const Operator* op) {
3065 DCHECK(JSOperator::IsBinaryWithFeedback(op->
opcode()));
3066 PrepareEagerCheckpoint();
3068 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
3069 Node* right = environment()->LookupAccumulator();
3072 bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex);
3074 TryBuildSimplifiedBinaryOp(op, left, right, slot);
3075 if (lowering.IsExit())
return;
3077 Node* node =
nullptr;
3078 if (lowering.IsSideEffectFree()) {
3079 node = lowering.value();
3081 DCHECK(!lowering.Changed());
3082 DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->
opcode()));
3083 node = NewNode(op, left, right, feedback_vector_node());
3086 environment()->BindAccumulator(node, Environment::kAttachFrameState);
3092 switch (
broker()->GetFeedbackForForIn(source)) {
3095 return ForInMode::kUseEnumCacheKeysAndIndices;
3097 return ForInMode::kUseEnumCacheKeys;
3099 return ForInMode::kGeneric;
3105 if (invocation_frequency_.IsUnknown())
return CallFrequency();
3109 float feedback_frequency =
3110 feedback.
IsInsufficient() ? 0.0f : feedback.AsCall().frequency();
3111 if (feedback_frequency == 0.0f) {
3114 return CallFrequency(feedback_frequency * invocation_frequency_.value());
3123 : feedback.AsCall().speculation_mode();
3127 int slot_id)
const {
3131 if (feedback.IsInsufficient())
return CallFeedbackRelation::kUnrelated;
3135 ? CallFeedbackRelation::kTarget
3136 : CallFeedbackRelation::kReceiver;
3139void BytecodeGraphBuilder::VisitBitwiseNot() {
3141 bytecode_iterator().GetSlotOperand(kUnaryOperationHintIndex));
3142 BuildUnaryOp(javascript()->BitwiseNot(feedback));
3145void BytecodeGraphBuilder::VisitDec() {
3146 FeedbackSource feedback = CreateFeedbackSource(
3147 bytecode_iterator().GetSlotOperand(kUnaryOperationHintIndex));
3148 BuildUnaryOp(javascript()->Decrement(feedback));
3151void BytecodeGraphBuilder::VisitInc() {
3152 FeedbackSource feedback = CreateFeedbackSource(
3153 bytecode_iterator().GetSlotOperand(kUnaryOperationHintIndex));
3154 BuildUnaryOp(javascript()->Increment(feedback));
3157void BytecodeGraphBuilder::VisitNegate() {
3158 FeedbackSource feedback = CreateFeedbackSource(
3159 bytecode_iterator().GetSlotOperand(kUnaryOperationHintIndex));
3160 BuildUnaryOp(javascript()->Negate(feedback));
3163void BytecodeGraphBuilder::VisitAdd() {
3164 FeedbackSource feedback = CreateFeedbackSource(
3165 bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex));
3166 BuildBinaryOp(javascript()->
Add(feedback));
3169void BytecodeGraphBuilder::VisitSub() {
3170 FeedbackSource feedback = CreateFeedbackSource(
3171 bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex));
3172 BuildBinaryOp(javascript()->
Subtract(feedback));
3175void BytecodeGraphBuilder::VisitMul() {
3176 FeedbackSource feedback = CreateFeedbackSource(
3177 bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex));
3178 BuildBinaryOp(javascript()->Multiply(feedback));
3181void BytecodeGraphBuilder::VisitDiv() {
3182 FeedbackSource feedback = CreateFeedbackSource(
3183 bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex));
3184 BuildBinaryOp(javascript()->
Divide(feedback));
3187void BytecodeGraphBuilder::VisitMod() {
3188 FeedbackSource feedback = CreateFeedbackSource(
3189 bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex));
3190 BuildBinaryOp(javascript()->Modulus(feedback));
3193void BytecodeGraphBuilder::VisitExp() {
3194 FeedbackSource feedback = CreateFeedbackSource(
3195 bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex));
3196 BuildBinaryOp(javascript()->Exponentiate(feedback));
3199void BytecodeGraphBuilder::VisitBitwiseOr() {
3200 FeedbackSource feedback = CreateFeedbackSource(
3201 bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex));
3202 BuildBinaryOp(javascript()->BitwiseOr(feedback));
3205void BytecodeGraphBuilder::VisitBitwiseXor() {
3206 FeedbackSource feedback = CreateFeedbackSource(
3207 bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex));
3208 BuildBinaryOp(javascript()->BitwiseXor(feedback));
3211void BytecodeGraphBuilder::VisitBitwiseAnd() {
3212 FeedbackSource feedback = CreateFeedbackSource(
3213 bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex));
3214 BuildBinaryOp(javascript()->BitwiseAnd(feedback));
3217void BytecodeGraphBuilder::VisitShiftLeft() {
3218 FeedbackSource feedback = CreateFeedbackSource(
3219 bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex));
3220 BuildBinaryOp(javascript()->ShiftLeft(feedback));
3223void BytecodeGraphBuilder::VisitShiftRight() {
3224 FeedbackSource feedback = CreateFeedbackSource(
3225 bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex));
3226 BuildBinaryOp(javascript()->ShiftRight(feedback));
3229void BytecodeGraphBuilder::VisitShiftRightLogical() {
3230 FeedbackSource feedback = CreateFeedbackSource(
3231 bytecode_iterator().GetSlotOperand(kBinaryOperationHintIndex));
3232 BuildBinaryOp(javascript()->ShiftRightLogical(feedback));
3235void BytecodeGraphBuilder::BuildBinaryOpWithImmediate(
const Operator* op) {
3236 DCHECK(JSOperator::IsBinaryWithFeedback(op->
opcode()));
3237 PrepareEagerCheckpoint();
3238 Node* left = environment()->LookupAccumulator();
3240 jsgraph()->ConstantNoHole(bytecode_iterator().GetImmediateOperand(0));
3243 bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex);
3245 TryBuildSimplifiedBinaryOp(op, left, right, slot);
3246 if (lowering.IsExit())
return;
3248 Node* node =
nullptr;
3249 if (lowering.IsSideEffectFree()) {
3250 node = lowering.value();
3252 DCHECK(!lowering.Changed());
3253 DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->
opcode()));
3254 node = NewNode(op, left, right, feedback_vector_node());
3256 environment()->BindAccumulator(node, Environment::kAttachFrameState);
3259void BytecodeGraphBuilder::VisitAddSmi() {
3261 bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex));
3262 BuildBinaryOpWithImmediate(javascript()->Add(feedback));
3265void BytecodeGraphBuilder::VisitSubSmi() {
3266 FeedbackSource feedback = CreateFeedbackSource(
3267 bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex));
3268 BuildBinaryOpWithImmediate(javascript()->Subtract(feedback));
3271void BytecodeGraphBuilder::VisitMulSmi() {
3272 FeedbackSource feedback = CreateFeedbackSource(
3273 bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex));
3274 BuildBinaryOpWithImmediate(javascript()->Multiply(feedback));
3277void BytecodeGraphBuilder::VisitDivSmi() {
3278 FeedbackSource feedback = CreateFeedbackSource(
3279 bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex));
3280 BuildBinaryOpWithImmediate(javascript()->Divide(feedback));
3283void BytecodeGraphBuilder::VisitModSmi() {
3284 FeedbackSource feedback = CreateFeedbackSource(
3285 bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex));
3286 BuildBinaryOpWithImmediate(javascript()->Modulus(feedback));
3289void BytecodeGraphBuilder::VisitExpSmi() {
3290 FeedbackSource feedback = CreateFeedbackSource(
3291 bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex));
3292 BuildBinaryOpWithImmediate(javascript()->Exponentiate(feedback));
3295void BytecodeGraphBuilder::VisitBitwiseOrSmi() {
3296 FeedbackSource feedback = CreateFeedbackSource(
3297 bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex));
3298 BuildBinaryOpWithImmediate(javascript()->BitwiseOr(feedback));
3301void BytecodeGraphBuilder::VisitBitwiseXorSmi() {
3302 FeedbackSource feedback = CreateFeedbackSource(
3303 bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex));
3304 BuildBinaryOpWithImmediate(javascript()->BitwiseXor(feedback));
3307void BytecodeGraphBuilder::VisitBitwiseAndSmi() {
3308 FeedbackSource feedback = CreateFeedbackSource(
3309 bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex));
3310 BuildBinaryOpWithImmediate(javascript()->BitwiseAnd(feedback));
3313void BytecodeGraphBuilder::VisitShiftLeftSmi() {
3314 FeedbackSource feedback = CreateFeedbackSource(
3315 bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex));
3316 BuildBinaryOpWithImmediate(javascript()->ShiftLeft(feedback));
3319void BytecodeGraphBuilder::VisitShiftRightSmi() {
3320 FeedbackSource feedback = CreateFeedbackSource(
3321 bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex));
3322 BuildBinaryOpWithImmediate(javascript()->ShiftRight(feedback));
3325void BytecodeGraphBuilder::VisitShiftRightLogicalSmi() {
3326 FeedbackSource feedback = CreateFeedbackSource(
3327 bytecode_iterator().GetSlotOperand(kBinaryOperationSmiHintIndex));
3328 BuildBinaryOpWithImmediate(javascript()->ShiftRightLogical(feedback));
3331void BytecodeGraphBuilder::VisitLogicalNot() {
3332 Node* value = environment()->LookupAccumulator();
3333 Node* node = NewNode(
simplified()->BooleanNot(), value);
3334 environment()->BindAccumulator(node);
3337void BytecodeGraphBuilder::VisitToBooleanLogicalNot() {
3339 NewNode(
simplified()->ToBoolean(), environment()->LookupAccumulator());
3340 Node* node = NewNode(
simplified()->BooleanNot(), value);
3341 environment()->BindAccumulator(node);
3344void BytecodeGraphBuilder::VisitTypeOf() {
3345 PrepareEagerCheckpoint();
3346 Node* operand = environment()->LookupAccumulator();
3348 FeedbackSlot slot = bytecode_iterator().GetSlotOperand(0);
3349 JSTypeHintLowering::LoweringResult lowering =
3350 TryBuildSimplifiedUnaryOp(
simplified()->TypeOf(), operand, slot);
3351 if (lowering.IsExit())
return;
3353 Node* node =
nullptr;
3354 if (lowering.IsSideEffectFree()) {
3355 node = lowering.value();
3357 DCHECK(!lowering.Changed());
3358 node = NewNode(
simplified()->TypeOf(), environment()->LookupAccumulator());
3361 environment()->BindAccumulator(node);
3365 PrepareEagerCheckpoint();
3366 Node*
key = environment()->LookupAccumulator();
3368 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
3369 Node* mode =
jsgraph()->ConstantNoHole(
static_cast<int32_t
>(language_mode));
3370 Node* node = NewNode(javascript()->DeleteProperty(),
object,
key, mode);
3371 environment()->BindAccumulator(node, Environment::kAttachFrameState);
3374void BytecodeGraphBuilder::VisitDeletePropertyStrict() {
3378void BytecodeGraphBuilder::VisitDeletePropertySloppy() {
3382void BytecodeGraphBuilder::VisitGetSuperConstructor() {
3383 Node* node = NewNode(javascript()->GetSuperConstructor(),
3384 environment()->LookupAccumulator());
3385 environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0), node,
3386 Environment::kAttachFrameState);
3389void BytecodeGraphBuilder::VisitFindNonDefaultConstructorOrConstruct() {
3390 Node* this_function =
3391 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
3393 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
3395 Node* node = NewNode(javascript()->FindNonDefaultConstructorOrConstruct(),
3404 environment()->BindRegister(bytecode_iterator().GetRegisterOperand(2),
3406 environment()->BindRegistersToProjections(
3407 bytecode_iterator().GetRegisterOperand(2), node,
3408 Environment::kAttachFrameState);
3411void BytecodeGraphBuilder::BuildCompareOp(
const Operator* op) {
3412 DCHECK(JSOperator::IsBinaryWithFeedback(op->
opcode()));
3413 PrepareEagerCheckpoint();
3415 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
3416 Node* right = environment()->LookupAccumulator();
3418 FeedbackSlot slot = bytecode_iterator().GetSlotOperand(1);
3420 TryBuildSimplifiedBinaryOp(op, left, right, slot);
3421 if (lowering.IsExit())
return;
3423 Node* node =
nullptr;
3424 if (lowering.IsSideEffectFree()) {
3425 node = lowering.value();
3427 DCHECK(!lowering.Changed());
3428 DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->
opcode()));
3429 node = NewNode(op, left, right, feedback_vector_node());
3431 environment()->BindAccumulator(node, Environment::kAttachFrameState);
3434void BytecodeGraphBuilder::VisitTestEqual() {
3436 bytecode_iterator().GetSlotOperand(kCompareOperationHintIndex));
3437 BuildCompareOp(javascript()->Equal(feedback));
3440void BytecodeGraphBuilder::VisitTestEqualStrict() {
3441 FeedbackSource feedback = CreateFeedbackSource(
3442 bytecode_iterator().GetSlotOperand(kCompareOperationHintIndex));
3443 BuildCompareOp(javascript()->StrictEqual(feedback));
3446void BytecodeGraphBuilder::VisitTestLessThan() {
3447 FeedbackSource feedback = CreateFeedbackSource(
3448 bytecode_iterator().GetSlotOperand(kCompareOperationHintIndex));
3449 BuildCompareOp(javascript()->LessThan(feedback));
3452void BytecodeGraphBuilder::VisitTestGreaterThan() {
3453 FeedbackSource feedback = CreateFeedbackSource(
3454 bytecode_iterator().GetSlotOperand(kCompareOperationHintIndex));
3455 BuildCompareOp(javascript()->GreaterThan(feedback));
3458void BytecodeGraphBuilder::VisitTestLessThanOrEqual() {
3459 FeedbackSource feedback = CreateFeedbackSource(
3460 bytecode_iterator().GetSlotOperand(kCompareOperationHintIndex));
3461 BuildCompareOp(javascript()->LessThanOrEqual(feedback));
3464void BytecodeGraphBuilder::VisitTestGreaterThanOrEqual() {
3465 FeedbackSource feedback = CreateFeedbackSource(
3466 bytecode_iterator().GetSlotOperand(kCompareOperationHintIndex));
3470void BytecodeGraphBuilder::VisitTestReferenceEqual() {
3472 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
3473 Node* right = environment()->LookupAccumulator();
3475 environment()->BindAccumulator(
result);
3478void BytecodeGraphBuilder::VisitTestIn() {
3479 PrepareEagerCheckpoint();
3480 Node*
object = environment()->LookupAccumulator();
3482 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
3483 FeedbackSource feedback =
3484 CreateFeedbackSource(bytecode_iterator().GetIndexOperand(1));
3485 static_assert(JSHasPropertyNode::ObjectIndex() == 0);
3486 static_assert(JSHasPropertyNode::KeyIndex() == 1);
3487 static_assert(JSHasPropertyNode::FeedbackVectorIndex() == 2);
3488 const Operator* op = javascript()->HasProperty(feedback);
3489 DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
3490 Node* node = NewNode(op,
object,
key, feedback_vector_node());
3491 environment()->BindAccumulator(node, Environment::kAttachFrameState);
3494void BytecodeGraphBuilder::VisitTestInstanceOf() {
3495 FeedbackSource feedback = CreateFeedbackSource(
3496 bytecode_iterator().GetSlotOperand(kCompareOperationHintIndex));
3497 BuildCompareOp(javascript()->InstanceOf(feedback));
3500void BytecodeGraphBuilder::VisitTestUndetectable() {
3501 Node*
object = environment()->LookupAccumulator();
3503 environment()->BindAccumulator(node);
3506void BytecodeGraphBuilder::VisitTestNull() {
3507 Node*
object = environment()->LookupAccumulator();
3510 environment()->BindAccumulator(
result);
3513void BytecodeGraphBuilder::VisitTestUndefined() {
3514 Node*
object = environment()->LookupAccumulator();
3517 environment()->BindAccumulator(
result);
3520void BytecodeGraphBuilder::VisitTestTypeOf() {
3521 Node*
object = environment()->LookupAccumulator();
3523 bytecode_iterator().GetFlag8Operand(0));
3525 switch (literal_flag) {
3526 case interpreter::TestTypeOfFlags::LiteralFlag::kNumber:
3529 case interpreter::TestTypeOfFlags::LiteralFlag::kString:
3532 case interpreter::TestTypeOfFlags::LiteralFlag::kSymbol:
3535 case interpreter::TestTypeOfFlags::LiteralFlag::kBigInt:
3538 case interpreter::TestTypeOfFlags::LiteralFlag::kBoolean:
3540 NewNode(
simplified()->ReferenceEqual(),
object,
3543 NewNode(
simplified()->ReferenceEqual(),
object,
3546 case interpreter::TestTypeOfFlags::LiteralFlag::kUndefined:
3554 case interpreter::TestTypeOfFlags::LiteralFlag::kFunction:
3558 case interpreter::TestTypeOfFlags::LiteralFlag::kObject:
3566 case interpreter::TestTypeOfFlags::LiteralFlag::kOther:
3569 environment()->BindAccumulator(
result);
3572void BytecodeGraphBuilder::BuildCastOperator(
const Operator* js_op) {
3573 Node* value = NewNode(js_op, environment()->LookupAccumulator());
3574 environment()->BindRegister(bytecode_iterator().GetRegisterOperand(0), value,
3575 Environment::kAttachFrameState);
3578void BytecodeGraphBuilder::VisitToName() {
3580 NewNode(javascript()->ToName(), environment()->LookupAccumulator());
3581 environment()->BindAccumulator(value, Environment::kAttachFrameState);
3584void BytecodeGraphBuilder::VisitToObject() {
3585 BuildCastOperator(javascript()->ToObject());
3588void BytecodeGraphBuilder::VisitToString() {
3590 NewNode(javascript()->
ToString(), environment()->LookupAccumulator());
3591 environment()->BindAccumulator(value, Environment::kAttachFrameState);
3594void BytecodeGraphBuilder::VisitToBoolean() {
3596 NewNode(
simplified()->ToBoolean(), environment()->LookupAccumulator());
3597 environment()->BindAccumulator(value, Environment::kAttachFrameState);
3600void BytecodeGraphBuilder::VisitToNumber() {
3601 PrepareEagerCheckpoint();
3602 Node*
object = environment()->LookupAccumulator();
3604 FeedbackSlot slot = bytecode_iterator().GetSlotOperand(0);
3605 JSTypeHintLowering::LoweringResult lowering =
3606 TryBuildSimplifiedToNumber(
object, slot);
3608 Node* node =
nullptr;
3609 if (lowering.IsSideEffectFree()) {
3610 node = lowering.value();
3612 DCHECK(!lowering.Changed());
3613 node = NewNode(javascript()->
ToNumber(),
object);
3616 environment()->BindAccumulator(node, Environment::kAttachFrameState);
3619void BytecodeGraphBuilder::VisitToNumeric() {
3620 PrepareEagerCheckpoint();
3621 Node*
object = environment()->LookupAccumulator();
3625 FeedbackSlot slot = bytecode_iterator().GetSlotOperand(0);
3626 JSTypeHintLowering::LoweringResult lowering =
3627 TryBuildSimplifiedToNumber(
object, slot);
3629 Node* node =
nullptr;
3630 if (lowering.IsSideEffectFree()) {
3631 node = lowering.value();
3633 DCHECK(!lowering.Changed());
3634 node = NewNode(javascript()->ToNumeric(),
object);
3637 environment()->BindAccumulator(node, Environment::kAttachFrameState);
3640void BytecodeGraphBuilder::VisitJump() { BuildJump(); }
3642void BytecodeGraphBuilder::VisitJumpConstant() { BuildJump(); }
3644void BytecodeGraphBuilder::VisitJumpIfTrue() { BuildJumpIfTrue(); }
3646void BytecodeGraphBuilder::VisitJumpIfTrueConstant() { BuildJumpIfTrue(); }
3648void BytecodeGraphBuilder::VisitJumpIfFalse() { BuildJumpIfFalse(); }
3650void BytecodeGraphBuilder::VisitJumpIfFalseConstant() { BuildJumpIfFalse(); }
3652void BytecodeGraphBuilder::VisitJumpIfToBooleanTrue() {
3653 BuildJumpIfToBooleanTrue();
3656void BytecodeGraphBuilder::VisitJumpIfToBooleanTrueConstant() {
3657 BuildJumpIfToBooleanTrue();
3660void BytecodeGraphBuilder::VisitJumpIfToBooleanFalse() {
3661 BuildJumpIfToBooleanFalse();
3664void BytecodeGraphBuilder::VisitJumpIfToBooleanFalseConstant() {
3665 BuildJumpIfToBooleanFalse();
3668void BytecodeGraphBuilder::VisitJumpIfJSReceiver() { BuildJumpIfJSReceiver(); }
3670void BytecodeGraphBuilder::VisitJumpIfJSReceiverConstant() {
3671 BuildJumpIfJSReceiver();
3674void BytecodeGraphBuilder::VisitJumpIfForInDone() { BuildJumpIfForInDone(); }
3676void BytecodeGraphBuilder::VisitJumpIfForInDoneConstant() {
3677 BuildJumpIfForInDone();
3680void BytecodeGraphBuilder::VisitJumpIfNull() {
3681 BuildJumpIfEqual(
jsgraph()->NullConstant());
3684void BytecodeGraphBuilder::VisitJumpIfNullConstant() {
3685 BuildJumpIfEqual(
jsgraph()->NullConstant());
3688void BytecodeGraphBuilder::VisitJumpIfNotNull() {
3689 BuildJumpIfNotEqual(
jsgraph()->NullConstant());
3692void BytecodeGraphBuilder::VisitJumpIfNotNullConstant() {
3693 BuildJumpIfNotEqual(
jsgraph()->NullConstant());
3696void BytecodeGraphBuilder::VisitJumpIfUndefined() {
3700void BytecodeGraphBuilder::VisitJumpIfUndefinedConstant() {
3704void BytecodeGraphBuilder::VisitJumpIfNotUndefined() {
3708void BytecodeGraphBuilder::VisitJumpIfNotUndefinedConstant() {
3712void BytecodeGraphBuilder::VisitJumpIfUndefinedOrNull() {
3714 BuildJumpIfEqual(
jsgraph()->NullConstant());
3717void BytecodeGraphBuilder::VisitJumpIfUndefinedOrNullConstant() {
3719 BuildJumpIfEqual(
jsgraph()->NullConstant());
3722void BytecodeGraphBuilder::VisitJumpLoop() {
3723 BuildIterationBodyStackCheck();
3729 bytecode_iterator().GetJumpTableTargetOffsets();
3734 NewIfValue(entry.case_value);
3735 MergeIntoSuccessorEnvironment(entry.target_offset);
3740void BytecodeGraphBuilder::VisitSwitchOnSmiNoFeedback() {
3741 PrepareEagerCheckpoint();
3743 Node* acc = environment()->LookupAccumulator();
3745 BuildSwitchOnSmi(acc_smi);
3748void BytecodeGraphBuilder::VisitSetPendingMessage() {
3749 Node* previous_message = NewNode(javascript()->LoadMessage());
3750 NewNode(javascript()->StoreMessage(), environment()->LookupAccumulator());
3751 environment()->BindAccumulator(previous_message);
3755 BuildLoopExitsForFunctionExit(liveness);
3758 NewNode(common()->Return(), pop_node, environment()->LookupAccumulator());
3759 MergeControlToLeaveFunction(control);
3762void BytecodeGraphBuilder::VisitReturn() {
3763 BuildReturn(bytecode_analysis().GetInLivenessFor(
3764 bytecode_iterator().current_offset()));
3767void BytecodeGraphBuilder::VisitDebugger() {
3768 PrepareEagerCheckpoint();
3769 Node* call = NewNode(javascript()->Debugger());
3770 environment()->RecordAfterState(call, Environment::kAttachFrameState);
3774#define DEBUG_BREAK(Name, ...) \
3775 void BytecodeGraphBuilder::Visit##Name() { UNREACHABLE(); }
3779void BytecodeGraphBuilder::VisitIncBlockCounter() {
3780 Node* closure = GetFunctionClosure();
3781 Node* coverage_array_slot =
3782 jsgraph()->ConstantNoHole(bytecode_iterator().GetIndexOperand(0));
3785 const Operator* op =
3786 javascript()->CallRuntime(Runtime::kInlineIncBlockCounter);
3788 NewNode(op, closure, coverage_array_slot);
3791void BytecodeGraphBuilder::VisitForInEnumerate() {
3793 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
3794 Node* enumerator = NewNode(javascript()->ForInEnumerate(),
receiver);
3795 environment()->BindAccumulator(enumerator, Environment::kAttachFrameState);
3798void BytecodeGraphBuilder::VisitForInPrepare() {
3799 PrepareEagerCheckpoint();
3800 Node* enumerator = environment()->LookupAccumulator();
3802 FeedbackSlot slot = bytecode_iterator().GetSlotOperand(1);
3803 JSTypeHintLowering::LoweringResult lowering =
3804 TryBuildSimplifiedForInPrepare(enumerator, slot);
3805 if (lowering.IsExit())
return;
3806 DCHECK(!lowering.Changed());
3807 FeedbackSource feedback = CreateFeedbackSource(slot);
3808 Node* node = NewNode(javascript()->ForInPrepare(GetForInMode(slot), feedback),
3809 enumerator, feedback_vector_node());
3810 environment()->BindRegistersToProjections(
3811 bytecode_iterator().GetRegisterOperand(0), node);
3814void BytecodeGraphBuilder::VisitForInNext() {
3815 PrepareEagerCheckpoint();
3817 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
3819 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
3820 int catch_reg_pair_index = bytecode_iterator().GetRegisterOperand(2).index();
3821 Node* cache_type = environment()->LookupRegister(
3822 interpreter::Register(catch_reg_pair_index));
3823 Node* cache_array = environment()->LookupRegister(
3824 interpreter::Register(catch_reg_pair_index + 1));
3828 index = NewNode(common()->TypeGuard(Type::UnsignedSmall()), index);
3830 FeedbackSlot slot = bytecode_iterator().GetSlotOperand(3);
3831 JSTypeHintLowering::LoweringResult lowering = TryBuildSimplifiedForInNext(
3832 receiver, cache_array, cache_type, index, slot);
3833 if (lowering.IsExit())
return;
3835 DCHECK(!lowering.Changed());
3836 FeedbackSource feedback = CreateFeedbackSource(slot);
3838 NewNode(javascript()->ForInNext(GetForInMode(slot), feedback),
receiver,
3839 cache_array, cache_type, index, feedback_vector_node());
3840 environment()->BindAccumulator(node, Environment::kAttachFrameState);
3843void BytecodeGraphBuilder::VisitForInStep() {
3844 PrepareEagerCheckpoint();
3845 interpreter::Register index_reg = bytecode_iterator().GetRegisterOperand(0);
3846 Node* index = environment()->LookupRegister(index_reg);
3847 index = NewNode(
simplified()->SpeculativeSmallIntegerAdd(
3848 NumberOperationHint::kSignedSmall),
3849 index,
jsgraph()->OneConstant());
3850 environment()->BindRegister(index_reg, index, Environment::kAttachFrameState);
3853void BytecodeGraphBuilder::VisitGetIterator() {
3854 PrepareEagerCheckpoint();
3856 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
3857 FeedbackSource load_feedback =
3858 CreateFeedbackSource(bytecode_iterator().GetIndexOperand(1));
3859 FeedbackSource call_feedback =
3860 CreateFeedbackSource(bytecode_iterator().GetIndexOperand(2));
3861 const Operator* op = javascript()->GetIterator(load_feedback, call_feedback);
3863 JSTypeHintLowering::LoweringResult lowering = TryBuildSimplifiedGetIterator(
3864 op,
receiver, load_feedback.slot, call_feedback.slot);
3865 if (lowering.IsExit())
return;
3867 DCHECK(!lowering.Changed());
3868 static_assert(JSGetIteratorNode::ReceiverIndex() == 0);
3869 static_assert(JSGetIteratorNode::FeedbackVectorIndex() == 1);
3870 DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
3871 Node* iterator = NewNode(op,
receiver, feedback_vector_node());
3872 environment()->BindAccumulator(iterator, Environment::kAttachFrameState);
3875void BytecodeGraphBuilder::VisitSuspendGenerator() {
3876 Node* generator = environment()->LookupRegister(
3877 bytecode_iterator().GetRegisterOperand(0));
3878 interpreter::Register first_reg = bytecode_iterator().GetRegisterOperand(1);
3881 int register_count =
3882 static_cast<int>(bytecode_iterator().GetRegisterCountOperand(2));
3883 int parameter_count_without_receiver = bytecode_array().parameter_count() - 1;
3885 Node* suspend_id =
jsgraph()->SmiConstant(
3886 bytecode_iterator().GetUnsignedImmediateOperand(3));
3891 jsgraph()->ConstantNoHole(bytecode_iterator().current_offset() +
3894 const BytecodeLivenessState* liveness = bytecode_analysis().GetInLivenessFor(
3895 bytecode_iterator().current_offset());
3901 int value_input_count = 3 + parameter_count_without_receiver + register_count;
3903 Node** value_inputs = local_zone()->AllocateArray<Node*>(value_input_count);
3904 value_inputs[0] = generator;
3905 value_inputs[1] = suspend_id;
3906 value_inputs[2] =
offset;
3908 int count_written = 0;
3910 for (
int i = 0;
i < parameter_count_without_receiver;
i++) {
3911 value_inputs[3 + count_written++] =
3912 environment()->LookupRegister(bytecode_iterator().
GetParameter(
i));
3916 for (
int i = 0;
i < register_count; ++
i) {
3917 if (liveness ==
nullptr || liveness->RegisterIsLive(
i)) {
3918 int index_in_parameters_and_registers =
3919 parameter_count_without_receiver +
i;
3920 while (count_written < index_in_parameters_and_registers) {
3921 value_inputs[3 + count_written++] =
jsgraph()->OptimizedOutConstant();
3923 value_inputs[3 + count_written++] =
3924 environment()->LookupRegister(interpreter::Register(
i));
3925 DCHECK_EQ(count_written, index_in_parameters_and_registers + 1);
3931 MakeNode(javascript()->GeneratorStore(count_written), 3 + count_written,
3932 value_inputs,
false);
3936 BuildReturn(bytecode_analysis().GetInLivenessFor(
3937 bytecode_iterator().current_offset()));
3940void BytecodeGraphBuilder::BuildSwitchOnGeneratorState(
3942 bool allow_fallthrough_on_executing) {
3943 Node* generator_state = environment()->LookupGeneratorState();
3945 int extra_cases = allow_fallthrough_on_executing ? 2 : 1;
3946 NewSwitch(generator_state,
3947 static_cast<int>(resume_jump_targets.
size() + extra_cases));
3950 NewIfValue(target.suspend_id());
3951 if (target.is_leaf()) {
3953 environment()->BindGeneratorState(
3957 MergeIntoSuccessorEnvironment(target.target_offset());
3967 NewNode(
simplified()->RuntimeAbort(AbortReason::kInvalidJumpTableIndex));
3969 Node* control = NewNode(common()->
Throw());
3970 MergeControlToLeaveFunction(control);
3973 if (allow_fallthrough_on_executing) {
3979 set_environment(
nullptr);
3983void BytecodeGraphBuilder::VisitSwitchOnGeneratorState() {
3985 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
3987 Node* generator_is_undefined =
3988 NewNode(
simplified()->ReferenceEqual(), generator,
3989 jsgraph()->UndefinedConstant());
3991 NewBranch(generator_is_undefined);
3993 SubEnvironment resume_env(
this);
3996 Node* generator_state =
3997 NewNode(javascript()->GeneratorRestoreContinuation(), generator);
3998 environment()->BindGeneratorState(generator_state);
4000 Node* generator_context =
4001 NewNode(javascript()->GeneratorRestoreContext(), generator);
4002 environment()->SetContext(generator_context);
4004 BuildSwitchOnGeneratorState(bytecode_analysis().resume_jump_targets(),
4012void BytecodeGraphBuilder::VisitResumeGenerator() {
4014 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(0));
4015 interpreter::Register first_reg = bytecode_iterator().GetRegisterOperand(1);
4019 const BytecodeLivenessState* liveness = bytecode_analysis().GetOutLivenessFor(
4020 bytecode_iterator().current_offset());
4022 int parameter_count_without_receiver = bytecode_array().parameter_count() - 1;
4026 for (
int i = 0;
i < environment()->register_count(); ++
i) {
4027 if (liveness ==
nullptr || liveness->RegisterIsLive(
i)) {
4028 Node* value = NewNode(javascript()->GeneratorRestoreRegister(
4029 parameter_count_without_receiver +
i),
4031 environment()->BindRegister(interpreter::Register(
i), value);
4036 Node* input_or_debug_pos =
4037 NewNode(javascript()->GeneratorRestoreInputOrDebugPos(), generator);
4038 environment()->BindAccumulator(input_or_debug_pos);
4041void BytecodeGraphBuilder::VisitWide() {
4046void BytecodeGraphBuilder::VisitExtraWide() {
4051void BytecodeGraphBuilder::VisitIllegal() {
4056void BytecodeGraphBuilder::SwitchToMergeEnvironment(
int current_offset) {
4057 auto it = merge_environments_.find(current_offset);
4058 if (it != merge_environments_.end()) {
4059 mark_as_needing_eager_checkpoint(
true);
4060 if (environment() !=
nullptr) {
4061 it->second->Merge(environment(),
4062 bytecode_analysis().GetInLivenessFor(current_offset));
4064 set_environment(it->second);
4068void BytecodeGraphBuilder::BuildLoopHeaderEnvironment(
int current_offset) {
4069 if (bytecode_analysis().IsLoopHeader(current_offset)) {
4070 mark_as_needing_eager_checkpoint(
true);
4072 bytecode_analysis().GetLoopInfoFor(current_offset);
4074 bytecode_analysis().GetInLivenessFor(current_offset);
4077 bool generate_suspend_switch = !resume_jump_targets.empty();
4080 environment()->PrepareForLoop(loop_info.
assignments(), liveness);
4084 merge_environments_[current_offset] = environment()->Copy();
4088 if (generate_suspend_switch) {
4096 environment()->BindGeneratorState(
4102void BytecodeGraphBuilder::MergeIntoSuccessorEnvironment(
int target_offset) {
4103 BuildLoopExitsForBranch(target_offset);
4104 Environment*& merge_environment = merge_environments_[target_offset];
4106 if (merge_environment ==
nullptr) {
4111 merge_environment = environment();
4114 merge_environment->
Merge(
4115 environment(), bytecode_analysis().GetInLivenessFor(target_offset));
4117 set_environment(
nullptr);
4120void BytecodeGraphBuilder::MergeControlToLeaveFunction(
Node* exit) {
4121 exit_controls_.push_back(exit);
4122 set_environment(
nullptr);
4125void BytecodeGraphBuilder::BuildLoopExitsForBranch(
int target_offset) {
4126 int origin_offset = bytecode_iterator().current_offset();
4128 if (target_offset > origin_offset) {
4129 BuildLoopExitsUntilLoop(
4130 bytecode_analysis().GetLoopOffsetFor(target_offset),
4131 bytecode_analysis().GetInLivenessFor(target_offset));
4135void BytecodeGraphBuilder::BuildLoopExitsUntilLoop(
4137 int origin_offset = bytecode_iterator().current_offset();
4138 int current_loop = bytecode_analysis().GetLoopOffsetFor(origin_offset);
4141 loop_offset = std::max(loop_offset, currently_peeled_loop_offset_);
4143 while (loop_offset < current_loop) {
4144 Node* loop_node = merge_environments_[current_loop]->GetControlDependency();
4146 bytecode_analysis().GetLoopInfoFor(current_loop);
4147 environment()->PrepareForLoopExit(loop_node, loop_info.
assignments(),
4153void BytecodeGraphBuilder::BuildLoopExitsForFunctionExit(
4155 BuildLoopExitsUntilLoop(-1, liveness);
4158void BytecodeGraphBuilder::BuildJump() {
4159 MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
4167 MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
4177 MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
4182void BytecodeGraphBuilder::BuildJumpIfEqual(
Node* comperand) {
4183 Node* accumulator = environment()->LookupAccumulator();
4185 NewNode(
simplified()->ReferenceEqual(), accumulator, comperand);
4189void BytecodeGraphBuilder::BuildJumpIfNotEqual(
Node* comperand) {
4190 Node* accumulator = environment()->LookupAccumulator();
4192 NewNode(
simplified()->ReferenceEqual(), accumulator, comperand);
4196void BytecodeGraphBuilder::BuildJumpIfFalse() {
4201 environment()->BindAccumulator(
jsgraph()->FalseConstant());
4202 MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
4205 environment()->BindAccumulator(
jsgraph()->TrueConstant());
4208void BytecodeGraphBuilder::BuildJumpIfTrue() {
4213 environment()->BindAccumulator(
jsgraph()->TrueConstant());
4214 MergeIntoSuccessorEnvironment(bytecode_iterator().GetJumpTargetOffset());
4217 environment()->BindAccumulator(
jsgraph()->FalseConstant());
4220void BytecodeGraphBuilder::BuildJumpIfToBooleanTrue() {
4221 Node* accumulator = environment()->LookupAccumulator();
4226void BytecodeGraphBuilder::BuildJumpIfToBooleanFalse() {
4227 Node* accumulator = environment()->LookupAccumulator();
4232void BytecodeGraphBuilder::BuildJumpIfNotHole() {
4233 Node* accumulator = environment()->LookupAccumulator();
4235 jsgraph()->TheHoleConstant());
4239void BytecodeGraphBuilder::BuildJumpIfJSReceiver() {
4240 Node* accumulator = environment()->LookupAccumulator();
4245void BytecodeGraphBuilder::BuildJumpIfForInDone() {
4248 PrepareEagerCheckpoint();
4250 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(1));
4251 Node* cache_length =
4252 environment()->LookupRegister(bytecode_iterator().GetRegisterOperand(2));
4254 simplified()->SpeculativeNumberEqual(NumberOperationHint::kSignedSmall),
4255 index, cache_length);
4260BytecodeGraphBuilder::TryBuildSimplifiedUnaryOp(
const Operator* op,
4263 Node* effect = environment()->GetEffectDependency();
4264 Node* control = environment()->GetControlDependency();
4266 type_hint_lowering().ReduceUnaryOperation(op, operand, effect, control,
4268 ApplyEarlyReduction(
result);
4273BytecodeGraphBuilder::TryBuildSimplifiedBinaryOp(
const Operator* op,
Node* left,
4276 Node* effect = environment()->GetEffectDependency();
4277 Node* control = environment()->GetControlDependency();
4279 type_hint_lowering().ReduceBinaryOperation(op, left, right, effect,
4281 ApplyEarlyReduction(
result);
4290 Node* effect = environment()->GetEffectDependency();
4291 Node* control = environment()->GetControlDependency();
4293 type_hint_lowering().ReduceForInNextOperation(
4294 receiver, cache_array, cache_type, index, effect, control, slot);
4295 ApplyEarlyReduction(
result);
4300BytecodeGraphBuilder::TryBuildSimplifiedForInPrepare(
Node* enumerator,
4302 Node* effect = environment()->GetEffectDependency();
4303 Node* control = environment()->GetControlDependency();
4305 type_hint_lowering().ReduceForInPrepareOperation(enumerator, effect,
4307 ApplyEarlyReduction(
result);
4312BytecodeGraphBuilder::TryBuildSimplifiedToNumber(
Node* value,
4314 Node* effect = environment()->GetEffectDependency();
4315 Node* control = environment()->GetControlDependency();
4317 type_hint_lowering().ReduceToNumberOperation(value, effect, control,
4319 ApplyEarlyReduction(
result);
4325 Node* effect = environment()->GetEffectDependency();
4326 Node* control = environment()->GetControlDependency();
4328 type_hint_lowering().ReduceCallOperation(op,
args, arg_count, effect,
4330 ApplyEarlyReduction(
result);
4335BytecodeGraphBuilder::TryBuildSimplifiedConstruct(
const Operator* op,
4339 Node* effect = environment()->GetEffectDependency();
4340 Node* control = environment()->GetControlDependency();
4342 type_hint_lowering().ReduceConstructOperation(op,
args, arg_count, effect,
4344 ApplyEarlyReduction(
result);
4349BytecodeGraphBuilder::TryBuildSimplifiedGetIterator(
const Operator* op,
4353 Node* effect = environment()->GetEffectDependency();
4354 Node* control = environment()->GetControlDependency();
4356 type_hint_lowering().ReduceGetIteratorOperation(
4357 op,
receiver, effect, control, load_slot, call_slot);
4358 ApplyEarlyReduction(early_reduction);
4359 return early_reduction;
4363BytecodeGraphBuilder::TryBuildSimplifiedLoadNamed(
const Operator* op,
4365 Node* effect = environment()->GetEffectDependency();
4366 Node* control = environment()->GetControlDependency();
4368 type_hint_lowering().ReduceLoadNamedOperation(op, effect, control, slot);
4369 ApplyEarlyReduction(early_reduction);
4370 return early_reduction;
4374BytecodeGraphBuilder::TryBuildSimplifiedLoadKeyed(
const Operator* op,
4377 Node* effect = environment()->GetEffectDependency();
4378 Node* control = environment()->GetControlDependency();
4380 type_hint_lowering().ReduceLoadKeyedOperation(op,
receiver,
key, effect,
4382 ApplyEarlyReduction(
result);
4387BytecodeGraphBuilder::TryBuildSimplifiedStoreNamed(
const Operator* op,
4390 Node* effect = environment()->GetEffectDependency();
4391 Node* control = environment()->GetControlDependency();
4393 type_hint_lowering().ReduceStoreNamedOperation(op,
receiver, value,
4394 effect, control, slot);
4395 ApplyEarlyReduction(
result);
4400BytecodeGraphBuilder::TryBuildSimplifiedStoreKeyed(
const Operator* op,
4404 Node* effect = environment()->GetEffectDependency();
4405 Node* control = environment()->GetControlDependency();
4407 type_hint_lowering().ReduceStoreKeyedOperation(op,
receiver,
key, value,
4408 effect, control, slot);
4409 ApplyEarlyReduction(
result);
4413void BytecodeGraphBuilder::ApplyEarlyReduction(
4415 if (reduction.IsExit()) {
4416 MergeControlToLeaveFunction(reduction.control());
4417 }
else if (reduction.IsSideEffectFree()) {
4418 environment()->UpdateEffectDependency(reduction.effect());
4419 environment()->UpdateControlDependency(reduction.control());
4421 DCHECK(!reduction.Changed());
4428Node** BytecodeGraphBuilder::EnsureInputBufferSize(
int size) {
4429 if (size > input_buffer_size_) {
4430 size = size + kInputBufferSizeIncrement + input_buffer_size_;
4431 input_buffer_ = local_zone()->AllocateArray<
Node*>(
size);
4432 input_buffer_size_ =
size;
4434 return input_buffer_;
4437void BytecodeGraphBuilder::ExitThenEnterExceptionHandlers(
int current_offset) {
4439 HandlerTable table(bytecode_array().handler_table_address(),
4440 bytecode_array().handler_table_size(),
4444 while (!exception_handlers_.empty()) {
4445 int current_end = exception_handlers_.top().end_offset_;
4446 if (current_offset < current_end)
break;
4447 exception_handlers_.pop();
4451 int num_entries = table.NumberOfRangeEntries();
4452 while (current_exception_handler_ < num_entries) {
4453 int next_start = table.GetRangeStart(current_exception_handler_);
4454 if (current_offset < next_start)
break;
4455 int next_end = table.GetRangeEnd(current_exception_handler_);
4456 int next_handler = table.GetRangeHandler(current_exception_handler_);
4457 int context_register = table.GetRangeData(current_exception_handler_);
4458 exception_handlers_.push(
4459 {next_start, next_end, next_handler, context_register});
4460 current_exception_handler_++;
4464Node* BytecodeGraphBuilder::MakeNode(
const Operator* op,
int value_input_count,
4465 Node*
const* value_inputs,
4470 op->
opcode() == IrOpcode::kParameter,
4471 (
nullptr == cached_parameters_[
static_cast<std::size_t
>(
4474 bool has_context = OperatorProperties::HasContextInput(op);
4475 bool has_frame_state = OperatorProperties::HasFrameStateInput(op);
4483 if (!has_context && !has_frame_state && !has_control && !has_effect) {
4484 result =
graph()->NewNode(op, value_input_count, value_inputs, incomplete);
4486 bool inside_handler = !exception_handlers_.empty();
4487 int input_count_with_deps = value_input_count;
4488 if (has_context) ++input_count_with_deps;
4489 if (has_frame_state) ++input_count_with_deps;
4490 if (has_control) ++input_count_with_deps;
4491 if (has_effect) ++input_count_with_deps;
4492 Node** buffer = EnsureInputBufferSize(input_count_with_deps);
4493 if (value_input_count > 0) {
4496 Node** current_input = buffer + value_input_count;
4498 *current_input++ = OperatorProperties::NeedsExactContext(op)
4499 ? environment()->Context()
4500 : native_context_node();
4502 if (has_frame_state) {
4506 *current_input++ =
jsgraph()->Dead();
4509 *current_input++ = environment()->GetEffectDependency();
4512 *current_input++ = environment()->GetControlDependency();
4514 result =
graph()->NewNode(op, input_count_with_deps, buffer, incomplete);
4516 if (
result->op()->ControlOutputCount() > 0) {
4517 environment()->UpdateControlDependency(
result);
4520 if (
result->op()->EffectOutputCount() > 0) {
4521 environment()->UpdateEffectDependency(
result);
4524 if (!
result->op()->HasProperty(Operator::kNoThrow) && inside_handler) {
4525 int handler_offset = exception_handlers_.top().handler_offset_;
4526 int context_index = exception_handlers_.top().context_register_;
4529 const Operator* if_exception = common()->IfException();
4530 Node* effect = environment()->GetEffectDependency();
4532 Node* context = environment()->LookupRegister(context_register);
4533 environment()->UpdateControlDependency(on_exception);
4534 environment()->UpdateEffectDependency(on_exception);
4535 environment()->BindAccumulator(on_exception);
4536 environment()->SetContext(context);
4537 MergeIntoSuccessorEnvironment(handler_offset);
4538 set_environment(success_env);
4541 if (!
result->op()->HasProperty(Operator::kNoThrow) && inside_handler) {
4542 const Operator* if_success = common()->IfSuccess();
4544 environment()->UpdateControlDependency(on_success);
4547 if (has_effect && !
result->op()->HasProperty(Operator::kNoWrite)) {
4548 mark_as_needing_eager_checkpoint(
true);
4558 Node** buffer = EnsureInputBufferSize(
count + 1);
4560 buffer[
count] = control;
4561 return graph()->NewNode(phi_op,
count + 1, buffer,
true);
4567 Node** buffer = EnsureInputBufferSize(
count + 1);
4569 buffer[
count] = control;
4570 return graph()->NewNode(phi_op,
count + 1, buffer,
true);
4575 int inputs = control->
op()->ControlInputCount() + 1;
4576 if (control->
opcode() == IrOpcode::kLoop) {
4578 const Operator* op = common()->Loop(inputs);
4580 NodeProperties::ChangeOp(control, op);
4581 }
else if (control->
opcode() == IrOpcode::kMerge) {
4583 const Operator* op = common()->Merge(inputs);
4585 NodeProperties::ChangeOp(control, op);
4588 const Operator* op = common()->Merge(inputs);
4589 Node* merge_inputs[] = {control, other};
4590 control =
graph()->NewNode(op,
arraysize(merge_inputs), merge_inputs,
true);
4597 int inputs = control->
op()->ControlInputCount();
4598 if (value->opcode() == IrOpcode::kEffectPhi &&
4599 NodeProperties::GetControlInput(value) == control) {
4601 value->InsertInput(
graph_zone(), inputs - 1, other);
4602 NodeProperties::ChangeOp(value, common()->EffectPhi(inputs));
4603 }
else if (value != other) {
4605 value = NewEffectPhi(inputs, value, control);
4606 value->ReplaceInput(inputs - 1, other);
4613 int inputs = control->
op()->ControlInputCount();
4614 if (value->opcode() == IrOpcode::kPhi &&
4615 NodeProperties::GetControlInput(value) == control) {
4617 value->InsertInput(
graph_zone(), inputs - 1, other);
4618 NodeProperties::ChangeOp(
4620 }
else if (value != other) {
4622 value = NewPhi(inputs, value, control);
4623 value->ReplaceInput(inputs - 1, other);
4628void BytecodeGraphBuilder::UpdateSourceAndBytecodePosition(
int offset) {
4629 if (node_origins_) {
4630 node_origins_->SetCurrentBytecodePosition(
offset);
4632 if (source_position_iterator().done())
return;
4633 if (source_position_iterator().code_offset() ==
offset) {
4635 source_position_iterator().source_position().ScriptOffset(),
4636 start_position_.InliningId()));
4637 source_position_iterator().Advance();
4652 broker, local_zone,
broker->target_native_context(), shared_info,
4653 bytecode, feedback_cell, osr_offset,
jsgraph, invocation_frequency,
4655 tick_counter, observe_node_info);
SimplifiedOperatorBuilder * simplified
#define SHORT_STAR_VISITOR(Name,...)
#define BYTECODE_CASE(name,...)
#define DEBUG_BREAK(Name,...)
#define BUILTIN_CODE(isolate, name)
#define DECLARE_VISIT_BYTECODE(name,...)
#define SHORT_STAR_BYTECODE_LIST(V)
#define DEBUG_BREAK_BYTECODE_LIST(V)
#define BYTECODE_LIST(V, V_TSA)
static constexpr T decode(U value)
constexpr int ToInt() const
static FeedbackSlot ToSlot(intptr_t index)
static constexpr int kHeaderSize
static const int kGeneratorExecuting
static bool IsNonReturning(FunctionId id)
std::reverse_iterator< const T * > const_reverse_iterator
void resize(size_t new_size)
const_reverse_iterator crbegin() const V8_NOEXCEPT
const_reverse_iterator crend() const V8_NOEXCEPT
void push_back(const T &value)
const BytecodeLivenessState * GetInLivenessFor(int offset) const
BytecodeOffset osr_bailout_id() const
void Decorate(Node *node) final
BytecodePositionDecorator(NodeOriginTable *node_origins)
NodeOriginTable * node_origins_
void BindGeneratorState(Node *node)
Node * parameters_state_values_
void BindRegister(interpreter::Register the_register, Node *node, FrameStateAttachmentMode mode=kDontAttachFrameState)
Node * LookupAccumulator() const
void RecordAfterState(Node *node, FrameStateAttachmentMode mode=kDontAttachFrameState)
void UpdateControlDependency(Node *dependency)
CommonOperatorBuilder * common() const
bool StateValuesRequireUpdate(Node **state_values, Node **values, int count)
int register_base() const
Node * GetEffectDependency()
int register_count() const
void PrepareForLoop(const BytecodeLoopAssignments &assignments, const BytecodeLivenessState *liveness)
void SetContext(Node *new_context)
void BindAccumulator(Node *node, FrameStateAttachmentMode mode=kDontAttachFrameState)
void UpdateEffectDependency(Node *dependency)
void BindRegistersToProjections(interpreter::Register first_reg, Node *node, FrameStateAttachmentMode mode=kDontAttachFrameState)
BytecodeGraphBuilder * builder_
int accumulator_base() const
Node * LookupGeneratorState() const
int RegisterToValuesIndex(interpreter::Register the_register) const
int parameter_count() const
Node * control_dependency_
void UpdateStateValues(Node **state_values, Node **values, int count)
void Merge(Environment *other, const BytecodeLivenessState *liveness)
BytecodeGraphBuilder * builder() const
void PrepareForLoopExit(Node *loop, const BytecodeLoopAssignments &assignments, const BytecodeLivenessState *liveness)
Node * GetStateValuesFromCache(Node **values, int count, const BytecodeLivenessState *liveness)
Environment(BytecodeGraphBuilder *builder, int register_count, int parameter_count, interpreter::Register incoming_new_target_or_generator, Node *control_dependency)
Node * GetControlDependency() const
Node * LookupRegister(interpreter::Register the_register) const
Node * Checkpoint(BytecodeOffset bytecode_offset, OutputFrameStateCombine combine, const BytecodeLivenessState *liveness)
const NodeVector * values() const
Node * effect_dependency_
BytecodeGraphBuilder * graph_builder_
ZoneStack< IteratorsStates > saved_states_
OsrIteratorState(BytecodeGraphBuilder *graph_builder)
void RestoreState(int target_offset, int new_parent_offset)
JSOperatorBuilder * javascript() const
FeedbackCellRef const feedback_cell_
OptionalScopeInfoRef TryGetScopeInfo()
void MergeControlToLeaveFunction(Node *exit)
void PrepareFrameStateForOSREntryStackCheck(Node *node)
void BuildJumpIfEqual(Node *comperand)
interpreter::BytecodeArrayIterator const & bytecode_iterator() const
void BuildJumpIfToBooleanTrue()
void BuildLdaLookupContextSlot(ContextKind context_kind, TypeofMode typeof_mode)
JSTypeHintLowering const type_hint_lowering_
Environment * CheckContextExtensions(uint32_t depth)
static const int kInputBufferSizeIncrement
void BuildFunctionEntryStackCheck()
NativeContextRef native_context() const
Zone * local_zone() const
void BuildJumpIfToBooleanFalse()
int currently_peeled_loop_offset_
void BuildLoopExitsUntilLoop(int loop_offset, const BytecodeLivenessState *liveness)
Node * native_context_node_
Node * NewPhi(int count, Node *input, Node *control)
JSTypeHintLowering::LoweringResult TryBuildSimplifiedStoreKeyed(const Operator *op, Node *receiver, Node *key, Node *value, FeedbackSlot slot)
static constexpr int kCompareOperationHintIndex
void BuildCastOperator(const Operator *op)
void BuildLoopExitsForFunctionExit(const BytecodeLivenessState *liveness)
bool skip_tierup_check() const
BytecodeGraphBuilder(JSHeapBroker *broker, Zone *local_zone, NativeContextRef native_context, SharedFunctionInfoRef shared_info, BytecodeArrayRef bytecode, FeedbackCellRef feedback_cell, BytecodeOffset osr_offset, JSGraph *jsgraph, CallFrequency const &invocation_frequency, SourcePositionTable *source_positions, NodeOriginTable *node_origins, int inlining_id, CodeKind code_kind, BytecodeGraphBuilderFlags flags, TickCounter *tick_counter, ObserveNodeInfo const &observe_node_info)
Node * NewIfValue(int32_t value)
Node * MergeEffect(Node *effect, Node *other_effect, Node *control)
const CodeKind code_kind_
void BuildLdaLookupSlot(TypeofMode typeof_mode)
Environment * environment()
FeedbackVectorRef feedback_vector() const
BytecodeAnalysis const bytecode_analysis_
void ExitThenEnterExceptionHandlers(int current_offset)
void PrepareFrameState(Node *node, OutputFrameStateCombine combine)
Environment * environment_
ForInMode GetForInMode(FeedbackSlot slot)
Node * BuildLoadNativeContextField(int index)
void BuildSwitchOnGeneratorState(const ZoneVector< ResumeJumpTarget > &resume_jump_targets, bool allow_fallthrough_on_executing)
JSTypeHintLowering::LoweringResult TryBuildSimplifiedToNumber(Node *input, FeedbackSlot slot)
JSTypeHintLowering::LoweringResult TryBuildSimplifiedStoreNamed(const Operator *op, Node *receiver, Node *value, FeedbackSlot slot)
void BuildHoleCheckAndThrow(Node *condition, Runtime::FunctionId runtime_id, Node *name=nullptr)
Node *const * GetCallArgumentsFromRegisters(Node *callee, Node *receiver, interpreter::Register first_arg, int arg_count)
bool skip_first_stack_check() const
Node * MakeNode(const Operator *op, int value_input_count, Node *const *value_inputs, bool incomplete=false)
StateValuesCache state_values_cache_
void BuildCall(ConvertReceiverMode receiver_mode, std::initializer_list< Node * > args, int slot_id)
void BuildJumpIfNotHole()
void BuildCreateArguments(CreateArgumentsType type)
Node * native_context_node() const
JSTypeHintLowering::LoweringResult TryBuildSimplifiedConstruct(const Operator *op, Node *const *args, int arg_count, FeedbackSlot slot)
void AdvanceIteratorsTo(int bytecode_offset)
JSTypeHintLowering::LoweringResult TryBuildSimplifiedUnaryOp(const Operator *op, Node *operand, FeedbackSlot slot)
SpeculationMode GetSpeculationMode(int slot_id) const
void RemoveBytecodePositionDecorator()
Node * NewBranch(Node *condition, BranchHint hint=BranchHint::kNone)
SourcePositionTableIterator source_position_iterator_
SharedFunctionInfoRef shared_info() const
void BuildCall(ConvertReceiverMode receiver_mode, Node *const *args, size_t arg_count, int slot_id)
TickCounter *const tick_counter_
void SwitchToMergeEnvironment(int current_offset)
BytecodeGraphBuilder(const BytecodeGraphBuilder &)=delete
void BuildBinaryOp(const Operator *op)
ZoneMap< int, Environment * > generator_merge_environments_
void BuildDelete(LanguageMode language_mode)
ZoneVector< Node * > cached_parameters_
Node * NewSwitch(Node *condition, int control_output_count)
BytecodeAnalysis const & bytecode_analysis() const
Node ** EnsureInputBufferSize(int size)
void BuildJumpIfForInDone()
JSTypeHintLowering::LoweringResult TryBuildSimplifiedForInNext(Node *receiver, Node *cache_array, Node *cache_type, Node *index, FeedbackSlot slot)
ZoneMap< int, Environment * > merge_environments_
Zone * graph_zone() const
const FrameStateFunctionInfo * frame_state_function_info() const
void BuildNamedStore(NamedStoreMode store_mode)
JSTypeHintLowering::LoweringResult TryBuildSimplifiedForInPrepare(Node *receiver, FeedbackSlot slot)
const JSTypeHintLowering & type_hint_lowering() const
SimplifiedOperatorBuilder * simplified() const
CallFrequency const invocation_frequency_
void set_currently_peeled_loop_offset(int offset)
void AdvanceToOsrEntryAndPeelLoops()
void MergeIntoSuccessorEnvironment(int target_offset)
SourcePosition const start_position_
interpreter::BytecodeArrayIterator bytecode_iterator_
void AddBytecodePositionDecorator()
void set_current_exception_handler(int index)
SharedFunctionInfoRef const shared_info_
Node * BuildLoadFeedbackCell(int index)
void CreateNativeContextNode()
JSTypeHintLowering::LoweringResult TryBuildSimplifiedLoadNamed(const Operator *op, FeedbackSlot slot)
SetOncePointer< Node > function_closure_
void UpdateSourceAndBytecodePosition(int offset)
BytecodeArrayRef const bytecode_array_
void VisitSingleBytecode()
ZoneVector< Node * > exit_controls_
int current_exception_handler() const
JSHeapBroker * broker() const
static constexpr int kUnaryOperationHintIndex
Node * GetFunctionClosure()
void BuildLoopHeaderEnvironment(int current_offset)
bool needs_eager_checkpoint() const
Isolate * isolate() const
void BuildLdaLookupGlobalSlot(TypeofMode typeof_mode)
BytecodeGraphBuilder & operator=(const BytecodeGraphBuilder &)=delete
SourcePositionTableIterator & source_position_iterator()
void BuildUnaryOp(const Operator *op)
void PrepareFrameState(Node *node, OutputFrameStateCombine combine, BytecodeOffset bailout_id, const BytecodeLivenessState *liveness)
const bool skip_first_stack_and_tierup_check_
Node * NewNode(const Operator *op, Node *n0, Args... nodes)
bool needs_eager_checkpoint_
Node * NewNode(const Operator *op, bool incomplete=false)
Node * MergeControl(Node *control, Node *other)
ObserveNodeInfo const observe_node_info_
void BuildLoopExitsForBranch(int target_offset)
void BuildOSREntryStackCheck()
const Environment * environment() const
void BuildReturn(const BytecodeLivenessState *liveness)
void PrepareEagerCheckpoint()
LocalIsolate *const local_isolate_
CommonOperatorBuilder * common() const
JSTypeHintLowering::LoweringResult TryBuildSimplifiedCall(const Operator *op, Node *const *args, int arg_count, FeedbackSlot slot)
void RemoveMergeEnvironmentsBeforeOffset(int limit_offset)
ZoneStack< ExceptionHandler > exception_handlers_
Node * MergeValue(Node *value, Node *other_value, Node *control)
void BuildJumpIfNot(Node *condition)
BytecodePositionDecorator * decorator_
FeedbackSource CreateFeedbackSource(int slot_id)
void ApplyEarlyReduction(JSTypeHintLowering::LoweringResult reduction)
Node * GetParameter(int index, const char *debug_name_hint=nullptr)
void CreateFeedbackVectorNode()
CodeKind code_kind() const
Environment * CheckContextExtensionsSlowPath(uint32_t depth)
JSTypeHintLowering::LoweringResult TryBuildSimplifiedBinaryOp(const Operator *op, Node *left, Node *right, FeedbackSlot slot)
ref_traits< T >::ref_type MakeRefForConstantForIndexOperand(int operand_index)
void BuildBinaryOpWithImmediate(const Operator *op)
CallFeedbackRelation ComputeCallFeedbackRelation(int slot_id) const
void BuildCompareOp(const Operator *op)
void BuildCallVarArgs(ConvertReceiverMode receiver_mode)
void BuildSwitchOnSmi(Node *condition)
NativeContextRef const native_context_
BytecodeArrayRef bytecode_array() const
Node * BuildLoadGlobal(NameRef name, uint32_t feedback_slot_index, TypeofMode typeof_mode)
CallFrequency ComputeCallFrequency(int slot_id) const
Node * ProcessCallRuntimeArguments(const Operator *call_runtime_op, interpreter::Register receiver, size_t reg_count)
static constexpr int kBinaryOperationHintIndex
interpreter::BytecodeArrayIterator & bytecode_iterator()
NodeOriginTable *const node_origins_
int currently_peeled_loop_offset() const
void BuildIterationBodyStackCheck()
const FrameStateFunctionInfo *const frame_state_function_info_
void BuildJumpIfJSReceiver()
Node * feedback_vector_node() const
void set_environment(Environment *env)
Node *const * ProcessCallVarArgs(ConvertReceiverMode receiver_mode, Node *callee, interpreter::Register first_reg, int arg_count)
static constexpr int kCountOperationHintIndex
Node * NewEffectPhi(int count, Node *input, Node *control)
JSHeapBroker *const broker_
SourcePositionTable *const source_positions_
JSTypeHintLowering::LoweringResult TryBuildSimplifiedGetIterator(const Operator *op, Node *receiver, FeedbackSlot load_slot, FeedbackSlot call_slot)
void mark_as_needing_eager_checkpoint(bool value)
Node *const * GetConstructArgumentsFromRegister(Node *target, Node *new_target, interpreter::Register first_arg, int arg_count)
JSTypeHintLowering::LoweringResult TryBuildSimplifiedLoadKeyed(const Operator *op, Node *receiver, Node *key, FeedbackSlot slot)
Node * feedback_vector_node_
static constexpr int kBinaryOperationSmiHintIndex
void PrepareFrameStateForFunctionEntryStackCheck(Node *node)
JSGraph * jsgraph() const
int current_exception_handler_
Environment * CheckContextExtensionAtDepth(Environment *slow_environment, uint32_t depth)
void BuildJumpIfNotEqual(Node *comperand)
void BuildJumpIf(Node *condition)
FeedbackVectorRef const feedback_vector_
bool RegisterIsLive(int index) const
bool AccumulatorIsLive() const
bool ContainsParameter(int index) const
bool ContainsLocal(int index) const
CallFeedbackContent call_feedback_content() const
const Operator * StateValues(int arguments, SparseInputMask bitmask)
const Operator * FrameState(BytecodeOffset bailout_id, OutputFrameStateCombine state_combine, const FrameStateFunctionInfo *function_info)
ScopeInfoRef scope_info() const
JSOperatorBuilder * javascript() const
SimplifiedOperatorBuilder * simplified() const
Isolate * isolate() const
Node * ConstantNoHole(ObjectRef ref, JSHeapBroker *broker)
static constexpr int GetJSCallNewTargetParamIndex(int parameter_count)
static constexpr int GetJSCallContextParamIndex(int parameter_count)
static constexpr int kJSCallClosureParamIndex
static const int kOsrContextSpillSlotIndex
static const int kOsrAccumulatorRegisterIndex
CommonOperatorBuilder * common() const
static Node * GetEffectInput(Node *node, int index=0)
static void ReplaceContextInput(Node *node, Node *context)
static Node * GetFrameStateInput(Node *node)
static void ReplaceFrameStateInput(Node *node, Node *frame_state)
constexpr IrOpcode::Value opcode() const
const Operator * op() const
void AppendInput(Zone *zone, Node *new_to)
static bool HasFrameStateInput(const Operator *op)
static int GetFrameStateInputCount(const Operator *op)
int ControlInputCount() const
int ValueInputCount() const
int EffectInputCount() const
constexpr Opcode opcode() const
static OutputFrameStateCombine PokeAt(size_t index)
static OutputFrameStateCombine Ignore()
static constexpr int kMinIndex
bool IsInsufficient() const
CallFeedback const & AsCall() const
bool HasOuterScopeInfo() const
bool HasContextExtensionSlot() const
ScopeInfoRef OuterScopeInfo(JSHeapBroker *broker) const
ScopeType scope_type() const
static constexpr int OutputArityForFormalParameterCount(int argc)
void SetStart(Node *start)
Node * NewNode(const Operator *op, int input_count, Node *const *inputs, bool incomplete=false)
int current_offset() const
static ConvertReceiverMode GetReceiverMode(Bytecode bytecode)
constexpr int index() const
constexpr int ToParameterIndex() const
constexpr bool is_current_context() const
constexpr bool is_function_closure() const
constexpr bool is_valid() const
constexpr bool is_parameter() const
static LiteralFlag Decode(uint8_t raw_flag)
CppGraphBuilderImpl & graph_builder_
Handle< Context > context_
base::Vector< const DirectHandle< Object > > args
DirectHandle< Object > new_target
SourcePositionTable * source_positions
ZoneVector< RpoNumber > & result
FunctionLiteral * literal
InstructionOperand source
void Add(RWDigits Z, Digits X, Digits Y)
bool GreaterThanOrEqual(Digits A, Digits B)
void Subtract(RWDigits Z, Digits X, Digits Y)
std::function< Node *(int, GraphAssemblerLabel< 0 > *)> GetParameter
TNode< Oddball > UndefinedConstant(JSGraph *jsgraph)
int ParameterIndexOf(const Operator *const op)
FloatMatcher< double, IrOpcode::kNumberConstant > NumberMatcher
ScopeInfoRef ScopeInfoOf(const Operator *op)
ref_traits< T >::ref_type MakeRefAssumeMemoryFence(JSHeapBroker *broker, Tagged< T > object)
CreateFunctionContextParameters const & CreateFunctionContextParametersOf(Operator const *op)
void BuildGraphFromBytecode(JSHeapBroker *broker, Zone *local_zone, SharedFunctionInfoRef shared_info, BytecodeArrayRef bytecode, FeedbackCellRef feedback_cell, BytecodeOffset osr_offset, JSGraph *jsgraph, CallFrequency const &invocation_frequency, SourcePositionTable *source_positions, NodeOriginTable *node_origins, int inlining_id, CodeKind code_kind, BytecodeGraphBuilderFlags flags, TickCounter *tick_counter, ObserveNodeInfo const &observe_node_info)
ref_traits< T >::ref_type MakeRef(JSHeapBroker *broker, Tagged< T > object)
@ kSkipFirstStackAndTierupCheck
@ kAnalyzeEnvironmentLiveness
@ kBailoutOnUninitialized
T * MakeNode(Args... args)
constexpr int kFunctionEntryBytecodeOffset
constexpr const char * ToString(DeoptimizeKind kind)
bool IsNone(Tagged< FieldType > obj)
bool is_sloppy(LanguageMode language_mode)
bool Is(IndirectHandle< U > value)
LanguageMode GetLanguageModeFromSlotKind(FeedbackSlotKind kind)
int ToNumber(Register reg)
constexpr int kSystemPointerSize
void Terminate(Isolate *isolate)
bool is_strict(LanguageMode language_mode)
V8_EXPORT_PRIVATE FlagValues v8_flags
@ kEnumCacheKeysAndIndices
bool IsLoadGlobalICKind(FeedbackSlotKind kind)
void MemsetPointer(FullObjectSlot start, Tagged< Object > value, size_t counter)
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
#define DCHECK_LE(v1, v2)
#define DCHECK_NOT_NULL(val)
#define DCHECK_IMPLIES(v1, v2)
#define DCHECK_NE(v1, v2)
#define DCHECK_GE(v1, v2)
#define CHECK_EQ(lhs, rhs)
#define DCHECK(condition)
#define DCHECK_LT(v1, v2)
#define DCHECK_EQ(v1, v2)
#define DCHECK_GT(v1, v2)
BytecodeGraphBuilder * builder_
SubEnvironment(BytecodeGraphBuilder *builder)
BytecodeGraphBuilder::Environment * parent_
int parent_offset() const
const ZoneVector< ResumeJumpTarget > & resume_jump_targets() const
BytecodeLoopAssignments & assignments()