mirror of
https://github.com/LadybirdBrowser/ladybird
synced 2026-05-05 06:32:30 +02:00
LibJS: Replace Vector<Value> with Value* for named property storage
Replace the 24-byte Vector<Value> m_storage with an 8-byte raw Value* m_named_properties pointer, backed by a malloc'd allocation with an inline capacity header. Memory layout of the allocation: [u32 capacity] [u32 padding] [Value 0] [Value 1] ... m_named_properties points to Value 0. This shrinks JS::Object from 64 to 48 bytes (on non-Windows platforms) and removes one level of indirection for property access in the asm interpreter, since the data pointer is now stored directly on the object rather than inside a Vector's internal metadata. Growth policy: max(4, max(needed, old_capacity * 2)).
This commit is contained in:
committed by
Andreas Kling
parent
15af5fb420
commit
f574ef528d
Notes:
github-actions[bot]
2026-03-18 03:30:08 +00:00
Author: https://github.com/awesomekling Commit: https://github.com/LadybirdBrowser/ladybird/commit/f574ef528d8 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/8479
@@ -1460,7 +1460,7 @@ handler GetById
|
||||
branch_ne t0, t2, .try_cache
|
||||
# IC hit! Load property value via get_direct (own property)
|
||||
load32 t0, [t5, PROPERTY_LOOKUP_CACHE_ENTRY0_PROPERTY_OFFSET]
|
||||
load64 t5, [t3, OBJECT_STORAGE_DATA]
|
||||
load64 t5, [t3, OBJECT_NAMED_PROPERTIES]
|
||||
load64 t0, [t5, t0, 8]
|
||||
# Check value is not an accessor
|
||||
extract_tag t2, t0
|
||||
@@ -1480,7 +1480,7 @@ handler GetById
|
||||
branch_ne t1, t2, .try_cache
|
||||
# IC hit! Load property value via get_direct (from prototype)
|
||||
load32 t1, [t5, PROPERTY_LOOKUP_CACHE_ENTRY0_PROPERTY_OFFSET]
|
||||
load64 t2, [t0, OBJECT_STORAGE_DATA]
|
||||
load64 t2, [t0, OBJECT_NAMED_PROPERTIES]
|
||||
load64 t0, [t2, t1, 8]
|
||||
# Check value is not an accessor
|
||||
extract_tag t2, t0
|
||||
@@ -1521,7 +1521,7 @@ handler PutById
|
||||
branch_ne t0, t2, .try_cache
|
||||
# Check current value at property_offset is not an accessor
|
||||
load32 t0, [t5, PROPERTY_LOOKUP_CACHE_ENTRY0_PROPERTY_OFFSET]
|
||||
load64 t5, [t3, OBJECT_STORAGE_DATA]
|
||||
load64 t5, [t3, OBJECT_NAMED_PROPERTIES]
|
||||
load64 t2, [t5, t0, 8]
|
||||
extract_tag t4, t2
|
||||
branch_eq t4, ACCESSOR_TAG, .try_cache
|
||||
@@ -1715,7 +1715,7 @@ handler GetLength
|
||||
branch_ne t0, t2, .slow
|
||||
# IC hit
|
||||
load32 t0, [t5, PROPERTY_LOOKUP_CACHE_ENTRY0_PROPERTY_OFFSET]
|
||||
load64 t5, [t3, OBJECT_STORAGE_DATA]
|
||||
load64 t5, [t3, OBJECT_NAMED_PROPERTIES]
|
||||
load64 t0, [t5, t0, 8]
|
||||
extract_tag t2, t0
|
||||
branch_eq t2, ACCESSOR_TAG, .slow
|
||||
@@ -1772,7 +1772,7 @@ handler GetGlobal
|
||||
branch_ne t0, t5, .try_env_binding
|
||||
# IC hit! Load property value via get_direct
|
||||
load32 t0, [t3, PROPERTY_LOOKUP_CACHE_ENTRY0_PROPERTY_OFFSET]
|
||||
load64 t5, [t2, OBJECT_STORAGE_DATA]
|
||||
load64 t5, [t2, OBJECT_NAMED_PROPERTIES]
|
||||
load64 t0, [t5, t0, 8]
|
||||
# Check not accessor
|
||||
extract_tag t5, t0
|
||||
@@ -1830,7 +1830,7 @@ handler SetGlobal
|
||||
branch_ne t0, t5, .try_env_binding
|
||||
# IC hit! Load current value to check it's not an accessor
|
||||
load32 t1, [t3, PROPERTY_LOOKUP_CACHE_ENTRY0_PROPERTY_OFFSET]
|
||||
load64 t5, [t2, OBJECT_STORAGE_DATA]
|
||||
load64 t5, [t2, OBJECT_NAMED_PROPERTIES]
|
||||
load64 t4, [t5, t1, 8]
|
||||
extract_tag t4, t4
|
||||
branch_eq t4, ACCESSOR_TAG, .slow
|
||||
|
||||
@@ -37,7 +37,7 @@ int main()
|
||||
// Object layout
|
||||
outln("# Object layout");
|
||||
EMIT_OFFSET(OBJECT_SHAPE, Object, m_shape);
|
||||
EMIT_OFFSET(OBJECT_STORAGE, Object, m_storage);
|
||||
EMIT_OFFSET(OBJECT_NAMED_PROPERTIES, Object, m_named_properties);
|
||||
EMIT_OFFSET(OBJECT_INDEXED_PROPERTIES, Object, m_indexed_properties);
|
||||
EMIT_SIZEOF(OBJECT_SIZE, Object);
|
||||
|
||||
@@ -110,7 +110,7 @@ int main()
|
||||
outln("\n# SimpleIndexedPropertyStorage layout");
|
||||
EMIT_OFFSET(SIMPLE_INDEXED_PROPERTY_STORAGE_PACKED_ELEMENTS, SimpleIndexedPropertyStorage, m_packed_elements);
|
||||
|
||||
// Vector<Value> layout (used for m_packed_elements and m_storage)
|
||||
// Vector<Value> layout (used for m_packed_elements and bytecode)
|
||||
outln("\n# Vector<Value> layout");
|
||||
{
|
||||
Vector<Value> v;
|
||||
@@ -120,9 +120,6 @@ int main()
|
||||
outln("const VECTOR_DATA = {}", vec_data);
|
||||
outln("const VECTOR_SIZE = {}", vec_size);
|
||||
|
||||
// Composite offsets for Object.m_storage data pointer
|
||||
outln("const OBJECT_STORAGE_DATA = {}", offsetof(Object, m_storage) + vec_data);
|
||||
outln("const OBJECT_STORAGE_SIZE = {}", offsetof(Object, m_storage) + vec_size);
|
||||
// Composite offsets for SimpleIndexedPropertyStorage.m_packed_elements data pointer
|
||||
outln("const SIMPLE_INDEXED_PROPERTY_STORAGE_PACKED_DATA = {}", offsetof(SimpleIndexedPropertyStorage, m_packed_elements) + vec_data);
|
||||
// Composite offset for Executable.bytecode data pointer
|
||||
|
||||
Reference in New Issue
Block a user