LibJS: Skip prototype chain lookup in internal_set() for arrays

...when Array.prototype and Object.prototype are intact.

If `internal_set()` is called on an array exotic object with a numeric
PropertyKey, and:
- the prototype chain has not been modified (i.e., there are no getters
  or setters for indexed properties), and
- the array is not the target of a Proxy object,

then we can directly store the value in the receiver's indexed
properties, without checking whether it already exists somewhere in the
prototype chain.

1.7x improvement on the following program:
```js
function f() {
    let a = [];
    let i = 0;
    while (i < 10_000_000) {
        a.push(i);
        i++;
    }
}

f();
```
This commit is contained in:
Aliaksandr Kalenik 2025-05-22 19:46:08 +03:00 committed by Alexander Kalenik
commit bd6750aaa5
Notes: github-actions[bot] 2025-05-23 12:52:28 +00:00
9 changed files with 133 additions and 8 deletions

View file

@ -50,6 +50,9 @@ public:
[[nodiscard]] u32 mapped_arguments_object_well_known_symbol_iterator_offset() const { return m_mapped_arguments_object_well_known_symbol_iterator_offset; }
[[nodiscard]] u32 mapped_arguments_object_callee_offset() const { return m_mapped_arguments_object_callee_offset; }
[[nodiscard]] GC::Ref<Shape> default_array_prototype_shape() const { return *m_default_array_prototype_shape; }
[[nodiscard]] GC::Ref<Shape> default_object_prototype_shape() const { return *m_default_object_prototype_shape; }
[[nodiscard]] GC::Ref<Accessor> throw_type_error_accessor() { return *m_throw_type_error_accessor; }
// Not included in JS_ENUMERATE_NATIVE_OBJECTS due to missing distinct prototype
@ -179,6 +182,9 @@ private:
u32 m_mapped_arguments_object_well_known_symbol_iterator_offset { 0 };
u32 m_mapped_arguments_object_callee_offset { 0 };
GC::Ptr<Shape> m_default_array_prototype_shape;
GC::Ptr<Shape> m_default_object_prototype_shape;
GC::Ptr<Accessor> m_throw_type_error_accessor;
// Not included in JS_ENUMERATE_NATIVE_OBJECTS due to missing distinct prototype