blob: 302365ff006e2c3dcdc53ae9bd2ebf663b9d97f6 [file] [log] [blame]
fpizlo@apple.comf24804c2012-08-15 02:48:35 +00001/*
oliver@apple.comc14eb7d2013-07-25 03:58:47 +00002 * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
fpizlo@apple.comf24804c2012-08-15 02:48:35 +00003 *
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 ArrayProfile_h
27#define ArrayProfile_h
28
oliver@apple.comd2056662013-07-25 04:00:37 +000029#include "ConcurrentJITLock.h"
fpizlo@apple.comf24804c2012-08-15 02:48:35 +000030#include "JSArray.h"
31#include "Structure.h"
32#include <wtf/HashMap.h>
33#include <wtf/SegmentedVector.h>
34
35namespace JSC {
36
fpizlo@apple.com99f37622012-10-29 04:02:08 +000037class CodeBlock;
fpizlo@apple.comf24804c2012-08-15 02:48:35 +000038class LLIntOffsetsExtractor;
39
fpizlo@apple.comd8dd0532012-09-13 04:18:52 +000040// This is a bitfield where each bit represents an IndexingType that we have seen.
fpizlo@apple.com1c4a32c2012-09-17 20:56:39 +000041// There are 32 indexing types, so an unsigned is enough.
fpizlo@apple.comf24804c2012-08-15 02:48:35 +000042typedef unsigned ArrayModes;
43
fpizlo@apple.comd8dd0532012-09-13 04:18:52 +000044#define asArrayModes(type) \
fpizlo@apple.com372c6d52012-10-20 06:53:04 +000045 (static_cast<unsigned>(1) << static_cast<unsigned>(type))
46
47#define ALL_NON_ARRAY_ARRAY_MODES \
48 (asArrayModes(NonArray) \
fpizlo@apple.com75c91a72012-11-08 22:28:25 +000049 | asArrayModes(NonArrayWithInt32) \
50 | asArrayModes(NonArrayWithDouble) \
51 | asArrayModes(NonArrayWithContiguous) \
52 | asArrayModes(NonArrayWithArrayStorage) \
53 | asArrayModes(NonArrayWithSlowPutArrayStorage))
fpizlo@apple.com372c6d52012-10-20 06:53:04 +000054
55#define ALL_ARRAY_ARRAY_MODES \
56 (asArrayModes(ArrayClass) \
fpizlo@apple.com75c91a72012-11-08 22:28:25 +000057 | asArrayModes(ArrayWithUndecided) \
58 | asArrayModes(ArrayWithInt32) \
59 | asArrayModes(ArrayWithDouble) \
60 | asArrayModes(ArrayWithContiguous) \
61 | asArrayModes(ArrayWithArrayStorage) \
62 | asArrayModes(ArrayWithSlowPutArrayStorage))
fpizlo@apple.com372c6d52012-10-20 06:53:04 +000063
64#define ALL_ARRAY_MODES (ALL_NON_ARRAY_ARRAY_MODES | ALL_ARRAY_ARRAY_MODES)
fpizlo@apple.comf24804c2012-08-15 02:48:35 +000065
66inline ArrayModes arrayModeFromStructure(Structure* structure)
67{
fpizlo@apple.com1c4a32c2012-09-17 20:56:39 +000068 return asArrayModes(structure->indexingType());
fpizlo@apple.comf24804c2012-08-15 02:48:35 +000069}
70
fpizlo@apple.com77ef0e32012-12-12 00:21:43 +000071void dumpArrayModes(PrintStream&, ArrayModes);
72MAKE_PRINT_ADAPTOR(ArrayModesDump, ArrayModes, dumpArrayModes);
fpizlo@apple.com372c6d52012-10-20 06:53:04 +000073
74inline bool mergeArrayModes(ArrayModes& left, ArrayModes right)
75{
76 ArrayModes newModes = left | right;
77 if (newModes == left)
78 return false;
79 left = newModes;
80 return true;
81}
82
oliver@apple.com06cf1a82013-07-25 04:04:35 +000083inline bool arrayModesAreClearOrTop(ArrayModes modes)
84{
85 return !modes || modes == ALL_ARRAY_MODES;
86}
87
fpizlo@apple.com372c6d52012-10-20 06:53:04 +000088// Checks if proven is a subset of expected.
89inline bool arrayModesAlreadyChecked(ArrayModes proven, ArrayModes expected)
90{
91 return (expected | proven) == expected;
92}
93
fpizlo@apple.com75c91a72012-11-08 22:28:25 +000094inline bool arrayModesInclude(ArrayModes arrayModes, IndexingType shape)
95{
96 return !!(arrayModes & (asArrayModes(NonArray | shape) | asArrayModes(ArrayClass | shape)));
97}
98
99inline bool shouldUseSlowPutArrayStorage(ArrayModes arrayModes)
100{
101 return arrayModesInclude(arrayModes, SlowPutArrayStorageShape);
102}
103
104inline bool shouldUseFastArrayStorage(ArrayModes arrayModes)
105{
106 return arrayModesInclude(arrayModes, ArrayStorageShape);
107}
108
109inline bool shouldUseContiguous(ArrayModes arrayModes)
110{
111 return arrayModesInclude(arrayModes, ContiguousShape);
112}
113
114inline bool shouldUseDouble(ArrayModes arrayModes)
115{
116 return arrayModesInclude(arrayModes, DoubleShape);
117}
118
119inline bool shouldUseInt32(ArrayModes arrayModes)
120{
121 return arrayModesInclude(arrayModes, Int32Shape);
122}
123
mhahnenberg@apple.com3ebd59e2013-05-09 19:38:23 +0000124inline bool hasSeenArray(ArrayModes arrayModes)
125{
126 return arrayModes & ALL_ARRAY_ARRAY_MODES;
127}
128
129inline bool hasSeenNonArray(ArrayModes arrayModes)
130{
131 return arrayModes & ALL_NON_ARRAY_ARRAY_MODES;
132}
133
fpizlo@apple.comf24804c2012-08-15 02:48:35 +0000134class ArrayProfile {
135public:
136 ArrayProfile()
137 : m_bytecodeOffset(std::numeric_limits<unsigned>::max())
mhahnenberg@apple.comb6f85192014-02-27 01:27:18 +0000138 , m_lastSeenStructureID(0)
fpizlo@apple.com69e27842012-09-19 21:43:10 +0000139 , m_mayStoreToHole(false)
fpizlo@apple.com304fbca2012-12-17 21:38:51 +0000140 , m_outOfBounds(false)
fpizlo@apple.com497c7512012-09-19 01:20:52 +0000141 , m_mayInterceptIndexedAccesses(false)
fpizlo@apple.com99f37622012-10-29 04:02:08 +0000142 , m_usesOriginalArrayStructures(true)
oliver@apple.com4cd40f22013-07-25 04:04:20 +0000143 , m_didPerformFirstRunPruning(false)
fpizlo@apple.comf24804c2012-08-15 02:48:35 +0000144 , m_observedArrayModes(0)
145 {
146 }
147
148 ArrayProfile(unsigned bytecodeOffset)
149 : m_bytecodeOffset(bytecodeOffset)
mhahnenberg@apple.comb6f85192014-02-27 01:27:18 +0000150 , m_lastSeenStructureID(0)
fpizlo@apple.com69e27842012-09-19 21:43:10 +0000151 , m_mayStoreToHole(false)
fpizlo@apple.com304fbca2012-12-17 21:38:51 +0000152 , m_outOfBounds(false)
fpizlo@apple.com497c7512012-09-19 01:20:52 +0000153 , m_mayInterceptIndexedAccesses(false)
fpizlo@apple.com99f37622012-10-29 04:02:08 +0000154 , m_usesOriginalArrayStructures(true)
oliver@apple.com4cd40f22013-07-25 04:04:20 +0000155 , m_didPerformFirstRunPruning(false)
fpizlo@apple.comf24804c2012-08-15 02:48:35 +0000156 , m_observedArrayModes(0)
157 {
158 }
159
160 unsigned bytecodeOffset() const { return m_bytecodeOffset; }
161
mhahnenberg@apple.comb6f85192014-02-27 01:27:18 +0000162 StructureID* addressOfLastSeenStructureID() { return &m_lastSeenStructureID; }
fpizlo@apple.comc7be5be02012-09-17 19:07:32 +0000163 ArrayModes* addressOfArrayModes() { return &m_observedArrayModes; }
fpizlo@apple.com69e27842012-09-19 21:43:10 +0000164 bool* addressOfMayStoreToHole() { return &m_mayStoreToHole; }
fpizlo@apple.com304fbca2012-12-17 21:38:51 +0000165 bool* addressOfOutOfBounds() { return &m_outOfBounds; }
fpizlo@apple.comf24804c2012-08-15 02:48:35 +0000166
167 void observeStructure(Structure* structure)
168 {
mhahnenberg@apple.comb6f85192014-02-27 01:27:18 +0000169 m_lastSeenStructureID = structure->id();
fpizlo@apple.comf24804c2012-08-15 02:48:35 +0000170 }
171
oliver@apple.com58cdc332013-07-25 04:04:59 +0000172 void computeUpdatedPrediction(const ConcurrentJITLocker&, CodeBlock*);
fpizlo@apple.comf24804c2012-08-15 02:48:35 +0000173
oliver@apple.comd2056662013-07-25 04:00:37 +0000174 ArrayModes observedArrayModes(const ConcurrentJITLocker&) const { return m_observedArrayModes; }
175 bool mayInterceptIndexedAccesses(const ConcurrentJITLocker&) const { return m_mayInterceptIndexedAccesses; }
fpizlo@apple.comf24804c2012-08-15 02:48:35 +0000176
oliver@apple.comd2056662013-07-25 04:00:37 +0000177 bool mayStoreToHole(const ConcurrentJITLocker&) const { return m_mayStoreToHole; }
178 bool outOfBounds(const ConcurrentJITLocker&) const { return m_outOfBounds; }
fpizlo@apple.com69e27842012-09-19 21:43:10 +0000179
oliver@apple.comd2056662013-07-25 04:00:37 +0000180 bool usesOriginalArrayStructures(const ConcurrentJITLocker&) const { return m_usesOriginalArrayStructures; }
fpizlo@apple.com99f37622012-10-29 04:02:08 +0000181
oliver@apple.comd2056662013-07-25 04:00:37 +0000182 CString briefDescription(const ConcurrentJITLocker&, CodeBlock*);
oliver@apple.com4cd40f22013-07-25 04:04:20 +0000183 CString briefDescriptionWithoutUpdating(const ConcurrentJITLocker&);
fpizlo@apple.com77ef0e32012-12-12 00:21:43 +0000184
fpizlo@apple.comf24804c2012-08-15 02:48:35 +0000185private:
186 friend class LLIntOffsetsExtractor;
187
fpizlo@apple.com304fbca2012-12-17 21:38:51 +0000188 static Structure* polymorphicStructure() { return static_cast<Structure*>(reinterpret_cast<void*>(1)); }
189
fpizlo@apple.comf24804c2012-08-15 02:48:35 +0000190 unsigned m_bytecodeOffset;
mhahnenberg@apple.comb6f85192014-02-27 01:27:18 +0000191 StructureID m_lastSeenStructureID;
fpizlo@apple.com69e27842012-09-19 21:43:10 +0000192 bool m_mayStoreToHole; // This flag may become overloaded to indicate other special cases that were encountered during array access, as it depends on indexing type. Since we currently have basically just one indexing type (two variants of ArrayStorage), this flag for now just means exactly what its name implies.
fpizlo@apple.com304fbca2012-12-17 21:38:51 +0000193 bool m_outOfBounds;
oliver@apple.com4cd40f22013-07-25 04:04:20 +0000194 bool m_mayInterceptIndexedAccesses : 1;
195 bool m_usesOriginalArrayStructures : 1;
196 bool m_didPerformFirstRunPruning : 1;
fpizlo@apple.comf24804c2012-08-15 02:48:35 +0000197 ArrayModes m_observedArrayModes;
198};
199
200typedef SegmentedVector<ArrayProfile, 4, 0> ArrayProfileVector;
201
202} // namespace JSC
203
204#endif // ArrayProfile_h
205