Replace use of WTF::FixedArray with std::array
[WebKit-https.git] / Source / JavaScriptCore / runtime / CodeCache.h
index 9aaeba3..f3ff747 100644 (file)
@@ -31,7 +31,7 @@
 #include "SourceCode.h"
 #include "Strong.h"
 #include "WeakRandom.h"
-#include <wtf/FixedArray.h>
+#include <wtf/CurrentTime.h>
 #include <wtf/Forward.h>
 #include <wtf/PassOwnPtr.h>
 #include <wtf/RandomNumber.h>
@@ -42,13 +42,14 @@ namespace JSC {
 class EvalExecutable;
 class FunctionBodyNode;
 class Identifier;
+class JSScope;
 class ProgramExecutable;
 class UnlinkedCodeBlock;
 class UnlinkedEvalCodeBlock;
 class UnlinkedFunctionCodeBlock;
 class UnlinkedFunctionExecutable;
 class UnlinkedProgramCodeBlock;
-class JSGlobalData;
+class VM;
 struct ParserError;
 class SourceCode;
 class SourceProvider;
@@ -118,8 +119,8 @@ struct SourceCodeValue {
     {
     }
 
-    SourceCodeValue(JSGlobalData& globalData, JSCell* cell, int64_t age)
-        : cell(globalData, cell)
+    SourceCodeValue(VM& vm, JSCell* cell, int64_t age)
+        : cell(vm, cell)
         , age(age)
     {
     }
@@ -134,16 +135,16 @@ public:
     typedef MapType::iterator iterator;
     typedef MapType::AddResult AddResult;
 
-    enum { MinCacheCapacity = 1000000 }; // Size in characters
-
     CodeCacheMap()
         : m_size(0)
-        , m_capacity(MinCacheCapacity)
+        , m_sizeAtLastPrune(0)
+        , m_timeAtLastPrune(monotonicallyIncreasingTime())
+        , m_minCapacity(0)
+        , m_capacity(0)
         , m_age(0)
     {
     }
 
-
     AddResult add(const SourceCodeKey& key, const SourceCodeValue& value)
     {
         prune();
@@ -166,8 +167,8 @@ public:
             // infer that requested objects are subject to low eviction probability,
             // so we shrink the cache to save memory.
             m_capacity -= recencyBias * key.length();
-            if (m_capacity < MinCacheCapacity)
-                m_capacity = MinCacheCapacity;
+            if (m_capacity < m_minCapacity)
+                m_capacity = m_minCapacity;
         }
 
         addResult.iterator->value.age = m_age;
@@ -191,6 +192,12 @@ public:
     int64_t age() { return m_age; }
 
 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 workingSetMaxBytes = 16000000;
+    static const size_t workingSetMaxEntries = 2000;
+
     // This constant factor biases cache capacity toward recent activity. We
     // want to adapt to changing workloads.
     static const int64_t recencyBias = 4;
@@ -200,16 +207,28 @@ 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 < workingSetMaxBytes
+            && canPruneQuickly())
+                return;
+
         pruneSlowCase();
     }
 
     MapType m_map;
     int64_t m_size;
+    int64_t m_sizeAtLastPrune;
+    double m_timeAtLastPrune;
+    int64_t m_minCapacity;
     int64_t m_capacity;
     int64_t m_age;
 };
@@ -219,9 +238,9 @@ class CodeCache {
 public:
     static PassOwnPtr<CodeCache> create() { return adoptPtr(new CodeCache); }
 
-    UnlinkedProgramCodeBlock* getProgramCodeBlock(JSGlobalData&, ProgramExecutable*, const SourceCode&, JSParserStrictness, DebuggerMode, ProfilerMode, ParserError&);
-    UnlinkedEvalCodeBlock* getEvalCodeBlock(JSGlobalData&, EvalExecutable*, const SourceCode&, JSParserStrictness, DebuggerMode, ProfilerMode, ParserError&);
-    UnlinkedFunctionExecutable* getFunctionExecutableFromGlobalCode(JSGlobalData&, const Identifier&, const SourceCode&, ParserError&);
+    UnlinkedProgramCodeBlock* getProgramCodeBlock(VM&, ProgramExecutable*, const SourceCode&, JSParserStrictness, DebuggerMode, ProfilerMode, ParserError&);
+    UnlinkedEvalCodeBlock* getEvalCodeBlock(VM&, EvalExecutable*, const SourceCode&, JSParserStrictness, DebuggerMode, ProfilerMode, ParserError&);
+    UnlinkedFunctionExecutable* getFunctionExecutableFromGlobalCode(VM&, const Identifier&, const SourceCode&, ParserError&);
     ~CodeCache();
 
     void clear()
@@ -233,7 +252,7 @@ private:
     CodeCache();
 
     template <class UnlinkedCodeBlockType, class ExecutableType> 
-    UnlinkedCodeBlockType* getCodeBlock(JSGlobalData&, ExecutableType*, const SourceCode&, JSParserStrictness, DebuggerMode, ProfilerMode, ParserError&);
+    UnlinkedCodeBlockType* getGlobalCodeBlock(VM&, ExecutableType*, const SourceCode&, JSParserStrictness, DebuggerMode, ProfilerMode, ParserError&);
 
     CodeCacheMap m_sourceCode;
 };