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}
)
#include "ScopeChain.h"
#include <wtf/Threading.h>
+#if PLATFORM(EFL)
+#include <Ecore.h>
+#endif
+
namespace JSC {
#if USE(CF)
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();
}
{
}
-bool HeapTimer::timerDidFire(void* info)
+Ecore_Timer* HeapTimer::add(double delay, void* agent)
+{
+ 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;
+}
+
+bool HeapTimer::timerEvent(void* info)
{
HeapTimer* agent = static_cast<HeapTimer*>(info);
+
+ APIEntryShim shim(agent->m_globalData);
agent->doWork();
+ agent->m_timer = 0;
return ECORE_CALLBACK_CANCEL;
}
#include <CoreFoundation/CoreFoundation.h>
#elif PLATFORM(BLACKBERRY)
#include <BlackBerryPlatformTimer.h>
-#elif PLATFORM(EFL) && ENABLE(TIZEN_GC_ACTIVITY_CALLBACK)
-#include <Ecore.h>
-#include <wtf/OwnPtr.h>
-#include <wtf/PassOwnPtr.h>
+#elif PLATFORM(EFL)
+typedef struct _Ecore_Timer Ecore_Timer;
#endif
namespace JSC {
BlackBerry::Platform::Timer<HeapTimer> m_timer;
-#elif PLATFORM(EFL) && ENABLE(TIZEN_GC_ACTIVITY_CALLBACK)
- void stop() { m_timer = nullptr; }
- static bool timerDidFire(void*);
-
- OwnPtr<Ecore_Timer> m_timer;
+#elif PLATFORM(EFL)
+ static bool timerEvent(void*);
+ Ecore_Timer* add(double delay, void* agent);
+ void stop();
+ Ecore_Timer* m_timer;
#endif
private:
#include <wtf/HashSet.h>
#include <wtf/WTFThreadData.h>
+#if PLATFORM(EFL)
+#include <wtf/MainThread.h>
+#endif
+
namespace JSC {
#if USE(CF)
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<MarkedBlock*>& 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)
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<MarkedBlock*> m_blocksToSweep;
-#else
-
- IncrementalSweeper(JSGlobalData*);
-
#endif
+
bool m_structuresCanBeSwept;
};
, m_enabled(true)
{
}
+#elif PLATFORM(EFL)
+ GCActivityCallback(JSGlobalData* globalData, bool flag)
+ : HeapTimer(globalData)
+ , m_enabled(flag)
+ {
+ }
# else
GCActivityCallback(JSGlobalData* globalData)
: HeapTimer(globalData)
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)
#include "config.h"
#include "GCActivityCallback.h"
+#include "APIShims.h"
#include "Heap.h"
#include "JSGlobalData.h"
+#include <wtf/MainThread.h>
+
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<Ecore_Task_Cb>(HeapTimer::timerDidFire), this));
+ ASSERT(WTF::isMainThread());
+ scheduleTimer(timeInterval);
}
void DefaultGCActivityCallback::willCollect()
{
- stop();
+ cancelTimer();
}
void DefaultGCActivityCallback::cancel()
{
- stop();
+ cancelTimer();
}
} // namespace JSC
#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