QV8Engine::~QV8Engine()
{
+ Q_ASSERT_X(v8::Isolate::GetCurrent(), "QV8Engine::~QV8Engine()", "called after v8::Isolate has exited");
for (int ii = 0; ii < m_extensionData.count(); ++ii)
delete m_extensionData[ii];
m_extensionData.clear();
}
}
+void QV8GCCallback::ThreadData::releaseStrongReferencer()
+{
+ // NOTE: must be called with a valid current isolate
+ if (!referencer.strongReferencer.IsEmpty()) {
+ qPersistentDispose(referencer.strongReferencer);
+ }
+}
+
+void QV8GCCallback::releaseWorkerThreadGcPrologueCallbackData()
+{
+ // Note that only worker-thread implementations with their
+ // own QV8Engine should explicitly release the Referencer
+ // by calling this functions.
+ Q_ASSERT_X(v8::Isolate::GetCurrent(), "QV8GCCallback::releaseWorkerThreadGcPrologueCallbackData()", "called after v8::Isolate has exited");
+ if (threadData.hasLocalData()) {
+ QV8GCCallback::ThreadData *td = threadData.localData();
+ td->releaseStrongReferencer();
+ }
+}
+
QV8GCCallback::Node::Node(PrologueCallback callback)
: prologueCallback(callback)
{
QV8GCCallback::Referencer::~Referencer()
{
- qPersistentDispose(strongReferencer);
+ if (!strongReferencer.IsEmpty()) {
+ Q_ASSERT_X(v8::Isolate::GetCurrent(), "QV8GCCallback::Referencer::~Referencer()", "called after v8::Isolate has exited");
+ // automatically release the strongReferencer if it hasn't
+ // been explicitly released already.
+ qPersistentDispose(strongReferencer);
+ }
}
QV8GCCallback::Referencer::Referencer()
public:
static void garbageCollectorPrologueCallback(v8::GCType, v8::GCCallbackFlags);
static void registerGcPrologueCallback();
+ static void releaseWorkerThreadGcPrologueCallbackData();
class Referencer {
public:
Referencer referencer;
bool gcPrologueCallbackRegistered;
QIntrusiveList<Node, &Node::node> gcCallbackNodes;
+ void releaseStrongReferencer();
};
static void initializeThreadData();