LibJS: Replace IndexedProperties with inline Packed/Holey/Dictionary

Replace the OwnPtr<IndexedPropertyStorage> indirection with inline
indexed element storage directly on Object. This eliminates virtual
dispatch and reduces indirection for indexed property access.

The new system uses three storage kinds tracked by IndexedStorageKind:

- Packed: Dense array, no holes. Elements stored in a malloced Value*
  array with capacity header (same layout as named properties).
- Holey: Dense array with possible holes marked by empty sentinel.
  Same physical layout as Packed.
- Dictionary: Sparse storage using GenericIndexedPropertyStorage,
  type-punned into the m_indexed_elements pointer.

Transitions: None->Packed->Holey->Dictionary (mostly monotonic).
Dictionary mode triggers on non-default attributes or sparse arrays.

Object keeps the same 48-byte size since m_indexed_elements (8 bytes)
replaces IndexedProperties (8 bytes), and the storage kind + array
size fit in existing padding alongside m_flags.

The asm interpreter benefits from one fewer indirection: it now reads
the element pointer and array size directly from Object fields instead
of chasing through OwnPtr -> IndexedPropertyStorage -> Vector.

Removes: IndexedProperties, SimpleIndexedPropertyStorage,
IndexedPropertyStorage, IndexedPropertyIterator.
Keeps: GenericIndexedPropertyStorage (for Dictionary mode).
This commit is contained in:
Andreas Kling
2026-03-17 00:54:54 -05:00
committed by Andreas Kling
parent f574ef528d
commit 614713ed08
Notes: github-actions[bot] 2026-03-18 03:30:01 +00:00
25 changed files with 689 additions and 631 deletions

View File

@@ -413,8 +413,8 @@ inline JSFileResult TestRunner::run_file_test(ByteString const& test_path)
auto user_output = MUST(realm->global_object().get("__UserOutput__"_utf16_fly_string));
auto& arr = user_output.as_array();
for (auto& entry : arr.indexed_properties()) {
auto message = MUST(arr.get(entry.index()));
for (u32 i = 0; i < arr.indexed_array_like_size(); ++i) {
auto message = MUST(arr.get(i));
file_result.logged_messages.append(message.to_string_without_side_effects().to_byte_string());
}