LibJS: Isolate object property storage

Add a JSObjectStorage heap partition and route heap-backed property
storage (both named and indexed element buffers) through it.

These buffers are directly shaped by script-visible object and array
operations, so keeping them separate from the general heap makes a
corruption primitive less useful against unrelated allocations.
This commit is contained in:
Andreas Kling 2026-06-10 14:27:28 +02:00 committed by Andreas Kling
parent 8a8625b399
commit 19dd5bef60
3 changed files with 7 additions and 2 deletions

View file

@ -131,6 +131,9 @@ static mi_heap_t* heap_for_partition(HeapPartition partition)
case HeapPartition::ArrayBuffer:
static mi_heap_t* array_buffer_heap = mi_heap_new();
return array_buffer_heap;
case HeapPartition::JSObjectStorage:
static mi_heap_t* js_object_storage_heap = mi_heap_new();
return js_object_storage_heap;
}
VERIFY_NOT_REACHED();
}

View file

@ -14,6 +14,7 @@
enum class HeapPartition {
General,
ArrayBuffer,
JSObjectStorage,
};
[[nodiscard]] void* ak_kcalloc(size_t count, size_t size);

View file

@ -51,7 +51,7 @@ static Value* allocate_heap_named_storage(u32 capacity)
{
VERIFY(capacity > Object::INLINE_NAMED_PROPERTY_CAPACITY);
auto allocation_size = HEAP_STORAGE_HEADER_SIZE + capacity * sizeof(Value);
auto* raw = static_cast<u8*>(kmalloc(allocation_size));
auto* raw = static_cast<u8*>(kmalloc(HeapPartition::JSObjectStorage, allocation_size));
VERIFY(raw);
*reinterpret_cast<u32*>(raw) = capacity;
return reinterpret_cast<Value*>(raw + HEAP_STORAGE_HEADER_SIZE);
@ -90,6 +90,7 @@ void Object::ensure_named_storage_capacity(u32 needed)
m_named_properties = new_storage;
} else {
auto* raw = static_cast<u8*>(krealloc(
HeapPartition::JSObjectStorage,
reinterpret_cast<u8*>(m_named_properties) - HEAP_STORAGE_HEADER_SIZE,
HEAP_STORAGE_HEADER_SIZE + new_capacity * sizeof(Value)));
VERIFY(raw);
@ -1798,7 +1799,7 @@ static Value* allocate_indexed_elements(u32 capacity)
{
// Layout: [u32 capacity] [u32 padding] [Value 0] [Value 1] ...
auto allocation_size = sizeof(u64) + capacity * sizeof(Value);
auto* raw = static_cast<u8*>(kmalloc(allocation_size));
auto* raw = static_cast<u8*>(kmalloc(HeapPartition::JSObjectStorage, allocation_size));
VERIFY(raw);
*reinterpret_cast<u32*>(raw) = capacity;
*reinterpret_cast<u32*>(raw + sizeof(u32)) = 0; // padding