30 Label* if_may_have_side_effects,
Label* if_exception,
33 CSA_DCHECK(
this, Word32BinaryNot(IsHashTableHole(key_value)));
35 TorqueStructKeyValuePair pair =
36 if_may_have_side_effects !=
nullptr
37 ? LoadKeyValuePairNoSideEffects(context, key_value,
38 if_may_have_side_effects)
39 : LoadKeyValuePair(context, key_value);
42 Call(context, add_function, collection, key_n, value_n);
45 Call(context, add_function, collection, key_value);
55 enum Mode { kSlow, kFastJSArray, kFastCollection };
59 Label if_fast_js_array(
this), allocate_table(
this);
67 GotoIf(IsFastJSArrayWithNoCustomIteration(context, initial_entries),
71 variant, initial_entries, context, &var_entries_table,
72 &var_at_least_space_for, &allocate_table);
74 Goto(&allocate_table);
76 Goto(&allocate_table);
78 BIND(&if_fast_js_array);
82 var_at_least_space_for =
90 Goto(&allocate_table);
94 Label exit(
this), from_fast_jsarray(
this), from_fast_collection(
this),
96 BIND(&allocate_table);
103 &from_fast_collection);
106 &from_fast_jsarray, &slow_loop);
108 BIND(&from_fast_jsarray);
115 CSA_DCHECK(
this, IsFastJSArrayWithNoCustomIteration(
116 context, initial_entries_jsarray));
123 this, &if_exception_during_fast_iteration, &var_exception);
125 variant, context,
native_context, collection, initial_entries_jsarray,
126 &if_may_have_side_effects, var_index);
131 BIND(&if_may_have_side_effects);
135 Label if_not_modified(
this), if_modified(
this);
138 Goto(&if_not_modified);
141 BIND(&if_not_modified);
144 LoadMap(initial_entries_jsarray)));
147 Goto(&allocate_table);
149 BIND(&if_exception_during_fast_iteration);
157 var_iterator_object = CreateArrayIterator(
164 BIND(&from_fast_collection);
167 var_entries_table.value());
175 &if_exception, &var_iterator_object, &var_exception);
183 TorqueStructIteratorRecord iterator = {var_iterator_object.value(), {}};
184 IteratorCloseOnException(context, iterator.object);
185 CallRuntime(Runtime::kReThrowWithMessage, context, var_exception.value(),
202 CSA_DCHECK(
this, IsFastJSArrayWithNoCustomIteration(context, fast_jsarray));
211 Label exit(
this), if_doubles(
this), if_smiorobjects(
this);
215 BIND(&if_smiorobjects);
221 if_may_have_side_effects);
241 ThrowTypeError(context, MessageTemplate::kIteratorValueNotAnObject,
270 Label exit(
this), loop(
this);
274 TorqueStructIteratorRecord iterator =
276 *var_iterator_object = iterator.object;
278 CSA_DCHECK(
this, Word32BinaryNot(IsUndefined(iterator.object)));
281 LoadContextElement(
native_context, Context::ITERATOR_RESULT_MAP_INDEX));
287 context, iterator, &exit, fast_iterator_result_map);
289 context, next, fast_iterator_result_map);
291 nullptr, if_exception, var_exception);
301 return RootIndex::kset_string;
304 return RootIndex::kadd_string;
320 static constexpr int kNoContextIndex = -1;
324 using DescriptorIndexNameValue =
327 DescriptorIndexNameValue property_to_check{
337 Label if_unmodified(
this);
338 prototype_check_assembler.
CheckAndBranch(prototype, &if_unmodified,
341 BIND(&if_unmodified);
350 is_target_unmodified,
361 CAST(LoadJSFunctionPrototypeOrInitialMap(constructor));
375 const int kIterableArg = 0;
386 Label add_constructor_entries(
this);
397 BIND(&add_constructor_entries);
418 BIND(&if_notcallable);
419 ThrowTypeError(context, MessageTemplate::kPropertyNotFunction, add_func,
431 index = Context::JS_MAP_FUN_INDEX;
434 index = Context::JS_SET_FUN_INDEX;
437 index = Context::JS_WEAK_MAP_FUN_INDEX;
440 index = Context::JS_WEAK_SET_FUN_INDEX;
451 index = Context::MAP_SET_INDEX;
454 index = Context::SET_ADD_INDEX;
457 index = Context::WEAKMAP_SET_INDEX;
460 index = Context::WEAKSET_ADD_INDEX;
469 return JSMap::kTableOffset;
471 return JSSet::kTableOffset;
473 return JSWeakMap::kTableOffset;
475 return JSWeakSet::kTableOffset;
483 Label check_symbol_key(
this);
492 if_cannot_be_held_weakly);
494 Bind(&check_symbol_key);
498 if_cannot_be_held_weakly);
505 int initial_prototype_index;
508 initial_prototype_index = Context::INITIAL_MAP_PROTOTYPE_MAP_INDEX;
511 initial_prototype_index = Context::INITIAL_SET_PROTOTYPE_MAP_INDEX;
514 initial_prototype_index = Context::INITIAL_WEAKMAP_PROTOTYPE_MAP_INDEX;
517 initial_prototype_index = Context::INITIAL_WEAKSET_PROTOTYPE_MAP_INDEX;
536 IsTheHole(element), [=,
this] {
return UndefinedConstant(); },
537 [=] {
return element; });
552 entry = UndefinedConstant();
556 return entry.value();
559template <
typename CollectionType>
568 table, CollectionType::NumberOfBucketsIndex())));
573 CollectionType::HashTableStartIndex() *
kTaggedSize)));
579 Label if_key_found(
this);
582 Label loop(
this, {&var_entry, entry_start_position}),
583 continue_next_entry(
this);
599 table, CollectionType::NumberOfElementsIndex())),
601 table, CollectionType::NumberOfDeletedElementsIndex()))))));
607 number_of_buckets_intptr);
613 key_compare(candidate_key, &if_key_found, &continue_next_entry);
615 BIND(&continue_next_entry);
619 (CollectionType::HashTableStartIndex() + CollectionType::kChainOffset) *
626 *entry_start_position = entry_start;
639 Label if_fast_js_set(
this), exit(
this);
642 initial_entries, context, &if_fast_js_set, if_not_fast_collection);
643 BIND(&if_fast_js_set);
667 IntPtrAdd(number_of_elements, number_of_deleted_elements);
683 Label if_key_is_not_hole(
this), continue_loop(
this);
684 Branch(IsHashTableHole(entry_key.value()), &continue_loop,
685 &if_key_is_not_hole);
686 BIND(&if_key_is_not_hole);
689 number_of_buckets_entry_table,
690 var_entry_table_occupancy.value());
691 Increment(&var_entry_table_occupancy, 1);
692 Goto(&continue_loop);
694 BIND(&continue_loop);
713 if (variant ==
kSet) {
719template <
typename IteratorType>
732 RootIndex::kEmptyFixedArray);
734 RootIndex::kEmptyFixedArray);
743 if (variant ==
kMap) {
753 auto new_target = Parameter<Object>(Descriptor::kJSNewTarget);
755 UncheckedParameter<Int32T>(Descriptor::kJSActualArgumentsCount));
756 auto context = Parameter<Context>(Descriptor::kContext);
763 auto new_target = Parameter<Object>(Descriptor::kJSNewTarget);
765 UncheckedParameter<Int32T>(Descriptor::kJSActualArgumentsCount));
766 auto context = Parameter<Context>(Descriptor::kContext);
783 std::make_pair(type_ptr, isolate_ptr),
784 std::make_pair(type_tagged,
key)));
800 std::make_pair(type_ptr, isolate_ptr),
801 std::make_pair(type_tagged,
key)));
808 Label if_receiver(
this), if_other(
this), done(
this);
824 return var_hash.value();
830 Label* if_not_same) {
846 GotoIf(Float64Equal(candidate_key_number, key_number), if_same);
866 Label if_key_or_value_iterator(
this), extra_checks(
this);
873 &if_key_or_value_iterator);
875 &if_key_or_value_iterator, if_false);
877 BIND(&if_key_or_value_iterator);
887 const TNode<Object> initial_map_iter_proto = LoadContextElement(
906 assembler.BranchIfIterableWithOriginalKeyOrValueMapIterator(
907 iterable, context, if_true, if_false);
923 Label if_set(
this), if_value_iterator(
this), check_protector(
this);
932 &if_value_iterator, if_false);
940 Goto(&check_protector);
942 BIND(&if_value_iterator);
950 const TNode<Object> initial_set_iter_proto = LoadContextElement(
962 Goto(&check_protector);
964 BIND(&check_protector);
973 assembler.BranchIfIterableWithOriginalValueSetIterator(iterable, context,
983 Label if_set(
this), if_iterator(
this), done(
this);
1003 std::tie(table, index) =
1009 RootIndex::kEmptyOrderedHashSet);
1013 SmiTag(number_of_elements));
1018 return var_table.value();
1026 std::tie(table, index) =
1040 const int first_element_offset =
1049 Label done(
this, {&var_index}), loop(
this, vars), continue_loop(
this, vars),
1050 write_key(
this, vars), write_value(
this, vars);
1060 std::tie(entry_key, entry_start_position, cur_index) =
1066 &write_key, &write_value);
1070 Store(elements, var_offset.value(), entry_key);
1071 Goto(&continue_loop);
1077 JS_MAP_VALUE_ITERATOR_TYPE));
1081 Store(elements, var_offset.value(), entry_value);
1082 Goto(&continue_loop);
1085 BIND(&continue_loop);
1088 var_index = cur_index;
1097 RootIndex::kEmptyOrderedHashMap);
1099 SmiTag(var_index.value()));
1104 auto context = Parameter<Context>(Descriptor::kContext);
1105 auto iterator = Parameter<JSMapIterator>(Descriptor::kSource);
1106 Return(MapIteratorToList(context, iterator));
1122 const int first_element_offset =
1130 Label done(
this), loop(
this, {&var_index, &var_offset});
1140 std::tie(entry_key, entry_start_position, cur_index) =
1143 Store(elements, var_offset.value(), entry_key);
1145 var_index = cur_index;
1155 auto context = Parameter<Context>(Descriptor::kContext);
1156 auto object = Parameter<HeapObject>(Descriptor::kSource);
1157 Return(SetOrSetIteratorToList(context,
object));
1174template <
typename CollectionType>
1186 result, entry_found, not_found);
1189template <
typename CollectionType>
1200 result, entry_found, not_found);
1203template <
typename CollectionType>
1215 result, entry_found, not_found);
1218template <
typename CollectionType>
1229 result, entry_found, not_found);
1232template <
typename CollectionType>
1243 result, entry_found, not_found);
1250 Label hash_not_computed(
this), done(
this, &var_result);
1255 BIND(&hash_not_computed);
1260 return var_result.value();
1265 Label* if_not_same) {
1276 Label* if_not_same) {
1283 if_same, if_not_same);
1288 Label* if_not_same) {
1289 Label if_smi(
this), if_keyisnan(
this);
1298 GotoIf(Float64Equal(key_float, candidate_float), if_same);
1307 Branch(Float64Equal(candidate_float, candidate_float), if_not_same,
1315 Branch(Float64Equal(key_float, candidate_float), if_same, if_not_same);
1320 auto table = Parameter<HeapObject>(Descriptor::kTable);
1321 auto index = Parameter<Smi>(Descriptor::kIndex);
1322 Label return_index(
this), return_zero(
this);
1325 GotoIfNot(SmiLessThan(SmiConstant(0), index), &return_zero);
1330 TNode<Int32T> number_of_deleted_elements = LoadAndUntagToWord32ObjectField(
1334 GotoIf(Word32Equal(number_of_deleted_elements,
1340 Label loop(
this, {&var_i, &var_index});
1345 GotoIfNot(Int32LessThan(
i, number_of_deleted_elements), &return_index);
1349 CAST(table), ChangeUint32ToWord(
i),
1351 GotoIf(SmiGreaterThanOrEqual(removed_index, index), &return_index);
1352 Decrement(&var_index);
1353 var_i = Int32Add(var_i.value(), Int32Constant(1));
1357 BIND(&return_index);
1358 Return(var_index.value());
1361 Return(SmiConstant(0));
1364template <
typename TableType>
1365std::pair<TNode<TableType>, TNode<IntPtrT>>
1374 &if_done, &if_transition);
1376 BIND(&if_transition);
1378 Label loop(
this, {&var_table, &var_index}), done_loop(
this);
1389 var_table =
CAST(next_table);
1392 SmiTag(current_index))));
1398 update_in_transition(var_table.value(), var_index.value());
1403 return {var_table.value(), var_index.value()};
1406template <
typename IteratorType,
typename TableType>
1422TorqueStructOrderedHashSetIndexPair
1428 table_arg, index_arg,
1430 return TorqueStructOrderedHashSetIndexPair{table, index};
1433template <
typename TableType>
1440 table, TableType::NumberOfBucketsOffset());
1442 table, TableType::NumberOfElementsOffset());
1444 table, TableType::NumberOfDeletedElementsOffset());
1446 Int32Add(number_of_elements, number_of_deleted_elements);
1452template <
typename TableType>
1459 table, TableType::NumberOfBucketsOffset())));
1465 table, TableType::NumberOfElementsOffset()),
1467 table, TableType::NumberOfDeletedElementsOffset()))));
1472 Label loop(
this, &var_index), done_loop(
this);
1476 GotoIfNot(Int32LessThan(var_index.value(), used_capacity), if_end);
1483 Branch(IsHashTableHole(entry_key), &loop, &done_loop);
1491template <
typename CollectionType>
1492TorqueStructKeyIndexPair
1499 table, CollectionType::NextTableOffset())));
1506 table, number_of_buckets, used_capacity, index, if_end);
1508 return TorqueStructKeyIndexPair{
key, next_index};
1511template TorqueStructKeyIndexPair
1516template TorqueStructKeyIndexPair
1522template <
typename CollectionType>
1530 std::tie(
key, entry_start_position, next_index) =
1533 return TorqueStructKeyIndexPair{
key, next_index};
1536template TorqueStructKeyIndexPair
1540template TorqueStructKeyIndexPair
1545TorqueStructKeyValueIndexTuple
1555 table, number_of_buckets, used_capacity, index, if_end);
1560 return TorqueStructKeyValueIndexTuple{
key,
value, next_index};
1563TorqueStructKeyValueIndexTuple
1571 std::tie(
key, entry_start_position, next_index) =
1577 return TorqueStructKeyValueIndexTuple{
key,
value, next_index};
1581 const auto receiver = Parameter<Object>(Descriptor::kReceiver);
1582 const auto key = Parameter<Object>(Descriptor::kKey);
1583 const auto context = Parameter<Context>(Descriptor::kContext);
1585 ThrowIfNotInstanceType(context,
receiver, JS_MAP_TYPE,
"Map.prototype.get");
1588 LoadObjectField<Object>(
CAST(
receiver), JSMap::kTableOffset);
1590 CAST(CallBuiltin(Builtin::kFindOrderedHashMapEntry, context, table,
key));
1592 Label if_found(
this), if_not_found(
this);
1593 Branch(SmiGreaterThanOrEqual(index, SmiConstant(0)), &if_found,
1597 Return(LoadValueFromOrderedHashMapEntry(
CAST(table), SmiUntag(index)));
1599 BIND(&if_not_found);
1600 Return(UndefinedConstant());
1604 const auto receiver = Parameter<Object>(Descriptor::kReceiver);
1605 const auto key = Parameter<Object>(Descriptor::kKey);
1606 const auto context = Parameter<Context>(Descriptor::kContext);
1608 ThrowIfNotInstanceType(context,
receiver, JS_MAP_TYPE,
"Map.prototype.has");
1613 Label if_found(
this), if_not_found(
this);
1614 Branch(TableHasKey(context, table,
key), &if_found, &if_not_found);
1617 Return(TrueConstant());
1619 BIND(&if_not_found);
1620 Return(FalseConstant());
1629 return SmiGreaterThanOrEqual(index,
SmiConstant(0));
1650template <
typename CollectionType>
1656 TVARIABLE(CollectionType, table_var, table);
1658 Label entry_found(
this), not_found(
this), done(
this);
1661 table,
key, &entry_start_position_or_hash, &entry_found, ¬_found);
1666 store_at_existing_entry(table, entry_start_position_or_hash.value());
1670 Label no_hash(
this), add_entry(
this), store_new_entry(
this);
1674 GotoIf(IntPtrGreaterThan(entry_start_position_or_hash.value(),
1689 table, CollectionType::NumberOfBucketsIndex())));
1691 static_assert(CollectionType::kLoadFactor == 2);
1695 table, CollectionType::NumberOfElementsOffset());
1698 table, CollectionType::NumberOfDeletedElementsOffset())));
1699 occupancy =
IntPtrAdd(number_of_elements, number_of_deleted);
1700 GotoIf(IntPtrLessThan(occupancy.value(), capacity), &store_new_entry);
1706 table_var.value(), CollectionType::NumberOfBucketsIndex())));
1709 table_var.value(), CollectionType::NumberOfElementsOffset());
1712 CollectionType::NumberOfDeletedElementsOffset())));
1713 occupancy =
IntPtrAdd(new_number_of_elements, new_number_of_deleted);
1714 Goto(&store_new_entry);
1717 BIND(&store_new_entry);
1720 table_var.value(), entry_start_position_or_hash.value(),
1721 number_of_buckets.value(), occupancy.value(), store_at_new_entry);
1726 return table_var.value();
1730 const auto receiver = Parameter<Object>(Descriptor::kReceiver);
1731 auto key = Parameter<JSAny>(Descriptor::kKey);
1732 const auto value = Parameter<Object>(Descriptor::kValue);
1733 const auto context = Parameter<Context>(Descriptor::kContext);
1735 ThrowIfNotInstanceType(context,
receiver, JS_MAP_TYPE,
"Map.prototype.set");
1737 key = NormalizeNumberKey(
key);
1741 return LoadObjectField<OrderedHashMap>(
CAST(
receiver), JSMap::kTableOffset);
1744 StoreAtEntry<OrderedHashMap> store_at_new_entry =
1747 UnsafeStoreKeyValueInOrderedHashMapEntry(table,
key, value,
1751 StoreAtEntry<OrderedHashMap> store_at_existing_entry =
1754 UnsafeStoreValueInOrderedHashMapEntry(table, value, entry_start);
1758 LoadObjectField<OrderedHashMap>(
CAST(
receiver), JSMap::kTableOffset);
1759 AddToOrderedHashTable(table,
key, grow, store_at_new_entry,
1760 store_at_existing_entry);
1764template <
typename CollectionType>
1772 table, bucket, CollectionType::HashTableStartIndex() *
kTaggedSize));
1778 store_at_new_entry(table, entry_start);
1782 table, entry_start, bucket_entry,
1783 kTaggedSize * (CollectionType::HashTableStartIndex() +
1784 CollectionType::kChainOffset));
1788 table, bucket,
SmiTag(occupancy),
1789 CollectionType::HashTableStartIndex() *
kTaggedSize);
1795 CollectionType::NumberOfElementsOffset(),
1801template <
typename CollectionType>
1806 Label if_key_smi(
this), if_key_string(
this), if_key_heap_number(
this),
1807 if_key_bigint(
this), if_key_other(
this), call_store(
this);
1815 GotoIf(IsHeapNumberMap(key_map), &if_key_heap_number);
1817 Goto(&if_key_other);
1819 BIND(&if_key_other);
1832 BIND(&if_key_string);
1838 BIND(&if_key_heap_number);
1844 BIND(&if_key_bigint);
1852 occupancy, store_at_new_entry);
1875 const auto receiver = Parameter<Object>(Descriptor::kReceiver);
1876 const auto key = Parameter<Object>(Descriptor::kKey);
1877 const auto context = Parameter<Context>(Descriptor::kContext);
1879 ThrowIfNotInstanceType(context,
receiver, JS_MAP_TYPE,
1880 "Map.prototype.delete");
1883 LoadObjectField<OrderedHashMap>(
CAST(
receiver), JSMap::kTableOffset);
1886 Label entry_found(
this), not_found(
this);
1888 TryLookupOrderedHashTableIndex<OrderedHashMap>(
1889 table,
key, &entry_start_position_or_hash, &entry_found, ¬_found);
1892 Return(FalseConstant());
1896 StoreKeyValueInOrderedHashMapEntry(table, HashTableHoleConstant(),
1897 HashTableHoleConstant(),
1898 entry_start_position_or_hash.value());
1901 const TNode<Smi> number_of_elements = SmiSub(
1904 StoreObjectFieldNoWriteBarrier(
1907 SmiAdd(
CAST(LoadObjectField(
1910 StoreObjectFieldNoWriteBarrier(
1919 GotoIf(SmiLessThan(SmiAdd(number_of_elements, number_of_elements),
1922 Return(TrueConstant());
1926 Return(TrueConstant());
1930 const auto receiver = Parameter<Object>(Descriptor::kReceiver);
1931 auto key = Parameter<JSAny>(Descriptor::kKey);
1932 const auto context = Parameter<Context>(Descriptor::kContext);
1934 ThrowIfNotInstanceType(context,
receiver, JS_SET_TYPE,
"Set.prototype.add");
1936 key = NormalizeNumberKey(
key);
1940 return LoadObjectField<OrderedHashSet>(
CAST(
receiver), JSSet::kTableOffset);
1943 StoreAtEntry<OrderedHashSet> store_at_new_entry =
1946 UnsafeStoreKeyInOrderedHashSetEntry(table,
key, entry_start);
1949 StoreAtEntry<OrderedHashSet> store_at_existing_entry =
1955 LoadObjectField<OrderedHashSet>(
CAST(
receiver), JSSet::kTableOffset);
1956 AddToOrderedHashTable(table,
key, grow, store_at_new_entry,
1957 store_at_existing_entry);
1968 CallRuntime(Runtime::kOrderedHashSetGrow, context, table, method_name));
1986 store_at_existing_entry);
1997template <
typename CollectionType>
2002 table, entry,
kTaggedSize * CollectionType::HashTableStartIndex(),
2018 const auto receiver = Parameter<Object>(Descriptor::kReceiver);
2019 const auto key = Parameter<Object>(Descriptor::kKey);
2020 const auto context = Parameter<Context>(Descriptor::kContext);
2022 ThrowIfNotInstanceType(context,
receiver, JS_SET_TYPE,
2023 "Set.prototype.delete");
2029 LoadObjectField<OrderedHashSet>(
CAST(
receiver), JSMap::kTableOffset);
2031 Label not_found(
this);
2033 DeleteFromSetTable(context, table,
key, ¬_found);
2040 GotoIf(SmiLessThan(SmiAdd(number_of_elements, number_of_elements),
2043 Return(TrueConstant());
2047 Return(TrueConstant());
2050 Return(FalseConstant());
2057 Label entry_found(
this);
2060 table,
key, &entry_start_position_or_hash, &entry_found, not_found);
2065 entry_start_position_or_hash.value());
2068 const TNode<Smi> number_of_elements = SmiSub(
2081 return number_of_elements;
2085 const auto receiver = Parameter<Object>(Descriptor::kReceiver);
2086 const auto context = Parameter<Context>(Descriptor::kContext);
2087 ThrowIfNotInstanceType(context,
receiver, JS_MAP_TYPE,
2088 "Map.prototype.entries");
2089 Return(AllocateJSCollectionIterator<JSMapIterator>(
2090 context, Context::MAP_KEY_VALUE_ITERATOR_MAP_INDEX,
CAST(
receiver)));
2094 const auto receiver = Parameter<Object>(Descriptor::kReceiver);
2095 const auto context = Parameter<Context>(Descriptor::kContext);
2096 ThrowIfNotInstanceType(context,
receiver, JS_MAP_TYPE,
2097 "get Map.prototype.size");
2099 LoadObjectField<OrderedHashMap>(
CAST(
receiver), JSMap::kTableOffset);
2104 const char*
const kMethodName =
"Map.prototype.forEach";
2105 auto argc = UncheckedParameter<Int32T>(Descriptor::kJSActualArgumentsCount);
2106 const auto context = Parameter<Context>(Descriptor::kContext);
2112 ThrowIfNotInstanceType(context,
receiver, JS_MAP_TYPE, kMethodName);
2115 Label callback_not_callable(
this, Label::kDeferred);
2116 GotoIf(TaggedIsSmi(
callback), &callback_not_callable);
2117 GotoIfNot(IsCallable(
CAST(
callback)), &callback_not_callable);
2122 Label loop(
this, {&var_index, &var_table}), done_loop(
this);
2130 std::tie(table, index) = Transition<OrderedHashMap>(
2136 std::tie(entry_key, entry_start_position, index) =
2137 NextSkipHashTableHoles<OrderedHashMap>(table, index, &done_loop);
2141 LoadValueFromOrderedHashMapEntry(table, entry_start_position);
2154 args.PopAndReturn(UndefinedConstant());
2156 BIND(&callback_not_callable);
2164 const auto receiver = Parameter<Object>(Descriptor::kReceiver);
2165 const auto context = Parameter<Context>(Descriptor::kContext);
2166 ThrowIfNotInstanceType(context,
receiver, JS_MAP_TYPE,
"Map.prototype.keys");
2167 Return(AllocateJSCollectionIterator<JSMapIterator>(
2168 context, Context::MAP_KEY_ITERATOR_MAP_INDEX,
CAST(
receiver)));
2172 const auto receiver = Parameter<Object>(Descriptor::kReceiver);
2173 const auto context = Parameter<Context>(Descriptor::kContext);
2174 ThrowIfNotInstanceType(context,
receiver, JS_MAP_TYPE,
2175 "Map.prototype.values");
2176 Return(AllocateJSCollectionIterator<JSMapIterator>(
2177 context, Context::MAP_VALUE_ITERATOR_MAP_INDEX,
CAST(
receiver)));
2181 const char*
const kMethodName =
"Map Iterator.prototype.next";
2182 const auto maybe_receiver = Parameter<Object>(Descriptor::kReceiver);
2183 const auto context = Parameter<Context>(Descriptor::kContext);
2186 Label if_receiver_valid(
this), if_receiver_invalid(
this, Label::kDeferred);
2187 GotoIf(TaggedIsSmi(maybe_receiver), &if_receiver_invalid);
2189 LoadInstanceType(
CAST(maybe_receiver));
2191 InstanceTypeEqual(receiver_instance_type, JS_MAP_KEY_VALUE_ITERATOR_TYPE),
2192 &if_receiver_valid);
2193 GotoIf(InstanceTypeEqual(receiver_instance_type, JS_MAP_KEY_ITERATOR_TYPE),
2194 &if_receiver_valid);
2195 Branch(InstanceTypeEqual(receiver_instance_type, JS_MAP_VALUE_ITERATOR_TYPE),
2196 &if_receiver_valid, &if_receiver_invalid);
2197 BIND(&if_receiver_invalid);
2198 ThrowTypeError(context, MessageTemplate::kIncompatibleMethodReceiver,
2199 StringConstant(kMethodName), maybe_receiver);
2200 BIND(&if_receiver_valid);
2206 Label return_value(
this, {&var_done, &var_value}), return_entry(
this),
2207 return_end(
this, Label::kDeferred);
2212 std::tie(table, index) =
2213 TransitionAndUpdate<JSMapIterator, OrderedHashMap>(
receiver);
2218 std::tie(entry_key, entry_start_position, index) =
2219 NextSkipHashTableHoles<OrderedHashMap>(table, index, &return_end);
2220 StoreObjectFieldNoWriteBarrier(
receiver, JSMapIterator::kIndexOffset,
2222 var_value = entry_key;
2223 var_done = FalseConstant();
2226 GotoIf(InstanceTypeEqual(receiver_instance_type, JS_MAP_KEY_ITERATOR_TYPE),
2228 var_value = LoadValueFromOrderedHashMapEntry(table, entry_start_position);
2229 Branch(InstanceTypeEqual(receiver_instance_type, JS_MAP_VALUE_ITERATOR_TYPE),
2230 &return_value, &return_entry);
2232 BIND(&return_entry);
2235 AllocateJSIteratorResultForEntry(context, entry_key, var_value.value());
2239 BIND(&return_value);
2242 AllocateJSIteratorResult(context, var_value.value(), var_done.value());
2248 StoreObjectFieldRoot(
receiver, JSMapIterator::kTableOffset,
2249 RootIndex::kEmptyOrderedHashMap);
2250 Goto(&return_value);
2255 const auto receiver = Parameter<Object>(Descriptor::kReceiver);
2256 const auto key = Parameter<Object>(Descriptor::kKey);
2257 const auto context = Parameter<Context>(Descriptor::kContext);
2259 ThrowIfNotInstanceType(context,
receiver, JS_SET_TYPE,
"Set.prototype.has");
2264 Label if_found(
this), if_not_found(
this);
2265 Branch(TableHasKey(context, table,
key), &if_found, &if_not_found);
2268 Return(TrueConstant());
2270 BIND(&if_not_found);
2271 Return(FalseConstant());
2280 return SmiGreaterThanOrEqual(index,
SmiConstant(0));
2284 const auto receiver = Parameter<Object>(Descriptor::kReceiver);
2285 const auto context = Parameter<Context>(Descriptor::kContext);
2286 ThrowIfNotInstanceType(context,
receiver, JS_SET_TYPE,
2287 "Set.prototype.entries");
2288 Return(AllocateJSCollectionIterator<JSSetIterator>(
2289 context, Context::SET_KEY_VALUE_ITERATOR_MAP_INDEX,
CAST(
receiver)));
2293 const auto receiver = Parameter<Object>(Descriptor::kReceiver);
2294 const auto context = Parameter<Context>(Descriptor::kContext);
2295 ThrowIfNotInstanceType(context,
receiver, JS_SET_TYPE,
2296 "get Set.prototype.size");
2298 LoadObjectField<OrderedHashSet>(
CAST(
receiver), JSSet::kTableOffset);
2303 const char*
const kMethodName =
"Set.prototype.forEach";
2304 auto argc = UncheckedParameter<Int32T>(Descriptor::kJSActualArgumentsCount);
2305 const auto context = Parameter<Context>(Descriptor::kContext);
2311 ThrowIfNotInstanceType(context,
receiver, JS_SET_TYPE, kMethodName);
2314 Label callback_not_callable(
this, Label::kDeferred);
2315 GotoIf(TaggedIsSmi(
callback), &callback_not_callable);
2316 GotoIfNot(IsCallable(
CAST(
callback)), &callback_not_callable);
2321 Label loop(
this, {&var_index, &var_table}), done_loop(
this);
2329 std::tie(table, index) = Transition<OrderedHashSet>(
2335 std::tie(entry_key, entry_start_position, index) =
2336 NextSkipHashTableHoles<OrderedHashSet>(table, index, &done_loop);
2348 args.PopAndReturn(UndefinedConstant());
2350 BIND(&callback_not_callable);
2358 const auto receiver = Parameter<Object>(Descriptor::kReceiver);
2359 const auto context = Parameter<Context>(Descriptor::kContext);
2360 ThrowIfNotInstanceType(context,
receiver, JS_SET_TYPE,
2361 "Set.prototype.values");
2362 Return(AllocateJSCollectionIterator<JSSetIterator>(
2363 context, Context::SET_VALUE_ITERATOR_MAP_INDEX,
CAST(
receiver)));
2367 const char*
const kMethodName =
"Set Iterator.prototype.next";
2368 const auto maybe_receiver = Parameter<Object>(Descriptor::kReceiver);
2369 const auto context = Parameter<Context>(Descriptor::kContext);
2372 Label if_receiver_valid(
this), if_receiver_invalid(
this, Label::kDeferred);
2373 GotoIf(TaggedIsSmi(maybe_receiver), &if_receiver_invalid);
2375 LoadInstanceType(
CAST(maybe_receiver));
2376 GotoIf(InstanceTypeEqual(receiver_instance_type, JS_SET_VALUE_ITERATOR_TYPE),
2377 &if_receiver_valid);
2379 InstanceTypeEqual(receiver_instance_type, JS_SET_KEY_VALUE_ITERATOR_TYPE),
2380 &if_receiver_valid, &if_receiver_invalid);
2381 BIND(&if_receiver_invalid);
2382 ThrowTypeError(context, MessageTemplate::kIncompatibleMethodReceiver,
2383 StringConstant(kMethodName), maybe_receiver);
2384 BIND(&if_receiver_valid);
2391 Label return_value(
this, {&var_done, &var_value}), return_entry(
this),
2392 return_end(
this, Label::kDeferred);
2397 std::tie(table, index) =
2398 TransitionAndUpdate<JSSetIterator, OrderedHashSet>(
receiver);
2403 std::tie(entry_key, entry_start_position, index) =
2404 NextSkipHashTableHoles<OrderedHashSet>(table, index, &return_end);
2405 StoreObjectFieldNoWriteBarrier(
receiver, JSSetIterator::kIndexOffset,
2407 var_value = entry_key;
2408 var_done = FalseConstant();
2411 Branch(InstanceTypeEqual(receiver_instance_type, JS_SET_VALUE_ITERATOR_TYPE),
2412 &return_value, &return_entry);
2414 BIND(&return_entry);
2417 context, var_value.value(), var_value.value());
2421 BIND(&return_value);
2424 AllocateJSIteratorResult(context, var_value.value(), var_done.value());
2430 StoreObjectFieldRoot(
receiver, JSSetIterator::kTableOffset,
2431 RootIndex::kEmptyOrderedHashSet);
2432 Goto(&return_value);
2436template <
typename CollectionType>
2440 Label if_key_smi(
this), if_key_string(
this), if_key_heap_number(
this),
2441 if_key_bigint(
this);
2449 GotoIf(IsHeapNumberMap(key_map), &if_key_heap_number);
2461 BIND(&if_key_string);
2467 BIND(&if_key_heap_number);
2473 BIND(&if_key_bigint);
2481 const auto table = Parameter<OrderedHashMap>(Descriptor::kTable);
2482 const auto key = Parameter<Object>(Descriptor::kKey);
2485 Label entry_found(
this), not_found(
this);
2487 TryLookupOrderedHashTableIndex<OrderedHashMap>(
2488 table,
key, &entry_start_position, &entry_found, ¬_found);
2491 Return(SmiTag(entry_start_position.value()));
2494 Return(SmiConstant(-1));
2498 const auto table = Parameter<OrderedHashSet>(Descriptor::kTable);
2499 const auto key = Parameter<Object>(Descriptor::kKey);
2502 Label entry_found(
this), not_found(
this);
2504 TryLookupOrderedHashTableIndex<OrderedHashSet>(
2505 table,
key, &entry_start_position, &entry_found, ¬_found);
2508 Return(SmiTag(entry_start_position.value()));
2511 Return(SmiConstant(-1));
2523 Label did_grow(
this), done(
this);
2554 store_at_existing_entry);
2568 EphemeronHashTable::kNumberOfElementsIndex,
2575 Label if_symbol(
this);
2576 Label return_result(
this);
2580 Goto(&return_result);
2587 Goto(&return_result);
2588 Bind(&return_result);
2589 return var_hash.value();
2610 EphemeronHashTable::kNumberOfDeletedElementsIndex,
2617 RootIndex::kUndefinedValue);
2632 std::make_pair(type_ptr, isolate_ptr),
2633 std::make_pair(type_tagged,
key)));
2647 Label done(
this, &coeff);
2655 return coeff.value();
2667 Label loop(
this, {&var_count, &var_entry}), if_found(
this);
2676 key_compare(entry_key, &if_found);
2694 GotoIf(
Word32Or(IsTheHole(entry_key), IsUndefined(entry_key)), if_found);
2696 return FindKeyIndex(table, key_hash, capacity, is_not_live);
2703 auto match_key_or_exit_on_empty = [&](
TNode<Object> entry_key,
2705 GotoIf(IsUndefined(entry_key), if_not_found);
2708 return FindKeyIndex(table, hash, capacity, match_key_or_exit_on_empty);
2718 EphemeronHashTable::kEntryKeyIndex));
2725 table, EphemeronHashTable::kNumberOfElementsIndex)));
2732 table, EphemeronHashTable::kNumberOfDeletedElementsIndex)));
2759 Int32GreaterThan(number_of_deleted, half_available),
2761 Int32GreaterThan(
Int32Add(number_of_elements, needed_available),
2778 EphemeronHashTable::kNumberOfDeletedElementsIndex,
2785 return Int32GreaterThanOrEqual(
Word32Shl(number_of_deleted, 1),
2786 number_of_elements);
2796 IntPtrLessThanOrEqual(number_of_elements, quarter_capacity),
2810 EphemeronHashTable::kEntryKeyIndex));
2814 auto new_target = Parameter<Object>(Descriptor::kJSNewTarget);
2816 UncheckedParameter<Int32T>(Descriptor::kJSActualArgumentsCount));
2817 auto context = Parameter<Context>(Descriptor::kContext);
2819 GenerateConstructor(kWeakMap,
isolate()->factory()->WeakMap_string(),
2824 auto new_target = Parameter<Object>(Descriptor::kJSNewTarget);
2826 UncheckedParameter<Int32T>(Descriptor::kJSActualArgumentsCount));
2827 auto context = Parameter<Context>(Descriptor::kContext);
2829 GenerateConstructor(kWeakSet,
isolate()->factory()->WeakSet_string(),
2834 auto table = Parameter<EphemeronHashTable>(Descriptor::kTable);
2835 auto key = Parameter<Object>(Descriptor::kKey);
2837 Label if_cannot_be_held_weakly(
this);
2839 GotoIfCannotBeHeldWeakly(
key, &if_cannot_be_held_weakly);
2844 FindKeyIndexForKey(table,
key, hash, capacity, &if_cannot_be_held_weakly);
2845 Return(SmiTag(ValueIndexFromKeyIndex(key_index)));
2847 BIND(&if_cannot_be_held_weakly);
2848 Return(SmiConstant(-1));
2852 const auto receiver = Parameter<Object>(Descriptor::kReceiver);
2853 const auto key = Parameter<Object>(Descriptor::kKey);
2854 const auto context = Parameter<Context>(Descriptor::kContext);
2856 Label return_undefined(
this);
2858 ThrowIfNotInstanceType(context,
receiver, JS_WEAK_MAP_TYPE,
2859 "WeakMap.prototype.get");
2863 CAST(CallBuiltin(Builtin::kWeakMapLookupHashIndex, context, table,
key));
2865 GotoIf(TaggedEqual(index, SmiConstant(-1)), &return_undefined);
2867 Return(LoadFixedArrayElement(table, SmiUntag(index)));
2869 BIND(&return_undefined);
2870 Return(UndefinedConstant());
2874 const auto receiver = Parameter<Object>(Descriptor::kReceiver);
2875 const auto key = Parameter<Object>(Descriptor::kKey);
2876 const auto context = Parameter<Context>(Descriptor::kContext);
2878 Label return_false(
this);
2880 ThrowIfNotInstanceType(context,
receiver, JS_WEAK_MAP_TYPE,
2881 "WeakMap.prototype.has");
2885 CallBuiltin(Builtin::kWeakMapLookupHashIndex, context, table,
key);
2887 GotoIf(TaggedEqual(index, SmiConstant(-1)), &return_false);
2889 Return(TrueConstant());
2891 BIND(&return_false);
2892 Return(FalseConstant());
2898 auto context = Parameter<Context>(Descriptor::kContext);
2899 auto collection = Parameter<JSWeakCollection>(Descriptor::kCollection);
2900 auto key = Parameter<Object>(Descriptor::kKey);
2902 Label call_runtime(
this), if_cannot_be_held_weakly(
this);
2904 GotoIfCannotBeHeldWeakly(
key, &if_cannot_be_held_weakly);
2910 FindKeyIndexForKey(table,
key, hash, capacity, &if_cannot_be_held_weakly);
2911 TNode<Int32T> number_of_elements = LoadNumberOfElements(table, -1);
2912 GotoIf(ShouldShrink(capacity, ChangeInt32ToIntPtr(number_of_elements)),
2915 RemoveEntry(table, key_index, ChangeInt32ToIntPtr(number_of_elements));
2916 Return(TrueConstant());
2918 BIND(&if_cannot_be_held_weakly);
2919 Return(FalseConstant());
2921 BIND(&call_runtime);
2922 Return(
CallRuntime(Runtime::kWeakCollectionDelete, context, collection,
key,
2929 auto context = Parameter<Context>(Descriptor::kContext);
2930 auto collection = Parameter<JSWeakCollection>(Descriptor::kCollection);
2931 auto key = Parameter<HeapObject>(Descriptor::kKey);
2932 auto value = Parameter<Object>(Descriptor::kValue);
2936 Label call_runtime(
this), if_no_hash(
this), if_not_found(
this);
2943 FindKeyIndexForKey(table,
key, var_hash.value(), capacity, &if_not_found);
2945 StoreFixedArrayElement(table, ValueIndexFromKeyIndex(key_index), value);
2951 var_hash = SmiUntag(CreateIdentityHash(
key));
2952 Goto(&if_not_found);
2954 BIND(&if_not_found);
2956 TNode<Int32T> number_of_deleted = LoadNumberOfDeleted(table);
2957 TNode<Int32T> number_of_elements = LoadNumberOfElements(table, 1);
2960 IntPtrLessThanOrEqual(capacity, IntPtrConstant(INT32_MAX)));
2962 IntPtrGreaterThanOrEqual(capacity, IntPtrConstant(INT32_MIN)));
2964 GotoIf(Word32Or(ShouldRehash(number_of_elements, number_of_deleted),
2965 InsufficientCapacityToAdd(TruncateIntPtrToInt32(capacity),
2967 number_of_deleted)),
2971 FindKeyIndexForInsertion(table, var_hash.value(), capacity);
2972 AddEntry(table, insertion_key_index,
key, value, number_of_elements);
2975 BIND(&call_runtime);
2977 CallRuntime(Runtime::kWeakCollectionSet, context, collection,
key, value,
2978 SmiTag(var_hash.value()));
2984 auto context = Parameter<Context>(Descriptor::kContext);
2985 auto receiver = Parameter<Object>(Descriptor::kReceiver);
2986 auto key = Parameter<Object>(Descriptor::kKey);
2988 ThrowIfNotInstanceType(context,
receiver, JS_WEAK_MAP_TYPE,
2989 "WeakMap.prototype.delete");
2994 Return(CallBuiltin(Builtin::kWeakCollectionDelete, context,
receiver,
key));
2998 auto context = Parameter<Context>(Descriptor::kContext);
2999 auto receiver = Parameter<Object>(Descriptor::kReceiver);
3000 auto key = Parameter<Object>(Descriptor::kKey);
3001 auto value = Parameter<Object>(Descriptor::kValue);
3003 ThrowIfNotInstanceType(context,
receiver, JS_WEAK_MAP_TYPE,
3004 "WeakMap.prototype.set");
3006 Label throw_invalid_key(
this);
3007 GotoIfCannotBeHeldWeakly(
key, &throw_invalid_key);
3010 CallBuiltin(Builtin::kWeakCollectionSet, context,
receiver,
key, value));
3012 BIND(&throw_invalid_key);
3013 ThrowTypeError(context, MessageTemplate::kInvalidWeakMapKey,
key);
3017 auto context = Parameter<Context>(Descriptor::kContext);
3018 auto receiver = Parameter<Object>(Descriptor::kReceiver);
3019 auto value = Parameter<Object>(Descriptor::kValue);
3021 ThrowIfNotInstanceType(context,
receiver, JS_WEAK_SET_TYPE,
3022 "WeakSet.prototype.add");
3024 Label throw_invalid_value(
this);
3025 GotoIfCannotBeHeldWeakly(value, &throw_invalid_value);
3027 Return(CallBuiltin(Builtin::kWeakCollectionSet, context,
receiver, value,
3030 BIND(&throw_invalid_value);
3031 ThrowTypeError(context, MessageTemplate::kInvalidWeakSetValue, value);
3035 auto context = Parameter<Context>(Descriptor::kContext);
3036 auto receiver = Parameter<Object>(Descriptor::kReceiver);
3037 auto value = Parameter<Object>(Descriptor::kValue);
3039 ThrowIfNotInstanceType(context,
receiver, JS_WEAK_SET_TYPE,
3040 "WeakSet.prototype.delete");
3045 Return(CallBuiltin(Builtin::kWeakCollectionDelete, context,
receiver, value));
3049 const auto receiver = Parameter<Object>(Descriptor::kReceiver);
3050 const auto key = Parameter<Object>(Descriptor::kKey);
3051 const auto context = Parameter<Context>(Descriptor::kContext);
3053 Label return_false(
this);
3055 ThrowIfNotInstanceType(context,
receiver, JS_WEAK_SET_TYPE,
3056 "WeakSet.prototype.has");
3060 CallBuiltin(Builtin::kWeakMapLookupHashIndex, context, table,
key);
3062 GotoIf(TaggedEqual(index, SmiConstant(-1)), &return_false);
3064 Return(TrueConstant());
3066 BIND(&return_false);
3067 Return(FalseConstant());
#define CSA_DCHECK(csa,...)
#define CSA_HOLE_SECURITY_CHECK(csa, x)
#define TF_BUILTIN(Name, AssemblerBase)
TNode< Object > LoadAndNormalizeFixedDoubleArrayElement(TNode< HeapObject > elements, TNode< IntPtrT > index)
TNode< Map > GetInitialCollectionPrototype(Variant variant, TNode< Context > native_context)
virtual void GetEntriesIfFastCollectionOrIterable(Variant variant, TNode< Object > initial_entries, TNode< Context > context, TVariable< HeapObject > *var_entries_table, TVariable< IntPtrT > *var_number_of_elements, Label *if_not_fast_collection)=0
TNode< JSFunction > GetInitialAddFunction(Variant variant, TNode< Context > native_context)
RootIndex GetAddFunctionNameIndex(Variant variant)
void AddConstructorEntriesFromFastJSArray(Variant variant, TNode< Context > context, TNode< Context > native_context, TNode< JSAny > collection, TNode< JSArray > fast_jsarray, Label *if_may_have_side_effects, TVariable< IntPtrT > &var_current_index)
TNode< JSFunction > GetConstructor(Variant variant, TNode< Context > native_context)
TNode< Object > LoadAndNormalizeFixedArrayElement(TNode< FixedArray > elements, TNode< IntPtrT > index)
TNode< Object > GetAddFunction(Variant variant, TNode< Context > context, TNode< JSAny > collection)
TNode< JSObject > AllocateJSCollection(TNode< Context > context, TNode< JSFunction > constructor, TNode< JSReceiver > new_target)
virtual TNode< HeapObject > AllocateTable(Variant variant, TNode< IntPtrT > at_least_space_for)=0
void AddConstructorEntries(Variant variant, TNode< Context > context, TNode< NativeContext > native_context, TNode< JSAnyNotSmi > collection, TNode< JSAny > initial_entries)
virtual void AddConstructorEntriesFromFastCollection(Variant variant, TNode< HeapObject > collection, TNode< HeapObject > source_table)=0
void GenerateConstructor(Variant variant, Handle< String > constructor_function_name, TNode< Object > new_target, TNode< IntPtrT > argc, TNode< Context > context)
void GotoIfInitialAddFunctionModified(Variant variant, TNode< NativeContext > native_context, TNode< HeapObject > collection, Label *if_modified)
int GetTableOffset(Variant variant)
void GotoIfCannotBeHeldWeakly(const TNode< Object > obj, Label *if_cannot_be_held_weakly)
void AddConstructorEntry(Variant variant, TNode< Context > context, TNode< JSAny > collection, TNode< Object > add_function, TNode< JSAny > key_value, Label *if_may_have_side_effects=nullptr, Label *if_exception=nullptr, TVariable< Object > *var_exception=nullptr)
TNode< BoolT > HasInitialCollectionPrototype(Variant variant, TNode< Context > native_context, TNode< JSAny > collection)
TNode< JSObject > AllocateJSCollectionSlow(TNode< Context > context, TNode< JSFunction > constructor, TNode< JSReceiver > new_target)
void AddConstructorEntriesFromIterable(Variant variant, TNode< Context > context, TNode< Context > native_context, TNode< JSAny > collection, TNode< JSAny > iterable, Label *if_exception, TVariable< JSReceiver > *var_iterator, TVariable< Object > *var_exception)
TNode< JSObject > AllocateJSCollectionFast(TNode< JSFunction > constructor)
TNode< JSArray > AllocateJSArray(ElementsKind kind, TNode< Map > array_map, TNode< IntPtrT > capacity, TNode< Smi > length, std::optional< TNode< AllocationSite > > allocation_site, AllocationFlags allocation_flags=AllocationFlag::kNone)
TNode< Smi > SmiFromInt32(TNode< Int32T > value)
TNode< BoolT > IsNullOrUndefined(TNode< Object > object)
TNode< FixedArrayBase > AllocateFixedArray(ElementsKind kind, TNode< TIndex > capacity, AllocationFlags flags=AllocationFlag::kNone, std::optional< TNode< Map > > fixed_array_map=std::nullopt)
TNode< Uint32T > LoadNameHash(TNode< Name > name, Label *if_hash_not_computed=nullptr)
TNode< IntPtrT > LoadAndUntagPositiveSmiObjectField(TNode< HeapObject > object, int offset)
TNode< Int32T > TruncateIntPtrToInt32(TNode< IntPtrT > value)
void SetPendingMessage(TNode< Union< Hole, JSMessageObject > > message)
TNode< BoolT > InstanceTypeEqual(TNode< Int32T > instance_type, int type)
TNode< BoolT > IsFastSmiOrTaggedElementsKind(TNode< Int32T > elements_kind)
TNode< BoolT > IsSymbolInstanceType(TNode< Int32T > instance_type)
TNode< Uint32T > PositiveSmiToUint32(TNode< Smi > value)
void StoreFixedArrayElement(TNode< FixedArray > object, int index, TNode< Object > value, WriteBarrierMode barrier_mode=UPDATE_WRITE_BARRIER, CheckBounds check_bounds=CheckBounds::kAlways)
TNode< Object > UnsafeLoadFixedArrayElement(TNode< FixedArray > object, TNode< IntPtrT > index, int additional_offset=0)
TNode< HeapObject > AllocateInNewSpace(TNode< IntPtrT > size, AllocationFlags flags=AllocationFlag::kNone)
TNode< BoolT > IsJSReceiver(TNode< HeapObject > object)
TNode< Smi > SmiFromIntPtr(TNode< IntPtrT > value)
void ThrowTypeError(TNode< Context > context, MessageTemplate message, char const *arg0=nullptr, char const *arg1=nullptr)
TNode< JSAny > GetProperty(TNode< Context > context, TNode< JSAny > receiver, Handle< Name > name)
TNode< Smi > SmiTag(TNode< IntPtrT > value)
void Increment(TVariable< TIndex > *variable, int value=1)
void BranchIfStringEqual(TNode< String > lhs, TNode< String > rhs, Label *if_true, Label *if_false, TVariable< Boolean > *result=nullptr)
TNode< BoolT > TaggedEqual(TNode< AnyTaggedT > a, TNode< AnyTaggedT > b)
void StoreObjectFieldRoot(TNode< HeapObject > object, int offset, RootIndex root)
TNode< FixedArrayBase > LoadElements(TNode< JSObject > object)
TNode< T > LoadObjectField(TNode< HeapObject > object, int offset)
TNode< IntPtrT > ChangePositiveInt32ToIntPtr(TNode< Int32T > input)
TNode< JSPrototype > LoadMapPrototype(TNode< Map > map)
TNode< ArrayList > ArrayListAdd(TNode< ArrayList > array, TNode< Object > object)
TNode< Uint32T > LoadJSReceiverIdentityHash(TNode< JSReceiver > receiver, Label *if_no_hash=nullptr)
TNode< IntPtrT > SmiUntag(TNode< Smi > value)
TNode< Map > LoadJSArrayElementsMap(ElementsKind kind, TNode< NativeContext > native_context)
void BuildFastLoop(const VariableList &vars, TVariable< TIndex > &var_index, TNode< TIndex > start_index, TNode< TIndex > end_index, const FastLoopBody< TIndex > &body, TNode< TIndex > increment, LoopUnrollingMode unrolling_mode, IndexAdvanceMode advance_mode, IndexAdvanceDirection advance_direction)
TNode< ArrayList > AllocateArrayList(TNode< Smi > size)
TNode< Float64T > SmiToFloat64(TNode< Smi > value)
TNode< Int32T > LoadElementsKind(TNode< HeapObject > object)
TNode< BoolT > IsBigIntInstanceType(TNode< Int32T > instance_type)
TNode< Int32T > LoadAndUntagToWord32ObjectField(TNode< HeapObject > object, int offset)
void StoreObjectFieldNoWriteBarrier(TNode< HeapObject > object, TNode< IntPtrT > offset, TNode< T > value)
TNode< Object > LoadFixedArrayElement(TNode< FixedArray > object, TNode< TIndex > index, int additional_offset=0, CheckBounds check_bounds=CheckBounds::kAlways)
TNode< JSAny > Call(TNode< Context > context, TNode< TCallable > callable, ConvertReceiverMode mode, TNode< JSAny > receiver, TArgs... args)
TNode< BoolT > IsJSReceiverInstanceType(TNode< Int32T > instance_type)
TNode< Uint16T > LoadMapInstanceType(TNode< Map > map)
TNode< IntPtrT > ElementOffsetFromIndex(TNode< TIndex > index, ElementsKind kind, int base_size=0)
void UnsafeStoreFixedArrayElement(TNode< FixedArray > object, int index, TNode< Object > value, WriteBarrierMode barrier_mode=UPDATE_WRITE_BARRIER)
TNode< HeapNumber > AllocateHeapNumberWithValue(TNode< Float64T > value)
void ArrayListSet(TNode< ArrayList > array, TNode< Smi > index, TNode< Object > object)
TNode< Uint16T > LoadInstanceType(TNode< HeapObject > object)
void ArrayListSetLength(TNode< ArrayList > array, TNode< Smi > length)
TNode< BoolT > IsConstructorMap(TNode< Map > map)
TNode< Smi > NoContextConstant()
TNode< NativeContext > LoadNativeContext(TNode< Context > context)
TNode< OrderedHashSet > AllocateOrderedHashSet()
TNode< T > Select(TNode< BoolT > condition, const NodeGenerator< T > &true_body, const NodeGenerator< T > &false_body, BranchHint branch_hint=BranchHint::kNone)
TNode< BoolT > TaggedIsSmi(TNode< MaybeObject > a)
TNode< Smi > LoadFastJSArrayLength(TNode< JSArray > array)
TNode< IntPtrT > HashTableComputeCapacity(TNode< IntPtrT > at_least_space_for)
TNode< Float64T > LoadHeapNumberValue(TNode< HeapObject > object)
TNode< OrderedHashMap > AllocateOrderedHashMap()
TNode< Float64T > LoadFixedDoubleArrayElement(TNode< FixedDoubleArray > object, TNode< IntPtrT > index, Label *if_hole=nullptr, MachineType machine_type=MachineType::Float64())
TNode< Map > LoadMap(TNode< HeapObject > object)
TNode< BoolT > IsString(TNode< HeapObject > object)
TNode< Int32T > SmiToInt32(TNode< Smi > value)
TNode< JSObject > AllocateJSObjectFromMap(TNode< Map > map, std::optional< TNode< HeapObject > > properties=std::nullopt, std::optional< TNode< FixedArray > > elements=std::nullopt, AllocationFlags flags=AllocationFlag::kNone, SlackTrackingMode slack_tracking_mode=kNoSlackTracking)
TNode< Union< Hole, JSMessageObject > > GetPendingMessage()
Uint32LessThanOrEqual IntPtrGreaterThanOrEqual
TNode< BoolT > IsStringInstanceType(TNode< Int32T > instance_type)
TNode< BoolT > IsAlwaysSharedSpaceJSObjectInstanceType(TNode< Int32T > instance_type)
TNode< IntPtrT > PositiveSmiUntag(TNode< Smi > value)
TNode< BoolT > IsCallable(TNode< HeapObject > object)
TNode< BoolT > IsBigInt(TNode< HeapObject > object)
void StoreObjectField(TNode< HeapObject > object, int offset, TNode< Smi > value)
void BranchIfFloat64IsNaN(TNode< Float64T > value, Label *if_true, Label *if_false)
void FillFixedArrayWithValue(ElementsKind kind, TNode< FixedArrayBase > array, TNode< TIndex > from_index, TNode< TIndex > to_index, RootIndex value_root_index)
void StoreMapNoWriteBarrier(TNode< HeapObject > object, RootIndex map_root_index)
void BranchIfSetIteratorProtectorValid(Label *if_true, Label *if_false)
TNode< BoolT > TableHasKey(const TNode< Object > context, TNode< OrderedHashSet > table, TNode< Object > key)
void SameValueZeroBigInt(TNode< BigInt > key, TNode< Object > candidate_key, Label *if_same, Label *if_not_same)
void BranchIfIterableWithOriginalValueSetIterator(TNode< Object > iterable, TNode< Context > context, Label *if_true, Label *if_false)
const TNode< JSAny > NormalizeNumberKey(const TNode< JSAny > key)
void SameValueZeroHeapNumber(TNode< Float64T > key_float, TNode< Object > candidate_key, Label *if_same, Label *if_not_same)
TorqueStructKeyValueIndexTuple NextKeyValueIndexTuple(const TNode< OrderedHashMap > table, const TNode< IntPtrT > index, Label *if_end)
void TryLookupOrderedHashTableIndex(const TNode< CollectionType > table, const TNode< Object > key, TVariable< IntPtrT > *result, Label *if_entry_found, Label *if_not_found)
void AddConstructorEntriesFromFastCollection(Variant variant, TNode< HeapObject > collection, TNode< HeapObject > source_table) override
TorqueStructKeyValueIndexTuple NextKeyValueIndexTupleUnmodifiedTable(const TNode< OrderedHashMap > table, const TNode< Int32T > number_of_buckets, const TNode< Int32T > used_capacity, const TNode< IntPtrT > index, Label *if_end)
TNode< Smi > CallGetOrCreateHashRaw(const TNode< HeapObject > key)
void StoreKeyInOrderedHashSetEntry(const TNode< OrderedHashSet > table, const TNode< Object > key, const TNode< IntPtrT > entry, CheckBounds check_bounds=CheckBounds::kAlways)
TNode< JSArray > MapIteratorToList(TNode< Context > context, TNode< JSMapIterator > iterator)
const TNode< OrderedHashMap > AddValueToKeyedGroup(const TNode< OrderedHashMap > groups, const TNode< Object > key, const TNode< Object > value, const TNode< String > methodName)
void StoreKeyValueInOrderedHashMapEntry(const TNode< OrderedHashMap > table, const TNode< Object > key, const TNode< Object > value, const TNode< IntPtrT > entry, CheckBounds check_bounds=CheckBounds::kAlways)
TNode< JSAny > LoadKeyFromOrderedHashTableEntry(const TNode< CollectionType > table, const TNode< IntPtrT > entry, CheckBounds check_bounds=CheckBounds::kAlways)
void FindOrderedHashTableEntry(const TNode< CollectionType > table, const TNode< Uint32T > hash, const std::function< void(TNode< Object >, Label *, Label *)> &key_compare, TVariable< IntPtrT > *entry_start_position, Label *entry_found, Label *not_found)
void StoreOrderedHashTableNewEntry(const TNode< CollectionType > table, const TNode< IntPtrT > hash, const TNode< IntPtrT > number_of_buckets, const TNode< IntPtrT > occupancy, const StoreAtEntry< CollectionType > &store_at_new_entry)
TNode< UnionOf< JSAny, ArrayList > > LoadValueFromOrderedHashMapEntry(const TNode< OrderedHashMap > table, const TNode< IntPtrT > entry, CheckBounds check_bounds=CheckBounds::kAlways)
void FindOrderedHashTableEntryForSmiKey(TNode< CollectionType > table, TNode< Smi > key_tagged, TVariable< IntPtrT > *result, Label *entry_found, Label *not_found)
void BranchIfIterableWithOriginalKeyOrValueMapIterator(TNode< Object > iterable, TNode< Context > context, Label *if_true, Label *if_false)
void SameValueZeroString(TNode< String > key_string, TNode< Object > candidate_key, Label *if_same, Label *if_not_same)
void FindOrderedHashTableEntryForStringKey(TNode< CollectionType > table, TNode< String > key_tagged, TVariable< IntPtrT > *result, Label *entry_found, Label *not_found)
TNode< JSAny > UnsafeLoadKeyFromOrderedHashTableEntry(const TNode< CollectionType > table, const TNode< IntPtrT > entry)
void BranchIfMapIteratorProtectorValid(Label *if_true, Label *if_false)
TNode< JSArray > SetOrSetIteratorToList(TNode< Context > context, TNode< HeapObject > iterable)
void FindOrderedHashTableEntryForOtherKey(TNode< CollectionType > table, TNode< HeapObject > key_heap_object, TVariable< IntPtrT > *result, Label *entry_found, Label *not_found)
std::tuple< TNode< JSAny >, TNode< IntPtrT >, TNode< IntPtrT > > NextSkipHashTableHoles(TNode< TableType > table, TNode< IntPtrT > index, Label *if_end)
TNode< Uint32T > ComputeStringHash(TNode< String > string_key)
std::pair< TNode< TableType >, TNode< IntPtrT > > TransitionAndUpdate(const TNode< IteratorType > iterator)
TorqueStructKeyIndexPair NextKeyIndexPairUnmodifiedTable(const TNode< CollectionType > table, const TNode< Int32T > number_of_buckets, const TNode< Int32T > used_capacity, const TNode< IntPtrT > index, Label *if_end)
void FindOrderedHashTableEntryForHeapNumberKey(TNode< CollectionType > table, TNode< HeapNumber > key_heap_number, TVariable< IntPtrT > *result, Label *entry_found, Label *not_found)
TorqueStructOrderedHashSetIndexPair TransitionOrderedHashSetNoUpdate(const TNode< OrderedHashSet > table, const TNode< IntPtrT > index)
void AddNewToOrderedHashTable(const TNode< CollectionType > table, const TNode< Object > normalised_key, const TNode< IntPtrT > number_of_buckets, const TNode< IntPtrT > occupancy, const StoreAtEntry< CollectionType > &store_at_new_entry)
void SameValueZeroSmi(TNode< Smi > key_smi, TNode< Object > candidate_key, Label *if_same, Label *if_not_same)
std::function< void(const TNode< TableType > table, const TNode< IntPtrT > index)> UpdateInTransition
void FindOrderedHashTableEntryForBigIntKey(TNode< CollectionType > table, TNode< BigInt > key_big_int, TVariable< IntPtrT > *result, Label *entry_found, Label *not_found)
TNode< UnionOf< JSAny, ArrayList > > UnsafeLoadValueFromOrderedHashMapEntry(const TNode< OrderedHashMap > table, const TNode< IntPtrT > entry)
TorqueStructKeyIndexPair NextKeyIndexPair(const TNode< CollectionType > table, const TNode< IntPtrT > index, Label *if_end)
TNode< HeapObject > AllocateJSCollectionIterator(const TNode< Context > context, int map_index, const TNode< HeapObject > collection)
void GetEntriesIfFastCollectionOrIterable(Variant variant, TNode< Object > initial_entries, TNode< Context > context, TVariable< HeapObject > *var_entries_table, TVariable< IntPtrT > *var_number_of_elements, Label *if_not_fast_collection) override
std::function< void(const TNode< CollectionType > table, const TNode< IntPtrT > entry_start)> StoreAtEntry
TNode< OrderedHashSet > AddToSetTable(TNode< Object > context, TNode< OrderedHashSet > table, TNode< JSAny > key, TNode< String > method_name)
void StoreValueInOrderedHashMapEntry(const TNode< OrderedHashMap > table, const TNode< Object > value, const TNode< IntPtrT > entry, CheckBounds check_bounds=CheckBounds::kAlways)
void AddNewToOrderedHashSet(const TNode< OrderedHashSet > table, const TNode< JSAny > key, const TNode< IntPtrT > number_of_buckets, const TNode< IntPtrT > occupancy)
void UnsafeStoreKeyInOrderedHashSetEntry(const TNode< OrderedHashSet > table, const TNode< Object > key, const TNode< IntPtrT > entry)
TNode< Word32T > ComputeUnseededHash(TNode< IntPtrT > key)
TNode< CollectionType > AddToOrderedHashTable(const TNode< CollectionType > table, const TNode< Object > key, const GrowCollection< CollectionType > &grow, const StoreAtEntry< CollectionType > &store_at_new_entry, const StoreAtEntry< CollectionType > &store_at_existing_entry)
TNode< Uint32T > CallGetHashRaw(const TNode< HeapObject > key)
TNode< Smi > DeleteFromSetTable(const TNode< Object > context, TNode< OrderedHashSet > table, TNode< Object > key, Label *not_found)
TNode< OrderedHashSet > SetOrSetIteratorToSet(TNode< Object > iterator)
std::pair< TNode< TableType >, TNode< IntPtrT > > Transition(const TNode< TableType > table, const TNode< IntPtrT > index, UpdateInTransition< TableType > const &update_in_transition)
TNode< HeapObject > AllocateTable(Variant variant, TNode< IntPtrT > at_least_space_for) override
std::function< const TNode< CollectionType >()> GrowCollection
void AddConstructorEntriesFromSet(TNode< JSSet > collection, TNode< OrderedHashSet > table)
TNode< Uint32T > GetHash(const TNode< HeapObject > key)
TNode< JSObject > FastNewObject(TNode< Context > context, TNode< JSFunction > target, TNode< JSReceiver > new_target)
static const bool kDoHashSpreading
static const uint32_t kHashBits
static V8_EXPORT_PRIVATE ExternalReference isolate_address()
v8::internal::Factory * factory()
TNode< JSReceiver > IteratorStep(TNode< Context > context, const IteratorRecord &iterator, Label *if_done, std::optional< TNode< Map > > fast_iterator_result_map=std::nullopt)
TNode< JSAny > IteratorValue(TNode< Context > context, TNode< JSReceiver > result, std::optional< TNode< Map > > fast_iterator_result_map=std::nullopt)
IteratorRecord GetIterator(TNode< Context > context, TNode< JSAny > object)
static const int kAddFunctionDescriptorIndex
static const int kAddFunctionDescriptorIndex
static constexpr MachineType Pointer()
static constexpr MachineType AnyTagged()
static const int kValueOffset
static const int kEntrySize
static constexpr int NextTableOffset()
static constexpr int RemovedHolesIndex()
static constexpr int HashTableStartIndex()
static const int kInitialCapacity
static const int kClearedTableSentinel
static constexpr int NumberOfElementsOffset()
static constexpr int NumberOfDeletedElementsOffset()
static constexpr int NumberOfBucketsIndex()
static const int kProtectorValid
@ kCheckPrototypePropertyConstness
@ kCheckPrototypePropertyIdentity
void CheckAndBranch(TNode< HeapObject > prototype, Label *if_unmodified, Label *if_modified)
TNode< Int32T > LoadNumberOfElements(TNode< EphemeronHashTable > table, int offset)
TNode< IntPtrT > GetHash(const TNode< HeapObject > key, Label *if_no_hash)
TNode< IntPtrT > LoadTableCapacity(TNode< EphemeronHashTable > table)
TNode< BoolT > ShouldRehash(TNode< Int32T > number_of_elements, TNode< Int32T > number_of_deleted)
TNode< IntPtrT > KeyIndexFromEntry(TNode< IntPtrT > entry)
std::function< void(TNode< Object > entry_key, Label *if_same)> KeyComparator
TNode< IntPtrT > FindKeyIndex(TNode< HeapObject > table, TNode< IntPtrT > key_hash, TNode< IntPtrT > capacity, const KeyComparator &key_compare)
TNode< Smi > CreateIdentityHash(TNode< Object > receiver)
TNode< Word32T > InsufficientCapacityToAdd(TNode< Int32T > capacity, TNode< Int32T > number_of_elements, TNode< Int32T > number_of_deleted)
void AddEntry(TNode< EphemeronHashTable > table, TNode< IntPtrT > key_index, TNode< Object > key, TNode< Object > value, TNode< Int32T > number_of_elements)
TNode< HeapObject > AllocateTable(Variant variant, TNode< IntPtrT > at_least_space_for) override
TNode< IntPtrT > FindKeyIndexForInsertion(TNode< HeapObject > table, TNode< IntPtrT > key_hash, TNode< IntPtrT > capacity)
void RemoveEntry(TNode< EphemeronHashTable > table, TNode< IntPtrT > key_index, TNode< IntPtrT > number_of_elements)
TNode< Word32T > ShouldShrink(TNode< IntPtrT > capacity, TNode< IntPtrT > number_of_elements)
TNode< IntPtrT > ValueIndexFromKeyIndex(TNode< IntPtrT > key_index)
TNode< IntPtrT > FindKeyIndexForKey(TNode< HeapObject > table, TNode< Object > key, TNode< IntPtrT > hash, TNode< IntPtrT > capacity, Label *if_not_found)
TNode< IntPtrT > EntryMask(TNode< IntPtrT > capacity)
TNode< EphemeronHashTable > LoadTable(TNode< JSWeakCollection > collection)
TNode< IntPtrT > Coefficient(TNode< IntPtrT > capacity)
TNode< Int32T > LoadNumberOfDeleted(TNode< EphemeronHashTable > table, int offset=0)
CodeAssemblerState * state()
TNode< IntPtrT > IntPtrMul(TNode< IntPtrT > left, TNode< IntPtrT > right)
TNode< IntPtrT > IntPtrAdd(TNode< IntPtrT > left, TNode< IntPtrT > right)
TNode< Int32T > Signed(TNode< Word32T > x)
TNode< IntPtrT > IntPtrConstant(intptr_t value)
TNode< UintPtrT > ChangeUint32ToWord(TNode< Word32T > value)
TNode< T > UncheckedCast(Node *value)
TNode< IntPtrT > WordShl(TNode< IntPtrT > left, TNode< IntegralT > right)
TNode< Int32T > Int32Mul(TNode< Int32T > left, TNode< Int32T > right)
void GotoIfNot(TNode< IntegralT > condition, Label *false_label, GotoHint goto_hint=GotoHint::kNone)
void Return(TNode< Object > value)
Isolate * isolate() const
TNode< Uint32T > Unsigned(TNode< Word32T > x)
TNode< Int32T > Word32And(TNode< Int32T > left, TNode< Int32T > right)
TNode< Int32T > Int32Add(TNode< Int32T > left, TNode< Int32T > right)
TNode< Smi > SmiConstant(Tagged< Smi > value)
void GotoIf(TNode< IntegralT > condition, Label *true_label, GotoHint goto_hint=GotoHint::kNone)
TNode< IntPtrT > ChangeInt32ToIntPtr(TNode< Word32T > value)
TNode< Int32T > Int32Sub(TNode< Int32T > left, TNode< Int32T > right)
TNode< Int32T > Word32Or(TNode< Int32T > left, TNode< Int32T > right)
TNode< Int32T > Word32Shl(TNode< Int32T > left, TNode< Int32T > right)
TNode< BoolT > IntPtrEqual(TNode< WordT > left, TNode< WordT > right)
TNode< IntPtrT > WordAnd(TNode< IntPtrT > left, TNode< IntPtrT > right)
TNode< IntPtrT > IntPtrSub(TNode< IntPtrT > left, TNode< IntPtrT > right)
TNode< Uint32T > Uint32Sub(TNode< Uint32T > left, TNode< Uint32T > right)
TNode< Float64T > Float64Constant(double value)
TNode< Uint32T > Word32Shr(TNode< Uint32T > left, TNode< Uint32T > right)
TNode< ExternalReference > ExternalConstant(ExternalReference address)
TNode< Int32T > Int32Constant(int32_t value)
Node * CallCFunction(Node *function, std::optional< MachineType > return_type, CArgs... cargs)
TNode< Uint32T > Uint32Constant(uint32_t value)
TNode< Type > HeapConstantNoHole(Handle< Type > object)
TNode< BoolT > Word32Equal(TNode< Word32T > left, TNode< Word32T > right)
TNode< T > CallRuntime(Runtime::FunctionId function, TNode< Object > context, TArgs... args)
void Store(Node *base, Node *value)
TNode< UintPtrT > WordShr(TNode< UintPtrT > left, TNode< IntegralT > right)
TNode< T > CallBuiltin(Builtin id, TNode< Object > context, TArgs... args)
void Branch(TNode< IntegralT > condition, Label *true_label, Label *false_label, BranchHint branch_hint=BranchHint::kNone)
base::Vector< const DirectHandle< Object > > args
DirectHandle< Object > new_target
ZoneVector< RpoNumber > & result
void BranchIfIterableWithOriginalKeyOrValueMapIterator(compiler::CodeAssemblerState *state, TNode< Object > iterable, TNode< Context > context, compiler::CodeAssemblerLabel *if_true, compiler::CodeAssemblerLabel *if_false)
constexpr int kTaggedSize
@ UPDATE_EPHEMERON_KEY_WRITE_BARRIER
Handle< To > UncheckedCast(Handle< From > value)
DONT_OVERRIDE DISABLE_ALLOCATION_SITES HOLEY_ELEMENTS
void BranchIfIterableWithOriginalValueSetIterator(compiler::CodeAssemblerState *state, TNode< Object > iterable, TNode< Context > context, compiler::CodeAssemblerLabel *if_true, compiler::CodeAssemblerLabel *if_false)
!IsContextMap !IsContextMap native_context
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
#define DCHECK_LE(v1, v2)
#define DCHECK_GE(v1, v2)
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)
#define OFFSET_OF_DATA_START(Type)