1,v875的v8::PersistentHandleVisitor是可以把句柄全遍历出来的,但要想保持这些句柄长久不被gc回收,要在v8::EmbedderHeapTracer的AdvanceTracing里调用tracer->RegisterEmbedderReference。在v8::PersistentHandleVisitor里调用RegisterEmbedderReference是无效的。这个我研究了很久v8才知道。
2,v8::EmbedderHeapTracer::RegisterV8References会回调blink,告诉有哪些句柄需要blink确认是否要被回收。但这里有个大坑,就是RegisterV8References有时候返回的句柄数量不完整,也就是说有的对象是在上次RegisterV8References的时候通知过去,下次可能就不通知了。
新blink(比如57版本)的解决方案是blink通过ActiveScriptWrappableBase收集所有需要trace的对象,再用ActiveScriptWrappableBase::traceActiveScriptWrappables告诉blink的ScriptWrappableVisitor::RegisterV8Reference收集起来。此外ScriptWrappableVisitor::RegisterV8References(和上面那个函数只差了一个s)也会被v8回调,告诉v8有哪些句柄。
这些被收集起来的句柄,统一在ScriptWrappableVisitor::AdvanceTracing里调用tracer->RegisterEmbedderReference,告诉v8别回收这些句柄。
另外有个小插曲,V8PerIsolateData::m_activeScriptWrappables的数量减少是blink的gc自动进行的。
3,所以在老版本blink上要移植v875,我的解决方案是在RegisterV8References里收集了V8References后不删除,直到整个blink、v8的gc都结束了再销毁收集的V8References。
并没有采用ActiveScriptWrappableBase收集的方式。