2012-11-09 Oliver Hunt <oliver@apple.com>
[WebKit-https.git] / Source / JavaScriptCore / runtime / CodeCache.h
1 /*
2  * Copyright (C) 2012 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 "Strong.h"
32 #include "WeakRandom.h"
33
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 Identifier;
44 class ProgramExecutable;
45 class UnlinkedCodeBlock;
46 class UnlinkedEvalCodeBlock;
47 class UnlinkedFunctionCodeBlock;
48 class UnlinkedFunctionExecutable;
49 class UnlinkedProgramCodeBlock;
50 class JSGlobalData;
51 struct ParserError;
52 class SourceCode;
53 class SourceProvider;
54
55 template <typename KeyType, typename EntryType, int CacheSize> class CacheMap {
56     typedef typename HashMap<KeyType, unsigned>::iterator iterator;
57 public:
58     CacheMap()
59         : m_randomGenerator((static_cast<uint32_t>(randomNumber() * UINT32_MAX)))
60     {
61     }
62     const EntryType* find(const KeyType& key)
63     {
64         iterator result = m_map.find(key);
65         if (result == m_map.end())
66             return 0;
67         return &m_data[result->value].second;
68     }
69     void add(const KeyType& key, const EntryType& value)
70     {
71         iterator result = m_map.find(key);
72         if (result != m_map.end()) {
73             m_data[result->value].second = value;
74             return;
75         }
76         size_t newIndex = m_randomGenerator.getUint32() % CacheSize;
77         if (m_data[newIndex].second)
78             m_map.remove(m_data[newIndex].first);
79         m_map.add(key, newIndex);
80         m_data[newIndex].first = key;
81         m_data[newIndex].second = value;
82         ASSERT(m_map.size() <= CacheSize);
83     }
84 private:
85     HashMap<KeyType, unsigned> m_map;
86     FixedArray<std::pair<KeyType, EntryType>, CacheSize> m_data;
87     WeakRandom m_randomGenerator;
88 };
89
90 class CodeCache {
91 public:
92     static PassOwnPtr<CodeCache> create() { return adoptPtr(new CodeCache); }
93
94     UnlinkedProgramCodeBlock* getProgramCodeBlock(JSGlobalData&, ProgramExecutable*, const SourceCode&, JSParserStrictness, DebuggerMode, ProfilerMode, ParserError&);
95     UnlinkedEvalCodeBlock* getEvalCodeBlock(JSGlobalData&, EvalExecutable*, const SourceCode&, JSParserStrictness, DebuggerMode, ProfilerMode, ParserError&);
96     UnlinkedFunctionCodeBlock* getFunctionCodeBlock(JSGlobalData&, UnlinkedFunctionExecutable*, const SourceCode&, CodeSpecializationKind, DebuggerMode, ProfilerMode, ParserError&);
97     UnlinkedFunctionExecutable* getFunctionExecutableFromGlobalCode(JSGlobalData&, const Identifier&, const SourceCode&, ParserError&);
98     void usedFunctionCode(JSGlobalData&, UnlinkedFunctionCodeBlock*);
99     ~CodeCache();
100
101     enum CodeType { EvalType, ProgramType, FunctionType };
102     typedef std::pair<String, unsigned> CodeBlockKey;
103     typedef std::pair<String, String> GlobalFunctionKey;
104
105 private:
106     CodeCache();
107
108     UnlinkedFunctionCodeBlock* generateFunctionCodeBlock(JSGlobalData&, UnlinkedFunctionExecutable*, const SourceCode&, CodeSpecializationKind, DebuggerMode, ProfilerMode, ParserError&);
109
110     template <class UnlinkedCodeBlockType, class ExecutableType> inline UnlinkedCodeBlockType* getCodeBlock(JSGlobalData&, ExecutableType*, const SourceCode&, JSParserStrictness, DebuggerMode, ProfilerMode, ParserError&);
111     CodeBlockKey makeCodeBlockKey(const SourceCode&, CodeType, JSParserStrictness);
112     GlobalFunctionKey makeGlobalFunctionKey(const SourceCode&, const String&);
113
114     enum {
115         kMaxCodeBlockEntries = 1024,
116         kMaxGlobalFunctionEntries = 1024,
117         kMaxFunctionCodeBlocks = 1024
118     };
119
120     CacheMap<CodeBlockKey, Strong<UnlinkedCodeBlock>, kMaxCodeBlockEntries> m_cachedCodeBlocks;
121     CacheMap<GlobalFunctionKey, Strong<UnlinkedFunctionExecutable>, kMaxGlobalFunctionEntries> m_cachedGlobalFunctions;
122     CacheMap<UnlinkedFunctionCodeBlock*, Strong<UnlinkedFunctionCodeBlock>, kMaxFunctionCodeBlocks> m_cachedFunctionCode;
123 };
124
125 }
126
127 #endif