diff options
Diffstat (limited to 'Source/JavaScriptCore/heap/HeapTimer.cpp')
-rw-r--r-- | Source/JavaScriptCore/heap/HeapTimer.cpp | 152 |
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() { } |