Unreviewed, rolling out r143348.
[WebKit-https.git] / Source / JavaScriptCore / runtime / CodeCache.h
1 /*
2  * Copyright (C) 2012, 2013 Apple Inc. All Rights Reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #ifndef CodeCache_h
27 #define CodeCache_h
28
29 #include "CodeSpecializationKind.h"
30 #include "ParserModes.h"
31 #include "SourceCode.h"
32 #include "Strong.h"
33 #include "WeakRandom.h"
34 #include <wtf/FixedArray.h>
35 #include <wtf/Forward.h>
36 #include <wtf/PassOwnPtr.h>
37 #include <wtf/RandomNumber.h>
38 #include <wtf/text/WTFString.h>
39
40 namespace JSC {
41
42 class EvalExecutable;
43 class FunctionBodyNode;
44 class Identifier;
45 class ProgramExecutable;
46 class UnlinkedCodeBlock;
47 class UnlinkedEvalCodeBlock;
48 class UnlinkedFunctionCodeBlock;
49 class UnlinkedFunctionExecutable;
50 class UnlinkedProgramCodeBlock;
51 class JSGlobalData;
52 struct ParserError;
53 class SourceCode;
54 class SourceProvider;
55
56 class SourceCodeKey {
57 public:
58     enum CodeType { EvalType, ProgramType, FunctionCallType, FunctionConstructType };
59
60     SourceCodeKey()
61         : m_flags(0)
62     {
63     }
64
65     SourceCodeKey(const SourceCode& sourceCode, const String& name, CodeType codeType, JSParserStrictness jsParserStrictness)
66         : m_sourceString(sourceCode.toString())
67         , m_name(name)
68         , m_flags((codeType << 1) | jsParserStrictness)
69     {
70     }
71
72     SourceCodeKey(WTF::HashTableDeletedValueType)
73         : m_sourceString(WTF::HashTableDeletedValue)
74     {
75     }
76
77     bool isHashTableDeletedValue() const { return m_sourceString.isHashTableDeletedValue(); }
78
79     unsigned hash() const { return m_sourceString.impl()->hash(); }
80
81     size_t length() const { return m_sourceString.length(); }
82
83     bool isNull() const { return m_sourceString.isNull(); }
84
85     bool operator==(const SourceCodeKey& other) const
86     {
87         return m_flags == other.m_flags
88             && m_name == other.m_name
89             && m_sourceString == other.m_sourceString;
90     }
91
92 private:
93     String m_sourceString;
94     String m_name;
95     unsigned m_flags;
96 };
97
98 struct SourceCodeKeyHash {
99     static unsigned hash(const SourceCodeKey& key) { return key.hash(); }
100     static bool equal(const SourceCodeKey& a, const SourceCodeKey& b) { return a == b; }
101     static const bool safeToCompareToEmptyOrDeleted = false;
102 };
103
104 struct SourceCodeKeyHashTraits : SimpleClassHashTraits<SourceCodeKey> {
105     static const bool hasIsEmptyValueFunction = true;
106     static bool isEmptyValue(const SourceCodeKey& sourceCodeKey) { return sourceCodeKey.isNull(); }
107 };
108
109 class CodeCacheMap {
110     typedef HashMap<SourceCodeKey, Strong<JSCell>, SourceCodeKeyHash, SourceCodeKeyHashTraits> MapType;
111     typedef MapType::iterator iterator;
112
113 public:
114     CodeCacheMap(size_t capacity)
115         : m_size(0)
116         , m_capacity(capacity)
117     {
118     }
119
120     const Strong<JSCell>* find(const SourceCodeKey& key)
121     {
122         iterator result = m_map.find(key);
123         if (result == m_map.end())
124             return 0;
125         return &result->value;
126     }
127
128     void set(const SourceCodeKey& key, const Strong<JSCell>& value)
129     {
130         while (m_size >= m_capacity) {
131             MapType::iterator it = m_map.begin();
132             m_size -= it->key.length();
133             m_map.remove(it);
134         }
135
136         m_size += key.length();
137         m_map.set(key, value);
138     }
139
140     void clear()
141     {
142         m_size = 0;
143         m_map.clear();
144     }
145
146 private:
147     MapType m_map;
148     size_t m_size;
149     size_t m_capacity;
150 };
151
152 // Caches top-level code such as <script>, eval(), new Function, and JSEvaluateScript().
153 class CodeCache {
154 public:
155     static PassOwnPtr<CodeCache> create() { return adoptPtr(new CodeCache); }
156
157     UnlinkedProgramCodeBlock* getProgramCodeBlock(JSGlobalData&, ProgramExecutable*, const SourceCode&, JSParserStrictness, DebuggerMode, ProfilerMode, ParserError&);
158     UnlinkedEvalCodeBlock* getEvalCodeBlock(JSGlobalData&, EvalExecutable*, const SourceCode&, JSParserStrictness, DebuggerMode, ProfilerMode, ParserError&);
159     UnlinkedFunctionExecutable* getFunctionExecutableFromGlobalCode(JSGlobalData&, const Identifier&, const SourceCode&, ParserError&);
160     ~CodeCache();
161
162     void clear()
163     {
164         m_sourceCode.clear();
165     }
166
167 private:
168     CodeCache();
169
170     template <class UnlinkedCodeBlockType, class ExecutableType> 
171     UnlinkedCodeBlockType* getCodeBlock(JSGlobalData&, ExecutableType*, const SourceCode&, JSParserStrictness, DebuggerMode, ProfilerMode, ParserError&);
172
173     enum { CacheSize = 16000000 }; // Size in characters
174
175     CodeCacheMap m_sourceCode;
176 };
177
178 }
179
180 #endif // CodeCache_h