blob: 942b4adaecb4192a219ecf159c7701768d13d414 [file] [log] [blame]
barraclough@apple.com2302c042011-03-14 23:31:00 +00001/*
keith_miller@apple.com3793b132016-01-11 21:31:04 +00002 * Copyright (C) 2011, 2013-2016 Apple Inc. All rights reserved.
barraclough@apple.com2302c042011-03-14 23:31:00 +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#include "config.h"
27#include "DFGOperations.h"
28
mark.lam@apple.coma4fe7ab2012-11-09 03:03:44 +000029#include "ButterflyInlines.h"
fpizlo@apple.comda834ae2015-03-26 04:28:43 +000030#include "ClonedArguments.h"
barraclough@apple.com2302c042011-03-14 23:31:00 +000031#include "CodeBlock.h"
oliver@apple.comb3e5acb2013-07-25 04:02:53 +000032#include "CommonSlowPaths.h"
mark.lam@apple.coma4fe7ab2012-11-09 03:03:44 +000033#include "CopiedSpaceInlines.h"
fpizlo@apple.com532f1e52013-09-04 06:26:04 +000034#include "DFGDriver.h"
fpizlo@apple.comb426f862014-02-10 02:51:13 +000035#include "DFGJITCode.h"
fpizlo@apple.com0bef2a12014-02-10 19:26:29 +000036#include "DFGOSRExit.h"
fpizlo@apple.com5e135772012-07-12 00:12:03 +000037#include "DFGThunks.h"
fpizlo@apple.com532f1e52013-09-04 06:26:04 +000038#include "DFGToFTLDeferredCompilationCallback.h"
39#include "DFGToFTLForOSREntryDeferredCompilationCallback.h"
40#include "DFGWorklist.h"
fpizlo@apple.comda834ae2015-03-26 04:28:43 +000041#include "DirectArguments.h"
fpizlo@apple.com532f1e52013-09-04 06:26:04 +000042#include "FTLForOSREntryJITCode.h"
43#include "FTLOSREntry.h"
fpizlo@apple.com7bbcaab2012-02-22 05:23:19 +000044#include "HostCallReturnValue.h"
fpizlo@apple.comdc03dc52012-01-17 00:53:40 +000045#include "GetterSetter.h"
barraclough@apple.com2302c042011-03-14 23:31:00 +000046#include "Interpreter.h"
fpizlo@apple.com16e2cbf2012-06-22 23:32:59 +000047#include "JIT.h"
oliver@apple.comc55314a2012-05-30 19:45:20 +000048#include "JITExceptions.h"
fpizlo@apple.comda834ae2015-03-26 04:28:43 +000049#include "JSCInlines.h"
oliver@apple.coma7dfb4d2014-09-11 18:18:14 +000050#include "JSLexicalEnvironment.h"
ggaren@apple.comc862eac2013-01-29 05:48:01 +000051#include "ObjectConstructor.h"
mark.lam@apple.com9df8b832013-09-26 20:27:14 +000052#include "Repatch.h"
fpizlo@apple.comda834ae2015-03-26 04:28:43 +000053#include "ScopedArguments.h"
commit-queue@webkit.orgaa31a5e2013-04-09 06:45:16 +000054#include "StringConstructor.h"
utatane.tea@gmail.com947fa4e2015-01-31 01:23:56 +000055#include "Symbol.h"
saambarati1@gmail.comdaf10202014-10-01 20:47:51 +000056#include "TypeProfilerLog.h"
fpizlo@apple.com372fa822013-08-21 19:43:47 +000057#include "TypedArrayInlines.h"
fpizlo@apple.comda834ae2015-03-26 04:28:43 +000058#include "VM.h"
fpizlo@apple.com16e2cbf2012-06-22 23:32:59 +000059#include <wtf/InlineASM.h>
barraclough@apple.com2302c042011-03-14 23:31:00 +000060
commit-queue@webkit.orgb8419482012-08-30 22:21:48 +000061#if ENABLE(JIT)
fpizlo@apple.com7bbcaab2012-02-22 05:23:19 +000062#if ENABLE(DFG_JIT)
63
barraclough@apple.com2302c042011-03-14 23:31:00 +000064namespace JSC { namespace DFG {
65
oliver@apple.come050d642013-10-19 00:09:28 +000066template<bool strict, bool direct>
weinig@apple.coma96509f2011-06-15 21:57:17 +000067static inline void putByVal(ExecState* exec, JSValue baseValue, uint32_t index, JSValue value)
barraclough@apple.comc7af2d32011-05-26 21:37:05 +000068{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +000069 VM& vm = exec->vm();
70 NativeCallFrameTracer tracer(&vm, exec);
utatane.tea@gmail.com20b6e302015-04-07 07:26:08 +000071 ASSERT(isIndex(index));
oliver@apple.come050d642013-10-19 00:09:28 +000072 if (direct) {
73 RELEASE_ASSERT(baseValue.isObject());
74 asObject(baseValue)->putDirectIndex(exec, index, value, 0, strict ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
75 return;
76 }
fpizlo@apple.comd8dd0532012-09-13 04:18:52 +000077 if (baseValue.isObject()) {
78 JSObject* object = asObject(baseValue);
79 if (object->canSetIndexQuickly(index)) {
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +000080 object->setIndexQuickly(vm, index, value);
weinig@apple.coma96509f2011-06-15 21:57:17 +000081 return;
82 }
83
mhahnenberg@apple.comb6f85192014-02-27 01:27:18 +000084 object->methodTable(vm)->putByIndex(object, exec, index, value, strict);
weinig@apple.coma96509f2011-06-15 21:57:17 +000085 return;
86 }
87
barraclough@apple.coma4d51f22012-03-06 01:18:42 +000088 baseValue.putByIndex(exec, index, value, strict);
weinig@apple.coma96509f2011-06-15 21:57:17 +000089}
90
oliver@apple.come050d642013-10-19 00:09:28 +000091template<bool strict, bool direct>
mark.lam@apple.com9df8b832013-09-26 20:27:14 +000092ALWAYS_INLINE static void JIT_OPERATION operationPutByValInternal(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
weinig@apple.coma96509f2011-06-15 21:57:17 +000093{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +000094 VM* vm = &exec->vm();
95 NativeCallFrameTracer tracer(vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +000096
barraclough@apple.comc7af2d32011-05-26 21:37:05 +000097 JSValue baseValue = JSValue::decode(encodedBase);
98 JSValue property = JSValue::decode(encodedProperty);
99 JSValue value = JSValue::decode(encodedValue);
100
101 if (LIKELY(property.isUInt32())) {
utatane.tea@gmail.com20b6e302015-04-07 07:26:08 +0000102 // Despite its name, JSValue::isUInt32 will return true only for positive boxed int32_t; all those values are valid array indices.
103 ASSERT(isIndex(property.asUInt32()));
commit-queue@webkit.orge3549c62015-01-22 19:34:34 +0000104 putByVal<strict, direct>(exec, baseValue, property.asUInt32(), value);
barraclough@apple.comc7af2d32011-05-26 21:37:05 +0000105 return;
106 }
107
weinig@apple.coma96509f2011-06-15 21:57:17 +0000108 if (property.isDouble()) {
109 double propertyAsDouble = property.asDouble();
110 uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
utatane.tea@gmail.com20b6e302015-04-07 07:26:08 +0000111 if (propertyAsDouble == propertyAsUInt32 && isIndex(propertyAsUInt32)) {
oliver@apple.come050d642013-10-19 00:09:28 +0000112 putByVal<strict, direct>(exec, baseValue, propertyAsUInt32, value);
weinig@apple.coma96509f2011-06-15 21:57:17 +0000113 return;
114 }
115 }
116
barraclough@apple.comc7af2d32011-05-26 21:37:05 +0000117 // Don't put to an object if toString throws an exception.
utatane.tea@gmail.come16e15d2015-03-20 21:35:17 +0000118 auto propertyName = property.toPropertyKey(exec);
utatane.tea@gmail.com20b6e302015-04-07 07:26:08 +0000119 if (vm->exception())
120 return;
121
122 PutPropertySlot slot(baseValue, strict);
123 if (direct) {
124 RELEASE_ASSERT(baseValue.isObject());
125 if (Optional<uint32_t> index = parseIndex(propertyName))
126 asObject(baseValue)->putDirectIndex(exec, index.value(), value, 0, strict ? PutDirectIndexShouldThrow : PutDirectIndexShouldNotThrow);
127 else
utatane.tea@gmail.com947fa4e2015-01-31 01:23:56 +0000128 asObject(baseValue)->putDirect(*vm, propertyName, value, slot);
utatane.tea@gmail.com20b6e302015-04-07 07:26:08 +0000129 } else
130 baseValue.put(exec, propertyName, value, slot);
barraclough@apple.comc7af2d32011-05-26 21:37:05 +0000131}
132
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000133template<typename ViewClass>
134char* newTypedArrayWithSize(ExecState* exec, Structure* structure, int32_t size)
135{
136 VM& vm = exec->vm();
137 NativeCallFrameTracer tracer(&vm, exec);
138 if (size < 0) {
commit-queue@webkit.org29e710c2014-08-29 21:33:30 +0000139 vm.throwException(exec, createRangeError(exec, ASCIILiteral("Requested length is negative")));
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000140 return 0;
141 }
142 return bitwise_cast<char*>(ViewClass::create(exec, structure, size));
143}
144
barraclough@apple.comc7af2d32011-05-26 21:37:05 +0000145extern "C" {
146
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000147EncodedJSValue JIT_OPERATION operationToThis(ExecState* exec, EncodedJSValue encodedOp)
barraclough@apple.com2302c042011-03-14 23:31:00 +0000148{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000149 VM* vm = &exec->vm();
150 NativeCallFrameTracer tracer(vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +0000151
fpizlo@apple.com018818d2013-09-13 23:18:19 +0000152 return JSValue::encode(JSValue::decode(encodedOp).toThis(exec, NotStrictMode));
153}
154
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000155EncodedJSValue JIT_OPERATION operationToThisStrict(ExecState* exec, EncodedJSValue encodedOp)
fpizlo@apple.com018818d2013-09-13 23:18:19 +0000156{
157 VM* vm = &exec->vm();
158 NativeCallFrameTracer tracer(vm, exec);
159
160 return JSValue::encode(JSValue::decode(encodedOp).toThis(exec, StrictMode));
barraclough@apple.com2302c042011-03-14 23:31:00 +0000161}
162
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000163JSCell* JIT_OPERATION operationCreateThis(ExecState* exec, JSObject* constructor, int32_t inlineCapacity)
fpizlo@apple.combb159ec2011-09-21 22:17:06 +0000164{
mhahnenberg@apple.comb6f85192014-02-27 01:27:18 +0000165 VM& vm = exec->vm();
166 NativeCallFrameTracer tracer(&vm, exec);
sbarati@apple.come5315aa2016-02-20 23:51:33 +0000167 if (constructor->type() == JSFunctionType)
168 return constructEmptyObject(exec, jsCast<JSFunction*>(constructor)->rareData(exec, inlineCapacity)->objectAllocationProfile()->structure());
barraclough@apple.comcef11dc2012-05-10 18:40:29 +0000169
sbarati@apple.come5315aa2016-02-20 23:51:33 +0000170 return constructEmptyObject(exec);
fpizlo@apple.com133c9ac2011-11-08 00:37:33 +0000171}
172
mark.lam@apple.comc0008652015-12-15 21:19:31 +0000173EncodedJSValue JIT_OPERATION operationValueBitAnd(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
174{
175 VM* vm = &exec->vm();
176 NativeCallFrameTracer tracer(vm, exec);
177
178 JSValue op1 = JSValue::decode(encodedOp1);
179 JSValue op2 = JSValue::decode(encodedOp2);
180
181 int32_t a = op1.toInt32(exec);
182 int32_t b = op2.toInt32(exec);
183 return JSValue::encode(jsNumber(a & b));
184}
185
186EncodedJSValue JIT_OPERATION operationValueBitOr(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
187{
188 VM* vm = &exec->vm();
189 NativeCallFrameTracer tracer(vm, exec);
190
191 JSValue op1 = JSValue::decode(encodedOp1);
192 JSValue op2 = JSValue::decode(encodedOp2);
193
194 int32_t a = op1.toInt32(exec);
195 int32_t b = op2.toInt32(exec);
196 return JSValue::encode(jsNumber(a | b));
197}
198
199EncodedJSValue JIT_OPERATION operationValueBitXor(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
200{
201 VM* vm = &exec->vm();
202 NativeCallFrameTracer tracer(vm, exec);
203
204 JSValue op1 = JSValue::decode(encodedOp1);
205 JSValue op2 = JSValue::decode(encodedOp2);
206
207 int32_t a = op1.toInt32(exec);
208 int32_t b = op2.toInt32(exec);
209 return JSValue::encode(jsNumber(a ^ b));
210}
211
212EncodedJSValue JIT_OPERATION operationValueBitLShift(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
213{
214 VM* vm = &exec->vm();
215 NativeCallFrameTracer tracer(vm, exec);
216
217 JSValue op1 = JSValue::decode(encodedOp1);
218 JSValue op2 = JSValue::decode(encodedOp2);
219
220 int32_t a = op1.toInt32(exec);
221 uint32_t b = op2.toUInt32(exec);
222 return JSValue::encode(jsNumber(a << (b & 0x1f)));
223}
224
225EncodedJSValue JIT_OPERATION operationValueBitRShift(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
226{
227 VM* vm = &exec->vm();
228 NativeCallFrameTracer tracer(vm, exec);
229
230 JSValue op1 = JSValue::decode(encodedOp1);
231 JSValue op2 = JSValue::decode(encodedOp2);
232
233 int32_t a = op1.toInt32(exec);
234 uint32_t b = op2.toUInt32(exec);
235 return JSValue::encode(jsNumber(a >> (b & 0x1f)));
236}
237
238EncodedJSValue JIT_OPERATION operationValueBitURShift(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
239{
240 VM* vm = &exec->vm();
241 NativeCallFrameTracer tracer(vm, exec);
242
243 JSValue op1 = JSValue::decode(encodedOp1);
244 JSValue op2 = JSValue::decode(encodedOp2);
245
246 uint32_t a = op1.toUInt32(exec);
247 uint32_t b = op2.toUInt32(exec);
248 return JSValue::encode(jsNumber(static_cast<int32_t>(a >> (b & 0x1f))));
249}
250
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000251EncodedJSValue JIT_OPERATION operationValueAdd(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
barraclough@apple.com2302c042011-03-14 23:31:00 +0000252{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000253 VM* vm = &exec->vm();
254 NativeCallFrameTracer tracer(vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +0000255
barraclough@apple.com2302c042011-03-14 23:31:00 +0000256 JSValue op1 = JSValue::decode(encodedOp1);
257 JSValue op2 = JSValue::decode(encodedOp2);
barraclough@apple.com2302c042011-03-14 23:31:00 +0000258
fpizlo@apple.com5c907042011-09-15 01:24:39 +0000259 return JSValue::encode(jsAdd(exec, op1, op2));
260}
261
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000262EncodedJSValue JIT_OPERATION operationValueAddNotNumber(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
fpizlo@apple.com5c907042011-09-15 01:24:39 +0000263{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000264 VM* vm = &exec->vm();
265 NativeCallFrameTracer tracer(vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +0000266
fpizlo@apple.com5c907042011-09-15 01:24:39 +0000267 JSValue op1 = JSValue::decode(encodedOp1);
268 JSValue op2 = JSValue::decode(encodedOp2);
269
fpizlo@apple.com5df0cd82011-08-19 00:18:49 +0000270 ASSERT(!op1.isNumber() || !op2.isNumber());
fpizlo@apple.com5c907042011-09-15 01:24:39 +0000271
ggaren@apple.com64be5e92012-01-24 07:34:10 +0000272 if (op1.isString() && !op2.isObject())
273 return JSValue::encode(jsString(exec, asString(op1), op2.toString(exec)));
barraclough@apple.com2302c042011-03-14 23:31:00 +0000274
275 return JSValue::encode(jsAddSlowCase(exec, op1, op2));
276}
277
mark.lam@apple.com224ce4d2015-12-08 21:44:12 +0000278EncodedJSValue JIT_OPERATION operationValueDiv(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
279{
280 VM* vm = &exec->vm();
281 NativeCallFrameTracer tracer(vm, exec);
282
283 JSValue op1 = JSValue::decode(encodedOp1);
284 JSValue op2 = JSValue::decode(encodedOp2);
285
286 double a = op1.toNumber(exec);
287 double b = op2.toNumber(exec);
288 return JSValue::encode(jsNumber(a / b));
289}
290
mark.lam@apple.com1d936142015-12-03 05:42:56 +0000291EncodedJSValue JIT_OPERATION operationValueMul(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
292{
293 VM* vm = &exec->vm();
294 NativeCallFrameTracer tracer(vm, exec);
295
296 JSValue op1 = JSValue::decode(encodedOp1);
297 JSValue op2 = JSValue::decode(encodedOp2);
298
299 double a = op1.toNumber(exec);
300 double b = op2.toNumber(exec);
301 return JSValue::encode(jsNumber(a * b));
302}
303
mark.lam@apple.com75249092015-10-16 23:26:14 +0000304EncodedJSValue JIT_OPERATION operationValueSub(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
305{
306 VM* vm = &exec->vm();
307 NativeCallFrameTracer tracer(vm, exec);
308
309 JSValue op1 = JSValue::decode(encodedOp1);
310 JSValue op2 = JSValue::decode(encodedOp2);
311
312 double a = op1.toNumber(exec);
313 double b = op2.toNumber(exec);
314 return JSValue::encode(jsNumber(a - b));
315}
316
akling@apple.com6d3d1812014-04-26 06:00:43 +0000317static ALWAYS_INLINE EncodedJSValue getByVal(ExecState* exec, JSCell* base, uint32_t index)
weinig@apple.coma96509f2011-06-15 21:57:17 +0000318{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000319 VM& vm = exec->vm();
320 NativeCallFrameTracer tracer(&vm, exec);
oliver@apple.com034a5e12012-05-01 21:34:53 +0000321
fpizlo@apple.comd8dd0532012-09-13 04:18:52 +0000322 if (base->isObject()) {
323 JSObject* object = asObject(base);
324 if (object->canGetIndexQuickly(index))
325 return JSValue::encode(object->getIndexQuickly(index));
326 }
weinig@apple.coma96509f2011-06-15 21:57:17 +0000327
mhahnenberg@apple.comc58d54d2011-12-16 19:06:44 +0000328 if (isJSString(base) && asString(base)->canGetIndex(index))
weinig@apple.coma96509f2011-06-15 21:57:17 +0000329 return JSValue::encode(asString(base)->getIndex(exec, index));
330
weinig@apple.coma96509f2011-06-15 21:57:17 +0000331 return JSValue::encode(JSValue(base).get(exec, index));
332}
333
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000334EncodedJSValue JIT_OPERATION operationGetByVal(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty)
barraclough@apple.com2302c042011-03-14 23:31:00 +0000335{
akling@apple.comb6d91ab2014-02-09 21:33:17 +0000336 VM& vm = exec->vm();
337 NativeCallFrameTracer tracer(&vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +0000338
barraclough@apple.com2302c042011-03-14 23:31:00 +0000339 JSValue baseValue = JSValue::decode(encodedBase);
340 JSValue property = JSValue::decode(encodedProperty);
341
342 if (LIKELY(baseValue.isCell())) {
343 JSCell* base = baseValue.asCell();
344
mhahnenberg@apple.com871ffe62013-03-15 21:52:35 +0000345 if (property.isUInt32()) {
weinig@apple.coma96509f2011-06-15 21:57:17 +0000346 return getByVal(exec, base, property.asUInt32());
mhahnenberg@apple.com871ffe62013-03-15 21:52:35 +0000347 } else if (property.isDouble()) {
weinig@apple.coma96509f2011-06-15 21:57:17 +0000348 double propertyAsDouble = property.asDouble();
349 uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
utatane.tea@gmail.com20b6e302015-04-07 07:26:08 +0000350 if (propertyAsUInt32 == propertyAsDouble && isIndex(propertyAsUInt32))
weinig@apple.coma96509f2011-06-15 21:57:17 +0000351 return getByVal(exec, base, propertyAsUInt32);
mhahnenberg@apple.com871ffe62013-03-15 21:52:35 +0000352 } else if (property.isString()) {
akling@apple.combaca5e82014-05-06 00:53:29 +0000353 Structure& structure = *base->structure(vm);
354 if (JSCell::canUseFastGetOwnProperty(structure)) {
utatane.tea@gmail.come0741fb2015-06-02 17:36:16 +0000355 if (RefPtr<AtomicStringImpl> existingAtomicString = asString(property)->toExistingAtomicString(exec)) {
356 if (JSValue result = base->fastGetOwnProperty(vm, structure, existingAtomicString.get()))
akling@apple.comcad89042014-09-02 22:29:59 +0000357 return JSValue::encode(result);
358 }
akling@apple.combaca5e82014-05-06 00:53:29 +0000359 }
mhahnenberg@apple.com871ffe62013-03-15 21:52:35 +0000360 }
barraclough@apple.com2302c042011-03-14 23:31:00 +0000361 }
mhahnenberg@apple.com871ffe62013-03-15 21:52:35 +0000362
utatane.tea@gmail.com9f61d132015-03-27 11:08:49 +0000363 baseValue.requireObjectCoercible(exec);
364 if (exec->hadException())
365 return JSValue::encode(jsUndefined());
utatane.tea@gmail.come16e15d2015-03-20 21:35:17 +0000366 auto propertyName = property.toPropertyKey(exec);
utatane.tea@gmail.com9f61d132015-03-27 11:08:49 +0000367 if (exec->hadException())
368 return JSValue::encode(jsUndefined());
utatane.tea@gmail.com947fa4e2015-01-31 01:23:56 +0000369 return JSValue::encode(baseValue.get(exec, propertyName));
barraclough@apple.com2302c042011-03-14 23:31:00 +0000370}
371
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000372EncodedJSValue JIT_OPERATION operationGetByValCell(ExecState* exec, JSCell* base, EncodedJSValue encodedProperty)
fpizlo@apple.comdc41f7f2011-10-09 20:07:36 +0000373{
akling@apple.comb6d91ab2014-02-09 21:33:17 +0000374 VM& vm = exec->vm();
375 NativeCallFrameTracer tracer(&vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +0000376
fpizlo@apple.comdc41f7f2011-10-09 20:07:36 +0000377 JSValue property = JSValue::decode(encodedProperty);
378
379 if (property.isUInt32())
380 return getByVal(exec, base, property.asUInt32());
mhahnenberg@apple.com871ffe62013-03-15 21:52:35 +0000381 if (property.isDouble()) {
fpizlo@apple.comdc41f7f2011-10-09 20:07:36 +0000382 double propertyAsDouble = property.asDouble();
383 uint32_t propertyAsUInt32 = static_cast<uint32_t>(propertyAsDouble);
384 if (propertyAsUInt32 == propertyAsDouble)
385 return getByVal(exec, base, propertyAsUInt32);
mhahnenberg@apple.com871ffe62013-03-15 21:52:35 +0000386 } else if (property.isString()) {
akling@apple.combaca5e82014-05-06 00:53:29 +0000387 Structure& structure = *base->structure(vm);
388 if (JSCell::canUseFastGetOwnProperty(structure)) {
utatane.tea@gmail.come0741fb2015-06-02 17:36:16 +0000389 if (RefPtr<AtomicStringImpl> existingAtomicString = asString(property)->toExistingAtomicString(exec)) {
390 if (JSValue result = base->fastGetOwnProperty(vm, structure, existingAtomicString.get()))
akling@apple.comcad89042014-09-02 22:29:59 +0000391 return JSValue::encode(result);
392 }
akling@apple.combaca5e82014-05-06 00:53:29 +0000393 }
mhahnenberg@apple.com871ffe62013-03-15 21:52:35 +0000394 }
fpizlo@apple.comdc41f7f2011-10-09 20:07:36 +0000395
utatane.tea@gmail.come16e15d2015-03-20 21:35:17 +0000396 auto propertyName = property.toPropertyKey(exec);
utatane.tea@gmail.com9f61d132015-03-27 11:08:49 +0000397 if (exec->hadException())
398 return JSValue::encode(jsUndefined());
utatane.tea@gmail.com947fa4e2015-01-31 01:23:56 +0000399 return JSValue::encode(JSValue(base).get(exec, propertyName));
fpizlo@apple.comdc41f7f2011-10-09 20:07:36 +0000400}
401
oliver@apple.com211b3be2013-07-25 04:03:39 +0000402ALWAYS_INLINE EncodedJSValue getByValCellInt(ExecState* exec, JSCell* base, int32_t index)
fpizlo@apple.comfa34ff82012-09-05 01:27:50 +0000403{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000404 VM* vm = &exec->vm();
405 NativeCallFrameTracer tracer(vm, exec);
fpizlo@apple.comfa34ff82012-09-05 01:27:50 +0000406
407 if (index < 0) {
408 // Go the slowest way possible becase negative indices don't use indexed storage.
409 return JSValue::encode(JSValue(base).get(exec, Identifier::from(exec, index)));
410 }
411
412 // Use this since we know that the value is out of bounds.
413 return JSValue::encode(JSValue(base).get(exec, index));
414}
415
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000416EncodedJSValue JIT_OPERATION operationGetByValArrayInt(ExecState* exec, JSArray* base, int32_t index)
oliver@apple.com211b3be2013-07-25 04:03:39 +0000417{
418 return getByValCellInt(exec, base, index);
419}
420
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000421EncodedJSValue JIT_OPERATION operationGetByValStringInt(ExecState* exec, JSString* base, int32_t index)
oliver@apple.com211b3be2013-07-25 04:03:39 +0000422{
423 return getByValCellInt(exec, base, index);
424}
425
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000426void JIT_OPERATION operationPutByValStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
barraclough@apple.com2302c042011-03-14 23:31:00 +0000427{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000428 VM* vm = &exec->vm();
429 NativeCallFrameTracer tracer(vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +0000430
oliver@apple.come050d642013-10-19 00:09:28 +0000431 operationPutByValInternal<true, false>(exec, encodedBase, encodedProperty, encodedValue);
barraclough@apple.com2302c042011-03-14 23:31:00 +0000432}
433
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000434void JIT_OPERATION operationPutByValNonStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
barraclough@apple.com2302c042011-03-14 23:31:00 +0000435{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000436 VM* vm = &exec->vm();
437 NativeCallFrameTracer tracer(vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +0000438
oliver@apple.come050d642013-10-19 00:09:28 +0000439 operationPutByValInternal<false, false>(exec, encodedBase, encodedProperty, encodedValue);
barraclough@apple.com2302c042011-03-14 23:31:00 +0000440}
441
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000442void JIT_OPERATION operationPutByValCellStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
fpizlo@apple.comdc41f7f2011-10-09 20:07:36 +0000443{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000444 VM* vm = &exec->vm();
445 NativeCallFrameTracer tracer(vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +0000446
oliver@apple.come050d642013-10-19 00:09:28 +0000447 operationPutByValInternal<true, false>(exec, JSValue::encode(cell), encodedProperty, encodedValue);
fpizlo@apple.comdc41f7f2011-10-09 20:07:36 +0000448}
449
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000450void JIT_OPERATION operationPutByValCellNonStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
fpizlo@apple.comdc41f7f2011-10-09 20:07:36 +0000451{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000452 VM* vm = &exec->vm();
453 NativeCallFrameTracer tracer(vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +0000454
oliver@apple.come050d642013-10-19 00:09:28 +0000455 operationPutByValInternal<false, false>(exec, JSValue::encode(cell), encodedProperty, encodedValue);
fpizlo@apple.comdc41f7f2011-10-09 20:07:36 +0000456}
457
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000458void JIT_OPERATION operationPutByValBeyondArrayBoundsStrict(ExecState* exec, JSObject* array, int32_t index, EncodedJSValue encodedValue)
barraclough@apple.come2130ff2011-06-07 23:03:32 +0000459{
mhahnenberg@apple.comb6f85192014-02-27 01:27:18 +0000460 VM& vm = exec->vm();
461 NativeCallFrameTracer tracer(&vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +0000462
fpizlo@apple.com73fbdf62012-05-18 01:34:01 +0000463 if (index >= 0) {
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +0000464 array->putByIndexInline(exec, index, JSValue::decode(encodedValue), true);
fpizlo@apple.com73fbdf62012-05-18 01:34:01 +0000465 return;
466 }
467
oliver@apple.com68848412014-01-02 20:56:20 +0000468 PutPropertySlot slot(array, true);
fpizlo@apple.com73fbdf62012-05-18 01:34:01 +0000469 array->methodTable()->put(
470 array, exec, Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
barraclough@apple.comb1db28d82012-03-06 07:23:21 +0000471}
472
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000473void JIT_OPERATION operationPutByValBeyondArrayBoundsNonStrict(ExecState* exec, JSObject* array, int32_t index, EncodedJSValue encodedValue)
barraclough@apple.comb1db28d82012-03-06 07:23:21 +0000474{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000475 VM* vm = &exec->vm();
476 NativeCallFrameTracer tracer(vm, exec);
barraclough@apple.comb1db28d82012-03-06 07:23:21 +0000477
fpizlo@apple.com73fbdf62012-05-18 01:34:01 +0000478 if (index >= 0) {
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +0000479 array->putByIndexInline(exec, index, JSValue::decode(encodedValue), false);
fpizlo@apple.com73fbdf62012-05-18 01:34:01 +0000480 return;
481 }
482
oliver@apple.com68848412014-01-02 20:56:20 +0000483 PutPropertySlot slot(array, false);
fpizlo@apple.com73fbdf62012-05-18 01:34:01 +0000484 array->methodTable()->put(
485 array, exec, Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
barraclough@apple.come2130ff2011-06-07 23:03:32 +0000486}
487
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000488void JIT_OPERATION operationPutDoubleByValBeyondArrayBoundsStrict(ExecState* exec, JSObject* array, int32_t index, double value)
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000489{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000490 VM* vm = &exec->vm();
491 NativeCallFrameTracer tracer(vm, exec);
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000492
493 JSValue jsValue = JSValue(JSValue::EncodeAsDouble, value);
494
495 if (index >= 0) {
496 array->putByIndexInline(exec, index, jsValue, true);
497 return;
498 }
499
oliver@apple.com68848412014-01-02 20:56:20 +0000500 PutPropertySlot slot(array, true);
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000501 array->methodTable()->put(
502 array, exec, Identifier::from(exec, index), jsValue, slot);
503}
504
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000505void JIT_OPERATION operationPutDoubleByValBeyondArrayBoundsNonStrict(ExecState* exec, JSObject* array, int32_t index, double value)
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000506{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000507 VM* vm = &exec->vm();
508 NativeCallFrameTracer tracer(vm, exec);
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000509
510 JSValue jsValue = JSValue(JSValue::EncodeAsDouble, value);
511
512 if (index >= 0) {
513 array->putByIndexInline(exec, index, jsValue, false);
514 return;
515 }
516
oliver@apple.com68848412014-01-02 20:56:20 +0000517 PutPropertySlot slot(array, false);
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000518 array->methodTable()->put(
519 array, exec, Identifier::from(exec, index), jsValue, slot);
520}
521
oliver@apple.come050d642013-10-19 00:09:28 +0000522void JIT_OPERATION operationPutByValDirectStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
523{
524 VM* vm = &exec->vm();
525 NativeCallFrameTracer tracer(vm, exec);
526
527 operationPutByValInternal<true, true>(exec, encodedBase, encodedProperty, encodedValue);
528}
529
530void JIT_OPERATION operationPutByValDirectNonStrict(ExecState* exec, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
531{
532 VM* vm = &exec->vm();
533 NativeCallFrameTracer tracer(vm, exec);
534
535 operationPutByValInternal<false, true>(exec, encodedBase, encodedProperty, encodedValue);
536}
537
538void JIT_OPERATION operationPutByValDirectCellStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
539{
540 VM* vm = &exec->vm();
541 NativeCallFrameTracer tracer(vm, exec);
542
543 operationPutByValInternal<true, true>(exec, JSValue::encode(cell), encodedProperty, encodedValue);
544}
545
546void JIT_OPERATION operationPutByValDirectCellNonStrict(ExecState* exec, JSCell* cell, EncodedJSValue encodedProperty, EncodedJSValue encodedValue)
547{
548 VM* vm = &exec->vm();
549 NativeCallFrameTracer tracer(vm, exec);
550
551 operationPutByValInternal<false, true>(exec, JSValue::encode(cell), encodedProperty, encodedValue);
552}
553
554void JIT_OPERATION operationPutByValDirectBeyondArrayBoundsStrict(ExecState* exec, JSObject* array, int32_t index, EncodedJSValue encodedValue)
555{
556 VM* vm = &exec->vm();
557 NativeCallFrameTracer tracer(vm, exec);
558 if (index >= 0) {
559 array->putDirectIndex(exec, index, JSValue::decode(encodedValue), 0, PutDirectIndexShouldThrow);
560 return;
561 }
562
oliver@apple.com68848412014-01-02 20:56:20 +0000563 PutPropertySlot slot(array, true);
oliver@apple.come050d642013-10-19 00:09:28 +0000564 array->putDirect(exec->vm(), Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
565}
566
567void JIT_OPERATION operationPutByValDirectBeyondArrayBoundsNonStrict(ExecState* exec, JSObject* array, int32_t index, EncodedJSValue encodedValue)
568{
569 VM* vm = &exec->vm();
570 NativeCallFrameTracer tracer(vm, exec);
571
572 if (index >= 0) {
573 array->putDirectIndex(exec, index, JSValue::decode(encodedValue));
574 return;
575 }
576
oliver@apple.com68848412014-01-02 20:56:20 +0000577 PutPropertySlot slot(array, false);
oliver@apple.come050d642013-10-19 00:09:28 +0000578 array->putDirect(exec->vm(), Identifier::from(exec, index), JSValue::decode(encodedValue), slot);
579}
580
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000581EncodedJSValue JIT_OPERATION operationArrayPush(ExecState* exec, EncodedJSValue encodedValue, JSArray* array)
fpizlo@apple.com24d24e52011-10-04 02:55:54 +0000582{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000583 VM* vm = &exec->vm();
584 NativeCallFrameTracer tracer(vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +0000585
fpizlo@apple.com24d24e52011-10-04 02:55:54 +0000586 array->push(exec, JSValue::decode(encodedValue));
587 return JSValue::encode(jsNumber(array->length()));
588}
barraclough@apple.com077fdd42012-03-18 01:08:16 +0000589
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000590EncodedJSValue JIT_OPERATION operationArrayPushDouble(ExecState* exec, double value, JSArray* array)
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000591{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000592 VM* vm = &exec->vm();
593 NativeCallFrameTracer tracer(vm, exec);
fpizlo@apple.com75c91a72012-11-08 22:28:25 +0000594
595 array->push(exec, JSValue(JSValue::EncodeAsDouble, value));
596 return JSValue::encode(jsNumber(array->length()));
597}
598
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000599EncodedJSValue JIT_OPERATION operationArrayPop(ExecState* exec, JSArray* array)
fpizlo@apple.com04c19742012-08-26 22:35:26 +0000600{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000601 VM* vm = &exec->vm();
602 NativeCallFrameTracer tracer(vm, exec);
fpizlo@apple.com04c19742012-08-26 22:35:26 +0000603
604 return JSValue::encode(array->pop(exec));
605}
606
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000607EncodedJSValue JIT_OPERATION operationArrayPopAndRecoverLength(ExecState* exec, JSArray* array)
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +0000608{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000609 VM* vm = &exec->vm();
610 NativeCallFrameTracer tracer(vm, exec);
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +0000611
612 array->butterfly()->setPublicLength(array->butterfly()->publicLength() + 1);
613
614 return JSValue::encode(array->pop(exec));
615}
616
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000617EncodedJSValue JIT_OPERATION operationRegExpExec(ExecState* exec, JSCell* base, JSCell* argument)
barraclough@apple.com077fdd42012-03-18 01:08:16 +0000618{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000619 VM& vm = exec->vm();
620 NativeCallFrameTracer tracer(&vm, exec);
oliver@apple.com034a5e12012-05-01 21:34:53 +0000621
fpizlo@apple.com10ae2d02013-08-14 02:41:47 +0000622 if (!base->inherits(RegExpObject::info()))
barraclough@apple.com077fdd42012-03-18 01:08:16 +0000623 return throwVMTypeError(exec);
624
625 ASSERT(argument->isString() || argument->isObject());
626 JSString* input = argument->isString() ? asString(argument) : asObject(argument)->toString(exec);
627 return JSValue::encode(asRegExpObject(base)->exec(exec, input));
628}
629
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000630size_t JIT_OPERATION operationRegExpTest(ExecState* exec, JSCell* base, JSCell* argument)
barraclough@apple.com077fdd42012-03-18 01:08:16 +0000631{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000632 VM& vm = exec->vm();
633 NativeCallFrameTracer tracer(&vm, exec);
oliver@apple.com034a5e12012-05-01 21:34:53 +0000634
fpizlo@apple.com10ae2d02013-08-14 02:41:47 +0000635 if (!base->inherits(RegExpObject::info())) {
barraclough@apple.com077fdd42012-03-18 01:08:16 +0000636 throwTypeError(exec);
637 return false;
638 }
639
640 ASSERT(argument->isString() || argument->isObject());
641 JSString* input = argument->isString() ? asString(argument) : asObject(argument)->toString(exec);
barraclough@apple.com9db2c542012-03-21 20:55:41 +0000642 return asRegExpObject(base)->test(exec, input);
barraclough@apple.com077fdd42012-03-18 01:08:16 +0000643}
fpizlo@apple.comee10e452013-04-09 00:10:16 +0000644
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000645size_t JIT_OPERATION operationCompareStrictEqCell(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
commit-queue@webkit.org6efa2ca2011-07-19 00:36:37 +0000646{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000647 VM* vm = &exec->vm();
648 NativeCallFrameTracer tracer(vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +0000649
commit-queue@webkit.org6efa2ca2011-07-19 00:36:37 +0000650 JSValue op1 = JSValue::decode(encodedOp1);
651 JSValue op2 = JSValue::decode(encodedOp2);
652
653 ASSERT(op1.isCell());
654 ASSERT(op2.isCell());
655
656 return JSValue::strictEqualSlowCaseInline(exec, op1, op2);
657}
658
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000659size_t JIT_OPERATION operationCompareStrictEq(ExecState* exec, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2)
barraclough@apple.com848a0cc2011-04-08 20:33:24 +0000660{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000661 VM* vm = &exec->vm();
662 NativeCallFrameTracer tracer(vm, exec);
fpizlo@apple.com82acbbf2012-02-28 00:37:58 +0000663
664 JSValue src1 = JSValue::decode(encodedOp1);
665 JSValue src2 = JSValue::decode(encodedOp2);
oliver@apple.come07a4592012-01-25 19:43:06 +0000666
fpizlo@apple.com82acbbf2012-02-28 00:37:58 +0000667 return JSValue::strictEqual(exec, src1, src2);
barraclough@apple.com848a0cc2011-04-08 20:33:24 +0000668}
669
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000670EncodedJSValue JIT_OPERATION operationToPrimitive(ExecState* exec, EncodedJSValue value)
fpizlo@apple.com90e5f0e2011-09-22 22:42:54 +0000671{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000672 VM* vm = &exec->vm();
673 NativeCallFrameTracer tracer(vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +0000674
fpizlo@apple.com90e5f0e2011-09-22 22:42:54 +0000675 return JSValue::encode(JSValue::decode(value).toPrimitive(exec));
676}
677
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000678char* JIT_OPERATION operationNewArray(ExecState* exec, Structure* arrayStructure, void* buffer, size_t size)
fpizlo@apple.com98a693c2011-09-28 05:33:21 +0000679{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000680 VM* vm = &exec->vm();
681 NativeCallFrameTracer tracer(vm, exec);
fpizlo@apple.com1bc68482012-10-13 03:56:09 +0000682
fpizlo@apple.com59d1ddb2013-11-05 00:05:02 +0000683 return bitwise_cast<char*>(constructArray(exec, arrayStructure, static_cast<JSValue*>(buffer), size));
fpizlo@apple.com6c89cd32012-06-26 19:42:05 +0000684}
685
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000686char* JIT_OPERATION operationNewEmptyArray(ExecState* exec, Structure* arrayStructure)
fpizlo@apple.com6c89cd32012-06-26 19:42:05 +0000687{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000688 VM* vm = &exec->vm();
689 NativeCallFrameTracer tracer(vm, exec);
fpizlo@apple.com1bc68482012-10-13 03:56:09 +0000690
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000691 return bitwise_cast<char*>(JSArray::create(*vm, arrayStructure));
fpizlo@apple.com6c89cd32012-06-26 19:42:05 +0000692}
693
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000694char* JIT_OPERATION operationNewArrayWithSize(ExecState* exec, Structure* arrayStructure, int32_t size)
fpizlo@apple.com6c89cd32012-06-26 19:42:05 +0000695{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000696 VM* vm = &exec->vm();
697 NativeCallFrameTracer tracer(vm, exec);
msaboff@apple.com51d65f22013-04-10 20:01:14 +0000698
msaboff@apple.com6ebf3b82013-04-11 16:19:35 +0000699 if (UNLIKELY(size < 0))
commit-queue@webkit.org3f922f92013-08-29 00:28:42 +0000700 return bitwise_cast<char*>(exec->vm().throwException(exec, createRangeError(exec, ASCIILiteral("Array size is not a small enough positive integer."))));
msaboff@apple.com51d65f22013-04-10 20:01:14 +0000701
fpizlo@apple.com8dde06b2015-10-12 22:41:01 +0000702 JSArray* result = JSArray::create(*vm, arrayStructure, size);
703 result->butterfly(); // Ensure that the backing store is in to-space.
704 return bitwise_cast<char*>(result);
fpizlo@apple.com98a693c2011-09-28 05:33:21 +0000705}
706
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000707char* JIT_OPERATION operationNewArrayBuffer(ExecState* exec, Structure* arrayStructure, size_t start, size_t size)
fpizlo@apple.com98a693c2011-09-28 05:33:21 +0000708{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000709 VM& vm = exec->vm();
710 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.com59d1ddb2013-11-05 00:05:02 +0000711 return bitwise_cast<char*>(constructArray(exec, arrayStructure, exec->codeBlock()->constantBuffer(start), size));
fpizlo@apple.com98a693c2011-09-28 05:33:21 +0000712}
713
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000714char* JIT_OPERATION operationNewInt8ArrayWithSize(
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000715 ExecState* exec, Structure* structure, int32_t length)
716{
717 return newTypedArrayWithSize<JSInt8Array>(exec, structure, length);
718}
719
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000720char* JIT_OPERATION operationNewInt8ArrayWithOneArgument(
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000721 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
722{
keith_miller@apple.coma646a262015-10-16 21:40:21 +0000723 return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSInt8Array>(exec, structure, encodedValue, 0, Nullopt));
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000724}
725
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000726char* JIT_OPERATION operationNewInt16ArrayWithSize(
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000727 ExecState* exec, Structure* structure, int32_t length)
728{
729 return newTypedArrayWithSize<JSInt16Array>(exec, structure, length);
730}
731
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000732char* JIT_OPERATION operationNewInt16ArrayWithOneArgument(
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000733 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
734{
keith_miller@apple.coma646a262015-10-16 21:40:21 +0000735 return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSInt16Array>(exec, structure, encodedValue, 0, Nullopt));
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000736}
737
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000738char* JIT_OPERATION operationNewInt32ArrayWithSize(
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000739 ExecState* exec, Structure* structure, int32_t length)
740{
741 return newTypedArrayWithSize<JSInt32Array>(exec, structure, length);
742}
743
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000744char* JIT_OPERATION operationNewInt32ArrayWithOneArgument(
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000745 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
746{
keith_miller@apple.coma646a262015-10-16 21:40:21 +0000747 return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSInt32Array>(exec, structure, encodedValue, 0, Nullopt));
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000748}
749
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000750char* JIT_OPERATION operationNewUint8ArrayWithSize(
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000751 ExecState* exec, Structure* structure, int32_t length)
752{
753 return newTypedArrayWithSize<JSUint8Array>(exec, structure, length);
754}
755
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000756char* JIT_OPERATION operationNewUint8ArrayWithOneArgument(
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000757 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
758{
keith_miller@apple.coma646a262015-10-16 21:40:21 +0000759 return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSUint8Array>(exec, structure, encodedValue, 0, Nullopt));
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000760}
761
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000762char* JIT_OPERATION operationNewUint8ClampedArrayWithSize(
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000763 ExecState* exec, Structure* structure, int32_t length)
764{
765 return newTypedArrayWithSize<JSUint8ClampedArray>(exec, structure, length);
766}
767
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000768char* JIT_OPERATION operationNewUint8ClampedArrayWithOneArgument(
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000769 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
770{
keith_miller@apple.coma646a262015-10-16 21:40:21 +0000771 return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSUint8ClampedArray>(exec, structure, encodedValue, 0, Nullopt));
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000772}
773
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000774char* JIT_OPERATION operationNewUint16ArrayWithSize(
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000775 ExecState* exec, Structure* structure, int32_t length)
776{
777 return newTypedArrayWithSize<JSUint16Array>(exec, structure, length);
778}
779
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000780char* JIT_OPERATION operationNewUint16ArrayWithOneArgument(
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000781 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
782{
keith_miller@apple.coma646a262015-10-16 21:40:21 +0000783 return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSUint16Array>(exec, structure, encodedValue, 0, Nullopt));
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000784}
785
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000786char* JIT_OPERATION operationNewUint32ArrayWithSize(
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000787 ExecState* exec, Structure* structure, int32_t length)
788{
789 return newTypedArrayWithSize<JSUint32Array>(exec, structure, length);
790}
791
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000792char* JIT_OPERATION operationNewUint32ArrayWithOneArgument(
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000793 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
794{
keith_miller@apple.coma646a262015-10-16 21:40:21 +0000795 return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSUint32Array>(exec, structure, encodedValue, 0, Nullopt));
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000796}
797
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000798char* JIT_OPERATION operationNewFloat32ArrayWithSize(
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000799 ExecState* exec, Structure* structure, int32_t length)
800{
801 return newTypedArrayWithSize<JSFloat32Array>(exec, structure, length);
802}
803
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000804char* JIT_OPERATION operationNewFloat32ArrayWithOneArgument(
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000805 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
806{
keith_miller@apple.coma646a262015-10-16 21:40:21 +0000807 return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSFloat32Array>(exec, structure, encodedValue, 0, Nullopt));
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000808}
809
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000810char* JIT_OPERATION operationNewFloat64ArrayWithSize(
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000811 ExecState* exec, Structure* structure, int32_t length)
812{
813 return newTypedArrayWithSize<JSFloat64Array>(exec, structure, length);
814}
815
mark.lam@apple.com9df8b832013-09-26 20:27:14 +0000816char* JIT_OPERATION operationNewFloat64ArrayWithOneArgument(
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000817 ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
818{
keith_miller@apple.coma646a262015-10-16 21:40:21 +0000819 return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSFloat64Array>(exec, structure, encodedValue, 0, Nullopt));
fpizlo@apple.com372fa822013-08-21 19:43:47 +0000820}
821
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +0000822JSCell* JIT_OPERATION operationCreateActivationDirect(ExecState* exec, Structure* structure, JSScope* scope, SymbolTable* table, EncodedJSValue initialValueEncoded)
fpizlo@apple.comc6446112012-05-23 20:52:42 +0000823{
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +0000824 JSValue initialValue = JSValue::decode(initialValueEncoded);
825 ASSERT(initialValue == jsUndefined() || initialValue == jsTDZValue());
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000826 VM& vm = exec->vm();
827 NativeCallFrameTracer tracer(&vm, exec);
saambarati1@gmail.com144f17c2015-07-15 21:41:08 +0000828 return JSLexicalEnvironment::create(vm, structure, scope, table, initialValue);
fpizlo@apple.comda834ae2015-03-26 04:28:43 +0000829}
830
831JSCell* JIT_OPERATION operationCreateDirectArguments(ExecState* exec, Structure* structure, int32_t length, int32_t minCapacity)
832{
833 VM& vm = exec->vm();
834 NativeCallFrameTracer target(&vm, exec);
835 DirectArguments* result = DirectArguments::create(
836 vm, structure, length, std::max(length, minCapacity));
837 // The caller will store to this object without barriers. Most likely, at this point, this is
838 // still a young object and so no barriers are needed. But it's good to be careful anyway,
839 // since the GC should be allowed to do crazy (like pretenuring, for example).
840 vm.heap.writeBarrier(result);
fpizlo@apple.com9a548f12012-05-24 05:33:09 +0000841 return result;
fpizlo@apple.comc6446112012-05-23 20:52:42 +0000842}
843
fpizlo@apple.comda834ae2015-03-26 04:28:43 +0000844JSCell* JIT_OPERATION operationCreateScopedArguments(ExecState* exec, Structure* structure, Register* argumentStart, int32_t length, JSFunction* callee, JSLexicalEnvironment* scope)
fpizlo@apple.com6d4456e2012-05-23 03:48:52 +0000845{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000846 VM& vm = exec->vm();
fpizlo@apple.comda834ae2015-03-26 04:28:43 +0000847 NativeCallFrameTracer target(&vm, exec);
fpizlo@apple.comd5547492012-06-07 00:23:36 +0000848
fpizlo@apple.comda834ae2015-03-26 04:28:43 +0000849 // We could pass the ScopedArgumentsTable* as an argument. We currently don't because I
850 // didn't feel like changing the max number of arguments for a slow path call from 6 to 7.
851 ScopedArgumentsTable* table = scope->symbolTable()->arguments();
fpizlo@apple.comd5547492012-06-07 00:23:36 +0000852
fpizlo@apple.comda834ae2015-03-26 04:28:43 +0000853 return ScopedArguments::createByCopyingFrom(
854 vm, structure, argumentStart, length, callee, table, scope);
fpizlo@apple.comd5547492012-06-07 00:23:36 +0000855}
856
fpizlo@apple.comda834ae2015-03-26 04:28:43 +0000857JSCell* JIT_OPERATION operationCreateClonedArguments(ExecState* exec, Structure* structure, Register* argumentStart, int32_t length, JSFunction* callee)
fpizlo@apple.comd5547492012-06-07 00:23:36 +0000858{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000859 VM& vm = exec->vm();
fpizlo@apple.comda834ae2015-03-26 04:28:43 +0000860 NativeCallFrameTracer target(&vm, exec);
861 return ClonedArguments::createByCopyingFrom(
862 exec, structure, argumentStart, length, callee);
fpizlo@apple.com6d4456e2012-05-23 03:48:52 +0000863}
864
fpizlo@apple.comda834ae2015-03-26 04:28:43 +0000865JSCell* JIT_OPERATION operationCreateDirectArgumentsDuringExit(ExecState* exec, InlineCallFrame* inlineCallFrame, JSFunction* callee, int32_t argumentCount)
fpizlo@apple.com17da7f32012-02-25 23:05:38 +0000866{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000867 VM& vm = exec->vm();
fpizlo@apple.comda834ae2015-03-26 04:28:43 +0000868 NativeCallFrameTracer target(&vm, exec);
869
870 DeferGCForAWhile deferGC(vm.heap);
871
872 CodeBlock* codeBlock;
873 if (inlineCallFrame)
874 codeBlock = baselineCodeBlockForInlineCallFrame(inlineCallFrame);
875 else
876 codeBlock = exec->codeBlock();
877
878 unsigned length = argumentCount - 1;
879 unsigned capacity = std::max(length, static_cast<unsigned>(codeBlock->numParameters() - 1));
880 DirectArguments* result = DirectArguments::create(
881 vm, codeBlock->globalObject()->directArgumentsStructure(), length, capacity);
882
883 result->callee().set(vm, result, callee);
884
885 Register* arguments =
886 exec->registers() + (inlineCallFrame ? inlineCallFrame->stackOffset : 0) +
887 CallFrame::argumentOffset(0);
888 for (unsigned i = length; i--;)
889 result->setIndexQuickly(vm, i, arguments[i].jsValue());
890
891 return result;
892}
893
894JSCell* JIT_OPERATION operationCreateClonedArgumentsDuringExit(ExecState* exec, InlineCallFrame* inlineCallFrame, JSFunction* callee, int32_t argumentCount)
895{
896 VM& vm = exec->vm();
897 NativeCallFrameTracer target(&vm, exec);
898
899 DeferGCForAWhile deferGC(vm.heap);
900
901 CodeBlock* codeBlock;
902 if (inlineCallFrame)
903 codeBlock = baselineCodeBlockForInlineCallFrame(inlineCallFrame);
904 else
905 codeBlock = exec->codeBlock();
906
907 unsigned length = argumentCount - 1;
908 ClonedArguments* result = ClonedArguments::createEmpty(
909 vm, codeBlock->globalObject()->outOfBandArgumentsStructure(), callee);
910
911 Register* arguments =
912 exec->registers() + (inlineCallFrame ? inlineCallFrame->stackOffset : 0) +
913 CallFrame::argumentOffset(0);
914 for (unsigned i = length; i--;)
915 result->putDirectIndex(exec, i, arguments[i].jsValue());
916
917 result->putDirect(vm, vm.propertyNames->length, jsNumber(length));
918
919 return result;
fpizlo@apple.com17da7f32012-02-25 23:05:38 +0000920}
921
sbarati@apple.com855d5602015-11-30 20:36:54 +0000922void JIT_OPERATION operationCopyRest(ExecState* exec, JSCell* arrayAsCell, Register* argumentStart, unsigned numberOfParamsToSkip, unsigned arraySize)
sbarati@apple.comc0722da2015-11-20 02:37:47 +0000923{
sbarati@apple.com855d5602015-11-30 20:36:54 +0000924 ASSERT(arraySize);
sbarati@apple.comc0722da2015-11-20 02:37:47 +0000925 JSArray* array = jsCast<JSArray*>(arrayAsCell);
sbarati@apple.com855d5602015-11-30 20:36:54 +0000926 ASSERT(arraySize == array->length());
sbarati@apple.comc0722da2015-11-20 02:37:47 +0000927 array->setLength(exec, arraySize);
928 for (unsigned i = 0; i < arraySize; i++)
929 array->putDirectIndex(exec, i, argumentStart[i + numberOfParamsToSkip].jsValue());
930}
931
fpizlo@apple.comb8823d52015-05-03 00:15:27 +0000932size_t JIT_OPERATION operationObjectIsObject(ExecState* exec, JSGlobalObject* globalObject, JSCell* object)
oliver@apple.come722ad02013-01-09 02:37:29 +0000933{
mark.lam@apple.com87a5b6f2014-02-05 04:22:43 +0000934 VM& vm = exec->vm();
935 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.comb8823d52015-05-03 00:15:27 +0000936
937 ASSERT(jsDynamicCast<JSObject*>(object));
938
939 if (object->structure(vm)->masqueradesAsUndefined(globalObject))
940 return false;
941 if (object->type() == JSFunctionType)
942 return false;
943 if (object->inlineTypeFlags() & TypeOfShouldCallGetCallData) {
944 CallData callData;
945 if (object->methodTable(vm)->getCallData(object, callData) != CallTypeNone)
946 return false;
947 }
948
949 return true;
950}
951
952size_t JIT_OPERATION operationObjectIsFunction(ExecState* exec, JSGlobalObject* globalObject, JSCell* object)
953{
954 VM& vm = exec->vm();
955 NativeCallFrameTracer tracer(&vm, exec);
956
957 ASSERT(jsDynamicCast<JSObject*>(object));
958
959 if (object->structure(vm)->masqueradesAsUndefined(globalObject))
960 return false;
961 if (object->type() == JSFunctionType)
962 return true;
963 if (object->inlineTypeFlags() & TypeOfShouldCallGetCallData) {
964 CallData callData;
965 if (object->methodTable(vm)->getCallData(object, callData) != CallTypeNone)
966 return true;
967 }
968
969 return false;
970}
971
972JSCell* JIT_OPERATION operationTypeOfObject(ExecState* exec, JSGlobalObject* globalObject, JSCell* object)
973{
974 VM& vm = exec->vm();
975 NativeCallFrameTracer tracer(&vm, exec);
976
977 ASSERT(jsDynamicCast<JSObject*>(object));
978
979 if (object->structure(vm)->masqueradesAsUndefined(globalObject))
980 return vm.smallStrings.undefinedString();
981 if (object->type() == JSFunctionType)
982 return vm.smallStrings.functionString();
983 if (object->inlineTypeFlags() & TypeOfShouldCallGetCallData) {
984 CallData callData;
985 if (object->methodTable(vm)->getCallData(object, callData) != CallTypeNone)
986 return vm.smallStrings.functionString();
987 }
988
989 return vm.smallStrings.objectString();
990}
991
992int32_t JIT_OPERATION operationTypeOfObjectAsTypeofType(ExecState* exec, JSGlobalObject* globalObject, JSCell* object)
993{
994 VM& vm = exec->vm();
995 NativeCallFrameTracer tracer(&vm, exec);
996
997 ASSERT(jsDynamicCast<JSObject*>(object));
998
999 if (object->structure(vm)->masqueradesAsUndefined(globalObject))
1000 return static_cast<int32_t>(TypeofType::Undefined);
1001 if (object->type() == JSFunctionType)
1002 return static_cast<int32_t>(TypeofType::Function);
1003 if (object->inlineTypeFlags() & TypeOfShouldCallGetCallData) {
1004 CallData callData;
1005 if (object->methodTable(vm)->getCallData(object, callData) != CallTypeNone)
1006 return static_cast<int32_t>(TypeofType::Function);
1007 }
1008
1009 return static_cast<int32_t>(TypeofType::Object);
oliver@apple.come722ad02013-01-09 02:37:29 +00001010}
1011
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001012char* JIT_OPERATION operationAllocatePropertyStorageWithInitialCapacity(ExecState* exec)
fpizlo@apple.com1ffdcff2012-07-19 00:30:34 +00001013{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001014 VM& vm = exec->vm();
1015 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.comc17054c2012-09-18 15:22:29 +00001016
fpizlo@apple.comd8dd0532012-09-13 04:18:52 +00001017 return reinterpret_cast<char*>(
oliver@apple.coma03796a2013-07-25 04:01:20 +00001018 Butterfly::createUninitialized(vm, 0, 0, initialOutOfLineCapacity, false, 0));
fpizlo@apple.com1ffdcff2012-07-19 00:30:34 +00001019}
1020
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001021char* JIT_OPERATION operationAllocatePropertyStorage(ExecState* exec, size_t newSize)
fpizlo@apple.com1ffdcff2012-07-19 00:30:34 +00001022{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001023 VM& vm = exec->vm();
1024 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.comc17054c2012-09-18 15:22:29 +00001025
fpizlo@apple.comd8dd0532012-09-13 04:18:52 +00001026 return reinterpret_cast<char*>(
oliver@apple.coma03796a2013-07-25 04:01:20 +00001027 Butterfly::createUninitialized(vm, 0, 0, newSize, false, 0));
fpizlo@apple.comd8dd0532012-09-13 04:18:52 +00001028}
1029
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001030char* JIT_OPERATION operationReallocateButterflyToHavePropertyStorageWithInitialCapacity(ExecState* exec, JSObject* object)
fpizlo@apple.comd8dd0532012-09-13 04:18:52 +00001031{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001032 VM& vm = exec->vm();
1033 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.comc17054c2012-09-18 15:22:29 +00001034
fpizlo@apple.comd8dd0532012-09-13 04:18:52 +00001035 ASSERT(!object->structure()->outOfLineCapacity());
mhahnenberg@apple.com3ddd7ac2014-01-10 02:28:27 +00001036 DeferGC deferGC(vm.heap);
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001037 Butterfly* result = object->growOutOfLineStorage(vm, 0, initialOutOfLineCapacity);
mhahnenberg@apple.comebf01912014-01-02 22:57:14 +00001038 object->setButterflyWithoutChangingStructure(vm, result);
fpizlo@apple.comd8dd0532012-09-13 04:18:52 +00001039 return reinterpret_cast<char*>(result);
1040}
1041
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001042char* JIT_OPERATION operationReallocateButterflyToGrowPropertyStorage(ExecState* exec, JSObject* object, size_t newSize)
fpizlo@apple.comd8dd0532012-09-13 04:18:52 +00001043{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001044 VM& vm = exec->vm();
1045 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.comc17054c2012-09-18 15:22:29 +00001046
mhahnenberg@apple.com3ddd7ac2014-01-10 02:28:27 +00001047 DeferGC deferGC(vm.heap);
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001048 Butterfly* result = object->growOutOfLineStorage(vm, object->structure()->outOfLineCapacity(), newSize);
mhahnenberg@apple.comebf01912014-01-02 22:57:14 +00001049 object->setButterflyWithoutChangingStructure(vm, result);
fpizlo@apple.comd8dd0532012-09-13 04:18:52 +00001050 return reinterpret_cast<char*>(result);
fpizlo@apple.com1ffdcff2012-07-19 00:30:34 +00001051}
1052
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001053char* JIT_OPERATION operationEnsureInt32(ExecState* exec, JSCell* cell)
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001054{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001055 VM& vm = exec->vm();
1056 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001057
fpizlo@apple.com274b6f12012-12-20 00:19:03 +00001058 if (!cell->isObject())
1059 return 0;
1060
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001061 return reinterpret_cast<char*>(asObject(cell)->ensureInt32(vm).data());
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001062}
1063
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001064char* JIT_OPERATION operationEnsureDouble(ExecState* exec, JSCell* cell)
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001065{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001066 VM& vm = exec->vm();
1067 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001068
fpizlo@apple.com274b6f12012-12-20 00:19:03 +00001069 if (!cell->isObject())
1070 return 0;
1071
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001072 return reinterpret_cast<char*>(asObject(cell)->ensureDouble(vm).data());
fpizlo@apple.com75c91a72012-11-08 22:28:25 +00001073}
1074
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001075char* JIT_OPERATION operationEnsureContiguous(ExecState* exec, JSCell* cell)
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +00001076{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001077 VM& vm = exec->vm();
1078 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +00001079
fpizlo@apple.com274b6f12012-12-20 00:19:03 +00001080 if (!cell->isObject())
1081 return 0;
1082
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001083 return reinterpret_cast<char*>(asObject(cell)->ensureContiguous(vm).data());
fpizlo@apple.com0e9910a2012-10-09 23:39:53 +00001084}
1085
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001086char* JIT_OPERATION operationEnsureArrayStorage(ExecState* exec, JSCell* cell)
fpizlo@apple.com497c7512012-09-19 01:20:52 +00001087{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001088 VM& vm = exec->vm();
1089 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.com274b6f12012-12-20 00:19:03 +00001090
1091 if (!cell->isObject())
1092 return 0;
fpizlo@apple.com497c7512012-09-19 01:20:52 +00001093
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001094 return reinterpret_cast<char*>(asObject(cell)->ensureArrayStorage(vm));
fpizlo@apple.com497c7512012-09-19 01:20:52 +00001095}
1096
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001097StringImpl* JIT_OPERATION operationResolveRope(ExecState* exec, JSString* string)
fpizlo@apple.com70bb5c52012-12-11 05:22:49 +00001098{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001099 VM& vm = exec->vm();
1100 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.com70bb5c52012-12-11 05:22:49 +00001101
1102 return string->value(exec).impl();
1103}
1104
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001105JSString* JIT_OPERATION operationSingleCharacterString(ExecState* exec, int32_t character)
oliver@apple.com63af2d42013-07-25 04:03:33 +00001106{
1107 VM& vm = exec->vm();
1108 NativeCallFrameTracer tracer(&vm, exec);
1109
1110 return jsSingleCharacterString(exec, static_cast<UChar>(character));
1111}
1112
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001113JSCell* JIT_OPERATION operationNewStringObject(ExecState* exec, JSString* string, Structure* structure)
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001114{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001115 VM& vm = exec->vm();
1116 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001117
akling@apple.com019809c2013-10-06 18:16:48 +00001118 return StringObject::create(vm, structure, string);
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001119}
1120
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001121JSCell* JIT_OPERATION operationToStringOnCell(ExecState* exec, JSCell* cell)
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001122{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001123 VM& vm = exec->vm();
1124 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001125
1126 return JSValue(cell).toString(exec);
1127}
1128
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001129JSCell* JIT_OPERATION operationToString(ExecState* exec, EncodedJSValue value)
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001130{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001131 VM& vm = exec->vm();
1132 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.com0e6e1542013-03-18 18:09:22 +00001133
1134 return JSValue::decode(value).toString(exec);
1135}
1136
utatane.tea@gmail.com153559e2015-04-06 19:07:12 +00001137JSCell* JIT_OPERATION operationCallStringConstructorOnCell(ExecState* exec, JSCell* cell)
1138{
1139 VM& vm = exec->vm();
1140 NativeCallFrameTracer tracer(&vm, exec);
1141
1142 return stringConstructor(exec, cell);
1143}
1144
1145JSCell* JIT_OPERATION operationCallStringConstructor(ExecState* exec, EncodedJSValue value)
1146{
1147 VM& vm = exec->vm();
1148 NativeCallFrameTracer tracer(&vm, exec);
1149
1150 return stringConstructor(exec, JSValue::decode(value));
1151}
1152
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001153JSCell* JIT_OPERATION operationMakeRope2(ExecState* exec, JSString* left, JSString* right)
fpizlo@apple.com8d225912013-03-19 00:44:57 +00001154{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001155 VM& vm = exec->vm();
1156 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.com24c49992014-04-19 21:13:46 +00001157
1158 if (sumOverflows<int32_t>(left->length(), right->length())) {
fpizlo@apple.com75104a32014-04-15 23:33:11 +00001159 throwOutOfMemoryError(exec);
fpizlo@apple.come28731c2014-04-19 20:36:58 +00001160 return nullptr;
fpizlo@apple.com75104a32014-04-15 23:33:11 +00001161 }
fpizlo@apple.com8d225912013-03-19 00:44:57 +00001162
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001163 return JSRopeString::create(vm, left, right);
fpizlo@apple.com8d225912013-03-19 00:44:57 +00001164}
1165
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001166JSCell* JIT_OPERATION operationMakeRope3(ExecState* exec, JSString* a, JSString* b, JSString* c)
fpizlo@apple.com4463e442013-03-20 20:29:37 +00001167{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001168 VM& vm = exec->vm();
1169 NativeCallFrameTracer tracer(&vm, exec);
fpizlo@apple.com4463e442013-03-20 20:29:37 +00001170
fpizlo@apple.com24c49992014-04-19 21:13:46 +00001171 if (sumOverflows<int32_t>(a->length(), b->length(), c->length())) {
fpizlo@apple.com75104a32014-04-15 23:33:11 +00001172 throwOutOfMemoryError(exec);
fpizlo@apple.come28731c2014-04-19 20:36:58 +00001173 return nullptr;
fpizlo@apple.com75104a32014-04-15 23:33:11 +00001174 }
1175
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001176 return JSRopeString::create(vm, a, b, c);
fpizlo@apple.com4463e442013-03-20 20:29:37 +00001177}
1178
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001179JSCell* JIT_OPERATION operationStrCat2(ExecState* exec, EncodedJSValue a, EncodedJSValue b)
1180{
1181 VM& vm = exec->vm();
1182 NativeCallFrameTracer tracer(&vm, exec);
1183
1184 JSString* str1 = JSValue::decode(a).toString(exec);
fpizlo@apple.com2b150e782015-08-27 23:59:57 +00001185 ASSERT(!exec->hadException()); // Impossible, since we must have been given primitives.
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001186 JSString* str2 = JSValue::decode(b).toString(exec);
fpizlo@apple.com2b150e782015-08-27 23:59:57 +00001187 ASSERT(!exec->hadException());
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001188
1189 if (sumOverflows<int32_t>(str1->length(), str2->length())) {
1190 throwOutOfMemoryError(exec);
1191 return nullptr;
1192 }
1193
1194 return JSRopeString::create(vm, str1, str2);
1195}
1196
1197JSCell* JIT_OPERATION operationStrCat3(ExecState* exec, EncodedJSValue a, EncodedJSValue b, EncodedJSValue c)
1198{
1199 VM& vm = exec->vm();
1200 NativeCallFrameTracer tracer(&vm, exec);
1201
1202 JSString* str1 = JSValue::decode(a).toString(exec);
fpizlo@apple.com2b150e782015-08-27 23:59:57 +00001203 ASSERT(!exec->hadException()); // Impossible, since we must have been given primitives.
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001204 JSString* str2 = JSValue::decode(b).toString(exec);
fpizlo@apple.com2b150e782015-08-27 23:59:57 +00001205 ASSERT(!exec->hadException());
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001206 JSString* str3 = JSValue::decode(c).toString(exec);
fpizlo@apple.com2b150e782015-08-27 23:59:57 +00001207 ASSERT(!exec->hadException());
fpizlo@apple.comb3b187c2015-08-22 18:35:47 +00001208
1209 if (sumOverflows<int32_t>(str1->length(), str2->length(), str3->length())) {
1210 throwOutOfMemoryError(exec);
1211 return nullptr;
1212 }
1213
1214 return JSRopeString::create(vm, str1, str2, str3);
1215}
1216
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001217char* JIT_OPERATION operationFindSwitchImmTargetForDouble(
oliver@apple.com9b7647b2013-07-25 04:03:00 +00001218 ExecState* exec, EncodedJSValue encodedValue, size_t tableIndex)
1219{
1220 CodeBlock* codeBlock = exec->codeBlock();
oliver@apple.coma14cea52013-07-25 04:03:23 +00001221 SimpleJumpTable& table = codeBlock->switchJumpTable(tableIndex);
oliver@apple.com9b7647b2013-07-25 04:03:00 +00001222 JSValue value = JSValue::decode(encodedValue);
1223 ASSERT(value.isDouble());
1224 double asDouble = value.asDouble();
1225 int32_t asInt32 = static_cast<int32_t>(asDouble);
1226 if (asDouble == asInt32)
1227 return static_cast<char*>(table.ctiForValue(asInt32).executableAddress());
1228 return static_cast<char*>(table.ctiDefault.executableAddress());
1229}
1230
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001231char* JIT_OPERATION operationSwitchString(ExecState* exec, size_t tableIndex, JSString* string)
oliver@apple.com5c826c02013-07-25 04:03:51 +00001232{
1233 VM& vm = exec->vm();
1234 NativeCallFrameTracer tracer(&vm, exec);
1235
1236 return static_cast<char*>(exec->codeBlock()->stringSwitchJumpTable(tableIndex).ctiForValue(string->value(exec).impl()).executableAddress());
1237}
1238
fpizlo@apple.com5a3036b2015-04-29 03:34:43 +00001239int32_t JIT_OPERATION operationSwitchStringAndGetBranchOffset(ExecState* exec, size_t tableIndex, JSString* string)
1240{
1241 VM& vm = exec->vm();
1242 NativeCallFrameTracer tracer(&vm, exec);
1243
1244 return exec->codeBlock()->stringSwitchJumpTable(tableIndex).offsetForValue(string->value(exec).impl(), std::numeric_limits<int32_t>::min());
1245}
1246
fpizlo@apple.com8dde06b2015-10-12 22:41:01 +00001247char* JIT_OPERATION operationGetButterfly(ExecState* exec, JSCell* cell)
1248{
1249 VM& vm = exec->vm();
1250 NativeCallFrameTracer tracer(&vm, exec);
1251
fpizlo@apple.com8dde06b2015-10-12 22:41:01 +00001252 return bitwise_cast<char*>(jsCast<JSObject*>(cell)->butterfly());
1253}
1254
1255char* JIT_OPERATION operationGetArrayBufferVector(ExecState* exec, JSCell* cell)
1256{
1257 VM& vm = exec->vm();
1258 NativeCallFrameTracer tracer(&vm, exec);
1259
1260 return bitwise_cast<char*>(jsCast<JSArrayBufferView*>(cell)->vector());
1261}
1262
fpizlo@apple.com3a2fa4c2015-04-13 22:13:12 +00001263void JIT_OPERATION operationNotifyWrite(ExecState* exec, WatchpointSet* set)
fpizlo@apple.com33961712013-11-20 05:49:05 +00001264{
1265 VM& vm = exec->vm();
1266 NativeCallFrameTracer tracer(&vm, exec);
1267
fpizlo@apple.com3a2fa4c2015-04-13 22:13:12 +00001268 set->touch("Executed NotifyWrite");
fpizlo@apple.com33961712013-11-20 05:49:05 +00001269}
1270
fpizlo@apple.comda834ae2015-03-26 04:28:43 +00001271void JIT_OPERATION operationThrowStackOverflowForVarargs(ExecState* exec)
1272{
1273 VM& vm = exec->vm();
1274 NativeCallFrameTracer tracer(&vm, exec);
1275 throwStackOverflowError(exec);
1276}
1277
fpizlo@apple.com8fefdd32015-02-18 19:55:47 +00001278int32_t JIT_OPERATION operationSizeOfVarargs(ExecState* exec, EncodedJSValue encodedArguments, int32_t firstVarArgOffset)
1279{
1280 VM& vm = exec->vm();
1281 NativeCallFrameTracer tracer(&vm, exec);
1282 JSValue arguments = JSValue::decode(encodedArguments);
1283
1284 return sizeOfVarargs(exec, arguments, firstVarArgOffset);
1285}
1286
1287void JIT_OPERATION operationLoadVarargs(ExecState* exec, int32_t firstElementDest, EncodedJSValue encodedArguments, int32_t offset, int32_t length, int32_t mandatoryMinimum)
1288{
1289 VM& vm = exec->vm();
1290 NativeCallFrameTracer tracer(&vm, exec);
1291 JSValue arguments = JSValue::decode(encodedArguments);
1292
1293 loadVarargs(exec, VirtualRegister(firstElementDest), arguments, offset, length);
1294
1295 for (int32_t i = length; i < mandatoryMinimum; ++i)
1296 exec->r(firstElementDest + i) = jsUndefined();
1297}
1298
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001299double JIT_OPERATION operationFModOnInts(int32_t a, int32_t b)
fpizlo@apple.com2c2536e2012-03-21 01:29:28 +00001300{
1301 return fmod(a, b);
1302}
1303
utatane.tea@gmail.comd2fca0a2015-12-15 03:51:42 +00001304#if USE(JSVALUE32_64)
1305double JIT_OPERATION operationRandom(JSGlobalObject* globalObject)
1306{
1307 return globalObject->weakRandomNumber();
1308}
1309#endif
1310
mark.lam@apple.com03a3e382016-01-08 18:44:36 +00001311JSCell* JIT_OPERATION operationStringFromCharCode(ExecState* exec, int32_t op1)
commit-queue@webkit.orgaa31a5e2013-04-09 06:45:16 +00001312{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001313 VM* vm = &exec->vm();
1314 NativeCallFrameTracer tracer(vm, exec);
mark.lam@apple.com03a3e382016-01-08 18:44:36 +00001315 return JSC::stringFromCharCode(exec, op1);
commit-queue@webkit.orgaa31a5e2013-04-09 06:45:16 +00001316}
1317
mark.lam@apple.com151fe102016-01-13 23:28:38 +00001318EncodedJSValue JIT_OPERATION operationStringFromCharCodeUntyped(ExecState* exec, EncodedJSValue encodedValue)
1319{
1320 VM* vm = &exec->vm();
1321 NativeCallFrameTracer tracer(vm, exec);
1322 JSValue charValue = JSValue::decode(encodedValue);
1323 int32_t chInt = charValue.toUInt32(exec);
1324 return JSValue::encode(JSC::stringFromCharCode(exec, chInt));
1325}
1326
fpizlo@apple.comf2999932014-07-15 00:41:39 +00001327int64_t JIT_OPERATION operationConvertBoxedDoubleToInt52(EncodedJSValue encodedValue)
1328{
1329 JSValue value = JSValue::decode(encodedValue);
1330 if (!value.isDouble())
1331 return JSValue::notInt52;
1332 return tryConvertToInt52(value.asDouble());
1333}
1334
1335int64_t JIT_OPERATION operationConvertDoubleToInt52(double value)
1336{
1337 return tryConvertToInt52(value);
1338}
1339
saambarati1@gmail.comdaf10202014-10-01 20:47:51 +00001340void JIT_OPERATION operationProcessTypeProfilerLogDFG(ExecState* exec)
1341{
1342 exec->vm().typeProfilerLog()->processLogEntries(ASCIILiteral("Log Full, called from inside DFG."));
1343}
1344
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001345void JIT_OPERATION debugOperationPrintSpeculationFailure(ExecState* exec, void* debugInfoRaw, void* scratch)
fpizlo@apple.com746c6d072011-09-07 02:47:51 +00001346{
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +00001347 VM* vm = &exec->vm();
1348 NativeCallFrameTracer tracer(vm, exec);
oliver@apple.come07a4592012-01-25 19:43:06 +00001349
fpizlo@apple.com746c6d072011-09-07 02:47:51 +00001350 SpeculationFailureDebugInfo* debugInfo = static_cast<SpeculationFailureDebugInfo*>(debugInfoRaw);
fpizlo@apple.comf2bf0dd2011-09-26 04:05:28 +00001351 CodeBlock* codeBlock = debugInfo->codeBlock;
fpizlo@apple.com47d3b642011-10-05 21:36:23 +00001352 CodeBlock* alternative = codeBlock->alternative();
mark.lam@apple.come7ecf832014-04-02 20:49:27 +00001353 dataLog("Speculation failure in ", *codeBlock);
1354 dataLog(" @ exit #", vm->osrExitIndex, " (bc#", debugInfo->bytecodeOffset, ", ", exitKindToString(debugInfo->kind), ") with ");
fpizlo@apple.com0bfcc382012-11-30 03:42:29 +00001355 if (alternative) {
1356 dataLog(
1357 "executeCounter = ", alternative->jitExecuteCounter(),
1358 ", reoptimizationRetryCounter = ", alternative->reoptimizationRetryCounter(),
1359 ", optimizationDelayCounter = ", alternative->optimizationDelayCounter());
1360 } else
1361 dataLog("no alternative code block (i.e. we've been jettisoned)");
1362 dataLog(", osrExitCounter = ", codeBlock->osrExitCounter(), "\n");
fpizlo@apple.com03e446e2013-01-11 22:18:27 +00001363 dataLog(" GPRs at time of exit:");
1364 char* scratchPointer = static_cast<char*>(scratch);
1365 for (unsigned i = 0; i < GPRInfo::numberOfRegisters; ++i) {
1366 GPRReg gpr = GPRInfo::toRegister(i);
commit-queue@webkit.org94ea8122013-02-25 13:13:43 +00001367 dataLog(" ", GPRInfo::debugName(gpr), ":", RawPointer(*reinterpret_cast_ptr<void**>(scratchPointer)));
fpizlo@apple.com03e446e2013-01-11 22:18:27 +00001368 scratchPointer += sizeof(EncodedJSValue);
1369 }
1370 dataLog("\n");
1371 dataLog(" FPRs at time of exit:");
1372 for (unsigned i = 0; i < FPRInfo::numberOfRegisters; ++i) {
1373 FPRReg fpr = FPRInfo::toRegister(i);
1374 dataLog(" ", FPRInfo::debugName(fpr), ":");
commit-queue@webkit.org94ea8122013-02-25 13:13:43 +00001375 uint64_t bits = *reinterpret_cast_ptr<uint64_t*>(scratchPointer);
1376 double value = *reinterpret_cast_ptr<double*>(scratchPointer);
ossy@webkit.org71aebd72013-01-12 09:33:01 +00001377 dataLogF("%llx:%lf", static_cast<long long>(bits), value);
fpizlo@apple.com03e446e2013-01-11 22:18:27 +00001378 scratchPointer += sizeof(EncodedJSValue);
1379 }
1380 dataLog("\n");
fpizlo@apple.com746c6d072011-09-07 02:47:51 +00001381}
fpizlo@apple.com746c6d072011-09-07 02:47:51 +00001382
fpizlo@apple.com2c4a7e92014-08-06 05:27:46 +00001383extern "C" void JIT_OPERATION triggerReoptimizationNow(CodeBlock* codeBlock, OSRExitBase* exit)
fpizlo@apple.com16e2cbf2012-06-22 23:32:59 +00001384{
fpizlo@apple.com98225492013-09-10 18:29:45 +00001385 // It's sort of preferable that we don't GC while in here. Anyways, doing so wouldn't
1386 // really be profitable.
1387 DeferGCForAWhile deferGC(codeBlock->vm()->heap);
1388
oliver@apple.com284cc3d2013-07-25 04:00:33 +00001389 if (Options::verboseOSR())
1390 dataLog(*codeBlock, ": Entered reoptimize\n");
fpizlo@apple.com16e2cbf2012-06-22 23:32:59 +00001391 // We must be called with the baseline code block.
oliver@apple.com5a24fdd2013-07-25 04:00:54 +00001392 ASSERT(JITCode::isBaselineCode(codeBlock->jitType()));
fpizlo@apple.com16e2cbf2012-06-22 23:32:59 +00001393
1394 // If I am my own replacement, then reoptimization has already been triggered.
1395 // This can happen in recursive functions.
oliver@apple.comd2a16382013-07-25 04:04:18 +00001396 if (codeBlock->replacement() == codeBlock) {
1397 if (Options::verboseOSR())
1398 dataLog(*codeBlock, ": Not reoptimizing because we've already been jettisoned.\n");
fpizlo@apple.com16e2cbf2012-06-22 23:32:59 +00001399 return;
oliver@apple.comd2a16382013-07-25 04:04:18 +00001400 }
1401
fpizlo@apple.com16e2cbf2012-06-22 23:32:59 +00001402 // Otherwise, the replacement must be optimized code. Use this as an opportunity
1403 // to check our logic.
1404 ASSERT(codeBlock->hasOptimizedReplacement());
oliver@apple.comd2a16382013-07-25 04:04:18 +00001405 CodeBlock* optimizedCodeBlock = codeBlock->replacement();
1406 ASSERT(JITCode::isOptimizingJIT(optimizedCodeBlock->jitType()));
fpizlo@apple.com2c4a7e92014-08-06 05:27:46 +00001407
1408 bool didTryToEnterIntoInlinedLoops = false;
msaboff@apple.coma3dc7532015-09-24 21:42:59 +00001409 for (InlineCallFrame* inlineCallFrame = exit->m_codeOrigin.inlineCallFrame; inlineCallFrame; inlineCallFrame = inlineCallFrame->directCaller.inlineCallFrame) {
ggaren@apple.com81def5f2015-10-09 23:10:16 +00001410 if (inlineCallFrame->baselineCodeBlock->ownerScriptExecutable()->didTryToEnterInLoop()) {
fpizlo@apple.com2c4a7e92014-08-06 05:27:46 +00001411 didTryToEnterIntoInlinedLoops = true;
1412 break;
1413 }
1414 }
oliver@apple.comd2a16382013-07-25 04:04:18 +00001415
1416 // In order to trigger reoptimization, one of two things must have happened:
1417 // 1) We exited more than some number of times.
1418 // 2) We exited and got stuck in a loop, and now we're exiting again.
1419 bool didExitABunch = optimizedCodeBlock->shouldReoptimizeNow();
1420 bool didGetStuckInLoop =
fpizlo@apple.com2c4a7e92014-08-06 05:27:46 +00001421 (codeBlock->checkIfOptimizationThresholdReached() || didTryToEnterIntoInlinedLoops)
oliver@apple.comd2a16382013-07-25 04:04:18 +00001422 && optimizedCodeBlock->shouldReoptimizeFromLoopNow();
1423
1424 if (!didExitABunch && !didGetStuckInLoop) {
1425 if (Options::verboseOSR())
1426 dataLog(*codeBlock, ": Not reoptimizing ", *optimizedCodeBlock, " because it either didn't exit enough or didn't loop enough after exit.\n");
1427 codeBlock->optimizeAfterLongWarmUp();
1428 return;
1429 }
fpizlo@apple.com16e2cbf2012-06-22 23:32:59 +00001430
fpizlo@apple.com0dda6d72014-02-02 02:25:13 +00001431 optimizedCodeBlock->jettison(Profiler::JettisonDueToOSRExit, CountReoptimization);
fpizlo@apple.com16e2cbf2012-06-22 23:32:59 +00001432}
1433
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001434#if ENABLE(FTL_JIT)
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00001435static bool shouldTriggerFTLCompile(CodeBlock* codeBlock, JITCode* jitCode)
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001436{
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001437 if (codeBlock->baselineVersion()->m_didFailFTLCompilation) {
1438 if (Options::verboseOSR())
1439 dataLog("Deferring FTL-optimization of ", *codeBlock, " indefinitely because there was an FTL failure.\n");
1440 jitCode->dontOptimizeAnytimeSoon(codeBlock);
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00001441 return false;
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001442 }
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00001443
1444 if (!codeBlock->hasOptimizedReplacement()
1445 && !jitCode->checkIfOptimizationThresholdReached(codeBlock)) {
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001446 if (Options::verboseOSR())
1447 dataLog("Choosing not to FTL-optimize ", *codeBlock, " yet.\n");
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00001448 return false;
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001449 }
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00001450 return true;
1451}
1452
1453static void triggerFTLReplacementCompile(VM* vm, CodeBlock* codeBlock, JITCode* jitCode)
1454{
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001455 Worklist::State worklistState;
msaboff@apple.com95894332014-01-29 19:18:54 +00001456 if (Worklist* worklist = existingGlobalFTLWorklistOrNull()) {
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001457 worklistState = worklist->completeAllReadyPlansForVM(
1458 *vm, CompilationKey(codeBlock->baselineVersion(), FTLMode));
1459 } else
1460 worklistState = Worklist::NotKnown;
1461
1462 if (worklistState == Worklist::Compiling) {
1463 jitCode->setOptimizationThresholdBasedOnCompilationResult(
1464 codeBlock, CompilationDeferred);
1465 return;
1466 }
1467
1468 if (codeBlock->hasOptimizedReplacement()) {
1469 // That's great, we've compiled the code - next time we call this function,
1470 // we'll enter that replacement.
1471 jitCode->optimizeSoon(codeBlock);
1472 return;
1473 }
1474
1475 if (worklistState == Worklist::Compiled) {
1476 // This means that we finished compiling, but failed somehow; in that case the
1477 // thresholds will be set appropriately.
1478 if (Options::verboseOSR())
1479 dataLog("Code block ", *codeBlock, " was compiled but it doesn't have an optimized replacement.\n");
1480 return;
1481 }
1482
1483 // We need to compile the code.
1484 compile(
ggaren@apple.com81def5f2015-10-09 23:10:16 +00001485 *vm, codeBlock->newReplacement(), codeBlock, FTLMode, UINT_MAX,
1486 Operands<JSValue>(), ToFTLDeferredCompilationCallback::create());
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00001487
1488 // If we reached here, the counter has not be reset. Do that now.
1489 jitCode->setOptimizationThresholdBasedOnCompilationResult(
1490 codeBlock, CompilationDeferred);
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001491}
1492
benjamin@webkit.org8f625992015-05-18 20:45:34 +00001493static void triggerTierUpNowCommon(ExecState* exec, bool inLoop)
fpizlo@apple.com0c606702014-02-06 07:11:48 +00001494{
1495 VM* vm = &exec->vm();
1496 NativeCallFrameTracer tracer(vm, exec);
1497 DeferGC deferGC(vm->heap);
1498 CodeBlock* codeBlock = exec->codeBlock();
1499
fpizlo@apple.com8a5fd182015-02-02 18:38:08 +00001500 if (codeBlock->jitType() != JITCode::DFGJIT) {
1501 dataLog("Unexpected code block in DFG->FTL tier-up: ", *codeBlock, "\n");
1502 RELEASE_ASSERT_NOT_REACHED();
1503 }
1504
fpizlo@apple.com0c606702014-02-06 07:11:48 +00001505 JITCode* jitCode = codeBlock->jitCode()->dfg();
1506
1507 if (Options::verboseOSR()) {
1508 dataLog(
1509 *codeBlock, ": Entered triggerTierUpNow with executeCounter = ",
1510 jitCode->tierUpCounter, "\n");
1511 }
benjamin@webkit.org8f625992015-05-18 20:45:34 +00001512 if (inLoop)
1513 jitCode->nestedTriggerIsSet = 1;
1514
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00001515 if (shouldTriggerFTLCompile(codeBlock, jitCode))
1516 triggerFTLReplacementCompile(vm, codeBlock, jitCode);
fpizlo@apple.com0c606702014-02-06 07:11:48 +00001517}
1518
benjamin@webkit.org8f625992015-05-18 20:45:34 +00001519void JIT_OPERATION triggerTierUpNow(ExecState* exec)
1520{
1521 triggerTierUpNowCommon(exec, false);
1522}
1523
1524void JIT_OPERATION triggerTierUpNowInLoop(ExecState* exec)
1525{
1526 triggerTierUpNowCommon(exec, true);
1527}
1528
mark.lam@apple.com9df8b832013-09-26 20:27:14 +00001529char* JIT_OPERATION triggerOSREntryNow(
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001530 ExecState* exec, int32_t bytecodeIndex, int32_t streamIndex)
1531{
1532 VM* vm = &exec->vm();
1533 NativeCallFrameTracer tracer(vm, exec);
1534 DeferGC deferGC(vm->heap);
1535 CodeBlock* codeBlock = exec->codeBlock();
1536
fpizlo@apple.com8a5fd182015-02-02 18:38:08 +00001537 if (codeBlock->jitType() != JITCode::DFGJIT) {
1538 dataLog("Unexpected code block in DFG->FTL tier-up: ", *codeBlock, "\n");
1539 RELEASE_ASSERT_NOT_REACHED();
1540 }
1541
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001542 JITCode* jitCode = codeBlock->jitCode()->dfg();
benjamin@webkit.org8f625992015-05-18 20:45:34 +00001543 jitCode->nestedTriggerIsSet = 0;
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001544
1545 if (Options::verboseOSR()) {
1546 dataLog(
fpizlo@apple.com2c4a7e92014-08-06 05:27:46 +00001547 *codeBlock, ": Entered triggerOSREntryNow with executeCounter = ",
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001548 jitCode->tierUpCounter, "\n");
1549 }
1550
fpizlo@apple.com0c606702014-02-06 07:11:48 +00001551 // - If we don't have an FTL code block, then try to compile one.
1552 // - If we do have an FTL code block, then try to enter for a while.
1553 // - If we couldn't enter for a while, then trigger OSR entry.
msaboff@apple.com95894332014-01-29 19:18:54 +00001554
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00001555 if (!shouldTriggerFTLCompile(codeBlock, jitCode))
1556 return nullptr;
1557
1558 if (!jitCode->neverExecutedEntry) {
1559 triggerFTLReplacementCompile(vm, codeBlock, jitCode);
1560
1561 if (!codeBlock->hasOptimizedReplacement())
1562 return nullptr;
fpizlo@apple.com0c606702014-02-06 07:11:48 +00001563 }
1564
1565 // It's time to try to compile code for OSR entry.
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001566 Worklist::State worklistState;
fpizlo@apple.com0c606702014-02-06 07:11:48 +00001567 if (Worklist* worklist = existingGlobalFTLWorklistOrNull()) {
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001568 worklistState = worklist->completeAllReadyPlansForVM(
1569 *vm, CompilationKey(codeBlock->baselineVersion(), FTLForOSREntryMode));
1570 } else
1571 worklistState = Worklist::NotKnown;
1572
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00001573 if (worklistState == Worklist::Compiling) {
1574 jitCode->setOptimizationThresholdBasedOnCompilationResult(
1575 codeBlock, CompilationDeferred);
1576 return nullptr;
1577 }
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001578
ggaren@apple.com81def5f2015-10-09 23:10:16 +00001579 if (CodeBlock* entryBlock = jitCode->osrEntryBlock()) {
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001580 void* address = FTL::prepareOSREntry(
1581 exec, codeBlock, entryBlock, bytecodeIndex, streamIndex);
fpizlo@apple.com0c606702014-02-06 07:11:48 +00001582 if (address)
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001583 return static_cast<char*>(address);
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00001584
1585 if (jitCode->osrEntryRetry < Options::ftlOSREntryRetryThreshold()) {
1586 jitCode->osrEntryRetry++;
1587 return nullptr;
1588 }
1589
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001590 FTL::ForOSREntryJITCode* entryCode = entryBlock->jitCode()->ftlForOSREntry();
1591 entryCode->countEntryFailure();
1592 if (entryCode->entryFailureCount() <
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00001593 Options::ftlOSREntryFailureCountForReoptimization()) {
1594 jitCode->optimizeSoon(codeBlock);
1595 return nullptr;
1596 }
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001597
1598 // OSR entry failed. Oh no! This implies that we need to retry. We retry
1599 // without exponential backoff and we only do this for the entry code block.
ggaren@apple.com81def5f2015-10-09 23:10:16 +00001600 jitCode->clearOSREntryBlock();
fpizlo@apple.com0c606702014-02-06 07:11:48 +00001601 jitCode->osrEntryRetry = 0;
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00001602 return nullptr;
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001603 }
1604
1605 if (worklistState == Worklist::Compiled) {
1606 // This means that compilation failed and we already set the thresholds.
1607 if (Options::verboseOSR())
1608 dataLog("Code block ", *codeBlock, " was compiled but it doesn't have an optimized replacement.\n");
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00001609 return nullptr;
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001610 }
1611
fpizlo@apple.com0c606702014-02-06 07:11:48 +00001612 // We aren't compiling and haven't compiled anything for OSR entry. So, try to compile
1613 // something.
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001614 Operands<JSValue> mustHandleValues;
1615 jitCode->reconstruct(
1616 exec, codeBlock, CodeOrigin(bytecodeIndex), streamIndex, mustHandleValues);
ggaren@apple.com81def5f2015-10-09 23:10:16 +00001617 CodeBlock* replacementCodeBlock = codeBlock->newReplacement();
msaboff@apple.com95894332014-01-29 19:18:54 +00001618 CompilationResult forEntryResult = compile(
ggaren@apple.com81def5f2015-10-09 23:10:16 +00001619 *vm, replacementCodeBlock, codeBlock, FTLForOSREntryMode, bytecodeIndex,
1620 mustHandleValues, ToFTLForOSREntryDeferredCompilationCallback::create());
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00001621
1622 if (jitCode->neverExecutedEntry)
1623 triggerFTLReplacementCompile(vm, codeBlock, jitCode);
1624
1625 if (forEntryResult != CompilationSuccessful) {
1626 jitCode->setOptimizationThresholdBasedOnCompilationResult(
1627 codeBlock, CompilationDeferred);
1628 return nullptr;
1629 }
mark.lam@apple.comaebf6852014-03-03 21:39:21 +00001630
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001631 // It's possible that the for-entry compile already succeeded. In that case OSR
1632 // entry will succeed unless we ran out of stack. It's not clear what we should do.
1633 // We signal to try again after a while if that happens.
1634 void* address = FTL::prepareOSREntry(
ggaren@apple.com81def5f2015-10-09 23:10:16 +00001635 exec, codeBlock, jitCode->osrEntryBlock(), bytecodeIndex, streamIndex);
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001636 return static_cast<char*>(address);
1637}
commit-queue@webkit.org2ae563d2016-02-26 05:59:48 +00001638
fpizlo@apple.com532f1e52013-09-04 06:26:04 +00001639#endif // ENABLE(FTL_JIT)
1640
barraclough@apple.comc7af2d32011-05-26 21:37:05 +00001641} // extern "C"
fpizlo@apple.com04659ba2012-02-21 09:49:22 +00001642} } // namespace JSC::DFG
1643
commit-queue@webkit.orgb8419482012-08-30 22:21:48 +00001644#endif // ENABLE(DFG_JIT)
fpizlo@apple.com7bbcaab2012-02-22 05:23:19 +00001645
commit-queue@webkit.orgb8419482012-08-30 22:21:48 +00001646#endif // ENABLE(JIT)