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    FastNewObjectStub stub(masm->isolate());
330    __ SmiTag(r6);
331    __ EnterBuiltinFrame(cp, r1, r6);
332    __ Push(r2);  // first argument
333    __ CallStub(&stub);
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    FastNewObjectStub stub(masm->isolate());
478    __ SmiTag(r6);
479    __ EnterBuiltinFrame(cp, r1, r6);
480    __ Push(r2);  // first argument
481    __ CallStub(&stub);
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  // ----------- S t a t e -------------
556  //  -- r0     : number of arguments
557  //  -- r1     : constructor function
558  //  -- r3     : new target
559  //  -- cp     : context
560  //  -- lr     : return address
561  //  -- sp[...]: constructor arguments
562  // -----------------------------------
563
564  Isolate* isolate = masm->isolate();
565
566  // Enter a construct frame.
567  {
568    FrameAndConstantPoolScope scope(masm, StackFrame::CONSTRUCT);
569
570    // Preserve the incoming parameters on the stack.
571    __ SmiTag(r0);
572    __ Push(cp, r0);
573
574    if (create_implicit_receiver) {
575      // Allocate the new receiver object.
576      __ Push(r1, r3);
577      FastNewObjectStub stub(masm->isolate());
578      __ CallStub(&stub);
579      __ mov(r4, r0);
580      __ Pop(r1, r3);
581
582      // ----------- S t a t e -------------
583      //  -- r1: constructor function
584      //  -- r3: new target
585      //  -- r4: newly allocated object
586      // -----------------------------------
587
588      // Retrieve smi-tagged arguments count from the stack.
589      __ ldr(r0, MemOperand(sp));
590    }
591
592    __ SmiUntag(r0);
593
594    if (create_implicit_receiver) {
595      // Push the allocated receiver to the stack. We need two copies
596      // because we may have to return the original one and the calling
597      // conventions dictate that the called function pops the receiver.
598      __ push(r4);
599      __ push(r4);
600    } else {
601      __ PushRoot(Heap::kTheHoleValueRootIndex);
602    }
603
604    // Set up pointer to last argument.
605    __ add(r2, fp, Operand(StandardFrameConstants::kCallerSPOffset));
606
607    // Copy arguments and receiver to the expression stack.
608    // r0: number of arguments
609    // r1: constructor function
610    // r2: address of last argument (caller sp)
611    // r3: new target
612    // r4: number of arguments (smi-tagged)
613    // sp[0]: receiver
614    // sp[1]: receiver
615    // sp[2]: number of arguments (smi-tagged)
616    Label loop, entry;
617    __ SmiTag(r4, r0);
618    __ b(&entry);
619    __ bind(&loop);
620    __ ldr(ip, MemOperand(r2, r4, LSL, kPointerSizeLog2 - 1));
621    __ push(ip);
622    __ bind(&entry);
623    __ sub(r4, r4, Operand(2), SetCC);
624    __ b(ge, &loop);
625
626    // Call the function.
627    // r0: number of arguments
628    // r1: constructor function
629    // r3: new target
630    ParameterCount actual(r0);
631    __ InvokeFunction(r1, r3, actual, CALL_FUNCTION,
632                      CheckDebugStepCallWrapper());
633
634    // Store offset of return address for deoptimizer.
635    if (create_implicit_receiver && !is_api_function) {
636      masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset());
637    }
638
639    // Restore context from the frame.
640    // r0: result
641    // sp[0]: receiver
642    // sp[1]: number of arguments (smi-tagged)
643    __ ldr(cp, MemOperand(fp, ConstructFrameConstants::kContextOffset));
644
645    if (create_implicit_receiver) {
646      // If the result is an object (in the ECMA sense), we should get rid
647      // of the receiver and use the result; see ECMA-262 section 13.2.2-7
648      // on page 74.
649      Label use_receiver, exit;
650
651      // If the result is a smi, it is *not* an object in the ECMA sense.
652      // r0: result
653      // sp[0]: receiver
654      // sp[1]: number of arguments (smi-tagged)
655      __ JumpIfSmi(r0, &use_receiver);
656
657      // If the type of the result (stored in its map) is less than
658      // FIRST_JS_RECEIVER_TYPE, it is not an object in the ECMA sense.
659      __ CompareObjectType(r0, r1, r3, FIRST_JS_RECEIVER_TYPE);
660      __ b(ge, &exit);
661
662      // Throw away the result of the constructor invocation and use the
663      // on-stack receiver as the result.
664      __ bind(&use_receiver);
665      __ ldr(r0, MemOperand(sp));
666
667      // Remove receiver from the stack, remove caller arguments, and
668      // return.
669      __ bind(&exit);
670      // r0: result
671      // sp[0]: receiver (newly allocated object)
672      // sp[1]: number of arguments (smi-tagged)
673      __ ldr(r1, MemOperand(sp, 1 * kPointerSize));
674    } else {
675      __ ldr(r1, MemOperand(sp));
676    }
677
678    // Leave construct frame.
679  }
680
681  // ES6 9.2.2. Step 13+
682  // Check that the result is not a Smi, indicating that the constructor result
683  // from a derived class is neither undefined nor an Object.
684  if (check_derived_construct) {
685    Label dont_throw;
686    __ JumpIfNotSmi(r0, &dont_throw);
687    {
688      FrameScope scope(masm, StackFrame::INTERNAL);
689      __ CallRuntime(Runtime::kThrowDerivedConstructorReturnedNonObject);
690    }
691    __ bind(&dont_throw);
692  }
693
694  __ add(sp, sp, Operand(r1, LSL, kPointerSizeLog2 - 1));
695  __ add(sp, sp, Operand(kPointerSize));
696  if (create_implicit_receiver) {
697    __ IncrementCounter(isolate->counters()->constructed_objects(), 1, r1, r2);
698  }
699  __ Jump(lr);
700}
701
702}  // namespace
703
704void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
705  Generate_JSConstructStubHelper(masm, false, true, false);
706}
707
708void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
709  Generate_JSConstructStubHelper(masm, true, false, false);
710}
711
712void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) {
713  Generate_JSConstructStubHelper(masm, false, false, false);
714}
715
716void Builtins::Generate_JSBuiltinsConstructStubForDerived(
717    MacroAssembler* masm) {
718  Generate_JSConstructStubHelper(masm, false, false, true);
719}
720
721// static
722void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
723  // ----------- S t a t e -------------
724  //  -- r0 : the value to pass to the generator
725  //  -- r1 : the JSGeneratorObject to resume
726  //  -- r2 : the resume mode (tagged)
727  //  -- lr : return address
728  // -----------------------------------
729  __ AssertGeneratorObject(r1);
730
731  // Store input value into generator object.
732  __ str(r0, FieldMemOperand(r1, JSGeneratorObject::kInputOrDebugPosOffset));
733  __ RecordWriteField(r1, JSGeneratorObject::kInputOrDebugPosOffset, r0, r3,
734                      kLRHasNotBeenSaved, kDontSaveFPRegs);
735
736  // Store resume mode into generator object.
737  __ str(r2, FieldMemOperand(r1, JSGeneratorObject::kResumeModeOffset));
738
739  // Load suspended function and context.
740  __ ldr(cp, FieldMemOperand(r1, JSGeneratorObject::kContextOffset));
741  __ ldr(r4, FieldMemOperand(r1, JSGeneratorObject::kFunctionOffset));
742
743  // Flood function if we are stepping.
744  Label prepare_step_in_if_stepping, prepare_step_in_suspended_generator;
745  Label stepping_prepared;
746  ExternalReference last_step_action =
747      ExternalReference::debug_last_step_action_address(masm->isolate());
748  STATIC_ASSERT(StepFrame > StepIn);
749  __ mov(ip, Operand(last_step_action));
750  __ ldrsb(ip, MemOperand(ip));
751  __ cmp(ip, Operand(StepIn));
752  __ b(ge, &prepare_step_in_if_stepping);
753
754  // Flood function if we need to continue stepping in the suspended generator.
755  ExternalReference debug_suspended_generator =
756      ExternalReference::debug_suspended_generator_address(masm->isolate());
757  __ mov(ip, Operand(debug_suspended_generator));
758  __ ldr(ip, MemOperand(ip));
759  __ cmp(ip, Operand(r1));
760  __ b(eq, &prepare_step_in_suspended_generator);
761  __ bind(&stepping_prepared);
762
763  // Push receiver.
764  __ ldr(ip, FieldMemOperand(r1, JSGeneratorObject::kReceiverOffset));
765  __ Push(ip);
766
767  // ----------- S t a t e -------------
768  //  -- r1    : the JSGeneratorObject to resume
769  //  -- r2    : the resume mode (tagged)
770  //  -- r4    : generator function
771  //  -- cp    : generator context
772  //  -- lr    : return address
773  //  -- sp[0] : generator receiver
774  // -----------------------------------
775
776  // Push holes for arguments to generator function. Since the parser forced
777  // context allocation for any variables in generators, the actual argument
778  // values have already been copied into the context and these dummy values
779  // will never be used.
780  __ ldr(r3, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset));
781  __ ldr(r3,
782         FieldMemOperand(r3, SharedFunctionInfo::kFormalParameterCountOffset));
783  {
784    Label done_loop, loop;
785    __ bind(&loop);
786    __ sub(r3, r3, Operand(Smi::FromInt(1)), SetCC);
787    __ b(mi, &done_loop);
788    __ PushRoot(Heap::kTheHoleValueRootIndex);
789    __ b(&loop);
790    __ bind(&done_loop);
791  }
792
793  // Dispatch on the kind of generator object.
794  Label old_generator;
795  __ ldr(r3, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset));
796  __ ldr(r3, FieldMemOperand(r3, SharedFunctionInfo::kFunctionDataOffset));
797  __ CompareObjectType(r3, r3, r3, BYTECODE_ARRAY_TYPE);
798  __ b(ne, &old_generator);
799
800  // New-style (ignition/turbofan) generator object
801  {
802    __ ldr(r0, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset));
803    __ ldr(r0, FieldMemOperand(
804                   r0, SharedFunctionInfo::kFormalParameterCountOffset));
805    __ SmiUntag(r0);
806    // We abuse new.target both to indicate that this is a resume call and to
807    // pass in the generator object.  In ordinary calls, new.target is always
808    // undefined because generator functions are non-constructable.
809    __ Move(r3, r1);
810    __ Move(r1, r4);
811    __ ldr(r5, FieldMemOperand(r1, JSFunction::kCodeEntryOffset));
812    __ Jump(r5);
813  }
814
815  // Old-style (full-codegen) generator object
816  __ bind(&old_generator);
817  {
818    // Enter a new JavaScript frame, and initialize its slots as they were when
819    // the generator was suspended.
820    DCHECK(!FLAG_enable_embedded_constant_pool);
821    FrameScope scope(masm, StackFrame::MANUAL);
822    __ Push(lr, fp);
823    __ Move(fp, sp);
824    __ Push(cp, r4);
825
826    // Restore the operand stack.
827    __ ldr(r0, FieldMemOperand(r1, JSGeneratorObject::kOperandStackOffset));
828    __ ldr(r3, FieldMemOperand(r0, FixedArray::kLengthOffset));
829    __ add(r0, r0, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
830    __ add(r3, r0, Operand(r3, LSL, kPointerSizeLog2 - 1));
831    {
832      Label done_loop, loop;
833      __ bind(&loop);
834      __ cmp(r0, r3);
835      __ b(eq, &done_loop);
836      __ ldr(ip, MemOperand(r0, kPointerSize, PostIndex));
837      __ Push(ip);
838      __ b(&loop);
839      __ bind(&done_loop);
840    }
841
842    // Reset operand stack so we don't leak.
843    __ LoadRoot(ip, Heap::kEmptyFixedArrayRootIndex);
844    __ str(ip, FieldMemOperand(r1, JSGeneratorObject::kOperandStackOffset));
845
846    // Resume the generator function at the continuation.
847    __ ldr(r3, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset));
848    __ ldr(r3, FieldMemOperand(r3, SharedFunctionInfo::kCodeOffset));
849    __ add(r3, r3, Operand(Code::kHeaderSize - kHeapObjectTag));
850    __ ldr(r2, FieldMemOperand(r1, JSGeneratorObject::kContinuationOffset));
851    __ add(r3, r3, Operand(r2, ASR, 1));
852    __ mov(r2, Operand(Smi::FromInt(JSGeneratorObject::kGeneratorExecuting)));
853    __ str(r2, FieldMemOperand(r1, JSGeneratorObject::kContinuationOffset));
854    __ Move(r0, r1);  // Continuation expects generator object in r0.
855    __ Jump(r3);
856  }
857
858  __ bind(&prepare_step_in_if_stepping);
859  {
860    FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
861    __ Push(r1, r2, r4);
862    __ CallRuntime(Runtime::kDebugPrepareStepInIfStepping);
863    __ Pop(r1, r2);
864    __ ldr(r4, FieldMemOperand(r1, JSGeneratorObject::kFunctionOffset));
865  }
866  __ b(&stepping_prepared);
867
868  __ bind(&prepare_step_in_suspended_generator);
869  {
870    FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
871    __ Push(r1, r2);
872    __ CallRuntime(Runtime::kDebugPrepareStepInSuspendedGenerator);
873    __ Pop(r1, r2);
874    __ ldr(r4, FieldMemOperand(r1, JSGeneratorObject::kFunctionOffset));
875  }
876  __ b(&stepping_prepared);
877}
878
879void Builtins::Generate_ConstructedNonConstructable(MacroAssembler* masm) {
880  FrameScope scope(masm, StackFrame::INTERNAL);
881  __ push(r1);
882  __ CallRuntime(Runtime::kThrowConstructedNonConstructable);
883}
884
885enum IsTagged { kArgcIsSmiTagged, kArgcIsUntaggedInt };
886
887// Clobbers r2; preserves all other registers.
888static void Generate_CheckStackOverflow(MacroAssembler* masm, Register argc,
889                                        IsTagged argc_is_tagged) {
890  // Check the stack for overflow. We are not trying to catch
891  // interruptions (e.g. debug break and preemption) here, so the "real stack
892  // limit" is checked.
893  Label okay;
894  __ LoadRoot(r2, Heap::kRealStackLimitRootIndex);
895  // Make r2 the space we have left. The stack might already be overflowed
896  // here which will cause r2 to become negative.
897  __ sub(r2, sp, r2);
898  // Check if the arguments will overflow the stack.
899  if (argc_is_tagged == kArgcIsSmiTagged) {
900    __ cmp(r2, Operand::PointerOffsetFromSmiKey(argc));
901  } else {
902    DCHECK(argc_is_tagged == kArgcIsUntaggedInt);
903    __ cmp(r2, Operand(argc, LSL, kPointerSizeLog2));
904  }
905  __ b(gt, &okay);  // Signed comparison.
906
907  // Out of stack space.
908  __ CallRuntime(Runtime::kThrowStackOverflow);
909
910  __ bind(&okay);
911}
912
913static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
914                                             bool is_construct) {
915  // Called from Generate_JS_Entry
916  // r0: new.target
917  // r1: function
918  // r2: receiver
919  // r3: argc
920  // r4: argv
921  // r5-r6, r8 (if !FLAG_enable_embedded_constant_pool) and cp may be clobbered
922  ProfileEntryHookStub::MaybeCallEntryHook(masm);
923
924  // Enter an internal frame.
925  {
926    FrameScope scope(masm, StackFrame::INTERNAL);
927
928    // Setup the context (we need to use the caller context from the isolate).
929    ExternalReference context_address(Isolate::kContextAddress,
930                                      masm->isolate());
931    __ mov(cp, Operand(context_address));
932    __ ldr(cp, MemOperand(cp));
933
934    __ InitializeRootRegister();
935
936    // Push the function and the receiver onto the stack.
937    __ Push(r1, r2);
938
939    // Check if we have enough stack space to push all arguments.
940    // Clobbers r2.
941    Generate_CheckStackOverflow(masm, r3, kArgcIsUntaggedInt);
942
943    // Remember new.target.
944    __ mov(r5, r0);
945
946    // Copy arguments to the stack in a loop.
947    // r1: function
948    // r3: argc
949    // r4: argv, i.e. points to first arg
950    Label loop, entry;
951    __ add(r2, r4, Operand(r3, LSL, kPointerSizeLog2));
952    // r2 points past last arg.
953    __ b(&entry);
954    __ bind(&loop);
955    __ ldr(r0, MemOperand(r4, kPointerSize, PostIndex));  // read next parameter
956    __ ldr(r0, MemOperand(r0));                           // dereference handle
957    __ push(r0);                                          // push parameter
958    __ bind(&entry);
959    __ cmp(r4, r2);
960    __ b(ne, &loop);
961
962    // Setup new.target and argc.
963    __ mov(r0, Operand(r3));
964    __ mov(r3, Operand(r5));
965
966    // Initialize all JavaScript callee-saved registers, since they will be seen
967    // by the garbage collector as part of handlers.
968    __ LoadRoot(r4, Heap::kUndefinedValueRootIndex);
969    __ mov(r5, Operand(r4));
970    __ mov(r6, Operand(r4));
971    if (!FLAG_enable_embedded_constant_pool) {
972      __ mov(r8, Operand(r4));
973    }
974    if (kR9Available == 1) {
975      __ mov(r9, Operand(r4));
976    }
977
978    // Invoke the code.
979    Handle<Code> builtin = is_construct
980                               ? masm->isolate()->builtins()->Construct()
981                               : masm->isolate()->builtins()->Call();
982    __ Call(builtin, RelocInfo::CODE_TARGET);
983
984    // Exit the JS frame and remove the parameters (except function), and
985    // return.
986    // Respect ABI stack constraint.
987  }
988  __ Jump(lr);
989
990  // r0: result
991}
992
993void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) {
994  Generate_JSEntryTrampolineHelper(masm, false);
995}
996
997void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) {
998  Generate_JSEntryTrampolineHelper(masm, true);
999}
1000
1001static void LeaveInterpreterFrame(MacroAssembler* masm, Register scratch) {
1002  Register args_count = scratch;
1003
1004  // Get the arguments + receiver count.
1005  __ ldr(args_count,
1006         MemOperand(fp, InterpreterFrameConstants::kBytecodeArrayFromFp));
1007  __ ldr(args_count,
1008         FieldMemOperand(args_count, BytecodeArray::kParameterSizeOffset));
1009
1010  // Leave the frame (also dropping the register file).
1011  __ LeaveFrame(StackFrame::JAVA_SCRIPT);
1012
1013  // Drop receiver + arguments.
1014  __ add(sp, sp, args_count, LeaveCC);
1015}
1016
1017// Generate code for entering a JS function with the interpreter.
1018// On entry to the function the receiver and arguments have been pushed on the
1019// stack left to right.  The actual argument count matches the formal parameter
1020// count expected by the function.
1021//
1022// The live registers are:
1023//   o r1: the JS function object being called.
1024//   o r3: the new target
1025//   o cp: our context
1026//   o pp: the caller's constant pool pointer (if enabled)
1027//   o fp: the caller's frame pointer
1028//   o sp: stack pointer
1029//   o lr: return address
1030//
1031// The function builds an interpreter frame.  See InterpreterFrameConstants in
1032// frames.h for its layout.
1033void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
1034  ProfileEntryHookStub::MaybeCallEntryHook(masm);
1035
1036  // Open a frame scope to indicate that there is a frame on the stack.  The
1037  // MANUAL indicates that the scope shouldn't actually generate code to set up
1038  // the frame (that is done below).
1039  FrameScope frame_scope(masm, StackFrame::MANUAL);
1040  __ PushStandardFrame(r1);
1041
1042  // Get the bytecode array from the function object (or from the DebugInfo if
1043  // it is present) and load it into kInterpreterBytecodeArrayRegister.
1044  __ ldr(r0, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
1045  Register debug_info = kInterpreterBytecodeArrayRegister;
1046  DCHECK(!debug_info.is(r0));
1047  __ ldr(debug_info, FieldMemOperand(r0, SharedFunctionInfo::kDebugInfoOffset));
1048  __ cmp(debug_info, Operand(DebugInfo::uninitialized()));
1049  // Load original bytecode array or the debug copy.
1050  __ ldr(kInterpreterBytecodeArrayRegister,
1051         FieldMemOperand(r0, SharedFunctionInfo::kFunctionDataOffset), eq);
1052  __ ldr(kInterpreterBytecodeArrayRegister,
1053         FieldMemOperand(debug_info, DebugInfo::kDebugBytecodeArrayIndex), ne);
1054
1055  // Check whether we should continue to use the interpreter.
1056  Label switch_to_different_code_kind;
1057  __ ldr(r0, FieldMemOperand(r0, SharedFunctionInfo::kCodeOffset));
1058  __ cmp(r0, Operand(masm->CodeObject()));  // Self-reference to this code.
1059  __ b(ne, &switch_to_different_code_kind);
1060
1061  // Increment invocation count for the function.
1062  __ ldr(r2, FieldMemOperand(r1, JSFunction::kLiteralsOffset));
1063  __ ldr(r2, FieldMemOperand(r2, LiteralsArray::kFeedbackVectorOffset));
1064  __ ldr(r9, FieldMemOperand(
1065                 r2, TypeFeedbackVector::kInvocationCountIndex * kPointerSize +
1066                         TypeFeedbackVector::kHeaderSize));
1067  __ add(r9, r9, Operand(Smi::FromInt(1)));
1068  __ str(r9, FieldMemOperand(
1069                 r2, TypeFeedbackVector::kInvocationCountIndex * kPointerSize +
1070                         TypeFeedbackVector::kHeaderSize));
1071
1072  // Check function data field is actually a BytecodeArray object.
1073  if (FLAG_debug_code) {
1074    __ SmiTst(kInterpreterBytecodeArrayRegister);
1075    __ Assert(ne, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry);
1076    __ CompareObjectType(kInterpreterBytecodeArrayRegister, r0, no_reg,
1077                         BYTECODE_ARRAY_TYPE);
1078    __ Assert(eq, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry);
1079  }
1080
1081  // Load the initial bytecode offset.
1082  __ mov(kInterpreterBytecodeOffsetRegister,
1083         Operand(BytecodeArray::kHeaderSize - kHeapObjectTag));
1084
1085  // Push new.target, bytecode array and Smi tagged bytecode array offset.
1086  __ SmiTag(r0, kInterpreterBytecodeOffsetRegister);
1087  __ Push(r3, kInterpreterBytecodeArrayRegister, r0);
1088
1089  // Allocate the local and temporary register file on the stack.
1090  {
1091    // Load frame size from the BytecodeArray object.
1092    __ ldr(r4, FieldMemOperand(kInterpreterBytecodeArrayRegister,
1093                               BytecodeArray::kFrameSizeOffset));
1094
1095    // Do a stack check to ensure we don't go over the limit.
1096    Label ok;
1097    __ sub(r9, sp, Operand(r4));
1098    __ LoadRoot(r2, Heap::kRealStackLimitRootIndex);
1099    __ cmp(r9, Operand(r2));
1100    __ b(hs, &ok);
1101    __ CallRuntime(Runtime::kThrowStackOverflow);
1102    __ bind(&ok);
1103
1104    // If ok, push undefined as the initial value for all register file entries.
1105    Label loop_header;
1106    Label loop_check;
1107    __ LoadRoot(r9, Heap::kUndefinedValueRootIndex);
1108    __ b(&loop_check, al);
1109    __ bind(&loop_header);
1110    // TODO(rmcilroy): Consider doing more than one push per loop iteration.
1111    __ push(r9);
1112    // Continue loop if not done.
1113    __ bind(&loop_check);
1114    __ sub(r4, r4, Operand(kPointerSize), SetCC);
1115    __ b(&loop_header, ge);
1116  }
1117
1118  // Load accumulator and dispatch table into registers.
1119  __ LoadRoot(kInterpreterAccumulatorRegister, Heap::kUndefinedValueRootIndex);
1120  __ mov(kInterpreterDispatchTableRegister,
1121         Operand(ExternalReference::interpreter_dispatch_table_address(
1122             masm->isolate())));
1123
1124  // Dispatch to the first bytecode handler for the function.
1125  __ ldrb(r1, MemOperand(kInterpreterBytecodeArrayRegister,
1126                         kInterpreterBytecodeOffsetRegister));
1127  __ ldr(ip, MemOperand(kInterpreterDispatchTableRegister, r1, LSL,
1128                        kPointerSizeLog2));
1129  __ Call(ip);
1130  masm->isolate()->heap()->SetInterpreterEntryReturnPCOffset(masm->pc_offset());
1131
1132  // The return value is in r0.
1133  LeaveInterpreterFrame(masm, r2);
1134  __ Jump(lr);
1135
1136  // If the shared code is no longer this entry trampoline, then the underlying
1137  // function has been switched to a different kind of code and we heal the
1138  // closure by switching the code entry field over to the new code as well.
1139  __ bind(&switch_to_different_code_kind);
1140  __ LeaveFrame(StackFrame::JAVA_SCRIPT);
1141  __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
1142  __ ldr(r4, FieldMemOperand(r4, SharedFunctionInfo::kCodeOffset));
1143  __ add(r4, r4, Operand(Code::kHeaderSize - kHeapObjectTag));
1144  __ str(r4, FieldMemOperand(r1, JSFunction::kCodeEntryOffset));
1145  __ RecordWriteCodeEntryField(r1, r4, r5);
1146  __ Jump(r4);
1147}
1148
1149static void Generate_StackOverflowCheck(MacroAssembler* masm, Register num_args,
1150                                        Register scratch,
1151                                        Label* stack_overflow) {
1152  // Check the stack for overflow. We are not trying to catch
1153  // interruptions (e.g. debug break and preemption) here, so the "real stack
1154  // limit" is checked.
1155  __ LoadRoot(scratch, Heap::kRealStackLimitRootIndex);
1156  // Make scratch the space we have left. The stack might already be overflowed
1157  // here which will cause scratch to become negative.
1158  __ sub(scratch, sp, scratch);
1159  // Check if the arguments will overflow the stack.
1160  __ cmp(scratch, Operand(num_args, LSL, kPointerSizeLog2));
1161  __ b(le, stack_overflow);  // Signed comparison.
1162}
1163
1164static void Generate_InterpreterPushArgs(MacroAssembler* masm,
1165                                         Register num_args, Register index,
1166                                         Register limit, Register scratch,
1167                                         Label* stack_overflow) {
1168  // Add a stack check before pushing arguments.
1169  Generate_StackOverflowCheck(masm, num_args, scratch, stack_overflow);
1170
1171  // Find the address of the last argument.
1172  __ mov(limit, num_args);
1173  __ mov(limit, Operand(limit, LSL, kPointerSizeLog2));
1174  __ sub(limit, index, limit);
1175
1176  Label loop_header, loop_check;
1177  __ b(al, &loop_check);
1178  __ bind(&loop_header);
1179  __ ldr(scratch, MemOperand(index, -kPointerSize, PostIndex));
1180  __ push(scratch);
1181  __ bind(&loop_check);
1182  __ cmp(index, limit);
1183  __ b(gt, &loop_header);
1184}
1185
1186// static
1187void Builtins::Generate_InterpreterPushArgsAndCallImpl(
1188    MacroAssembler* masm, TailCallMode tail_call_mode,
1189    CallableType function_type) {
1190  // ----------- S t a t e -------------
1191  //  -- r0 : the number of arguments (not including the receiver)
1192  //  -- r2 : the address of the first argument to be pushed. Subsequent
1193  //          arguments should be consecutive above this, in the same order as
1194  //          they are to be pushed onto the stack.
1195  //  -- r1 : the target to call (can be any Object).
1196  // -----------------------------------
1197  Label stack_overflow;
1198
1199  __ add(r3, r0, Operand(1));  // Add one for receiver.
1200
1201  // Push the arguments. r2, r4, r5 will be modified.
1202  Generate_InterpreterPushArgs(masm, r3, r2, r4, r5, &stack_overflow);
1203
1204  // Call the target.
1205  if (function_type == CallableType::kJSFunction) {
1206    __ Jump(masm->isolate()->builtins()->CallFunction(ConvertReceiverMode::kAny,
1207                                                      tail_call_mode),
1208            RelocInfo::CODE_TARGET);
1209  } else {
1210    DCHECK_EQ(function_type, CallableType::kAny);
1211    __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny,
1212                                              tail_call_mode),
1213            RelocInfo::CODE_TARGET);
1214  }
1215
1216  __ bind(&stack_overflow);
1217  {
1218    __ TailCallRuntime(Runtime::kThrowStackOverflow);
1219    // Unreachable code.
1220    __ bkpt(0);
1221  }
1222}
1223
1224// static
1225void Builtins::Generate_InterpreterPushArgsAndConstructImpl(
1226    MacroAssembler* masm, CallableType construct_type) {
1227  // ----------- S t a t e -------------
1228  // -- r0 : argument count (not including receiver)
1229  // -- r3 : new target
1230  // -- r1 : constructor to call
1231  // -- r2 : allocation site feedback if available, undefined otherwise.
1232  // -- r4 : address of the first argument
1233  // -----------------------------------
1234  Label stack_overflow;
1235
1236  // Push a slot for the receiver to be constructed.
1237  __ mov(ip, Operand::Zero());
1238  __ push(ip);
1239
1240  // Push the arguments. r5, r4, r6 will be modified.
1241  Generate_InterpreterPushArgs(masm, r0, r4, r5, r6, &stack_overflow);
1242
1243  __ AssertUndefinedOrAllocationSite(r2, r5);
1244  if (construct_type == CallableType::kJSFunction) {
1245    __ AssertFunction(r1);
1246
1247    // Tail call to the function-specific construct stub (still in the caller
1248    // context at this point).
1249    __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
1250    __ ldr(r4, FieldMemOperand(r4, SharedFunctionInfo::kConstructStubOffset));
1251    // Jump to the construct function.
1252    __ add(pc, r4, Operand(Code::kHeaderSize - kHeapObjectTag));
1253
1254  } else {
1255    DCHECK_EQ(construct_type, CallableType::kAny);
1256    // Call the constructor with r0, r1, and r3 unmodified.
1257    __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
1258  }
1259
1260  __ bind(&stack_overflow);
1261  {
1262    __ TailCallRuntime(Runtime::kThrowStackOverflow);
1263    // Unreachable code.
1264    __ bkpt(0);
1265  }
1266}
1267
1268// static
1269void Builtins::Generate_InterpreterPushArgsAndConstructArray(
1270    MacroAssembler* masm) {
1271  // ----------- S t a t e -------------
1272  // -- r0 : argument count (not including receiver)
1273  // -- r1 : target to call verified to be Array function
1274  // -- r2 : allocation site feedback if available, undefined otherwise.
1275  // -- r3 : address of the first argument
1276  // -----------------------------------
1277  Label stack_overflow;
1278
1279  __ add(r4, r0, Operand(1));  // Add one for receiver.
1280
1281  // TODO(mythria): Add a stack check before pushing arguments.
1282  // Push the arguments. r3, r5, r6 will be modified.
1283  Generate_InterpreterPushArgs(masm, r4, r3, r5, r6, &stack_overflow);
1284
1285  // Array constructor expects constructor in r3. It is same as r1 here.
1286  __ mov(r3, r1);
1287
1288  ArrayConstructorStub stub(masm->isolate());
1289  __ TailCallStub(&stub);
1290
1291  __ bind(&stack_overflow);
1292  {
1293    __ TailCallRuntime(Runtime::kThrowStackOverflow);
1294    // Unreachable code.
1295    __ bkpt(0);
1296  }
1297}
1298
1299static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) {
1300  // Set the return address to the correct point in the interpreter entry
1301  // trampoline.
1302  Smi* interpreter_entry_return_pc_offset(
1303      masm->isolate()->heap()->interpreter_entry_return_pc_offset());
1304  DCHECK_NE(interpreter_entry_return_pc_offset, Smi::kZero);
1305  __ Move(r2, masm->isolate()->builtins()->InterpreterEntryTrampoline());
1306  __ add(lr, r2, Operand(interpreter_entry_return_pc_offset->value() +
1307                         Code::kHeaderSize - kHeapObjectTag));
1308
1309  // Initialize the dispatch table register.
1310  __ mov(kInterpreterDispatchTableRegister,
1311         Operand(ExternalReference::interpreter_dispatch_table_address(
1312             masm->isolate())));
1313
1314  // Get the bytecode array pointer from the frame.
1315  __ ldr(kInterpreterBytecodeArrayRegister,
1316         MemOperand(fp, InterpreterFrameConstants::kBytecodeArrayFromFp));
1317
1318  if (FLAG_debug_code) {
1319    // Check function data field is actually a BytecodeArray object.
1320    __ SmiTst(kInterpreterBytecodeArrayRegister);
1321    __ Assert(ne, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry);
1322    __ CompareObjectType(kInterpreterBytecodeArrayRegister, r1, no_reg,
1323                         BYTECODE_ARRAY_TYPE);
1324    __ Assert(eq, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry);
1325  }
1326
1327  // Get the target bytecode offset from the frame.
1328  __ ldr(kInterpreterBytecodeOffsetRegister,
1329         MemOperand(fp, InterpreterFrameConstants::kBytecodeOffsetFromFp));
1330  __ SmiUntag(kInterpreterBytecodeOffsetRegister);
1331
1332  // Dispatch to the target bytecode.
1333  __ ldrb(r1, MemOperand(kInterpreterBytecodeArrayRegister,
1334                         kInterpreterBytecodeOffsetRegister));
1335  __ ldr(ip, MemOperand(kInterpreterDispatchTableRegister, r1, LSL,
1336                        kPointerSizeLog2));
1337  __ mov(pc, ip);
1338}
1339
1340void Builtins::Generate_InterpreterEnterBytecodeAdvance(MacroAssembler* masm) {
1341  // Advance the current bytecode offset stored within the given interpreter
1342  // stack frame. This simulates what all bytecode handlers do upon completion
1343  // of the underlying operation.
1344  __ ldr(r1, MemOperand(fp, InterpreterFrameConstants::kBytecodeArrayFromFp));
1345  __ ldr(r2, MemOperand(fp, InterpreterFrameConstants::kBytecodeOffsetFromFp));
1346  __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1347  {
1348    FrameScope scope(masm, StackFrame::INTERNAL);
1349    __ Push(kInterpreterAccumulatorRegister, r1, r2);
1350    __ CallRuntime(Runtime::kInterpreterAdvanceBytecodeOffset);
1351    __ mov(r2, r0);  // Result is the new bytecode offset.
1352    __ Pop(kInterpreterAccumulatorRegister);
1353  }
1354  __ str(r2, MemOperand(fp, InterpreterFrameConstants::kBytecodeOffsetFromFp));
1355
1356  Generate_InterpreterEnterBytecode(masm);
1357}
1358
1359void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) {
1360  Generate_InterpreterEnterBytecode(masm);
1361}
1362
1363void Builtins::Generate_CompileLazy(MacroAssembler* masm) {
1364  // ----------- S t a t e -------------
1365  //  -- r0 : argument count (preserved for callee)
1366  //  -- r3 : new target (preserved for callee)
1367  //  -- r1 : target function (preserved for callee)
1368  // -----------------------------------
1369  // First lookup code, maybe we don't need to compile!
1370  Label gotta_call_runtime, gotta_call_runtime_no_stack;
1371  Label try_shared;
1372  Label loop_top, loop_bottom;
1373
1374  Register argument_count = r0;
1375  Register closure = r1;
1376  Register new_target = r3;
1377  __ push(argument_count);
1378  __ push(new_target);
1379  __ push(closure);
1380
1381  Register map = argument_count;
1382  Register index = r2;
1383  __ ldr(map, FieldMemOperand(closure, JSFunction::kSharedFunctionInfoOffset));
1384  __ ldr(map,
1385         FieldMemOperand(map, SharedFunctionInfo::kOptimizedCodeMapOffset));
1386  __ ldr(index, FieldMemOperand(map, FixedArray::kLengthOffset));
1387  __ cmp(index, Operand(Smi::FromInt(2)));
1388  __ b(lt, &gotta_call_runtime);
1389
1390  // Find literals.
1391  // r3  : native context
1392  // r2  : length / index
1393  // r0  : optimized code map
1394  // stack[0] : new target
1395  // stack[4] : closure
1396  Register native_context = r3;
1397  __ ldr(native_context, NativeContextMemOperand());
1398
1399  __ bind(&loop_top);
1400  Register temp = r1;
1401  Register array_pointer = r5;
1402
1403  // Does the native context match?
1404  __ add(array_pointer, map, Operand::PointerOffsetFromSmiKey(index));
1405  __ ldr(temp, FieldMemOperand(array_pointer,
1406                               SharedFunctionInfo::kOffsetToPreviousContext));
1407  __ ldr(temp, FieldMemOperand(temp, WeakCell::kValueOffset));
1408  __ cmp(temp, native_context);
1409  __ b(ne, &loop_bottom);
1410  // OSR id set to none?
1411  __ ldr(temp, FieldMemOperand(array_pointer,
1412                               SharedFunctionInfo::kOffsetToPreviousOsrAstId));
1413  const int bailout_id = BailoutId::None().ToInt();
1414  __ cmp(temp, Operand(Smi::FromInt(bailout_id)));
1415  __ b(ne, &loop_bottom);
1416  // Literals available?
1417  __ ldr(temp, FieldMemOperand(array_pointer,
1418                               SharedFunctionInfo::kOffsetToPreviousLiterals));
1419  __ ldr(temp, FieldMemOperand(temp, WeakCell::kValueOffset));
1420  __ JumpIfSmi(temp, &gotta_call_runtime);
1421
1422  // Save the literals in the closure.
1423  __ ldr(r4, MemOperand(sp, 0));
1424  __ str(temp, FieldMemOperand(r4, JSFunction::kLiteralsOffset));
1425  __ push(index);
1426  __ RecordWriteField(r4, JSFunction::kLiteralsOffset, temp, index,
1427                      kLRHasNotBeenSaved, kDontSaveFPRegs, EMIT_REMEMBERED_SET,
1428                      OMIT_SMI_CHECK);
1429  __ pop(index);
1430
1431  // Code available?
1432  Register entry = r4;
1433  __ ldr(entry,
1434         FieldMemOperand(array_pointer,
1435                         SharedFunctionInfo::kOffsetToPreviousCachedCode));
1436  __ ldr(entry, FieldMemOperand(entry, WeakCell::kValueOffset));
1437  __ JumpIfSmi(entry, &try_shared);
1438
1439  // Found literals and code. Get them into the closure and return.
1440  __ pop(closure);
1441  // Store code entry in the closure.
1442  __ add(entry, entry, Operand(Code::kHeaderSize - kHeapObjectTag));
1443  __ str(entry, FieldMemOperand(closure, JSFunction::kCodeEntryOffset));
1444  __ RecordWriteCodeEntryField(closure, entry, r5);
1445
1446  // Link the closure into the optimized function list.
1447  // r4 : code entry
1448  // r3 : native context
1449  // r1 : closure
1450  __ ldr(r5,
1451         ContextMemOperand(native_context, Context::OPTIMIZED_FUNCTIONS_LIST));
1452  __ str(r5, FieldMemOperand(closure, JSFunction::kNextFunctionLinkOffset));
1453  __ RecordWriteField(closure, JSFunction::kNextFunctionLinkOffset, r5, r0,
1454                      kLRHasNotBeenSaved, kDontSaveFPRegs, EMIT_REMEMBERED_SET,
1455                      OMIT_SMI_CHECK);
1456  const int function_list_offset =
1457      Context::SlotOffset(Context::OPTIMIZED_FUNCTIONS_LIST);
1458  __ str(closure,
1459         ContextMemOperand(native_context, Context::OPTIMIZED_FUNCTIONS_LIST));
1460  // Save closure before the write barrier.
1461  __ mov(r5, closure);
1462  __ RecordWriteContextSlot(native_context, function_list_offset, closure, r0,
1463                            kLRHasNotBeenSaved, kDontSaveFPRegs);
1464  __ mov(closure, r5);
1465  __ pop(new_target);
1466  __ pop(argument_count);
1467  __ Jump(entry);
1468
1469  __ bind(&loop_bottom);
1470  __ sub(index, index, Operand(Smi::FromInt(SharedFunctionInfo::kEntryLength)));
1471  __ cmp(index, Operand(Smi::FromInt(1)));
1472  __ b(gt, &loop_top);
1473
1474  // We found neither literals nor code.
1475  __ jmp(&gotta_call_runtime);
1476
1477  __ bind(&try_shared);
1478  __ pop(closure);
1479  __ pop(new_target);
1480  __ pop(argument_count);
1481  __ ldr(entry,
1482         FieldMemOperand(closure, JSFunction::kSharedFunctionInfoOffset));
1483  // Is the shared function marked for tier up?
1484  __ ldrb(r5, FieldMemOperand(entry,
1485                              SharedFunctionInfo::kMarkedForTierUpByteOffset));
1486  __ tst(r5, Operand(1 << SharedFunctionInfo::kMarkedForTierUpBitWithinByte));
1487  __ b(ne, &gotta_call_runtime_no_stack);
1488  // Is the full code valid?
1489  __ ldr(entry, FieldMemOperand(entry, SharedFunctionInfo::kCodeOffset));
1490  __ ldr(r5, FieldMemOperand(entry, Code::kFlagsOffset));
1491  __ and_(r5, r5, Operand(Code::KindField::kMask));
1492  __ mov(r5, Operand(r5, LSR, Code::KindField::kShift));
1493  __ cmp(r5, Operand(Code::BUILTIN));
1494  __ b(eq, &gotta_call_runtime_no_stack);
1495  // Yes, install the full code.
1496  __ add(entry, entry, Operand(Code::kHeaderSize - kHeapObjectTag));
1497  __ str(entry, FieldMemOperand(closure, JSFunction::kCodeEntryOffset));
1498  __ RecordWriteCodeEntryField(closure, entry, r5);
1499  __ Jump(entry);
1500
1501  __ bind(&gotta_call_runtime);
1502  __ pop(closure);
1503  __ pop(new_target);
1504  __ pop(argument_count);
1505  __ bind(&gotta_call_runtime_no_stack);
1506  GenerateTailCallToReturnedCode(masm, Runtime::kCompileLazy);
1507}
1508
1509void Builtins::Generate_CompileBaseline(MacroAssembler* masm) {
1510  GenerateTailCallToReturnedCode(masm, Runtime::kCompileBaseline);
1511}
1512
1513void Builtins::Generate_CompileOptimized(MacroAssembler* masm) {
1514  GenerateTailCallToReturnedCode(masm,
1515                                 Runtime::kCompileOptimized_NotConcurrent);
1516}
1517
1518void Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) {
1519  GenerateTailCallToReturnedCode(masm, Runtime::kCompileOptimized_Concurrent);
1520}
1521
1522void Builtins::Generate_InstantiateAsmJs(MacroAssembler* masm) {
1523  // ----------- S t a t e -------------
1524  //  -- r0 : argument count (preserved for callee)
1525  //  -- r1 : new target (preserved for callee)
1526  //  -- r3 : target function (preserved for callee)
1527  // -----------------------------------
1528  Label failed;
1529  {
1530    FrameScope scope(masm, StackFrame::INTERNAL);
1531    // Preserve argument count for later compare.
1532    __ Move(r4, r0);
1533    // Push the number of arguments to the callee.
1534    __ SmiTag(r0);
1535    __ push(r0);
1536    // Push a copy of the target function and the new target.
1537    __ push(r1);
1538    __ push(r3);
1539
1540    // The function.
1541    __ push(r1);
1542    // Copy arguments from caller (stdlib, foreign, heap).
1543    Label args_done;
1544    for (int j = 0; j < 4; ++j) {
1545      Label over;
1546      if (j < 3) {
1547        __ cmp(r4, Operand(j));
1548        __ b(ne, &over);
1549      }
1550      for (int i = j - 1; i >= 0; --i) {
1551        __ ldr(r4, MemOperand(fp, StandardFrameConstants::kCallerSPOffset +
1552                                      i * kPointerSize));
1553        __ push(r4);
1554      }
1555      for (int i = 0; i < 3 - j; ++i) {
1556        __ PushRoot(Heap::kUndefinedValueRootIndex);
1557      }
1558      if (j < 3) {
1559        __ jmp(&args_done);
1560        __ bind(&over);
1561      }
1562    }
1563    __ bind(&args_done);
1564
1565    // Call runtime, on success unwind frame, and parent frame.
1566    __ CallRuntime(Runtime::kInstantiateAsmJs, 4);
1567    // A smi 0 is returned on failure, an object on success.
1568    __ JumpIfSmi(r0, &failed);
1569
1570    __ Drop(2);
1571    __ pop(r4);
1572    __ SmiUntag(r4);
1573    scope.GenerateLeaveFrame();
1574
1575    __ add(r4, r4, Operand(1));
1576    __ Drop(r4);
1577    __ Ret();
1578
1579    __ bind(&failed);
1580    // Restore target function and new target.
1581    __ pop(r3);
1582    __ pop(r1);
1583    __ pop(r0);
1584    __ SmiUntag(r0);
1585  }
1586  // On failure, tail call back to regular js.
1587  GenerateTailCallToReturnedCode(masm, Runtime::kCompileLazy);
1588}
1589
1590static void GenerateMakeCodeYoungAgainCommon(MacroAssembler* masm) {
1591  // For now, we are relying on the fact that make_code_young doesn't do any
1592  // garbage collection which allows us to save/restore the registers without
1593  // worrying about which of them contain pointers. We also don't build an
1594  // internal frame to make the code faster, since we shouldn't have to do stack
1595  // crawls in MakeCodeYoung. This seems a bit fragile.
1596
1597  // The following registers must be saved and restored when calling through to
1598  // the runtime:
1599  //   r0 - contains return address (beginning of patch sequence)
1600  //   r1 - isolate
1601  //   r3 - new target
1602  FrameScope scope(masm, StackFrame::MANUAL);
1603  __ stm(db_w, sp, r0.bit() | r1.bit() | r3.bit() | fp.bit() | lr.bit());
1604  __ PrepareCallCFunction(2, 0, r2);
1605  __ mov(r1, Operand(ExternalReference::isolate_address(masm->isolate())));
1606  __ CallCFunction(
1607      ExternalReference::get_make_code_young_function(masm->isolate()), 2);
1608  __ ldm(ia_w, sp, r0.bit() | r1.bit() | r3.bit() | fp.bit() | lr.bit());
1609  __ mov(pc, r0);
1610}
1611
1612#define DEFINE_CODE_AGE_BUILTIN_GENERATOR(C)                  \
1613  void Builtins::Generate_Make##C##CodeYoungAgainEvenMarking( \
1614      MacroAssembler* masm) {                                 \
1615    GenerateMakeCodeYoungAgainCommon(masm);                   \
1616  }                                                           \
1617  void Builtins::Generate_Make##C##CodeYoungAgainOddMarking(  \
1618      MacroAssembler* masm) {                                 \
1619    GenerateMakeCodeYoungAgainCommon(masm);                   \
1620  }
1621CODE_AGE_LIST(DEFINE_CODE_AGE_BUILTIN_GENERATOR)
1622#undef DEFINE_CODE_AGE_BUILTIN_GENERATOR
1623
1624void Builtins::Generate_MarkCodeAsExecutedOnce(MacroAssembler* masm) {
1625  // For now, as in GenerateMakeCodeYoungAgainCommon, we are relying on the fact
1626  // that make_code_young doesn't do any garbage collection which allows us to
1627  // save/restore the registers without worrying about which of them contain
1628  // pointers.
1629
1630  // The following registers must be saved and restored when calling through to
1631  // the runtime:
1632  //   r0 - contains return address (beginning of patch sequence)
1633  //   r1 - isolate
1634  //   r3 - new target
1635  FrameScope scope(masm, StackFrame::MANUAL);
1636  __ stm(db_w, sp, r0.bit() | r1.bit() | r3.bit() | fp.bit() | lr.bit());
1637  __ PrepareCallCFunction(2, 0, r2);
1638  __ mov(r1, Operand(ExternalReference::isolate_address(masm->isolate())));
1639  __ CallCFunction(
1640      ExternalReference::get_mark_code_as_executed_function(masm->isolate()),
1641      2);
1642  __ ldm(ia_w, sp, r0.bit() | r1.bit() | r3.bit() | fp.bit() | lr.bit());
1643
1644  // Perform prologue operations usually performed by the young code stub.
1645  __ PushStandardFrame(r1);
1646
1647  // Jump to point after the code-age stub.
1648  __ add(r0, r0, Operand(kNoCodeAgeSequenceLength));
1649  __ mov(pc, r0);
1650}
1651
1652void Builtins::Generate_MarkCodeAsExecutedTwice(MacroAssembler* masm) {
1653  GenerateMakeCodeYoungAgainCommon(masm);
1654}
1655
1656void Builtins::Generate_MarkCodeAsToBeExecutedOnce(MacroAssembler* masm) {
1657  Generate_MarkCodeAsExecutedOnce(masm);
1658}
1659
1660static void Generate_NotifyStubFailureHelper(MacroAssembler* masm,
1661                                             SaveFPRegsMode save_doubles) {
1662  {
1663    FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
1664
1665    // Preserve registers across notification, this is important for compiled
1666    // stubs that tail call the runtime on deopts passing their parameters in
1667    // registers.
1668    __ stm(db_w, sp, kJSCallerSaved | kCalleeSaved);
1669    // Pass the function and deoptimization type to the runtime system.
1670    __ CallRuntime(Runtime::kNotifyStubFailure, save_doubles);
1671    __ ldm(ia_w, sp, kJSCallerSaved | kCalleeSaved);
1672  }
1673
1674  __ add(sp, sp, Operand(kPointerSize));  // Ignore state
1675  __ mov(pc, lr);                         // Jump to miss handler
1676}
1677
1678void Builtins::Generate_NotifyStubFailure(MacroAssembler* masm) {
1679  Generate_NotifyStubFailureHelper(masm, kDontSaveFPRegs);
1680}
1681
1682void Builtins::Generate_NotifyStubFailureSaveDoubles(MacroAssembler* masm) {
1683  Generate_NotifyStubFailureHelper(masm, kSaveFPRegs);
1684}
1685
1686static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm,
1687                                             Deoptimizer::BailoutType type) {
1688  {
1689    FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
1690    // Pass the function and deoptimization type to the runtime system.
1691    __ mov(r0, Operand(Smi::FromInt(static_cast<int>(type))));
1692    __ push(r0);
1693    __ CallRuntime(Runtime::kNotifyDeoptimized);
1694  }
1695
1696  // Get the full codegen state from the stack and untag it -> r6.
1697  __ ldr(r6, MemOperand(sp, 0 * kPointerSize));
1698  __ SmiUntag(r6);
1699  // Switch on the state.
1700  Label with_tos_register, unknown_state;
1701  __ cmp(r6,
1702         Operand(static_cast<int>(Deoptimizer::BailoutState::NO_REGISTERS)));
1703  __ b(ne, &with_tos_register);
1704  __ add(sp, sp, Operand(1 * kPointerSize));  // Remove state.
1705  __ Ret();
1706
1707  __ bind(&with_tos_register);
1708  DCHECK_EQ(kInterpreterAccumulatorRegister.code(), r0.code());
1709  __ ldr(r0, MemOperand(sp, 1 * kPointerSize));
1710  __ cmp(r6,
1711         Operand(static_cast<int>(Deoptimizer::BailoutState::TOS_REGISTER)));
1712  __ b(ne, &unknown_state);
1713  __ add(sp, sp, Operand(2 * kPointerSize));  // Remove state.
1714  __ Ret();
1715
1716  __ bind(&unknown_state);
1717  __ stop("no cases left");
1718}
1719
1720void Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) {
1721  Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::EAGER);
1722}
1723
1724void Builtins::Generate_NotifySoftDeoptimized(MacroAssembler* masm) {
1725  Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::SOFT);
1726}
1727
1728void Builtins::Generate_NotifyLazyDeoptimized(MacroAssembler* masm) {
1729  Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::LAZY);
1730}
1731
1732static void CompatibleReceiverCheck(MacroAssembler* masm, Register receiver,
1733                                    Register function_template_info,
1734                                    Register scratch0, Register scratch1,
1735                                    Register scratch2,
1736                                    Label* receiver_check_failed) {
1737  Register signature = scratch0;
1738  Register map = scratch1;
1739  Register constructor = scratch2;
1740
1741  // If there is no signature, return the holder.
1742  __ ldr(signature, FieldMemOperand(function_template_info,
1743                                    FunctionTemplateInfo::kSignatureOffset));
1744  __ CompareRoot(signature, Heap::kUndefinedValueRootIndex);
1745  Label receiver_check_passed;
1746  __ b(eq, &receiver_check_passed);
1747
1748  // Walk the prototype chain.
1749  __ ldr(map, FieldMemOperand(receiver, HeapObject::kMapOffset));
1750  Label prototype_loop_start;
1751  __ bind(&prototype_loop_start);
1752
1753  // Get the constructor, if any.
1754  __ GetMapConstructor(constructor, map, ip, ip);
1755  __ cmp(ip, Operand(JS_FUNCTION_TYPE));
1756  Label next_prototype;
1757  __ b(ne, &next_prototype);
1758  Register type = constructor;
1759  __ ldr(type,
1760         FieldMemOperand(constructor, JSFunction::kSharedFunctionInfoOffset));
1761  __ ldr(type, FieldMemOperand(type, SharedFunctionInfo::kFunctionDataOffset));
1762
1763  // Loop through the chain of inheriting function templates.
1764  Label function_template_loop;
1765  __ bind(&function_template_loop);
1766
1767  // If the signatures match, we have a compatible receiver.
1768  __ cmp(signature, type);
1769  __ b(eq, &receiver_check_passed);
1770
1771  // If the current type is not a FunctionTemplateInfo, load the next prototype
1772  // in the chain.
1773  __ JumpIfSmi(type, &next_prototype);
1774  __ CompareObjectType(type, ip, ip, FUNCTION_TEMPLATE_INFO_TYPE);
1775
1776  // Otherwise load the parent function template and iterate.
1777  __ ldr(type,
1778         FieldMemOperand(type, FunctionTemplateInfo::kParentTemplateOffset),
1779         eq);
1780  __ b(&function_template_loop, eq);
1781
1782  // Load the next prototype.
1783  __ bind(&next_prototype);
1784  __ ldr(ip, FieldMemOperand(map, Map::kBitField3Offset));
1785  __ tst(ip, Operand(Map::HasHiddenPrototype::kMask));
1786  __ b(eq, receiver_check_failed);
1787  __ ldr(receiver, FieldMemOperand(map, Map::kPrototypeOffset));
1788  __ ldr(map, FieldMemOperand(receiver, HeapObject::kMapOffset));
1789  // Iterate.
1790  __ b(&prototype_loop_start);
1791
1792  __ bind(&receiver_check_passed);
1793}
1794
1795void Builtins::Generate_HandleFastApiCall(MacroAssembler* masm) {
1796  // ----------- S t a t e -------------
1797  //  -- r0                 : number of arguments excluding receiver
1798  //  -- r1                 : callee
1799  //  -- lr                 : return address
1800  //  -- sp[0]              : last argument
1801  //  -- ...
1802  //  -- sp[4 * (argc - 1)] : first argument
1803  //  -- sp[4 * argc]       : receiver
1804  // -----------------------------------
1805
1806  // Load the FunctionTemplateInfo.
1807  __ ldr(r3, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
1808  __ ldr(r3, FieldMemOperand(r3, SharedFunctionInfo::kFunctionDataOffset));
1809
1810  // Do the compatible receiver check.
1811  Label receiver_check_failed;
1812  __ ldr(r2, MemOperand(sp, r0, LSL, kPointerSizeLog2));
1813  CompatibleReceiverCheck(masm, r2, r3, r4, r5, r6, &receiver_check_failed);
1814
1815  // Get the callback offset from the FunctionTemplateInfo, and jump to the
1816  // beginning of the code.
1817  __ ldr(r4, FieldMemOperand(r3, FunctionTemplateInfo::kCallCodeOffset));
1818  __ ldr(r4, FieldMemOperand(r4, CallHandlerInfo::kFastHandlerOffset));
1819  __ add(r4, r4, Operand(Code::kHeaderSize - kHeapObjectTag));
1820  __ Jump(r4);
1821
1822  // Compatible receiver check failed: throw an Illegal Invocation exception.
1823  __ bind(&receiver_check_failed);
1824  // Drop the arguments (including the receiver)
1825  __ add(r0, r0, Operand(1));
1826  __ add(sp, sp, Operand(r0, LSL, kPointerSizeLog2));
1827  __ TailCallRuntime(Runtime::kThrowIllegalInvocation);
1828}
1829
1830static void Generate_OnStackReplacementHelper(MacroAssembler* masm,
1831                                              bool has_handler_frame) {
1832  // Lookup the function in the JavaScript frame.
1833  if (has_handler_frame) {
1834    __ ldr(r0, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
1835    __ ldr(r0, MemOperand(r0, JavaScriptFrameConstants::kFunctionOffset));
1836  } else {
1837    __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
1838  }
1839
1840  {
1841    FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
1842    // Pass function as argument.
1843    __ push(r0);
1844    __ CallRuntime(Runtime::kCompileForOnStackReplacement);
1845  }
1846
1847  // If the code object is null, just return to the caller.
1848  Label skip;
1849  __ cmp(r0, Operand(Smi::kZero));
1850  __ b(ne, &skip);
1851  __ Ret();
1852
1853  __ bind(&skip);
1854
1855  // Drop any potential handler frame that is be sitting on top of the actual
1856  // JavaScript frame. This is the case then OSR is triggered from bytecode.
1857  if (has_handler_frame) {
1858    __ LeaveFrame(StackFrame::STUB);
1859  }
1860
1861  // Load deoptimization data from the code object.
1862  // <deopt_data> = <code>[#deoptimization_data_offset]
1863  __ ldr(r1, FieldMemOperand(r0, Code::kDeoptimizationDataOffset));
1864
1865  {
1866    ConstantPoolUnavailableScope constant_pool_unavailable(masm);
1867    __ add(r0, r0, Operand(Code::kHeaderSize - kHeapObjectTag));  // Code start
1868
1869    if (FLAG_enable_embedded_constant_pool) {
1870      __ LoadConstantPoolPointerRegisterFromCodeTargetAddress(r0);
1871    }
1872
1873    // Load the OSR entrypoint offset from the deoptimization data.
1874    // <osr_offset> = <deopt_data>[#header_size + #osr_pc_offset]
1875    __ ldr(r1, FieldMemOperand(
1876                   r1, FixedArray::OffsetOfElementAt(
1877                           DeoptimizationInputData::kOsrPcOffsetIndex)));
1878
1879    // Compute the target address = code start + osr_offset
1880    __ add(lr, r0, Operand::SmiUntag(r1));
1881
1882    // And "return" to the OSR entry point of the function.
1883    __ Ret();
1884  }
1885}
1886
1887void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) {
1888  Generate_OnStackReplacementHelper(masm, false);
1889}
1890
1891void Builtins::Generate_InterpreterOnStackReplacement(MacroAssembler* masm) {
1892  Generate_OnStackReplacementHelper(masm, true);
1893}
1894
1895// static
1896void Builtins::Generate_FunctionPrototypeApply(MacroAssembler* masm) {
1897  // ----------- S t a t e -------------
1898  //  -- r0    : argc
1899  //  -- sp[0] : argArray
1900  //  -- sp[4] : thisArg
1901  //  -- sp[8] : receiver
1902  // -----------------------------------
1903
1904  // 1. Load receiver into r1, argArray into r0 (if present), remove all
1905  // arguments from the stack (including the receiver), and push thisArg (if
1906  // present) instead.
1907  {
1908    __ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
1909    __ mov(r3, r2);
1910    __ ldr(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2));  // receiver
1911    __ sub(r4, r0, Operand(1), SetCC);
1912    __ ldr(r2, MemOperand(sp, r4, LSL, kPointerSizeLog2), ge);  // thisArg
1913    __ sub(r4, r4, Operand(1), SetCC, ge);
1914    __ ldr(r3, MemOperand(sp, r4, LSL, kPointerSizeLog2), ge);  // argArray
1915    __ add(sp, sp, Operand(r0, LSL, kPointerSizeLog2));
1916    __ str(r2, MemOperand(sp, 0));
1917    __ mov(r0, r3);
1918  }
1919
1920  // ----------- S t a t e -------------
1921  //  -- r0    : argArray
1922  //  -- r1    : receiver
1923  //  -- sp[0] : thisArg
1924  // -----------------------------------
1925
1926  // 2. Make sure the receiver is actually callable.
1927  Label receiver_not_callable;
1928  __ JumpIfSmi(r1, &receiver_not_callable);
1929  __ ldr(r4, FieldMemOperand(r1, HeapObject::kMapOffset));
1930  __ ldrb(r4, FieldMemOperand(r4, Map::kBitFieldOffset));
1931  __ tst(r4, Operand(1 << Map::kIsCallable));
1932  __ b(eq, &receiver_not_callable);
1933
1934  // 3. Tail call with no arguments if argArray is null or undefined.
1935  Label no_arguments;
1936  __ JumpIfRoot(r0, Heap::kNullValueRootIndex, &no_arguments);
1937  __ JumpIfRoot(r0, Heap::kUndefinedValueRootIndex, &no_arguments);
1938
1939  // 4a. Apply the receiver to the given argArray (passing undefined for
1940  // new.target).
1941  __ LoadRoot(r3, Heap::kUndefinedValueRootIndex);
1942  __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET);
1943
1944  // 4b. The argArray is either null or undefined, so we tail call without any
1945  // arguments to the receiver.
1946  __ bind(&no_arguments);
1947  {
1948    __ mov(r0, Operand(0));
1949    __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
1950  }
1951
1952  // 4c. The receiver is not callable, throw an appropriate TypeError.
1953  __ bind(&receiver_not_callable);
1954  {
1955    __ str(r1, MemOperand(sp, 0));
1956    __ TailCallRuntime(Runtime::kThrowApplyNonFunction);
1957  }
1958}
1959
1960// static
1961void Builtins::Generate_FunctionPrototypeCall(MacroAssembler* masm) {
1962  // 1. Make sure we have at least one argument.
1963  // r0: actual number of arguments
1964  {
1965    Label done;
1966    __ cmp(r0, Operand::Zero());
1967    __ b(ne, &done);
1968    __ PushRoot(Heap::kUndefinedValueRootIndex);
1969    __ add(r0, r0, Operand(1));
1970    __ bind(&done);
1971  }
1972
1973  // 2. Get the callable to call (passed as receiver) from the stack.
1974  // r0: actual number of arguments
1975  __ ldr(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2));
1976
1977  // 3. Shift arguments and return address one slot down on the stack
1978  //    (overwriting the original receiver).  Adjust argument count to make
1979  //    the original first argument the new receiver.
1980  // r0: actual number of arguments
1981  // r1: callable
1982  {
1983    Label loop;
1984    // Calculate the copy start address (destination). Copy end address is sp.
1985    __ add(r2, sp, Operand(r0, LSL, kPointerSizeLog2));
1986
1987    __ bind(&loop);
1988    __ ldr(ip, MemOperand(r2, -kPointerSize));
1989    __ str(ip, MemOperand(r2));
1990    __ sub(r2, r2, Operand(kPointerSize));
1991    __ cmp(r2, sp);
1992    __ b(ne, &loop);
1993    // Adjust the actual number of arguments and remove the top element
1994    // (which is a copy of the last argument).
1995    __ sub(r0, r0, Operand(1));
1996    __ pop();
1997  }
1998
1999  // 4. Call the callable.
2000  __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
2001}
2002
2003void Builtins::Generate_ReflectApply(MacroAssembler* masm) {
2004  // ----------- S t a t e -------------
2005  //  -- r0     : argc
2006  //  -- sp[0]  : argumentsList
2007  //  -- sp[4]  : thisArgument
2008  //  -- sp[8]  : target
2009  //  -- sp[12] : receiver
2010  // -----------------------------------
2011
2012  // 1. Load target into r1 (if present), argumentsList into r0 (if present),
2013  // remove all arguments from the stack (including the receiver), and push
2014  // thisArgument (if present) instead.
2015  {
2016    __ LoadRoot(r1, Heap::kUndefinedValueRootIndex);
2017    __ mov(r2, r1);
2018    __ mov(r3, r1);
2019    __ sub(r4, r0, Operand(1), SetCC);
2020    __ ldr(r1, MemOperand(sp, r4, LSL, kPointerSizeLog2), ge);  // target
2021    __ sub(r4, r4, Operand(1), SetCC, ge);
2022    __ ldr(r2, MemOperand(sp, r4, LSL, kPointerSizeLog2), ge);  // thisArgument
2023    __ sub(r4, r4, Operand(1), SetCC, ge);
2024    __ ldr(r3, MemOperand(sp, r4, LSL, kPointerSizeLog2), ge);  // argumentsList
2025    __ add(sp, sp, Operand(r0, LSL, kPointerSizeLog2));
2026    __ str(r2, MemOperand(sp, 0));
2027    __ mov(r0, r3);
2028  }
2029
2030  // ----------- S t a t e -------------
2031  //  -- r0    : argumentsList
2032  //  -- r1    : target
2033  //  -- sp[0] : thisArgument
2034  // -----------------------------------
2035
2036  // 2. Make sure the target is actually callable.
2037  Label target_not_callable;
2038  __ JumpIfSmi(r1, &target_not_callable);
2039  __ ldr(r4, FieldMemOperand(r1, HeapObject::kMapOffset));
2040  __ ldrb(r4, FieldMemOperand(r4, Map::kBitFieldOffset));
2041  __ tst(r4, Operand(1 << Map::kIsCallable));
2042  __ b(eq, &target_not_callable);
2043
2044  // 3a. Apply the target to the given argumentsList (passing undefined for
2045  // new.target).
2046  __ LoadRoot(r3, Heap::kUndefinedValueRootIndex);
2047  __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET);
2048
2049  // 3b. The target is not callable, throw an appropriate TypeError.
2050  __ bind(&target_not_callable);
2051  {
2052    __ str(r1, MemOperand(sp, 0));
2053    __ TailCallRuntime(Runtime::kThrowApplyNonFunction);
2054  }
2055}
2056
2057void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) {
2058  // ----------- S t a t e -------------
2059  //  -- r0     : argc
2060  //  -- sp[0]  : new.target (optional)
2061  //  -- sp[4]  : argumentsList
2062  //  -- sp[8]  : target
2063  //  -- sp[12] : receiver
2064  // -----------------------------------
2065
2066  // 1. Load target into r1 (if present), argumentsList into r0 (if present),
2067  // new.target into r3 (if present, otherwise use target), remove all
2068  // arguments from the stack (including the receiver), and push thisArgument
2069  // (if present) instead.
2070  {
2071    __ LoadRoot(r1, Heap::kUndefinedValueRootIndex);
2072    __ mov(r2, r1);
2073    __ str(r2, MemOperand(sp, r0, LSL, kPointerSizeLog2));  // receiver
2074    __ sub(r4, r0, Operand(1), SetCC);
2075    __ ldr(r1, MemOperand(sp, r4, LSL, kPointerSizeLog2), ge);  // target
2076    __ mov(r3, r1);  // new.target defaults to target
2077    __ sub(r4, r4, Operand(1), SetCC, ge);
2078    __ ldr(r2, MemOperand(sp, r4, LSL, kPointerSizeLog2), ge);  // argumentsList
2079    __ sub(r4, r4, Operand(1), SetCC, ge);
2080    __ ldr(r3, MemOperand(sp, r4, LSL, kPointerSizeLog2), ge);  // new.target
2081    __ add(sp, sp, Operand(r0, LSL, kPointerSizeLog2));
2082    __ mov(r0, r2);
2083  }
2084
2085  // ----------- S t a t e -------------
2086  //  -- r0    : argumentsList
2087  //  -- r3    : new.target
2088  //  -- r1    : target
2089  //  -- sp[0] : receiver (undefined)
2090  // -----------------------------------
2091
2092  // 2. Make sure the target is actually a constructor.
2093  Label target_not_constructor;
2094  __ JumpIfSmi(r1, &target_not_constructor);
2095  __ ldr(r4, FieldMemOperand(r1, HeapObject::kMapOffset));
2096  __ ldrb(r4, FieldMemOperand(r4, Map::kBitFieldOffset));
2097  __ tst(r4, Operand(1 << Map::kIsConstructor));
2098  __ b(eq, &target_not_constructor);
2099
2100  // 3. Make sure the target is actually a constructor.
2101  Label new_target_not_constructor;
2102  __ JumpIfSmi(r3, &new_target_not_constructor);
2103  __ ldr(r4, FieldMemOperand(r3, HeapObject::kMapOffset));
2104  __ ldrb(r4, FieldMemOperand(r4, Map::kBitFieldOffset));
2105  __ tst(r4, Operand(1 << Map::kIsConstructor));
2106  __ b(eq, &new_target_not_constructor);
2107
2108  // 4a. Construct the target with the given new.target and argumentsList.
2109  __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET);
2110
2111  // 4b. The target is not a constructor, throw an appropriate TypeError.
2112  __ bind(&target_not_constructor);
2113  {
2114    __ str(r1, MemOperand(sp, 0));
2115    __ TailCallRuntime(Runtime::kThrowCalledNonCallable);
2116  }
2117
2118  // 4c. The new.target is not a constructor, throw an appropriate TypeError.
2119  __ bind(&new_target_not_constructor);
2120  {
2121    __ str(r3, MemOperand(sp, 0));
2122    __ TailCallRuntime(Runtime::kThrowCalledNonCallable);
2123  }
2124}
2125
2126static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
2127  __ SmiTag(r0);
2128  __ mov(r4, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
2129  __ stm(db_w, sp, r0.bit() | r1.bit() | r4.bit() |
2130                       (FLAG_enable_embedded_constant_pool ? pp.bit() : 0) |
2131                       fp.bit() | lr.bit());
2132  __ add(fp, sp,
2133         Operand(StandardFrameConstants::kFixedFrameSizeFromFp + kPointerSize));
2134}
2135
2136static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) {
2137  // ----------- S t a t e -------------
2138  //  -- r0 : result being passed through
2139  // -----------------------------------
2140  // Get the number of arguments passed (as a smi), tear down the frame and
2141  // then tear down the parameters.
2142  __ ldr(r1, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp +
2143                              kPointerSize)));
2144
2145  __ LeaveFrame(StackFrame::ARGUMENTS_ADAPTOR);
2146  __ add(sp, sp, Operand::PointerOffsetFromSmiKey(r1));
2147  __ add(sp, sp, Operand(kPointerSize));  // adjust for receiver
2148}
2149
2150// static
2151void Builtins::Generate_Apply(MacroAssembler* masm) {
2152  // ----------- S t a t e -------------
2153  //  -- r0    : argumentsList
2154  //  -- r1    : target
2155  //  -- r3    : new.target (checked to be constructor or undefined)
2156  //  -- sp[0] : thisArgument
2157  // -----------------------------------
2158
2159  // Create the list of arguments from the array-like argumentsList.
2160  {
2161    Label create_arguments, create_array, create_runtime, done_create;
2162    __ JumpIfSmi(r0, &create_runtime);
2163
2164    // Load the map of argumentsList into r2.
2165    __ ldr(r2, FieldMemOperand(r0, HeapObject::kMapOffset));
2166
2167    // Load native context into r4.
2168    __ ldr(r4, NativeContextMemOperand());
2169
2170    // Check if argumentsList is an (unmodified) arguments object.
2171    __ ldr(ip, ContextMemOperand(r4, Context::SLOPPY_ARGUMENTS_MAP_INDEX));
2172    __ cmp(ip, r2);
2173    __ b(eq, &create_arguments);
2174    __ ldr(ip, ContextMemOperand(r4, Context::STRICT_ARGUMENTS_MAP_INDEX));
2175    __ cmp(ip, r2);
2176    __ b(eq, &create_arguments);
2177
2178    // Check if argumentsList is a fast JSArray.
2179    __ CompareInstanceType(r2, ip, JS_ARRAY_TYPE);
2180    __ b(eq, &create_array);
2181
2182    // Ask the runtime to create the list (actually a FixedArray).
2183    __ bind(&create_runtime);
2184    {
2185      FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
2186      __ Push(r1, r3, r0);
2187      __ CallRuntime(Runtime::kCreateListFromArrayLike);
2188      __ Pop(r1, r3);
2189      __ ldr(r2, FieldMemOperand(r0, FixedArray::kLengthOffset));
2190      __ SmiUntag(r2);
2191    }
2192    __ jmp(&done_create);
2193
2194    // Try to create the list from an arguments object.
2195    __ bind(&create_arguments);
2196    __ ldr(r2, FieldMemOperand(r0, JSArgumentsObject::kLengthOffset));
2197    __ ldr(r4, FieldMemOperand(r0, JSObject::kElementsOffset));
2198    __ ldr(ip, FieldMemOperand(r4, FixedArray::kLengthOffset));
2199    __ cmp(r2, ip);
2200    __ b(ne, &create_runtime);
2201    __ SmiUntag(r2);
2202    __ mov(r0, r4);
2203    __ b(&done_create);
2204
2205    // Try to create the list from a JSArray object.
2206    __ bind(&create_array);
2207    __ ldr(r2, FieldMemOperand(r2, Map::kBitField2Offset));
2208    __ DecodeField<Map::ElementsKindBits>(r2);
2209    STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
2210    STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
2211    STATIC_ASSERT(FAST_ELEMENTS == 2);
2212    __ cmp(r2, Operand(FAST_ELEMENTS));
2213    __ b(hi, &create_runtime);
2214    __ cmp(r2, Operand(FAST_HOLEY_SMI_ELEMENTS));
2215    __ b(eq, &create_runtime);
2216    __ ldr(r2, FieldMemOperand(r0, JSArray::kLengthOffset));
2217    __ ldr(r0, FieldMemOperand(r0, JSArray::kElementsOffset));
2218    __ SmiUntag(r2);
2219
2220    __ bind(&done_create);
2221  }
2222
2223  // Check for stack overflow.
2224  {
2225    // Check the stack for overflow. We are not trying to catch interruptions
2226    // (i.e. debug break and preemption) here, so check the "real stack limit".
2227    Label done;
2228    __ LoadRoot(ip, Heap::kRealStackLimitRootIndex);
2229    // Make ip the space we have left. The stack might already be overflowed
2230    // here which will cause ip to become negative.
2231    __ sub(ip, sp, ip);
2232    // Check if the arguments will overflow the stack.
2233    __ cmp(ip, Operand(r2, LSL, kPointerSizeLog2));
2234    __ b(gt, &done);  // Signed comparison.
2235    __ TailCallRuntime(Runtime::kThrowStackOverflow);
2236    __ bind(&done);
2237  }
2238
2239  // ----------- S t a t e -------------
2240  //  -- r1    : target
2241  //  -- r0    : args (a FixedArray built from argumentsList)
2242  //  -- r2    : len (number of elements to push from args)
2243  //  -- r3    : new.target (checked to be constructor or undefined)
2244  //  -- sp[0] : thisArgument
2245  // -----------------------------------
2246
2247  // Push arguments onto the stack (thisArgument is already on the stack).
2248  {
2249    __ mov(r4, Operand(0));
2250    Label done, loop;
2251    __ bind(&loop);
2252    __ cmp(r4, r2);
2253    __ b(eq, &done);
2254    __ add(ip, r0, Operand(r4, LSL, kPointerSizeLog2));
2255    __ ldr(ip, FieldMemOperand(ip, FixedArray::kHeaderSize));
2256    __ Push(ip);
2257    __ add(r4, r4, Operand(1));
2258    __ b(&loop);
2259    __ bind(&done);
2260    __ Move(r0, r4);
2261  }
2262
2263  // Dispatch to Call or Construct depending on whether new.target is undefined.
2264  {
2265    __ CompareRoot(r3, Heap::kUndefinedValueRootIndex);
2266    __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET, eq);
2267    __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
2268  }
2269}
2270
2271namespace {
2272
2273// Drops top JavaScript frame and an arguments adaptor frame below it (if
2274// present) preserving all the arguments prepared for current call.
2275// Does nothing if debugger is currently active.
2276// ES6 14.6.3. PrepareForTailCall
2277//
2278// Stack structure for the function g() tail calling f():
2279//
2280// ------- Caller frame: -------
2281// |  ...
2282// |  g()'s arg M
2283// |  ...
2284// |  g()'s arg 1
2285// |  g()'s receiver arg
2286// |  g()'s caller pc
2287// ------- g()'s frame: -------
2288// |  g()'s caller fp      <- fp
2289// |  g()'s context
2290// |  function pointer: g
2291// |  -------------------------
2292// |  ...
2293// |  ...
2294// |  f()'s arg N
2295// |  ...
2296// |  f()'s arg 1
2297// |  f()'s receiver arg   <- sp (f()'s caller pc is not on the stack yet!)
2298// ----------------------
2299//
2300void PrepareForTailCall(MacroAssembler* masm, Register args_reg,
2301                        Register scratch1, Register scratch2,
2302                        Register scratch3) {
2303  DCHECK(!AreAliased(args_reg, scratch1, scratch2, scratch3));
2304  Comment cmnt(masm, "[ PrepareForTailCall");
2305
2306  // Prepare for tail call only if ES2015 tail call elimination is enabled.
2307  Label done;
2308  ExternalReference is_tail_call_elimination_enabled =
2309      ExternalReference::is_tail_call_elimination_enabled_address(
2310          masm->isolate());
2311  __ mov(scratch1, Operand(is_tail_call_elimination_enabled));
2312  __ ldrb(scratch1, MemOperand(scratch1));
2313  __ cmp(scratch1, Operand(0));
2314  __ b(eq, &done);
2315
2316  // Drop possible interpreter handler/stub frame.
2317  {
2318    Label no_interpreter_frame;
2319    __ ldr(scratch3,
2320           MemOperand(fp, CommonFrameConstants::kContextOrFrameTypeOffset));
2321    __ cmp(scratch3, Operand(Smi::FromInt(StackFrame::STUB)));
2322    __ b(ne, &no_interpreter_frame);
2323    __ ldr(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
2324    __ bind(&no_interpreter_frame);
2325  }
2326
2327  // Check if next frame is an arguments adaptor frame.
2328  Register caller_args_count_reg = scratch1;
2329  Label no_arguments_adaptor, formal_parameter_count_loaded;
2330  __ ldr(scratch2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
2331  __ ldr(scratch3,
2332         MemOperand(scratch2, CommonFrameConstants::kContextOrFrameTypeOffset));
2333  __ cmp(scratch3, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
2334  __ b(ne, &no_arguments_adaptor);
2335
2336  // Drop current frame and load arguments count from arguments adaptor frame.
2337  __ mov(fp, scratch2);
2338  __ ldr(caller_args_count_reg,
2339         MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset));
2340  __ SmiUntag(caller_args_count_reg);
2341  __ b(&formal_parameter_count_loaded);
2342
2343  __ bind(&no_arguments_adaptor);
2344  // Load caller's formal parameter count
2345  __ ldr(scratch1,
2346         MemOperand(fp, ArgumentsAdaptorFrameConstants::kFunctionOffset));
2347  __ ldr(scratch1,
2348         FieldMemOperand(scratch1, JSFunction::kSharedFunctionInfoOffset));
2349  __ ldr(caller_args_count_reg,
2350         FieldMemOperand(scratch1,
2351                         SharedFunctionInfo::kFormalParameterCountOffset));
2352  __ SmiUntag(caller_args_count_reg);
2353
2354  __ bind(&formal_parameter_count_loaded);
2355
2356  ParameterCount callee_args_count(args_reg);
2357  __ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2,
2358                        scratch3);
2359  __ bind(&done);
2360}
2361}  // namespace
2362
2363// static
2364void Builtins::Generate_CallFunction(MacroAssembler* masm,
2365                                     ConvertReceiverMode mode,
2366                                     TailCallMode tail_call_mode) {
2367  // ----------- S t a t e -------------
2368  //  -- r0 : the number of arguments (not including the receiver)
2369  //  -- r1 : the function to call (checked to be a JSFunction)
2370  // -----------------------------------
2371  __ AssertFunction(r1);
2372
2373  // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList)
2374  // Check that the function is not a "classConstructor".
2375  Label class_constructor;
2376  __ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
2377  __ ldrb(r3, FieldMemOperand(r2, SharedFunctionInfo::kFunctionKindByteOffset));
2378  __ tst(r3, Operand(SharedFunctionInfo::kClassConstructorBitsWithinByte));
2379  __ b(ne, &class_constructor);
2380
2381  // Enter the context of the function; ToObject has to run in the function
2382  // context, and we also need to take the global proxy from the function
2383  // context in case of conversion.
2384  STATIC_ASSERT(SharedFunctionInfo::kNativeByteOffset ==
2385                SharedFunctionInfo::kStrictModeByteOffset);
2386  __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
2387  // We need to convert the receiver for non-native sloppy mode functions.
2388  Label done_convert;
2389  __ ldrb(r3, FieldMemOperand(r2, SharedFunctionInfo::kNativeByteOffset));
2390  __ tst(r3, Operand((1 << SharedFunctionInfo::kNativeBitWithinByte) |
2391                     (1 << SharedFunctionInfo::kStrictModeBitWithinByte)));
2392  __ b(ne, &done_convert);
2393  {
2394    // ----------- S t a t e -------------
2395    //  -- r0 : the number of arguments (not including the receiver)
2396    //  -- r1 : the function to call (checked to be a JSFunction)
2397    //  -- r2 : the shared function info.
2398    //  -- cp : the function context.
2399    // -----------------------------------
2400
2401    if (mode == ConvertReceiverMode::kNullOrUndefined) {
2402      // Patch receiver to global proxy.
2403      __ LoadGlobalProxy(r3);
2404    } else {
2405      Label convert_to_object, convert_receiver;
2406      __ ldr(r3, MemOperand(sp, r0, LSL, kPointerSizeLog2));
2407      __ JumpIfSmi(r3, &convert_to_object);
2408      STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
2409      __ CompareObjectType(r3, r4, r4, FIRST_JS_RECEIVER_TYPE);
2410      __ b(hs, &done_convert);
2411      if (mode != ConvertReceiverMode::kNotNullOrUndefined) {
2412        Label convert_global_proxy;
2413        __ JumpIfRoot(r3, Heap::kUndefinedValueRootIndex,
2414                      &convert_global_proxy);
2415        __ JumpIfNotRoot(r3, Heap::kNullValueRootIndex, &convert_to_object);
2416        __ bind(&convert_global_proxy);
2417        {
2418          // Patch receiver to global proxy.
2419          __ LoadGlobalProxy(r3);
2420        }
2421        __ b(&convert_receiver);
2422      }
2423      __ bind(&convert_to_object);
2424      {
2425        // Convert receiver using ToObject.
2426        // TODO(bmeurer): Inline the allocation here to avoid building the frame
2427        // in the fast case? (fall back to AllocateInNewSpace?)
2428        FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
2429        __ SmiTag(r0);
2430        __ Push(r0, r1);
2431        __ mov(r0, r3);
2432        __ Push(cp);
2433        __ Call(masm->isolate()->builtins()->ToObject(),
2434                RelocInfo::CODE_TARGET);
2435        __ Pop(cp);
2436        __ mov(r3, r0);
2437        __ Pop(r0, r1);
2438        __ SmiUntag(r0);
2439      }
2440      __ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
2441      __ bind(&convert_receiver);
2442    }
2443    __ str(r3, MemOperand(sp, r0, LSL, kPointerSizeLog2));
2444  }
2445  __ bind(&done_convert);
2446
2447  // ----------- S t a t e -------------
2448  //  -- r0 : the number of arguments (not including the receiver)
2449  //  -- r1 : the function to call (checked to be a JSFunction)
2450  //  -- r2 : the shared function info.
2451  //  -- cp : the function context.
2452  // -----------------------------------
2453
2454  if (tail_call_mode == TailCallMode::kAllow) {
2455    PrepareForTailCall(masm, r0, r3, r4, r5);
2456  }
2457
2458  __ ldr(r2,
2459         FieldMemOperand(r2, SharedFunctionInfo::kFormalParameterCountOffset));
2460  __ SmiUntag(r2);
2461  ParameterCount actual(r0);
2462  ParameterCount expected(r2);
2463  __ InvokeFunctionCode(r1, no_reg, expected, actual, JUMP_FUNCTION,
2464                        CheckDebugStepCallWrapper());
2465
2466  // The function is a "classConstructor", need to raise an exception.
2467  __ bind(&class_constructor);
2468  {
2469    FrameScope frame(masm, StackFrame::INTERNAL);
2470    __ push(r1);
2471    __ CallRuntime(Runtime::kThrowConstructorNonCallableError);
2472  }
2473}
2474
2475namespace {
2476
2477void Generate_PushBoundArguments(MacroAssembler* masm) {
2478  // ----------- S t a t e -------------
2479  //  -- r0 : the number of arguments (not including the receiver)
2480  //  -- r1 : target (checked to be a JSBoundFunction)
2481  //  -- r3 : new.target (only in case of [[Construct]])
2482  // -----------------------------------
2483
2484  // Load [[BoundArguments]] into r2 and length of that into r4.
2485  Label no_bound_arguments;
2486  __ ldr(r2, FieldMemOperand(r1, JSBoundFunction::kBoundArgumentsOffset));
2487  __ ldr(r4, FieldMemOperand(r2, FixedArray::kLengthOffset));
2488  __ SmiUntag(r4);
2489  __ cmp(r4, Operand(0));
2490  __ b(eq, &no_bound_arguments);
2491  {
2492    // ----------- S t a t e -------------
2493    //  -- r0 : the number of arguments (not including the receiver)
2494    //  -- r1 : target (checked to be a JSBoundFunction)
2495    //  -- r2 : the [[BoundArguments]] (implemented as FixedArray)
2496    //  -- r3 : new.target (only in case of [[Construct]])
2497    //  -- r4 : the number of [[BoundArguments]]
2498    // -----------------------------------
2499
2500    // Reserve stack space for the [[BoundArguments]].
2501    {
2502      Label done;
2503      __ sub(sp, sp, Operand(r4, LSL, kPointerSizeLog2));
2504      // Check the stack for overflow. We are not trying to catch interruptions
2505      // (i.e. debug break and preemption) here, so check the "real stack
2506      // limit".
2507      __ CompareRoot(sp, Heap::kRealStackLimitRootIndex);
2508      __ b(gt, &done);  // Signed comparison.
2509      // Restore the stack pointer.
2510      __ add(sp, sp, Operand(r4, LSL, kPointerSizeLog2));
2511      {
2512        FrameScope scope(masm, StackFrame::MANUAL);
2513        __ EnterFrame(StackFrame::INTERNAL);
2514        __ CallRuntime(Runtime::kThrowStackOverflow);
2515      }
2516      __ bind(&done);
2517    }
2518
2519    // Relocate arguments down the stack.
2520    {
2521      Label loop, done_loop;
2522      __ mov(r5, Operand(0));
2523      __ bind(&loop);
2524      __ cmp(r5, r0);
2525      __ b(gt, &done_loop);
2526      __ ldr(ip, MemOperand(sp, r4, LSL, kPointerSizeLog2));
2527      __ str(ip, MemOperand(sp, r5, LSL, kPointerSizeLog2));
2528      __ add(r4, r4, Operand(1));
2529      __ add(r5, r5, Operand(1));
2530      __ b(&loop);
2531      __ bind(&done_loop);
2532    }
2533
2534    // Copy [[BoundArguments]] to the stack (below the arguments).
2535    {
2536      Label loop;
2537      __ ldr(r4, FieldMemOperand(r2, FixedArray::kLengthOffset));
2538      __ SmiUntag(r4);
2539      __ add(r2, r2, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
2540      __ bind(&loop);
2541      __ sub(r4, r4, Operand(1), SetCC);
2542      __ ldr(ip, MemOperand(r2, r4, LSL, kPointerSizeLog2));
2543      __ str(ip, MemOperand(sp, r0, LSL, kPointerSizeLog2));
2544      __ add(r0, r0, Operand(1));
2545      __ b(gt, &loop);
2546    }
2547  }
2548  __ bind(&no_bound_arguments);
2549}
2550
2551}  // namespace
2552
2553// static
2554void Builtins::Generate_CallBoundFunctionImpl(MacroAssembler* masm,
2555                                              TailCallMode tail_call_mode) {
2556  // ----------- S t a t e -------------
2557  //  -- r0 : the number of arguments (not including the receiver)
2558  //  -- r1 : the function to call (checked to be a JSBoundFunction)
2559  // -----------------------------------
2560  __ AssertBoundFunction(r1);
2561
2562  if (tail_call_mode == TailCallMode::kAllow) {
2563    PrepareForTailCall(masm, r0, r3, r4, r5);
2564  }
2565
2566  // Patch the receiver to [[BoundThis]].
2567  __ ldr(ip, FieldMemOperand(r1, JSBoundFunction::kBoundThisOffset));
2568  __ str(ip, MemOperand(sp, r0, LSL, kPointerSizeLog2));
2569
2570  // Push the [[BoundArguments]] onto the stack.
2571  Generate_PushBoundArguments(masm);
2572
2573  // Call the [[BoundTargetFunction]] via the Call builtin.
2574  __ ldr(r1, FieldMemOperand(r1, JSBoundFunction::kBoundTargetFunctionOffset));
2575  __ mov(ip, Operand(ExternalReference(Builtins::kCall_ReceiverIsAny,
2576                                       masm->isolate())));
2577  __ ldr(ip, MemOperand(ip));
2578  __ add(pc, ip, Operand(Code::kHeaderSize - kHeapObjectTag));
2579}
2580
2581// static
2582void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode,
2583                             TailCallMode tail_call_mode) {
2584  // ----------- S t a t e -------------
2585  //  -- r0 : the number of arguments (not including the receiver)
2586  //  -- r1 : the target to call (can be any Object).
2587  // -----------------------------------
2588
2589  Label non_callable, non_function, non_smi;
2590  __ JumpIfSmi(r1, &non_callable);
2591  __ bind(&non_smi);
2592  __ CompareObjectType(r1, r4, r5, JS_FUNCTION_TYPE);
2593  __ Jump(masm->isolate()->builtins()->CallFunction(mode, tail_call_mode),
2594          RelocInfo::CODE_TARGET, eq);
2595  __ cmp(r5, Operand(JS_BOUND_FUNCTION_TYPE));
2596  __ Jump(masm->isolate()->builtins()->CallBoundFunction(tail_call_mode),
2597          RelocInfo::CODE_TARGET, eq);
2598
2599  // Check if target has a [[Call]] internal method.
2600  __ ldrb(r4, FieldMemOperand(r4, Map::kBitFieldOffset));
2601  __ tst(r4, Operand(1 << Map::kIsCallable));
2602  __ b(eq, &non_callable);
2603
2604  __ cmp(r5, Operand(JS_PROXY_TYPE));
2605  __ b(ne, &non_function);
2606
2607  // 0. Prepare for tail call if necessary.
2608  if (tail_call_mode == TailCallMode::kAllow) {
2609    PrepareForTailCall(masm, r0, r3, r4, r5);
2610  }
2611
2612  // 1. Runtime fallback for Proxy [[Call]].
2613  __ Push(r1);
2614  // Increase the arguments size to include the pushed function and the
2615  // existing receiver on the stack.
2616  __ add(r0, r0, Operand(2));
2617  // Tail-call to the runtime.
2618  __ JumpToExternalReference(
2619      ExternalReference(Runtime::kJSProxyCall, masm->isolate()));
2620
2621  // 2. Call to something else, which might have a [[Call]] internal method (if
2622  // not we raise an exception).
2623  __ bind(&non_function);
2624  // Overwrite the original receiver the (original) target.
2625  __ str(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2));
2626  // Let the "call_as_function_delegate" take care of the rest.
2627  __ LoadNativeContextSlot(Context::CALL_AS_FUNCTION_DELEGATE_INDEX, r1);
2628  __ Jump(masm->isolate()->builtins()->CallFunction(
2629              ConvertReceiverMode::kNotNullOrUndefined, tail_call_mode),
2630          RelocInfo::CODE_TARGET);
2631
2632  // 3. Call to something that is not callable.
2633  __ bind(&non_callable);
2634  {
2635    FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
2636    __ Push(r1);
2637    __ CallRuntime(Runtime::kThrowCalledNonCallable);
2638  }
2639}
2640
2641// static
2642void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
2643  // ----------- S t a t e -------------
2644  //  -- r0 : the number of arguments (not including the receiver)
2645  //  -- r1 : the constructor to call (checked to be a JSFunction)
2646  //  -- r3 : the new target (checked to be a constructor)
2647  // -----------------------------------
2648  __ AssertFunction(r1);
2649
2650  // Calling convention for function specific ConstructStubs require
2651  // r2 to contain either an AllocationSite or undefined.
2652  __ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
2653
2654  // Tail call to the function-specific construct stub (still in the caller
2655  // context at this point).
2656  __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
2657  __ ldr(r4, FieldMemOperand(r4, SharedFunctionInfo::kConstructStubOffset));
2658  __ add(pc, r4, Operand(Code::kHeaderSize - kHeapObjectTag));
2659}
2660
2661// static
2662void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) {
2663  // ----------- S t a t e -------------
2664  //  -- r0 : the number of arguments (not including the receiver)
2665  //  -- r1 : the function to call (checked to be a JSBoundFunction)
2666  //  -- r3 : the new target (checked to be a constructor)
2667  // -----------------------------------
2668  __ AssertBoundFunction(r1);
2669
2670  // Push the [[BoundArguments]] onto the stack.
2671  Generate_PushBoundArguments(masm);
2672
2673  // Patch new.target to [[BoundTargetFunction]] if new.target equals target.
2674  __ cmp(r1, r3);
2675  __ ldr(r3, FieldMemOperand(r1, JSBoundFunction::kBoundTargetFunctionOffset),
2676         eq);
2677
2678  // Construct the [[BoundTargetFunction]] via the Construct builtin.
2679  __ ldr(r1, FieldMemOperand(r1, JSBoundFunction::kBoundTargetFunctionOffset));
2680  __ mov(ip, Operand(ExternalReference(Builtins::kConstruct, masm->isolate())));
2681  __ ldr(ip, MemOperand(ip));
2682  __ add(pc, ip, Operand(Code::kHeaderSize - kHeapObjectTag));
2683}
2684
2685// static
2686void Builtins::Generate_ConstructProxy(MacroAssembler* masm) {
2687  // ----------- S t a t e -------------
2688  //  -- r0 : the number of arguments (not including the receiver)
2689  //  -- r1 : the constructor to call (checked to be a JSProxy)
2690  //  -- r3 : the new target (either the same as the constructor or
2691  //          the JSFunction on which new was invoked initially)
2692  // -----------------------------------
2693
2694  // Call into the Runtime for Proxy [[Construct]].
2695  __ Push(r1);
2696  __ Push(r3);
2697  // Include the pushed new_target, constructor and the receiver.
2698  __ add(r0, r0, Operand(3));
2699  // Tail-call to the runtime.
2700  __ JumpToExternalReference(
2701      ExternalReference(Runtime::kJSProxyConstruct, masm->isolate()));
2702}
2703
2704// static
2705void Builtins::Generate_Construct(MacroAssembler* masm) {
2706  // ----------- S t a t e -------------
2707  //  -- r0 : the number of arguments (not including the receiver)
2708  //  -- r1 : the constructor to call (can be any Object)
2709  //  -- r3 : the new target (either the same as the constructor or
2710  //          the JSFunction on which new was invoked initially)
2711  // -----------------------------------
2712
2713  // Check if target is a Smi.
2714  Label non_constructor;
2715  __ JumpIfSmi(r1, &non_constructor);
2716
2717  // Dispatch based on instance type.
2718  __ CompareObjectType(r1, r4, r5, JS_FUNCTION_TYPE);
2719  __ Jump(masm->isolate()->builtins()->ConstructFunction(),
2720          RelocInfo::CODE_TARGET, eq);
2721
2722  // Check if target has a [[Construct]] internal method.
2723  __ ldrb(r2, FieldMemOperand(r4, Map::kBitFieldOffset));
2724  __ tst(r2, Operand(1 << Map::kIsConstructor));
2725  __ b(eq, &non_constructor);
2726
2727  // Only dispatch to bound functions after checking whether they are
2728  // constructors.
2729  __ cmp(r5, Operand(JS_BOUND_FUNCTION_TYPE));
2730  __ Jump(masm->isolate()->builtins()->ConstructBoundFunction(),
2731          RelocInfo::CODE_TARGET, eq);
2732
2733  // Only dispatch to proxies after checking whether they are constructors.
2734  __ cmp(r5, Operand(JS_PROXY_TYPE));
2735  __ Jump(masm->isolate()->builtins()->ConstructProxy(), RelocInfo::CODE_TARGET,
2736          eq);
2737
2738  // Called Construct on an exotic Object with a [[Construct]] internal method.
2739  {
2740    // Overwrite the original receiver with the (original) target.
2741    __ str(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2));
2742    // Let the "call_as_constructor_delegate" take care of the rest.
2743    __ LoadNativeContextSlot(Context::CALL_AS_CONSTRUCTOR_DELEGATE_INDEX, r1);
2744    __ Jump(masm->isolate()->builtins()->CallFunction(),
2745            RelocInfo::CODE_TARGET);
2746  }
2747
2748  // Called Construct on an Object that doesn't have a [[Construct]] internal
2749  // method.
2750  __ bind(&non_constructor);
2751  __ Jump(masm->isolate()->builtins()->ConstructedNonConstructable(),
2752          RelocInfo::CODE_TARGET);
2753}
2754
2755// static
2756void Builtins::Generate_AllocateInNewSpace(MacroAssembler* masm) {
2757  // ----------- S t a t e -------------
2758  //  -- r1 : requested object size (untagged)
2759  //  -- lr : return address
2760  // -----------------------------------
2761  __ SmiTag(r1);
2762  __ Push(r1);
2763  __ Move(cp, Smi::kZero);
2764  __ TailCallRuntime(Runtime::kAllocateInNewSpace);
2765}
2766
2767// static
2768void Builtins::Generate_AllocateInOldSpace(MacroAssembler* masm) {
2769  // ----------- S t a t e -------------
2770  //  -- r1 : requested object size (untagged)
2771  //  -- lr : return address
2772  // -----------------------------------
2773  __ SmiTag(r1);
2774  __ Move(r2, Smi::FromInt(AllocateTargetSpace::encode(OLD_SPACE)));
2775  __ Push(r1, r2);
2776  __ Move(cp, Smi::kZero);
2777  __ TailCallRuntime(Runtime::kAllocateInTargetSpace);
2778}
2779
2780// static
2781void Builtins::Generate_Abort(MacroAssembler* masm) {
2782  // ----------- S t a t e -------------
2783  //  -- r1 : message_id as Smi
2784  //  -- lr : return address
2785  // -----------------------------------
2786  __ Push(r1);
2787  __ Move(cp, Smi::kZero);
2788  __ TailCallRuntime(Runtime::kAbort);
2789}
2790
2791void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
2792  // ----------- S t a t e -------------
2793  //  -- r0 : actual number of arguments
2794  //  -- r1 : function (passed through to callee)
2795  //  -- r2 : expected number of arguments
2796  //  -- r3 : new target (passed through to callee)
2797  // -----------------------------------
2798
2799  Label invoke, dont_adapt_arguments, stack_overflow;
2800
2801  Label enough, too_few;
2802  __ cmp(r0, r2);
2803  __ b(lt, &too_few);
2804  __ cmp(r2, Operand(SharedFunctionInfo::kDontAdaptArgumentsSentinel));
2805  __ b(eq, &dont_adapt_arguments);
2806
2807  {  // Enough parameters: actual >= expected
2808    __ bind(&enough);
2809    EnterArgumentsAdaptorFrame(masm);
2810    Generate_StackOverflowCheck(masm, r2, r5, &stack_overflow);
2811
2812    // Calculate copy start address into r0 and copy end address into r4.
2813    // r0: actual number of arguments as a smi
2814    // r1: function
2815    // r2: expected number of arguments
2816    // r3: new target (passed through to callee)
2817    __ add(r0, fp, Operand::PointerOffsetFromSmiKey(r0));
2818    // adjust for return address and receiver
2819    __ add(r0, r0, Operand(2 * kPointerSize));
2820    __ sub(r4, r0, Operand(r2, LSL, kPointerSizeLog2));
2821
2822    // Copy the arguments (including the receiver) to the new stack frame.
2823    // r0: copy start address
2824    // r1: function
2825    // r2: expected number of arguments
2826    // r3: new target (passed through to callee)
2827    // r4: copy end address
2828
2829    Label copy;
2830    __ bind(&copy);
2831    __ ldr(ip, MemOperand(r0, 0));
2832    __ push(ip);
2833    __ cmp(r0, r4);  // Compare before moving to next argument.
2834    __ sub(r0, r0, Operand(kPointerSize));
2835    __ b(ne, &copy);
2836
2837    __ b(&invoke);
2838  }
2839
2840  {  // Too few parameters: Actual < expected
2841    __ bind(&too_few);
2842    EnterArgumentsAdaptorFrame(masm);
2843    Generate_StackOverflowCheck(masm, r2, r5, &stack_overflow);
2844
2845    // Calculate copy start address into r0 and copy end address is fp.
2846    // r0: actual number of arguments as a smi
2847    // r1: function
2848    // r2: expected number of arguments
2849    // r3: new target (passed through to callee)
2850    __ add(r0, fp, Operand::PointerOffsetFromSmiKey(r0));
2851
2852    // Copy the arguments (including the receiver) to the new stack frame.
2853    // r0: copy start address
2854    // r1: function
2855    // r2: expected number of arguments
2856    // r3: new target (passed through to callee)
2857    Label copy;
2858    __ bind(&copy);
2859    // Adjust load for return address and receiver.
2860    __ ldr(ip, MemOperand(r0, 2 * kPointerSize));
2861    __ push(ip);
2862    __ cmp(r0, fp);  // Compare before moving to next argument.
2863    __ sub(r0, r0, Operand(kPointerSize));
2864    __ b(ne, &copy);
2865
2866    // Fill the remaining expected arguments with undefined.
2867    // r1: function
2868    // r2: expected number of arguments
2869    // r3: new target (passed through to callee)
2870    __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
2871    __ sub(r4, fp, Operand(r2, LSL, kPointerSizeLog2));
2872    // Adjust for frame.
2873    __ sub(r4, r4, Operand(StandardFrameConstants::kFixedFrameSizeFromFp +
2874                           2 * kPointerSize));
2875
2876    Label fill;
2877    __ bind(&fill);
2878    __ push(ip);
2879    __ cmp(sp, r4);
2880    __ b(ne, &fill);
2881  }
2882
2883  // Call the entry point.
2884  __ bind(&invoke);
2885  __ mov(r0, r2);
2886  // r0 : expected number of arguments
2887  // r1 : function (passed through to callee)
2888  // r3 : new target (passed through to callee)
2889  __ ldr(r4, FieldMemOperand(r1, JSFunction::kCodeEntryOffset));
2890  __ Call(r4);
2891
2892  // Store offset of return address for deoptimizer.
2893  masm->isolate()->heap()->SetArgumentsAdaptorDeoptPCOffset(masm->pc_offset());
2894
2895  // Exit frame and return.
2896  LeaveArgumentsAdaptorFrame(masm);
2897  __ Jump(lr);
2898
2899  // -------------------------------------------
2900  // Dont adapt arguments.
2901  // -------------------------------------------
2902  __ bind(&dont_adapt_arguments);
2903  __ ldr(r4, FieldMemOperand(r1, JSFunction::kCodeEntryOffset));
2904  __ Jump(r4);
2905
2906  __ bind(&stack_overflow);
2907  {
2908    FrameScope frame(masm, StackFrame::MANUAL);
2909    __ CallRuntime(Runtime::kThrowStackOverflow);
2910    __ bkpt(0);
2911  }
2912}
2913
2914#undef __
2915
2916}  // namespace internal
2917}  // namespace v8
2918
2919#endif  // V8_TARGET_ARCH_ARM
2920