483e5b5bb130b47c9be6aebe2161f6ed9c131d62
[WebKit-https.git] / Source / JavaScriptCore / bytecode / LazyOperandValueProfile.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 LazyOperandValueProfile_h
27 #define LazyOperandValueProfile_h
28
29 #include <wtf/Platform.h>
30
31 #if ENABLE(VALUE_PROFILER)
32
33 #include "ConcurrentJITLock.h"
34 #include "ValueProfile.h"
35 #include "VirtualRegister.h"
36 #include <wtf/HashMap.h>
37 #include <wtf/Noncopyable.h>
38 #include <wtf/OwnPtr.h>
39 #include <wtf/SegmentedVector.h>
40
41 namespace JSC {
42
43 class ScriptExecutable;
44
45 class LazyOperandValueProfileKey {
46 public:
47     LazyOperandValueProfileKey()
48         : m_bytecodeOffset(0) // 0 = empty value
49         , m_operand(VirtualRegister()) // not a valid operand index in our current scheme
50     {
51     }
52     
53     LazyOperandValueProfileKey(WTF::HashTableDeletedValueType)
54         : m_bytecodeOffset(1) // 1 = deleted value
55         , m_operand(VirtualRegister()) // not a valid operand index in our current scheme
56     {
57     }
58     
59     LazyOperandValueProfileKey(unsigned bytecodeOffset, VirtualRegister operand)
60         : m_bytecodeOffset(bytecodeOffset)
61         , m_operand(operand)
62     {
63         ASSERT(m_operand.isValid());
64     }
65     
66     bool operator!() const
67     {
68         return !m_operand.isValid();
69     }
70     
71     bool operator==(const LazyOperandValueProfileKey& other) const
72     {
73         return m_bytecodeOffset == other.m_bytecodeOffset
74             && m_operand == other.m_operand;
75     }
76     
77     unsigned hash() const
78     {
79         return WTF::intHash(m_bytecodeOffset) + m_operand.offset();
80     }
81     
82     unsigned bytecodeOffset() const
83     {
84         ASSERT(!!*this);
85         return m_bytecodeOffset;
86     }
87
88     VirtualRegister operand() const
89     {
90         ASSERT(!!*this);
91         return m_operand;
92     }
93     
94     bool isHashTableDeletedValue() const
95     {
96         return !m_operand.isValid() && m_bytecodeOffset;
97     }
98 private: 
99     unsigned m_bytecodeOffset;
100     VirtualRegister m_operand;
101 };
102
103 struct LazyOperandValueProfileKeyHash {
104     static unsigned hash(const LazyOperandValueProfileKey& key) { return key.hash(); }
105     static bool equal(
106         const LazyOperandValueProfileKey& a,
107         const LazyOperandValueProfileKey& b) { return a == b; }
108     static const bool safeToCompareToEmptyOrDeleted = true;
109 };
110
111 } // namespace JSC
112
113 namespace WTF {
114
115 template<typename T> struct DefaultHash;
116 template<> struct DefaultHash<JSC::LazyOperandValueProfileKey> {
117     typedef JSC::LazyOperandValueProfileKeyHash Hash;
118 };
119
120 template<typename T> struct HashTraits;
121 template<> struct HashTraits<JSC::LazyOperandValueProfileKey> : public GenericHashTraits<JSC::LazyOperandValueProfileKey> {
122     static void constructDeletedValue(JSC::LazyOperandValueProfileKey& slot) { new (NotNull, &slot) JSC::LazyOperandValueProfileKey(HashTableDeletedValue); }
123     static bool isDeletedValue(const JSC::LazyOperandValueProfileKey& value) { return value.isHashTableDeletedValue(); }
124 };
125
126 } // namespace WTF
127
128 namespace JSC {
129
130 struct LazyOperandValueProfile : public MinimalValueProfile {
131     LazyOperandValueProfile()
132         : MinimalValueProfile()
133         , m_operand(VirtualRegister())
134     {
135     }
136     
137     explicit LazyOperandValueProfile(const LazyOperandValueProfileKey& key)
138         : MinimalValueProfile(key.bytecodeOffset())
139         , m_operand(key.operand())
140     {
141     }
142     
143     LazyOperandValueProfileKey key() const
144     {
145         return LazyOperandValueProfileKey(m_bytecodeOffset, m_operand);
146     }
147     
148     VirtualRegister m_operand;
149     
150     typedef SegmentedVector<LazyOperandValueProfile, 8> List;
151 };
152
153 class LazyOperandValueProfileParser;
154
155 class CompressedLazyOperandValueProfileHolder {
156     WTF_MAKE_NONCOPYABLE(CompressedLazyOperandValueProfileHolder);
157 public:
158     CompressedLazyOperandValueProfileHolder();
159     ~CompressedLazyOperandValueProfileHolder();
160     
161     void computeUpdatedPredictions(const ConcurrentJITLocker&);
162     
163     LazyOperandValueProfile* add(
164         const ConcurrentJITLocker&, const LazyOperandValueProfileKey& key);
165     
166 private:
167     friend class LazyOperandValueProfileParser;
168     OwnPtr<LazyOperandValueProfile::List> m_data;
169 };
170
171 class LazyOperandValueProfileParser {
172     WTF_MAKE_NONCOPYABLE(LazyOperandValueProfileParser);
173 public:
174     explicit LazyOperandValueProfileParser();
175     ~LazyOperandValueProfileParser();
176     
177     void initialize(
178         const ConcurrentJITLocker&, CompressedLazyOperandValueProfileHolder& holder);
179     
180     LazyOperandValueProfile* getIfPresent(
181         const LazyOperandValueProfileKey& key) const;
182     
183     SpeculatedType prediction(
184         const ConcurrentJITLocker&, const LazyOperandValueProfileKey& key) const;
185 private:
186     HashMap<LazyOperandValueProfileKey, LazyOperandValueProfile*> m_map;
187 };
188
189 } // namespace JSC
190
191 #endif // ENABLE(VALUE_PROFILER)
192
193 #endif // LazyOperandValueProfile_h
194
195