2 * Copyright (C) 2012 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
26 #ifndef ArrayProfile_h
27 #define ArrayProfile_h
30 #include "Structure.h"
31 #include <wtf/HashMap.h>
32 #include <wtf/SegmentedVector.h>
37 class LLIntOffsetsExtractor
;
39 // This is a bitfield where each bit represents an IndexingType that we have seen.
40 // There are 32 indexing types, so an unsigned is enough.
41 typedef unsigned ArrayModes
;
43 #define asArrayModes(type) \
44 (static_cast<unsigned>(1) << static_cast<unsigned>(type))
46 #define ALL_NON_ARRAY_ARRAY_MODES \
47 (asArrayModes(NonArray) \
48 | asArrayModes(NonArrayWithInt32) \
49 | asArrayModes(NonArrayWithDouble) \
50 | asArrayModes(NonArrayWithContiguous) \
51 | asArrayModes(NonArrayWithArrayStorage) \
52 | asArrayModes(NonArrayWithSlowPutArrayStorage))
54 #define ALL_ARRAY_ARRAY_MODES \
55 (asArrayModes(ArrayClass) \
56 | asArrayModes(ArrayWithUndecided) \
57 | asArrayModes(ArrayWithInt32) \
58 | asArrayModes(ArrayWithDouble) \
59 | asArrayModes(ArrayWithContiguous) \
60 | asArrayModes(ArrayWithArrayStorage) \
61 | asArrayModes(ArrayWithSlowPutArrayStorage))
63 #define ALL_ARRAY_MODES (ALL_NON_ARRAY_ARRAY_MODES | ALL_ARRAY_ARRAY_MODES)
65 inline ArrayModes
arrayModeFromStructure(Structure
* structure
)
67 return asArrayModes(structure
->indexingType());
70 void dumpArrayModes(PrintStream
&, ArrayModes
);
71 MAKE_PRINT_ADAPTOR(ArrayModesDump
, ArrayModes
, dumpArrayModes
);
73 inline bool mergeArrayModes(ArrayModes
& left
, ArrayModes right
)
75 ArrayModes newModes
= left
| right
;
82 // Checks if proven is a subset of expected.
83 inline bool arrayModesAlreadyChecked(ArrayModes proven
, ArrayModes expected
)
85 return (expected
| proven
) == expected
;
88 inline bool arrayModesInclude(ArrayModes arrayModes
, IndexingType shape
)
90 return !!(arrayModes
& (asArrayModes(NonArray
| shape
) | asArrayModes(ArrayClass
| shape
)));
93 inline bool shouldUseSlowPutArrayStorage(ArrayModes arrayModes
)
95 return arrayModesInclude(arrayModes
, SlowPutArrayStorageShape
);
98 inline bool shouldUseFastArrayStorage(ArrayModes arrayModes
)
100 return arrayModesInclude(arrayModes
, ArrayStorageShape
);
103 inline bool shouldUseContiguous(ArrayModes arrayModes
)
105 return arrayModesInclude(arrayModes
, ContiguousShape
);
108 inline bool shouldUseDouble(ArrayModes arrayModes
)
110 return arrayModesInclude(arrayModes
, DoubleShape
);
113 inline bool shouldUseInt32(ArrayModes arrayModes
)
115 return arrayModesInclude(arrayModes
, Int32Shape
);
118 inline bool hasSeenArray(ArrayModes arrayModes
)
120 return arrayModes
& ALL_ARRAY_ARRAY_MODES
;
123 inline bool hasSeenNonArray(ArrayModes arrayModes
)
125 return arrayModes
& ALL_NON_ARRAY_ARRAY_MODES
;
131 : m_bytecodeOffset(std::numeric_limits
<unsigned>::max())
132 , m_lastSeenStructure(0)
133 , m_expectedStructure(0)
134 , m_mayStoreToHole(false)
135 , m_outOfBounds(false)
136 , m_mayInterceptIndexedAccesses(false)
137 , m_usesOriginalArrayStructures(true)
138 , m_observedArrayModes(0)
142 ArrayProfile(unsigned bytecodeOffset
)
143 : m_bytecodeOffset(bytecodeOffset
)
144 , m_lastSeenStructure(0)
145 , m_expectedStructure(0)
146 , m_mayStoreToHole(false)
147 , m_outOfBounds(false)
148 , m_mayInterceptIndexedAccesses(false)
149 , m_usesOriginalArrayStructures(true)
150 , m_observedArrayModes(0)
154 unsigned bytecodeOffset() const { return m_bytecodeOffset
; }
156 Structure
** addressOfLastSeenStructure() { return &m_lastSeenStructure
; }
157 ArrayModes
* addressOfArrayModes() { return &m_observedArrayModes
; }
158 bool* addressOfMayStoreToHole() { return &m_mayStoreToHole
; }
159 bool* addressOfOutOfBounds() { return &m_outOfBounds
; }
161 void observeStructure(Structure
* structure
)
163 m_lastSeenStructure
= structure
;
166 void computeUpdatedPrediction(CodeBlock
*, OperationInProgress
= NoOperation
);
168 Structure
* expectedStructure() const
170 if (structureIsPolymorphic())
172 return m_expectedStructure
;
174 bool structureIsPolymorphic() const
176 return m_expectedStructure
== polymorphicStructure();
178 bool hasDefiniteStructure() const
180 return !structureIsPolymorphic() && m_expectedStructure
;
182 ArrayModes
observedArrayModes() const { return m_observedArrayModes
; }
183 ArrayModes
updatedObservedArrayModes() const; // Computes the observed array modes without updating the profile.
184 bool mayInterceptIndexedAccesses() const { return m_mayInterceptIndexedAccesses
; }
186 bool mayStoreToHole() const { return m_mayStoreToHole
; }
187 bool outOfBounds() const { return m_outOfBounds
; }
189 bool usesOriginalArrayStructures() const { return m_usesOriginalArrayStructures
; }
191 CString
briefDescription(CodeBlock
*);
194 friend class LLIntOffsetsExtractor
;
196 static Structure
* polymorphicStructure() { return static_cast<Structure
*>(reinterpret_cast<void*>(1)); }
198 unsigned m_bytecodeOffset
;
199 Structure
* m_lastSeenStructure
;
200 Structure
* m_expectedStructure
;
201 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.
203 bool m_mayInterceptIndexedAccesses
;
204 bool m_usesOriginalArrayStructures
;
205 ArrayModes m_observedArrayModes
;
208 typedef SegmentedVector
<ArrayProfile
, 4, 0> ArrayProfileVector
;
212 #endif // ArrayProfile_h