Commit 0d46b892 authored by mhahnenberg@apple.com's avatar mhahnenberg@apple.com

Safari hangs during test262 run in CodeCache::pruneSlowCase

https://bugs.webkit.org/show_bug.cgi?id=113469

Reviewed by Geoffrey Garen.

We can end up hanging for quite some time if we add a lot of small keys to the CodeCache.
By the time we get around to pruning the cache, we have a potentially tens or hundreds of 
thousands of small entries, which can cause a noticeable hang when pruning them.

To fix this issue we added a hard cap to the number of entries in the cache because we 
could potentially have to remove every element in the map.

* runtime/CodeCache.cpp:
(JSC::CodeCacheMap::pruneSlowCase): We need to prune until we're both under the hard cap and the
capacity in bytes.
* runtime/CodeCache.h:
(CodeCacheMap):
(JSC::CodeCacheMap::numberOfEntries): Convenience accessor function to the number of entries in 
the map that does the cast to size_t of m_map.size() for us. 
(JSC::CodeCacheMap::canPruneQuickly): Checks that the total number is under the hard cap. We put this 
check inside a function to more accurately describe why we're doing the check and to abstract out 
the actual calculation in case we want to coalesce calls to pruneSlowCase in the future.
(JSC::CodeCacheMap::prune): Check the number of entries against our hard cap. If it's greater than
the cap then we need to drop down to pruneSlowCase.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@147150 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 8961ae91
2013-03-28 Mark Hahnenberg <mhahnenberg@apple.com>
Safari hangs during test262 run in CodeCache::pruneSlowCase
https://bugs.webkit.org/show_bug.cgi?id=113469
Reviewed by Geoffrey Garen.
We can end up hanging for quite some time if we add a lot of small keys to the CodeCache.
By the time we get around to pruning the cache, we have a potentially tens or hundreds of
thousands of small entries, which can cause a noticeable hang when pruning them.
To fix this issue we added a hard cap to the number of entries in the cache because we
could potentially have to remove every element in the map.
* runtime/CodeCache.cpp:
(JSC::CodeCacheMap::pruneSlowCase): We need to prune until we're both under the hard cap and the
capacity in bytes.
* runtime/CodeCache.h:
(CodeCacheMap):
(JSC::CodeCacheMap::numberOfEntries): Convenience accessor function to the number of entries in
the map that does the cast to size_t of m_map.size() for us.
(JSC::CodeCacheMap::canPruneQuickly): Checks that the total number is under the hard cap. We put this
check inside a function to more accurately describe why we're doing the check and to abstract out
the actual calculation in case we want to coalesce calls to pruneSlowCase in the future.
(JSC::CodeCacheMap::prune): Check the number of entries against our hard cap. If it's greater than
the cap then we need to drop down to pruneSlowCase.
2013-03-28 Zan Dobersek <zdobersek@igalia.com>
Unreviewed build fix for the EFL and GTK ports.
......
......@@ -47,7 +47,7 @@ void CodeCacheMap::pruneSlowCase()
if (m_capacity < m_minCapacity)
m_capacity = m_minCapacity;
while (m_size > m_capacity) {
while (m_size > m_capacity || !canPruneQuickly()) {
MapType::iterator it = m_map.begin();
m_size -= it->key.length();
m_map.remove(it);
......
......@@ -196,7 +196,8 @@ private:
// This constant factor biases cache capacity toward allowing a minimum
// working set to enter the cache before it starts evicting.
static const double workingSetTime;
static const int64_t workingSetMax = 16000000;
static const int64_t workingSetMaxBytes = 16000000;
static const size_t workingSetMaxEntries = 2000;
// This constant factor biases cache capacity toward recent activity. We
// want to adapt to changing workloads.
......@@ -207,14 +208,18 @@ private:
// sample them, so we need to extrapolate from the ones we do sample.
static const int64_t oldObjectSamplingMultiplier = 32;
size_t numberOfEntries() const { return static_cast<size_t>(m_map.size()); }
bool canPruneQuickly() const { return numberOfEntries() < workingSetMaxEntries; }
void pruneSlowCase();
void prune()
{
if (m_size <= m_capacity)
if (m_size <= m_capacity && canPruneQuickly())
return;
if (monotonicallyIncreasingTime() - m_timeAtLastPrune < workingSetTime
&& m_size - m_sizeAtLastPrune < workingSetMax)
&& m_size - m_sizeAtLastPrune < workingSetMaxBytes
&& canPruneQuickly())
return;
pruneSlowCase();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment