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.cpp160
1 files changed, 92 insertions, 68 deletions
diff --git a/Source/JavaScriptCore/heap/HeapTimer.cpp b/Source/JavaScriptCore/heap/HeapTimer.cpp
index 1331b0ac0..9c8b30252 100644
--- a/Source/JavaScriptCore/heap/HeapTimer.cpp
+++ b/Source/JavaScriptCore/heap/HeapTimer.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,116 +26,137 @@
#include "config.h"
#include "HeapTimer.h"
-#include "APIShims.h"
+#include "GCActivityCallback.h"
+#include "IncrementalSweeper.h"
#include "JSObject.h"
#include "JSString.h"
-
+#include "JSCInlines.h"
#include <wtf/MainThread.h>
#include <wtf/Threading.h>
-#if PLATFORM(EFL)
-#include <Ecore.h>
+#if USE(GLIB)
+#include <glib.h>
#endif
namespace JSC {
+void HeapTimer::timerDidFire()
+{
+ m_apiLock->lock();
+
+ RefPtr<VM> vm = m_apiLock->vm();
+ if (!vm) {
+ // The VM has been destroyed, so we should just give up.
+ m_apiLock->unlock();
+ return;
+ }
+
+ {
+ JSLockHolder locker(vm.get());
+ doWork();
+ }
+
+ m_apiLock->unlock();
+}
+
#if USE(CF)
const CFTimeInterval HeapTimer::s_decade = 60 * 60 * 24 * 365 * 10;
-static const void* retainAPILock(const void* info)
+HeapTimer::HeapTimer(VM* vm)
+ : m_vm(vm)
+ , m_apiLock(&vm->apiLock())
{
- static_cast<JSLock*>(const_cast<void*>(info))->ref();
- return info;
+ setRunLoop(vm->heap.runLoop());
}
-static void releaseAPILock(const void* info)
+void HeapTimer::setRunLoop(CFRunLoopRef runLoop)
{
- static_cast<JSLock*>(const_cast<void*>(info))->deref();
+ if (m_runLoop) {
+ CFRunLoopRemoveTimer(m_runLoop.get(), m_timer.get(), kCFRunLoopCommonModes);
+ CFRunLoopTimerInvalidate(m_timer.get());
+ m_runLoop.clear();
+ m_timer.clear();
+ }
+
+ if (runLoop) {
+ m_runLoop = runLoop;
+ memset(&m_context, 0, sizeof(CFRunLoopTimerContext));
+ m_context.info = this;
+ m_timer = adoptCF(CFRunLoopTimerCreate(kCFAllocatorDefault, s_decade, s_decade, 0, 0, HeapTimer::timerDidFireCallback, &m_context));
+ CFRunLoopAddTimer(m_runLoop.get(), m_timer.get(), kCFRunLoopCommonModes);
+ }
}
-HeapTimer::HeapTimer(VM* vm, CFRunLoopRef runLoop)
- : m_vm(vm)
- , m_runLoop(runLoop)
+HeapTimer::~HeapTimer()
{
- 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);
+ setRunLoop(0);
}
-HeapTimer::~HeapTimer()
+void HeapTimer::timerDidFireCallback(CFRunLoopTimerRef, void* contextPtr)
{
- CFRunLoopRemoveTimer(m_runLoop.get(), m_timer.get(), kCFRunLoopCommonModes);
- CFRunLoopTimerInvalidate(m_timer.get());
+ static_cast<JSRunLoopTimer*>(contextPtr)->timerDidFire();
}
-void HeapTimer::timerDidFire(CFRunLoopTimerRef timer, void* context)
+void HeapTimer::scheduleTimer(double intervalInSeconds)
{
- JSLock* apiLock = static_cast<JSLock*>(context);
- apiLock->lock();
-
- VM* vm = apiLock->vm();
- // The VM has been destroyed, so we should just give up.
- if (!vm) {
- apiLock->unlock();
- return;
- }
+ CFRunLoopTimerSetNextFireDate(m_timer.get(), CFAbsoluteTimeGetCurrent() + intervalInSeconds);
+ m_isScheduled = true;
+}
- HeapTimer* heapTimer = 0;
- if (vm->heap.activityCallback() && 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();
+void HeapTimer::cancelTimer()
+{
+ CFRunLoopTimerSetNextFireDate(m_timer.get(), CFAbsoluteTimeGetCurrent() + s_decade);
+ m_isScheduled = false;
+}
- {
- APIEntryShim shim(vm);
- heapTimer->doWork();
- }
+#elif USE(GLIB)
- apiLock->unlock();
-}
+const long HeapTimer::s_decade = 60 * 60 * 24 * 365 * 10;
-#elif PLATFORM(EFL)
+static GSourceFuncs heapTimerSourceFunctions = {
+ nullptr, // prepare
+ nullptr, // check
+ // dispatch
+ [](GSource*, GSourceFunc callback, gpointer userData) -> gboolean
+ {
+ return callback(userData);
+ },
+ nullptr, // finalize
+ nullptr, // closure_callback
+ nullptr, // closure_marshall
+};
HeapTimer::HeapTimer(VM* vm)
: m_vm(vm)
- , m_timer(0)
+ , m_apiLock(&vm->apiLock())
+ , m_timer(adoptGRef(g_source_new(&heapTimerSourceFunctions, sizeof(GSource))))
{
+ g_source_set_name(m_timer.get(), "[JavaScriptCore] HeapTimer");
+ g_source_set_callback(m_timer.get(), [](gpointer userData) -> gboolean {
+ auto& heapTimer = *static_cast<HeapTimer*>(userData);
+ g_source_set_ready_time(heapTimer.m_timer.get(), g_get_monotonic_time() + HeapTimer::s_decade * G_USEC_PER_SEC);
+ heapTimer.timerDidFire();
+ return G_SOURCE_CONTINUE;
+ }, this, nullptr);
+ g_source_attach(m_timer.get(), g_main_context_get_thread_default());
}
HeapTimer::~HeapTimer()
{
- stop();
+ g_source_destroy(m_timer.get());
}
-Ecore_Timer* HeapTimer::add(double delay, void* agent)
+void HeapTimer::scheduleTimer(double intervalInSeconds)
{
- return ecore_timer_add(delay, reinterpret_cast<Ecore_Task_Cb>(timerEvent), agent);
-}
-
-void HeapTimer::stop()
-{
- if (!m_timer)
- return;
-
- ecore_timer_del(m_timer);
- m_timer = 0;
+ g_source_set_ready_time(m_timer.get(), g_get_monotonic_time() + intervalInSeconds * G_USEC_PER_SEC);
+ m_isScheduled = true;
}
-bool HeapTimer::timerEvent(void* info)
+void HeapTimer::cancelTimer()
{
- HeapTimer* agent = static_cast<HeapTimer*>(info);
-
- APIEntryShim shim(agent->m_vm);
- agent->doWork();
- agent->m_timer = 0;
-
- return ECORE_CALLBACK_CANCEL;
+ g_source_set_ready_time(m_timer.get(), g_get_monotonic_time() + s_decade * G_USEC_PER_SEC);
+ m_isScheduled = false;
}
#else
HeapTimer::HeapTimer(VM* vm)
@@ -147,10 +168,13 @@ HeapTimer::~HeapTimer()
{
}
-void HeapTimer::invalidate()
+void HeapTimer::scheduleTimer(double)
{
}
+void HeapTimer::cancelTimer()
+{
+}
#endif