Unreviewed, rolling out r156474.
[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(InvalidVirtualRegister) // 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(InvalidVirtualRegister) // not a valid operand index in our current scheme
56     {
57     }
58     
59     LazyOperandValueProfileKey(unsigned bytecodeOffset, int operand)
60         : m_bytecodeOffset(bytecodeOffset)
61         , m_operand(operand)
62     {
63         ASSERT(operand != InvalidVirtualRegister);
64     }
65     
66     bool operator!() const
67     {
68         return m_operand == InvalidVirtualRegister;
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;
80     }
81     
82     unsigned bytecodeOffset() const
83     {
84         ASSERT(!!*this);
85         return m_bytecodeOffset;
86     }
87     int operand() const
88     {
89         ASSERT(!!*this);
90         return m_operand;
91     }
92     
93     bool isHashTableDeletedValue() const
94     {
95         return m_operand == InvalidVirtualRegister && m_bytecodeOffset;
96     }
97 private: 
98     unsigned m_bytecodeOffset;
99     int m_operand;
100 };
101
102 struct LazyOperandValueProfileKeyHash {
103     static unsigned hash(const LazyOperandValueProfileKey& key) { return key.hash(); }
104     static bool equal(
105         const LazyOperandValueProfileKey& a,
106         const LazyOperandValueProfileKey& b) { return a == b; }
107     static const bool safeToCompareToEmptyOrDeleted = true;
108 };
109
110 } // namespace JSC
111
112 namespace WTF {
113
114 template<typename T> struct DefaultHash;
115 template<> struct DefaultHash<JSC::LazyOperandValueProfileKey> {
116     typedef JSC::LazyOperandValueProfileKeyHash Hash;
117 };
118
119 template<typename T> struct HashTraits;
120 template<> struct HashTraits<JSC::LazyOperandValueProfileKey> : public GenericHashTraits<JSC::LazyOperandValueProfileKey> {
121     static void constructDeletedValue(JSC::LazyOperandValueProfileKey& slot) { new (NotNull, &slot) JSC::LazyOperandValueProfileKey(HashTableDeletedValue); }
122     static bool isDeletedValue(const JSC::LazyOperandValueProfileKey& value) { return value.isHashTableDeletedValue(); }
123 };
124
125 } // namespace WTF
126
127 namespace JSC {
128
129 struct LazyOperandValueProfile : public MinimalValueProfile {
130     LazyOperandValueProfile()
131         : MinimalValueProfile()
132         , m_operand(InvalidVirtualRegister)
133     {
134     }
135     
136     explicit LazyOperandValueProfile(const LazyOperandValueProfileKey& key)
137         : MinimalValueProfile(key.bytecodeOffset())
138         , m_operand(key.operand())
139     {
140     }
141     
142     LazyOperandValueProfileKey key() const
143     {
144         return LazyOperandValueProfileKey(m_bytecodeOffset, m_operand);
145     }
146     
147     int m_operand;
148     
149     typedef SegmentedVector<LazyOperandValueProfile, 8> List;
150 };
151
152 class LazyOperandValueProfileParser;
153
154 class CompressedLazyOperandValueProfileHolder {
155     WTF_MAKE_NONCOPYABLE(CompressedLazyOperandValueProfileHolder);
156 public:
157     CompressedLazyOperandValueProfileHolder();
158     ~CompressedLazyOperandValueProfileHolder();
159     
160     void computeUpdatedPredictions(const ConcurrentJITLocker&);
161     
162     LazyOperandValueProfile* add(
163         const ConcurrentJITLocker&, const LazyOperandValueProfileKey& key);
164     
165 private:
166     friend class LazyOperandValueProfileParser;
167     OwnPtr<LazyOperandValueProfile::List> m_data;
168 };
169
170 class LazyOperandValueProfileParser {
171     WTF_MAKE_NONCOPYABLE(LazyOperandValueProfileParser);
172 public:
173     explicit LazyOperandValueProfileParser();
174     ~LazyOperandValueProfileParser();
175     
176     void initialize(
177         const ConcurrentJITLocker&, CompressedLazyOperandValueProfileHolder& holder);
178     
179     LazyOperandValueProfile* getIfPresent(
180         const LazyOperandValueProfileKey& key) const;
181     
182     SpeculatedType prediction(
183         const ConcurrentJITLocker&, const LazyOperandValueProfileKey& key) const;
184 private:
185     HashMap<LazyOperandValueProfileKey, LazyOperandValueProfile*> m_map;
186 };
187
188 } // namespace JSC
189
190 #endif // ENABLE(VALUE_PROFILER)
191
192 #endif // LazyOperandValueProfile_h
193
194