Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LibWeb: PointerEvent improvements #1854

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

gmta
Copy link
Collaborator

@gmta gmta commented Oct 18, 2024

Fixes at least 6 WPT subtests. :^)

@gmta gmta force-pushed the libweb-uievents-pointerevent-improvements branch from 8f2f744 to ac48ea7 Compare October 18, 2024 11:22
Comment on lines 133 to 137
// https://w3c.github.io/pointerevents/#dom-pointerevent-getcoalescedevents
AK::Vector<JS::Handle<PointerEvent>> m_coalesced_events;

// https://w3c.github.io/pointerevents/#dom-pointerevent-getpredictedevents
AK::Vector<JS::Handle<PointerEvent>> m_predicted_events;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please change these two vectors to be visited instead of using JS::Handle. we generally try to visit whenever it's possible, because using JS::Handle, especially when it's owned by another GC-allocated object will cause a leak.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, updated!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the flip side, don't we also try and avoid exposing public getters which return a Vector<NonnullGCPtr> since those GCPtrs if copied by a caller are not tracked by the GC since the pointer on the heap and not the stack?

Not suggesting any change at all - but it feels like either approach does have a downside. Do we typically use a MarkedVector in that scenario or something?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the flip side, don't we also try and avoid exposing public getters which return a Vector since those GCPtrs if copied by a caller are not tracked by the GC since the pointer on the heap and not the stack?

If caller wants a copy of vector then it should be responsible for visiting it. JS::Handle creates a strong root and we want to limit its usage only to the cases when GC-allocated object is owned by non GC-allocated object.

Not suggesting any change at all - but it feels like either approach does have a downside. Do we typically use a MarkedVector in that scenario or something?

MarkedVector same as JS::Handle creates a strong root. we never want to have GC-allocated object that own a strong root, because 99% it will lead to GC-allocated caused by objects visiting each other.

Copy link
Contributor

@trflynn89 trflynn89 Oct 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If caller wants a copy of vector then it should be responsible for visiting it.

The problem with this is when GC occurs between the caller getting this vector and having a chance to store it, which is the case throughout our generated prototypes.

So as currently written, this getter is unsafe:

AK::Vector<JS::NonnullGCPtr<PointerEvent>> get_coalesced_events() const { return m_coalesced_events; }

Because the caller in the generated prototype looks like:

auto retval = TRY(throw_dom_exception_if_needed(vm, [&] { return impl->get_coalesced_events(); }));
auto new_array0 = MUST(JS::Array::create(realm, 0));

If GC is triggered during Array::create, the returned vector is not protected. I think even if we return a const& from get_coalesced_events, the declaration of auto retval will actually create a copy.

It's safest/necessary to do one of two things:

  1. Store as a Vector<NNGCPtr> as the class member, and return Vector<Handle> or MarkedVector from this getter. This is what we usually do, and is safe, but is unnecessarily expensive, so...
  2. Return ReadonlySpan<NNGCPtr> from this getter.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem with this is when GC occurs between the caller getting this vector and having a chance to store it, which is the case throughout our generated prototypes.

right, that's what I started thinking about once I posted this message 😅 definitely something I should revisit on the next round of GC-leaks fixing.

It's safest/necessary to do one of two things:

both options seems good, thanks for suggestion!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Went with ReadonlySpan<NNGCPtr>!

@gmta gmta force-pushed the libweb-uievents-pointerevent-improvements branch 2 times, most recently from 394a195 to 1c00040 Compare October 18, 2024 14:22
Fixes at least 2 WPT subtests in /pointerevents.
Fixes at least 4 WPT subtests in /pointerevents.
@gmta gmta force-pushed the libweb-uievents-pointerevent-improvements branch from 1c00040 to 92f0f36 Compare October 18, 2024 21:29
Comment on lines +32 to +36
m_coalesced_events.unchecked_append(static_cast<PointerEvent&>(*coalesced_event));

m_predicted_events.ensure_capacity(event_init.predicted_events.size());
for (auto const& predicted_event : event_init.predicted_events)
m_predicted_events.unchecked_append(static_cast<PointerEvent&>(*predicted_event));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, sorry, was just about to merge this, but noticed these casts on a last look - they don't seem necessary? Compiles without the casts for me

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants