如何在 Spidermonkey 中创建、处理和销毁 JS::Heap 对象?

2023-12-03

Using 蜘蛛猴 24, 38, 45

蜘蛛猴文档说:“堆上的 GC 事物指针必须包装在 JS::Heap 中。唯一的例外是,如果使用 JS_AddRoot() 函数或 JS::PersistentRooted 类将它们添加为根,但是不要这样做,除非这确实有必要。JS::Heap 指针也必须继续以正常方式跟踪,这里不涉及。”

在这种情况下,追踪究竟意味着什么?下面的代码是不是少了什么东西?

struct Foo
{
   Foo(JS::HandleObject bar) : _bar(bar) {}  // Does that root bar?
   ~Foo() {_bar = nullptr;}                  // Does that release memory?

   JS::Heap<JSObject*>  _bar;
};

Foo *create(JSContext *jscontext, JSObject *parent)
{
   JS::RootedObject bar(jscontext, JS_NewObject(jscontext, &SOME_CLASS, NULL, parent));
   return new Foo(bar);
}

我需要添加“跟踪”吗?当 bar 对象存储在 Foo 中时,我需要 root 吗?我应该使用 JS_AddRoot() 函数来根栏而不是使用堆吗?


JS::Heap<T>用于驻留在堆上的数据结构。追踪确实是一个要求。如果没有它,GC 可能会确定您的对象无法访问,或者在不更新您的对象的情况下重新定位它JS::Heap<T> handle.

在 Spidermonkey 中追踪物体很简单。您需要使用以下命令请求额外的 GC 根跟踪器JS_AddExtraGCRootsTracer(JSRuntime* rt, JSTraceDataOp traceOp, void* data)。 JSTraceDataOp 是一个带有接口的函数指针void traceOp(JSTracer* trc, void* data)。在您的函数中,您必须调用各种JS_Call<T>Tracer(定义于Tracer.h) 传递跟踪器和您的对象的方法。此外,您应该致电JS_TraceChildren有必要的。

使用您的示例,添加跟踪器可能如下所示。

Foo* ref = create(cx, nullptr);

void trace_foos(JSTracer* tracer, void* data) {
   JS_CallHeapObjectTracer(tracer, &(ref->_bar), "foo");
}

JS_AddExtraGCRootsTracer(rt, trace_foos, nullptr);

每当 GC 运行时,您的跟踪回调就会运行,您应该遍历对象图并跟踪 GC 的情况。

至于您评论中的问题——

   Foo(JS::HandleObject bar) : _bar(bar) {}  // Does that root bar?

bar已经在堆栈上扎根了JS::RootedObject bar in Foo* create. Heap<T>句柄不是根——这就是为什么必须追踪它们。立刻create返回时,该对象不再有根。

  ~Foo() {_bar = nullptr;}                  // Does that release memory?

No. _bar只是一个例子JS::Heap<T>处理。它指向的东西将在后续循环中被垃圾收集。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Spidermonkey 中创建、处理和销毁 JS::Heap 对象? 的相关文章

随机推荐