Return a Weak Persistent to JS

106 views
Skip to first unread message

Vinayaka Kamath

unread,
Jan 18, 2021, 8:28:21 AM1/18/21
to v8-users
Hello All,

I am trying to return a weak persistent handle to JS through a function template. However the v8 is crashing on triggering the codepath. What is the correct way to do it?
My intention is to trigger GC on the persistent handle when it goes out of scope.

_____________________________________
My Function Template:

void QueryFunction(const v8::FunctionCallbackInfo<v8::Value> &args) {
  // This function is made available as Query() in the JS code
   .
   .
    auto wrapper = new Query::WrapStop(isolate, iterator, it_info.iterable);
    args.GetReturnValue().Set(wrapper->value);   // How to return this?? Set requires a pointer to Persistent
    // The intention is to force GC on wrapper->value when it goes out of scope in JS
}
________________________________________
Definition of WrapStop

struct WrapStop {
       explicit WrapStop(v8::Isolate *, Query::Iterator *, v8::Local<v8::Value>);
       virtual ~WrapStop();
       v8::Persistent<v8::Value> value;    // Force GC on this handle when it goes out of scope
       Query::Iterator *iterator;
        static void Callback(const v8::WeakCallbackInfo<WrapStop> &); // Callback triggered on GC
};
________________________________________
Constructor for WrapStop

Query::WrapStop::WrapStop(v8::Isolate *isolate, Query::Iterator *iter, v8::Local<v8::Value> val) : value(isolate, val), iterator(iter) {
      value.SetWeak(this, Query::WrapStop::Callback, v8::WeakCallbackType::kParameter);
      // Set value as weak to force GC
}



J Decker

unread,
Jan 18, 2021, 9:56:13 AM1/18/21
to v8-users
On Mon, Jan 18, 2021 at 5:28 AM Vinayaka Kamath <vinayak...@couchbase.com> wrote:
Hello All,

I am trying to return a weak persistent handle to JS through a function template. However the v8 is crashing on triggering the codepath. What is the correct way to do it?
My intention is to trigger GC on the persistent handle when it goes out of scope.

_____________________________________
My Function Template:

void QueryFunction(const v8::FunctionCallbackInfo<v8::Value> &args) {
  // This function is made available as Query() in the JS code
   .
   .
    auto wrapper = new Query::WrapStop(isolate, iterator, it_info.iterable);
    args.GetReturnValue().Set(wrapper->value);   // How to return this?? Set requires a pointer to Persistent

 
   args.GetReturnValue().Set(wrapper->value.Get(Isolate));   // return a reference to the persistent object.

 
    // The intention is to force GC on wrapper->value when it goes out of scope in JS
}
________________________________________
Definition of WrapStop

struct WrapStop {
       explicit WrapStop(v8::Isolate *, Query::Iterator *, v8::Local<v8::Value>);
       virtual ~WrapStop();
       v8::Persistent<v8::Value> value;    // Force GC on this handle when it goes out of scope
       Query::Iterator *iterator;
        static void Callback(const v8::WeakCallbackInfo<WrapStop> &); // Callback triggered on GC
};
________________________________________
Constructor for WrapStop

Query::WrapStop::WrapStop(v8::Isolate *isolate, Query::Iterator *iter, v8::Local<v8::Value> val) : value(isolate, val), iterator(iter) {
      value.SetWeak(this, Query::WrapStop::Callback, v8::WeakCallbackType::kParameter);
      // Set value as weak to force GC
}



--
--
v8-users mailing list
v8-u...@googlegroups.com
http://groups.google.com/group/v8-users
---
You received this message because you are subscribed to the Google Groups "v8-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to v8-users+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/v8-users/490983ae-fd94-4b3e-aa4b-0b4ff8e0c23dn%40googlegroups.com.

Vinayaka Kamath

unread,
Jan 19, 2021, 6:25:57 AM1/19/21
to v8-users
It seems like the v8 is crashing when I follow this. To add more to what I am trying to do, when the "value" goes out of scope I want it to get garbage collected and in the callback, I am freeing up resources held by the value. I am basically forcing GC using isolate->LowMemoryNotification() only when I am creating a new item that holds the same type of resource as of that of "value". I've ensured that I'm calling LowMemoryNotification() in the same thread as that of persistent->setWeak(). However one of the threads running the process is crashing.

Ben Noordhuis

unread,
Jan 19, 2021, 7:35:16 AM1/19/21
to v8-users
On Tue, Jan 19, 2021 at 12:26 PM Vinayaka Kamath
<vinayak...@couchbase.com> wrote:
>
> It seems like the v8 is crashing when I follow this. To add more to what I am trying to do, when the "value" goes out of scope I want it to get garbage collected and in the callback, I am freeing up resources held by the value. I am basically forcing GC using isolate->LowMemoryNotification() only when I am creating a new item that holds the same type of resource as of that of "value". I've ensured that I'm calling LowMemoryNotification() in the same thread as that of persistent->setWeak(). However one of the threads running the process is crashing.

Not a direct answer to your question but it sounds like you're
approaching this wrong. The garbage collector is not a good mechanism
for deterministic resource management.

I also get the impression that you have the wrong idea what "weak"
means here: it's not weak in the sense that it's immediately eligible
for collection, only when there are no strong references (and only
when the garbage collector feels like it - V8's GC is very lazy.)

If your JS code is the functional equivalent of `globalThis.value =
create()`, then you can call LowMemoryNotification() all you want but
it's never going to get collected.

Vinayaka Kamath

unread,
Jan 19, 2021, 7:44:30 AM1/19/21
to v8-users
Is there any better way to do it? Basically I am exposing an Object Template to JS through weak persistent handle and it holds internal resources with it. When the object is no longer accessible in the current executing scope of the JS code, I want to free up all the resources held by the instance of Object Template(maybe through some callback).  At first glance it seems like this is what weak handles are meant for.

Ben Noordhuis

unread,
Jan 19, 2021, 7:55:04 AM1/19/21
to v8-users
On Tue, Jan 19, 2021 at 1:44 PM Vinayaka Kamath
<vinayak...@couchbase.com> wrote:
>
> Is there any better way to do it? Basically I am exposing an Object Template to JS through weak persistent handle and it holds internal resources with it. When the object is no longer accessible in the current executing scope of the JS code, I want to free up all the resources held by the instance of Object Template(maybe through some callback). At first glance it seems like this is what weak handles are meant for.

Well, now you know they're not. :-)

Think of GC as "may reclaim", not "will reclaim", certainly not "will
deterministically reclaim."

If you need determinism, either JS needs to manually release the
resource in try/finally fashion, or you neuter the object after JS is
done with it, callback style:

withResource(function(resource) {
// do something with |resource|
}); // <- withResource() neuters |resource| when the callback returns

"Neuter" in this context means "free the internal resource". The
object may still exist in JS land but you clear its internal pointer.

J Decker

unread,
Jan 19, 2021, 8:11:05 AM1/19/21
to v8-users
On Tue, Jan 19, 2021 at 4:44 AM Vinayaka Kamath <vinayak...@couchbase.com> wrote:
Is there any better way to do it? Basically I am exposing an Object Template to JS through weak persistent handle and it holds internal resources with it. When the object is no longer accessible in the current executing scope of the JS code, I want to free up all the resources held by the instance of Object Template(maybe through some callback).  At first glance it seems like this is what weak handles are meant for.




don't need persistent... which are things that shouldn't be garbage collected...

Node's ObjectWrap class is a generic thing used to wrap C++ classes in JS objects which get garbage collected and have their destructor called...
 
On Tuesday, January 19, 2021 at 6:05:16 PM UTC+5:30 Ben Noordhuis wrote:
On Tue, Jan 19, 2021 at 12:26 PM Vinayaka Kamath
<vinayak...@couchbase.com> wrote:
>
> It seems like the v8 is crashing when I follow this. To add more to what I am trying to do, when the "value" goes out of scope I want it to get garbage collected and in the callback, I am freeing up resources held by the value. I am basically forcing GC using isolate->LowMemoryNotification() only when I am creating a new item that holds the same type of resource as of that of "value". I've ensured that I'm calling LowMemoryNotification() in the same thread as that of persistent->setWeak(). However one of the threads running the process is crashing.

Not a direct answer to your question but it sounds like you're
approaching this wrong. The garbage collector is not a good mechanism
for deterministic resource management.

I also get the impression that you have the wrong idea what "weak"
means here: it's not weak in the sense that it's immediately eligible
for collection, only when there are no strong references (and only
when the garbage collector feels like it - V8's GC is very lazy.)

If your JS code is the functional equivalent of `globalThis.value =
create()`, then you can call LowMemoryNotification() all you want but
it's never going to get collected.

--
--
v8-users mailing list
v8-u...@googlegroups.com
http://groups.google.com/group/v8-users
---
You received this message because you are subscribed to the Google Groups "v8-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to v8-users+u...@googlegroups.com.

Vinayaka Kamath

unread,
Jan 19, 2021, 8:28:03 AM1/19/21
to v8-users
Hello d3c...@gmail.com, I am trying to do the exact same thing. But I am forcing GC with LowMemoryNotification since I want to force release of resources. v8 is intermittently crashing and I've narrowed it down to the call of LowMemoryNotification. Also I am using embedded v8 instead of node.
Reply all
Reply to author
Forward
0 new messages