1/*
2 * Copyright (C) 2012-2018 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#pragma once
27
28#include "ClassInfo.h"
29#include "CodeLocation.h"
30#include "IndexingType.h"
31#include "JITStubRoutine.h"
32#include "Structure.h"
33
34namespace JSC {
35
36class Symbol;
37
38#if ENABLE(JIT)
39
40class StructureStubInfo;
41
42enum JITArrayMode : uint8_t {
43 JITInt32,
44 JITDouble,
45 JITContiguous,
46 JITArrayStorage,
47 JITDirectArguments,
48 JITScopedArguments,
49 JITInt8Array,
50 JITInt16Array,
51 JITInt32Array,
52 JITUint8Array,
53 JITUint8ClampedArray,
54 JITUint16Array,
55 JITUint32Array,
56 JITFloat32Array,
57 JITFloat64Array
58};
59
60inline bool isOptimizableIndexingType(IndexingType indexingType)
61{
62 switch (indexingType) {
63 case ALL_INT32_INDEXING_TYPES:
64 case ALL_DOUBLE_INDEXING_TYPES:
65 case ALL_CONTIGUOUS_INDEXING_TYPES:
66 case ARRAY_WITH_ARRAY_STORAGE_INDEXING_TYPES:
67 return true;
68 default:
69 return false;
70 }
71}
72
73inline bool hasOptimizableIndexingForJSType(JSType type)
74{
75 switch (type) {
76 case DirectArgumentsType:
77 case ScopedArgumentsType:
78 return true;
79 default:
80 return false;
81 }
82}
83
84inline bool hasOptimizableIndexingForClassInfo(const ClassInfo* classInfo)
85{
86 return isTypedView(classInfo->typedArrayStorageType);
87}
88
89inline bool hasOptimizableIndexing(Structure* structure)
90{
91 return isOptimizableIndexingType(structure->indexingType())
92 || hasOptimizableIndexingForJSType(structure->typeInfo().type())
93 || hasOptimizableIndexingForClassInfo(structure->classInfo());
94}
95
96inline JITArrayMode jitArrayModeForIndexingType(IndexingType indexingType)
97{
98 switch (indexingType) {
99 case ALL_INT32_INDEXING_TYPES:
100 return JITInt32;
101 case ALL_DOUBLE_INDEXING_TYPES:
102 return JITDouble;
103 case ALL_CONTIGUOUS_INDEXING_TYPES:
104 return JITContiguous;
105 case ARRAY_WITH_ARRAY_STORAGE_INDEXING_TYPES:
106 return JITArrayStorage;
107 default:
108 CRASH();
109 return JITContiguous;
110 }
111}
112
113inline JITArrayMode jitArrayModeForJSType(JSType type)
114{
115 switch (type) {
116 case DirectArgumentsType:
117 return JITDirectArguments;
118 case ScopedArgumentsType:
119 return JITScopedArguments;
120 default:
121 RELEASE_ASSERT_NOT_REACHED();
122 return JITContiguous;
123 }
124}
125
126inline JITArrayMode jitArrayModeForClassInfo(const ClassInfo* classInfo)
127{
128 switch (classInfo->typedArrayStorageType) {
129 case TypeInt8:
130 return JITInt8Array;
131 case TypeInt16:
132 return JITInt16Array;
133 case TypeInt32:
134 return JITInt32Array;
135 case TypeUint8:
136 return JITUint8Array;
137 case TypeUint8Clamped:
138 return JITUint8ClampedArray;
139 case TypeUint16:
140 return JITUint16Array;
141 case TypeUint32:
142 return JITUint32Array;
143 case TypeFloat32:
144 return JITFloat32Array;
145 case TypeFloat64:
146 return JITFloat64Array;
147 default:
148 CRASH();
149 return JITContiguous;
150 }
151}
152
153inline bool jitArrayModePermitsPut(JITArrayMode mode)
154{
155 switch (mode) {
156 case JITDirectArguments:
157 case JITScopedArguments:
158 // We could support put_by_val on these at some point, but it's just not that profitable
159 // at the moment.
160 return false;
161 default:
162 return true;
163 }
164}
165
166inline bool jitArrayModePermitsPutDirect(JITArrayMode mode)
167{
168 // We don't allow typed array putDirect here since putDirect has
169 // defineOwnProperty({configurable: true, writable:true, enumerable:true})
170 // semantics. Typed array indexed properties are non-configurable by
171 // default, so we can't simply store to a typed array for putDirect.
172 //
173 // We could model putDirect on ScopedArguments and DirectArguments, but we
174 // haven't found any performance incentive to do it yet.
175 switch (mode) {
176 case JITInt32:
177 case JITDouble:
178 case JITContiguous:
179 case JITArrayStorage:
180 return true;
181 default:
182 return false;
183 }
184}
185
186inline TypedArrayType typedArrayTypeForJITArrayMode(JITArrayMode mode)
187{
188 switch (mode) {
189 case JITInt8Array:
190 return TypeInt8;
191 case JITInt16Array:
192 return TypeInt16;
193 case JITInt32Array:
194 return TypeInt32;
195 case JITUint8Array:
196 return TypeUint8;
197 case JITUint8ClampedArray:
198 return TypeUint8Clamped;
199 case JITUint16Array:
200 return TypeUint16;
201 case JITUint32Array:
202 return TypeUint32;
203 case JITFloat32Array:
204 return TypeFloat32;
205 case JITFloat64Array:
206 return TypeFloat64;
207 default:
208 CRASH();
209 return NotTypedArray;
210 }
211}
212
213inline JITArrayMode jitArrayModeForStructure(Structure* structure)
214{
215 if (isOptimizableIndexingType(structure->indexingType()))
216 return jitArrayModeForIndexingType(structure->indexingType());
217
218 if (hasOptimizableIndexingForJSType(structure->typeInfo().type()))
219 return jitArrayModeForJSType(structure->typeInfo().type());
220
221 ASSERT(hasOptimizableIndexingForClassInfo(structure->classInfo()));
222 return jitArrayModeForClassInfo(structure->classInfo());
223}
224
225struct ByValInfo {
226 ByValInfo() { }
227
228 ByValInfo(unsigned bytecodeIndex, CodeLocationJump<JSInternalPtrTag> notIndexJump, CodeLocationJump<JSInternalPtrTag> badTypeJump, CodeLocationLabel<ExceptionHandlerPtrTag> exceptionHandler, JITArrayMode arrayMode, ArrayProfile* arrayProfile, CodeLocationLabel<JSInternalPtrTag> badTypeDoneTarget, CodeLocationLabel<JSInternalPtrTag> badTypeNextHotPathTarget, CodeLocationLabel<JSInternalPtrTag> slowPathTarget)
229 : notIndexJump(notIndexJump)
230 , badTypeJump(badTypeJump)
231 , exceptionHandler(exceptionHandler)
232 , badTypeDoneTarget(badTypeDoneTarget)
233 , badTypeNextHotPathTarget(badTypeNextHotPathTarget)
234 , slowPathTarget(slowPathTarget)
235 , arrayProfile(arrayProfile)
236 , bytecodeIndex(bytecodeIndex)
237 , slowPathCount(0)
238 , stubInfo(nullptr)
239 , arrayMode(arrayMode)
240 , tookSlowPath(false)
241 , seen(false)
242 {
243 }
244
245 CodeLocationJump<JSInternalPtrTag> notIndexJump;
246 CodeLocationJump<JSInternalPtrTag> badTypeJump;
247 CodeLocationLabel<ExceptionHandlerPtrTag> exceptionHandler;
248 CodeLocationLabel<JSInternalPtrTag> badTypeDoneTarget;
249 CodeLocationLabel<JSInternalPtrTag> badTypeNextHotPathTarget;
250 CodeLocationLabel<JSInternalPtrTag> slowPathTarget;
251 ArrayProfile* arrayProfile;
252 unsigned bytecodeIndex;
253 unsigned slowPathCount;
254 RefPtr<JITStubRoutine> stubRoutine;
255 Identifier cachedId;
256 WriteBarrier<Symbol> cachedSymbol;
257 StructureStubInfo* stubInfo;
258 JITArrayMode arrayMode; // The array mode that was baked into the inline JIT code.
259 bool tookSlowPath : 1;
260 bool seen : 1;
261};
262
263inline unsigned getByValInfoBytecodeIndex(ByValInfo* info)
264{
265 return info->bytecodeIndex;
266}
267
268#endif // ENABLE(JIT)
269
270} // namespace JSC
271