Changeset 143759 in webkit


Ignore:
Timestamp:
Feb 22, 2013 11:16:03 AM (11 years ago)
Author:
ggaren@apple.com
Message:

Code cache size should adapt to workload
https://bugs.webkit.org/show_bug.cgi?id=110560

Reviewed by Antti Koivisto.

(*) 5% PLT arithmetic mean speedup
(*) 10% PLT geometric mean speedup
(*) 3.4X microbenchmark speedup
(*) Reduces initial cache capacity by 16X

  • runtime/CodeCache.cpp:

(JSC::CodeCache::CodeCache): Updated for interface change.

  • runtime/CodeCache.h:

(JSC::SourceCodeValue::SourceCodeValue):
(SourceCodeValue): Turned the cache value into a struct so it can track its age.

(CodeCacheMap):
(JSC::CodeCacheMap::CodeCacheMap):
(JSC::CodeCacheMap::find):
(JSC::CodeCacheMap::set):
(JSC::CodeCacheMap::clear):
(JSC::CodeCacheMap::pruneIfNeeded):
(CodeCache): Grow and shrink in response to usage.

Location:
trunk/Source/JavaScriptCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r143679 r143759  
     12013-02-21  Geoffrey Garen  <ggaren@apple.com>
     2
     3        Code cache size should adapt to workload
     4        https://bugs.webkit.org/show_bug.cgi?id=110560
     5
     6        Reviewed by Antti Koivisto.
     7
     8        (*) 5% PLT arithmetic mean speedup
     9        (*) 10% PLT geometric mean speedup
     10        (*) 3.4X microbenchmark speedup
     11        (*) Reduces initial cache capacity by 16X
     12
     13        * runtime/CodeCache.cpp:
     14        (JSC::CodeCache::CodeCache): Updated for interface change.
     15
     16        * runtime/CodeCache.h:
     17        (JSC::SourceCodeValue::SourceCodeValue):
     18        (SourceCodeValue): Turned the cache value into a struct so it can track its age.
     19
     20        (CodeCacheMap):
     21        (JSC::CodeCacheMap::CodeCacheMap):
     22        (JSC::CodeCacheMap::find):
     23        (JSC::CodeCacheMap::set):
     24        (JSC::CodeCacheMap::clear):
     25        (JSC::CodeCacheMap::pruneIfNeeded):
     26        (CodeCache): Grow and shrink in response to usage.
     27
    1282013-02-21  Jessie Berlin  <jberlin@apple.com>
    229
  • trunk/Source/JavaScriptCore/runtime/CodeCache.cpp

    r143384 r143759  
    3838
    3939CodeCache::CodeCache()
    40     : m_sourceCode(CacheSize)
    4140{
    4241}
  • trunk/Source/JavaScriptCore/runtime/CodeCache.h

    r143384 r143759  
    114114};
    115115
     116struct SourceCodeValue {
     117    SourceCodeValue()
     118    {
     119    }
     120
     121    SourceCodeValue(const Strong<JSCell>& cell, int64_t age)
     122        : cell(cell)
     123        , age(age)
     124    {
     125    }
     126
     127    Strong<JSCell> cell;
     128    int64_t age;
     129};
     130
    116131class CodeCacheMap {
    117     typedef HashMap<SourceCodeKey, Strong<JSCell>, SourceCodeKeyHash, SourceCodeKeyHashTraits> MapType;
     132    typedef HashMap<SourceCodeKey, SourceCodeValue, SourceCodeKeyHash, SourceCodeKeyHashTraits> MapType;
    118133    typedef MapType::iterator iterator;
    119134
    120135public:
    121     CodeCacheMap(size_t capacity)
     136    enum { MinCacheCapacity = 1000000 }; // Size in characters
     137
     138    CodeCacheMap()
    122139        : m_size(0)
    123         , m_capacity(capacity)
     140        , m_capacity(MinCacheCapacity)
     141        , m_age(0)
    124142    {
    125143    }
     
    127145    const Strong<JSCell>* find(const SourceCodeKey& key)
    128146    {
    129         iterator result = m_map.find(key);
    130         if (result == m_map.end())
     147        iterator it = m_map.find(key);
     148        if (it == m_map.end())
    131149            return 0;
    132         return &result->value;
     150
     151        size_t age = m_age - it->value.age;
     152        if (age > m_capacity) {
     153            // A requested object is older than the cache's capacity. We can
     154            // infer that requested objects are subject to high eviction probability,
     155            // so we grow the cache to improve our hit rate.
     156            m_capacity += recencyBias * oldObjectSamplingMultiplier * key.length();
     157        } else if (age < m_capacity / 2) {
     158            // A requested object is much younger than the cache's capacity. We can
     159            // infer that requested objects are subject to low eviction probability,
     160            // so we shrink the cache to save memory.
     161            m_capacity -= recencyBias * key.length();
     162            if (m_capacity < MinCacheCapacity)
     163                m_capacity = MinCacheCapacity;
     164        }
     165
     166        it->value.age = m_age;
     167        m_age += key.length();
     168        return &it->value.cell;
    133169    }
    134170
    135171    void set(const SourceCodeKey& key, const Strong<JSCell>& value)
     172    {
     173        pruneIfNeeded();
     174
     175        m_size += key.length();
     176        m_age += key.length();
     177        m_map.set(key, SourceCodeValue(value, m_age));
     178    }
     179
     180    void clear()
     181    {
     182        m_size = 0;
     183        m_age = 0;
     184        m_map.clear();
     185    }
     186
     187private:
     188    // This constant factor biases cache capacity toward recent activity. We
     189    // want to adapt to changing workloads.
     190    static const int64_t recencyBias = 4;
     191
     192    // This constant factor treats a sampled event for one old object as if it
     193    // happened for many old objects. Most old objects are evicted before we can
     194    // sample them, so we need to extrapolate from the ones we do sample.
     195    static const int64_t oldObjectSamplingMultiplier = 32;
     196
     197    void pruneIfNeeded()
    136198    {
    137199        while (m_size >= m_capacity) {
     
    140202            m_map.remove(it);
    141203        }
    142 
    143         m_size += key.length();
    144         m_map.set(key, value);
    145     }
    146 
    147     void clear()
    148     {
    149         m_size = 0;
    150         m_map.clear();
    151     }
    152 
    153 private:
     204    }
     205
    154206    MapType m_map;
    155207    size_t m_size;
    156208    size_t m_capacity;
     209    int64_t m_age;
    157210};
    158211
     
    178231    UnlinkedCodeBlockType* getCodeBlock(JSGlobalData&, ExecutableType*, const SourceCode&, JSParserStrictness, DebuggerMode, ProfilerMode, ParserError&);
    179232
    180     enum { CacheSize = 16000000 }; // Size in characters
    181 
    182233    CodeCacheMap m_sourceCode;
    183234};
Note: See TracChangeset for help on using the changeset viewer.