mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-22 20:45:14 +00:00
LibJS: Make IteratorRecord inherit from Cell, not Object
This shaves its size down from 104 bytes to 48 bytes, cutting GC pressure caused by this type in more than half.
This commit is contained in:
parent
842eb7c2e8
commit
86cc9395d0
5 changed files with 18 additions and 25 deletions
|
@ -1613,7 +1613,7 @@ inline ThrowCompletionOr<GC::Ref<Object>> super_call_with_argument_array(VM& vm,
|
|||
|
||||
inline ThrowCompletionOr<GC::Ref<Array>> iterator_to_array(VM& vm, Value iterator)
|
||||
{
|
||||
auto& iterator_record = as<IteratorRecord>(iterator.as_object());
|
||||
auto& iterator_record = static_cast<IteratorRecord&>(iterator.as_cell());
|
||||
|
||||
auto array = MUST(Array::create(*vm.current_realm(), 0));
|
||||
size_t index = 0;
|
||||
|
@ -1719,7 +1719,7 @@ inline ThrowCompletionOr<Value> delete_by_value_with_this(Bytecode::Interpreter&
|
|||
}
|
||||
|
||||
// 14.7.5.9 EnumerateObjectProperties ( O ), https://tc39.es/ecma262/#sec-enumerate-object-properties
|
||||
inline ThrowCompletionOr<Object*> get_object_property_iterator(VM& vm, Value value)
|
||||
inline ThrowCompletionOr<Value> get_object_property_iterator(VM& vm, Value value)
|
||||
{
|
||||
// While the spec does provide an algorithm, it allows us to implement it ourselves so long as we meet the following invariants:
|
||||
// 1- Returned property keys do not include keys that are Symbols
|
||||
|
@ -1804,7 +1804,7 @@ inline ThrowCompletionOr<Object*> get_object_property_iterator(VM& vm, Value val
|
|||
}
|
||||
},
|
||||
1, vm.names.next);
|
||||
return realm.create<IteratorRecord>(realm, object, callback, false).ptr();
|
||||
return vm.heap().allocate<IteratorRecord>(object, callback, false);
|
||||
}
|
||||
|
||||
ByteString Instruction::to_byte_string(Bytecode::Executable const& executable) const
|
||||
|
@ -2915,14 +2915,14 @@ ThrowCompletionOr<void> GetIterator::execute_impl(Bytecode::Interpreter& interpr
|
|||
|
||||
ThrowCompletionOr<void> GetObjectFromIteratorRecord::execute_impl(Bytecode::Interpreter& interpreter) const
|
||||
{
|
||||
auto& iterator_record = as<IteratorRecord>(interpreter.get(m_iterator_record).as_object());
|
||||
auto& iterator_record = static_cast<IteratorRecord&>(interpreter.get(m_iterator_record).as_cell());
|
||||
interpreter.set(m_object, iterator_record.iterator);
|
||||
return {};
|
||||
}
|
||||
|
||||
ThrowCompletionOr<void> GetNextMethodFromIteratorRecord::execute_impl(Bytecode::Interpreter& interpreter) const
|
||||
{
|
||||
auto& iterator_record = as<IteratorRecord>(interpreter.get(m_iterator_record).as_object());
|
||||
auto& iterator_record = static_cast<IteratorRecord&>(interpreter.get(m_iterator_record).as_cell());
|
||||
interpreter.set(m_next_method, iterator_record.next_method);
|
||||
return {};
|
||||
}
|
||||
|
@ -2938,14 +2938,15 @@ ThrowCompletionOr<void> GetMethod::execute_impl(Bytecode::Interpreter& interpret
|
|||
|
||||
ThrowCompletionOr<void> GetObjectPropertyIterator::execute_impl(Bytecode::Interpreter& interpreter) const
|
||||
{
|
||||
interpreter.set(dst(), TRY(get_object_property_iterator(interpreter.vm(), interpreter.get(object()))));
|
||||
auto iterator_record = TRY(get_object_property_iterator(interpreter.vm(), interpreter.get(object())));
|
||||
interpreter.set(dst(), iterator_record);
|
||||
return {};
|
||||
}
|
||||
|
||||
ThrowCompletionOr<void> IteratorClose::execute_impl(Bytecode::Interpreter& interpreter) const
|
||||
{
|
||||
auto& vm = interpreter.vm();
|
||||
auto& iterator = as<IteratorRecord>(interpreter.get(m_iterator_record).as_object());
|
||||
auto& iterator = static_cast<IteratorRecord&>(interpreter.get(m_iterator_record).as_cell());
|
||||
|
||||
// FIXME: Return the value of the resulting completion. (Note that m_completion_value can be empty!)
|
||||
TRY(iterator_close(vm, iterator, Completion { m_completion_type, m_completion_value }));
|
||||
|
@ -2955,7 +2956,7 @@ ThrowCompletionOr<void> IteratorClose::execute_impl(Bytecode::Interpreter& inter
|
|||
ThrowCompletionOr<void> AsyncIteratorClose::execute_impl(Bytecode::Interpreter& interpreter) const
|
||||
{
|
||||
auto& vm = interpreter.vm();
|
||||
auto& iterator = as<IteratorRecord>(interpreter.get(m_iterator_record).as_object());
|
||||
auto& iterator = static_cast<IteratorRecord&>(interpreter.get(m_iterator_record).as_cell());
|
||||
|
||||
// FIXME: Return the value of the resulting completion. (Note that m_completion_value can be empty!)
|
||||
TRY(async_iterator_close(vm, iterator, Completion { m_completion_type, m_completion_value }));
|
||||
|
@ -2965,7 +2966,7 @@ ThrowCompletionOr<void> AsyncIteratorClose::execute_impl(Bytecode::Interpreter&
|
|||
ThrowCompletionOr<void> IteratorNext::execute_impl(Bytecode::Interpreter& interpreter) const
|
||||
{
|
||||
auto& vm = interpreter.vm();
|
||||
auto& iterator_record = as<IteratorRecord>(interpreter.get(m_iterator_record).as_object());
|
||||
auto& iterator_record = static_cast<IteratorRecord&>(interpreter.get(m_iterator_record).as_cell());
|
||||
interpreter.set(dst(), TRY(iterator_next(vm, iterator_record)));
|
||||
return {};
|
||||
}
|
||||
|
|
|
@ -211,7 +211,7 @@ GC::Ref<IteratorRecord> create_async_from_sync_iterator(VM& vm, GC::Ref<Iterator
|
|||
auto next_method = MUST(async_iterator->get(vm.names.next));
|
||||
|
||||
// 4. Let iteratorRecord be the Iterator Record { [[Iterator]]: asyncIterator, [[NextMethod]]: nextMethod, [[Done]]: false }.
|
||||
auto iterator_record = realm.create<IteratorRecord>(realm, async_iterator, next_method, false);
|
||||
auto iterator_record = vm.heap().allocate<IteratorRecord>(async_iterator, next_method, false);
|
||||
|
||||
// 5. Return iteratorRecord.
|
||||
return iterator_record;
|
||||
|
|
|
@ -31,7 +31,7 @@ Iterator::Iterator(Object& prototype, GC::Ref<IteratorRecord> iterated)
|
|||
}
|
||||
|
||||
Iterator::Iterator(Object& prototype)
|
||||
: Iterator(prototype, prototype.shape().realm().create<IteratorRecord>(prototype.shape().realm(), nullptr, js_undefined(), false))
|
||||
: Iterator(prototype, prototype.heap().allocate<IteratorRecord>(nullptr, js_undefined(), false))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -43,8 +43,7 @@ ThrowCompletionOr<GC::Ref<IteratorRecord>> get_iterator_direct(VM& vm, Object& o
|
|||
|
||||
// 2. Let iteratorRecord be Record { [[Iterator]]: obj, [[NextMethod]]: nextMethod, [[Done]]: false }.
|
||||
// 3. Return iteratorRecord.
|
||||
auto& realm = *vm.current_realm();
|
||||
return realm.create<IteratorRecord>(realm, object, next_method, false);
|
||||
return vm.heap().allocate<IteratorRecord>(object, next_method, false);
|
||||
}
|
||||
|
||||
// 7.4.3 GetIteratorFromMethod ( obj, method ), https://tc39.es/ecma262/#sec-getiteratorfrommethod
|
||||
|
@ -61,8 +60,7 @@ ThrowCompletionOr<GC::Ref<IteratorRecord>> get_iterator_from_method(VM& vm, Valu
|
|||
auto next_method = TRY(iterator.get(vm, vm.names.next));
|
||||
|
||||
// 4. Let iteratorRecord be the Iterator Record { [[Iterator]]: iterator, [[NextMethod]]: nextMethod, [[Done]]: false }.
|
||||
auto& realm = *vm.current_realm();
|
||||
auto iterator_record = realm.create<IteratorRecord>(realm, iterator.as_object(), next_method, false);
|
||||
auto iterator_record = vm.heap().allocate<IteratorRecord>(iterator.as_object(), next_method, false);
|
||||
|
||||
// 5. Return iteratorRecord.
|
||||
return iterator_record;
|
||||
|
|
|
@ -17,14 +17,13 @@
|
|||
namespace JS {
|
||||
|
||||
// 7.4.1 Iterator Records, https://tc39.es/ecma262/#sec-iterator-records
|
||||
class IteratorRecord final : public Object {
|
||||
JS_OBJECT(IteratorRecord, Object);
|
||||
class IteratorRecord final : public Cell {
|
||||
GC_CELL(IteratorRecord, Cell);
|
||||
GC_DECLARE_ALLOCATOR(IteratorRecord);
|
||||
|
||||
public:
|
||||
IteratorRecord(Realm& realm, GC::Ptr<Object> iterator, Value next_method, bool done)
|
||||
: Object(ConstructWithoutPrototypeTag::Tag, realm)
|
||||
, iterator(iterator)
|
||||
IteratorRecord(GC::Ptr<Object> iterator, Value next_method, bool done)
|
||||
: iterator(iterator)
|
||||
, next_method(next_method)
|
||||
, done(done)
|
||||
{
|
||||
|
@ -36,12 +35,8 @@ public:
|
|||
|
||||
private:
|
||||
virtual void visit_edges(Cell::Visitor&) override;
|
||||
virtual bool is_iterator_record() const override { return true; }
|
||||
};
|
||||
|
||||
template<>
|
||||
inline bool Object::fast_is<IteratorRecord>() const { return is_iterator_record(); }
|
||||
|
||||
class Iterator : public Object {
|
||||
JS_OBJECT(Iterator, Object);
|
||||
GC_DECLARE_ALLOCATOR(Iterator);
|
||||
|
|
|
@ -195,7 +195,6 @@ public:
|
|||
virtual bool is_proxy_object() const { return false; }
|
||||
virtual bool is_native_function() const { return false; }
|
||||
virtual bool is_ecmascript_function_object() const { return false; }
|
||||
virtual bool is_iterator_record() const { return false; }
|
||||
virtual bool is_array_iterator() const { return false; }
|
||||
|
||||
// B.3.7 The [[IsHTMLDDA]] Internal Slot, https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot
|
||||
|
|
Loading…
Add table
Reference in a new issue