Changeset 192773 in webkit


Ignore:
Timestamp:
Nov 26, 2015 5:52:45 AM (8 years ago)
Author:
Carlos Garcia Campos
Message:

[GLIB] Implement garbage collector timers
https://bugs.webkit.org/show_bug.cgi?id=151391

Reviewed by Žan Doberšek.

Add GLib implementation using GSource.

  • heap/EdenGCActivityCallback.cpp:
  • heap/FullGCActivityCallback.cpp:
  • heap/GCActivityCallback.cpp:

(JSC::GCActivityCallback::GCActivityCallback):
(JSC::GCActivityCallback::scheduleTimer):
(JSC::GCActivityCallback::cancelTimer):

  • heap/GCActivityCallback.h:
  • heap/Heap.cpp:

(JSC::Heap::Heap):

  • heap/HeapTimer.cpp:

(JSC::HeapTimer::HeapTimer):
(JSC::HeapTimer::~HeapTimer):
(JSC::HeapTimer::timerDidFire):

  • heap/HeapTimer.h:
  • heap/IncrementalSweeper.cpp:

(JSC::IncrementalSweeper::IncrementalSweeper):
(JSC::IncrementalSweeper::scheduleTimer):
(JSC::IncrementalSweeper::cancelTimer):

  • heap/IncrementalSweeper.h:
Location:
trunk/Source/JavaScriptCore
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r192768 r192773  
     12015-11-26  Carlos Garcia Campos  <cgarcia@igalia.com>
     2
     3        [GLIB] Implement garbage collector timers
     4        https://bugs.webkit.org/show_bug.cgi?id=151391
     5
     6        Reviewed by Žan Doberšek.
     7
     8        Add GLib implementation using GSource.
     9
     10        * heap/EdenGCActivityCallback.cpp:
     11        * heap/FullGCActivityCallback.cpp:
     12        * heap/GCActivityCallback.cpp:
     13        (JSC::GCActivityCallback::GCActivityCallback):
     14        (JSC::GCActivityCallback::scheduleTimer):
     15        (JSC::GCActivityCallback::cancelTimer):
     16        * heap/GCActivityCallback.h:
     17        * heap/Heap.cpp:
     18        (JSC::Heap::Heap):
     19        * heap/HeapTimer.cpp:
     20        (JSC::HeapTimer::HeapTimer):
     21        (JSC::HeapTimer::~HeapTimer):
     22        (JSC::HeapTimer::timerDidFire):
     23        * heap/HeapTimer.h:
     24        * heap/IncrementalSweeper.cpp:
     25        (JSC::IncrementalSweeper::IncrementalSweeper):
     26        (JSC::IncrementalSweeper::scheduleTimer):
     27        (JSC::IncrementalSweeper::cancelTimer):
     28        * heap/IncrementalSweeper.h:
     29
    1302015-11-24  Caitlin Potter  <caitp@igalia.com>
    231
  • trunk/Source/JavaScriptCore/heap/EdenGCActivityCallback.cpp

    r192721 r192773  
    3131namespace JSC {
    3232
    33 #if USE(CF) || PLATFORM(EFL)
     33#if USE(CF) || USE(GLIB)
    3434
    3535EdenGCActivityCallback::EdenGCActivityCallback(Heap* heap)
  • trunk/Source/JavaScriptCore/heap/FullGCActivityCallback.cpp

    r192721 r192773  
    3131namespace JSC {
    3232
    33 #if USE(CF) || PLATFORM(EFL)
     33#if USE(CF) || USE(GLIB)
    3434
    3535#if !PLATFORM(IOS)
  • trunk/Source/JavaScriptCore/heap/GCActivityCallback.cpp

    r165940 r192773  
    4040#if PLATFORM(EFL)
    4141#include <wtf/MainThread.h>
     42#elif USE(GLIB)
     43#include <glib.h>
    4244#endif
    4345
     
    4648bool GCActivityCallback::s_shouldCreateGCTimer = true;
    4749
    48 #if USE(CF) || PLATFORM(EFL)
     50#if USE(CF) || USE(GLIB)
    4951
    5052const double timerSlop = 2.0; // Fudge factor to avoid performance cost of resetting timer.
     
    6365GCActivityCallback::GCActivityCallback(Heap* heap)
    6466    : GCActivityCallback(heap->vm(), WTF::isMainThread())
     67{
     68}
     69#elif USE(GLIB)
     70GCActivityCallback::GCActivityCallback(Heap* heap)
     71    : GCActivityCallback(heap->vm())
    6572{
    6673}
     
    114121    m_delay = s_hour;
    115122    stop();
     123}
     124#elif USE(GLIB)
     125void GCActivityCallback::scheduleTimer(double newDelay)
     126{
     127    ASSERT(newDelay >= 0);
     128    if (m_delay != -1 && newDelay * timerSlop > m_delay)
     129        return;
     130
     131    m_delay = newDelay;
     132    if (!m_delay) {
     133        g_source_set_ready_time(m_timer.get(), 0);
     134        return;
     135    }
     136
     137    auto delayDuration = std::chrono::duration<double>(m_delay);
     138    auto safeDelayDuration = std::chrono::microseconds::max();
     139    if (delayDuration < safeDelayDuration)
     140        safeDelayDuration = std::chrono::duration_cast<std::chrono::microseconds>(delayDuration);
     141    gint64 currentTime = g_get_monotonic_time();
     142    gint64 targetTime = currentTime + std::min<gint64>(G_MAXINT64 - currentTime, safeDelayDuration.count());
     143    ASSERT(targetTime >= currentTime);
     144    g_source_set_ready_time(m_timer.get(), targetTime);
     145}
     146
     147void GCActivityCallback::cancelTimer()
     148{
     149    m_delay = -1;
     150    g_source_set_ready_time(m_timer.get(), -1);
    116151}
    117152#endif
  • trunk/Source/JavaScriptCore/heap/GCActivityCallback.h

    r185387 r192773  
    8282    {
    8383    }
     84#elif USE(GLIB)
     85    GCActivityCallback(VM* vm)
     86        : HeapTimer(vm)
     87        , m_enabled(true)
     88        , m_delay(-1)
     89    {
     90    }
    8491#else
    8592    GCActivityCallback(VM* vm)
     
    96103    GCActivityCallback(Heap*, CFRunLoopRef);
    97104#endif
    98 #if USE(CF) || PLATFORM(EFL)
     105#if USE(CF) || USE(GLIB)
    99106protected:
    100107    void cancelTimer();
  • trunk/Source/JavaScriptCore/heap/Heap.cpp

    r191849 r192773  
    348348    , m_sweeper(std::make_unique<IncrementalSweeper>(this, CFRunLoopGetCurrent()))
    349349#else
    350     , m_sweeper(std::make_unique<IncrementalSweeper>(this->vm()))
     350    , m_sweeper(std::make_unique<IncrementalSweeper>(this))
    351351#endif
    352352    , m_deferralDepth(0)
  • trunk/Source/JavaScriptCore/heap/HeapTimer.cpp

    r182847 r192773  
    3737#if PLATFORM(EFL)
    3838#include <Ecore.h>
     39#elif USE(GLIB)
     40#include <glib.h>
    3941#endif
    4042
     
    141143    return ECORE_CALLBACK_CANCEL;
    142144}
     145
     146#elif USE(GLIB)
     147
     148static GSourceFuncs heapTimerSourceFunctions = {
     149    nullptr, // prepare
     150    nullptr, // check
     151    // dispatch
     152    [](GSource* source, GSourceFunc callback, gpointer userData) -> gboolean
     153    {
     154        if (g_source_get_ready_time(source) == -1)
     155            return G_SOURCE_CONTINUE;
     156        g_source_set_ready_time(source, -1);
     157        return callback(userData);
     158    },
     159    nullptr, // finalize
     160    nullptr, // closure_callback
     161    nullptr, // closure_marshall
     162};
     163
     164HeapTimer::HeapTimer(VM* vm)
     165    : m_vm(vm)
     166    , m_apiLock(&vm->apiLock())
     167    , m_timer(adoptGRef(g_source_new(&heapTimerSourceFunctions, sizeof(GSource))))
     168{
     169    g_source_set_name(m_timer.get(), "[JavaScriptCore] HeapTimer");
     170    g_source_set_callback(m_timer.get(), [](gpointer userData) -> gboolean {
     171        static_cast<HeapTimer*>(userData)->timerDidFire();
     172        return G_SOURCE_CONTINUE;
     173    }, this, nullptr);
     174    g_source_attach(m_timer.get(), g_main_context_get_thread_default());
     175}
     176
     177HeapTimer::~HeapTimer()
     178{
     179    g_source_destroy(m_timer.get());
     180}
     181
     182void HeapTimer::timerDidFire()
     183{
     184    m_apiLock->lock();
     185
     186    if (!m_apiLock->vm()) {
     187        // The VM has been destroyed, so we should just give up.
     188        m_apiLock->unlock();
     189        return;
     190    }
     191
     192    {
     193        JSLockHolder locker(m_vm);
     194        doWork();
     195    }
     196
     197    m_apiLock->unlock();
     198}
     199
    143200#else
    144201HeapTimer::HeapTimer(VM* vm)
  • trunk/Source/JavaScriptCore/heap/HeapTimer.h

    r188499 r192773  
    3535#endif
    3636
     37#if USE(GLIB) && !PLATFORM(EFL)
     38#include <wtf/glib/GRefPtr.h>
     39#endif
     40
    3741namespace JSC {
    3842
     43class JSLock;
    3944class VM;
    4045
     
    6772    void stop();
    6873    Ecore_Timer* m_timer;
     74#elif USE(GLIB)
     75    void timerDidFire();
     76    RefPtr<JSLock> m_apiLock;
     77    GRefPtr<GSource> m_timer;
    6978#endif
    7079   
  • trunk/Source/JavaScriptCore/heap/IncrementalSweeper.cpp

    r185387 r192773  
    3636#include <wtf/WTFThreadData.h>
    3737
     38#if USE(GLIB) && !PLATFORM(EFL)
     39#include <glib.h>
     40#endif
     41
    3842namespace JSC {
    3943
    40 #if USE(CF)
     44#if USE(CF) || (USE(GLIB) && !PLATFORM(EFL))
    4145
    4246static const double sweepTimeSlice = .01; // seconds
     
    4448static const double sweepTimeMultiplier = 1.0 / sweepTimeTotal;
    4549
     50#if USE(CF)
    4651IncrementalSweeper::IncrementalSweeper(Heap* heap, CFRunLoopRef runLoop)
    4752    : HeapTimer(heap->vm(), runLoop)
     
    5964    CFRunLoopTimerSetNextFireDate(m_timer.get(), CFAbsoluteTimeGetCurrent() + s_decade);
    6065}
     66#elif USE(GLIB)
     67IncrementalSweeper::IncrementalSweeper(Heap* heap)
     68    : HeapTimer(heap->vm())
     69    , m_blocksToSweep(heap->m_blockSnapshot)
     70{
     71}
     72
     73void IncrementalSweeper::scheduleTimer()
     74{
     75    auto delayDuration = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::duration<double>(sweepTimeSlice * sweepTimeMultiplier));
     76    gint64 currentTime = g_get_monotonic_time();
     77    gint64 targetTime = currentTime + std::min<gint64>(G_MAXINT64 - currentTime, delayDuration.count());
     78    ASSERT(targetTime >= currentTime);
     79    g_source_set_ready_time(m_timer.get(), targetTime);
     80}
     81
     82void IncrementalSweeper::cancelTimer()
     83{
     84    g_source_set_ready_time(m_timer.get(), -1);
     85}
     86#endif
    6187
    6288void IncrementalSweeper::doWork()
     
    111137#else
    112138
    113 IncrementalSweeper::IncrementalSweeper(VM* vm)
    114     : HeapTimer(vm)
     139IncrementalSweeper::IncrementalSweeper(Heap* heap)
     140    : HeapTimer(heap->vm())
    115141{
    116142}
  • trunk/Source/JavaScriptCore/heap/IncrementalSweeper.h

    r185387 r192773  
    4141    JS_EXPORT_PRIVATE IncrementalSweeper(Heap*, CFRunLoopRef);
    4242#else
    43     explicit IncrementalSweeper(VM*);
     43    explicit IncrementalSweeper(Heap*);
    4444#endif
    4545
     
    5050    void willFinishSweeping();
    5151
    52 #if USE(CF)
     52#if USE(CF) || (USE(GLIB) && !PLATFORM(EFL))
    5353private:
    5454    void doSweep(double startTime);
Note: See TracChangeset for help on using the changeset viewer.