-
Notifications
You must be signed in to change notification settings - Fork 14
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
Suggestion: lock the map during access to prevent recursive modification #40
Comments
I just found this bit about lower-spec VMs, and this just reinforces this suggestion - this really feels like an algorithmic oversight. |
The latest spec still seems to have this issue. Would be great to decide on a solution. Right now there is no check after the callback is invoked Line 45 in 8668664
That mapData hasn't been updated before we get to Line 47 in 8668664
Meaning there could end up with two records with matching keys. I personally like the idea of throwing a re-entrancy error in |
Alternatively, a spec note could be used to recommend a special boolean "has reserved entry" flag to make the added check cheap:
This could be further optimized by keeping the old value (as just a raw integer reference value - it can't be followed by GC) and comparing that for equality instead. Then, the "clear" woukd be setting it to a sentinel, the "set" would be setting it to the key, and the test would be comparing for equality. And this pattern could then be extended to has/get/update by storing the value of the most recently looked-up entry. (IIRC this is not far off of how WebKit optimized has+get pairs, but this is much more general.) |
a design question (tc39/proposal-upsert#40) during committee.
a design question (tc39/proposal-upsert#40) during committee.
Essentially, what I'm proposing is that
emplace
should set a flag to block recursive updates to the same map or weak map, whether it be throughset
,delete
, oremplace
. This enables implementations to not have to do nearly the bookkeeping when managing updates.It also exposes potential bugs to the user - recursive updates are rarely intended, and if absolutely desired, you can just do something like this to still work around the lock and avoid it:
*This is only technically the case if the hash table is represented as an array of inline key/value pairs (as in something like
std::vector<HashTable>
) rather than an array of pointers to entries (as in something likestd::vector<std::shared_ptr<HashTable>>
). For efficiency, nearly every hash table implementation in practice does the former if they want to aim for any serious performance, and of course, every engine I'm aware of also does it that way, and so yeah, it's widely enough applicable for me to say "always" here as that's in practice the case because of how everyone implements it.The text was updated successfully, but these errors were encountered: