31constexpr int kDummyEnumerationIndex = 0;
35 using Flags = ClassBoilerplate::ComputedEntryFlags;
36 int flags = Flags::ValueKindBits::encode(value_kind) |
37 Flags::KeyIndexBits::encode(key_index);
46 pair->set_getter(index);
49 pair->set_setter(index);
53 pair->set_getter(index);
66 pair->set_getter(index, tag);
69 pair->set_setter(index, tag);
73 pair->set_getter(index, tag);
81template <
typename IsolateT>
82void AddToDescriptorArrayTemplate(
83 IsolateT* isolate, DirectHandle<DescriptorArray> descriptor_array_template,
85 DirectHandle<Object> value) {
86 InternalIndex entry = descriptor_array_template->Search(
87 *name, descriptor_array_template->number_of_descriptors());
90 if (entry.is_not_found()) {
99 DirectHandle<AccessorPair> pair = isolate->factory()->NewAccessorPair();
100 SetAccessorPlaceholderIndices(*pair, value_kind,
Cast<Smi>(*value));
103 descriptor_array_template->Append(&d);
107 int sorted_index = descriptor_array_template->GetDetails(entry).pointer();
110 d.SetSortedKeyIndex(sorted_index);
111 descriptor_array_template->Set(entry, &d);
117 descriptor_array_template->GetStrongValue(entry);
119 if (IsAccessorPair(raw_accessor)) {
122 DirectHandle<AccessorPair> new_pair =
123 isolate->factory()->NewAccessorPair();
125 d.SetSortedKeyIndex(sorted_index);
126 descriptor_array_template->Set(entry, &d);
129 SetAccessorPlaceholderIndices(pair, value_kind,
Cast<Smi>(*value),
135template <
typename IsolateT>
138 DirectHandle<Name> name, DirectHandle<Object> value,
139 PropertyDetails details, InternalIndex* entry_out =
nullptr) {
140 return NameDictionary::AddNoUpdateNextEnumerationIndex(
141 isolate, dictionary, name, value, details, entry_out);
144template <
typename IsolateT>
147 DirectHandle<Name> name, DirectHandle<Object> value,
148 PropertyDetails details, InternalIndex* entry_out =
nullptr) {
154template <
typename IsolateT>
155DirectHandle<NumberDictionary> DictionaryAddNoUpdateNextEnumerationIndex(
157 DirectHandle<Object> value, PropertyDetails details,
158 InternalIndex* entry_out =
nullptr) {
161 return NumberDictionary::Add(isolate, dictionary, element, value, details,
167template <
template <
typename>
typename HandleType,
typename Dictionary>
168void DictionaryUpdateMaxNumberKey(HandleType<Dictionary> dictionary,
169 DirectHandle<Name> name)
171 std::is_convertible_v<HandleType<Dictionary>, DirectHandle<Dictionary>>)
173 static_assert((std::is_same_v<Dictionary, SwissNameDictionary> ||
174 std::is_same_v<Dictionary, NameDictionary>));
178void DictionaryUpdateMaxNumberKey(DirectHandle<NumberDictionary> dictionary,
180 dictionary->UpdateMaxNumberKey(element, DirectHandle<JSObject>());
181 dictionary->set_requires_slow_elements();
184constexpr int ComputeEnumerationIndex(
int value_index) {
193constexpr int kAccessorNotDefined = -1;
199template <
typename IsolateT,
typename Dictionary,
typename Key>
201 Key
key,
int key_index,
204 InternalIndex entry = dictionary->FindEntry(isolate,
key);
206 const bool is_elements_dictionary =
207 std::is_same_v<Dictionary, NumberDictionary>;
208 static_assert(is_elements_dictionary !=
209 (std::is_same_v<Dictionary, NameDictionary> ||
210 std::is_same_v<Dictionary, SwissNameDictionary>));
212 if (entry.is_not_found()) {
215 Dictionary::kIsOrderedDictionaryType || is_elements_dictionary
216 ? kDummyEnumerationIndex
217 : ComputeEnumerationIndex(key_index);
218 DirectHandle<Object> value_handle;
219 PropertyDetails details(
229 DirectHandle<AccessorPair> pair(isolate->factory()->NewAccessorPair());
230 SetAccessorPlaceholderIndices(*pair, value_kind,
Cast<Smi>(value));
235 DirectHandle<Dictionary> dict = DictionaryAddNoUpdateNextEnumerationIndex(
236 isolate, dictionary,
key, value_handle, details, &entry);
242 DictionaryUpdateMaxNumberKey(dictionary,
key);
246 int enum_order_existing =
247 Dictionary::kIsOrderedDictionaryType
248 ? kDummyEnumerationIndex
249 : dictionary->DetailsAt(entry).dictionary_index();
250 int enum_order_computed =
251 Dictionary::kIsOrderedDictionaryType || is_elements_dictionary
252 ? kDummyEnumerationIndex
253 : ComputeEnumerationIndex(key_index);
258 if (IsAccessorPair(existing_value)) {
261 int existing_getter_index =
262 GetExistingValueIndex(current_pair->getter());
263 int existing_setter_index =
264 GetExistingValueIndex(current_pair->setter());
266 static_assert(kAccessorNotDefined < 0);
267 DCHECK(existing_getter_index >= 0 || existing_setter_index >= 0);
268 if (existing_getter_index < key_index &&
269 existing_setter_index < key_index) {
273 PropertyDetails details(
276 enum_order_existing);
277 dictionary->DetailsAtPut(entry, details);
278 dictionary->ValueAtPut(entry, value);
280 }
else if (existing_getter_index != kAccessorNotDefined &&
281 existing_getter_index < key_index) {
282 DCHECK_LT(key_index, existing_setter_index);
287 current_pair->set_getter(*isolate->factory()->null_value());
289 }
else if (existing_setter_index != kAccessorNotDefined &&
290 existing_setter_index < key_index) {
291 DCHECK_LT(key_index, existing_getter_index);
296 current_pair->set_setter(*isolate->factory()->null_value());
306 DCHECK(key_index < existing_getter_index ||
307 existing_getter_index == kAccessorNotDefined);
308 DCHECK(key_index < existing_setter_index ||
309 existing_setter_index == kAccessorNotDefined);
310 DCHECK(existing_getter_index != kAccessorNotDefined ||
311 existing_setter_index != kAccessorNotDefined);
312 if (!is_elements_dictionary) {
316 PropertyDetails details = dictionary->DetailsAt(entry);
317 details = details.set_index(enum_order_computed);
318 dictionary->DetailsAtPut(entry, details);
327 *isolate->factory()->length_string() ||
329 *isolate->factory()->name_string());
330 if (!
IsSmi(existing_value) ||
Smi::ToInt(existing_value) < key_index) {
334 PropertyDetails details(
337 enum_order_existing);
338 dictionary->DetailsAtPut(entry, details);
339 dictionary->ValueAtPut(entry, value);
343 if (!is_elements_dictionary) {
347 PropertyDetails details(
350 enum_order_computed);
352 dictionary->DetailsAtPut(entry, details);
357 if (IsAccessorPair(existing_value)) {
361 bool updated =
false;
362 switch (value_kind) {
364 int existing_get_component_index =
366 int existing_set_component_index =
368 if (existing_get_component_index < key_index &&
369 existing_set_component_index < key_index) {
370 SetAccessorPlaceholderIndices(current_pair, value_kind, value,
374 if (existing_get_component_index < key_index) {
375 SetAccessorPlaceholderIndices(current_pair,
379 }
else if (existing_set_component_index < key_index) {
380 SetAccessorPlaceholderIndices(
393 int existing_component_index =
394 GetExistingValueIndex(current_pair->get(component));
395 if (existing_component_index < key_index) {
396 SetAccessorPlaceholderIndices(current_pair, value_kind, value,
409 if (!is_elements_dictionary) {
414 PropertyDetails details(
417 enum_order_computed);
418 dictionary->DetailsAtPut(entry, details);
423 DCHECK(!IsAccessorPair(existing_value));
426 if (!
IsSmi(existing_value) ||
Smi::ToInt(existing_value) < key_index) {
429 DirectHandle<AccessorPair> pair(
430 isolate->factory()->NewAccessorPair());
431 SetAccessorPlaceholderIndices(*pair, value_kind, value);
432 PropertyDetails details(
435 enum_order_existing);
436 dictionary->DetailsAtPut(entry, details);
437 dictionary->ValueAtPut(entry, *pair);
443 if (!is_elements_dictionary) {
447 PropertyDetails details(
450 enum_order_computed);
452 dictionary->DetailsAtPut(entry, details);
464template <
typename IsolateT>
493 auto* factory = isolate->factory();
497 factory->empty_swiss_property_dictionary();
507 isolate->factory()->NewSwissNameDictionary(need_space_for,
524 : factory->empty_slow_element_dictionary();
529 : factory->empty_fixed_array();
536 bool is_accessor = IsAccessorInfo(*value);
537 DCHECK(!IsAccessorPair(*value));
540 is_accessor ? i::PropertyKind::kAccessor : i::PropertyKind::kData;
542 ? kDummyEnumerationIndex
548 DictionaryAddNoUpdateNextEnumerationIndex(
553 DictionaryAddNoUpdateNextEnumerationIndex(
572 AddToDictionaryTemplate(isolate,
574 value_index, value_kind, value);
577 value_index, value_kind, value);
591 value_index, value_kind, value);
595 int value_index = key_index + 1;
598 int flags = EncodeComputedEntry(value_kind, key_index);
603 int current_index = ComputeEnumerationIndex(value_index);
647template <
typename IsolateT,
typename PropertyDict>
651 AddToDictionaryTemplate(isolate, dictionary, name, key_index, value_kind,
664template <
typename IsolateT>
668 AddToDictionaryTemplate(isolate, dictionary,
key, key_index, value_kind,
679template <
typename IsolateT>
686 typename IsolateT::HandleScopeType scope(isolate);
687 auto* factory = isolate->factory();
694 property->is_static() ? static_desc : instance_desc;
695 if (property->is_computed_name()) {
697 desc.IncComputedCount();
700 if (property->key()->AsLiteral()->IsPropertyName()) {
701 desc.IncPropertiesCount();
703 desc.IncElementsCount();
712 static_assert(JSFunction::kLengthDescriptorIndex == 0);
717 static_desc.
AddConstant(isolate, factory->length_string(),
718 factory->function_length_accessor(), attribs);
725 static_desc.
AddConstant(isolate, factory->name_string(),
726 factory->function_name_accessor(), attribs);
732 static_desc.
AddConstant(isolate, factory->prototype_string(),
733 factory->function_prototype_accessor(), attribs);
738 static_desc.
AddConstant(isolate, factory->class_positions_symbol(),
749 instance_desc.
AddConstant(isolate, factory->constructor_string(), value,
761 int value_index = dynamic_argument_index;
762 switch (property->kind()) {
773 DCHECK_IMPLIES(property->is_computed_name(), !property->is_private());
774 if (property->is_computed_name()) {
775 ++dynamic_argument_index;
781 ++dynamic_argument_index;
785 property->is_static() ? static_desc : instance_desc;
786 if (property->is_computed_name()) {
787 int computed_name_index = value_index;
788 dynamic_argument_index += 2;
789 desc.AddComputed(value_kind, computed_name_index);
792 dynamic_argument_index++;
794 Literal* key_literal = property->key()->AsLiteral();
797 desc.AddIndexedProperty(isolate, index, value_kind, value_index);
801 DCHECK(IsInternalizedString(*name));
802 desc.AddNamedProperty(isolate, name, value_kind, value_index);
810 factory->NewStruct(CLASS_BOILERPLATE_TYPE, allocation));
812 result->set_arguments_count(dynamic_argument_index);
818 result->set_instance_properties_template(
821 result->set_instance_computed_properties(
824 return scope.CloseAndEscape(
result);
834 <<
Brief(constant_elements());
839 static_assert(JSRegExp::kDataOffset == JSObject::kHeaderSize);
840 static_assert(JSRegExp::kSourceOffset == JSRegExp::kDataOffset +
kTaggedSize);
841 static_assert(JSRegExp::kFlagsOffset ==
843 static_assert(JSRegExp::kHeaderSize == JSRegExp::kFlagsOffset +
kTaggedSize);
union v8::internal::@341::BuiltinMetadata::KindSpecificData data
ElementsKind elements_kind() const
void BriefPrintDetails(std::ostream &os)
static const int kMinimumPrototypePropertiesCount
static void AddToPropertiesTemplate(IsolateT *isolate, Handle< Dictionary > dictionary, Handle< Name > name, int key_index, ValueKind value_kind, Tagged< Smi > value)
static const int kMinimumClassPropertiesCount
static void AddToElementsTemplate(IsolateT *isolate, Handle< NumberDictionary > dictionary, uint32_t key, int key_index, ValueKind value_kind, Tagged< Smi > value)
static Handle< ClassBoilerplate > New(IsolateT *isolate, ClassLiteral *expr, AllocationType allocation=AllocationType::kYoung)
@ kFirstDynamicArgumentIndex
@ kConstructorArgumentIndex
int start_position() const
ZonePtrList< Property > * public_members() const
static V8_EXPORT_PRIVATE Handle< DescriptorArray > Allocate(IsolateT *isolate, int nof_descriptors, int slack, AllocationType allocation=AllocationType::kYoung)
static Descriptor AccessorConstant(DirectHandle< Name > key, DirectHandle< Object > foreign, PropertyAttributes attributes)
static Descriptor DataConstant(DirectHandle< Name > key, DirectHandle< Object > value, PropertyAttributes attributes)
void PatchValue(Tagged< T > new_value)
bool AsArrayIndex(uint32_t *index) const
const AstRawString * AsRawPropertyName()
static V8_WARN_UNUSED_RESULT Handle< NameDictionary > New(IsolateT *isolate, int at_least_space_for, AllocationType allocation=AllocationType::kYoung, MinimumCapacity capacity_option=USE_DEFAULT_MINIMUM_CAPACITY)
int current_computed_index_
Handle< Object > properties_template() const
const int property_slack_
int next_enumeration_index_
void UpdateNextEnumerationIndex(int value_index)
Handle< NumberDictionary > elements_dictionary_template_
Handle< FixedArray > computed_properties() const
Handle< SwissNameDictionary > properties_ordered_dictionary_template() const
void CreateTemplates(IsolateT *isolate)
void AddConstant(IsolateT *isolate, DirectHandle< Name > name, DirectHandle< Object > value, PropertyAttributes attribs)
bool HasDictionaryProperties() const
void IncPropertiesCount()
Handle< FixedArray > computed_properties_
Handle< HeapObject > properties_dictionary_template_
Handle< DescriptorArray > descriptor_array_template_
void AddComputed(ClassBoilerplate::ValueKind value_kind, int key_index)
void Finalize(IsolateT *isolate)
Handle< NameDictionary > properties_dictionary_template() const
Handle< Object > temp_handle_
ObjectDescriptor(int property_slack)
void AddIndexedProperty(IsolateT *isolate, uint32_t element, ClassBoilerplate::ValueKind value_kind, int value_index)
void AddNamedProperty(IsolateT *isolate, Handle< Name > name, ClassBoilerplate::ValueKind value_kind, int value_index)
Handle< NumberDictionary > elements_template() const
static constexpr PropertyConstness kConstIfDictConstnessTracking
static const int kInitialIndex
void BriefPrintDetails(std::ostream &os)
static constexpr int ToInt(const Tagged< Object > object)
static constexpr Tagged< Smi > FromInt(int value)
static constexpr Tagged< Smi > zero()
static HandleType< SwissNameDictionary > Add(IsolateT *isolate, HandleType< SwissNameDictionary > table, DirectHandle< Name > key, DirectHandle< Object > value, PropertyDetails details, InternalIndex *entry_out=nullptr)
#define V8_ENABLE_SWISS_NAME_DICTIONARY_BOOL
ZoneVector< RpoNumber > & result
InstructionOperand source
V8_INLINE IndirectHandle< T > handle(Tagged< T > object, Isolate *isolate)
V8_EXPORT_PRIVATE base::Vector< Flag > Flags()
constexpr int kTaggedSize
Tagged(T object) -> Tagged< T >
V8_INLINE constexpr bool IsSmi(TaggedImpl< kRefType, StorageType > obj)
V8_INLINE DirectHandle< T > direct_handle(Tagged< T > object, Isolate *isolate)
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
const char * ElementsKindToString(ElementsKind kind)
V8_INLINE IsolateForSandbox GetIsolateForSandbox(Tagged< HeapObject >)
static const int kMaxNumberOfDescriptors
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
static constexpr ReleaseStoreTag kReleaseStore
#define DCHECK_LE(v1, v2)
#define DCHECK_IMPLIES(v1, v2)
#define CHECK_EQ(lhs, rhs)
#define DCHECK(condition)
#define DCHECK_LT(v1, v2)
#define DCHECK_EQ(v1, v2)