48bool HasNumberMaps(JSHeapBroker*
broker, ZoneVector<MapRef>
const& maps) {
49 for (MapRef map : maps) {
50 if (map.IsHeapNumberMap())
return true;
56 for (MapRef map : maps) {
57 if (!map.IsJSArrayMap())
return false;
72 broker->target_native_context().global_object(
broker).object()),
74 broker->target_native_context().global_proxy_object(
broker).object()),
76 shared_zone_(shared_zone),
78 created_strings_(zone) {}
81 switch (node->opcode()) {
82 case IrOpcode::kJSAdd:
84 case IrOpcode::kJSAsyncFunctionEnter:
86 case IrOpcode::kJSAsyncFunctionReject:
88 case IrOpcode::kJSAsyncFunctionResolve:
90 case IrOpcode::kJSGetSuperConstructor:
92 case IrOpcode::kJSFindNonDefaultConstructorOrConstruct:
94 case IrOpcode::kJSInstanceOf:
96 case IrOpcode::kJSHasInPrototypeChain:
98 case IrOpcode::kJSOrdinaryHasInstance:
100 case IrOpcode::kJSPromiseResolve:
102 case IrOpcode::kJSResolvePromise:
104 case IrOpcode::kJSLoadGlobal:
106 case IrOpcode::kJSStoreGlobal:
108 case IrOpcode::kJSLoadNamed:
110 case IrOpcode::kJSLoadNamedFromSuper:
112 case IrOpcode::kJSSetNamedProperty:
114 case IrOpcode::kJSHasProperty:
116 case IrOpcode::kJSLoadProperty:
118 case IrOpcode::kJSSetKeyedProperty:
120 case IrOpcode::kJSDefineKeyedOwnProperty:
122 case IrOpcode::kJSDefineNamedOwnProperty:
124 case IrOpcode::kJSDefineKeyedOwnPropertyInLiteral:
126 case IrOpcode::kJSStoreInArrayLiteral:
128 case IrOpcode::kJSToObject:
130 case IrOpcode::kJSToString:
132 case IrOpcode::kJSGetIterator:
150 return input.length();
164 DCHECK_EQ(IrOpcode::kJSToString, node->opcode());
189 common()->HeapConstant(
broker()->CanonicalPersistentHandle(num_str)));
232 return matcher.HasResolvedValue() && matcher.Ref(
broker).IsString();
235bool IsStringWithNonAccessibleContent(JSHeapBroker*
broker, Node* node) {
237 if (matcher.HasResolvedValue() && matcher.Ref(
broker).IsString()) {
238 StringRef input = matcher.Ref(
broker).AsString();
239 return !input.IsContentAccessible();
247 DCHECK_EQ(IrOpcode::kJSAsyncFunctionEnter, node->opcode());
258 Node* promise = effect =
266 DCHECK(shared.is_compiled());
268 shared.internal_formal_parameter_count_without_receiver() +
269 shared.GetBytecodeArray(
broker()).register_count();
275 Node* value = effect =
277 closure,
receiver, promise, context, effect, control);
284 DCHECK_EQ(IrOpcode::kJSAsyncFunctionReject, node->opcode());
297 async_function_object, effect, control);
303 Node* parameters[] = {promise};
305 jsgraph(), Builtin::kAsyncFunctionLazyDeoptContinuation, context,
306 parameters,
arraysize(parameters), frame_state,
313 debug_event, context, frame_state, effect, control);
320 DCHECK_EQ(IrOpcode::kJSAsyncFunctionResolve, node->opcode());
333 async_function_object, effect, control);
339 Node* parameters[] = {promise};
341 jsgraph(), Builtin::kAsyncFunctionLazyDeoptContinuation, context,
342 parameters,
arraysize(parameters), frame_state,
346 context, frame_state, effect, control);
359 if (left->length() == 0)
return right;
360 if (right->length() == 0)
return left;
370 constexpr int32_t kConstantStringFlattenMaxSize = 100;
372 int32_t length = left->length() + right->length();
373 if (length > kConstantStringFlattenMaxSize) {
396 *left,
broker()->local_isolate_or_isolate()) ||
398 *right,
broker()->local_isolate_or_isolate());
402 const bool result_is_one_byte_string =
403 left->IsOneByteRepresentation() && right->IsOneByteRepresentation();
405 if (result_is_one_byte_string) {
412 ->local_isolate_or_isolate()
419 require_guard ?
broker()->local_isolate_or_isolate() :
nullptr);
421 left->length(), access_guard);
423 flat->GetChars(no_gc, access_guard) + left->length(), 0,
424 right->length(), access_guard);
431 ->local_isolate_or_isolate()
438 require_guard ?
broker()->local_isolate_or_isolate() :
nullptr);
440 left->length(), access_guard);
442 flat->GetChars(no_gc, access_guard) + left->length(), 0,
443 right->length(), access_guard);
450 DCHECK(node->opcode() == IrOpcode::kHeapConstant ||
451 node->opcode() == IrOpcode::kNumberConstant);
452 if (
broker()->IsMainThread()) {
456 if (node->opcode() == IrOpcode::kNumberConstant) {
461 return !IsStringWithNonAccessibleContent(
broker(), node) ||
470 DCHECK_EQ(IrOpcode::kJSAdd, node->opcode());
477 if (!lhs_len || !rhs_len)
return NoChange();
482 (IsStringConstant(
broker(), lhs) || IsStringConstant(
broker(), rhs))) {
507 broker()->CanonicalPersistentHandle(concatenated)));
523 broker()->CanonicalPersistentHandle(concatenated)));
534 DCHECK_EQ(IrOpcode::kJSGetSuperConstructor, node->opcode());
539 if (!
m.HasResolvedValue() || !
m.Ref(
broker()).IsJSFunction()) {
549 if (function_map.is_stable()) {
563 Node* this_function = n.this_function();
565 Node* effect = n.effect();
586 if (!
m.HasResolvedValue() || !
m.Ref(
broker()).IsJSFunction()) {
595 OptionalJSObjectRef last_function;
598 Node* ctor_or_instance;
603 if (!current.IsJSFunction()) {
617 .ClassScopeHasPrivateBrand()) {
626 if (!
dependencies()->DependOnArrayIteratorProtector()) {
629 last_function = current_function;
656 .GetOffsetToPokeAt();
663 n.context(), new_frame_state, effect, control);
680 for (
Edge edge : node->use_edges()) {
681 Node*
const user = edge.from();
683 edge.UpdateTo(effect);
685 edge.UpdateTo(control);
693 Replace(user, ctor_or_instance);
705 JSInstanceOfNode
n(node);
707 Node*
object = n.left();
708 Node* constructor = n.right();
711 Effect effect = n.effect();
718 if (
m.HasResolvedValue() &&
m.Ref(
broker()).IsJSObject()) {
723 if (feedback.IsInsufficient())
return NoChange();
724 receiver = feedback.AsInstanceOf().value();
760 static_assert(n.FeedbackVectorIndex() == 2);
761 node->RemoveInput(n.FeedbackVectorIndex());
767 OptionalJSObjectRef holder = access_info.
holder();
768 bool found_on_proto = holder.has_value();
774 if (!constant.has_value() || !constant->IsHeapObject() ||
775 !constant->AsHeapObject().map(
broker()).is_callable()) {
779 if (found_on_proto) {
786 constructor = access_builder.
BuildCheckValue(constructor, &effect, control,
800 jsgraph(), Builtin::kToBooleanLazyDeoptContinuation, context,
nullptr,
808 node->EnsureInputCount(
graph()->
zone(), 8);
809 node->ReplaceInput(JSCallNode::TargetIndex(), target);
810 node->ReplaceInput(JSCallNode::ReceiverIndex(), constructor);
812 node->ReplaceInput(3, feedback);
813 node->ReplaceInput(4, context);
814 node->ReplaceInput(5, continuation_frame_state);
815 node->ReplaceInput(6, effect);
816 node->ReplaceInput(7, control);
824 for (
Edge edge : node->use_edges()) {
826 edge.UpdateTo(value);
851 for (
MapRef map : receiver_maps) {
860 if (!map.IsJSObjectMap()) {
865 if (map_prototype.equals(prototype)) {
871 if (!map.is_stable() || map.is_dictionary_map()) {
884 OptionalJSObjectRef last_prototype;
892 if (!prototype.IsJSObject() || !prototype.map(
broker()).is_stable()) {
895 last_prototype = prototype.AsJSObject();
910 DCHECK_EQ(IrOpcode::kJSHasInPrototypeChain, node->opcode());
918 if (
m.HasResolvedValue()) {
922 Node* result_in_chain =
925 return Replace(result_in_chain);
934 DCHECK_EQ(IrOpcode::kJSOrdinaryHasInstance, node->opcode());
940 if (!
m.HasResolvedValue())
return NoChange();
942 if (
m.Ref(
broker()).IsJSBoundFunction()) {
948 JSInstanceOfNode::LeftIndex());
951 jsgraph()->ConstantNoHole(function.bound_target_function(
broker()),
953 JSInstanceOfNode::RightIndex());
954 node->InsertInput(
zone(), JSInstanceOfNode::FeedbackVectorIndex(),
960 if (
m.Ref(
broker()).IsJSFunction()) {
968 !function.has_instance_prototype(
broker()) ||
969 function.PrototypeRequiresRuntimeLookup(
broker())) {
989 DCHECK_EQ(IrOpcode::kJSPromiseResolve, node->opcode());
999 if (!
m.HasResolvedValue() ||
1014 Node* promise = effect =
1021 Node* parameters[] = {promise};
1023 jsgraph(), Builtin::kAsyncFunctionLazyDeoptContinuation, context,
1024 parameters,
arraysize(parameters), frame_state,
1028 context, frame_state, effect, control);
1035 DCHECK_EQ(IrOpcode::kJSResolvePromise, node->opcode());
1051 for (
MapRef map : resolution_maps) {
1075 Node* value = effect =
1077 context, effect, control);
1093 FieldAccess access = {
1095 kind,
"PropertyCellValue"};
1116 ObjectRef property_cell_value = property_cell.
value(
broker());
1117 if (property_cell_value.IsPropertyCellHole()) {
1127 if (effect ==
nullptr) {
1143 if (property_cell_value.IsHeapObject() &&
1144 !property_cell_value.AsHeapObject().map(
broker()).is_stable()) {
1159 if (
key !=
nullptr) {
1168 if (lookup_start_object !=
nullptr) {
1174 lookup_start_object, effect, control);
1199 DCHECK(!property_cell_value.IsHeapObject() ||
1200 !property_cell_value.IsPropertyCellHole());
1206 Type property_cell_value_type = Type::NonInternal();
1210 if (property_cell_value.IsSmi()) {
1213 }
else if (property_cell_value.IsHeapNumber()) {
1214 property_cell_value_type = Type::Number();
1217 MapRef property_cell_value_map =
1218 property_cell_value.AsHeapObject().map(
broker());
1219 property_cell_value_type =
1226 if (property_cell_value_map.
is_stable()) {
1228 map = property_cell_value_map;
1233 simplified()->LoadField(ForPropertyCellValue(
1234 representation, property_cell_value_type, map, name)),
1251 simplified()->CheckIf(DeoptimizeReason::kValueMismatch), check,
1260 Type property_cell_value_type;
1262 if (property_cell_value.IsHeapObject()) {
1263 MapRef property_cell_value_map =
1264 property_cell_value.AsHeapObject().map(
broker());
1269 value, effect, control);
1274 value, effect, control);
1275 property_cell_value_type = Type::OtherInternal();
1286 representation, property_cell_value_type,
1287 OptionalMapRef(), name)),
1289 value, effect, control);
1299 Type::NonInternal(), OptionalMapRef(), name)),
1301 value, effect, control);
1326 if (feedback.IsScriptContextSlot()) {
1327 Effect effect = n.effect();
1328 Control control = n.control();
1329 Node* script_context =
1332 if ((
v8_flags.script_context_mutable_heap_number ||
1334 !feedback.immutable()) {
1337 javascript()->LoadScriptContext(0, feedback.slot_index()),
1338 script_context, effect, control);
1342 feedback.immutable()),
1343 script_context, effect);
1347 }
else if (feedback.IsPropertyCell()) {
1350 feedback.property_cell());
1352 DCHECK(feedback.IsMegamorphic());
1360 Node* value = n.value();
1368 if (feedback.IsScriptContextSlot()) {
1369 if (feedback.immutable())
return NoChange();
1370 Node* effect = n.effect();
1371 Node* control = n.control();
1372 Node* script_context =
1374 if (
v8_flags.script_context_mutable_heap_number ||
1377 javascript()->StoreScriptContext(0, feedback.slot_index()), value,
1378 script_context, effect, control);
1382 value, script_context, effect, control);
1386 }
else if (feedback.IsPropertyCell()) {
1389 feedback.property_cell());
1391 DCHECK(feedback.IsMegamorphic());
1399 DCHECK(node->opcode() == IrOpcode::kJSLoadNamed ||
1400 node->opcode() == IrOpcode::kJSLoadProperty);
1402 static_assert(JSLoadNamedNode::ObjectIndex() == 0 &&
1403 JSLoadPropertyNode::ObjectIndex() == 0,
1404 "Assumptions about ObjectIndex have changed, please update "
1418 int16_t range_start =
1427 Node* receiver_map = effect =
1429 lookup_start_object, effect, control);
1432 receiver_map, effect, control);
1434 if (
v8_flags.experimental_embedder_instance_types && range_start != 0) {
1436 Node* diff_to_start =
1438 jsgraph()->ConstantNoHole(range_start));
1444 diff_to_start, range_length);
1446 simplified()->CheckIf(DeoptimizeReason::kWrongInstanceType), check,
1452 jsgraph()->ConstantNoHole(JS_API_OBJECT_TYPE));
1454 simplified()->CheckIf(DeoptimizeReason::kWrongInstanceType), check,
1459 isolate(), Builtin::kCallFunctionTemplate_CheckCompatibleReceiver);
1471 lookup_start_object,
1477 value = effect = control =
1482 value =
InlineApiCall(lookup_start_object, frame_state,
nullptr ,
1483 &effect, &control, function_template_info, source);
1491 DCHECK(node->opcode() == IrOpcode::kJSLoadNamed ||
1492 node->opcode() == IrOpcode::kJSSetNamedProperty ||
1493 node->opcode() == IrOpcode::kJSLoadProperty ||
1494 node->opcode() == IrOpcode::kJSSetKeyedProperty ||
1495 node->opcode() == IrOpcode::kJSDefineNamedOwnProperty ||
1496 node->opcode() == IrOpcode::kJSDefineKeyedOwnPropertyInLiteral ||
1497 node->opcode() == IrOpcode::kJSHasProperty ||
1498 node->opcode() == IrOpcode::kJSLoadNamedFromSuper ||
1499 node->opcode() == IrOpcode::kJSDefineKeyedOwnProperty);
1500 static_assert(JSLoadNamedNode::ObjectIndex() == 0 &&
1501 JSSetNamedPropertyNode::ObjectIndex() == 0 &&
1502 JSLoadPropertyNode::ObjectIndex() == 0 &&
1503 JSSetKeyedPropertyNode::ObjectIndex() == 0 &&
1504 JSDefineNamedOwnPropertyNode::ObjectIndex() == 0 &&
1505 JSSetNamedPropertyNode::ObjectIndex() == 0 &&
1506 JSDefineKeyedOwnPropertyInLiteralNode::ObjectIndex() == 0 &&
1507 JSHasPropertyNode::ObjectIndex() == 0 &&
1508 JSDefineKeyedOwnPropertyNode::ObjectIndex() == 0);
1509 static_assert(JSLoadNamedFromSuperNode::ReceiverIndex() == 0);
1519 Node* lookup_start_object;
1520 if (node->opcode() == IrOpcode::kJSLoadNamedFromSuper) {
1524 lookup_start_object = effect =
1532 if (!
InferMaps(lookup_start_object, effect, &inferred_maps)) {
1533 for (
MapRef map : feedback.maps()) {
1542 if (inferred_maps.
size() == 1) {
1543 MapRef lookup_start_object_map = inferred_maps[0];
1544 if (lookup_start_object_map.equals(
1547 OptionalPropertyCellRef cell =
1549 broker(), feedback.name());
1550 if (!cell.has_value())
return NoChange();
1554 feedback.name(), access_mode,
key, *cell,
1563 for (
MapRef map : inferred_maps) {
1564 if (map.is_deprecated())
continue;
1568 if (InstanceTypeChecker::IsAlwaysSharedSpaceJSObject(
1569 map.instance_type()) &&
1576 access_infos_for_feedback.
push_back(access_info);
1581 access_infos_for_feedback, access_mode, &access_infos)) {
1587 if (
key !=
nullptr) {
1594 Node* if_exception =
nullptr;
1596 if_exceptions = &if_exception_nodes;
1602 if (access_infos.
size() == 1) {
1604 if (
receiver != lookup_start_object) {
1610 lookup_start_object, &effect, control,
1612 feedback.has_deprecated_map_without_migration_target());
1618 lookup_start_object = effect =
1620 lookup_start_object, effect, control);
1627 lookup_start_object = effect =
1629 lookup_start_object, effect, control);
1634 &effect, control) &&
1637 &effect, control)) {
1652 Node* etrue = effect;
1658 feedback.has_deprecated_map_without_migration_target());
1666 feedback.has_deprecated_map_without_migration_target());
1677 lookup_start_object =
receiver = effect =
1679 lookup_start_object, effect, control);
1686 lookup_start_object =
receiver = effect =
1688 lookup_start_object, effect, control);
1699 lookup_start_object,
receiver, value, context, frame_state, effect,
1700 control, feedback.name(), if_exceptions, access_info, access_mode);
1719 Node* receiverissmi_control =
nullptr;
1720 Node* receiverissmi_effect = effect;
1722 if (
receiver == lookup_start_object) {
1724 bool receiverissmi_possible =
false;
1726 if (HasNumberMaps(
broker(), access_info.lookup_start_object_maps())) {
1727 receiverissmi_possible =
true;
1733 if (receiverissmi_possible) {
1738 receiverissmi_effect = effect;
1743 Node* fallthrough_control = control;
1744 for (
size_t j = 0; j < access_infos.
size(); ++j) {
1747 Node* this_lookup_start_object = lookup_start_object;
1749 Effect this_effect = effect;
1750 Control this_control{fallthrough_control};
1758 bool insert_map_guard =
true;
1761 if (j == access_infos.
size() - 1) {
1765 lookup_start_object, &this_effect, this_control,
1766 lookup_start_object_maps,
1767 feedback.has_deprecated_map_without_migration_target());
1768 fallthrough_control =
nullptr;
1773 insert_map_guard =
false;
1777 lookup_start_object_maps.
end(), graph()->
zone());
1778 Node* check = this_effect =
1780 lookup_start_object, this_effect, this_control);
1788 if (HasNumberMaps(
broker(), lookup_start_object_maps)) {
1794 receiverissmi_control);
1796 receiverissmi_effect, this_control);
1797 receiverissmi_effect = receiverissmi_control =
nullptr;
1801 insert_map_guard =
false;
1805 if (insert_map_guard) {
1807 lookup_start_object_maps.
end(), graph()->
zone());
1810 lookup_start_object, this_effect, this_control);
1820 this_lookup_start_object = this_receiver = this_effect =
1822 lookup_start_object, this_effect, this_control);
1824 lookup_start_object_maps)) {
1825 bool receiver_is_lookup_start =
1826 this_lookup_start_object == this_receiver;
1828 receiver_is_lookup_start);
1829 this_lookup_start_object = this_effect =
1831 lookup_start_object, this_effect, this_control);
1832 if (receiver_is_lookup_start) {
1833 this_receiver = this_lookup_start_object;
1836 broker(), lookup_start_object_maps)) {
1837 bool receiver_is_lookup_start =
1838 this_lookup_start_object == this_receiver;
1840 receiver_is_lookup_start);
1841 this_lookup_start_object = this_effect =
1843 lookup_start_object, this_effect, this_control);
1844 if (receiver_is_lookup_start) {
1845 this_receiver = this_lookup_start_object;
1852 this_lookup_start_object, this_receiver, this_value, context,
1853 frame_state, this_effect, this_control, feedback.name(),
1854 if_exceptions, access_info, access_mode);
1872 int const control_count =
static_cast<int>(controls.
size());
1873 if (control_count == 0) {
1875 }
else if (control_count == 1) {
1876 value = values.front();
1877 effect = effects.
front();
1878 control = controls.
front();
1882 values.push_back(control);
1885 control_count + 1, &values.front());
1888 control_count + 1, &effects.
front());
1893 if (!if_exception_nodes.
empty()) {
1895 DCHECK_EQ(if_exceptions, &if_exception_nodes);
1896 int const if_exception_count =
static_cast<int>(if_exceptions->
size());
1898 if_exception_count, &if_exceptions->
front());
1902 if_exception_count + 1, &if_exceptions->
front());
1905 if_exception_count + 1, &if_exceptions->
front());
1921 if (
m.HasResolvedValue()) {
1922 ObjectRef
object =
m.Ref(
broker());
1923 if (
object.IsJSFunction() && name.equals(
broker()->prototype_string())) {
1929 !function.has_instance_prototype(
broker()) ||
1930 function.PrototypeRequiresRuntimeLookup(
broker())) {
1938 }
else if (
object.IsString() && name.equals(
broker()->length_string())) {
1969 Effect effect = n.effect();
1970 Control control = n.control();
1972 Node* iterator_exception_node =
nullptr;
1973 Node* if_exception_merge =
nullptr;
1974 Node* if_exception_effect_phi =
nullptr;
1975 Node* if_exception_phi =
nullptr;
1976 bool has_exception_node =
1978 int exception_node_index = 0;
1979 if (has_exception_node) {
1990 if_exception_merge =
1992 dead_node, dead_node);
1993 if_exception_effect_phi =
1995 dead_node, dead_node, dead_node, if_exception_merge);
1998 dead_node, dead_node, dead_node, if_exception_merge);
2001 if_exception_effect_phi, if_exception_merge);
2003 iterator_exception_node);
2004 if_exception_effect_phi->
ReplaceInput(exception_node_index,
2005 iterator_exception_node);
2007 iterator_exception_node);
2008 exception_node_index++;
2020 Node* lazy_deopt_parameters[] = {
receiver, call_slot, call_feedback};
2022 jsgraph(), Builtin::kGetIteratorWithFeedbackLazyDeoptContinuation,
2023 context, lazy_deopt_parameters,
arraysize(lazy_deopt_parameters),
2025 Node* load_property =
2027 lazy_deopt_frame_state, effect, control);
2028 effect = load_property;
2029 control = load_property;
2032 if (has_exception_node) {
2033 Node* if_exception =
2035 if_exception_merge->
ReplaceInput(exception_node_index, if_exception);
2036 if_exception_phi->
ReplaceInput(exception_node_index, if_exception);
2037 if_exception_effect_phi->
ReplaceInput(exception_node_index, if_exception);
2038 exception_node_index++;
2043 jsgraph()->UndefinedConstant());
2049 Node* effect_not_iterator = effect;
2050 Node* control_not_iterator = if_not_iterator;
2051 Node* call_runtime = effect_not_iterator = control_not_iterator =
2054 receiver, context, frame_state, effect_not_iterator,
2055 control_not_iterator);
2057 if (has_exception_node) {
2059 common()->IfException(), effect_not_iterator, control_not_iterator);
2060 if_exception_merge->
ReplaceInput(exception_node_index, if_exception);
2061 if_exception_phi->
ReplaceInput(exception_node_index, if_exception);
2062 if_exception_effect_phi->
ReplaceInput(exception_node_index, if_exception);
2063 exception_node_index++;
2064 control_not_iterator =
2075 Node* parameters[] = {
receiver, load_property, call_slot, call_feedback};
2077 jsgraph(), Builtin::kCallIteratorWithFeedback, context, parameters,
2080 common()->Checkpoint(), eager_deopt_frame_state, effect, control);
2081 effect = deopt_checkpoint;
2088 : feedback.AsCall().speculation_mode();
2095 jsgraph(), Builtin::kCallIteratorWithFeedbackLazyDeoptContinuation,
2097 Node* call_property = effect = control =
2099 context, call_lazy_deopt_frame_state, effect, control);
2102 if (has_exception_node) {
2103 Node* if_exception =
2105 if_exception_merge->
ReplaceInput(exception_node_index, if_exception);
2106 if_exception_phi->
ReplaceInput(exception_node_index, if_exception);
2107 if_exception_effect_phi->
ReplaceInput(exception_node_index, if_exception);
2108 exception_node_index++;
2116 is_receiver, control);
2119 Node* effect_not_receiver = effect;
2120 Node* control_not_receiver = if_not_receiver;
2121 Node* call_runtime = effect_not_receiver = control_not_receiver =
2124 context, frame_state, effect_not_receiver, control_not_receiver);
2126 if (has_exception_node) {
2128 common()->IfException(), effect_not_receiver, control_not_receiver);
2129 if_exception_merge->
ReplaceInput(exception_node_index, if_exception);
2130 if_exception_phi->
ReplaceInput(exception_node_index, if_exception);
2131 if_exception_effect_phi->
ReplaceInput(exception_node_index, if_exception);
2132 exception_node_index++;
2133 control_not_receiver =
2143 if (has_exception_node) {
2148 for (
Node* input : if_exception_merge->
inputs()) {
2149 DCHECK(!input->IsDead());
2151 for (
Node* input : if_exception_effect_phi->
inputs()) {
2152 DCHECK(!input->IsDead());
2154 for (
Node* input : if_exception_phi->
inputs()) {
2155 DCHECK(!input->IsDead());
2213 if (!
m.HasResolvedValue())
return std::nullopt;
2214 ObjectRef
object =
m.Ref(
broker);
2215 if (!
object.IsJSTypedArray())
return std::nullopt;
2217 if (typed_array.
is_on_heap())
return std::nullopt;
2226 if (root_map.has_value() && !root_map->is_abandoned_prototype_map()) {
2228 std::remove_if(maps->begin(), maps->end(),
2229 [root_map,
this](
MapRef map) {
2230 return map.is_abandoned_prototype_map() ||
2231 !map.FindRootMap(broker()).equals(*root_map);
2243 bool use_inference =
2245 if (!use_inference)
return feedback;
2255 return feedback.Refine(
broker(), inferred_maps);
2261 DCHECK(node->opcode() == IrOpcode::kJSLoadProperty ||
2262 node->opcode() == IrOpcode::kJSSetKeyedProperty ||
2263 node->opcode() == IrOpcode::kJSStoreInArrayLiteral ||
2264 node->opcode() == IrOpcode::kJSDefineKeyedOwnPropertyInLiteral ||
2265 node->opcode() == IrOpcode::kJSHasProperty ||
2266 node->opcode() == IrOpcode::kJSDefineKeyedOwnProperty);
2267 static_assert(JSLoadPropertyNode::ObjectIndex() == 0 &&
2268 JSSetKeyedPropertyNode::ObjectIndex() == 0 &&
2269 JSStoreInArrayLiteralNode::ArrayIndex() == 0 &&
2270 JSDefineKeyedOwnPropertyInLiteralNode::ObjectIndex() == 0 &&
2271 JSHasPropertyNode::ObjectIndex() == 0);
2280 if (feedback.transition_groups().empty())
return NoChange();
2287 receiver->opcode() == IrOpcode::kHeapConstant) {
2290 if (reduction.Changed())
return reduction;
2303 access_infos.
empty()) {
2311 access_info.elements_kind())) {
2326 for (
MapRef receiver_map : access_info.lookup_start_object_maps()) {
2334 !receiver_map.PrototypesElementsDoNotHaveAccessorsOrThrow(
2335 broker(), &prototype_maps)) {
2342 if (InstanceTypeChecker::IsAlwaysSharedSpaceJSObject(
2343 receiver_map.instance_type())) {
2348 for (
MapRef prototype_map : prototype_maps) {
2364 if (access_infos.
size() == 1) {
2376 sources, transition_target)),
2387 access_info, feedback.keyed_mode());
2399 Node* fallthrough_control = control;
2400 for (
size_t j = 0; j < access_infos.
size(); ++j) {
2405 Effect this_effect = effect;
2406 Control this_control{fallthrough_control};
2418 transition_source, transition_target)),
2419 receiver, this_effect, this_control);
2425 if (j == access_infos.
size() - 1) {
2430 fallthrough_control =
nullptr;
2435 Node* check = this_effect =
2437 this_effect, fallthrough_control);
2445 this_effect, this_control);
2450 this_receiver, this_index, this_value, this_effect, this_control,
2451 context, access_info, feedback.keyed_mode());
2460 int const control_count =
static_cast<int>(controls.
size());
2461 if (control_count == 0) {
2463 }
else if (control_count == 1) {
2464 value = values.front();
2465 effect = effects.
front();
2466 control = controls.
front();
2470 values.push_back(control);
2473 control_count + 1, &values.front());
2476 control_count + 1, &effects.
front());
2487 DCHECK(node->opcode() == IrOpcode::kJSLoadProperty ||
2488 node->opcode() == IrOpcode::kJSHasProperty);
2495 if (receiver_ref.IsNull() || receiver_ref.IsUndefined() ||
2507 const uint32_t index =
static_cast<uint32_t
>(mkey.
ResolvedValue());
2508 OptionalObjectRef element;
2510 if (receiver_ref.IsJSObject()) {
2511 JSObjectRef jsobject_ref = receiver_ref.AsJSObject();
2512 OptionalFixedArrayBaseRef elements =
2514 if (elements.has_value()) {
2517 if (!element.has_value() && receiver_ref.IsJSArray()) {
2521 element = receiver_ref.AsJSArray().GetOwnCowElement(
broker(),
2523 if (element.has_value()) {
2528 simplified()->ReferenceEqual(), actual_elements,
2532 DeoptimizeReason::kCowArrayElementsChanged),
2533 check, effect, control);
2537 }
else if (receiver_ref.IsString()) {
2539 receiver_ref.AsString().GetCharAsStringOrUndefined(
broker(), index);
2542 if (element.has_value()) {
2553 if (receiver_ref.IsString()) {
2562 &control, load_mode);
2574 DCHECK(node->opcode() == IrOpcode::kJSLoadProperty ||
2575 node->opcode() == IrOpcode::kJSSetKeyedProperty ||
2576 node->opcode() == IrOpcode::kJSStoreInArrayLiteral ||
2577 node->opcode() == IrOpcode::kJSDefineKeyedOwnPropertyInLiteral ||
2578 node->opcode() == IrOpcode::kJSHasProperty ||
2579 node->opcode() == IrOpcode::kJSLoadNamed ||
2580 node->opcode() == IrOpcode::kJSSetNamedProperty ||
2581 node->opcode() == IrOpcode::kJSDefineNamedOwnProperty ||
2582 node->opcode() == IrOpcode::kJSLoadNamedFromSuper ||
2583 node->opcode() == IrOpcode::kJSDefineKeyedOwnProperty);
2584 DCHECK_GE(node->op()->ControlOutputCount(), 1);
2590 feedback->AsElementAccess().transition_groups().empty()) {
2595 feedback = &feedback->AsElementAccess().Refine(
2601 switch (feedback->kind()) {
2605 DeoptimizeReason::kInsufficientTypeFeedbackForGenericNamedAccess);
2613 node, value, feedback->AsMegaDOMPropertyAccess(), source);
2615 DCHECK_EQ(feedback->AsElementAccess().keyed_mode().access_mode(),
2617 DCHECK_NE(node->opcode(), IrOpcode::kJSLoadNamedFromSuper);
2634 frame_state, effect, control);
2636 node->TrimInputCount(0);
2723 DCHECK_EQ(IrOpcode::kJSLoadProperty, node->opcode());
2733 Node*
object = name.receiver();
2734 Node* cache_type = name.cache_type();
2735 Node* index = name.index();
2736 if (object->opcode() == IrOpcode::kJSToObject) {
2739 bool speculating_object_is_receiver =
false;
2757 speculating_object_is_receiver =
true;
2764 speculating_object_is_receiver) {
2766 Node* receiver_map = effect =
2773 check, effect, control);
2782 descriptor_array, effect, control);
2791 jsgraph()->EmptyFixedArrayConstant()));
2793 simplified()->CheckIf(DeoptimizeReason::kWrongEnumIndices), check, effect,
2800 enum_indices, index, effect, control);
2812 Node* name = n.key();
2814 if (name->opcode() == IrOpcode::kJSForInNext) {
2816 if (reduction.Changed())
return reduction;
2845 Node* lookup_start_object,
Node* context,
Node* frame_state,
Node** effect,
2848 ObjectRef constant = access_info.
constant().value();
2861 if (constant.IsJSFunction()) {
2867 target,
receiver, feedback, context, frame_state, *effect, *control);
2871 if (
receiver != lookup_start_object) {
2878 if (if_exceptions !=
nullptr) {
2880 Node*
const if_exception =
2884 *control = if_success;
2893 ObjectRef constant = access_info.
constant().value();
2896 if (constant.IsJSFunction()) {
2902 target,
receiver, value, feedback, context, frame_state, *effect,
2909 if (if_exceptions !=
nullptr) {
2911 Node*
const if_exception =
2915 *control = if_success;
2926 int const argc = value ==
nullptr ? 0 : 1;
2932 ? Builtin::kCallApiCallbackOptimizedNoProfiling
2933 : Builtin::kCallApiCallbackOptimized);
2943 static_cast<uint32_t
>(
2950 inputs[cursor++] =
code;
2951 inputs[cursor++] = function_reference;
2953 inputs[cursor++] = func_templ;
2956 inputs[cursor++] =
value;
2959 inputs[cursor++] = frame_state;
2960 inputs[cursor++] = *effect;
2961 inputs[cursor++] = *control;
2977 compiler::OptionalObjectRef maybe_callback_data =
2980 if (!maybe_callback_data.has_value()) {
2984 << function_template_info);
2989 int const argc = value ==
nullptr ? 0 : 1;
2993 broker(), function_template_info, argc);
2996 const int input_count = 14;
2997 Node* inputs[input_count];
3002 inputs[cursor++] =
value;
3007 auto call_descriptor = PushRegularApiCallInputs(
3009 function_template_info, inputs, cursor);
3016 simplified()->FastApiCall(c_function, feedback, call_descriptor),
3024 function_template_info, inputs, cursor);
3026 return *effect = *control =
3030std::optional<JSNativeContextSpecialization::ValueEffectControl>
3036 OptionalJSObjectRef holder = access_info.
holder();
3046 value =
jsgraph()->UndefinedConstant();
3054 receiver, receiver_mode, lookup_start_object, context, frame_state,
3055 &effect, &control, if_exceptions, access_info);
3061 cell, effect, control);
3067 lookup_start_object);
3069 if (
receiver != lookup_start_object) {
3076 static_cast<int>(MessageTemplate::kIncompatibleMethodReceiver)),
3078 receiver, context, frame_state, effect, control);
3081 if (if_exceptions !=
nullptr) {
3083 Node*
const if_exception =
3085 Node*
const if_success =
3088 control = if_success;
3095 simplified()->TypedArrayLength(maps[0].elements_kind()),
3096 lookup_start_object);
3105 if (!maybe_value)
return {};
3106 value = maybe_value.value();
3109 name, access_info, lookup_start_object, &effect, &control);
3112 if (value !=
nullptr) {
3115 return std::optional<ValueEffectControl>();
3125 OptionalJSObjectRef holder = access_info.
holder();
3126 if (holder.has_value()) {
3136std::optional<JSNativeContextSpecialization::ValueEffectControl>
3142 switch (access_mode) {
3145 frame_state, effect, control, name,
3146 if_exceptions, access_info);
3152 control, name, if_exceptions, access_info,
3168 OptionalJSObjectRef holder = access_info.
holder();
3169 if (holder.has_value()) {
3182 &control, if_exceptions, access_info);
3198 storage, effect, control);
3203 simplified()->CheckIf(DeoptimizeReason::kStoreToConstant),
3204 jsgraph()->FalseConstant(), effect, control);
3216 "BuildPropertyStore",
3220 switch (field_representation) {
3229 Type::OtherInternal());
3233 a.Store(value_field_access, value);
3234 value = effect = a.Finish();
3246 Type::OtherInternal(),
3249 "BuildPropertyStore",
3259 field_access = value_field_access;
3271 }
else if (field_representation ==
3273 OptionalMapRef field_map = access_info.
field_map();
3274 if (field_map.has_value()) {
3279 value, effect, control);
3283 value, effect, control);
3312 if (transition_map.has_value()) {
3315 MapRef transition_map_ref = transition_map.value();
3332 original_map, storage, effect, control);
3336 storage, value, effect, control);
3347 jsgraph()->ConstantNoHole(transition_map_ref,
broker()), effect,
3350 value, effect, control);
3352 jsgraph()->UndefinedConstant(), effect);
3356 value, effect, control);
3392 DCHECK_EQ(IrOpcode::kJSToObject, node->opcode());
3419 receiver, index, value, effect, control, context, elements_kind,
3436 elements, effect, control);
3440 bool receiver_is_jsarray = HasOnlyJSArrayMaps(
broker(), receiver_maps);
3443 Node* length = effect =
3451 elements, effect, control);
3456 }
else if (keyed_mode.
IsLoad() &&
3471 index, length, effect, control);
3475 Type element_type = Type::NonInternal();
3478 element_type = Type::Number();
3485 element_type, element_machine_type,
3493 element_access.
type =
3510 Node* etrue = effect;
3516 if (
v8_flags.turbo_typer_hardening) {
3522 index, length, etrue, if_true);
3528 elements, index, etrue, if_true);
3547 vtrue, etrue, if_true);
3553 Node* efalse = effect;
3557 vfalse =
jsgraph()->UndefinedConstant();
3563 vtrue, vfalse, control);
3568 index, effect, control);
3582 value, effect, control);
3597 value, effect, control);
3603 value, effect, control);
3612 index, length, effect, control);
3619 Node* efalse = effect;
3622 element_access.
type =
3631 Node* etrue = effect;
3636 index, length, etrue, if_true);
3638 Node* element = etrue =
3640 checked, etrue, if_true);
3649 jsgraph()->TheHoleConstant());
3667 element, etrue, if_true);
3670 vtrue =
jsgraph()->TrueConstant();
3676 vtrue, vfalse, control);
3698 elements, effect, control);
3703 elements, effect, control);
3723 : receiver_is_jsarray
3730 index, limit, effect, control);
3739 elements, index, elements_length, effect, control);
3747 receiver, elements, effect, control);
3751 if (receiver_is_jsarray) {
3757 Node* etrue = effect;
3764 Node* efalse = effect;
3784 elements, index, value, effect, control);
3805 Node* external_pointer;
3809 OptionalJSTypedArrayRef typed_array =
3811 if (typed_array.has_value() &&
3814 if (typed_array->map(
broker()).elements_kind() != elements_kind) {
3820 assembler.Unreachable();
3828 DCHECK(!typed_array->is_on_heap());
3834 base_pointer =
jsgraph()->ZeroConstant();
3842 length = assembler.TypedArrayLength(
3845 std::tie(effect, control) =
3854 base_pointer =
jsgraph()->ZeroConstant();
3862 external_pointer = effect =
3869 if (!
dependencies()->DependOnArrayBufferDetachingProtector()) {
3872 typed_array.has_value()
3883 buffer, effect, control);
3887 simplified()->NumberBitwiseAnd(), buffer_bit_field,
3888 jsgraph()->ConstantNoHole(JSArrayBuffer::WasDetachedBit::kMask)),
3891 simplified()->CheckIf(DeoptimizeReason::kArrayBufferWasDetached), check,
3895 buffer_or_receiver = buffer;
3898 enum Situation { kBoundsCheckDone, kHandleOOB_SmiAndRangeCheckComputed };
3899 Situation situation;
3908 index, effect, control);
3920 assembler.Int32LessThanOrEqual(assembler.Int32Constant(0), index_int32);
3922 assembler.Word32And(check_less_than_length, check_non_negative));
3923 std::tie(effect, control) =
3926 situation = kHandleOOB_SmiAndRangeCheckComputed;
3932 index, length, effect, control);
3933 situation = kBoundsCheckDone;
3942 if (situation == kHandleOOB_SmiAndRangeCheckComputed) {
3949 Node* etrue = effect;
3955 if (
v8_flags.turbo_typer_hardening) {
3961 index, length, etrue, if_true);
3966 simplified()->LoadTypedElement(external_array_type),
3967 buffer_or_receiver, base_pointer, external_pointer, index, etrue,
3972 Node* efalse = effect;
3976 vfalse =
jsgraph()->UndefinedConstant();
3984 vtrue, vfalse, control);
3989 simplified()->LoadTypedElement(external_array_type),
3990 buffer_or_receiver, base_pointer, external_pointer, index, effect,
4004 value, effect, control);
4012 value, effect, control);
4023 if (situation == kHandleOOB_SmiAndRangeCheckComputed) {
4032 Node* etrue = effect;
4037 if (
v8_flags.turbo_typer_hardening) {
4043 index, length, etrue, if_true);
4048 simplified()->StoreTypedElement(external_array_type),
4049 buffer_or_receiver, base_pointer, external_pointer, index, value,
4054 Node* efalse = effect;
4066 simplified()->StoreTypedElement(external_array_type),
4067 buffer_or_receiver, base_pointer, external_pointer, index, value,
4073 if (situation == kHandleOOB_SmiAndRangeCheckComputed) {
4079 value = assembler.MachineSelectIf<
Boolean>(check)
4080 .Then([&]() {
return assembler.TrueConstant(); })
4081 .Else([&]() {
return assembler.FalseConstant(); })
4084 std::tie(effect, control) =
4089 value =
jsgraph()->TrueConstant();
4120 Node* etrue = *effect;
4121 if (
v8_flags.turbo_typer_hardening) {
4126 index, length, etrue, if_true);
4139 vtrue, vfalse, *control);
4145 index, length, *effect, *control);
4166 DCHECK_EQ(map.UnusedPropertyFields(), 0);
4167 int length = map.NextFreePropertyIndex() - map.GetInObjectProperties();
4180 properties, effect, control);
4181 values.push_back(value);
4185 values.push_back(
jsgraph()->UndefinedConstant());
4193 graph()->NewNode(
simplified()->ObjectIsSmi(), properties), properties,
4196 hash, effect, control);
4203 properties, effect, control);
4208 Node* new_length_and_hash =
4212 new_length_and_hash = effect =
4214 new_length_and_hash, effect, control);
4219 Type::OtherInternal());
4232 DCHECK(name.IsUniqueName());
4245 for (
MapRef receiver_map : receiver_maps) {
4246 ObjectRef receiver_prototype = receiver_map.prototype(
broker());
4247 if (!receiver_prototype.IsJSObject() ||
4248 !
broker()->IsArrayOrObjectPrototype(receiver_prototype.AsJSObject())) {
4263 for (
MapRef map : map_set) {
4264 maps->push_back(map);
4270 for (
MapRef map : map_set) {
4271 if (!map.is_stable())
return false;
4273 for (
MapRef map : map_set) {
4274 maps->push_back(map);
4283 if (
m.HasResolvedValue()) {
4286 }
else if (
m.IsJSCreate()) {
4294 return std::nullopt;
4299 Node* map = effect =
4307std::pair<Node*, Node*>
4311 DCHECK(catch_scope->is_outermost());
4313 if (catch_scope->has_handler() &&
4314 catch_scope->has_exceptional_control_flow()) {
4316 Effect handler_effect{
nullptr};
4317 Control handler_control{
nullptr};
4319 &handler_exception, &handler_effect, &handler_control);
4322 handler_effect, handler_control);
#define SBXCHECK_GE(lhs, rhs)
static constexpr int kShift
static V8_EXPORT_PRIVATE Callable CallableFor(Isolate *isolate, Builtin builtin)
int GetStackParameterCount() const
Handle< Code > code() const
CallInterfaceDescriptor descriptor() const
static const uint32_t kMinLength
static ExternalReference Create(const SCTableReference &table_ref)
V8_WARN_UNUSED_RESULT Handle< String > NumberToString(DirectHandle< Object > number, NumberCacheMode mode=NumberCacheMode::kBoth)
V8_WARN_UNUSED_RESULT HandleType< String >::MaybeType NewConsString(HandleType< String > left, HandleType< String > right, AllocationType allocation=AllocationType::kYoung)
Handle< Number > NewNumber(double value)
static V8_INLINE bool InYoungGeneration(Tagged< Object > object)
v8::internal::Factory * factory()
static const int kFieldsAdded
static constexpr uint32_t kMaxElementIndex
static const uint32_t kMaxGap
static constexpr size_t kMaxSizeInHeap
v8::internal::LocalFactory * factory()
static MachineType TypeForRepresentation(const MachineRepresentation &rep, bool isSigned=true)
static constexpr MachineType Float64()
static constexpr MachineType AnyTagged()
static constexpr MachineType TaggedSigned()
static constexpr MachineType TaggedPointer()
static constexpr int SizeFor(int length)
static const int kNoHashSentinel
PropertyCellType cell_type() const
PropertyKind kind() const
bool IsConfigurable() const
constexpr bool IsDouble() const
static bool IsNeeded(Tagged< String > str, LocalIsolate *local_isolate)
static constexpr int kMaxValue
static void WriteToFlat(Tagged< String > source, SinkCharT *sink, uint32_t start, uint32_t length)
static const uint32_t kMaxLength
static TNode UncheckedCast(compiler::Node *node)
void push_back(const T &value)
static FieldAccess ForJSArrayBufferViewBuffer()
static ElementAccess ForFixedArrayElement()
static FieldAccess ForMap(WriteBarrierKind write_barrier=kMapWriteBarrier)
static FieldAccess ForCellValue()
static FieldAccess ForHeapNumberValue()
static FieldAccess ForFixedArraySlot(size_t index, WriteBarrierKind write_barrier_kind=kFullWriteBarrier)
static FieldAccess ForJSObjectPropertiesOrHashKnownPointer()
static FieldAccess ForJSArrayBufferBitField()
static FieldAccess ForFixedArrayLength()
static FieldAccess ForJSArrayLength(ElementsKind elements_kind)
static FieldAccess ForJSAsyncFunctionObjectPromise()
static FieldAccess ForEnumCacheIndices()
static FieldAccess ForMapPrototype()
static FieldAccess ForJSTypedArrayExternalPointer()
static FieldAccess ForMapInstanceType()
static FieldAccess ForMapDescriptors()
static FieldAccess ForPropertyArrayLengthAndHash()
static FieldAccess ForJSTypedArrayBasePointer()
static FieldAccess ForDescriptorArrayEnumCache()
static FieldAccess ForJSObjectElements()
bool ComputeElementAccessInfos(ElementAccessFeedback const &feedback, ZoneVector< ElementAccessInfo > *access_infos) const
bool FinalizePropertyAccessInfos(ZoneVector< PropertyAccessInfo > infos, AccessMode access_mode, ZoneVector< PropertyAccessInfo > *result) const
PropertyAccessInfo FinalizePropertyAccessInfosAsOne(ZoneVector< PropertyAccessInfo > infos, AccessMode access_mode) const
void ReplaceWithValue(Node *node, Node *value, Node *effect=nullptr, Node *control=nullptr)
void MergeControlToEnd(TFGraph *graph, CommonOperatorBuilder *common, Node *node)
static Reduction Replace(Node *node)
bool CanAllocateArray(int length, MapRef map, AllocationType allocation=AllocationType::kYoung)
const Operator * ExternalConstant(const ExternalReference &)
bool DependOnNoProfilingProtector()
void DependOnConstantInDictionaryPrototypeChain(MapRef receiver_map, NameRef property_name, ObjectRef constant, PropertyKind kind)
HeapObjectRef DependOnPrototypeProperty(JSFunctionRef function)
void DependOnNoSlackTrackingChange(MapRef map)
void DependOnGlobalProperty(PropertyCellRef cell)
void DependOnStablePrototypeChain(MapRef receiver_maps, WhereToStart start, OptionalJSObjectRef last_prototype=OptionalJSObjectRef())
void DependOnStablePrototypeChains(ZoneVector< MapRef > const &receiver_maps, WhereToStart start, OptionalJSObjectRef last_prototype=OptionalJSObjectRef())
void DependOnStableMap(MapRef map)
bool DependOnNoElementsProtector()
FeedbackSource const & feedback() const
bool HasOnlyStringMaps(JSHeapBroker *broker) const
KeyedAccessMode keyed_mode() const
ZoneVector< TransitionGroup > const & transition_groups() const
ZoneVector< MapRef > const & lookup_start_object_maps() const
ZoneVector< MapRef > const & transition_sources() const
ElementsKind elements_kind() const
FeedbackSource const & feedback() const
const FrameStateInfo & frame_state_info() const
ZoneVector< const CFunctionInfo * > c_signatures(JSHeapBroker *broker) const
ZoneVector< Address > c_functions(JSHeapBroker *broker) const
IndirectHandle< FunctionTemplateInfo > object() const
Address callback(JSHeapBroker *broker) const
int16_t allowed_receiver_instance_type_range_start() const
int16_t allowed_receiver_instance_type_range_end() const
bool is_signature_undefined(JSHeapBroker *broker) const
OptionalObjectRef callback_data(JSHeapBroker *broker) const
FeedbackSource const & callFeedback() const
FeedbackSource const & loadFeedback() const
void InitializeEffectControl(Node *effect, Node *control)
IndirectHandle< HeapObject > object() const
V8_EXPORT_PRIVATE MapRef map(JSHeapBroker *broker) const
static bool IsConstantOpcode(Value value)
static constexpr int ArityForArgc(int parameters)
static constexpr int ArgumentIndex(int i)
ContextRef context(JSHeapBroker *broker) const
SharedFunctionInfoRef shared(JSHeapBroker *broker) const
void MergeExceptionalPaths(TNode< Object > *exception_out, Effect *effect_out, Control *control_out)
CatchScope * catch_scope() const
Node * outermost_handler() const
JSOperatorBuilder * javascript() const
SimplifiedOperatorBuilder * simplified() const
Node * HeapConstantNoHole(Handle< HeapObject > value)
Isolate * isolate() const
Node * ConstantNoHole(ObjectRef ref, JSHeapBroker *broker)
TNode< Boolean > BooleanConstant(bool is_true)
Node * SmiConstant(int32_t immediate)
LocalIsolate * local_isolate_or_isolate() const
Handle< T > CanonicalPersistentHandle(Tagged< T > object)
ProcessedFeedback const & GetFeedbackForPropertyAccess(FeedbackSource const &source, AccessMode mode, OptionalNameRef static_name)
CompilationDependencies * dependencies() const
ProcessedFeedback const & GetFeedbackForGlobalAccess(FeedbackSource const &source)
ProcessedFeedback const & GetFeedbackForInstanceOf(FeedbackSource const &source)
ProcessedFeedback const & GetFeedbackForCall(FeedbackSource const &source)
PropertyAccessInfo GetPropertyAccessInfo(MapRef map, NameRef name, AccessMode access_mode)
NativeContextRef target_native_context() const
Reduction ReduceJSGetSuperConstructor(Node *node)
Reduction ReduceJSResolvePromise(Node *node)
Node * BuildIndexedStringLoad(Node *receiver, Node *index, Node *length, Node **effect, Node **control, KeyedAccessLoadMode load_mode)
Reduction ReduceNamedAccess(Node *node, Node *value, NamedAccessFeedback const &feedback, AccessMode access_mode, Node *key=nullptr)
Reduction ReduceJSLoadPropertyWithEnumeratedKey(Node *node)
Reduction ReduceJSDefineKeyedOwnPropertyInLiteral(Node *node)
JSOperatorBuilder * javascript() const
Node * BuildExtendPropertiesBackingStore(MapRef map, Node *properties, Node *effect, Node *control)
Reduction ReduceJSFindNonDefaultConstructorOrConstruct(Node *node)
static std::optional< size_t > GetMaxStringLength(JSHeapBroker *broker, Node *node)
Reduction ReduceJSLoadGlobal(Node *node)
Node * BuildCheckEqualsName(NameRef name, Node *value, Node *effect, Node *control)
ValueEffectControl BuildElementAccessForTypedArrayOrRabGsabTypedArray(Node *receiver, Node *index, Node *value, Node *effect, Node *control, Node *context, ElementsKind elements_kind, KeyedAccessMode const &keyed_mode)
Reduction ReducePropertyAccess(Node *node, Node *key, OptionalNameRef static_name, Node *value, FeedbackSource const &source, AccessMode access_mode)
Reduction ReduceJSAdd(Node *node)
Reduction ReduceJSHasProperty(Node *node)
Node * InlineApiCall(Node *receiver, Node *frame_state, Node *value, Node **effect, Node **control, FunctionTemplateInfoRef function_template_info, const FeedbackSource &feedback)
ValueEffectControl BuildElementAccess(Node *receiver, Node *index, Node *value, Node *effect, Node *control, Node *context, ElementAccessInfo const &access_info, KeyedAccessMode const &keyed_mode)
Reduction ReduceJSGetIterator(Node *node)
Reduction ReduceJSAsyncFunctionEnter(Node *node)
Node * BuildLoadPrototypeFromObject(Node *object, Node *effect, Node *control)
std::optional< ValueEffectControl > BuildPropertyAccess(Node *lookup_start_object, Node *receiver, Node *value, Node *context, Node *frame_state, Node *effect, Node *control, NameRef name, ZoneVector< Node * > *if_exceptions, PropertyAccessInfo const &access_info, AccessMode access_mode)
Reduction ReduceMegaDOMPropertyAccess(Node *node, Node *value, MegaDOMPropertyAccessFeedback const &feedback, FeedbackSource const &source)
bool InferMaps(Node *object, Effect effect, ZoneVector< MapRef > *maps) const
JSHeapBroker * broker() const
bool StringCanSafelyBeRead(Node *const node, Handle< String > str)
Reduction ReduceJSDefineKeyedOwnProperty(Node *node)
Reduction ReduceJSLoadNamedFromSuper(Node *node)
Handle< String > Concatenate(Handle< String > left, Handle< String > right)
CompilationDependencies * dependencies() const
Reduction ReduceJSStoreGlobal(Node *node)
InferHasInPrototypeChainResult InferHasInPrototypeChain(Node *receiver, Effect effect, HeapObjectRef prototype)
InferHasInPrototypeChainResult
Reduction ReduceJSStoreInArrayLiteral(Node *node)
void InlinePropertySetterCall(Node *receiver, Node *value, Node *context, Node *frame_state, Node **effect, Node **control, ZoneVector< Node * > *if_exceptions, PropertyAccessInfo const &access_info)
Factory * factory() const
ValueEffectControl BuildPropertyTest(Node *effect, Node *control, PropertyAccessInfo const &access_info)
Reduction ReduceJSPromiseResolve(Node *node)
Handle< String > CreateStringConstant(Node *node)
Node * InlinePropertyGetterCall(Node *receiver, ConvertReceiverMode receiver_mode, Node *lookup_start_object, Node *context, Node *frame_state, Node **effect, Node **control, ZoneVector< Node * > *if_exceptions, PropertyAccessInfo const &access_info)
JSGraph * jsgraph() const
Reduction ReduceJSLoadProperty(Node *node)
JSNativeContextSpecialization(Editor *editor, JSGraph *jsgraph, JSHeapBroker *broker, Flags flags, Zone *zone, Zone *shared_zone)
Reduction ReduceJSLoadNamed(Node *node)
Reduction ReduceElementLoadFromHeapConstant(Node *node, Node *key, AccessMode access_mode, KeyedAccessLoadMode load_mode)
ValueEffectControl BuildPropertyStore(Node *receiver, Node *value, Node *context, Node *frame_state, Node *effect, Node *control, NameRef name, ZoneVector< Node * > *if_exceptions, PropertyAccessInfo const &access_info, AccessMode access_mode)
Reduction ReduceEagerDeoptimize(Node *node, DeoptimizeReason reason)
ZoneUnorderedSet< IndirectHandle< String >, IndirectHandle< String >::hash, IndirectHandle< String >::equal_to > created_strings_
CommonOperatorBuilder * common() const
Reduction ReduceJSInstanceOf(Node *node)
Isolate * isolate() const
Reduction ReduceJSSetNamedProperty(Node *node)
void RemoveImpossibleMaps(Node *object, ZoneVector< MapRef > *maps) const
std::pair< Node *, Node * > ReleaseEffectAndControlFromAssembler(JSGraphAssembler *assembler)
Reduction ReduceJSToString(Node *node)
Reduction ReduceJSToObject(Node *node)
std::optional< ValueEffectControl > BuildPropertyLoad(Node *lookup_start_object, Node *receiver, Node *context, Node *frame_state, Node *effect, Node *control, NameRef name, ZoneVector< Node * > *if_exceptions, PropertyAccessInfo const &access_info)
SimplifiedOperatorBuilder * simplified() const
Reduction ReduceElementAccess(Node *node, Node *index, Node *value, ElementAccessFeedback const &feedback)
@ kBailoutOnUninitialized
Reduction ReduceJSDefineNamedOwnProperty(Node *node)
Reduction ReduceJSHasInPrototypeChain(Node *node)
OptionalMapRef InferRootMap(Node *object) const
NativeContextRef native_context() const
Reduction ReduceJSSetKeyedProperty(Node *node)
Reduction ReduceJSAsyncFunctionReject(Node *node)
Reduction ReduceElementAccessOnString(Node *node, Node *index, Node *value, KeyedAccessMode const &keyed_mode)
ElementAccessFeedback const & TryRefineElementAccessFeedback(ElementAccessFeedback const &feedback, Node *receiver, Effect effect) const
bool CanTreatHoleAsUndefined(ZoneVector< MapRef > const &receiver_maps)
Reduction Reduce(Node *node) final
Reduction ReduceJSAsyncFunctionResolve(Node *node)
Reduction ReduceGlobalAccess(Node *node, Node *lookup_start_object, Node *receiver, Node *value, NameRef name, AccessMode access_mode, Node *key, PropertyCellRef property_cell, Node *effect=nullptr)
Reduction ReduceJSOrdinaryHasInstance(Node *node)
OptionalObjectRef GetOwnFastConstantDataProperty(JSHeapBroker *broker, Representation field_representation, FieldIndex index, CompilationDependencies *dependencies) const
OptionalObjectRef GetOwnConstantElement(JSHeapBroker *broker, FixedArrayBaseRef elements_ref, uint32_t index, CompilationDependencies *dependencies) const
OptionalFixedArrayBaseRef elements(JSHeapBroker *broker, RelaxedLoadTag) const
const Operator * Call(size_t arity, CallFrequency const &frequency=CallFrequency(), FeedbackSource const &feedback=FeedbackSource(), ConvertReceiverMode convert_mode=ConvertReceiverMode::kAny, SpeculationMode speculation_mode=SpeculationMode::kDisallowSpeculation, CallFeedbackRelation feedback_relation=CallFeedbackRelation::kUnrelated)
const Operator * LoadNamed(NameRef name, FeedbackSource const &feedback)
AccessMode access_mode() const
KeyedAccessStoreMode store_mode() const
KeyedAccessLoadMode load_mode() const
static CallDescriptor * GetStubCallDescriptor(Zone *zone, const CallInterfaceDescriptor &descriptor, int stack_parameter_count, CallDescriptor::Flags flags, Operator::Properties properties=Operator::kNoProperties, StubCallMode stub_mode=StubCallMode::kCallCodeObject)
const FeedbackSource & feedback() const
CommonOperatorBuilder * common() const
Node * PointerConstant(intptr_t value)
Node * Int32Constant(int32_t value)
V8_WARN_UNUSED_RESULT bool RelyOnMapsViaStability(CompilationDependencies *dependencies)
V8_WARN_UNUSED_RESULT ZoneRefSet< Map > const & GetMaps()
V8_WARN_UNUSED_RESULT Reduction NoChange()
V8_WARN_UNUSED_RESULT bool HaveMaps() const
V8_WARN_UNUSED_RESULT bool AllOfInstanceTypesAreJSReceiver() const
V8_WARN_UNUSED_RESULT bool AnyOfInstanceTypesAre(InstanceType type) const
MapRef FindRootMap(JSHeapBroker *broker) const
HeapObjectRef prototype(JSHeapBroker *broker) const
HeapObjectRef GetBackPointer(JSHeapBroker *broker) const
ElementsKind elements_kind() const
int UnusedPropertyFields() const
bool IsUniqueName() const
IndirectHandle< Name > object() const
FeedbackSource const & feedback() const
static void ChangeOp(Node *node, const Operator *new_op)
static void ReplaceEffectInput(Node *node, Node *effect, int index=0)
static bool IsControlEdge(Edge edge)
static OptionalMapRef GetJSCreateMap(JSHeapBroker *broker, Node *receiver)
static Node * GetEffectInput(Node *node, int index=0)
static Node * GetContextInput(Node *node)
static bool IsValueEdge(Edge edge)
static Node * GetFrameStateInput(Node *node)
static Node * GetValueInput(Node *node, int index)
static bool IsEffectEdge(Edge edge)
static void ReplaceValueInput(Node *node, Node *value, int index)
static Node * FindFrameStateBefore(Node *node, Node *unreachable_sentinel)
static bool NoObservableSideEffectBetween(Node *effect, Node *dominator)
static bool IsExceptionalCall(Node *node, Node **out_exception=nullptr)
static InferMapsResult InferMapsUnsafe(JSHeapBroker *broker, Node *receiver, Effect effect, ZoneRefSet< Map > *maps_out)
static Node * GetControlInput(Node *node, int index=0)
const Operator * op() const
void ReplaceInput(int index, Node *new_to)
Node * InputAt(int index) const
static OutputFrameStateCombine PokeAt(size_t index)
bool IsInsufficient() const
GlobalAccessFeedback const & AsGlobalAccess() const
static MachineRepresentation ConvertRepresentation(Representation representation)
bool TryBuildNumberCheck(JSHeapBroker *broker, ZoneVector< MapRef > const &maps, Node **receiver, Effect *effect, Control control)
Node * BuildCheckValue(Node *receiver, Effect *effect, Control control, ObjectRef value)
bool TryBuildStringCheck(JSHeapBroker *broker, ZoneVector< MapRef > const &maps, Node **receiver, Effect *effect, Control control)
void BuildCheckMaps(Node *object, Effect *effect, Control control, ZoneVector< MapRef > const &maps, bool has_deprecated_map_without_migration_target=false)
std::optional< Node * > FoldLoadDictPrototypeConstant(PropertyAccessInfo const &access_info)
Node * BuildLoadDataField(NameRef name, PropertyAccessInfo const &access_info, Node *lookup_start_object, Node **effect, Node **control)
Representation field_representation() const
bool IsFastAccessorConstant() const
bool IsStringLength() const
ConstFieldInfo GetConstFieldInfo() const
OptionalMapRef transition_map() const
bool IsDictionaryProtoAccessorConstant() const
bool IsDictionaryProtoDataConstant() const
bool IsStringWrapperLength() const
bool IsTypedArrayLength() const
OptionalJSObjectRef holder() const
FieldIndex field_index() const
ZoneVector< MapRef > const & lookup_start_object_maps() const
bool HasDictionaryHolder() const
bool IsFastDataConstant() const
bool IsModuleExport() const
bool HasTransitionMap() const
OptionalObjectRef constant() const
OptionalMapRef field_map() const
void RecordDependencies(CompilationDependencies *dependencies)
FeedbackSource const & feedback() const
V8_WARN_UNUSED_RESULT bool Cache(JSHeapBroker *broker) const
PropertyDetails property_details() const
ObjectRef value(JSHeapBroker *broker) const
static Reduction Changed(Node *node)
static Reduction NoChange()
Reduction FollowedBy(Reduction next) const
const Operator * CheckEqualsSymbol()
const Operator * CheckEqualsInternalizedString()
FeedbackSource const & feedback() const
Node * NewNode(const Operator *op, int input_count, Node *const *inputs, bool incomplete=false)
static Type Union(Type type1, Type type2, Zone *zone)
static Type For(MapRef type, JSHeapBroker *broker)
static Type SignedSmall()
static UseInfo TruncatingWord32()
JSHeapBroker *const broker_
DirectHandle< Object > new_target
std::optional< TNode< JSArray > > a
#define TRACE_BROKER_MISSING(broker, x)
ZoneVector< RpoNumber > & result
MovableLabel continuation
FastApiCallFunction GetFastApiCallTarget(JSHeapBroker *broker, FunctionTemplateInfoRef function_template_info, size_t arg_count)
V8_INLINE const Operation & Get(const Graph &graph, OpIndex index)
bool HasOnlyNonResizableTypedArrayMaps(JSHeapBroker *broker, ZoneVector< MapRef > const &maps)
bool HasOnlyStringMaps(JSHeapBroker *broker, ZoneVector< MapRef > const &maps)
FrameState CloneFrameState(JSGraph *jsgraph, FrameState frame_state, OutputFrameStateCombine changed_state_combine)
size_t ProjectionIndexOf(const Operator *const op)
@ kUseEnumCacheKeysAndIndices
bool IsAnyStore(AccessMode mode)
@ kConvertStringAndMinusZero
bool HasOnlyStringWrapperMaps(JSHeapBroker *broker, ZoneVector< MapRef > const &maps)
const FrameStateInfo & FrameStateInfoOf(const Operator *op)
FrameState CreateStubBuiltinContinuationFrameState(JSGraph *jsgraph, Builtin name, Node *context, Node *const *parameters, int parameter_count, Node *outer_frame_state, ContinuationFrameStateMode mode, const wasm::CanonicalSig *signature)
HeapConstantNoHole(BUILTIN_CODE(isolate(), AllocateInOldGeneration))) DEFINE_GETTER(ArrayConstructorStubConstant
ExternalArrayType GetArrayTypeFromElementsKind(ElementsKind kind)
ref_traits< T >::ref_type MakeRef(JSHeapBroker *broker, Tagged< T > object)
HeapObjectMatcherImpl< IrOpcode::kHeapConstant > HeapObjectMatcher
bool HasOnlyJSArrayMaps(base::Vector< const compiler::MapRef > maps)
bool StoreModeHandlesCOW(KeyedAccessStoreMode store_mode)
bool StoreModeCanGrow(KeyedAccessStoreMode store_mode)
constexpr bool IsHoleyElementsKind(ElementsKind kind)
bool IsSpecialReceiverInstanceType(InstanceType instance_type)
bool IsTypedArrayElementsKind(ElementsKind kind)
bool IsRabGsabTypedArrayElementsKind(ElementsKind kind)
constexpr bool IsSmiElementsKind(ElementsKind kind)
constexpr int kMaxDoubleStringLength
too high values may cause the compiler to set high thresholds for inlining to as much as possible avoid inlined allocation of objects that cannot escape trace load stores from virtual maglev objects use TurboFan fast string builder analyze liveness of environment slots and zap dead values trace TurboFan load elimination emit data about basic block usage in builtins to this enable builtin reordering when run mksnapshot flag for emit warnings when applying builtin profile data verify register allocation in TurboFan randomly schedule instructions to stress dependency tracking enable store store elimination in TurboFan rewrite far to near simulate GC compiler thread race related to allow float parameters to be passed in simulator mode JS Wasm Run additional turbo_optimize_inlined_js_wasm_wrappers enable experimental feedback collection in generic lowering enable Turboshaft s WasmLoadElimination enable Turboshaft s low level load elimination for JS enable Turboshaft s escape analysis for string concatenation use enable Turbolev features that we want to ship in the not too far future trace individual Turboshaft reduction steps trace intermediate Turboshaft reduction steps invocation count threshold for early optimization Enables optimizations which favor memory size over execution speed Enables sampling allocation profiler with X as a sample interval min size of a semi the new space consists of two semi spaces max size of the Collect garbage after Collect garbage after keeps maps alive for< n > old space garbage collections print one detailed trace line in name
bool IsSimpleMapChangeTransition(ElementsKind from_kind, ElementsKind to_kind)
bool IsSmiOrObjectElementsKind(ElementsKind kind)
DONT_OVERRIDE DISABLE_ALLOCATION_SITES HOLEY_ELEMENTS
bool IsFastElementsKind(ElementsKind kind)
DONT_OVERRIDE DISABLE_ALLOCATION_SITES DISABLE_ALLOCATION_SITES HOLEY_DOUBLE_ELEMENTS
bool IsHoleyOrDictionaryElementsKind(ElementsKind kind)
bool StoreModeIgnoresTypeArrayOOB(KeyedAccessStoreMode store_mode)
V8_EXPORT_PRIVATE FlagValues v8_flags
@ kExternalUint8ClampedArray
@ kExternalBigUint64Array
too high values may cause the compiler to set high thresholds for inlining to as much as possible avoid inlined allocation of objects that cannot escape trace load stores from virtual maglev objects use TurboFan fast string builder analyze liveness of environment slots and zap dead values trace TurboFan load elimination emit data about basic block usage in builtins to this enable builtin reordering when run mksnapshot flag for emit warnings when applying builtin profile data verify register allocation in TurboFan randomly schedule instructions to stress dependency tracking enable store store elimination in TurboFan rewrite far to near simulate GC compiler thread race related to allow float parameters to be passed in simulator mode JS Wasm Run additional turbo_optimize_inlined_js_wasm_wrappers enable experimental feedback collection in generic lowering enable Turboshaft s WasmLoadElimination enable Turboshaft s low level load elimination for JS enable Turboshaft s escape analysis for string concatenation use enable Turbolev features that we want to ship in the not too far future trace individual Turboshaft reduction steps trace intermediate Turboshaft reduction steps invocation count threshold for early optimization Enables optimizations which favor memory size over execution speed Enables sampling allocation profiler with X as a sample interval min size of a semi the new space consists of two semi spaces max size of the Collect garbage after Collect garbage after keeps maps alive for< n > old space garbage collections print one detailed trace line in allocation gc speed threshold for starting incremental marking via a task in percent of available threshold for starting incremental marking immediately in percent of available Use a single schedule for determining a marking schedule between JS and C objects schedules the minor GC task with kUserVisible priority max worker number of concurrent for NumberOfWorkerThreads start background threads that allocate memory concurrent_array_buffer_sweeping use parallel threads to clear weak refs in the atomic pause trace progress of the incremental marking trace object counts and memory usage report a tick only when allocated zone memory changes by this amount TracingFlags::gc_stats TracingFlags::gc_stats track native contexts that are expected to be garbage collected verify heap pointers before and after GC memory reducer runs GC with ReduceMemoryFootprint flag Maximum number of memory reducer GCs scheduled Old gen GC speed is computed directly from gc tracer counters Perform compaction on full GCs based on V8 s default heuristics Perform compaction on every full GC Perform code space compaction when finalizing a full GC with stack Stress GC compaction to flush out bugs with moving objects flush of baseline code when it has not been executed recently Use time base code flushing instead of age Use a progress bar to scan large objects in increments when incremental marking is active force incremental marking for small heaps and run it more often force marking at random points between and force scavenge at random points between and reclaim otherwise unreachable unmodified wrapper objects when possible less compaction in non memory reducing mode use high priority threads for concurrent Marking Test mode only flag It allows an unit test to select evacuation candidates use incremental marking for CppHeap cppheap_concurrent_marking c value for membalancer A special constant to balance between memory and space tradeoff The smaller the more memory it uses enable use of SSE4 instructions if available enable use of AVX VNNI instructions if available enable use of POPCNT instruction if available force all emitted branches to be in long enable use of partial constant none
SharedFunctionInfo::HasStaticPrivateMethodsOrAccessorsBit SharedFunctionInfo::MaglevCompilationFailedBit SharedFunctionInfo::FunctionSyntaxKindBits SharedFunctionInfo::HasDuplicateParametersBit requires_instance_members_initializer
bool IsTypedArrayOrRabGsabTypedArrayElementsKind(ElementsKind kind)
@ kDefaultDerivedConstructor
@ kDefaultBaseConstructor
bool LoadModeHandlesHoles(KeyedAccessLoadMode load_mode)
constexpr bool IsDoubleElementsKind(ElementsKind kind)
constexpr uint32_t kMaxUInt32
bool LoadModeHandlesOOB(KeyedAccessLoadMode load_mode)
static constexpr RelaxedLoadTag kRelaxedLoad
#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 DCHECK(condition)
#define DCHECK_EQ(v1, v2)
IndirectHandle< FeedbackVector > vector
WriteBarrierKind write_barrier_kind
ConstFieldInfo const_field_info
bool IsInRange(const T &low, const T &high) const
HeapObjectRef Ref(JSHeapBroker *broker) const
const T & ResolvedValue() const
bool HasResolvedValue() const
#define OFFSET_OF_DATA_START(Type)