]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - runtime/CodeCache.h
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / runtime / CodeCache.h
index 986b266c2342363fbe1b4881516a2a6e6700c14e..8877fc06c84e83b61a3451b5b8f253da19d47990 100644 (file)
@@ -32,9 +32,7 @@
 #include "Strong.h"
 #include "WeakRandom.h"
 #include <wtf/CurrentTime.h>
-#include <wtf/FixedArray.h>
 #include <wtf/Forward.h>
-#include <wtf/PassOwnPtr.h>
 #include <wtf/RandomNumber.h>
 #include <wtf/text/WTFString.h>
 
@@ -44,6 +42,7 @@ class EvalExecutable;
 class FunctionBodyNode;
 class Identifier;
 class JSScope;
+class ParserError;
 class ProgramExecutable;
 class UnlinkedCodeBlock;
 class UnlinkedEvalCodeBlock;
@@ -51,7 +50,6 @@ class UnlinkedFunctionCodeBlock;
 class UnlinkedFunctionExecutable;
 class UnlinkedProgramCodeBlock;
 class VM;
-struct ParserError;
 class SourceCode;
 class SourceProvider;
 
@@ -63,10 +61,15 @@ public:
     {
     }
 
-    SourceCodeKey(const SourceCode& sourceCode, const String& name, CodeType codeType, JSParserStrictness jsParserStrictness)
+    SourceCodeKey(const SourceCode& sourceCode, const String& name, CodeType codeType, JSParserBuiltinMode builtinMode,
+        JSParserStrictMode strictMode, ThisTDZMode thisTDZMode = ThisTDZMode::CheckIfNeeded)
         : m_sourceCode(sourceCode)
         , m_name(name)
-        , m_flags((codeType << 1) | jsParserStrictness)
+        , m_flags(
+            (static_cast<unsigned>(codeType) << 3)
+            | (static_cast<unsigned>(builtinMode) << 2)
+            | (static_cast<unsigned>(strictMode) << 1)
+            | static_cast<unsigned>(thisTDZMode))
         , m_hash(string().impl()->hash())
     {
     }
@@ -136,30 +139,25 @@ public:
     typedef MapType::iterator iterator;
     typedef MapType::AddResult AddResult;
 
-    CodeCacheMap(int64_t workingSetMaxBytes, size_t workingSetMaxEntries)
+    CodeCacheMap()
         : m_size(0)
         , m_sizeAtLastPrune(0)
         , m_timeAtLastPrune(monotonicallyIncreasingTime())
         , m_minCapacity(0)
         , m_capacity(0)
         , m_age(0)
-        , m_workingSetMaxBytes(workingSetMaxBytes)
-        , m_workingSetMaxEntries(workingSetMaxEntries)
     {
     }
 
-    AddResult add(const SourceCodeKey& key, const SourceCodeValue& value)
+    SourceCodeValue* findCacheAndUpdateAge(const SourceCodeKey& key)
     {
         prune();
 
-        AddResult addResult = m_map.add(key, value);
-        if (addResult.isNewEntry) {
-            m_size += key.length();
-            m_age += key.length();
-            return addResult;
-        }
+        iterator findResult = m_map.find(key);
+        if (findResult == m_map.end())
+            return nullptr;
 
-        int64_t age = m_age - addResult.iterator->value.age;
+        int64_t age = m_age - findResult->value.age;
         if (age > m_capacity) {
             // A requested object is older than the cache's capacity. We can
             // infer that requested objects are subject to high eviction probability,
@@ -174,7 +172,20 @@ public:
                 m_capacity = m_minCapacity;
         }
 
-        addResult.iterator->value.age = m_age;
+        findResult->value.age = m_age;
+        m_age += key.length();
+
+        return &findResult->value;
+    }
+
+    AddResult addCache(const SourceCodeKey& key, const SourceCodeValue& value)
+    {
+        prune();
+
+        AddResult addResult = m_map.add(key, value);
+        ASSERT(addResult.isNewEntry);
+
+        m_size += key.length();
         m_age += key.length();
         return addResult;
     }
@@ -194,20 +205,12 @@ public:
 
     int64_t age() { return m_age; }
 
-    static const int64_t globalWorkingSetMaxBytes;
-    static const size_t globalWorkingSetMaxEntries;
-
-    // We have a smaller cap for the per-codeblock CodeCache that approximates the
-    // linked EvalCodeCache limits, but still allows us to keep large string based
-    // evals at least partially cached.
-    static const unsigned nonGlobalWorkingSetScale;
-    static const int64_t nonGlobalWorkingSetMaxBytes;
-    static const size_t nonGlobalWorkingSetMaxEntries;
-
 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.
@@ -219,7 +222,7 @@ private:
     static const int64_t oldObjectSamplingMultiplier = 32;
 
     size_t numberOfEntries() const { return static_cast<size_t>(m_map.size()); }
-    bool canPruneQuickly() const { return numberOfEntries() < m_workingSetMaxEntries; }
+    bool canPruneQuickly() const { return numberOfEntries() < workingSetMaxEntries; }
 
     void pruneSlowCase();
     void prune()
@@ -228,7 +231,7 @@ private:
             return;
 
         if (monotonicallyIncreasingTime() - m_timeAtLastPrune < workingSetTime
-            && m_size - m_sizeAtLastPrune < m_workingSetMaxBytes
+            && m_size - m_sizeAtLastPrune < workingSetMaxBytes
             && canPruneQuickly())
                 return;
 
@@ -242,20 +245,18 @@ private:
     int64_t m_minCapacity;
     int64_t m_capacity;
     int64_t m_age;
-    const int64_t m_workingSetMaxBytes;
-    const size_t m_workingSetMaxEntries;
 };
 
 // Caches top-level code such as <script>, eval(), new Function, and JSEvaluateScript().
-class CodeCache : public RefCounted<CodeCache> {
+class CodeCache {
+    WTF_MAKE_FAST_ALLOCATED;
 public:
-    enum CodeCacheKind { GlobalCodeCache, NonGlobalCodeCache };
-    static PassRefPtr<CodeCache> create(CodeCacheKind kind) { return adoptRef(new CodeCache(kind)); }
+    CodeCache();
+    ~CodeCache();
 
-    UnlinkedProgramCodeBlock* getProgramCodeBlock(VM&, ProgramExecutable*, const SourceCode&, JSParserStrictness, DebuggerMode, ProfilerMode, ParserError&);
-    UnlinkedEvalCodeBlock* getEvalCodeBlock(VM&, JSScope*, EvalExecutable*, const SourceCode&, JSParserStrictness, DebuggerMode, ProfilerMode, ParserError&);
+    UnlinkedProgramCodeBlock* getProgramCodeBlock(VM&, ProgramExecutable*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, DebuggerMode, ProfilerMode, ParserError&);
+    UnlinkedEvalCodeBlock* getEvalCodeBlock(VM&, EvalExecutable*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, ThisTDZMode, DebuggerMode, ProfilerMode, ParserError&);
     UnlinkedFunctionExecutable* getFunctionExecutableFromGlobalCode(VM&, const Identifier&, const SourceCode&, ParserError&);
-    ~CodeCache();
 
     void clear()
     {
@@ -263,13 +264,8 @@ public:
     }
 
 private:
-    CodeCache(CodeCacheKind);
-
     template <class UnlinkedCodeBlockType, class ExecutableType> 
-    UnlinkedCodeBlockType* getCodeBlock(VM&, JSScope*, ExecutableType*, const SourceCode&, JSParserStrictness, DebuggerMode, ProfilerMode, ParserError&);
-
-    template <class UnlinkedCodeBlockType, class ExecutableType>
-    UnlinkedCodeBlockType* generateBytecode(VM&, JSScope*, ExecutableType*, const SourceCode&, JSParserStrictness, DebuggerMode, ProfilerMode, ParserError&);
+    UnlinkedCodeBlockType* getGlobalCodeBlock(VM&, ExecutableType*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, ThisTDZMode, DebuggerMode, ProfilerMode, ParserError&);
 
     CodeCacheMap m_sourceCode;
 };