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