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