how to create a Persistent handle cache?

53 views
Skip to first unread message

jres...@gmail.com

unread,
Nov 9, 2020, 10:54:19 PM11/9/20
to v8-users
I would like to cache Persistent handles in such a way that I can retrieve the same Persistent instance given the identical JS object, i.e. imagine a function like so:

Persistent<Object> GetPersistentForObject(Local<Object> obj)
{
   // If we have already created a Persistent for obj, find and return it.
   // Otherwise, create and return a Persistent for obj and cache it for 
   // future calls.
}

The obvious thought is to store the Persistent handles in a map of some kind, but what to use as the key? I assume it would not be possible to actually use Local handles as keys in a map that outlives the current HandleScope.

One thought I had was to assign a unique integer to the object using obj.SetPrivate(...), and use that as the key, but SetPrivate is documented as experimental, which is discouraging.

Is there an easier way to achieve what I'm trying to do? I feel like I may be missing something obvious...

Jonathan


Ben Noordhuis

unread,
Nov 10, 2020, 5:14:35 AM11/10/20
to v8-users
A hashmap should work if you observe the following;

1. Use `v8::Object::GetIdentityHash()` to compute the hash key.
2. Use `Persistent::operator==()` to detect duplicates (also has an
overload that compares against a Local)

I.e., step 1 is to find the right bucket and step 2 is to find out if
that bucket already contains the object.

Using just the identity hash isn't sufficient, see [1] and [2] for discussion.

Caveat: use `v8::Value::SameValue()` - not `Persistent::operator==()`
- if you also store primitives (numbers, strings, etc.)

[1] https://github.com/denoland/deno/pull/7946#discussion_r504192165
[2] https://github.com/denoland/deno/issues/7969

jres...@gmail.com

unread,
Nov 25, 2020, 10:23:12 PM11/25/20
to v8-users
Thank you for the suggestion Ben!
Reply all
Reply to author
Forward
0 new messages