summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/heap/HeapTimer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/heap/HeapTimer.cpp')
-rw-r--r--Source/JavaScriptCore/heap/HeapTimer.cpp152
1 files changed, 73 insertions, 79 deletions
diff --git a/Source/JavaScriptCore/heap/HeapTimer.cpp b/Source/JavaScriptCore/heap/HeapTimer.cpp
index d69ee9607..a30a28b45 100644
--- a/Source/JavaScriptCore/heap/HeapTimer.cpp
+++ b/Source/JavaScriptCore/heap/HeapTimer.cpp
@@ -38,6 +38,8 @@
#include <QMutexLocker>
#include <QThread>
#include <QTimerEvent>
+#elif PLATFORM(EFL)
+#include <Ecore.h>
#endif
namespace JSC {
@@ -46,70 +48,67 @@ namespace JSC {
const CFTimeInterval HeapTimer::s_decade = 60 * 60 * 24 * 365 * 10;
-HeapTimer::HeapTimer(JSGlobalData* globalData, CFRunLoopRef runLoop)
- : m_globalData(globalData)
- , m_runLoop(runLoop)
+static const void* retainAPILock(const void* info)
{
- memset(&m_context, 0, sizeof(CFRunLoopTimerContext));
- m_context.info = this;
- m_timer.adoptCF(CFRunLoopTimerCreate(0, s_decade, s_decade, 0, 0, HeapTimer::timerDidFire, &m_context));
- CFRunLoopAddTimer(m_runLoop.get(), m_timer.get(), kCFRunLoopCommonModes);
+ static_cast<JSLock*>(const_cast<void*>(info))->ref();
+ return info;
}
-HeapTimer::~HeapTimer()
+static void releaseAPILock(const void* info)
{
- CFRunLoopRemoveTimer(m_runLoop.get(), m_timer.get(), kCFRunLoopCommonModes);
- CFRunLoopTimerInvalidate(m_timer.get());
+ static_cast<JSLock*>(const_cast<void*>(info))->deref();
}
-void HeapTimer::synchronize()
+HeapTimer::HeapTimer(VM* vm, CFRunLoopRef runLoop)
+ : m_vm(vm)
+ , m_runLoop(runLoop)
{
- if (CFRunLoopGetCurrent() == m_runLoop.get())
- return;
- CFRunLoopRemoveTimer(m_runLoop.get(), m_timer.get(), kCFRunLoopCommonModes);
- m_runLoop = CFRunLoopGetCurrent();
+ memset(&m_context, 0, sizeof(CFRunLoopTimerContext));
+ m_context.info = &vm->apiLock();
+ m_context.retain = retainAPILock;
+ m_context.release = releaseAPILock;
+ m_timer = adoptCF(CFRunLoopTimerCreate(0, s_decade, s_decade, 0, 0, HeapTimer::timerDidFire, &m_context));
CFRunLoopAddTimer(m_runLoop.get(), m_timer.get(), kCFRunLoopCommonModes);
}
-void HeapTimer::invalidate()
+HeapTimer::~HeapTimer()
{
- m_globalData = 0;
- CFRunLoopTimerSetNextFireDate(m_timer.get(), CFAbsoluteTimeGetCurrent() - s_decade);
+ CFRunLoopRemoveTimer(m_runLoop.get(), m_timer.get(), kCFRunLoopCommonModes);
+ CFRunLoopTimerInvalidate(m_timer.get());
}
-void HeapTimer::didStartVMShutdown()
+void HeapTimer::timerDidFire(CFRunLoopTimerRef timer, void* context)
{
- if (CFRunLoopGetCurrent() == m_runLoop.get()) {
- invalidate();
- delete this;
- return;
- }
- ASSERT(!m_globalData->apiLock().currentThreadIsHoldingLock());
- MutexLocker locker(m_shutdownMutex);
- invalidate();
-}
+ JSLock* apiLock = static_cast<JSLock*>(context);
+ apiLock->lock();
-void HeapTimer::timerDidFire(CFRunLoopTimerRef, void* info)
-{
- HeapTimer* agent = static_cast<HeapTimer*>(info);
- agent->m_shutdownMutex.lock();
- if (!agent->m_globalData) {
- agent->m_shutdownMutex.unlock();
- delete agent;
+ VM* vm = apiLock->vm();
+ // The VM has been destroyed, so we should just give up.
+ if (!vm) {
+ apiLock->unlock();
return;
}
+
+ HeapTimer* heapTimer = 0;
+ if (vm->heap.activityCallback()->m_timer.get() == timer)
+ heapTimer = vm->heap.activityCallback();
+ else if (vm->heap.sweeper()->m_timer.get() == timer)
+ heapTimer = vm->heap.sweeper();
+ else
+ RELEASE_ASSERT_NOT_REACHED();
+
{
- // We don't ref here to prevent us from resurrecting the ref count of a "dead" JSGlobalData.
- APIEntryShim shim(agent->m_globalData, APIEntryShimWithoutLock::DontRefGlobalData);
- agent->doWork();
+ APIEntryShim shim(vm);
+ heapTimer->doWork();
}
- agent->m_shutdownMutex.unlock();
+
+ apiLock->unlock();
}
#elif PLATFORM(BLACKBERRY)
-HeapTimer::HeapTimer(JSGlobalData* globalData)
- : m_globalData(globalData)
+HeapTimer::HeapTimer(VM* vm)
+ : m_vm(vm)
, m_timer(this, &HeapTimer::timerDidFire)
{
// FIXME: Implement HeapTimer for other threads.
@@ -126,23 +125,14 @@ void HeapTimer::timerDidFire()
doWork();
}
-void HeapTimer::synchronize()
-{
-}
-
void HeapTimer::invalidate()
{
}
-void HeapTimer::didStartVMShutdown()
-{
- delete this;
-}
-
#elif PLATFORM(QT)
-HeapTimer::HeapTimer(JSGlobalData* globalData)
- : m_globalData(globalData)
+HeapTimer::HeapTimer(VM* vm)
+ : m_vm(vm)
, m_newThread(0)
, m_mutex(QMutex::NonRecursive)
{
@@ -153,6 +143,8 @@ HeapTimer::HeapTimer(JSGlobalData* globalData)
HeapTimer::~HeapTimer()
{
+ QMutexLocker lock(&m_mutex);
+ m_timer.stop();
}
void HeapTimer::timerEvent(QTimerEvent*)
@@ -163,7 +155,7 @@ void HeapTimer::timerEvent(QTimerEvent*)
return;
}
- APIEntryShim shim(m_globalData, APIEntryShimWithoutLock::DontRefGlobalData);
+ APIEntryShim shim(m_vm);
doWork();
}
@@ -175,49 +167,51 @@ void HeapTimer::customEvent(QEvent*)
m_newThread = 0;
}
-void HeapTimer::synchronize()
+#elif PLATFORM(EFL)
+
+HeapTimer::HeapTimer(VM* vm)
+ : m_vm(vm)
+ , m_timer(0)
{
- if (thread() != QThread::currentThread()) {
- // We can only move from the objects own thread to another, so we fire an
- // event into the owning thread to trigger the move.
- // This must be processed before any timerEvents so giving it high priority.
- QMutexLocker lock(&m_mutex);
- m_newThread = QThread::currentThread();
- QCoreApplication::postEvent(this, new QEvent(QEvent::User), Qt::HighEventPriority);
- }
}
-void HeapTimer::invalidate()
+HeapTimer::~HeapTimer()
{
- QMutexLocker lock(&m_mutex);
- m_timer.stop();
+ stop();
}
-void HeapTimer::didStartVMShutdown()
+Ecore_Timer* HeapTimer::add(double delay, void* agent)
{
- invalidate();
- if (thread() == QThread::currentThread())
- delete this;
- else
- deleteLater();
+ return ecore_timer_add(delay, reinterpret_cast<Ecore_Task_Cb>(timerEvent), agent);
}
-
-#else
-HeapTimer::HeapTimer(JSGlobalData* globalData)
- : m_globalData(globalData)
+
+void HeapTimer::stop()
{
+ if (!m_timer)
+ return;
+
+ ecore_timer_del(m_timer);
+ m_timer = 0;
}
-HeapTimer::~HeapTimer()
+bool HeapTimer::timerEvent(void* info)
{
+ HeapTimer* agent = static_cast<HeapTimer*>(info);
+
+ APIEntryShim shim(agent->m_vm);
+ agent->doWork();
+ agent->m_timer = 0;
+
+ return ECORE_CALLBACK_CANCEL;
}
-void HeapTimer::didStartVMShutdown()
+#else
+HeapTimer::HeapTimer(VM* vm)
+ : m_vm(vm)
{
- delete this;
}
-void HeapTimer::synchronize()
+HeapTimer::~HeapTimer()
{
}