1// Copyright 2012 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#if V8_TARGET_ARCH_ARM
6
7#include "src/codegen.h"
8#include "src/debug/debug.h"
9#include "src/deoptimizer.h"
10#include "src/full-codegen/full-codegen.h"
11#include "src/runtime/runtime.h"
12
13namespace v8 {
14namespace internal {
15
16#define __ ACCESS_MASM(masm)
17
18void Builtins::Generate_Adaptor(MacroAssembler* masm, Address address,
19                                ExitFrameType exit_frame_type) {
20  // ----------- S t a t e -------------
21  //  -- r0                 : number of arguments excluding receiver
22  //  -- r1                 : target
23  //  -- r3                 : new.target
24  //  -- sp[0]              : last argument
25  //  -- ...
26  //  -- sp[4 * (argc - 1)] : first argument
27  //  -- sp[4 * argc]       : receiver
28  // -----------------------------------
29  __ AssertFunction(r1);
30
31  // Make sure we operate in the context of the called function (for example
32  // ConstructStubs implemented in C++ will be run in the context of the caller
33  // instead of the callee, due to the way that [[Construct]] is defined for
34  // ordinary functions).
35  __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
36
37  // JumpToExternalReference expects r0 to contain the number of arguments
38  // including the receiver and the extra arguments.
39  const int num_extra_args = 3;
40  __ add(r0, r0, Operand(num_extra_args + 1));
41
42  // Insert extra arguments.
43  __ SmiTag(r0);
44  __ Push(r0, r1, r3);
45  __ SmiUntag(r0);
46
47  __ JumpToExternalReference(ExternalReference(address, masm->isolate()),
48                             exit_frame_type == BUILTIN_EXIT);
49}
50
51// Load the built-in InternalArray function from the current context.
52static void GenerateLoadInternalArrayFunction(MacroAssembler* masm,
53                                              Register result) {
54  // Load the InternalArray function from the current native context.
55  __ LoadNativeContextSlot(Context::INTERNAL_ARRAY_FUNCTION_INDEX, result);
56}
57
58// Load the built-in Array function from the current context.
59static void GenerateLoadArrayFunction(MacroAssembler* masm, Register result) {
60  // Load the Array function from the current native context.
61  __ LoadNativeContextSlot(Context::ARRAY_FUNCTION_INDEX, result);
62}
63
64void Builtins::Generate_InternalArrayCode(MacroAssembler* masm) {
65  // ----------- S t a t e -------------
66  //  -- r0     : number of arguments
67  //  -- lr     : return address
68  //  -- sp[...]: constructor arguments
69  // -----------------------------------
70  Label generic_array_code, one_or_more_arguments, two_or_more_arguments;
71
72  // Get the InternalArray function.
73  GenerateLoadInternalArrayFunction(masm, r1);
74
75  if (FLAG_debug_code) {
76    // Initial map for the builtin InternalArray functions should be maps.
77    __ ldr(r2, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset));
78    __ SmiTst(r2);
79    __ Assert(ne, kUnexpectedInitialMapForInternalArrayFunction);
80    __ CompareObjectType(r2, r3, r4, MAP_TYPE);
81    __ Assert(eq, kUnexpectedInitialMapForInternalArrayFunction);
82  }
83
84  // Run the native code for the InternalArray function called as a normal
85  // function.
86  // tail call a stub
87  InternalArrayConstructorStub stub(masm->isolate());
88  __ TailCallStub(&stub);
89}
90
91void Builtins::Generate_ArrayCode(MacroAssembler* masm) {
92  // ----------- S t a t e -------------
93  //  -- r0     : number of arguments
94  //  -- lr     : return address
95  //  -- sp[...]: constructor arguments
96  // -----------------------------------
97  Label generic_array_code, one_or_more_arguments, two_or_more_arguments;
98
99  // Get the Array function.
100  GenerateLoadArrayFunction(masm, r1);
101
102  if (FLAG_debug_code) {
103    // Initial map for the builtin Array functions should be maps.
104    __ ldr(r2, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset));
105    __ SmiTst(r2);
106    __ Assert(ne, kUnexpectedInitialMapForArrayFunction);
107    __ CompareObjectType(r2, r3, r4, MAP_TYPE);
108    __ Assert(eq, kUnexpectedInitialMapForArrayFunction);
109  }
110
111  __ mov(r3, r1);
112  // Run the native code for the Array function called as a normal function.
113  // tail call a stub
114  __ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
115  ArrayConstructorStub stub(masm->isolate());
116  __ TailCallStub(&stub);
117}
118
119// static
120void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) {
121  // ----------- S t a t e -------------
122  //  -- r0                     : number of arguments
123  //  -- r1                     : function
124  //  -- cp                     : context
125  //  -- lr                     : return address
126  //  -- sp[(argc - n - 1) * 4] : arg[n] (zero based)
127  //  -- sp[argc * 4]           : receiver
128  // -----------------------------------
129  Condition const cc_done = (kind == MathMaxMinKind::kMin) ? mi : gt;
130  Condition const cc_swap = (kind == MathMaxMinKind::kMin) ? gt : mi;
131  Heap::RootListIndex const root_index =
132      (kind == MathMaxMinKind::kMin) ? Heap::kInfinityValueRootIndex
133                                     : Heap::kMinusInfinityValueRootIndex;
134  DoubleRegister const reg = (kind == MathMaxMinKind::kMin) ? d2 : d1;
135
136  // Load the accumulator with the default return value (either -Infinity or
137  // +Infinity), with the tagged value in r5 and the double value in d1.
138  __ LoadRoot(r5, root_index);
139  __ vldr(d1, FieldMemOperand(r5, HeapNumber::kValueOffset));
140
141  Label done_loop, loop;
142  __ mov(r4, r0);
143  __ bind(&loop);
144  {
145    // Check if all parameters done.
146    __ sub(r4, r4, Operand(1), SetCC);
147    __ b(lt, &done_loop);
148
149    // Load the next parameter tagged value into r2.
150    __ ldr(r2, MemOperand(sp, r4, LSL, kPointerSizeLog2));
151
152    // Load the double value of the parameter into d2, maybe converting the
153    // parameter to a number first using the ToNumber builtin if necessary.
154    Label convert, convert_smi, convert_number, done_convert;
155    __ bind(&convert);
156    __ JumpIfSmi(r2, &convert_smi);
157    __ ldr(r3, FieldMemOperand(r2, HeapObject::kMapOffset));
158    __ JumpIfRoot(r3, Heap::kHeapNumberMapRootIndex, &convert_number);
159    {
160      // Parameter is not a Number, use the ToNumber builtin to convert it.
161      DCHECK(!FLAG_enable_embedded_constant_pool);
162      FrameScope scope(masm, StackFrame::MANUAL);
163      __ SmiTag(r0);
164      __ SmiTag(r4);
165      __ EnterBuiltinFrame(cp, r1, r0);
166      __ Push(r4, r5);
167      __ mov(r0, r2);
168      __ Call(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET);
169      __ mov(r2, r0);
170      __ Pop(r4, r5);
171      __ LeaveBuiltinFrame(cp, r1, r0);
172      __ SmiUntag(r4);
173      __ SmiUntag(r0);
174      {
175        // Restore the double accumulator value (d1).
176        Label done_restore;
177        __ SmiToDouble(d1, r5);
178        __ JumpIfSmi(r5, &done_restore);
179        __ vldr(d1, FieldMemOperand(r5, HeapNumber::kValueOffset));
180        __ bind(&done_restore);
181      }
182    }
183    __ b(&convert);
184    __ bind(&convert_number);
185    __ vldr(d2, FieldMemOperand(r2, HeapNumber::kValueOffset));
186    __ b(&done_convert);
187    __ bind(&convert_smi);
188    __ SmiToDouble(d2, r2);
189    __ bind(&done_convert);
190
191    // Perform the actual comparison with the accumulator value on the left hand
192    // side (d1) and the next parameter value on the right hand side (d2).
193    Label compare_nan, compare_swap;
194    __ VFPCompareAndSetFlags(d1, d2);
195    __ b(cc_done, &loop);
196    __ b(cc_swap, &compare_swap);
197    __ b(vs, &compare_nan);
198
199    // Left and right hand side are equal, check for -0 vs. +0.
200    __ VmovHigh(ip, reg);
201    __ cmp(ip, Operand(0x80000000));
202    __ b(ne, &loop);
203
204    // Result is on the right hand side.
205    __ bind(&compare_swap);
206    __ vmov(d1, d2);
207    __ mov(r5, r2);
208    __ b(&loop);
209
210    // At least one side is NaN, which means that the result will be NaN too.
211    __ bind(&compare_nan);
212    __ LoadRoot(r5, Heap::kNanValueRootIndex);
213    __ vldr(d1, FieldMemOperand(r5, HeapNumber::kValueOffset));
214    __ b(&loop);
215  }
216
217  __ bind(&done_loop);
218  // Drop all slots, including the receiver.
219  __ add(r0, r0, Operand(1));
220  __ Drop(r0);
221  __ mov(r0, r5);
222  __ Ret();
223}
224
225// static
226void Builtins::Generate_NumberConstructor(MacroAssembler* masm) {
227  // ----------- S t a t e -------------
228  //  -- r0                     : number of arguments
229  //  -- r1                     : constructor function
230  //  -- cp                     : context
231  //  -- lr                     : return address
232  //  -- sp[(argc - n - 1) * 4] : arg[n] (zero based)
233  //  -- sp[argc * 4]           : receiver
234  // -----------------------------------
235
236  // 1. Load the first argument into r0.
237  Label no_arguments;
238  {
239    __ mov(r2, r0);  // Store argc in r2.
240    __ sub(r0, r0, Operand(1), SetCC);
241    __ b(lo, &no_arguments);
242    __ ldr(r0, MemOperand(sp, r0, LSL, kPointerSizeLog2));
243  }
244
245  // 2a. Convert the first argument to a number.
246  {
247    FrameScope scope(masm, StackFrame::MANUAL);
248    __ SmiTag(r2);
249    __ EnterBuiltinFrame(cp, r1, r2);
250    __ Call(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET);
251    __ LeaveBuiltinFrame(cp, r1, r2);
252    __ SmiUntag(r2);
253  }
254
255  {
256    // Drop all arguments including the receiver.
257    __ Drop(r2);
258    __ Ret(1);
259  }
260
261  // 2b. No arguments, return +0.
262  __ bind(&no_arguments);
263  __ Move(r0, Smi::kZero);
264  __ Ret(1);
265}
266
267// static
268void Builtins::Generate_NumberConstructor_ConstructStub(MacroAssembler* masm) {
269  // ----------- S t a t e -------------
270  //  -- r0                     : number of arguments
271  //  -- r1                     : constructor function
272  //  -- r3                     : new target
273  //  -- cp                     : context
274  //  -- lr                     : return address
275  //  -- sp[(argc - n - 1) * 4] : arg[n] (zero based)
276  //  -- sp[argc * 4]           : receiver
277  // -----------------------------------
278
279  // 1. Make sure we operate in the context of the called function.
280  __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
281
282  // 2. Load the first argument into r2.
283  {
284    Label no_arguments, done;
285    __ mov(r6, r0);  // Store argc in r6.
286    __ sub(r0, r0, Operand(1), SetCC);
287    __ b(lo, &no_arguments);
288    __ ldr(r2, MemOperand(sp, r0, LSL, kPointerSizeLog2));
289    __ b(&done);
290    __ bind(&no_arguments);
291    __ Move(r2, Smi::kZero);
292    __ bind(&done);
293  }
294
295  // 3. Make sure r2 is a number.
296  {
297    Label done_convert;
298    __ JumpIfSmi(r2, &done_convert);
299    __ CompareObjectType(r2, r4, r4, HEAP_NUMBER_TYPE);
300    __ b(eq, &done_convert);
301    {
302      FrameScope scope(masm, StackFrame::MANUAL);
303      __ SmiTag(r6);
304      __ EnterBuiltinFrame(cp, r1, r6);
305      __ Push(r3);
306      __ Move(r0, r2);
307      __ Call(masm->isolate()->builtins()->ToNumber(), RelocInfo::CODE_TARGET);
308      __ Move(r2, r0);
309      __ Pop(r3);
310      __ LeaveBuiltinFrame(cp, r1, r6);
311      __ SmiUntag(r6);
312    }
313    __ bind(&done_convert);
314  }
315
316  // 4. Check if new target and constructor differ.
317  Label drop_frame_and_ret, new_object;
318  __ cmp(r1, r3);
319  __ b(ne, &new_object);
320
321  // 5. Allocate a JSValue wrapper for the number.
322  __ AllocateJSValue(r0, r1, r2, r4, r5, &new_object);
323  __ b(&drop_frame_and_ret);
324
325  // 6. Fallback to the runtime to create new object.
326  __ bind(&new_object);
327  {
328    FrameScope scope(masm, StackFrame::MANUAL);
329    __ SmiTag(r6);
330    __ EnterBuiltinFrame(cp, r1, r6);
331    __ Push(r2);  // first argument
332    __ Call(CodeFactory::FastNewObject(masm->isolate()).code(),
333            RelocInfo::CODE_TARGET);
334    __ Pop(r2);
335    __ LeaveBuiltinFrame(cp, r1, r6);
336    __ SmiUntag(r6);
337  }
338  __ str(r2, FieldMemOperand(r0, JSValue::kValueOffset));
339
340  __ bind(&drop_frame_and_ret);
341  {
342    __ Drop(r6);
343    __ Ret(1);
344  }
345}
346
347// static
348void Builtins::Generate_StringConstructor(MacroAssembler* masm) {
349  // ----------- S t a t e -------------
350  //  -- r0                     : number of arguments
351  //  -- r1                     : constructor function
352  //  -- cp                     : context
353  //  -- lr                     : return address
354  //  -- sp[(argc - n - 1) * 4] : arg[n] (zero based)
355  //  -- sp[argc * 4]           : receiver
356  // -----------------------------------
357
358  // 1. Load the first argument into r0.
359  Label no_arguments;
360  {
361    __ mov(r2, r0);  // Store argc in r2.
362    __ sub(r0, r0, Operand(1), SetCC);
363    __ b(lo, &no_arguments);
364    __ ldr(r0, MemOperand(sp, r0, LSL, kPointerSizeLog2));
365  }
366
367  // 2a. At least one argument, return r0 if it's a string, otherwise
368  // dispatch to appropriate conversion.
369  Label drop_frame_and_ret, to_string, symbol_descriptive_string;
370  {
371    __ JumpIfSmi(r0, &to_string);
372    STATIC_ASSERT(FIRST_NONSTRING_TYPE == SYMBOL_TYPE);
373    __ CompareObjectType(r0, r3, r3, FIRST_NONSTRING_TYPE);
374    __ b(hi, &to_string);
375    __ b(eq, &symbol_descriptive_string);
376    __ b(&drop_frame_and_ret);
377  }
378
379  // 2b. No arguments, return the empty string (and pop the receiver).
380  __ bind(&no_arguments);
381  {
382    __ LoadRoot(r0, Heap::kempty_stringRootIndex);
383    __ Ret(1);
384  }
385
386  // 3a. Convert r0 to a string.
387  __ bind(&to_string);
388  {
389    FrameScope scope(masm, StackFrame::MANUAL);
390    __ SmiTag(r2);
391    __ EnterBuiltinFrame(cp, r1, r2);
392    __ Call(masm->isolate()->builtins()->ToString(), RelocInfo::CODE_TARGET);
393    __ LeaveBuiltinFrame(cp, r1, r2);
394    __ SmiUntag(r2);
395  }
396  __ b(&drop_frame_and_ret);
397
398  // 3b. Convert symbol in r0 to a string.
399  __ bind(&symbol_descriptive_string);
400  {
401    __ Drop(r2);
402    __ Drop(1);
403    __ Push(r0);
404    __ TailCallRuntime(Runtime::kSymbolDescriptiveString);
405  }
406
407  __ bind(&drop_frame_and_ret);
408  {
409    __ Drop(r2);
410    __ Ret(1);
411  }
412}
413
414// static
415void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) {
416  // ----------- S t a t e -------------
417  //  -- r0                     : number of arguments
418  //  -- r1                     : constructor function
419  //  -- r3                     : new target
420  //  -- cp                     : context
421  //  -- lr                     : return address
422  //  -- sp[(argc - n - 1) * 4] : arg[n] (zero based)
423  //  -- sp[argc * 4]           : receiver
424  // -----------------------------------
425
426  // 1. Make sure we operate in the context of the called function.
427  __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
428
429  // 2. Load the first argument into r2.
430  {
431    Label no_arguments, done;
432    __ mov(r6, r0);  // Store argc in r6.
433    __ sub(r0, r0, Operand(1), SetCC);
434    __ b(lo, &no_arguments);
435    __ ldr(r2, MemOperand(sp, r0, LSL, kPointerSizeLog2));
436    __ b(&done);
437    __ bind(&no_arguments);
438    __ LoadRoot(r2, Heap::kempty_stringRootIndex);
439    __ bind(&done);
440  }
441
442  // 3. Make sure r2 is a string.
443  {
444    Label convert, done_convert;
445    __ JumpIfSmi(r2, &convert);
446    __ CompareObjectType(r2, r4, r4, FIRST_NONSTRING_TYPE);
447    __ b(lo, &done_convert);
448    __ bind(&convert);
449    {
450      FrameScope scope(masm, StackFrame::MANUAL);
451      __ SmiTag(r6);
452      __ EnterBuiltinFrame(cp, r1, r6);
453      __ Push(r3);
454      __ Move(r0, r2);
455      __ Call(masm->isolate()->builtins()->ToString(), RelocInfo::CODE_TARGET);
456      __ Move(r2, r0);
457      __ Pop(r3);
458      __ LeaveBuiltinFrame(cp, r1, r6);
459      __ SmiUntag(r6);
460    }
461    __ bind(&done_convert);
462  }
463
464  // 4. Check if new target and constructor differ.
465  Label drop_frame_and_ret, new_object;
466  __ cmp(r1, r3);
467  __ b(ne, &new_object);
468
469  // 5. Allocate a JSValue wrapper for the string.
470  __ AllocateJSValue(r0, r1, r2, r4, r5, &new_object);
471  __ b(&drop_frame_and_ret);
472
473  // 6. Fallback to the runtime to create new object.
474  __ bind(&new_object);
475  {
476    FrameScope scope(masm, StackFrame::MANUAL);
477    __ SmiTag(r6);
478    __ EnterBuiltinFrame(cp, r1, r6);
479    __ Push(r2);  // first argument
480    __ Call(CodeFactory::FastNewObject(masm->isolate()).code(),
481            RelocInfo::CODE_TARGET);
482    __ Pop(r2);
483    __ LeaveBuiltinFrame(cp, r1, r6);
484    __ SmiUntag(r6);
485  }
486  __ str(r2, FieldMemOperand(r0, JSValue::kValueOffset));
487
488  __ bind(&drop_frame_and_ret);
489  {
490    __ Drop(r6);
491    __ Ret(1);
492  }
493}
494
495static void GenerateTailCallToSharedCode(MacroAssembler* masm) {
496  __ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
497  __ ldr(r2, FieldMemOperand(r2, SharedFunctionInfo::kCodeOffset));
498  __ add(r2, r2, Operand(Code::kHeaderSize - kHeapObjectTag));
499  __ Jump(r2);
500}
501
502static void GenerateTailCallToReturnedCode(MacroAssembler* masm,
503                                           Runtime::FunctionId function_id) {
504  // ----------- S t a t e -------------
505  //  -- r0 : argument count (preserved for callee)
506  //  -- r1 : target function (preserved for callee)
507  //  -- r3 : new target (preserved for callee)
508  // -----------------------------------
509  {
510    FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
511    // Push the number of arguments to the callee.
512    __ SmiTag(r0);
513    __ push(r0);
514    // Push a copy of the target function and the new target.
515    __ push(r1);
516    __ push(r3);
517    // Push function as parameter to the runtime call.
518    __ Push(r1);
519
520    __ CallRuntime(function_id, 1);
521    __ mov(r2, r0);
522
523    // Restore target function and new target.
524    __ pop(r3);
525    __ pop(r1);
526    __ pop(r0);
527    __ SmiUntag(r0, r0);
528  }
529  __ add(r2, r2, Operand(Code::kHeaderSize - kHeapObjectTag));
530  __ Jump(r2);
531}
532
533void Builtins::Generate_InOptimizationQueue(MacroAssembler* masm) {
534  // Checking whether the queued function is ready for install is optional,
535  // since we come across interrupts and stack checks elsewhere.  However,
536  // not checking may delay installing ready functions, and always checking
537  // would be quite expensive.  A good compromise is to first check against
538  // stack limit as a cue for an interrupt signal.
539  Label ok;
540  __ LoadRoot(ip, Heap::kStackLimitRootIndex);
541  __ cmp(sp, Operand(ip));
542  __ b(hs, &ok);
543
544  GenerateTailCallToReturnedCode(masm, Runtime::kTryInstallOptimizedCode);
545
546  __ bind(&ok);
547  GenerateTailCallToSharedCode(masm);
548}
549
550namespace {
551
552void Generate_JSConstructStubHelper(MacroAssembler* masm, bool is_api_function,
553                                    bool create_implicit_receiver,
554                                    bool check_derived_construct) {
555  Label post_instantiation_deopt_entry;
556
557  // ----------- S t a t e -------------
558  //  -- r0     : number of arguments
559  //  -- r1     : constructor function
560  //  -- r3     : new target
561  //  -- cp     : context
562  //  -- lr     : return address
563  //  -- sp[...]: constructor arguments
564  // -----------------------------------
565
566  Isolate* isolate = masm->isolate();
567
568  // Enter a construct frame.
569  {
570    FrameAndConstantPoolScope scope(masm, StackFrame::CONSTRUCT);
571
572    // Preserve the incoming parameters on the stack.
573    __ SmiTag(r0);
574    __ Push(cp, r0);
575
576    if (create_implicit_receiver) {
577      // Allocate the new receiver object.
578      __ Push(r1, r3);
579      __ Call(CodeFactory::FastNewObject(masm->isolate()).code(),
580              RelocInfo::CODE_TARGET);
581      __ mov(r4, r0);
582      __ Pop(r1, r3);
583
584      // ----------- S t a t e -------------
585      //  -- r1: constructor function
586      //  -- r3: new target
587      //  -- r4: newly allocated object
588      // -----------------------------------
589
590      // Retrieve smi-tagged arguments count from the stack.
591      __ ldr(r0, MemOperand(sp));
592    }
593
594    __ SmiUntag(r0);
595
596    if (create_implicit_receiver) {
597      // Push the allocated receiver to the stack. We need two copies
598      // because we may have to return the original one and the calling
599      // conventions dictate that the called function pops the receiver.
600      __ push(r4);
601      __ push(r4);
602    } else {
603      __ PushRoot(Heap::kTheHoleValueRootIndex);
604    }
605
606    // Deoptimizer re-enters stub code here.
607    __ bind(&post_instantiation_deopt_entry);
608
609    // Set up pointer to last argument.
610    __ add(r2, fp, Operand(StandardFrameConstants::kCallerSPOffset));
611
612    // Copy arguments and receiver to the expression stack.
613    // r0: number of arguments
614    // r1: constructor function
615    // r2: address of last argument (caller sp)
616    // r3: new target
617    // r4: number of arguments (smi-tagged)
618    // sp[0]: receiver
619    // sp[1]: receiver
620    // sp[2]: number of arguments (smi-tagged)
621    Label loop, entry;
622    __ SmiTag(r4, r0);
623    __ b(&entry);
624    __ bind(&loop);
625    __ ldr(ip, MemOperand(r2, r4, LSL, kPointerSizeLog2 - 1));
626    __ push(ip);
627    __ bind(&entry);
628    __ sub(r4, r4, Operand(2), SetCC);
629    __ b(ge, &loop);
630
631    // Call the function.
632    // r0: number of arguments
633    // r1: constructor function
634    // r3: new target
635    ParameterCount actual(r0);
636    __ InvokeFunction(r1, r3, actual, CALL_FUNCTION,
637                      CheckDebugStepCallWrapper());
638
639    // Store offset of return address for deoptimizer.
640    if (create_implicit_receiver && !is_api_function) {
641      masm->isolate()->heap()->SetConstructStubInvokeDeoptPCOffset(
642          masm->pc_offset());
643    }
644
645    // Restore context from the frame.
646    // r0: result
647    // sp[0]: receiver
648    // sp[1]: number of arguments (smi-tagged)
649    __ ldr(cp, MemOperand(fp, ConstructFrameConstants::kContextOffset));
650
651    if (create_implicit_receiver) {
652      // If the result is an object (in the ECMA sense), we should get rid
653      // of the receiver and use the result; see ECMA-262 section 13.2.2-7
654      // on page 74.
655      Label use_receiver, exit;
656
657      // If the result is a smi, it is *not* an object in the ECMA sense.
658      // r0: result
659      // sp[0]: receiver
660      // sp[1]: number of arguments (smi-tagged)
661      __ JumpIfSmi(r0, &use_receiver);
662
663      // If the type of the result (stored in its map) is less than
664      // FIRST_JS_RECEIVER_TYPE, it is not an object in the ECMA sense.
665      __ CompareObjectType(r0, r1, r3, FIRST_JS_RECEIVER_TYPE);
666      __ b(ge, &exit);
667
668      // Throw away the result of the constructor invocation and use the
669      // on-stack receiver as the result.
670      __ bind(&use_receiver);
671      __ ldr(r0, MemOperand(sp));
672
673      // Remove receiver from the stack, remove caller arguments, and
674      // return.
675      __ bind(&exit);
676      // r0: result
677      // sp[0]: receiver (newly allocated object)
678      // sp[1]: number of arguments (smi-tagged)
679      __ ldr(r1, MemOperand(sp, 1 * kPointerSize));
680    } else {
681      __ ldr(r1, MemOperand(sp));
682    }
683
684    // Leave construct frame.
685  }
686
687  // ES6 9.2.2. Step 13+
688  // Check that the result is not a Smi, indicating that the constructor result
689  // from a derived class is neither undefined nor an Object.
690  if (check_derived_construct) {
691    Label dont_throw;
692    __ JumpIfNotSmi(r0, &dont_throw);
693    {
694      FrameScope scope(masm, StackFrame::INTERNAL);
695      __ CallRuntime(Runtime::kThrowDerivedConstructorReturnedNonObject);
696    }
697    __ bind(&dont_throw);
698  }
699
700  __ add(sp, sp, Operand(r1, LSL, kPointerSizeLog2 - 1));
701  __ add(sp, sp, Operand(kPointerSize));
702  if (create_implicit_receiver) {
703    __ IncrementCounter(isolate->counters()->constructed_objects(), 1, r1, r2);
704  }
705  __ Jump(lr);
706
707  // Store offset of trampoline address for deoptimizer. This is the bailout
708  // point after the receiver instantiation but before the function invocation.
709  // We need to restore some registers in order to continue the above code.
710  if (create_implicit_receiver && !is_api_function) {
711    masm->isolate()->heap()->SetConstructStubCreateDeoptPCOffset(
712        masm->pc_offset());
713
714    // ----------- S t a t e -------------
715    //  -- r0    : newly allocated object
716    //  -- sp[0] : constructor function
717    // -----------------------------------
718
719    __ pop(r1);
720    __ push(r0);
721    __ push(r0);
722
723    // Retrieve smi-tagged arguments count from the stack.
724    __ ldr(r0, MemOperand(fp, ConstructFrameConstants::kLengthOffset));
725    __ SmiUntag(r0);
726
727    // Retrieve the new target value from the stack. This was placed into the
728    // frame description in place of the receiver by the optimizing compiler.
729    __ add(r3, fp, Operand(StandardFrameConstants::kCallerSPOffset));
730    __ ldr(r3, MemOperand(r3, r0, LSL, kPointerSizeLog2));
731
732    // Continue with constructor function invocation.
733    __ b(&post_instantiation_deopt_entry);
734  }
735}
736
737}  // namespace
738
739void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
740  Generate_JSConstructStubHelper(masm, false, true, false);
741}
742
743void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
744  Generate_JSConstructStubHelper(masm, true, false, false);
745}
746
747void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) {
748  Generate_JSConstructStubHelper(masm, false, false, false);
749}
750
751void Builtins::Generate_JSBuiltinsConstructStubForDerived(
752    MacroAssembler* masm) {
753  Generate_JSConstructStubHelper(masm, false, false, true);
754}
755
756// static
757void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
758  // ----------- S t a t e -------------
759  //  -- r0 : the value to pass to the generator
760  //  -- r1 : the JSGeneratorObject to resume
761  //  -- r2 : the resume mode (tagged)
762  //  -- lr : return address
763  // -----------------------------------
764  __ AssertGeneratorObject(r1);
765
766  // Store input value into generator object.
767  __ str(r0, FieldMemOperand(r1, JSGeneratorObject::kInputOrDebugPosOffset));
768  __ RecordWriteField(r1, JSGeneratorObject::kInputOrDebugPosOffset, r0, r3,
769                      kLRHasNotBeenSaved, kDontSaveFPRegs);
770
771  // Store resume mode into generator object.
772  __ str(r2, FieldMemOperand(r1, JSGeneratorObject::kResumeModeOffset));
773
774  // Load suspended function and context.
775  __ ldr(r4, FieldMemOperand(r1, JSGeneratorObject::kFunctionOffset));
776  __ ldr(cp, FieldMemOperand(r4, JSFunction::kContextOffset));
777
778  // Flood function if we are stepping.
779  Label prepare_step_in_if_stepping, prepare_step_in_suspended_generator;
780  Label stepping_prepared;
781  ExternalReference debug_hook =
782      ExternalReference::debug_hook_on_function_call_address(masm->isolate());
783  __ mov(ip, Operand(debug_hook));
784  __ ldrsb(ip, MemOperand(ip));
785  __ cmp(ip, Operand(0));
786  __ b(ne, &prepare_step_in_if_stepping);
787
788  // Flood function if we need to continue stepping in the suspended generator.
789  ExternalReference debug_suspended_generator =
790      ExternalReference::debug_suspended_generator_address(masm->isolate());
791  __ mov(ip, Operand(debug_suspended_generator));
792  __ ldr(ip, MemOperand(ip));
793  __ cmp(ip, Operand(r1));
794  __ b(eq, &prepare_step_in_suspended_generator);
795  __ bind(&stepping_prepared);
796
797  // Push receiver.
798  __ ldr(ip, FieldMemOperand(r1, JSGeneratorObject::kReceiverOffset));
799  __ Push(ip);
800
801  // ----------- S t a t e -------------
802  //  -- r1    : the JSGeneratorObject to resume
803  //  -- r2    : the resume mode (tagged)
804  //  -- r4    : generator function
805  //  -- cp    : generator context
806  //  -- lr    : return address
807  //  -- sp[0] : generator receiver
808  // -----------------------------------
809
810  // Push holes for arguments to generator function. Since the parser forced
811  // context allocation for any variables in generators, the actual argument
812  // values have already been copied into the context and these dummy values
813  // will never be used.
814  __ ldr(r3, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset));
815  __ ldr(r3,
816         FieldMemOperand(r3, SharedFunctionInfo::kFormalParameterCountOffset));
817  {
818    Label done_loop, loop;
819    __ bind(&loop);
820    __ sub(r3, r3, Operand(Smi::FromInt(1)), SetCC);
821    __ b(mi, &done_loop);
822    __ PushRoot(Heap::kTheHoleValueRootIndex);
823    __ b(&loop);
824    __ bind(&done_loop);
825  }
826
827  // Underlying function needs to have bytecode available.
828  if (FLAG_debug_code) {
829    __ ldr(r3, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset));
830    __ ldr(r3, FieldMemOperand(r3, SharedFunctionInfo::kFunctionDataOffset));
831    __ CompareObjectType(r3, r3, r3, BYTECODE_ARRAY_TYPE);
832    __ Assert(eq, kMissingBytecodeArray);
833  }
834
835  // Resume (Ignition/TurboFan) generator object.
836  {
837    __ ldr(r0, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset));
838    __ ldr(r0, FieldMemOperand(
839                   r0, SharedFunctionInfo::kFormalParameterCountOffset));
840    __ SmiUntag(r0);
841    // We abuse new.target both to indicate that this is a resume call and to
842    // pass in the generator object.  In ordinary calls, new.target is always
843    // undefined because generator functions are non-constructable.
844    __ Move(r3, r1);
845    __ Move(r1, r4);
846    __ ldr(r5, FieldMemOperand(r1, JSFunction::kCodeEntryOffset));
847    __ Jump(r5);
848  }
849
850  __ bind(&prepare_step_in_if_stepping);
851  {
852    FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
853    __ Push(r1, r2, r4);
854    __ CallRuntime(Runtime::kDebugOnFunctionCall);
855    __ Pop(r1, r2);
856    __ ldr(r4, FieldMemOperand(r1, JSGeneratorObject::kFunctionOffset));
857  }
858  __ b(&stepping_prepared);
859
860  __ bind(&prepare_step_in_suspended_generator);
861  {
862    FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
863    __ Push(r1, r2);
864    __ CallRuntime(Runtime::kDebugPrepareStepInSuspendedGenerator);
865    __ Pop(r1, r2);
866    __ ldr(r4, FieldMemOperand(r1, JSGeneratorObject::kFunctionOffset));
867  }
868  __ b(&stepping_prepared);
869}
870
871void Builtins::Generate_ConstructedNonConstructable(MacroAssembler* masm) {
872  FrameScope scope(masm, StackFrame::INTERNAL);
873  __ push(r1);
874  __ CallRuntime(Runtime::kThrowConstructedNonConstructable);
875}
876
877enum IsTagged { kArgcIsSmiTagged, kArgcIsUntaggedInt };
878
879// Clobbers r2; preserves all other registers.
880static void Generate_CheckStackOverflow(MacroAssembler* masm, Register argc,
881                                        IsTagged argc_is_tagged) {
882  // Check the stack for overflow. We are not trying to catch
883  // interruptions (e.g. debug break and preemption) here, so the "real stack
884  // limit" is checked.
885  Label okay;
886  __ LoadRoot(r2, Heap::kRealStackLimitRootIndex);
887  // Make r2 the space we have left. The stack might already be overflowed
888  // here which will cause r2 to become negative.
889  __ sub(r2, sp, r2);
890  // Check if the arguments will overflow the stack.
891  if (argc_is_tagged == kArgcIsSmiTagged) {
892    __ cmp(r2, Operand::PointerOffsetFromSmiKey(argc));
893  } else {
894    DCHECK(argc_is_tagged == kArgcIsUntaggedInt);
895    __ cmp(r2, Operand(argc, LSL, kPointerSizeLog2));
896  }
897  __ b(gt, &okay);  // Signed comparison.
898
899  // Out of stack space.
900  __ CallRuntime(Runtime::kThrowStackOverflow);
901
902  __ bind(&okay);
903}
904
905static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
906                                             bool is_construct) {
907  // Called from Generate_JS_Entry
908  // r0: new.target
909  // r1: function
910  // r2: receiver
911  // r3: argc
912  // r4: argv
913  // r5-r6, r8 (if !FLAG_enable_embedded_constant_pool) and cp may be clobbered
914  ProfileEntryHookStub::MaybeCallEntryHook(masm);
915
916  // Enter an internal frame.
917  {
918    FrameScope scope(masm, StackFrame::INTERNAL);
919
920    // Setup the context (we need to use the caller context from the isolate).
921    ExternalReference context_address(Isolate::kContextAddress,
922                                      masm->isolate());
923    __ mov(cp, Operand(context_address));
924    __ ldr(cp, MemOperand(cp));
925
926    __ InitializeRootRegister();
927
928    // Push the function and the receiver onto the stack.
929    __ Push(r1, r2);
930
931    // Check if we have enough stack space to push all arguments.
932    // Clobbers r2.
933    Generate_CheckStackOverflow(masm, r3, kArgcIsUntaggedInt);
934
935    // Remember new.target.
936    __ mov(r5, r0);
937
938    // Copy arguments to the stack in a loop.
939    // r1: function
940    // r3: argc
941    // r4: argv, i.e. points to first arg
942    Label loop, entry;
943    __ add(r2, r4, Operand(r3, LSL, kPointerSizeLog2));
944    // r2 points past last arg.
945    __ b(&entry);
946    __ bind(&loop);
947    __ ldr(r0, MemOperand(r4, kPointerSize, PostIndex));  // read next parameter
948    __ ldr(r0, MemOperand(r0));                           // dereference handle
949    __ push(r0);                                          // push parameter
950    __ bind(&entry);
951    __ cmp(r4, r2);
952    __ b(ne, &loop);
953
954    // Setup new.target and argc.
955    __ mov(r0, Operand(r3));
956    __ mov(r3, Operand(r5));
957
958    // Initialize all JavaScript callee-saved registers, since they will be seen
959    // by the garbage collector as part of handlers.
960    __ LoadRoot(r4, Heap::kUndefinedValueRootIndex);
961    __ mov(r5, Operand(r4));
962    __ mov(r6, Operand(r4));
963    if (!FLAG_enable_embedded_constant_pool) {
964      __ mov(r8, Operand(r4));
965    }
966    if (kR9Available == 1) {
967      __ mov(r9, Operand(r4));
968    }
969
970    // Invoke the code.
971    Handle<Code> builtin = is_construct
972                               ? masm->isolate()->builtins()->Construct()
973                               : masm->isolate()->builtins()->Call();
974    __ Call(builtin, RelocInfo::CODE_TARGET);
975
976    // Exit the JS frame and remove the parameters (except function), and
977    // return.
978    // Respect ABI stack constraint.
979  }
980  __ Jump(lr);
981
982  // r0: result
983}
984
985void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) {
986  Generate_JSEntryTrampolineHelper(masm, false);
987}
988
989void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) {
990  Generate_JSEntryTrampolineHelper(masm, true);
991}
992
993static void LeaveInterpreterFrame(MacroAssembler* masm, Register scratch) {
994  Register args_count = scratch;
995
996  // Get the arguments + receiver count.
997  __ ldr(args_count,
998         MemOperand(fp, InterpreterFrameConstants::kBytecodeArrayFromFp));
999  __ ldr(args_count,
1000         FieldMemOperand(args_count, BytecodeArray::kParameterSizeOffset));
1001
1002  // Leave the frame (also dropping the register file).
1003  __ LeaveFrame(StackFrame::JAVA_SCRIPT);
1004
1005  // Drop receiver + arguments.
1006  __ add(sp, sp, args_count, LeaveCC);
1007}
1008
1009// Generate code for entering a JS function with the interpreter.
1010// On entry to the function the receiver and arguments have been pushed on the
1011// stack left to right.  The actual argument count matches the formal parameter
1012// count expected by the function.
1013//
1014// The live registers are:
1015//   o r1: the JS function object being called.
1016//   o r3: the new target
1017//   o cp: our context
1018//   o pp: the caller's constant pool pointer (if enabled)
1019//   o fp: the caller's frame pointer
1020//   o sp: stack pointer
1021//   o lr: return address
1022//
1023// The function builds an interpreter frame.  See InterpreterFrameConstants in
1024// frames.h for its layout.
1025void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
1026  ProfileEntryHookStub::MaybeCallEntryHook(masm);
1027
1028  // Open a frame scope to indicate that there is a frame on the stack.  The
1029  // MANUAL indicates that the scope shouldn't actually generate code to set up
1030  // the frame (that is done below).
1031  FrameScope frame_scope(masm, StackFrame::MANUAL);
1032  __ PushStandardFrame(r1);
1033
1034  // Get the bytecode array from the function object (or from the DebugInfo if
1035  // it is present) and load it into kInterpreterBytecodeArrayRegister.
1036  __ ldr(r0, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
1037  Register debug_info = kInterpreterBytecodeArrayRegister;
1038  DCHECK(!debug_info.is(r0));
1039  __ ldr(debug_info, FieldMemOperand(r0, SharedFunctionInfo::kDebugInfoOffset));
1040  __ SmiTst(debug_info);
1041  // Load original bytecode array or the debug copy.
1042  __ ldr(kInterpreterBytecodeArrayRegister,
1043         FieldMemOperand(r0, SharedFunctionInfo::kFunctionDataOffset), eq);
1044  __ ldr(kInterpreterBytecodeArrayRegister,
1045         FieldMemOperand(debug_info, DebugInfo::kDebugBytecodeArrayIndex), ne);
1046
1047  // Check whether we should continue to use the interpreter.
1048  Label switch_to_different_code_kind;
1049  __ ldr(r0, FieldMemOperand(r0, SharedFunctionInfo::kCodeOffset));
1050  __ cmp(r0, Operand(masm->CodeObject()));  // Self-reference to this code.
1051  __ b(ne, &switch_to_different_code_kind);
1052
1053  // Increment invocation count for the function.
1054  __ ldr(r2, FieldMemOperand(r1, JSFunction::kFeedbackVectorOffset));
1055  __ ldr(r2, FieldMemOperand(r2, Cell::kValueOffset));
1056  __ ldr(r9, FieldMemOperand(
1057                 r2, FeedbackVector::kInvocationCountIndex * kPointerSize +
1058                         FeedbackVector::kHeaderSize));
1059  __ add(r9, r9, Operand(Smi::FromInt(1)));
1060  __ str(r9, FieldMemOperand(
1061                 r2, FeedbackVector::kInvocationCountIndex * kPointerSize +
1062                         FeedbackVector::kHeaderSize));
1063
1064  // Check function data field is actually a BytecodeArray object.
1065  if (FLAG_debug_code) {
1066    __ SmiTst(kInterpreterBytecodeArrayRegister);
1067    __ Assert(ne, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry);
1068    __ CompareObjectType(kInterpreterBytecodeArrayRegister, r0, no_reg,
1069                         BYTECODE_ARRAY_TYPE);
1070    __ Assert(eq, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry);
1071  }
1072
1073  // Reset code age.
1074  __ mov(r9, Operand(BytecodeArray::kNoAgeBytecodeAge));
1075  __ strb(r9, FieldMemOperand(kInterpreterBytecodeArrayRegister,
1076                              BytecodeArray::kBytecodeAgeOffset));
1077
1078  // Load the initial bytecode offset.
1079  __ mov(kInterpreterBytecodeOffsetRegister,
1080         Operand(BytecodeArray::kHeaderSize - kHeapObjectTag));
1081
1082  // Push new.target, bytecode array and Smi tagged bytecode array offset.
1083  __ SmiTag(r0, kInterpreterBytecodeOffsetRegister);
1084  __ Push(r3, kInterpreterBytecodeArrayRegister, r0);
1085
1086  // Allocate the local and temporary register file on the stack.
1087  {
1088    // Load frame size from the BytecodeArray object.
1089    __ ldr(r4, FieldMemOperand(kInterpreterBytecodeArrayRegister,
1090                               BytecodeArray::kFrameSizeOffset));
1091
1092    // Do a stack check to ensure we don't go over the limit.
1093    Label ok;
1094    __ sub(r9, sp, Operand(r4));
1095    __ LoadRoot(r2, Heap::kRealStackLimitRootIndex);
1096    __ cmp(r9, Operand(r2));
1097    __ b(hs, &ok);
1098    __ CallRuntime(Runtime::kThrowStackOverflow);
1099    __ bind(&ok);
1100
1101    // If ok, push undefined as the initial value for all register file entries.
1102    Label loop_header;
1103    Label loop_check;
1104    __ LoadRoot(r9, Heap::kUndefinedValueRootIndex);
1105    __ b(&loop_check, al);
1106    __ bind(&loop_header);
1107    // TODO(rmcilroy): Consider doing more than one push per loop iteration.
1108    __ push(r9);
1109    // Continue loop if not done.
1110    __ bind(&loop_check);
1111    __ sub(r4, r4, Operand(kPointerSize), SetCC);
1112    __ b(&loop_header, ge);
1113  }
1114
1115  // Load accumulator and dispatch table into registers.
1116  __ LoadRoot(kInterpreterAccumulatorRegister, Heap::kUndefinedValueRootIndex);
1117  __ mov(kInterpreterDispatchTableRegister,
1118         Operand(ExternalReference::interpreter_dispatch_table_address(
1119             masm->isolate())));
1120
1121  // Dispatch to the first bytecode handler for the function.
1122  __ ldrb(r1, MemOperand(kInterpreterBytecodeArrayRegister,
1123                         kInterpreterBytecodeOffsetRegister));
1124  __ ldr(ip, MemOperand(kInterpreterDispatchTableRegister, r1, LSL,
1125                        kPointerSizeLog2));
1126  __ Call(ip);
1127  masm->isolate()->heap()->SetInterpreterEntryReturnPCOffset(masm->pc_offset());
1128
1129  // The return value is in r0.
1130  LeaveInterpreterFrame(masm, r2);
1131  __ Jump(lr);
1132
1133  // If the shared code is no longer this entry trampoline, then the underlying
1134  // function has been switched to a different kind of code and we heal the
1135  // closure by switching the code entry field over to the new code as well.
1136  __ bind(&switch_to_different_code_kind);
1137  __ LeaveFrame(StackFrame::JAVA_SCRIPT);
1138  __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
1139  __ ldr(r4, FieldMemOperand(r4, SharedFunctionInfo::kCodeOffset));
1140  __ add(r4, r4, Operand(Code::kHeaderSize - kHeapObjectTag));
1141  __ str(r4, FieldMemOperand(r1, JSFunction::kCodeEntryOffset));
1142  __ RecordWriteCodeEntryField(r1, r4, r5);
1143  __ Jump(r4);
1144}
1145
1146static void Generate_StackOverflowCheck(MacroAssembler* masm, Register num_args,
1147                                        Register scratch,
1148                                        Label* stack_overflow) {
1149  // Check the stack for overflow. We are not trying to catch
1150  // interruptions (e.g. debug break and preemption) here, so the "real stack
1151  // limit" is checked.
1152  __ LoadRoot(scratch, Heap::kRealStackLimitRootIndex);
1153  // Make scratch the space we have left. The stack might already be overflowed
1154  // here which will cause scratch to become negative.
1155  __ sub(scratch, sp, scratch);
1156  // Check if the arguments will overflow the stack.
1157  __ cmp(scratch, Operand(num_args, LSL, kPointerSizeLog2));
1158  __ b(le, stack_overflow);  // Signed comparison.
1159}
1160
1161static void Generate_InterpreterPushArgs(MacroAssembler* masm,
1162                                         Register num_args, Register index,
1163                                         Register limit, Register scratch,
1164                                         Label* stack_overflow) {
1165  // Add a stack check before pushing arguments.
1166  Generate_StackOverflowCheck(masm, num_args, scratch, stack_overflow);
1167
1168  // Find the address of the last argument.
1169  __ mov(limit, num_args);
1170  __ mov(limit, Operand(limit, LSL, kPointerSizeLog2));
1171  __ sub(limit, index, limit);
1172
1173  Label loop_header, loop_check;
1174  __ b(al, &loop_check);
1175  __ bind(&loop_header);
1176  __ ldr(scratch, MemOperand(index, -kPointerSize, PostIndex));
1177  __ push(scratch);
1178  __ bind(&loop_check);
1179  __ cmp(index, limit);
1180  __ b(gt, &loop_header);
1181}
1182
1183// static
1184void Builtins::Generate_InterpreterPushArgsAndCallImpl(
1185    MacroAssembler* masm, TailCallMode tail_call_mode,
1186    InterpreterPushArgsMode mode) {
1187  // ----------- S t a t e -------------
1188  //  -- r0 : the number of arguments (not including the receiver)
1189  //  -- r2 : the address of the first argument to be pushed. Subsequent
1190  //          arguments should be consecutive above this, in the same order as
1191  //          they are to be pushed onto the stack.
1192  //  -- r1 : the target to call (can be any Object).
1193  // -----------------------------------
1194  Label stack_overflow;
1195
1196  __ add(r3, r0, Operand(1));  // Add one for receiver.
1197
1198  // Push the arguments. r2, r4, r5 will be modified.
1199  Generate_InterpreterPushArgs(masm, r3, r2, r4, r5, &stack_overflow);
1200
1201  // Call the target.
1202  if (mode == InterpreterPushArgsMode::kJSFunction) {
1203    __ Jump(masm->isolate()->builtins()->CallFunction(ConvertReceiverMode::kAny,
1204                                                      tail_call_mode),
1205            RelocInfo::CODE_TARGET);
1206  } else if (mode == InterpreterPushArgsMode::kWithFinalSpread) {
1207    __ Jump(masm->isolate()->builtins()->CallWithSpread(),
1208            RelocInfo::CODE_TARGET);
1209  } else {
1210    __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny,
1211                                              tail_call_mode),
1212            RelocInfo::CODE_TARGET);
1213  }
1214
1215  __ bind(&stack_overflow);
1216  {
1217    __ TailCallRuntime(Runtime::kThrowStackOverflow);
1218    // Unreachable code.
1219    __ bkpt(0);
1220  }
1221}
1222
1223// static
1224void Builtins::Generate_InterpreterPushArgsAndConstructImpl(
1225    MacroAssembler* masm, InterpreterPushArgsMode mode) {
1226  // ----------- S t a t e -------------
1227  // -- r0 : argument count (not including receiver)
1228  // -- r3 : new target
1229  // -- r1 : constructor to call
1230  // -- r2 : allocation site feedback if available, undefined otherwise.
1231  // -- r4 : address of the first argument
1232  // -----------------------------------
1233  Label stack_overflow;
1234
1235  // Push a slot for the receiver to be constructed.
1236  __ mov(ip, Operand::Zero());
1237  __ push(ip);
1238
1239  // Push the arguments. r5, r4, r6 will be modified.
1240  Generate_InterpreterPushArgs(masm, r0, r4, r5, r6, &stack_overflow);
1241
1242  __ AssertUndefinedOrAllocationSite(r2, r5);
1243  if (mode == InterpreterPushArgsMode::kJSFunction) {
1244    __ AssertFunction(r1);
1245
1246    // Tail call to the function-specific construct stub (still in the caller
1247    // context at this point).
1248    __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
1249    __ ldr(r4, FieldMemOperand(r4, SharedFunctionInfo::kConstructStubOffset));
1250    // Jump to the construct function.
1251    __ add(pc, r4, Operand(Code::kHeaderSize - kHeapObjectTag));
1252  } else if (mode == InterpreterPushArgsMode::kWithFinalSpread) {
1253    // Call the constructor with r0, r1, and r3 unmodified.
1254    __ Jump(masm->isolate()->builtins()->ConstructWithSpread(),
1255            RelocInfo::CODE_TARGET);
1256  } else {
1257    DCHECK_EQ(InterpreterPushArgsMode::kOther, mode);
1258    // Call the constructor with r0, r1, and r3 unmodified.
1259    __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
1260  }
1261
1262  __ bind(&stack_overflow);
1263  {
1264    __ TailCallRuntime(Runtime::kThrowStackOverflow);
1265    // Unreachable code.
1266    __ bkpt(0);
1267  }
1268}
1269
1270// static
1271void Builtins::Generate_InterpreterPushArgsAndConstructArray(
1272    MacroAssembler* masm) {
1273  // ----------- S t a t e -------------
1274  // -- r0 : argument count (not including receiver)
1275  // -- r1 : target to call verified to be Array function
1276  // -- r2 : allocation site feedback if available, undefined otherwise.
1277  // -- r3 : address of the first argument
1278  // -----------------------------------
1279  Label stack_overflow;
1280
1281  __ add(r4, r0, Operand(1));  // Add one for receiver.
1282
1283  // TODO(mythria): Add a stack check before pushing arguments.
1284  // Push the arguments. r3, r5, r6 will be modified.
1285  Generate_InterpreterPushArgs(masm, r4, r3, r5, r6, &stack_overflow);
1286
1287  // Array constructor expects constructor in r3. It is same as r1 here.
1288  __ mov(r3, r1);
1289
1290  ArrayConstructorStub stub(masm->isolate());
1291  __ TailCallStub(&stub);
1292
1293  __ bind(&stack_overflow);
1294  {
1295    __ TailCallRuntime(Runtime::kThrowStackOverflow);
1296    // Unreachable code.
1297    __ bkpt(0);
1298  }
1299}
1300
1301static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) {
1302  // Set the return address to the correct point in the interpreter entry
1303  // trampoline.
1304  Smi* interpreter_entry_return_pc_offset(
1305      masm->isolate()->heap()->interpreter_entry_return_pc_offset());
1306  DCHECK_NE(interpreter_entry_return_pc_offset, Smi::kZero);
1307  __ Move(r2, masm->isolate()->builtins()->InterpreterEntryTrampoline());
1308  __ add(lr, r2, Operand(interpreter_entry_return_pc_offset->value() +
1309                         Code::kHeaderSize - kHeapObjectTag));
1310
1311  // Initialize the dispatch table register.
1312  __ mov(kInterpreterDispatchTableRegister,
1313         Operand(ExternalReference::interpreter_dispatch_table_address(
1314             masm->isolate())));
1315
1316  // Get the bytecode array pointer from the frame.
1317  __ ldr(kInterpreterBytecodeArrayRegister,
1318         MemOperand(fp, InterpreterFrameConstants::kBytecodeArrayFromFp));
1319
1320  if (FLAG_debug_code) {
1321    // Check function data field is actually a BytecodeArray object.
1322    __ SmiTst(kInterpreterBytecodeArrayRegister);
1323    __ Assert(ne, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry);
1324    __ CompareObjectType(kInterpreterBytecodeArrayRegister, r1, no_reg,
1325                         BYTECODE_ARRAY_TYPE);
1326    __ Assert(eq, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry);
1327  }
1328
1329  // Get the target bytecode offset from the frame.
1330  __ ldr(kInterpreterBytecodeOffsetRegister,
1331         MemOperand(fp, InterpreterFrameConstants::kBytecodeOffsetFromFp));
1332  __ SmiUntag(kInterpreterBytecodeOffsetRegister);
1333
1334  // Dispatch to the target bytecode.
1335  __ ldrb(r1, MemOperand(kInterpreterBytecodeArrayRegister,
1336                         kInterpreterBytecodeOffsetRegister));
1337  __ ldr(ip, MemOperand(kInterpreterDispatchTableRegister, r1, LSL,
1338                        kPointerSizeLog2));
1339  __ mov(pc, ip);
1340}
1341
1342void Builtins::Generate_InterpreterEnterBytecodeAdvance(MacroAssembler* masm) {
1343  // Advance the current bytecode offset stored within the given interpreter
1344  // stack frame. This simulates what all bytecode handlers do upon completion
1345  // of the underlying operation.
1346  __ ldr(r1, MemOperand(fp, InterpreterFrameConstants::kBytecodeArrayFromFp));
1347  __ ldr(r2, MemOperand(fp, InterpreterFrameConstants::kBytecodeOffsetFromFp));
1348  __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1349  {
1350    FrameScope scope(masm, StackFrame::INTERNAL);
1351    __ Push(kInterpreterAccumulatorRegister, r1, r2);
1352    __ CallRuntime(Runtime::kInterpreterAdvanceBytecodeOffset);
1353    __ mov(r2, r0);  // Result is the new bytecode offset.
1354    __ Pop(kInterpreterAccumulatorRegister);
1355  }
1356  __ str(r2, MemOperand(fp, InterpreterFrameConstants::kBytecodeOffsetFromFp));
1357
1358  Generate_InterpreterEnterBytecode(masm);
1359}
1360
1361void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) {
1362  Generate_InterpreterEnterBytecode(masm);
1363}
1364
1365void Builtins::Generate_CompileLazy(MacroAssembler* masm) {
1366  // ----------- S t a t e -------------
1367  //  -- r0 : argument count (preserved for callee)
1368  //  -- r3 : new target (preserved for callee)
1369  //  -- r1 : target function (preserved for callee)
1370  // -----------------------------------
1371  // First lookup code, maybe we don't need to compile!
1372  Label gotta_call_runtime, gotta_call_runtime_no_stack;
1373  Label try_shared;
1374  Label loop_top, loop_bottom;
1375
1376  Register argument_count = r0;
1377  Register closure = r1;
1378  Register new_target = r3;
1379  Register map = argument_count;
1380  Register index = r2;
1381
1382  // Do we have a valid feedback vector?
1383  __ ldr(index, FieldMemOperand(closure, JSFunction::kFeedbackVectorOffset));
1384  __ ldr(index, FieldMemOperand(index, Cell::kValueOffset));
1385  __ JumpIfRoot(index, Heap::kUndefinedValueRootIndex,
1386                &gotta_call_runtime_no_stack);
1387
1388  __ push(argument_count);
1389  __ push(new_target);
1390  __ push(closure);
1391
1392  __ ldr(map, FieldMemOperand(closure, JSFunction::kSharedFunctionInfoOffset));
1393  __ ldr(map,
1394         FieldMemOperand(map, SharedFunctionInfo::kOptimizedCodeMapOffset));
1395  __ ldr(index, FieldMemOperand(map, FixedArray::kLengthOffset));
1396  __ cmp(index, Operand(Smi::FromInt(2)));
1397  __ b(lt, &try_shared);
1398
1399  // r3  : native context
1400  // r2  : length / index
1401  // r0  : optimized code map
1402  // stack[0] : new target
1403  // stack[4] : closure
1404  Register native_context = r3;
1405  __ ldr(native_context, NativeContextMemOperand());
1406
1407  __ bind(&loop_top);
1408  Register temp = r1;
1409  Register array_pointer = r5;
1410
1411  // Does the native context match?
1412  __ add(array_pointer, map, Operand::PointerOffsetFromSmiKey(index));
1413  __ ldr(temp, FieldMemOperand(array_pointer,
1414                               SharedFunctionInfo::kOffsetToPreviousContext));
1415  __ ldr(temp, FieldMemOperand(temp, WeakCell::kValueOffset));
1416  __ cmp(temp, native_context);
1417  __ b(ne, &loop_bottom);
1418
1419  // Code available?
1420  Register entry = r4;
1421  __ ldr(entry,
1422         FieldMemOperand(array_pointer,
1423                         SharedFunctionInfo::kOffsetToPreviousCachedCode));
1424  __ ldr(entry, FieldMemOperand(entry, WeakCell::kValueOffset));
1425  __ JumpIfSmi(entry, &try_shared);
1426
1427  // Found code. Get it into the closure and return.
1428  __ pop(closure);
1429  // Store code entry in the closure.
1430  __ add(entry, entry, Operand(Code::kHeaderSize - kHeapObjectTag));
1431  __ str(entry, FieldMemOperand(closure, JSFunction::kCodeEntryOffset));
1432  __ RecordWriteCodeEntryField(closure, entry, r5);
1433
1434  // Link the closure into the optimized function list.
1435  // r4 : code entry
1436  // r3 : native context
1437  // r1 : closure
1438  __ ldr(r5,
1439         ContextMemOperand(native_context, Context::OPTIMIZED_FUNCTIONS_LIST));
1440  __ str(r5, FieldMemOperand(closure, JSFunction::kNextFunctionLinkOffset));
1441  __ RecordWriteField(closure, JSFunction::kNextFunctionLinkOffset, r5, r0,
1442                      kLRHasNotBeenSaved, kDontSaveFPRegs, EMIT_REMEMBERED_SET,
1443                      OMIT_SMI_CHECK);
1444  const int function_list_offset =
1445      Context::SlotOffset(Context::OPTIMIZED_FUNCTIONS_LIST);
1446  __ str(closure,
1447         ContextMemOperand(native_context, Context::OPTIMIZED_FUNCTIONS_LIST));
1448  // Save closure before the write barrier.
1449  __ mov(r5, closure);
1450  __ RecordWriteContextSlot(native_context, function_list_offset, closure, r0,
1451                            kLRHasNotBeenSaved, kDontSaveFPRegs);
1452  __ mov(closure, r5);
1453  __ pop(new_target);
1454  __ pop(argument_count);
1455  __ Jump(entry);
1456
1457  __ bind(&loop_bottom);
1458  __ sub(index, index, Operand(Smi::FromInt(SharedFunctionInfo::kEntryLength)));
1459  __ cmp(index, Operand(Smi::FromInt(1)));
1460  __ b(gt, &loop_top);
1461
1462  // We found no code.
1463  __ bind(&try_shared);
1464  __ pop(closure);
1465  __ pop(new_target);
1466  __ pop(argument_count);
1467  __ ldr(entry,
1468         FieldMemOperand(closure, JSFunction::kSharedFunctionInfoOffset));
1469  // Is the shared function marked for tier up?
1470  __ ldrb(r5, FieldMemOperand(entry,
1471                              SharedFunctionInfo::kMarkedForTierUpByteOffset));
1472  __ tst(r5, Operand(1 << SharedFunctionInfo::kMarkedForTierUpBitWithinByte));
1473  __ b(ne, &gotta_call_runtime_no_stack);
1474
1475  // If SFI points to anything other than CompileLazy, install that.
1476  __ ldr(entry, FieldMemOperand(entry, SharedFunctionInfo::kCodeOffset));
1477  __ Move(r5, masm->CodeObject());
1478  __ cmp(entry, r5);
1479  __ b(eq, &gotta_call_runtime_no_stack);
1480
1481  // Install the SFI's code entry.
1482  __ add(entry, entry, Operand(Code::kHeaderSize - kHeapObjectTag));
1483  __ str(entry, FieldMemOperand(closure, JSFunction::kCodeEntryOffset));
1484  __ RecordWriteCodeEntryField(closure, entry, r5);
1485  __ Jump(entry);
1486
1487  __ bind(&gotta_call_runtime);
1488  __ pop(closure);
1489  __ pop(new_target);
1490  __ pop(argument_count);
1491  __ bind(&gotta_call_runtime_no_stack);
1492  GenerateTailCallToReturnedCode(masm, Runtime::kCompileLazy);
1493}
1494
1495void Builtins::Generate_CompileBaseline(MacroAssembler* masm) {
1496  GenerateTailCallToReturnedCode(masm, Runtime::kCompileBaseline);
1497}
1498
1499void Builtins::Generate_CompileOptimized(MacroAssembler* masm) {
1500  GenerateTailCallToReturnedCode(masm,
1501                                 Runtime::kCompileOptimized_NotConcurrent);
1502}
1503
1504void Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) {
1505  GenerateTailCallToReturnedCode(masm, Runtime::kCompileOptimized_Concurrent);
1506}
1507
1508void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) {
1509  // ----------- S t a t e -------------
1510  //  -- r0 : argument count (preserved for callee)
1511  //  -- r1 : new target (preserved for callee)
1512  //  -- r3 : target function (preserved for callee)
1513  // -----------------------------------
1514  Label failed;
1515  {
1516    FrameScope scope(masm, StackFrame::INTERNAL);
1517    // Preserve argument count for later compare.
1518    __ Move(r4, r0);
1519    // Push the number of arguments to the callee.
1520    __ SmiTag(r0);
1521    __ push(r0);
1522    // Push a copy of the target function and the new target.
1523    __ push(r1);
1524    __ push(r3);
1525
1526    // The function.
1527    __ push(r1);
1528    // Copy arguments from caller (stdlib, foreign, heap).
1529    Label args_done;
1530    for (int j = 0; j < 4; ++j) {
1531      Label over;
1532      if (j < 3) {
1533        __ cmp(r4, Operand(j));
1534        __ b(ne, &over);
1535      }
1536      for (int i = j - 1; i >= 0; --i) {
1537        __ ldr(r4, MemOperand(fp, StandardFrameConstants::kCallerSPOffset +
1538                                      i * kPointerSize));
1539        __ push(r4);
1540      }
1541      for (int i = 0; i < 3 - j; ++i) {
1542        __ PushRoot(Heap::kUndefinedValueRootIndex);
1543      }
1544      if (j < 3) {
1545        __ jmp(&args_done);
1546        __ bind(&over);
1547      }
1548    }
1549    __ bind(&args_done);
1550
1551    // Call runtime, on success unwind frame, and parent frame.
1552    __ CallRuntime(Runtime::kInstantiateAsmJs, 4);
1553    // A smi 0 is returned on failure, an object on success.
1554    __ JumpIfSmi(r0, &failed);
1555
1556    __ Drop(2);
1557    __ pop(r4);
1558    __ SmiUntag(r4);
1559    scope.GenerateLeaveFrame();
1560
1561    __ add(r4, r4, Operand(1));
1562    __ Drop(r4);
1563    __ Ret();
1564
1565    __ bind(&failed);
1566    // Restore target function and new target.
1567    __ pop(r3);
1568    __ pop(r1);
1569    __ pop(r0);
1570    __ SmiUntag(r0);
1571  }
1572  // On failure, tail call back to regular js.
1573  GenerateTailCallToReturnedCode(masm, Runtime::kCompileLazy);
1574}
1575
1576static void GenerateMakeCodeYoungAgainCommon(MacroAssembler* masm) {
1577  // For now, we are relying on the fact that make_code_young doesn't do any
1578  // garbage collection which allows us to save/restore the registers without
1579  // worrying about which of them contain pointers. We also don't build an
1580  // internal frame to make the code faster, since we shouldn't have to do stack
1581  // crawls in MakeCodeYoung. This seems a bit fragile.
1582
1583  // The following registers must be saved and restored when calling through to
1584  // the runtime:
1585  //   r0 - contains return address (beginning of patch sequence)
1586  //   r1 - isolate
1587  //   r3 - new target
1588  FrameScope scope(masm, StackFrame::MANUAL);
1589  __ stm(db_w, sp, r0.bit() | r1.bit() | r3.bit() | fp.bit() | lr.bit());
1590  __ PrepareCallCFunction(2, 0, r2);
1591  __ mov(r1, Operand(ExternalReference::isolate_address(masm->isolate())));
1592  __ CallCFunction(
1593      ExternalReference::get_make_code_young_function(masm->isolate()), 2);
1594  __ ldm(ia_w, sp, r0.bit() | r1.bit() | r3.bit() | fp.bit() | lr.bit());
1595  __ mov(pc, r0);
1596}
1597
1598#define DEFINE_CODE_AGE_BUILTIN_GENERATOR(C)                              \
1599  void Builtins::Generate_Make##C##CodeYoungAgain(MacroAssembler* masm) { \
1600    GenerateMakeCodeYoungAgainCommon(masm);                               \
1601  }
1602CODE_AGE_LIST(DEFINE_CODE_AGE_BUILTIN_GENERATOR)
1603#undef DEFINE_CODE_AGE_BUILTIN_GENERATOR
1604
1605void Builtins::Generate_MarkCodeAsExecutedOnce(MacroAssembler* masm) {
1606  // For now, as in GenerateMakeCodeYoungAgainCommon, we are relying on the fact
1607  // that make_code_young doesn't do any garbage collection which allows us to
1608  // save/restore the registers without worrying about which of them contain
1609  // pointers.
1610
1611  // The following registers must be saved and restored when calling through to
1612  // the runtime:
1613  //   r0 - contains return address (beginning of patch sequence)
1614  //   r1 - isolate
1615  //   r3 - new target
1616  FrameScope scope(masm, StackFrame::MANUAL);
1617  __ stm(db_w, sp, r0.bit() | r1.bit() | r3.bit() | fp.bit() | lr.bit());
1618  __ PrepareCallCFunction(2, 0, r2);
1619  __ mov(r1, Operand(ExternalReference::isolate_address(masm->isolate())));
1620  __ CallCFunction(
1621      ExternalReference::get_mark_code_as_executed_function(masm->isolate()),
1622      2);
1623  __ ldm(ia_w, sp, r0.bit() | r1.bit() | r3.bit() | fp.bit() | lr.bit());
1624
1625  // Perform prologue operations usually performed by the young code stub.
1626  __ PushStandardFrame(r1);
1627
1628  // Jump to point after the code-age stub.
1629  __ add(r0, r0, Operand(kNoCodeAgeSequenceLength));
1630  __ mov(pc, r0);
1631}
1632
1633void Builtins::Generate_MarkCodeAsExecutedTwice(MacroAssembler* masm) {
1634  GenerateMakeCodeYoungAgainCommon(masm);
1635}
1636
1637void Builtins::Generate_MarkCodeAsToBeExecutedOnce(MacroAssembler* masm) {
1638  Generate_MarkCodeAsExecutedOnce(masm);
1639}
1640
1641static void Generate_NotifyStubFailureHelper(MacroAssembler* masm,
1642                                             SaveFPRegsMode save_doubles) {
1643  {
1644    FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
1645
1646    // Preserve registers across notification, this is important for compiled
1647    // stubs that tail call the runtime on deopts passing their parameters in
1648    // registers.
1649    __ stm(db_w, sp, kJSCallerSaved | kCalleeSaved);
1650    // Pass the function and deoptimization type to the runtime system.
1651    __ CallRuntime(Runtime::kNotifyStubFailure, save_doubles);
1652    __ ldm(ia_w, sp, kJSCallerSaved | kCalleeSaved);
1653  }
1654
1655  __ add(sp, sp, Operand(kPointerSize));  // Ignore state
1656  __ mov(pc, lr);                         // Jump to miss handler
1657}
1658
1659void Builtins::Generate_NotifyStubFailure(MacroAssembler* masm) {
1660  Generate_NotifyStubFailureHelper(masm, kDontSaveFPRegs);
1661}
1662
1663void Builtins::Generate_NotifyStubFailureSaveDoubles(MacroAssembler* masm) {
1664  Generate_NotifyStubFailureHelper(masm, kSaveFPRegs);
1665}
1666
1667static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm,
1668                                             Deoptimizer::BailoutType type) {
1669  {
1670    FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
1671    // Pass the function and deoptimization type to the runtime system.
1672    __ mov(r0, Operand(Smi::FromInt(static_cast<int>(type))));
1673    __ push(r0);
1674    __ CallRuntime(Runtime::kNotifyDeoptimized);
1675  }
1676
1677  // Get the full codegen state from the stack and untag it -> r6.
1678  __ ldr(r6, MemOperand(sp, 0 * kPointerSize));
1679  __ SmiUntag(r6);
1680  // Switch on the state.
1681  Label with_tos_register, unknown_state;
1682  __ cmp(r6,
1683         Operand(static_cast<int>(Deoptimizer::BailoutState::NO_REGISTERS)));
1684  __ b(ne, &with_tos_register);
1685  __ add(sp, sp, Operand(1 * kPointerSize));  // Remove state.
1686  __ Ret();
1687
1688  __ bind(&with_tos_register);
1689  DCHECK_EQ(kInterpreterAccumulatorRegister.code(), r0.code());
1690  __ ldr(r0, MemOperand(sp, 1 * kPointerSize));
1691  __ cmp(r6,
1692         Operand(static_cast<int>(Deoptimizer::BailoutState::TOS_REGISTER)));
1693  __ b(ne, &unknown_state);
1694  __ add(sp, sp, Operand(2 * kPointerSize));  // Remove state.
1695  __ Ret();
1696
1697  __ bind(&unknown_state);
1698  __ stop("no cases left");
1699}
1700
1701void Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) {
1702  Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::EAGER);
1703}
1704
1705void Builtins::Generate_NotifySoftDeoptimized(MacroAssembler* masm) {
1706  Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::SOFT);
1707}
1708
1709void Builtins::Generate_NotifyLazyDeoptimized(MacroAssembler* masm) {
1710  Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::LAZY);
1711}
1712
1713static void CompatibleReceiverCheck(MacroAssembler* masm, Register receiver,
1714                                    Register function_template_info,
1715                                    Register scratch0, Register scratch1,
1716                                    Register scratch2,
1717                                    Label* receiver_check_failed) {
1718  Register signature = scratch0;
1719  Register map = scratch1;
1720  Register constructor = scratch2;
1721
1722  // If there is no signature, return the holder.
1723  __ ldr(signature, FieldMemOperand(function_template_info,
1724                                    FunctionTemplateInfo::kSignatureOffset));
1725  __ CompareRoot(signature, Heap::kUndefinedValueRootIndex);
1726  Label receiver_check_passed;
1727  __ b(eq, &receiver_check_passed);
1728
1729  // Walk the prototype chain.
1730  __ ldr(map, FieldMemOperand(receiver, HeapObject::kMapOffset));
1731  Label prototype_loop_start;
1732  __ bind(&prototype_loop_start);
1733
1734  // Get the constructor, if any.
1735  __ GetMapConstructor(constructor, map, ip, ip);
1736  __ cmp(ip, Operand(JS_FUNCTION_TYPE));
1737  Label next_prototype;
1738  __ b(ne, &next_prototype);
1739  Register type = constructor;
1740  __ ldr(type,
1741         FieldMemOperand(constructor, JSFunction::kSharedFunctionInfoOffset));
1742  __ ldr(type, FieldMemOperand(type, SharedFunctionInfo::kFunctionDataOffset));
1743
1744  // Loop through the chain of inheriting function templates.
1745  Label function_template_loop;
1746  __ bind(&function_template_loop);
1747
1748  // If the signatures match, we have a compatible receiver.
1749  __ cmp(signature, type);
1750  __ b(eq, &receiver_check_passed);
1751
1752  // If the current type is not a FunctionTemplateInfo, load the next prototype
1753  // in the chain.
1754  __ JumpIfSmi(type, &next_prototype);
1755  __ CompareObjectType(type, ip, ip, FUNCTION_TEMPLATE_INFO_TYPE);
1756
1757  // Otherwise load the parent function template and iterate.
1758  __ ldr(type,
1759         FieldMemOperand(type, FunctionTemplateInfo::kParentTemplateOffset),
1760         eq);
1761  __ b(&function_template_loop, eq);
1762
1763  // Load the next prototype.
1764  __ bind(&next_prototype);
1765  __ ldr(ip, FieldMemOperand(map, Map::kBitField3Offset));
1766  __ tst(ip, Operand(Map::HasHiddenPrototype::kMask));
1767  __ b(eq, receiver_check_failed);
1768  __ ldr(receiver, FieldMemOperand(map, Map::kPrototypeOffset));
1769  __ ldr(map, FieldMemOperand(receiver, HeapObject::kMapOffset));
1770  // Iterate.
1771  __ b(&prototype_loop_start);
1772
1773  __ bind(&receiver_check_passed);
1774}
1775
1776void Builtins::Generate_HandleFastApiCall(MacroAssembler* masm) {
1777  // ----------- S t a t e -------------
1778  //  -- r0                 : number of arguments excluding receiver
1779  //  -- r1                 : callee
1780  //  -- lr                 : return address
1781  //  -- sp[0]              : last argument
1782  //  -- ...
1783  //  -- sp[4 * (argc - 1)] : first argument
1784  //  -- sp[4 * argc]       : receiver
1785  // -----------------------------------
1786
1787  // Load the FunctionTemplateInfo.
1788  __ ldr(r3, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
1789  __ ldr(r3, FieldMemOperand(r3, SharedFunctionInfo::kFunctionDataOffset));
1790
1791  // Do the compatible receiver check.
1792  Label receiver_check_failed;
1793  __ ldr(r2, MemOperand(sp, r0, LSL, kPointerSizeLog2));
1794  CompatibleReceiverCheck(masm, r2, r3, r4, r5, r6, &receiver_check_failed);
1795
1796  // Get the callback offset from the FunctionTemplateInfo, and jump to the
1797  // beginning of the code.
1798  __ ldr(r4, FieldMemOperand(r3, FunctionTemplateInfo::kCallCodeOffset));
1799  __ ldr(r4, FieldMemOperand(r4, CallHandlerInfo::kFastHandlerOffset));
1800  __ add(r4, r4, Operand(Code::kHeaderSize - kHeapObjectTag));
1801  __ Jump(r4);
1802
1803  // Compatible receiver check failed: throw an Illegal Invocation exception.
1804  __ bind(&receiver_check_failed);
1805  // Drop the arguments (including the receiver)
1806  __ add(r0, r0, Operand(1));
1807  __ add(sp, sp, Operand(r0, LSL, kPointerSizeLog2));
1808  __ TailCallRuntime(Runtime::kThrowIllegalInvocation);
1809}
1810
1811static void Generate_OnStackReplacementHelper(MacroAssembler* masm,
1812                                              bool has_handler_frame) {
1813  // Lookup the function in the JavaScript frame.
1814  if (has_handler_frame) {
1815    __ ldr(r0, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
1816    __ ldr(r0, MemOperand(r0, JavaScriptFrameConstants::kFunctionOffset));
1817  } else {
1818    __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
1819  }
1820
1821  {
1822    FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
1823    // Pass function as argument.
1824    __ push(r0);
1825    __ CallRuntime(Runtime::kCompileForOnStackReplacement);
1826  }
1827
1828  // If the code object is null, just return to the caller.
1829  Label skip;
1830  __ cmp(r0, Operand(Smi::kZero));
1831  __ b(ne, &skip);
1832  __ Ret();
1833
1834  __ bind(&skip);
1835
1836  // Drop any potential handler frame that is be sitting on top of the actual
1837  // JavaScript frame. This is the case then OSR is triggered from bytecode.
1838  if (has_handler_frame) {
1839    __ LeaveFrame(StackFrame::STUB);
1840  }
1841
1842  // Load deoptimization data from the code object.
1843  // <deopt_data> = <code>[#deoptimization_data_offset]
1844  __ ldr(r1, FieldMemOperand(r0, Code::kDeoptimizationDataOffset));
1845
1846  {
1847    ConstantPoolUnavailableScope constant_pool_unavailable(masm);
1848    __ add(r0, r0, Operand(Code::kHeaderSize - kHeapObjectTag));  // Code start
1849
1850    if (FLAG_enable_embedded_constant_pool) {
1851      __ LoadConstantPoolPointerRegisterFromCodeTargetAddress(r0);
1852    }
1853
1854    // Load the OSR entrypoint offset from the deoptimization data.
1855    // <osr_offset> = <deopt_data>[#header_size + #osr_pc_offset]
1856    __ ldr(r1, FieldMemOperand(
1857                   r1, FixedArray::OffsetOfElementAt(
1858                           DeoptimizationInputData::kOsrPcOffsetIndex)));
1859
1860    // Compute the target address = code start + osr_offset
1861    __ add(lr, r0, Operand::SmiUntag(r1));
1862
1863    // And "return" to the OSR entry point of the function.
1864    __ Ret();
1865  }
1866}
1867
1868void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) {
1869  Generate_OnStackReplacementHelper(masm, false);
1870}
1871
1872void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) {
1873  Generate_OnStackReplacementHelper(masm, true);
1874}
1875
1876// static
1877void Builtins::Generate_FunctionPrototypeApply(MacroAssembler* masm) {
1878  // ----------- S t a t e -------------
1879  //  -- r0    : argc
1880  //  -- sp[0] : argArray
1881  //  -- sp[4] : thisArg
1882  //  -- sp[8] : receiver
1883  // -----------------------------------
1884
1885  // 1. Load receiver into r1, argArray into r0 (if present), remove all
1886  // arguments from the stack (including the receiver), and push thisArg (if
1887  // present) instead.
1888  {
1889    __ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
1890    __ mov(r3, r2);
1891    __ ldr(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2));  // receiver
1892    __ sub(r4, r0, Operand(1), SetCC);
1893    __ ldr(r2, MemOperand(sp, r4, LSL, kPointerSizeLog2), ge);  // thisArg
1894    __ sub(r4, r4, Operand(1), SetCC, ge);
1895    __ ldr(r3, MemOperand(sp, r4, LSL, kPointerSizeLog2), ge);  // argArray
1896    __ add(sp, sp, Operand(r0, LSL, kPointerSizeLog2));
1897    __ str(r2, MemOperand(sp, 0));
1898    __ mov(r0, r3);
1899  }
1900
1901  // ----------- S t a t e -------------
1902  //  -- r0    : argArray
1903  //  -- r1    : receiver
1904  //  -- sp[0] : thisArg
1905  // -----------------------------------
1906
1907  // 2. Make sure the receiver is actually callable.
1908  Label receiver_not_callable;
1909  __ JumpIfSmi(r1, &receiver_not_callable);
1910  __ ldr(r4, FieldMemOperand(r1, HeapObject::kMapOffset));
1911  __ ldrb(r4, FieldMemOperand(r4, Map::kBitFieldOffset));
1912  __ tst(r4, Operand(1 << Map::kIsCallable));
1913  __ b(eq, &receiver_not_callable);
1914
1915  // 3. Tail call with no arguments if argArray is null or undefined.
1916  Label no_arguments;
1917  __ JumpIfRoot(r0, Heap::kNullValueRootIndex, &no_arguments);
1918  __ JumpIfRoot(r0, Heap::kUndefinedValueRootIndex, &no_arguments);
1919
1920  // 4a. Apply the receiver to the given argArray (passing undefined for
1921  // new.target).
1922  __ LoadRoot(r3, Heap::kUndefinedValueRootIndex);
1923  __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET);
1924
1925  // 4b. The argArray is either null or undefined, so we tail call without any
1926  // arguments to the receiver.
1927  __ bind(&no_arguments);
1928  {
1929    __ mov(r0, Operand(0));
1930    __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
1931  }
1932
1933  // 4c. The receiver is not callable, throw an appropriate TypeError.
1934  __ bind(&receiver_not_callable);
1935  {
1936    __ str(r1, MemOperand(sp, 0));
1937    __ TailCallRuntime(Runtime::kThrowApplyNonFunction);
1938  }
1939}
1940
1941// static
1942void Builtins::Generate_FunctionPrototypeCall(MacroAssembler* masm) {
1943  // 1. Make sure we have at least one argument.
1944  // r0: actual number of arguments
1945  {
1946    Label done;
1947    __ cmp(r0, Operand::Zero());
1948    __ b(ne, &done);
1949    __ PushRoot(Heap::kUndefinedValueRootIndex);
1950    __ add(r0, r0, Operand(1));
1951    __ bind(&done);
1952  }
1953
1954  // 2. Get the callable to call (passed as receiver) from the stack.
1955  // r0: actual number of arguments
1956  __ ldr(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2));
1957
1958  // 3. Shift arguments and return address one slot down on the stack
1959  //    (overwriting the original receiver).  Adjust argument count to make
1960  //    the original first argument the new receiver.
1961  // r0: actual number of arguments
1962  // r1: callable
1963  {
1964    Label loop;
1965    // Calculate the copy start address (destination). Copy end address is sp.
1966    __ add(r2, sp, Operand(r0, LSL, kPointerSizeLog2));
1967
1968    __ bind(&loop);
1969    __ ldr(ip, MemOperand(r2, -kPointerSize));
1970    __ str(ip, MemOperand(r2));
1971    __ sub(r2, r2, Operand(kPointerSize));
1972    __ cmp(r2, sp);
1973    __ b(ne, &loop);
1974    // Adjust the actual number of arguments and remove the top element
1975    // (which is a copy of the last argument).
1976    __ sub(r0, r0, Operand(1));
1977    __ pop();
1978  }
1979
1980  // 4. Call the callable.
1981  __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
1982}
1983
1984void Builtins::Generate_ReflectApply(MacroAssembler* masm) {
1985  // ----------- S t a t e -------------
1986  //  -- r0     : argc
1987  //  -- sp[0]  : argumentsList
1988  //  -- sp[4]  : thisArgument
1989  //  -- sp[8]  : target
1990  //  -- sp[12] : receiver
1991  // -----------------------------------
1992
1993  // 1. Load target into r1 (if present), argumentsList into r0 (if present),
1994  // remove all arguments from the stack (including the receiver), and push
1995  // thisArgument (if present) instead.
1996  {
1997    __ LoadRoot(r1, Heap::kUndefinedValueRootIndex);
1998    __ mov(r2, r1);
1999    __ mov(r3, r1);
2000    __ sub(r4, r0, Operand(1), SetCC);
2001    __ ldr(r1, MemOperand(sp, r4, LSL, kPointerSizeLog2), ge);  // target
2002    __ sub(r4, r4, Operand(1), SetCC, ge);
2003    __ ldr(r2, MemOperand(sp, r4, LSL, kPointerSizeLog2), ge);  // thisArgument
2004    __ sub(r4, r4, Operand(1), SetCC, ge);
2005    __ ldr(r3, MemOperand(sp, r4, LSL, kPointerSizeLog2), ge);  // argumentsList
2006    __ add(sp, sp, Operand(r0, LSL, kPointerSizeLog2));
2007    __ str(r2, MemOperand(sp, 0));
2008    __ mov(r0, r3);
2009  }
2010
2011  // ----------- S t a t e -------------
2012  //  -- r0    : argumentsList
2013  //  -- r1    : target
2014  //  -- sp[0] : thisArgument
2015  // -----------------------------------
2016
2017  // 2. Make sure the target is actually callable.
2018  Label target_not_callable;
2019  __ JumpIfSmi(r1, &target_not_callable);
2020  __ ldr(r4, FieldMemOperand(r1, HeapObject::kMapOffset));
2021  __ ldrb(r4, FieldMemOperand(r4, Map::kBitFieldOffset));
2022  __ tst(r4, Operand(1 << Map::kIsCallable));
2023  __ b(eq, &target_not_callable);
2024
2025  // 3a. Apply the target to the given argumentsList (passing undefined for
2026  // new.target).
2027  __ LoadRoot(r3, Heap::kUndefinedValueRootIndex);
2028  __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET);
2029
2030  // 3b. The target is not callable, throw an appropriate TypeError.
2031  __ bind(&target_not_callable);
2032  {
2033    __ str(r1, MemOperand(sp, 0));
2034    __ TailCallRuntime(Runtime::kThrowApplyNonFunction);
2035  }
2036}
2037
2038void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) {
2039  // ----------- S t a t e -------------
2040  //  -- r0     : argc
2041  //  -- sp[0]  : new.target (optional)
2042  //  -- sp[4]  : argumentsList
2043  //  -- sp[8]  : target
2044  //  -- sp[12] : receiver
2045  // -----------------------------------
2046
2047  // 1. Load target into r1 (if present), argumentsList into r0 (if present),
2048  // new.target into r3 (if present, otherwise use target), remove all
2049  // arguments from the stack (including the receiver), and push thisArgument
2050  // (if present) instead.
2051  {
2052    __ LoadRoot(r1, Heap::kUndefinedValueRootIndex);
2053    __ mov(r2, r1);
2054    __ str(r2, MemOperand(sp, r0, LSL, kPointerSizeLog2));  // receiver
2055    __ sub(r4, r0, Operand(1), SetCC);
2056    __ ldr(r1, MemOperand(sp, r4, LSL, kPointerSizeLog2), ge);  // target
2057    __ mov(r3, r1);  // new.target defaults to target
2058    __ sub(r4, r4, Operand(1), SetCC, ge);
2059    __ ldr(r2, MemOperand(sp, r4, LSL, kPointerSizeLog2), ge);  // argumentsList
2060    __ sub(r4, r4, Operand(1), SetCC, ge);
2061    __ ldr(r3, MemOperand(sp, r4, LSL, kPointerSizeLog2), ge);  // new.target
2062    __ add(sp, sp, Operand(r0, LSL, kPointerSizeLog2));
2063    __ mov(r0, r2);
2064  }
2065
2066  // ----------- S t a t e -------------
2067  //  -- r0    : argumentsList
2068  //  -- r3    : new.target
2069  //  -- r1    : target
2070  //  -- sp[0] : receiver (undefined)
2071  // -----------------------------------
2072
2073  // 2. Make sure the target is actually a constructor.
2074  Label target_not_constructor;
2075  __ JumpIfSmi(r1, &target_not_constructor);
2076  __ ldr(r4, FieldMemOperand(r1, HeapObject::kMapOffset));
2077  __ ldrb(r4, FieldMemOperand(r4, Map::kBitFieldOffset));
2078  __ tst(r4, Operand(1 << Map::kIsConstructor));
2079  __ b(eq, &target_not_constructor);
2080
2081  // 3. Make sure the target is actually a constructor.
2082  Label new_target_not_constructor;
2083  __ JumpIfSmi(r3, &new_target_not_constructor);
2084  __ ldr(r4, FieldMemOperand(r3, HeapObject::kMapOffset));
2085  __ ldrb(r4, FieldMemOperand(r4, Map::kBitFieldOffset));
2086  __ tst(r4, Operand(1 << Map::kIsConstructor));
2087  __ b(eq, &new_target_not_constructor);
2088
2089  // 4a. Construct the target with the given new.target and argumentsList.
2090  __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET);
2091
2092  // 4b. The target is not a constructor, throw an appropriate TypeError.
2093  __ bind(&target_not_constructor);
2094  {
2095    __ str(r1, MemOperand(sp, 0));
2096    __ TailCallRuntime(Runtime::kThrowNotConstructor);
2097  }
2098
2099  // 4c. The new.target is not a constructor, throw an appropriate TypeError.
2100  __ bind(&new_target_not_constructor);
2101  {
2102    __ str(r3, MemOperand(sp, 0));
2103    __ TailCallRuntime(Runtime::kThrowNotConstructor);
2104  }
2105}
2106
2107static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
2108  __ SmiTag(r0);
2109  __ mov(r4, Operand(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)));
2110  __ stm(db_w, sp, r0.bit() | r1.bit() | r4.bit() |
2111                       (FLAG_enable_embedded_constant_pool ? pp.bit() : 0) |
2112                       fp.bit() | lr.bit());
2113  __ add(fp, sp,
2114         Operand(StandardFrameConstants::kFixedFrameSizeFromFp + kPointerSize));
2115}
2116
2117static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) {
2118  // ----------- S t a t e -------------
2119  //  -- r0 : result being passed through
2120  // -----------------------------------
2121  // Get the number of arguments passed (as a smi), tear down the frame and
2122  // then tear down the parameters.
2123  __ ldr(r1, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp +
2124                              kPointerSize)));
2125
2126  __ LeaveFrame(StackFrame::ARGUMENTS_ADAPTOR);
2127  __ add(sp, sp, Operand::PointerOffsetFromSmiKey(r1));
2128  __ add(sp, sp, Operand(kPointerSize));  // adjust for receiver
2129}
2130
2131// static
2132void Builtins::Generate_Apply(MacroAssembler* masm) {
2133  // ----------- S t a t e -------------
2134  //  -- r0    : argumentsList
2135  //  -- r1    : target
2136  //  -- r3    : new.target (checked to be constructor or undefined)
2137  //  -- sp[0] : thisArgument
2138  // -----------------------------------
2139
2140  // Create the list of arguments from the array-like argumentsList.
2141  {
2142    Label create_arguments, create_array, create_holey_array, create_runtime,
2143        done_create;
2144    __ JumpIfSmi(r0, &create_runtime);
2145
2146    // Load the map of argumentsList into r2.
2147    __ ldr(r2, FieldMemOperand(r0, HeapObject::kMapOffset));
2148
2149    // Load native context into r4.
2150    __ ldr(r4, NativeContextMemOperand());
2151
2152    // Check if argumentsList is an (unmodified) arguments object.
2153    __ ldr(ip, ContextMemOperand(r4, Context::SLOPPY_ARGUMENTS_MAP_INDEX));
2154    __ cmp(ip, r2);
2155    __ b(eq, &create_arguments);
2156    __ ldr(ip, ContextMemOperand(r4, Context::STRICT_ARGUMENTS_MAP_INDEX));
2157    __ cmp(ip, r2);
2158    __ b(eq, &create_arguments);
2159
2160    // Check if argumentsList is a fast JSArray.
2161    __ CompareInstanceType(r2, ip, JS_ARRAY_TYPE);
2162    __ b(eq, &create_array);
2163
2164    // Ask the runtime to create the list (actually a FixedArray).
2165    __ bind(&create_runtime);
2166    {
2167      FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
2168      __ Push(r1, r3, r0);
2169      __ CallRuntime(Runtime::kCreateListFromArrayLike);
2170      __ Pop(r1, r3);
2171      __ ldr(r2, FieldMemOperand(r0, FixedArray::kLengthOffset));
2172      __ SmiUntag(r2);
2173    }
2174    __ jmp(&done_create);
2175
2176    // Try to create the list from an arguments object.
2177    __ bind(&create_arguments);
2178    __ ldr(r2, FieldMemOperand(r0, JSArgumentsObject::kLengthOffset));
2179    __ ldr(r4, FieldMemOperand(r0, JSObject::kElementsOffset));
2180    __ ldr(ip, FieldMemOperand(r4, FixedArray::kLengthOffset));
2181    __ cmp(r2, ip);
2182    __ b(ne, &create_runtime);
2183    __ SmiUntag(r2);
2184    __ mov(r0, r4);
2185    __ b(&done_create);
2186
2187    // For holey JSArrays we need to check that the array prototype chain
2188    // protector is intact and our prototype is the Array.prototype actually.
2189    __ bind(&create_holey_array);
2190    __ ldr(r2, FieldMemOperand(r2, Map::kPrototypeOffset));
2191    __ ldr(r4, ContextMemOperand(r4, Context::INITIAL_ARRAY_PROTOTYPE_INDEX));
2192    __ cmp(r2, r4);
2193    __ b(ne, &create_runtime);
2194    __ LoadRoot(r4, Heap::kArrayProtectorRootIndex);
2195    __ ldr(r2, FieldMemOperand(r4, PropertyCell::kValueOffset));
2196    __ cmp(r2, Operand(Smi::FromInt(Isolate::kProtectorValid)));
2197    __ b(ne, &create_runtime);
2198    __ ldr(r2, FieldMemOperand(r0, JSArray::kLengthOffset));
2199    __ ldr(r0, FieldMemOperand(r0, JSArray::kElementsOffset));
2200    __ SmiUntag(r2);
2201    __ b(&done_create);
2202
2203    // Try to create the list from a JSArray object.
2204    //  -- r2 and r4 must be preserved till bne create_holey_array.
2205    __ bind(&create_array);
2206    __ ldr(r5, FieldMemOperand(r2, Map::kBitField2Offset));
2207    __ DecodeField<Map::ElementsKindBits>(r5);
2208    STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
2209    STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
2210    STATIC_ASSERT(FAST_ELEMENTS == 2);
2211    STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3);
2212    __ cmp(r5, Operand(FAST_HOLEY_ELEMENTS));
2213    __ b(hi, &create_runtime);
2214    // Only FAST_XXX after this point, FAST_HOLEY_XXX are odd values.
2215    __ tst(r5, Operand(1));
2216    __ b(ne, &create_holey_array);
2217    // FAST_SMI_ELEMENTS or FAST_ELEMENTS after this point.
2218    __ ldr(r2, FieldMemOperand(r0, JSArray::kLengthOffset));
2219    __ ldr(r0, FieldMemOperand(r0, JSArray::kElementsOffset));
2220    __ SmiUntag(r2);
2221
2222    __ bind(&done_create);
2223  }
2224
2225  // Check for stack overflow.
2226  {
2227    // Check the stack for overflow. We are not trying to catch interruptions
2228    // (i.e. debug break and preemption) here, so check the "real stack limit".
2229    Label done;
2230    __ LoadRoot(ip, Heap::kRealStackLimitRootIndex);
2231    // Make ip the space we have left. The stack might already be overflowed
2232    // here which will cause ip to become negative.
2233    __ sub(ip, sp, ip);
2234    // Check if the arguments will overflow the stack.
2235    __ cmp(ip, Operand(r2, LSL, kPointerSizeLog2));
2236    __ b(gt, &done);  // Signed comparison.
2237    __ TailCallRuntime(Runtime::kThrowStackOverflow);
2238    __ bind(&done);
2239  }
2240
2241  // ----------- S t a t e -------------
2242  //  -- r1    : target
2243  //  -- r0    : args (a FixedArray built from argumentsList)
2244  //  -- r2    : len (number of elements to push from args)
2245  //  -- r3    : new.target (checked to be constructor or undefined)
2246  //  -- sp[0] : thisArgument
2247  // -----------------------------------
2248
2249  // Push arguments onto the stack (thisArgument is already on the stack).
2250  {
2251    __ mov(r4, Operand(0));
2252    __ LoadRoot(r5, Heap::kTheHoleValueRootIndex);
2253    __ LoadRoot(r6, Heap::kUndefinedValueRootIndex);
2254    Label done, loop;
2255    __ bind(&loop);
2256    __ cmp(r4, r2);
2257    __ b(eq, &done);
2258    __ add(ip, r0, Operand(r4, LSL, kPointerSizeLog2));
2259    __ ldr(ip, FieldMemOperand(ip, FixedArray::kHeaderSize));
2260    __ cmp(r5, ip);
2261    __ mov(ip, r6, LeaveCC, eq);
2262    __ Push(ip);
2263    __ add(r4, r4, Operand(1));
2264    __ b(&loop);
2265    __ bind(&done);
2266    __ Move(r0, r4);
2267  }
2268
2269  // Dispatch to Call or Construct depending on whether new.target is undefined.
2270  {
2271    __ CompareRoot(r3, Heap::kUndefinedValueRootIndex);
2272    __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET, eq);
2273    __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
2274  }
2275}
2276
2277// static
2278void Builtins::Generate_CallForwardVarargs(MacroAssembler* masm,
2279                                           Handle<Code> code) {
2280  // ----------- S t a t e -------------
2281  //  -- r1    : the target to call (can be any Object)
2282  //  -- r2    : start index (to support rest parameters)
2283  //  -- lr    : return address.
2284  //  -- sp[0] : thisArgument
2285  // -----------------------------------
2286
2287  // Check if we have an arguments adaptor frame below the function frame.
2288  Label arguments_adaptor, arguments_done;
2289  __ ldr(r3, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
2290  __ ldr(ip, MemOperand(r3, CommonFrameConstants::kContextOrFrameTypeOffset));
2291  __ cmp(ip, Operand(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)));
2292  __ b(eq, &arguments_adaptor);
2293  {
2294    __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
2295    __ ldr(r0, FieldMemOperand(r0, JSFunction::kSharedFunctionInfoOffset));
2296    __ ldr(r0, FieldMemOperand(
2297                   r0, SharedFunctionInfo::kFormalParameterCountOffset));
2298    __ mov(r3, fp);
2299  }
2300  __ b(&arguments_done);
2301  __ bind(&arguments_adaptor);
2302  {
2303    // Load the length from the ArgumentsAdaptorFrame.
2304    __ ldr(r0, MemOperand(r3, ArgumentsAdaptorFrameConstants::kLengthOffset));
2305  }
2306  __ bind(&arguments_done);
2307
2308  Label stack_empty, stack_done, stack_overflow;
2309  __ SmiUntag(r0);
2310  __ sub(r0, r0, r2, SetCC);
2311  __ b(le, &stack_empty);
2312  {
2313    // Check for stack overflow.
2314    Generate_StackOverflowCheck(masm, r0, r2, &stack_overflow);
2315
2316    // Forward the arguments from the caller frame.
2317    {
2318      Label loop;
2319      __ add(r3, r3, Operand(kPointerSize));
2320      __ mov(r2, r0);
2321      __ bind(&loop);
2322      {
2323        __ ldr(ip, MemOperand(r3, r2, LSL, kPointerSizeLog2));
2324        __ push(ip);
2325        __ sub(r2, r2, Operand(1), SetCC);
2326        __ b(ne, &loop);
2327      }
2328    }
2329  }
2330  __ b(&stack_done);
2331  __ bind(&stack_overflow);
2332  __ TailCallRuntime(Runtime::kThrowStackOverflow);
2333  __ bind(&stack_empty);
2334  {
2335    // We just pass the receiver, which is already on the stack.
2336    __ mov(r0, Operand(0));
2337  }
2338  __ bind(&stack_done);
2339
2340  __ Jump(code, RelocInfo::CODE_TARGET);
2341}
2342
2343namespace {
2344
2345// Drops top JavaScript frame and an arguments adaptor frame below it (if
2346// present) preserving all the arguments prepared for current call.
2347// Does nothing if debugger is currently active.
2348// ES6 14.6.3. PrepareForTailCall
2349//
2350// Stack structure for the function g() tail calling f():
2351//
2352// ------- Caller frame: -------
2353// |  ...
2354// |  g()'s arg M
2355// |  ...
2356// |  g()'s arg 1
2357// |  g()'s receiver arg
2358// |  g()'s caller pc
2359// ------- g()'s frame: -------
2360// |  g()'s caller fp      <- fp
2361// |  g()'s context
2362// |  function pointer: g
2363// |  -------------------------
2364// |  ...
2365// |  ...
2366// |  f()'s arg N
2367// |  ...
2368// |  f()'s arg 1
2369// |  f()'s receiver arg   <- sp (f()'s caller pc is not on the stack yet!)
2370// ----------------------
2371//
2372void PrepareForTailCall(MacroAssembler* masm, Register args_reg,
2373                        Register scratch1, Register scratch2,
2374                        Register scratch3) {
2375  DCHECK(!AreAliased(args_reg, scratch1, scratch2, scratch3));
2376  Comment cmnt(masm, "[ PrepareForTailCall");
2377
2378  // Prepare for tail call only if ES2015 tail call elimination is enabled.
2379  Label done;
2380  ExternalReference is_tail_call_elimination_enabled =
2381      ExternalReference::is_tail_call_elimination_enabled_address(
2382          masm->isolate());
2383  __ mov(scratch1, Operand(is_tail_call_elimination_enabled));
2384  __ ldrb(scratch1, MemOperand(scratch1));
2385  __ cmp(scratch1, Operand(0));
2386  __ b(eq, &done);
2387
2388  // Drop possible interpreter handler/stub frame.
2389  {
2390    Label no_interpreter_frame;
2391    __ ldr(scratch3,
2392           MemOperand(fp, CommonFrameConstants::kContextOrFrameTypeOffset));
2393    __ cmp(scratch3, Operand(StackFrame::TypeToMarker(StackFrame::STUB)));
2394    __ b(ne, &no_interpreter_frame);
2395    __ ldr(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
2396    __ bind(&no_interpreter_frame);
2397  }
2398
2399  // Check if next frame is an arguments adaptor frame.
2400  Register caller_args_count_reg = scratch1;
2401  Label no_arguments_adaptor, formal_parameter_count_loaded;
2402  __ ldr(scratch2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
2403  __ ldr(scratch3,
2404         MemOperand(scratch2, CommonFrameConstants::kContextOrFrameTypeOffset));
2405  __ cmp(scratch3,
2406         Operand(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)));
2407  __ b(ne, &no_arguments_adaptor);
2408
2409  // Drop current frame and load arguments count from arguments adaptor frame.
2410  __ mov(fp, scratch2);
2411  __ ldr(caller_args_count_reg,
2412         MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset));
2413  __ SmiUntag(caller_args_count_reg);
2414  __ b(&formal_parameter_count_loaded);
2415
2416  __ bind(&no_arguments_adaptor);
2417  // Load caller's formal parameter count
2418  __ ldr(scratch1,
2419         MemOperand(fp, ArgumentsAdaptorFrameConstants::kFunctionOffset));
2420  __ ldr(scratch1,
2421         FieldMemOperand(scratch1, JSFunction::kSharedFunctionInfoOffset));
2422  __ ldr(caller_args_count_reg,
2423         FieldMemOperand(scratch1,
2424                         SharedFunctionInfo::kFormalParameterCountOffset));
2425  __ SmiUntag(caller_args_count_reg);
2426
2427  __ bind(&formal_parameter_count_loaded);
2428
2429  ParameterCount callee_args_count(args_reg);
2430  __ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2,
2431                        scratch3);
2432  __ bind(&done);
2433}
2434}  // namespace
2435
2436// static
2437void Builtins::Generate_CallFunction(MacroAssembler* masm,
2438                                     ConvertReceiverMode mode,
2439                                     TailCallMode tail_call_mode) {
2440  // ----------- S t a t e -------------
2441  //  -- r0 : the number of arguments (not including the receiver)
2442  //  -- r1 : the function to call (checked to be a JSFunction)
2443  // -----------------------------------
2444  __ AssertFunction(r1);
2445
2446  // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList)
2447  // Check that the function is not a "classConstructor".
2448  Label class_constructor;
2449  __ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
2450  __ ldrb(r3, FieldMemOperand(r2, SharedFunctionInfo::kFunctionKindByteOffset));
2451  __ tst(r3, Operand(SharedFunctionInfo::kClassConstructorBitsWithinByte));
2452  __ b(ne, &class_constructor);
2453
2454  // Enter the context of the function; ToObject has to run in the function
2455  // context, and we also need to take the global proxy from the function
2456  // context in case of conversion.
2457  STATIC_ASSERT(SharedFunctionInfo::kNativeByteOffset ==
2458                SharedFunctionInfo::kStrictModeByteOffset);
2459  __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
2460  // We need to convert the receiver for non-native sloppy mode functions.
2461  Label done_convert;
2462  __ ldrb(r3, FieldMemOperand(r2, SharedFunctionInfo::kNativeByteOffset));
2463  __ tst(r3, Operand((1 << SharedFunctionInfo::kNativeBitWithinByte) |
2464                     (1 << SharedFunctionInfo::kStrictModeBitWithinByte)));
2465  __ b(ne, &done_convert);
2466  {
2467    // ----------- S t a t e -------------
2468    //  -- r0 : the number of arguments (not including the receiver)
2469    //  -- r1 : the function to call (checked to be a JSFunction)
2470    //  -- r2 : the shared function info.
2471    //  -- cp : the function context.
2472    // -----------------------------------
2473
2474    if (mode == ConvertReceiverMode::kNullOrUndefined) {
2475      // Patch receiver to global proxy.
2476      __ LoadGlobalProxy(r3);
2477    } else {
2478      Label convert_to_object, convert_receiver;
2479      __ ldr(r3, MemOperand(sp, r0, LSL, kPointerSizeLog2));
2480      __ JumpIfSmi(r3, &convert_to_object);
2481      STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
2482      __ CompareObjectType(r3, r4, r4, FIRST_JS_RECEIVER_TYPE);
2483      __ b(hs, &done_convert);
2484      if (mode != ConvertReceiverMode::kNotNullOrUndefined) {
2485        Label convert_global_proxy;
2486        __ JumpIfRoot(r3, Heap::kUndefinedValueRootIndex,
2487                      &convert_global_proxy);
2488        __ JumpIfNotRoot(r3, Heap::kNullValueRootIndex, &convert_to_object);
2489        __ bind(&convert_global_proxy);
2490        {
2491          // Patch receiver to global proxy.
2492          __ LoadGlobalProxy(r3);
2493        }
2494        __ b(&convert_receiver);
2495      }
2496      __ bind(&convert_to_object);
2497      {
2498        // Convert receiver using ToObject.
2499        // TODO(bmeurer): Inline the allocation here to avoid building the frame
2500        // in the fast case? (fall back to AllocateInNewSpace?)
2501        FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
2502        __ SmiTag(r0);
2503        __ Push(r0, r1);
2504        __ mov(r0, r3);
2505        __ Push(cp);
2506        __ Call(masm->isolate()->builtins()->ToObject(),
2507                RelocInfo::CODE_TARGET);
2508        __ Pop(cp);
2509        __ mov(r3, r0);
2510        __ Pop(r0, r1);
2511        __ SmiUntag(r0);
2512      }
2513      __ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
2514      __ bind(&convert_receiver);
2515    }
2516    __ str(r3, MemOperand(sp, r0, LSL, kPointerSizeLog2));
2517  }
2518  __ bind(&done_convert);
2519
2520  // ----------- S t a t e -------------
2521  //  -- r0 : the number of arguments (not including the receiver)
2522  //  -- r1 : the function to call (checked to be a JSFunction)
2523  //  -- r2 : the shared function info.
2524  //  -- cp : the function context.
2525  // -----------------------------------
2526
2527  if (tail_call_mode == TailCallMode::kAllow) {
2528    PrepareForTailCall(masm, r0, r3, r4, r5);
2529  }
2530
2531  __ ldr(r2,
2532         FieldMemOperand(r2, SharedFunctionInfo::kFormalParameterCountOffset));
2533  __ SmiUntag(r2);
2534  ParameterCount actual(r0);
2535  ParameterCount expected(r2);
2536  __ InvokeFunctionCode(r1, no_reg, expected, actual, JUMP_FUNCTION,
2537                        CheckDebugStepCallWrapper());
2538
2539  // The function is a "classConstructor", need to raise an exception.
2540  __ bind(&class_constructor);
2541  {
2542    FrameScope frame(masm, StackFrame::INTERNAL);
2543    __ push(r1);
2544    __ CallRuntime(Runtime::kThrowConstructorNonCallableError);
2545  }
2546}
2547
2548namespace {
2549
2550void Generate_PushBoundArguments(MacroAssembler* masm) {
2551  // ----------- S t a t e -------------
2552  //  -- r0 : the number of arguments (not including the receiver)
2553  //  -- r1 : target (checked to be a JSBoundFunction)
2554  //  -- r3 : new.target (only in case of [[Construct]])
2555  // -----------------------------------
2556
2557  // Load [[BoundArguments]] into r2 and length of that into r4.
2558  Label no_bound_arguments;
2559  __ ldr(r2, FieldMemOperand(r1, JSBoundFunction::kBoundArgumentsOffset));
2560  __ ldr(r4, FieldMemOperand(r2, FixedArray::kLengthOffset));
2561  __ SmiUntag(r4);
2562  __ cmp(r4, Operand(0));
2563  __ b(eq, &no_bound_arguments);
2564  {
2565    // ----------- S t a t e -------------
2566    //  -- r0 : the number of arguments (not including the receiver)
2567    //  -- r1 : target (checked to be a JSBoundFunction)
2568    //  -- r2 : the [[BoundArguments]] (implemented as FixedArray)
2569    //  -- r3 : new.target (only in case of [[Construct]])
2570    //  -- r4 : the number of [[BoundArguments]]
2571    // -----------------------------------
2572
2573    // Reserve stack space for the [[BoundArguments]].
2574    {
2575      Label done;
2576      __ sub(sp, sp, Operand(r4, LSL, kPointerSizeLog2));
2577      // Check the stack for overflow. We are not trying to catch interruptions
2578      // (i.e. debug break and preemption) here, so check the "real stack
2579      // limit".
2580      __ CompareRoot(sp, Heap::kRealStackLimitRootIndex);
2581      __ b(gt, &done);  // Signed comparison.
2582      // Restore the stack pointer.
2583      __ add(sp, sp, Operand(r4, LSL, kPointerSizeLog2));
2584      {
2585        FrameScope scope(masm, StackFrame::MANUAL);
2586        __ EnterFrame(StackFrame::INTERNAL);
2587        __ CallRuntime(Runtime::kThrowStackOverflow);
2588      }
2589      __ bind(&done);
2590    }
2591
2592    // Relocate arguments down the stack.
2593    {
2594      Label loop, done_loop;
2595      __ mov(r5, Operand(0));
2596      __ bind(&loop);
2597      __ cmp(r5, r0);
2598      __ b(gt, &done_loop);
2599      __ ldr(ip, MemOperand(sp, r4, LSL, kPointerSizeLog2));
2600      __ str(ip, MemOperand(sp, r5, LSL, kPointerSizeLog2));
2601      __ add(r4, r4, Operand(1));
2602      __ add(r5, r5, Operand(1));
2603      __ b(&loop);
2604      __ bind(&done_loop);
2605    }
2606
2607    // Copy [[BoundArguments]] to the stack (below the arguments).
2608    {
2609      Label loop;
2610      __ ldr(r4, FieldMemOperand(r2, FixedArray::kLengthOffset));
2611      __ SmiUntag(r4);
2612      __ add(r2, r2, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
2613      __ bind(&loop);
2614      __ sub(r4, r4, Operand(1), SetCC);
2615      __ ldr(ip, MemOperand(r2, r4, LSL, kPointerSizeLog2));
2616      __ str(ip, MemOperand(sp, r0, LSL, kPointerSizeLog2));
2617      __ add(r0, r0, Operand(1));
2618      __ b(gt, &loop);
2619    }
2620  }
2621  __ bind(&no_bound_arguments);
2622}
2623
2624}  // namespace
2625
2626// static
2627void Builtins::Generate_CallBoundFunctionImpl(MacroAssembler* masm,
2628                                              TailCallMode tail_call_mode) {
2629  // ----------- S t a t e -------------
2630  //  -- r0 : the number of arguments (not including the receiver)
2631  //  -- r1 : the function to call (checked to be a JSBoundFunction)
2632  // -----------------------------------
2633  __ AssertBoundFunction(r1);
2634
2635  if (tail_call_mode == TailCallMode::kAllow) {
2636    PrepareForTailCall(masm, r0, r3, r4, r5);
2637  }
2638
2639  // Patch the receiver to [[BoundThis]].
2640  __ ldr(ip, FieldMemOperand(r1, JSBoundFunction::kBoundThisOffset));
2641  __ str(ip, MemOperand(sp, r0, LSL, kPointerSizeLog2));
2642
2643  // Push the [[BoundArguments]] onto the stack.
2644  Generate_PushBoundArguments(masm);
2645
2646  // Call the [[BoundTargetFunction]] via the Call builtin.
2647  __ ldr(r1, FieldMemOperand(r1, JSBoundFunction::kBoundTargetFunctionOffset));
2648  __ mov(ip, Operand(ExternalReference(Builtins::kCall_ReceiverIsAny,
2649                                       masm->isolate())));
2650  __ ldr(ip, MemOperand(ip));
2651  __ add(pc, ip, Operand(Code::kHeaderSize - kHeapObjectTag));
2652}
2653
2654// static
2655void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode,
2656                             TailCallMode tail_call_mode) {
2657  // ----------- S t a t e -------------
2658  //  -- r0 : the number of arguments (not including the receiver)
2659  //  -- r1 : the target to call (can be any Object).
2660  // -----------------------------------
2661
2662  Label non_callable, non_function, non_smi;
2663  __ JumpIfSmi(r1, &non_callable);
2664  __ bind(&non_smi);
2665  __ CompareObjectType(r1, r4, r5, JS_FUNCTION_TYPE);
2666  __ Jump(masm->isolate()->builtins()->CallFunction(mode, tail_call_mode),
2667          RelocInfo::CODE_TARGET, eq);
2668  __ cmp(r5, Operand(JS_BOUND_FUNCTION_TYPE));
2669  __ Jump(masm->isolate()->builtins()->CallBoundFunction(tail_call_mode),
2670          RelocInfo::CODE_TARGET, eq);
2671
2672  // Check if target has a [[Call]] internal method.
2673  __ ldrb(r4, FieldMemOperand(r4, Map::kBitFieldOffset));
2674  __ tst(r4, Operand(1 << Map::kIsCallable));
2675  __ b(eq, &non_callable);
2676
2677  __ cmp(r5, Operand(JS_PROXY_TYPE));
2678  __ b(ne, &non_function);
2679
2680  // 0. Prepare for tail call if necessary.
2681  if (tail_call_mode == TailCallMode::kAllow) {
2682    PrepareForTailCall(masm, r0, r3, r4, r5);
2683  }
2684
2685  // 1. Runtime fallback for Proxy [[Call]].
2686  __ Push(r1);
2687  // Increase the arguments size to include the pushed function and the
2688  // existing receiver on the stack.
2689  __ add(r0, r0, Operand(2));
2690  // Tail-call to the runtime.
2691  __ JumpToExternalReference(
2692      ExternalReference(Runtime::kJSProxyCall, masm->isolate()));
2693
2694  // 2. Call to something else, which might have a [[Call]] internal method (if
2695  // not we raise an exception).
2696  __ bind(&non_function);
2697  // Overwrite the original receiver the (original) target.
2698  __ str(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2));
2699  // Let the "call_as_function_delegate" take care of the rest.
2700  __ LoadNativeContextSlot(Context::CALL_AS_FUNCTION_DELEGATE_INDEX, r1);
2701  __ Jump(masm->isolate()->builtins()->CallFunction(
2702              ConvertReceiverMode::kNotNullOrUndefined, tail_call_mode),
2703          RelocInfo::CODE_TARGET);
2704
2705  // 3. Call to something that is not callable.
2706  __ bind(&non_callable);
2707  {
2708    FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
2709    __ Push(r1);
2710    __ CallRuntime(Runtime::kThrowCalledNonCallable);
2711  }
2712}
2713
2714static void CheckSpreadAndPushToStack(MacroAssembler* masm) {
2715  Register argc = r0;
2716  Register constructor = r1;
2717  Register new_target = r3;
2718
2719  Register scratch = r2;
2720  Register scratch2 = r6;
2721
2722  Register spread = r4;
2723  Register spread_map = r5;
2724
2725  Register spread_len = r5;
2726
2727  Label runtime_call, push_args;
2728  __ ldr(spread, MemOperand(sp, 0));
2729  __ JumpIfSmi(spread, &runtime_call);
2730  __ ldr(spread_map, FieldMemOperand(spread, HeapObject::kMapOffset));
2731
2732  // Check that the spread is an array.
2733  __ CompareInstanceType(spread_map, scratch, JS_ARRAY_TYPE);
2734  __ b(ne, &runtime_call);
2735
2736  // Check that we have the original ArrayPrototype.
2737  __ ldr(scratch, FieldMemOperand(spread_map, Map::kPrototypeOffset));
2738  __ ldr(scratch2, NativeContextMemOperand());
2739  __ ldr(scratch2,
2740         ContextMemOperand(scratch2, Context::INITIAL_ARRAY_PROTOTYPE_INDEX));
2741  __ cmp(scratch, scratch2);
2742  __ b(ne, &runtime_call);
2743
2744  // Check that the ArrayPrototype hasn't been modified in a way that would
2745  // affect iteration.
2746  __ LoadRoot(scratch, Heap::kArrayIteratorProtectorRootIndex);
2747  __ ldr(scratch, FieldMemOperand(scratch, PropertyCell::kValueOffset));
2748  __ cmp(scratch, Operand(Smi::FromInt(Isolate::kProtectorValid)));
2749  __ b(ne, &runtime_call);
2750
2751  // Check that the map of the initial array iterator hasn't changed.
2752  __ ldr(scratch2, NativeContextMemOperand());
2753  __ ldr(scratch,
2754         ContextMemOperand(scratch2,
2755                           Context::INITIAL_ARRAY_ITERATOR_PROTOTYPE_INDEX));
2756  __ ldr(scratch, FieldMemOperand(scratch, HeapObject::kMapOffset));
2757  __ ldr(scratch2,
2758         ContextMemOperand(
2759             scratch2, Context::INITIAL_ARRAY_ITERATOR_PROTOTYPE_MAP_INDEX));
2760  __ cmp(scratch, scratch2);
2761  __ b(ne, &runtime_call);
2762
2763  // For FastPacked kinds, iteration will have the same effect as simply
2764  // accessing each property in order.
2765  Label no_protector_check;
2766  __ ldr(scratch, FieldMemOperand(spread_map, Map::kBitField2Offset));
2767  __ DecodeField<Map::ElementsKindBits>(scratch);
2768  __ cmp(scratch, Operand(FAST_HOLEY_ELEMENTS));
2769  __ b(hi, &runtime_call);
2770  // For non-FastHoley kinds, we can skip the protector check.
2771  __ cmp(scratch, Operand(FAST_SMI_ELEMENTS));
2772  __ b(eq, &no_protector_check);
2773  __ cmp(scratch, Operand(FAST_ELEMENTS));
2774  __ b(eq, &no_protector_check);
2775  // Check the ArrayProtector cell.
2776  __ LoadRoot(scratch, Heap::kArrayProtectorRootIndex);
2777  __ ldr(scratch, FieldMemOperand(scratch, PropertyCell::kValueOffset));
2778  __ cmp(scratch, Operand(Smi::FromInt(Isolate::kProtectorValid)));
2779  __ b(ne, &runtime_call);
2780
2781  __ bind(&no_protector_check);
2782  // Load the FixedArray backing store, but use the length from the array.
2783  __ ldr(spread_len, FieldMemOperand(spread, JSArray::kLengthOffset));
2784  __ SmiUntag(spread_len);
2785  __ ldr(spread, FieldMemOperand(spread, JSArray::kElementsOffset));
2786  __ b(&push_args);
2787
2788  __ bind(&runtime_call);
2789  {
2790    // Call the builtin for the result of the spread.
2791    FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
2792    __ SmiTag(argc);
2793    __ Push(constructor);
2794    __ Push(new_target);
2795    __ Push(argc);
2796    __ Push(spread);
2797    __ CallRuntime(Runtime::kSpreadIterableFixed);
2798    __ mov(spread, r0);
2799    __ Pop(argc);
2800    __ Pop(new_target);
2801    __ Pop(constructor);
2802    __ SmiUntag(argc);
2803  }
2804
2805  {
2806    // Calculate the new nargs including the result of the spread.
2807    __ ldr(spread_len, FieldMemOperand(spread, FixedArray::kLengthOffset));
2808    __ SmiUntag(spread_len);
2809
2810    __ bind(&push_args);
2811    // argc += spread_len - 1. Subtract 1 for the spread itself.
2812    __ add(argc, argc, spread_len);
2813    __ sub(argc, argc, Operand(1));
2814
2815    // Pop the spread argument off the stack.
2816    __ Pop(scratch);
2817  }
2818
2819  // Check for stack overflow.
2820  {
2821    // Check the stack for overflow. We are not trying to catch interruptions
2822    // (i.e. debug break and preemption) here, so check the "real stack limit".
2823    Label done;
2824    __ LoadRoot(scratch, Heap::kRealStackLimitRootIndex);
2825    // Make scratch the space we have left. The stack might already be
2826    // overflowed here which will cause scratch to become negative.
2827    __ sub(scratch, sp, scratch);
2828    // Check if the arguments will overflow the stack.
2829    __ cmp(scratch, Operand(spread_len, LSL, kPointerSizeLog2));
2830    __ b(gt, &done);  // Signed comparison.
2831    __ TailCallRuntime(Runtime::kThrowStackOverflow);
2832    __ bind(&done);
2833  }
2834
2835  // Put the evaluated spread onto the stack as additional arguments.
2836  {
2837    __ mov(scratch, Operand(0));
2838    Label done, push, loop;
2839    __ bind(&loop);
2840    __ cmp(scratch, spread_len);
2841    __ b(eq, &done);
2842    __ add(scratch2, spread, Operand(scratch, LSL, kPointerSizeLog2));
2843    __ ldr(scratch2, FieldMemOperand(scratch2, FixedArray::kHeaderSize));
2844    __ JumpIfNotRoot(scratch2, Heap::kTheHoleValueRootIndex, &push);
2845    __ LoadRoot(scratch2, Heap::kUndefinedValueRootIndex);
2846    __ bind(&push);
2847    __ Push(scratch2);
2848    __ add(scratch, scratch, Operand(1));
2849    __ b(&loop);
2850    __ bind(&done);
2851  }
2852}
2853
2854// static
2855void Builtins::Generate_CallWithSpread(MacroAssembler* masm) {
2856  // ----------- S t a t e -------------
2857  //  -- r0 : the number of arguments (not including the receiver)
2858  //  -- r1 : the constructor to call (can be any Object)
2859  // -----------------------------------
2860
2861  // CheckSpreadAndPushToStack will push r3 to save it.
2862  __ LoadRoot(r3, Heap::kUndefinedValueRootIndex);
2863  CheckSpreadAndPushToStack(masm);
2864  __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny,
2865                                            TailCallMode::kDisallow),
2866          RelocInfo::CODE_TARGET);
2867}
2868
2869// static
2870void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
2871  // ----------- S t a t e -------------
2872  //  -- r0 : the number of arguments (not including the receiver)
2873  //  -- r1 : the constructor to call (checked to be a JSFunction)
2874  //  -- r3 : the new target (checked to be a constructor)
2875  // -----------------------------------
2876  __ AssertFunction(r1);
2877
2878  // Calling convention for function specific ConstructStubs require
2879  // r2 to contain either an AllocationSite or undefined.
2880  __ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
2881
2882  // Tail call to the function-specific construct stub (still in the caller
2883  // context at this point).
2884  __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
2885  __ ldr(r4, FieldMemOperand(r4, SharedFunctionInfo::kConstructStubOffset));
2886  __ add(pc, r4, Operand(Code::kHeaderSize - kHeapObjectTag));
2887}
2888
2889// static
2890void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) {
2891  // ----------- S t a t e -------------
2892  //  -- r0 : the number of arguments (not including the receiver)
2893  //  -- r1 : the function to call (checked to be a JSBoundFunction)
2894  //  -- r3 : the new target (checked to be a constructor)
2895  // -----------------------------------
2896  __ AssertBoundFunction(r1);
2897
2898  // Push the [[BoundArguments]] onto the stack.
2899  Generate_PushBoundArguments(masm);
2900
2901  // Patch new.target to [[BoundTargetFunction]] if new.target equals target.
2902  __ cmp(r1, r3);
2903  __ ldr(r3, FieldMemOperand(r1, JSBoundFunction::kBoundTargetFunctionOffset),
2904         eq);
2905
2906  // Construct the [[BoundTargetFunction]] via the Construct builtin.
2907  __ ldr(r1, FieldMemOperand(r1, JSBoundFunction::kBoundTargetFunctionOffset));
2908  __ mov(ip, Operand(ExternalReference(Builtins::kConstruct, masm->isolate())));
2909  __ ldr(ip, MemOperand(ip));
2910  __ add(pc, ip, Operand(Code::kHeaderSize - kHeapObjectTag));
2911}
2912
2913// static
2914void Builtins::Generate_ConstructProxy(MacroAssembler* masm) {
2915  // ----------- S t a t e -------------
2916  //  -- r0 : the number of arguments (not including the receiver)
2917  //  -- r1 : the constructor to call (checked to be a JSProxy)
2918  //  -- r3 : the new target (either the same as the constructor or
2919  //          the JSFunction on which new was invoked initially)
2920  // -----------------------------------
2921
2922  // Call into the Runtime for Proxy [[Construct]].
2923  __ Push(r1);
2924  __ Push(r3);
2925  // Include the pushed new_target, constructor and the receiver.
2926  __ add(r0, r0, Operand(3));
2927  // Tail-call to the runtime.
2928  __ JumpToExternalReference(
2929      ExternalReference(Runtime::kJSProxyConstruct, masm->isolate()));
2930}
2931
2932// static
2933void Builtins::Generate_Construct(MacroAssembler* masm) {
2934  // ----------- S t a t e -------------
2935  //  -- r0 : the number of arguments (not including the receiver)
2936  //  -- r1 : the constructor to call (can be any Object)
2937  //  -- r3 : the new target (either the same as the constructor or
2938  //          the JSFunction on which new was invoked initially)
2939  // -----------------------------------
2940
2941  // Check if target is a Smi.
2942  Label non_constructor;
2943  __ JumpIfSmi(r1, &non_constructor);
2944
2945  // Dispatch based on instance type.
2946  __ CompareObjectType(r1, r4, r5, JS_FUNCTION_TYPE);
2947  __ Jump(masm->isolate()->builtins()->ConstructFunction(),
2948          RelocInfo::CODE_TARGET, eq);
2949
2950  // Check if target has a [[Construct]] internal method.
2951  __ ldrb(r2, FieldMemOperand(r4, Map::kBitFieldOffset));
2952  __ tst(r2, Operand(1 << Map::kIsConstructor));
2953  __ b(eq, &non_constructor);
2954
2955  // Only dispatch to bound functions after checking whether they are
2956  // constructors.
2957  __ cmp(r5, Operand(JS_BOUND_FUNCTION_TYPE));
2958  __ Jump(masm->isolate()->builtins()->ConstructBoundFunction(),
2959          RelocInfo::CODE_TARGET, eq);
2960
2961  // Only dispatch to proxies after checking whether they are constructors.
2962  __ cmp(r5, Operand(JS_PROXY_TYPE));
2963  __ Jump(masm->isolate()->builtins()->ConstructProxy(), RelocInfo::CODE_TARGET,
2964          eq);
2965
2966  // Called Construct on an exotic Object with a [[Construct]] internal method.
2967  {
2968    // Overwrite the original receiver with the (original) target.
2969    __ str(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2));
2970    // Let the "call_as_constructor_delegate" take care of the rest.
2971    __ LoadNativeContextSlot(Context::CALL_AS_CONSTRUCTOR_DELEGATE_INDEX, r1);
2972    __ Jump(masm->isolate()->builtins()->CallFunction(),
2973            RelocInfo::CODE_TARGET);
2974  }
2975
2976  // Called Construct on an Object that doesn't have a [[Construct]] internal
2977  // method.
2978  __ bind(&non_constructor);
2979  __ Jump(masm->isolate()->builtins()->ConstructedNonConstructable(),
2980          RelocInfo::CODE_TARGET);
2981}
2982
2983// static
2984void Builtins::Generate_ConstructWithSpread(MacroAssembler* masm) {
2985  // ----------- S t a t e -------------
2986  //  -- r0 : the number of arguments (not including the receiver)
2987  //  -- r1 : the constructor to call (can be any Object)
2988  //  -- r3 : the new target (either the same as the constructor or
2989  //          the JSFunction on which new was invoked initially)
2990  // -----------------------------------
2991
2992  CheckSpreadAndPushToStack(masm);
2993  __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
2994}
2995
2996// static
2997void Builtins::Generate_AllocateInNewSpace(MacroAssembler* masm) {
2998  // ----------- S t a t e -------------
2999  //  -- r1 : requested object size (untagged)
3000  //  -- lr : return address
3001  // -----------------------------------
3002  __ SmiTag(r1);
3003  __ Push(r1);
3004  __ Move(cp, Smi::kZero);
3005  __ TailCallRuntime(Runtime::kAllocateInNewSpace);
3006}
3007
3008// static
3009void Builtins::Generate_AllocateInOldSpace(MacroAssembler* masm) {
3010  // ----------- S t a t e -------------
3011  //  -- r1 : requested object size (untagged)
3012  //  -- lr : return address
3013  // -----------------------------------
3014  __ SmiTag(r1);
3015  __ Move(r2, Smi::FromInt(AllocateTargetSpace::encode(OLD_SPACE)));
3016  __ Push(r1, r2);
3017  __ Move(cp, Smi::kZero);
3018  __ TailCallRuntime(Runtime::kAllocateInTargetSpace);
3019}
3020
3021// static
3022void Builtins::Generate_Abort(MacroAssembler* masm) {
3023  // ----------- S t a t e -------------
3024  //  -- r1 : message_id as Smi
3025  //  -- lr : return address
3026  // -----------------------------------
3027  __ Push(r1);
3028  __ Move(cp, Smi::kZero);
3029  __ TailCallRuntime(Runtime::kAbort);
3030}
3031
3032void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
3033  // ----------- S t a t e -------------
3034  //  -- r0 : actual number of arguments
3035  //  -- r1 : function (passed through to callee)
3036  //  -- r2 : expected number of arguments
3037  //  -- r3 : new target (passed through to callee)
3038  // -----------------------------------
3039
3040  Label invoke, dont_adapt_arguments, stack_overflow;
3041
3042  Label enough, too_few;
3043  __ cmp(r0, r2);
3044  __ b(lt, &too_few);
3045  __ cmp(r2, Operand(SharedFunctionInfo::kDontAdaptArgumentsSentinel));
3046  __ b(eq, &dont_adapt_arguments);
3047
3048  {  // Enough parameters: actual >= expected
3049    __ bind(&enough);
3050    EnterArgumentsAdaptorFrame(masm);
3051    Generate_StackOverflowCheck(masm, r2, r5, &stack_overflow);
3052
3053    // Calculate copy start address into r0 and copy end address into r4.
3054    // r0: actual number of arguments as a smi
3055    // r1: function
3056    // r2: expected number of arguments
3057    // r3: new target (passed through to callee)
3058    __ add(r0, fp, Operand::PointerOffsetFromSmiKey(r0));
3059    // adjust for return address and receiver
3060    __ add(r0, r0, Operand(2 * kPointerSize));
3061    __ sub(r4, r0, Operand(r2, LSL, kPointerSizeLog2));
3062
3063    // Copy the arguments (including the receiver) to the new stack frame.
3064    // r0: copy start address
3065    // r1: function
3066    // r2: expected number of arguments
3067    // r3: new target (passed through to callee)
3068    // r4: copy end address
3069
3070    Label copy;
3071    __ bind(&copy);
3072    __ ldr(ip, MemOperand(r0, 0));
3073    __ push(ip);
3074    __ cmp(r0, r4);  // Compare before moving to next argument.
3075    __ sub(r0, r0, Operand(kPointerSize));
3076    __ b(ne, &copy);
3077
3078    __ b(&invoke);
3079  }
3080
3081  {  // Too few parameters: Actual < expected
3082    __ bind(&too_few);
3083    EnterArgumentsAdaptorFrame(masm);
3084    Generate_StackOverflowCheck(masm, r2, r5, &stack_overflow);
3085
3086    // Calculate copy start address into r0 and copy end address is fp.
3087    // r0: actual number of arguments as a smi
3088    // r1: function
3089    // r2: expected number of arguments
3090    // r3: new target (passed through to callee)
3091    __ add(r0, fp, Operand::PointerOffsetFromSmiKey(r0));
3092
3093    // Copy the arguments (including the receiver) to the new stack frame.
3094    // r0: copy start address
3095    // r1: function
3096    // r2: expected number of arguments
3097    // r3: new target (passed through to callee)
3098    Label copy;
3099    __ bind(&copy);
3100    // Adjust load for return address and receiver.
3101    __ ldr(ip, MemOperand(r0, 2 * kPointerSize));
3102    __ push(ip);
3103    __ cmp(r0, fp);  // Compare before moving to next argument.
3104    __ sub(r0, r0, Operand(kPointerSize));
3105    __ b(ne, &copy);
3106
3107    // Fill the remaining expected arguments with undefined.
3108    // r1: function
3109    // r2: expected number of arguments
3110    // r3: new target (passed through to callee)
3111    __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
3112    __ sub(r4, fp, Operand(r2, LSL, kPointerSizeLog2));
3113    // Adjust for frame.
3114    __ sub(r4, r4, Operand(StandardFrameConstants::kFixedFrameSizeFromFp +
3115                           2 * kPointerSize));
3116
3117    Label fill;
3118    __ bind(&fill);
3119    __ push(ip);
3120    __ cmp(sp, r4);
3121    __ b(ne, &fill);
3122  }
3123
3124  // Call the entry point.
3125  __ bind(&invoke);
3126  __ mov(r0, r2);
3127  // r0 : expected number of arguments
3128  // r1 : function (passed through to callee)
3129  // r3 : new target (passed through to callee)
3130  __ ldr(r4, FieldMemOperand(r1, JSFunction::kCodeEntryOffset));
3131  __ Call(r4);
3132
3133  // Store offset of return address for deoptimizer.
3134  masm->isolate()->heap()->SetArgumentsAdaptorDeoptPCOffset(masm->pc_offset());
3135
3136  // Exit frame and return.
3137  LeaveArgumentsAdaptorFrame(masm);
3138  __ Jump(lr);
3139
3140  // -------------------------------------------
3141  // Dont adapt arguments.
3142  // -------------------------------------------
3143  __ bind(&dont_adapt_arguments);
3144  __ ldr(r4, FieldMemOperand(r1, JSFunction::kCodeEntryOffset));
3145  __ Jump(r4);
3146
3147  __ bind(&stack_overflow);
3148  {
3149    FrameScope frame(masm, StackFrame::MANUAL);
3150    __ CallRuntime(Runtime::kThrowStackOverflow);
3151    __ bkpt(0);
3152  }
3153}
3154
3155#undef __
3156
3157}  // namespace internal
3158}  // namespace v8
3159
3160#endif  // V8_TARGET_ARCH_ARM
3161