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

Implement FinalizationRegistry #168

Merged
merged 1 commit into from
Dec 5, 2023
Merged

Implement FinalizationRegistry #168

merged 1 commit into from
Dec 5, 2023

Conversation

saghul
Copy link
Contributor

@saghul saghul commented Dec 2, 2023

No description provided.

@saghul saghul force-pushed the finrec branch 3 times, most recently from 83492c8 to 1aa580b Compare December 4, 2023 11:59
@saghul saghul marked this pull request as ready for review December 4, 2023 11:59
test262_errors.txt Outdated Show resolved Hide resolved
@saghul
Copy link
Contributor Author

saghul commented Dec 4, 2023

@bnoordhuis This is ready now, PTAL!

@saghul saghul requested a review from bnoordhuis December 4, 2023 20:10
Copy link
Contributor

@bnoordhuis bnoordhuis left a comment

Choose a reason for hiding this comment

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

LGTM with some comments/suggestions. Nice work, Saúl.

quickjs.c Show resolved Hide resolved
quickjs.c Show resolved Hide resolved
quickjs.c Show resolved Hide resolved
quickjs.c Outdated
Comment on lines 50917 to 50920
list_for_each_safe(el, el1, &frd->entries) {
JSFinRecEntry *fre = list_entry(el, JSFinRecEntry, link);
delete_finrec_weakref(rt, fre);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this an accidentally-quadratic (well, O(n*m)) thing? Perhaps it's better to use a doubly linked list / circular queue so removal is O(1) and this loop stays O(n)?

I suppose the counterargument is that it makes every JSObject one almost-always-unused pointer bigger. And you know, that's actually a pretty good counterargument.

As an aside: you could use plain list_for_each here since the list isn't mutated. Not that I object to using the _safe variant, just mentioning it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is this an accidentally-quadratic (well, O(n*m)) thing? Perhaps it's better to use a doubly linked list / circular queue so removal is O(1) and this loop stays O(n)?

I suppose the counterargument is that it makes every JSObject one almost-always-unused pointer bigger. And you know, that's actually a pretty good counterargument.

So here is the problem: you have a finalization registry where you did this:

finReg.register(target);
finReg.register(target, undefined, target);

The 2nd line is dumb, but allowed. The script reaches the end and the runtime is being destroyed. The finalization registry will go first.

Now as we destroy it, target will have a refcount of 1, but 2 weak ref entries.

Because we added the one with the token last it will be the first one to go. As its refcount reaches 0 it will be freed and we'll be left hanging on to freed memory as we continue iterating that list.

Since weakrefs don't seem to be very used I think keeping it simple, as in as small overhead as possible is a good compromise. A similar pattern is used in reset_weak_ref I reckon for a similar reason.

Thanks for the review!

As an aside: you could use plain list_for_each here since the list isn't mutated. Not that I object to using the _safe variant, just mentioning it.

Yeah, I kinda left it that way because it doesn't hurt...

quickjs.c Show resolved Hide resolved
quickjs.c Show resolved Hide resolved
quickjs.c Outdated Show resolved Hide resolved
@saghul saghul merged commit 99f12f4 into master Dec 5, 2023
30 checks passed
@saghul saghul deleted the finrec branch December 5, 2023 21:41
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.

2 participants