27982 {
27983 ASSERT(!field_names.IsNull());
27984 ASSERT(field_names.IsImmutable());
27985 ASSERT(field_names.ptr() == Object::empty_array().ptr() ||
27986 field_names.Length() > 0);
27987
27988 Zone* zone = thread->zone();
27989 IsolateGroup* isolate_group = thread->isolate_group();
27990 ObjectStore* object_store = isolate_group->object_store();
27991
27992 if (object_store->record_field_names<std::memory_order_acquire>() ==
27994
27995 SafepointWriteRwLocker ml(thread, isolate_group->program_lock());
27996 if (object_store->record_field_names() ==
Array::null()) {
27997
27999 HashTables::New<RecordFieldNamesMap>(16,
Heap::kOld));
28000 map.InsertOrGetValue(Object::empty_array(),
28003 object_store->set_record_field_names_map(
map.Release());
28005 table.SetAt(0, Object::empty_array());
28006 object_store->set_record_field_names<std::memory_order_release>(
table);
28007 }
28008 }
28009
28010#if defined(DART_PRECOMPILER)
28011 const intptr_t
kMaxNumFields = compiler::target::RecordShape::kMaxNumFields;
28013 compiler::target::RecordShape::kMaxFieldNamesIndex;
28014#else
28017#endif
28018
28020 FATAL(
"Too many record fields");
28021 }
28022 if (field_names.ptr() == Object::empty_array().ptr()) {
28024 }
28025
28026 {
28027 SafepointReadRwLocker ml(thread, isolate_group->program_lock());
28030 index ^=
map.GetOrNull(field_names);
28031 ASSERT(
map.Release().ptr() == object_store->record_field_names_map());
28032 if (!index.IsNull()) {
28034 }
28035 }
28036
28037 SafepointWriteRwLocker ml(thread, isolate_group->program_lock());
28039 const intptr_t new_index =
map.NumOccupied();
28041 FATAL(
"Too many record shapes");
28042 }
28043
28047
28048 if (index == new_index) {
28049 ASSERT(
map.NumOccupied() == (new_index + 1));
28051 intptr_t capacity =
table.Length();
28052 if (index >=
table.Length()) {
28053 capacity = capacity + (capacity >> 2);
28055 object_store->set_record_field_names(
table);
28056 }
28057 table.SetAt(index, field_names);
28058 } else {
28059 ASSERT(index < new_index);
28060 }
28061 object_store->set_record_field_names_map(
map.Release());
28062
28064 ASSERT(shape.GetFieldNames(thread) == field_names.ptr());
28066 return shape;
28067}
static ArrayPtr New(intptr_t len, Heap::Space space=Heap::kNew)
static ArrayPtr Grow(const Array &source, intptr_t new_length, Heap::Space space=Heap::kNew)
static RecordShape ForUnnamed(intptr_t num_fields)
static constexpr intptr_t kMaxFieldNamesIndex
static constexpr intptr_t kMaxNumFields
UnorderedHashMap< RecordFieldNamesMapTraits > RecordFieldNamesMap
SI auto map(std::index_sequence< I... >, Fn &&fn, const Args &... args) -> skvx::Vec< sizeof...(I), decltype(fn(args[0]...))>