From 873d345a9ee4c78a30c80a12c627586f280c4eab Mon Sep 17 00:00:00 2001 From: Hojong Han Date: Fri, 21 Jun 2013 16:32:19 +0900 Subject: [PATCH] Incremetal sweeper added to improve memory usage [Title] Incremetal sweeper added to improve memory usage [Issue#] N/A [Problem] N/A [Cause] N/A [Solution] GC Activity Callback modified and Incremental Sweeper added Change-Id: I912fc9b537566cce20b8f6655a1bfc2b2d0942af --- Source/JavaScriptCore/PlatformEfl.cmake | 18 ++--- Source/JavaScriptCore/heap/HeapTimer.cpp | 26 ++++++- Source/JavaScriptCore/heap/HeapTimer.h | 16 ++-- Source/JavaScriptCore/heap/IncrementalSweeper.cpp | 89 ++++++++++++++++++++++ Source/JavaScriptCore/heap/IncrementalSweeper.h | 21 +++-- Source/JavaScriptCore/runtime/GCActivityCallback.h | 13 +++- .../runtime/GCActivityCallbackEfl.cpp | 34 ++++++--- Source/cmakeconfig.h.cmake | 1 - 8 files changed, 175 insertions(+), 43 deletions(-) diff --git a/Source/JavaScriptCore/PlatformEfl.cmake b/Source/JavaScriptCore/PlatformEfl.cmake index ae95146..177c80d 100755 --- a/Source/JavaScriptCore/PlatformEfl.cmake +++ b/Source/JavaScriptCore/PlatformEfl.cmake @@ -1,26 +1,20 @@ LIST(APPEND JavaScriptCore_SOURCES jit/ExecutableAllocatorFixedVMPool.cpp jit/ExecutableAllocator.cpp + runtime/GCActivityCallbackEfl.cpp ) -IF (ENABLE_TIZEN_GC_ACTIVITY_CALLBACK) - LIST(REMOVE_ITEM JavaScriptCore_SOURCES - runtime/GCActivityCallback.cpp - ) - LIST(APPEND JavaScriptCore_SOURCES - runtime/GCActivityCallbackEfl.cpp - ) - LIST(APPEND JavaScriptCore_INCLUDE_DIRECTORIES - ${ECORE_X_INCLUDE_DIRS} - ${EINA_INCLUDE_DIRS} - ) -ENDIF () +LIST(REMOVE_ITEM JavaScriptCore_SOURCES + runtime/GCActivityCallback.cpp +) LIST(APPEND JavaScriptCore_LIBRARIES ${ICU_I18N_LIBRARIES} ) LIST(APPEND JavaScriptCore_INCLUDE_DIRECTORIES + ${ECORE_INCLUDE_DIRS} + ${EINA_INCLUDE_DIRS} ${ICU_INCLUDE_DIRS} ) diff --git a/Source/JavaScriptCore/heap/HeapTimer.cpp b/Source/JavaScriptCore/heap/HeapTimer.cpp index 59546a8..d90690a 100644 --- a/Source/JavaScriptCore/heap/HeapTimer.cpp +++ b/Source/JavaScriptCore/heap/HeapTimer.cpp @@ -32,6 +32,10 @@ #include "ScopeChain.h" #include +#if PLATFORM(EFL) +#include +#endif + namespace JSC { #if USE(CF) @@ -128,10 +132,11 @@ void HeapTimer::didStartVMShutdown() delete this; } -#elif PLATFORM(EFL) && ENABLE(TIZEN_GC_ACTIVITY_CALLBACK) +#elif PLATFORM(EFL) HeapTimer::HeapTimer(JSGlobalData* globalData) : m_globalData(globalData) + , m_timer(0) { ecore_init(); } @@ -155,10 +160,27 @@ void HeapTimer::invalidate() { } -bool HeapTimer::timerDidFire(void* info) +Ecore_Timer* HeapTimer::add(double delay, void* agent) +{ + return ecore_timer_add(delay, reinterpret_cast(timerEvent), agent); +} + +void HeapTimer::stop() +{ + if (!m_timer) + return; + + ecore_timer_del(m_timer); + m_timer = 0; +} + +bool HeapTimer::timerEvent(void* info) { HeapTimer* agent = static_cast(info); + + APIEntryShim shim(agent->m_globalData); agent->doWork(); + agent->m_timer = 0; return ECORE_CALLBACK_CANCEL; } diff --git a/Source/JavaScriptCore/heap/HeapTimer.h b/Source/JavaScriptCore/heap/HeapTimer.h index 14b9a37..56f8cdf 100644 --- a/Source/JavaScriptCore/heap/HeapTimer.h +++ b/Source/JavaScriptCore/heap/HeapTimer.h @@ -33,10 +33,8 @@ #include #elif PLATFORM(BLACKBERRY) #include -#elif PLATFORM(EFL) && ENABLE(TIZEN_GC_ACTIVITY_CALLBACK) -#include -#include -#include +#elif PLATFORM(EFL) +typedef struct _Ecore_Timer Ecore_Timer; #endif namespace JSC { @@ -75,11 +73,11 @@ protected: BlackBerry::Platform::Timer m_timer; -#elif PLATFORM(EFL) && ENABLE(TIZEN_GC_ACTIVITY_CALLBACK) - void stop() { m_timer = nullptr; } - static bool timerDidFire(void*); - - OwnPtr m_timer; +#elif PLATFORM(EFL) + static bool timerEvent(void*); + Ecore_Timer* add(double delay, void* agent); + void stop(); + Ecore_Timer* m_timer; #endif private: diff --git a/Source/JavaScriptCore/heap/IncrementalSweeper.cpp b/Source/JavaScriptCore/heap/IncrementalSweeper.cpp index f284d8b..f1c365b 100644 --- a/Source/JavaScriptCore/heap/IncrementalSweeper.cpp +++ b/Source/JavaScriptCore/heap/IncrementalSweeper.cpp @@ -35,6 +35,10 @@ #include #include +#if PLATFORM(EFL) +#include +#endif + namespace JSC { #if USE(CF) @@ -124,6 +128,91 @@ void IncrementalSweeper::willFinishSweeping() cancelTimer(); } +#elif PLATFORM(EFL) + +static const double sweepTimeSlice = .01; // seconds +static const double sweepTimeTotal = .10; +static const double sweepTimeMultiplier = 1.0 / sweepTimeTotal; + +IncrementalSweeper::IncrementalSweeper(JSGlobalData* globalData) + : HeapTimer(globalData) + , m_enabled(WTF::isMainThread()) + , m_structuresCanBeSwept(false) +{ +} + +void IncrementalSweeper::doWork() +{ + double startTime = WTF::monotonicallyIncreasingTime(); + while (m_currentBlockToSweepIndex < m_blocksToSweep.size()) { + sweepNextBlock(); + + double elapsedTime = WTF::monotonicallyIncreasingTime() - startTime; + if (elapsedTime < sweepTimeSlice) + continue; + + scheduleTimer(); + return; + } + m_blocksToSweep.clear(); + cancelTimer(); +} + +void IncrementalSweeper::scheduleTimer() +{ + cancelTimer(); + m_timer = add(sweepTimeSlice * sweepTimeMultiplier, this); +} + +void IncrementalSweeper::cancelTimer() +{ + stop(); +} + +IncrementalSweeper* IncrementalSweeper::create(Heap* heap) +{ + return new IncrementalSweeper(heap->globalData()); +} + +void IncrementalSweeper::sweepNextBlock() +{ + while (m_currentBlockToSweepIndex < m_blocksToSweep.size()) { + MarkedBlock* block = m_blocksToSweep[m_currentBlockToSweepIndex++]; + if (block->onlyContainsStructures()) + m_structuresCanBeSwept = true; + else + ASSERT(!m_structuresCanBeSwept); + + if (!block->needsSweeping()) + continue; + + block->sweep(); + m_globalData->heap.objectSpace().freeOrShrinkBlock(block); + return; + } +} + +void IncrementalSweeper::startSweeping(const HashSet& blockSnapshot) +{ + if (!isEnabled()) + return; + + m_blocksToSweep.resize(blockSnapshot.size()); + CopyFunctor functor(m_blocksToSweep); + m_globalData->heap.objectSpace().forEachBlock(functor); + m_currentBlockToSweepIndex = 0; + m_structuresCanBeSwept = false; + scheduleTimer(); +} + +void IncrementalSweeper::willFinishSweeping() +{ + m_currentBlockToSweepIndex = 0; + m_structuresCanBeSwept = true; + m_blocksToSweep.clear(); + if (m_globalData) + cancelTimer(); +} #else IncrementalSweeper::IncrementalSweeper(JSGlobalData* globalData) diff --git a/Source/JavaScriptCore/heap/IncrementalSweeper.h b/Source/JavaScriptCore/heap/IncrementalSweeper.h index c8005b0..78684d5 100644 --- a/Source/JavaScriptCore/heap/IncrementalSweeper.h +++ b/Source/JavaScriptCore/heap/IncrementalSweeper.h @@ -62,18 +62,27 @@ public: private: #if USE(CF) IncrementalSweeper(Heap*, CFRunLoopRef); - + void doSweep(double startTime); +#elif PLATFORM(EFL) + IncrementalSweeper(JSGlobalData*); + + bool isEnabled() const { return m_enabled; } + bool m_enabled; +#else + + IncrementalSweeper(JSGlobalData*); + +#endif + +#if USE(CF) || PLATFORM(EFL) void scheduleTimer(); void cancelTimer(); - + unsigned m_currentBlockToSweepIndex; Vector m_blocksToSweep; -#else - - IncrementalSweeper(JSGlobalData*); - #endif + bool m_structuresCanBeSwept; }; diff --git a/Source/JavaScriptCore/runtime/GCActivityCallback.h b/Source/JavaScriptCore/runtime/GCActivityCallback.h index 67ee174..584681e 100644 --- a/Source/JavaScriptCore/runtime/GCActivityCallback.h +++ b/Source/JavaScriptCore/runtime/GCActivityCallback.h @@ -56,6 +56,12 @@ protected: , m_enabled(true) { } +#elif PLATFORM(EFL) + GCActivityCallback(JSGlobalData* globalData, bool flag) + : HeapTimer(globalData) + , m_enabled(flag) + { + } # else GCActivityCallback(JSGlobalData* globalData) : HeapTimer(globalData) @@ -83,12 +89,13 @@ public: protected: DefaultGCActivityCallback(Heap*, CFRunLoopRef); - void cancelTimer(); - void scheduleTimer(double); - private: double m_delay; #endif +#if USE(CF) || PLATFORM(EFL) + void cancelTimer(); + void scheduleTimer(double); +#endif }; inline DefaultGCActivityCallback* DefaultGCActivityCallback::create(Heap* heap) diff --git a/Source/JavaScriptCore/runtime/GCActivityCallbackEfl.cpp b/Source/JavaScriptCore/runtime/GCActivityCallbackEfl.cpp index 92c03e0..4e6f17d 100644 --- a/Source/JavaScriptCore/runtime/GCActivityCallbackEfl.cpp +++ b/Source/JavaScriptCore/runtime/GCActivityCallbackEfl.cpp @@ -19,43 +19,57 @@ #include "config.h" #include "GCActivityCallback.h" +#include "APIShims.h" #include "Heap.h" #include "JSGlobalData.h" +#include + namespace JSC { -const double timerInterval = 0.3; +const double timeInterval = 0.3; +const size_t threshold = 1 * MB; DefaultGCActivityCallback::DefaultGCActivityCallback(Heap* heap) - : GCActivityCallback(heap->globalData()) + : GCActivityCallback(heap->globalData(), WTF::isMainThread()) { } void DefaultGCActivityCallback::doWork() { - JSLockHolder lock(m_globalData); + APIEntryShim shim(m_globalData); m_globalData->heap.collect(Heap::DoNotSweep); } -void DefaultGCActivityCallback::didAllocate(size_t bytes) +void DefaultGCActivityCallback::scheduleTimer(double newDelay) { - if (bytes < 1 * MB) - return; + stop(); + ASSERT(!m_timer); + m_timer = add(newDelay, this); +} - if (m_timer || m_globalData->usingAPI()) +void DefaultGCActivityCallback::cancelTimer() +{ + stop(); +} + +void DefaultGCActivityCallback::didAllocate(size_t bytes) +{ + if (!isEnabled() || (bytes < threshold) || m_timer) return; - m_timer = adoptPtr(ecore_timer_add(timerInterval, reinterpret_cast(HeapTimer::timerDidFire), this)); + ASSERT(WTF::isMainThread()); + scheduleTimer(timeInterval); } void DefaultGCActivityCallback::willCollect() { - stop(); + cancelTimer(); } void DefaultGCActivityCallback::cancel() { - stop(); + cancelTimer(); } } // namespace JSC diff --git a/Source/cmakeconfig.h.cmake b/Source/cmakeconfig.h.cmake index b5955e9..e90d2d1 100644 --- a/Source/cmakeconfig.h.cmake +++ b/Source/cmakeconfig.h.cmake @@ -126,7 +126,6 @@ #cmakedefine01 ENABLE_TIZEN_SUPPORT_WEBAPP_META_TAG #cmakedefine01 ENABLE_TIZEN_SQL_DATABASE_ENCRYPTION #cmakedefine01 ENABLE_TIZEN_WEBKIT2_ROTATION_WHILE_JAVASCRIPT_POPUP -#cmakedefine01 ENABLE_TIZEN_GC_ACTIVITY_CALLBACK #cmakedefine01 ENABLE_TIZEN_GESTURE #cmakedefine01 ENABLE_TIZEN_WEBKIT2_TEXT_SELECTION -- 2.7.4