51 (*target)->SetBackPointer(*map);
61 isolate->factory()->NewTransitionArray(1, 0);
75 simple_transition->GetLastDescriptorDetails(isolate);
77 if (
key->Equals(*name) && old_details.
kind() == new_details.
kind() &&
86 isolate->factory()->NewTransitionArray(1, 1);
91 if (simple_transition.
is_null()) {
116 result->SetNumberOfTransitions(2);
117 if (insertion_index == 0) {
123 result->SetKey(insertion_index, *name);
135 int number_of_transitions = 0;
147 number_of_transitions = array->number_of_transitions();
150 is_special_transition
151 ? array->SearchSpecial(
Cast<Symbol>(*name),
false, &insertion_index)
157 array->SetRawTarget(index,
MakeWeak(*target));
161 new_nof = number_of_transitions + 1;
164 DCHECK_LE(insertion_index, number_of_transitions);
169 array->SetNumberOfTransitions(new_nof);
170 for (
int i = number_of_transitions;
i > insertion_index; --
i) {
171 array->SetKey(
i, array->GetKey(
i - 1));
172 array->SetRawTarget(
i, array->GetRawTarget(
i - 1));
174 array->SetKey(insertion_index, *name);
175 array->SetRawTarget(insertion_index,
MakeWeak(*target));
191 if (array->number_of_transitions() != number_of_transitions) {
192 DCHECK_LT(array->number_of_transitions(), number_of_transitions);
195 is_special_transition
196 ? array->SearchSpecial(
Cast<Symbol>(*name),
false, &insertion_index)
202 DCHECK_LE(insertion_index, number_of_transitions);
204 number_of_transitions = array->number_of_transitions();
205 new_nof = number_of_transitions + 1;
206 result->SetNumberOfTransitions(new_nof);
209 if (array->HasPrototypeTransitions()) {
210 result->SetPrototypeTransitions(array->GetPrototypeTransitions());
212 if (array->HasSideStepTransitions()) {
213 result->SetSideStepTransitions(array->GetSideStepTransitions());
217 for (
int i = 0;
i < insertion_index; ++
i) {
218 result->Set(
i, array->GetKey(
i), array->GetRawTarget(
i));
221 for (
int i = insertion_index;
i < number_of_transitions; ++
i) {
222 result->Set(
i + 1, array->GetKey(
i), array->GetRawTarget(
i));
263 if (!IsSymbol(name))
return false;
264 return name == roots.nonextensible_symbol() ||
265 name == roots.sealed_symbol() || name == roots.frozen_symbol() ||
266 name == roots.elements_transition_symbol() ||
267 name == roots.strict_function_transition_symbol();
272 DCHECK(IsInternalizedString(*name));
318 if (map->is_dictionary_map())
return false;
336 if (
key != name)
return false;
337 return descriptors->GetDetails(descriptor)
338 .HasKindAndAttributes(
kind, attributes);
350 int new_number_of_transitions = 0;
353 DCHECK(target.IsCleared() ||
354 (target.IsWeak() && IsMap(target.GetHeapObject())));
355 if (!target.IsCleared()) {
356 if (new_number_of_transitions !=
i) {
357 array->set(header + new_number_of_transitions, target);
359 new_number_of_transitions++;
365 array->set(header +
i, undefined);
380 int grow_by = new_capacity - capacity;
382 isolate->factory()->CopyWeakFixedArrayAndGrow(array, grow_by);
397 IsUndefined(map->GetBackPointer()));
411 if (map->is_prototype_map())
return false;
412 if (map->is_dictionary_map() || !
v8_flags.cache_prototype_transitions)
419 int capacity = cache->length() - header;
422 if (transitions > capacity) {
436 cache, 2 * transitions, isolate);
441 if (
v8_flags.move_prototype_transitions_first) {
442 target_map->SetBackPointer(*map);
447 int entry = header + last;
452 cache->set(entry,
MakeWeak(*target_map));
467 DCHECK(target.IsWeakOrCleared());
469 if (target.GetHeapObjectIfWeak(&heap_object)) {
471 if (target_map->prototype() == prototype) {
489 if (!transition_array->HasPrototypeTransitions()) {
492 return transition_array->GetPrototypeTransitions();
498 DCHECK_NE(proto_transitions->length(), 0);
537 DCHECK(map->is_deprecated());
554 CheckNewTransitionsAreConsistent(
555 isolate, map, new_transitions.GetHeapObjectAssumeStrong());
557 new_transitions.GetHeapObjectAssumeStrong());
577 ->SetPrototypeTransitions(*proto_transitions);
589 isolate->factory()->NewTransitionArray(nof);
595 result->SetNumberOfTransitions(0);
610 static constexpr int kStaticStackSize = 16;
615 while (!stack.empty()) {
638 if (transitions->HasPrototypeTransitions()) {
640 transitions->GetPrototypeTransitions();
647 if (target.GetHeapObjectIfWeak(&heap_object)) {
648 stack.emplace_back(
Cast<Map>(heap_object));
650 DCHECK(target.IsCleared());
655 for (
int i = 0;
i < transitions->number_of_transitions(); ++
i) {
656 stack.emplace_back(transitions->GetTarget(
i));
666void TransitionsAccessor::CheckNewTransitionsAreConsistent(
673 for (
int i = 0;
i < old_transitions->number_of_transitions();
i++) {
675 if (old_transitions->GetTargetIfExists(
i, isolate, &target)) {
676 if (target->instance_descriptors(isolate) ==
677 map->instance_descriptors(isolate)) {
679 int new_target_index;
684 new_target_index = new_transitions->Search(details.kind(),
key,
685 details.attributes());
688 DCHECK_EQ(target, new_transitions->GetTarget(new_target_index));
701 int* out_insertion_index) {
703 DCHECK(transition < nof_transitions);
705 for (; transition < nof_transitions &&
GetKey(transition) ==
key;
715 }
else if (cmp < 0) {
719 if (out_insertion_index !=
nullptr) *out_insertion_index = transition;
726 DCHECK(transition < nof_transitions);
728 for (; transition < nof_transitions &&
GetKey(transition) ==
key;
738 }
else if (cmp < 0) {
747 int* out_insertion_index) {
748 int transition =
SearchName(name,
false, out_insertion_index);
769 DCHECK(transition < nof_transitions);
771 for (; transition < nof_transitions &&
GetKey(transition) ==
key;
796 for (j =
i - 1; j >= 0; j--) {
806 temp_kind = details.
kind();
810 CompareKeys(temp_key, temp_key->hash(), temp_kind, temp_attributes,
822 DCHECK(IsSortedNoDuplicates());
830 if (out_integrity_level) *out_integrity_level =
FROZEN;
831 if (out_symbol) *out_symbol = roots.frozen_symbol();
833 if (out_integrity_level) *out_integrity_level =
SEALED;
834 if (out_symbol) *out_symbol = roots.sealed_symbol();
835 }
else if (
SearchSpecial(roots.nonextensible_symbol()) == to) {
836 if (out_integrity_level) *out_integrity_level =
NONE;
837 if (out_symbol) *out_symbol = roots.nonextensible_symbol();
850 if (transitions->HasSideStepTransitions())
return;
858 DCHECK(!transitions->HasSideStepTransitions());
862 transitions->SetSideStepTransitions(*
result);
868 os <<
"Object.assign-validity-cell";
871 os <<
"Object.assign-map";
874 os <<
"Clone-object-IC-map";
#define SLOW_DCHECK(condition)
void emplace_back(Args &&... args)
base::Mutex * full_transition_array_access()
static int SlackForArraySize(int old_size, int size_limit)
PropertyAttributes attributes() const
PropertyLocation location() const
PropertyKind kind() const
static constexpr PropertyDetails Empty(PropertyCellType cell_type=PropertyCellType::kNoCell)
static constexpr Tagged< Smi > FromInt(int value)
V8_INLINE constexpr bool is_null() const
static ThreadId Current()
int SearchDetails(int transition, PropertyKind kind, PropertyAttributes attributes, int *out_insertion_index)
int Search(PropertyKind kind, Tagged< Name > name, PropertyAttributes attributes, int *out_insertion_index=nullptr)
int SearchName(Tagged< Name > name, bool concurrent_search=false, int *out_insertion_index=nullptr)
V8_EXPORT_PRIVATE Tagged< Map > SearchAndGetTarget(PropertyKind kind, Tagged< Name > name, PropertyAttributes attributes)
Tagged< Name > GetKey(int transition_number)
void SetKey(int transition_number, Tagged< Name > value)
static int CompareDetails(PropertyKind kind1, PropertyAttributes attributes1, PropertyKind kind2, PropertyAttributes attributes2)
static DirectHandle< WeakFixedArray > GrowPrototypeTransitionArray(DirectHandle< WeakFixedArray > array, int new_capacity, Isolate *isolate)
V8_EXPORT_PRIVATE void Sort()
static bool CompactPrototypeTransitionArray(Isolate *isolate, Tagged< WeakFixedArray > array)
void ForEachTransitionTo(Tagged< Name > name, const ForEachTransitionCallback &callback)
Tagged< MaybeObject > GetRawTarget(int transition_number)
Tagged< Map > SearchDetailsAndGetTarget(int transition, PropertyKind kind, PropertyAttributes attributes)
static int CompareKeys(Tagged< Name > key1, uint32_t hash1, PropertyKind kind1, PropertyAttributes attributes1, Tagged< Name > key2, uint32_t hash2, PropertyKind kind2, PropertyAttributes attributes2)
void SetRawTarget(int transition_number, Tagged< MaybeObject > target)
static const int kProtoTransitionNumberOfEntriesOffset
Tagged< Map > GetTarget(int transition_number)
static const int kProtoTransitionHeaderSize
static int NumberOfPrototypeTransitions(Tagged< WeakFixedArray > proto_transitions)
static void CreateSideStepTransitions(Isolate *isolate, DirectHandle< TransitionArray > transitions)
static const int kMaxCachedPrototypeTransitions
int number_of_transitions() const
static constexpr int kNotFound
static void SetNumberOfPrototypeTransitions(Tagged< WeakFixedArray > proto_transitions, int value)
static Tagged< Map > GetSimpleTransition(Isolate *isolate, DirectHandle< Map > map)
bool HasSimpleTransitionTo(Tagged< Map > map)
void TraverseTransitionTreeInternal(const TraverseCallback &callback, DisallowGarbageCollection *no_gc)
static Tagged< WeakFixedArray > GetPrototypeTransitions(Isolate *isolate, Tagged< Map > map)
static bool CanHaveMoreTransitions(Isolate *isolate, DirectHandle< Map > map)
static std::optional< Tagged< Map > > GetPrototypeTransition(Isolate *isolate, Tagged< Map > map, Tagged< Object > prototype)
static void EnsureHasFullTransitionArray(Isolate *isolate, DirectHandle< Map > map)
Tagged< Map > SearchTransition(Tagged< Name > name, PropertyKind kind, PropertyAttributes attributes)
static Tagged< TransitionArray > GetTransitionArray(Isolate *isolate, Tagged< MaybeObject > raw_transitions)
static void ReplaceTransitions(Isolate *isolate, DirectHandle< Map > map, Tagged< UnionOf< TransitionArray, MaybeWeak< Map > > > new_transitions)
static bool PutPrototypeTransition(Isolate *isolate, DirectHandle< Map >, DirectHandle< Object > prototype, DirectHandle< Map > target_map)
static Tagged< Map > GetTargetFromRaw(Tagged< MaybeObject > raw)
static void SetMigrationTarget(Isolate *isolate, DirectHandle< Map > map, Tagged< Map > migration_target)
Tagged< MaybeObject > raw_transitions_
Tagged< TransitionArray > transitions()
static bool IsSpecialTransition(ReadOnlyRoots roots, Tagged< Name > name)
static void EnsureHasSideStepTransitions(Isolate *isolate, DirectHandle< Map > map)
static const int kMaxNumberOfTransitions
std::function< void(Tagged< Map >)> TraverseCallback
void ForEachTransitionTo(Tagged< Name > name, const ForEachTransitionCallback &callback, DisallowGarbageCollection *no_gc)
Tagged< Map > GetMigrationTarget()
static bool IsMatchingMap(Tagged< Map > target, Tagged< Name > name, PropertyKind kind, PropertyAttributes attributes)
int NumberOfTransitions()
static PropertyDetails GetTargetDetails(Tagged< Name > name, Tagged< Map > target)
Tagged< Map > SearchSpecial(Tagged< Symbol > name)
static Tagged< Name > GetSimpleTransitionKey(Tagged< Map > transition)
MaybeHandle< Map > FindTransitionToField(DirectHandle< String > name)
static void InsertHelper(Isolate *isolate, DirectHandle< Map > map, DirectHandle< Name > name, DirectHandle< Map > target, TransitionKindFlag flag)
bool HasPrototypeTransitions()
static Encoding GetEncoding(Isolate *isolate, Tagged< MaybeObject > raw_transitions)
static void SetPrototypeTransitions(Isolate *isolate, DirectHandle< Map > map, DirectHandle< WeakFixedArray > proto_transitions)
bool HasIntegrityLevelTransitionTo(Tagged< Map > to, Tagged< Symbol > *out_symbol=nullptr, PropertyAttributes *out_integrity_level=nullptr)
static Handle< WeakFixedArray > New(IsolateT *isolate, int capacity, AllocationType allocation=AllocationType::kYoung, MaybeDirectHandle< Object > initial_value={})
ZoneVector< RpoNumber > & result
ZoneStack< RpoNumber > & stack
ReadOnlyRoots GetReadOnlyRoots()
V8_INLINE DirectHandle< T > direct_handle(Tagged< T > object, Isolate *isolate)
@ SIMPLE_PROPERTY_TRANSITION
std::ostream & operator<<(std::ostream &os, AtomicMemoryOrder order)
kInstanceDescriptorsOffset raw_transitions
typename detail::FlattenUnionHelper< Union<>, Ts... >::type UnionOf
Tagged< MaybeWeak< T > > MakeWeak(Tagged< T > value)
V8_EXPORT_PRIVATE FlagValues v8_flags
bool IsUniqueName(Tagged< Name > obj)
std::function< void(Tagged< Map >)> ForEachTransitionCallback
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
static constexpr ReleaseStoreTag kReleaseStore
static constexpr RelaxedLoadTag kRelaxedLoad
static constexpr AcquireLoadTag kAcquireLoad
#define DCHECK_LE(v1, v2)
#define CHECK_LE(lhs, rhs)
#define DCHECK_IMPLIES(v1, v2)
#define DCHECK_NE(v1, v2)
#define DCHECK_GE(v1, v2)
#define CHECK_EQ(lhs, rhs)
#define DCHECK(condition)
#define DCHECK_LT(v1, v2)
#define DCHECK_EQ(v1, v2)
#define DCHECK_GT(v1, v2)
static constexpr Tagged< Smi > Empty
static constexpr uint32_t kSize
@ kObjectAssignValidityCell