deps: update v8 to 4.3.61.21
[platform/upstream/nodejs.git] / deps / v8 / src / arm64 / builtins-arm64.cc
1 // Copyright 2013 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 #include "src/v8.h"
6
7 #if V8_TARGET_ARCH_ARM64
8
9 #include "src/codegen.h"
10 #include "src/debug.h"
11 #include "src/deoptimizer.h"
12 #include "src/full-codegen.h"
13 #include "src/runtime/runtime.h"
14
15 namespace v8 {
16 namespace internal {
17
18
19 #define __ ACCESS_MASM(masm)
20
21
22 // Load the built-in Array function from the current context.
23 static void GenerateLoadArrayFunction(MacroAssembler* masm, Register result) {
24   // Load the native context.
25   __ Ldr(result, GlobalObjectMemOperand());
26   __ Ldr(result,
27          FieldMemOperand(result, GlobalObject::kNativeContextOffset));
28   // Load the InternalArray function from the native context.
29   __ Ldr(result,
30          MemOperand(result,
31                     Context::SlotOffset(Context::ARRAY_FUNCTION_INDEX)));
32 }
33
34
35 // Load the built-in InternalArray function from the current context.
36 static void GenerateLoadInternalArrayFunction(MacroAssembler* masm,
37                                               Register result) {
38   // Load the native context.
39   __ Ldr(result, GlobalObjectMemOperand());
40   __ Ldr(result,
41          FieldMemOperand(result, GlobalObject::kNativeContextOffset));
42   // Load the InternalArray function from the native context.
43   __ Ldr(result, ContextMemOperand(result,
44                                    Context::INTERNAL_ARRAY_FUNCTION_INDEX));
45 }
46
47
48 void Builtins::Generate_Adaptor(MacroAssembler* masm,
49                                 CFunctionId id,
50                                 BuiltinExtraArguments extra_args) {
51   // ----------- S t a t e -------------
52   //  -- x0                 : number of arguments excluding receiver
53   //  -- x1                 : called function (only guaranteed when
54   //                          extra_args requires it)
55   //  -- cp                 : context
56   //  -- sp[0]              : last argument
57   //  -- ...
58   //  -- sp[4 * (argc - 1)] : first argument (argc == x0)
59   //  -- sp[4 * argc]       : receiver
60   // -----------------------------------
61
62   // Insert extra arguments.
63   int num_extra_args = 0;
64   if (extra_args == NEEDS_CALLED_FUNCTION) {
65     num_extra_args = 1;
66     __ Push(x1);
67   } else {
68     DCHECK(extra_args == NO_EXTRA_ARGUMENTS);
69   }
70
71   // JumpToExternalReference expects x0 to contain the number of arguments
72   // including the receiver and the extra arguments.
73   __ Add(x0, x0, num_extra_args + 1);
74   __ JumpToExternalReference(ExternalReference(id, masm->isolate()));
75 }
76
77
78 void Builtins::Generate_InternalArrayCode(MacroAssembler* masm) {
79   // ----------- S t a t e -------------
80   //  -- x0     : number of arguments
81   //  -- lr     : return address
82   //  -- sp[...]: constructor arguments
83   // -----------------------------------
84   ASM_LOCATION("Builtins::Generate_InternalArrayCode");
85   Label generic_array_code;
86
87   // Get the InternalArray function.
88   GenerateLoadInternalArrayFunction(masm, x1);
89
90   if (FLAG_debug_code) {
91     // Initial map for the builtin InternalArray functions should be maps.
92     __ Ldr(x10, FieldMemOperand(x1, JSFunction::kPrototypeOrInitialMapOffset));
93     __ Tst(x10, kSmiTagMask);
94     __ Assert(ne, kUnexpectedInitialMapForInternalArrayFunction);
95     __ CompareObjectType(x10, x11, x12, MAP_TYPE);
96     __ Assert(eq, kUnexpectedInitialMapForInternalArrayFunction);
97   }
98
99   // Run the native code for the InternalArray function called as a normal
100   // function.
101   InternalArrayConstructorStub stub(masm->isolate());
102   __ TailCallStub(&stub);
103 }
104
105
106 void Builtins::Generate_ArrayCode(MacroAssembler* masm) {
107   // ----------- S t a t e -------------
108   //  -- x0     : number of arguments
109   //  -- lr     : return address
110   //  -- sp[...]: constructor arguments
111   // -----------------------------------
112   ASM_LOCATION("Builtins::Generate_ArrayCode");
113   Label generic_array_code, one_or_more_arguments, two_or_more_arguments;
114
115   // Get the Array function.
116   GenerateLoadArrayFunction(masm, x1);
117
118   if (FLAG_debug_code) {
119     // Initial map for the builtin Array functions should be maps.
120     __ Ldr(x10, FieldMemOperand(x1, JSFunction::kPrototypeOrInitialMapOffset));
121     __ Tst(x10, kSmiTagMask);
122     __ Assert(ne, kUnexpectedInitialMapForArrayFunction);
123     __ CompareObjectType(x10, x11, x12, MAP_TYPE);
124     __ Assert(eq, kUnexpectedInitialMapForArrayFunction);
125   }
126
127   // Run the native code for the Array function called as a normal function.
128   __ LoadRoot(x2, Heap::kUndefinedValueRootIndex);
129   __ Mov(x3, x1);
130   ArrayConstructorStub stub(masm->isolate());
131   __ TailCallStub(&stub);
132 }
133
134
135 void Builtins::Generate_StringConstructCode(MacroAssembler* masm) {
136   // ----------- S t a t e -------------
137   //  -- x0                     : number of arguments
138   //  -- x1                     : constructor function
139   //  -- lr                     : return address
140   //  -- sp[(argc - n - 1) * 8] : arg[n] (zero based)
141   //  -- sp[argc * 8]           : receiver
142   // -----------------------------------
143   ASM_LOCATION("Builtins::Generate_StringConstructCode");
144   Counters* counters = masm->isolate()->counters();
145   __ IncrementCounter(counters->string_ctor_calls(), 1, x10, x11);
146
147   Register argc = x0;
148   Register function = x1;
149   if (FLAG_debug_code) {
150     __ LoadGlobalFunction(Context::STRING_FUNCTION_INDEX, x10);
151     __ Cmp(function, x10);
152     __ Assert(eq, kUnexpectedStringFunction);
153   }
154
155   // Load the first arguments in x0 and get rid of the rest.
156   Label no_arguments;
157   __ Cbz(argc, &no_arguments);
158   // First args = sp[(argc - 1) * 8].
159   __ Sub(argc, argc, 1);
160   __ Drop(argc, kXRegSize);
161   // jssp now point to args[0], load and drop args[0] + receiver.
162   Register arg = argc;
163   __ Ldr(arg, MemOperand(jssp, 2 * kPointerSize, PostIndex));
164   argc = NoReg;
165
166   Register argument = x2;
167   Label not_cached, argument_is_string;
168   __ LookupNumberStringCache(arg,        // Input.
169                              argument,   // Result.
170                              x10,        // Scratch.
171                              x11,        // Scratch.
172                              x12,        // Scratch.
173                              &not_cached);
174   __ IncrementCounter(counters->string_ctor_cached_number(), 1, x10, x11);
175   __ Bind(&argument_is_string);
176
177   // ----------- S t a t e -------------
178   //  -- x2     : argument converted to string
179   //  -- x1     : constructor function
180   //  -- lr     : return address
181   // -----------------------------------
182
183   Label gc_required;
184   Register new_obj = x0;
185   __ Allocate(JSValue::kSize, new_obj, x10, x11, &gc_required, TAG_OBJECT);
186
187   // Initialize the String object.
188   Register map = x3;
189   __ LoadGlobalFunctionInitialMap(function, map, x10);
190   if (FLAG_debug_code) {
191     __ Ldrb(x4, FieldMemOperand(map, Map::kInstanceSizeOffset));
192     __ Cmp(x4, JSValue::kSize >> kPointerSizeLog2);
193     __ Assert(eq, kUnexpectedStringWrapperInstanceSize);
194     __ Ldrb(x4, FieldMemOperand(map, Map::kUnusedPropertyFieldsOffset));
195     __ Cmp(x4, 0);
196     __ Assert(eq, kUnexpectedUnusedPropertiesOfStringWrapper);
197   }
198   __ Str(map, FieldMemOperand(new_obj, HeapObject::kMapOffset));
199
200   Register empty = x3;
201   __ LoadRoot(empty, Heap::kEmptyFixedArrayRootIndex);
202   __ Str(empty, FieldMemOperand(new_obj, JSObject::kPropertiesOffset));
203   __ Str(empty, FieldMemOperand(new_obj, JSObject::kElementsOffset));
204
205   __ Str(argument, FieldMemOperand(new_obj, JSValue::kValueOffset));
206
207   // Ensure the object is fully initialized.
208   STATIC_ASSERT(JSValue::kSize == (4 * kPointerSize));
209
210   __ Ret();
211
212   // The argument was not found in the number to string cache. Check
213   // if it's a string already before calling the conversion builtin.
214   Label convert_argument;
215   __ Bind(&not_cached);
216   __ JumpIfSmi(arg, &convert_argument);
217
218   // Is it a String?
219   __ Ldr(x10, FieldMemOperand(x0, HeapObject::kMapOffset));
220   __ Ldrb(x11, FieldMemOperand(x10, Map::kInstanceTypeOffset));
221   __ Tbnz(x11, MaskToBit(kIsNotStringMask), &convert_argument);
222   __ Mov(argument, arg);
223   __ IncrementCounter(counters->string_ctor_string_value(), 1, x10, x11);
224   __ B(&argument_is_string);
225
226   // Invoke the conversion builtin and put the result into x2.
227   __ Bind(&convert_argument);
228   __ Push(function);  // Preserve the function.
229   __ IncrementCounter(counters->string_ctor_conversions(), 1, x10, x11);
230   {
231     FrameScope scope(masm, StackFrame::INTERNAL);
232     __ Push(arg);
233     __ InvokeBuiltin(Builtins::TO_STRING, CALL_FUNCTION);
234   }
235   __ Pop(function);
236   __ Mov(argument, x0);
237   __ B(&argument_is_string);
238
239   // Load the empty string into x2, remove the receiver from the
240   // stack, and jump back to the case where the argument is a string.
241   __ Bind(&no_arguments);
242   __ LoadRoot(argument, Heap::kempty_stringRootIndex);
243   __ Drop(1);
244   __ B(&argument_is_string);
245
246   // At this point the argument is already a string. Call runtime to create a
247   // string wrapper.
248   __ Bind(&gc_required);
249   __ IncrementCounter(counters->string_ctor_gc_required(), 1, x10, x11);
250   {
251     FrameScope scope(masm, StackFrame::INTERNAL);
252     __ Push(argument);
253     __ CallRuntime(Runtime::kNewStringWrapper, 1);
254   }
255   __ Ret();
256 }
257
258
259 static void CallRuntimePassFunction(MacroAssembler* masm,
260                                     Runtime::FunctionId function_id) {
261   FrameScope scope(masm, StackFrame::INTERNAL);
262   //   - Push a copy of the function onto the stack.
263   //   - Push another copy as a parameter to the runtime call.
264   __ Push(x1, x1);
265
266   __ CallRuntime(function_id, 1);
267
268   //   - Restore receiver.
269   __ Pop(x1);
270 }
271
272
273 static void GenerateTailCallToSharedCode(MacroAssembler* masm) {
274   __ Ldr(x2, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset));
275   __ Ldr(x2, FieldMemOperand(x2, SharedFunctionInfo::kCodeOffset));
276   __ Add(x2, x2, Code::kHeaderSize - kHeapObjectTag);
277   __ Br(x2);
278 }
279
280
281 static void GenerateTailCallToReturnedCode(MacroAssembler* masm) {
282   __ Add(x0, x0, Code::kHeaderSize - kHeapObjectTag);
283   __ Br(x0);
284 }
285
286
287 void Builtins::Generate_InOptimizationQueue(MacroAssembler* masm) {
288   // Checking whether the queued function is ready for install is optional,
289   // since we come across interrupts and stack checks elsewhere. However, not
290   // checking may delay installing ready functions, and always checking would be
291   // quite expensive. A good compromise is to first check against stack limit as
292   // a cue for an interrupt signal.
293   Label ok;
294   __ CompareRoot(masm->StackPointer(), Heap::kStackLimitRootIndex);
295   __ B(hs, &ok);
296
297   CallRuntimePassFunction(masm, Runtime::kTryInstallOptimizedCode);
298   GenerateTailCallToReturnedCode(masm);
299
300   __ Bind(&ok);
301   GenerateTailCallToSharedCode(masm);
302 }
303
304
305 static void Generate_Runtime_NewObject(MacroAssembler* masm,
306                                        bool create_memento,
307                                        Register original_constructor,
308                                        Label* count_incremented,
309                                        Label* allocated) {
310   if (create_memento) {
311     // Get the cell or allocation site.
312     __ Peek(x4, 2 * kXRegSize);
313     __ Push(x4);
314     __ Push(x1);  // Argument for Runtime_NewObject.
315     __ Push(original_constructor);
316     __ CallRuntime(Runtime::kNewObjectWithAllocationSite, 3);
317     __ Mov(x4, x0);
318     // If we ended up using the runtime, and we want a memento, then the
319     // runtime call made it for us, and we shouldn't do create count
320     // increment.
321     __ jmp(count_incremented);
322   } else {
323     __ Push(x1);  // Argument for Runtime_NewObject.
324     __ Push(original_constructor);
325     __ CallRuntime(Runtime::kNewObject, 2);
326     __ Mov(x4, x0);
327     __ jmp(allocated);
328   }
329 }
330
331
332 static void Generate_JSConstructStubHelper(MacroAssembler* masm,
333                                            bool is_api_function,
334                                            bool create_memento) {
335   // ----------- S t a t e -------------
336   //  -- x0     : number of arguments
337   //  -- x1     : constructor function
338   //  -- x2     : allocation site or undefined
339   //  -- x3    : original constructor
340   //  -- lr     : return address
341   //  -- sp[...]: constructor arguments
342   // -----------------------------------
343
344   ASM_LOCATION("Builtins::Generate_JSConstructStubHelper");
345   // Should never create mementos for api functions.
346   DCHECK(!is_api_function || !create_memento);
347
348   Isolate* isolate = masm->isolate();
349
350   // Enter a construct frame.
351   {
352     FrameScope scope(masm, StackFrame::CONSTRUCT);
353
354     // Preserve the three incoming parameters on the stack.
355     if (create_memento) {
356       __ AssertUndefinedOrAllocationSite(x2, x10);
357       __ Push(x2);
358     }
359
360     Register argc = x0;
361     Register constructor = x1;
362     Register original_constructor = x3;
363     // x1: constructor function
364     __ SmiTag(argc);
365     __ Push(argc, constructor);
366     // sp[0] : Constructor function.
367     // sp[1]: number of arguments (smi-tagged)
368
369     Label rt_call, count_incremented, allocated, normal_new;
370     __ Cmp(constructor, original_constructor);
371     __ B(eq, &normal_new);
372     Generate_Runtime_NewObject(masm, create_memento, original_constructor,
373                                &count_incremented, &allocated);
374
375     __ Bind(&normal_new);
376
377     // Try to allocate the object without transitioning into C code. If any of
378     // the preconditions is not met, the code bails out to the runtime call.
379     if (FLAG_inline_new) {
380       Label undo_allocation;
381       ExternalReference debug_step_in_fp =
382           ExternalReference::debug_step_in_fp_address(isolate);
383       __ Mov(x2, Operand(debug_step_in_fp));
384       __ Ldr(x2, MemOperand(x2));
385       __ Cbnz(x2, &rt_call);
386       // Load the initial map and verify that it is in fact a map.
387       Register init_map = x2;
388       __ Ldr(init_map,
389              FieldMemOperand(constructor,
390                              JSFunction::kPrototypeOrInitialMapOffset));
391       __ JumpIfSmi(init_map, &rt_call);
392       __ JumpIfNotObjectType(init_map, x10, x11, MAP_TYPE, &rt_call);
393
394       // Check that the constructor is not constructing a JSFunction (see
395       // comments in Runtime_NewObject in runtime.cc). In which case the initial
396       // map's instance type would be JS_FUNCTION_TYPE.
397       __ CompareInstanceType(init_map, x10, JS_FUNCTION_TYPE);
398       __ B(eq, &rt_call);
399
400       Register constructon_count = x14;
401       if (!is_api_function) {
402         Label allocate;
403         MemOperand bit_field3 =
404             FieldMemOperand(init_map, Map::kBitField3Offset);
405         // Check if slack tracking is enabled.
406         __ Ldr(x4, bit_field3);
407         __ DecodeField<Map::Counter>(constructon_count, x4);
408         __ Cmp(constructon_count, Operand(Map::kSlackTrackingCounterEnd));
409         __ B(lt, &allocate);
410         // Decrease generous allocation count.
411         __ Subs(x4, x4, Operand(1 << Map::Counter::kShift));
412         __ Str(x4, bit_field3);
413         __ Cmp(constructon_count, Operand(Map::kSlackTrackingCounterEnd));
414         __ B(ne, &allocate);
415
416         // Push the constructor and map to the stack, and the constructor again
417         // as argument to the runtime call.
418         __ Push(constructor, init_map, constructor);
419         __ CallRuntime(Runtime::kFinalizeInstanceSize, 1);
420         __ Pop(init_map, constructor);
421         __ Mov(constructon_count, Operand(Map::kSlackTrackingCounterEnd - 1));
422         __ Bind(&allocate);
423       }
424
425       // Now allocate the JSObject on the heap.
426       Register obj_size = x3;
427       Register new_obj = x4;
428       __ Ldrb(obj_size, FieldMemOperand(init_map, Map::kInstanceSizeOffset));
429       if (create_memento) {
430         __ Add(x7, obj_size,
431                Operand(AllocationMemento::kSize / kPointerSize));
432         __ Allocate(x7, new_obj, x10, x11, &rt_call, SIZE_IN_WORDS);
433       } else {
434         __ Allocate(obj_size, new_obj, x10, x11, &rt_call, SIZE_IN_WORDS);
435       }
436
437       // Allocated the JSObject, now initialize the fields. Map is set to
438       // initial map and properties and elements are set to empty fixed array.
439       // NB. the object pointer is not tagged, so MemOperand is used.
440       Register empty = x5;
441       __ LoadRoot(empty, Heap::kEmptyFixedArrayRootIndex);
442       __ Str(init_map, MemOperand(new_obj, JSObject::kMapOffset));
443       STATIC_ASSERT(JSObject::kElementsOffset ==
444           (JSObject::kPropertiesOffset + kPointerSize));
445       __ Stp(empty, empty, MemOperand(new_obj, JSObject::kPropertiesOffset));
446
447       Register first_prop = x5;
448       __ Add(first_prop, new_obj, JSObject::kHeaderSize);
449
450       // Fill all of the in-object properties with the appropriate filler.
451       Register filler = x7;
452       __ LoadRoot(filler, Heap::kUndefinedValueRootIndex);
453
454       // Obtain number of pre-allocated property fields and in-object
455       // properties.
456       Register prealloc_fields = x10;
457       Register inobject_props = x11;
458       Register inst_sizes = x11;
459       __ Ldr(inst_sizes, FieldMemOperand(init_map, Map::kInstanceSizesOffset));
460       __ Ubfx(prealloc_fields, inst_sizes,
461               Map::kPreAllocatedPropertyFieldsByte * kBitsPerByte,
462               kBitsPerByte);
463       __ Ubfx(inobject_props, inst_sizes,
464               Map::kInObjectPropertiesByte * kBitsPerByte, kBitsPerByte);
465
466       // Calculate number of property fields in the object.
467       Register prop_fields = x6;
468       __ Sub(prop_fields, obj_size, JSObject::kHeaderSize / kPointerSize);
469
470       if (!is_api_function) {
471         Label no_inobject_slack_tracking;
472
473         // Check if slack tracking is enabled.
474         __ Cmp(constructon_count, Operand(Map::kSlackTrackingCounterEnd));
475         __ B(lt, &no_inobject_slack_tracking);
476         constructon_count = NoReg;
477
478         // Fill the pre-allocated fields with undef.
479         __ FillFields(first_prop, prealloc_fields, filler);
480
481         // Update first_prop register to be the offset of the first field after
482         // pre-allocated fields.
483         __ Add(first_prop, first_prop,
484                Operand(prealloc_fields, LSL, kPointerSizeLog2));
485
486         if (FLAG_debug_code) {
487           Register obj_end = x14;
488           __ Add(obj_end, new_obj, Operand(obj_size, LSL, kPointerSizeLog2));
489           __ Cmp(first_prop, obj_end);
490           __ Assert(le, kUnexpectedNumberOfPreAllocatedPropertyFields);
491         }
492
493         // Fill the remaining fields with one pointer filler map.
494         __ LoadRoot(filler, Heap::kOnePointerFillerMapRootIndex);
495         __ Sub(prop_fields, prop_fields, prealloc_fields);
496
497         __ bind(&no_inobject_slack_tracking);
498       }
499       if (create_memento) {
500         // Fill the pre-allocated fields with undef.
501         __ FillFields(first_prop, prop_fields, filler);
502         __ Add(first_prop, new_obj, Operand(obj_size, LSL, kPointerSizeLog2));
503         __ LoadRoot(x14, Heap::kAllocationMementoMapRootIndex);
504         DCHECK_EQ(0 * kPointerSize, AllocationMemento::kMapOffset);
505         __ Str(x14, MemOperand(first_prop, kPointerSize, PostIndex));
506         // Load the AllocationSite
507         __ Peek(x14, 2 * kXRegSize);
508         DCHECK_EQ(1 * kPointerSize, AllocationMemento::kAllocationSiteOffset);
509         __ Str(x14, MemOperand(first_prop, kPointerSize, PostIndex));
510         first_prop = NoReg;
511       } else {
512         // Fill all of the property fields with undef.
513         __ FillFields(first_prop, prop_fields, filler);
514         first_prop = NoReg;
515         prop_fields = NoReg;
516       }
517
518       // Add the object tag to make the JSObject real, so that we can continue
519       // and jump into the continuation code at any time from now on. Any
520       // failures need to undo the allocation, so that the heap is in a
521       // consistent state and verifiable.
522       __ Add(new_obj, new_obj, kHeapObjectTag);
523
524       // Check if a non-empty properties array is needed. Continue with
525       // allocated object if not, or fall through to runtime call if it is.
526       Register element_count = x3;
527       __ Ldrb(element_count,
528               FieldMemOperand(init_map, Map::kUnusedPropertyFieldsOffset));
529       // The field instance sizes contains both pre-allocated property fields
530       // and in-object properties.
531       __ Add(element_count, element_count, prealloc_fields);
532       __ Subs(element_count, element_count, inobject_props);
533
534       // Done if no extra properties are to be allocated.
535       __ B(eq, &allocated);
536       __ Assert(pl, kPropertyAllocationCountFailed);
537
538       // Scale the number of elements by pointer size and add the header for
539       // FixedArrays to the start of the next object calculation from above.
540       Register new_array = x5;
541       Register array_size = x6;
542       __ Add(array_size, element_count, FixedArray::kHeaderSize / kPointerSize);
543       __ Allocate(array_size, new_array, x11, x12, &undo_allocation,
544                   static_cast<AllocationFlags>(RESULT_CONTAINS_TOP |
545                                                SIZE_IN_WORDS));
546
547       Register array_map = x10;
548       __ LoadRoot(array_map, Heap::kFixedArrayMapRootIndex);
549       __ Str(array_map, MemOperand(new_array, FixedArray::kMapOffset));
550       __ SmiTag(x0, element_count);
551       __ Str(x0, MemOperand(new_array, FixedArray::kLengthOffset));
552
553       // Initialize the fields to undefined.
554       Register elements = x10;
555       __ Add(elements, new_array, FixedArray::kHeaderSize);
556       __ FillFields(elements, element_count, filler);
557
558       // Store the initialized FixedArray into the properties field of the
559       // JSObject.
560       __ Add(new_array, new_array, kHeapObjectTag);
561       __ Str(new_array, FieldMemOperand(new_obj, JSObject::kPropertiesOffset));
562
563       // Continue with JSObject being successfully allocated.
564       __ B(&allocated);
565
566       // Undo the setting of the new top so that the heap is verifiable. For
567       // example, the map's unused properties potentially do not match the
568       // allocated objects unused properties.
569       __ Bind(&undo_allocation);
570       __ UndoAllocationInNewSpace(new_obj, x14);
571     }
572
573     // Allocate the new receiver object using the runtime call.
574     __ Bind(&rt_call);
575     Generate_Runtime_NewObject(masm, create_memento, constructor,
576                                &count_incremented, &allocated);
577
578     // Receiver for constructor call allocated.
579     // x4: JSObject
580     __ Bind(&allocated);
581
582     if (create_memento) {
583       __ Peek(x10, 2 * kXRegSize);
584       __ JumpIfRoot(x10, Heap::kUndefinedValueRootIndex, &count_incremented);
585       // r2 is an AllocationSite. We are creating a memento from it, so we
586       // need to increment the memento create count.
587       __ Ldr(x5, FieldMemOperand(x10,
588                                  AllocationSite::kPretenureCreateCountOffset));
589       __ Add(x5, x5, Operand(Smi::FromInt(1)));
590       __ Str(x5, FieldMemOperand(x10,
591                                  AllocationSite::kPretenureCreateCountOffset));
592       __ bind(&count_incremented);
593     }
594
595     __ Push(x4, x4);
596
597     // Reload the number of arguments from the stack.
598     // Set it up in x0 for the function call below.
599     // jssp[0]: receiver
600     // jssp[1]: receiver
601     // jssp[2]: constructor function
602     // jssp[3]: number of arguments (smi-tagged)
603     __ Peek(constructor, 2 * kXRegSize);  // Load constructor.
604     __ Peek(argc, 3 * kXRegSize);  // Load number of arguments.
605     __ SmiUntag(argc);
606
607     // Set up pointer to last argument.
608     __ Add(x2, fp, StandardFrameConstants::kCallerSPOffset);
609
610     // Copy arguments and receiver to the expression stack.
611     // Copy 2 values every loop to use ldp/stp.
612     // x0: number of arguments
613     // x1: constructor function
614     // x2: address of last argument (caller sp)
615     // jssp[0]: receiver
616     // jssp[1]: receiver
617     // jssp[2]: constructor function
618     // jssp[3]: number of arguments (smi-tagged)
619     // Compute the start address of the copy in x3.
620     __ Add(x3, x2, Operand(argc, LSL, kPointerSizeLog2));
621     Label loop, entry, done_copying_arguments;
622     __ B(&entry);
623     __ Bind(&loop);
624     __ Ldp(x10, x11, MemOperand(x3, -2 * kPointerSize, PreIndex));
625     __ Push(x11, x10);
626     __ Bind(&entry);
627     __ Cmp(x3, x2);
628     __ B(gt, &loop);
629     // Because we copied values 2 by 2 we may have copied one extra value.
630     // Drop it if that is the case.
631     __ B(eq, &done_copying_arguments);
632     __ Drop(1);
633     __ Bind(&done_copying_arguments);
634
635     // Call the function.
636     // x0: number of arguments
637     // x1: constructor function
638     if (is_api_function) {
639       __ Ldr(cp, FieldMemOperand(constructor, JSFunction::kContextOffset));
640       Handle<Code> code =
641           masm->isolate()->builtins()->HandleApiCallConstruct();
642       __ Call(code, RelocInfo::CODE_TARGET);
643     } else {
644       ParameterCount actual(argc);
645       __ InvokeFunction(constructor, actual, CALL_FUNCTION, NullCallWrapper());
646     }
647
648     // Store offset of return address for deoptimizer.
649     if (!is_api_function) {
650       masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset());
651     }
652
653     // Restore the context from the frame.
654     // x0: result
655     // jssp[0]: receiver
656     // jssp[1]: constructor function
657     // jssp[2]: number of arguments (smi-tagged)
658     __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
659
660     // If the result is an object (in the ECMA sense), we should get rid
661     // of the receiver and use the result; see ECMA-262 section 13.2.2-7
662     // on page 74.
663     Label use_receiver, exit;
664
665     // If the result is a smi, it is *not* an object in the ECMA sense.
666     // x0: result
667     // jssp[0]: receiver (newly allocated object)
668     // jssp[1]: constructor function
669     // jssp[2]: number of arguments (smi-tagged)
670     __ JumpIfSmi(x0, &use_receiver);
671
672     // If the type of the result (stored in its map) is less than
673     // FIRST_SPEC_OBJECT_TYPE, it is not an object in the ECMA sense.
674     __ JumpIfObjectType(x0, x1, x3, FIRST_SPEC_OBJECT_TYPE, &exit, ge);
675
676     // Throw away the result of the constructor invocation and use the
677     // on-stack receiver as the result.
678     __ Bind(&use_receiver);
679     __ Peek(x0, 0);
680
681     // Remove the receiver from the stack, remove caller arguments, and
682     // return.
683     __ Bind(&exit);
684     // x0: result
685     // jssp[0]: receiver (newly allocated object)
686     // jssp[1]: constructor function
687     // jssp[2]: number of arguments (smi-tagged)
688     __ Peek(x1, 2 * kXRegSize);
689
690     // Leave construct frame.
691   }
692
693   __ DropBySMI(x1);
694   __ Drop(1);
695   __ IncrementCounter(isolate->counters()->constructed_objects(), 1, x1, x2);
696   __ Ret();
697 }
698
699
700 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
701   Generate_JSConstructStubHelper(masm, false, FLAG_pretenuring_call_new);
702 }
703
704
705 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
706   Generate_JSConstructStubHelper(masm, true, false);
707 }
708
709
710 void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) {
711   // ----------- S t a t e -------------
712   //  -- x0     : number of arguments
713   //  -- x1     : constructor function
714   //  -- x2     : allocation site or undefined
715   //  -- x3    : original constructor
716   //  -- lr     : return address
717   //  -- sp[...]: constructor arguments
718   // -----------------------------------
719   ASM_LOCATION("Builtins::Generate_JSConstructStubForDerived");
720
721   // TODO(dslomov): support pretenuring
722   CHECK(!FLAG_pretenuring_call_new);
723
724   {
725     FrameScope frame_scope(masm, StackFrame::CONSTRUCT);
726     __ Mov(x4, x0);
727     __ SmiTag(x4);
728     __ LoadRoot(x10, Heap::kTheHoleValueRootIndex);
729     __ Push(x4, x3, x10);
730     // sp[0]: number of arguments
731     // sp[1]: new.target
732     // sp[2]: receiver (the hole)
733
734
735     // Set up pointer to last argument.
736     __ Add(x2, fp, StandardFrameConstants::kCallerSPOffset);
737
738     // Copy arguments and receiver to the expression stack.
739     // Copy 2 values every loop to use ldp/stp.
740     // x0: number of arguments
741     // x1: constructor function
742     // x2: address of last argument (caller sp)
743     // jssp[0]: receiver
744     // jssp[1]: new.target
745     // jssp[2]: number of arguments (smi-tagged)
746     // Compute the start address of the copy in x4.
747     __ Add(x4, x2, Operand(x0, LSL, kPointerSizeLog2));
748     Label loop, entry, done_copying_arguments;
749     __ B(&entry);
750     __ Bind(&loop);
751     __ Ldp(x10, x11, MemOperand(x4, -2 * kPointerSize, PreIndex));
752     __ Push(x11, x10);
753     __ Bind(&entry);
754     __ Cmp(x4, x2);
755     __ B(gt, &loop);
756     // Because we copied values 2 by 2 we may have copied one extra value.
757     // Drop it if that is the case.
758     __ B(eq, &done_copying_arguments);
759     __ Drop(1);
760     __ Bind(&done_copying_arguments);
761
762     __ Add(x0, x0, Operand(1));  // new.target
763
764     // Handle step in.
765     Label skip_step_in;
766     ExternalReference debug_step_in_fp =
767         ExternalReference::debug_step_in_fp_address(masm->isolate());
768     __ Mov(x2, Operand(debug_step_in_fp));
769     __ Ldr(x2, MemOperand(x2));
770     __ Cbz(x2, &skip_step_in);
771
772     __ Push(x0, x1, x1);
773     __ CallRuntime(Runtime::kHandleStepInForDerivedConstructors, 1);
774     __ Pop(x1, x0);
775
776     __ bind(&skip_step_in);
777
778     // Call the function.
779     // x0: number of arguments
780     // x1: constructor function
781     ParameterCount actual(x0);
782     __ InvokeFunction(x1, actual, CALL_FUNCTION, NullCallWrapper());
783
784
785     // Restore the context from the frame.
786     // x0: result
787     // jssp[0]: number of arguments (smi-tagged)
788     __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
789
790     // Load number of arguments (smi).
791     __ Peek(x1, 0);
792
793     // Leave construct frame
794   }
795
796   __ DropBySMI(x1);
797   __ Drop(1);
798   __ Ret();
799 }
800
801
802 // Input:
803 //   x0: code entry.
804 //   x1: function.
805 //   x2: receiver.
806 //   x3: argc.
807 //   x4: argv.
808 // Output:
809 //   x0: result.
810 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
811                                              bool is_construct) {
812   // Called from JSEntryStub::GenerateBody().
813   Register function = x1;
814   Register receiver = x2;
815   Register argc = x3;
816   Register argv = x4;
817
818   ProfileEntryHookStub::MaybeCallEntryHook(masm);
819
820   // Clear the context before we push it when entering the internal frame.
821   __ Mov(cp, 0);
822
823   {
824     // Enter an internal frame.
825     FrameScope scope(masm, StackFrame::INTERNAL);
826
827     // Set up the context from the function argument.
828     __ Ldr(cp, FieldMemOperand(function, JSFunction::kContextOffset));
829
830     __ InitializeRootRegister();
831
832     // Push the function and the receiver onto the stack.
833     __ Push(function, receiver);
834
835     // Copy arguments to the stack in a loop, in reverse order.
836     // x3: argc.
837     // x4: argv.
838     Label loop, entry;
839     // Compute the copy end address.
840     __ Add(x10, argv, Operand(argc, LSL, kPointerSizeLog2));
841
842     __ B(&entry);
843     __ Bind(&loop);
844     __ Ldr(x11, MemOperand(argv, kPointerSize, PostIndex));
845     __ Ldr(x12, MemOperand(x11));  // Dereference the handle.
846     __ Push(x12);  // Push the argument.
847     __ Bind(&entry);
848     __ Cmp(x10, argv);
849     __ B(ne, &loop);
850
851     // Initialize all JavaScript callee-saved registers, since they will be seen
852     // by the garbage collector as part of handlers.
853     // The original values have been saved in JSEntryStub::GenerateBody().
854     __ LoadRoot(x19, Heap::kUndefinedValueRootIndex);
855     __ Mov(x20, x19);
856     __ Mov(x21, x19);
857     __ Mov(x22, x19);
858     __ Mov(x23, x19);
859     __ Mov(x24, x19);
860     __ Mov(x25, x19);
861     // Don't initialize the reserved registers.
862     // x26 : root register (root).
863     // x27 : context pointer (cp).
864     // x28 : JS stack pointer (jssp).
865     // x29 : frame pointer (fp).
866
867     __ Mov(x0, argc);
868     if (is_construct) {
869       // No type feedback cell is available.
870       __ LoadRoot(x2, Heap::kUndefinedValueRootIndex);
871
872       CallConstructStub stub(masm->isolate(), NO_CALL_CONSTRUCTOR_FLAGS);
873       __ CallStub(&stub);
874     } else {
875       ParameterCount actual(x0);
876       __ InvokeFunction(function, actual, CALL_FUNCTION, NullCallWrapper());
877     }
878     // Exit the JS internal frame and remove the parameters (except function),
879     // and return.
880   }
881
882   // Result is in x0. Return.
883   __ Ret();
884 }
885
886
887 void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) {
888   Generate_JSEntryTrampolineHelper(masm, false);
889 }
890
891
892 void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) {
893   Generate_JSEntryTrampolineHelper(masm, true);
894 }
895
896
897 void Builtins::Generate_CompileLazy(MacroAssembler* masm) {
898   CallRuntimePassFunction(masm, Runtime::kCompileLazy);
899   GenerateTailCallToReturnedCode(masm);
900 }
901
902
903 static void CallCompileOptimized(MacroAssembler* masm, bool concurrent) {
904   FrameScope scope(masm, StackFrame::INTERNAL);
905   Register function = x1;
906
907   // Preserve function. At the same time, push arguments for
908   // kCompileOptimized.
909   __ LoadObject(x10, masm->isolate()->factory()->ToBoolean(concurrent));
910   __ Push(function, function, x10);
911
912   __ CallRuntime(Runtime::kCompileOptimized, 2);
913
914   // Restore receiver.
915   __ Pop(function);
916 }
917
918
919 void Builtins::Generate_CompileOptimized(MacroAssembler* masm) {
920   CallCompileOptimized(masm, false);
921   GenerateTailCallToReturnedCode(masm);
922 }
923
924
925 void Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) {
926   CallCompileOptimized(masm, true);
927   GenerateTailCallToReturnedCode(masm);
928 }
929
930
931 static void GenerateMakeCodeYoungAgainCommon(MacroAssembler* masm) {
932   // For now, we are relying on the fact that make_code_young doesn't do any
933   // garbage collection which allows us to save/restore the registers without
934   // worrying about which of them contain pointers. We also don't build an
935   // internal frame to make the code fast, since we shouldn't have to do stack
936   // crawls in MakeCodeYoung. This seems a bit fragile.
937
938   // The following caller-saved registers must be saved and restored when
939   // calling through to the runtime:
940   //   x0 - The address from which to resume execution.
941   //   x1 - isolate
942   //   lr - The return address for the JSFunction itself. It has not yet been
943   //        preserved on the stack because the frame setup code was replaced
944   //        with a call to this stub, to handle code ageing.
945   {
946     FrameScope scope(masm, StackFrame::MANUAL);
947     __ Push(x0, x1, fp, lr);
948     __ Mov(x1, ExternalReference::isolate_address(masm->isolate()));
949     __ CallCFunction(
950         ExternalReference::get_make_code_young_function(masm->isolate()), 2);
951     __ Pop(lr, fp, x1, x0);
952   }
953
954   // The calling function has been made young again, so return to execute the
955   // real frame set-up code.
956   __ Br(x0);
957 }
958
959 #define DEFINE_CODE_AGE_BUILTIN_GENERATOR(C)                 \
960 void Builtins::Generate_Make##C##CodeYoungAgainEvenMarking(  \
961     MacroAssembler* masm) {                                  \
962   GenerateMakeCodeYoungAgainCommon(masm);                    \
963 }                                                            \
964 void Builtins::Generate_Make##C##CodeYoungAgainOddMarking(   \
965     MacroAssembler* masm) {                                  \
966   GenerateMakeCodeYoungAgainCommon(masm);                    \
967 }
968 CODE_AGE_LIST(DEFINE_CODE_AGE_BUILTIN_GENERATOR)
969 #undef DEFINE_CODE_AGE_BUILTIN_GENERATOR
970
971
972 void Builtins::Generate_MarkCodeAsExecutedOnce(MacroAssembler* masm) {
973   // For now, as in GenerateMakeCodeYoungAgainCommon, we are relying on the fact
974   // that make_code_young doesn't do any garbage collection which allows us to
975   // save/restore the registers without worrying about which of them contain
976   // pointers.
977
978   // The following caller-saved registers must be saved and restored when
979   // calling through to the runtime:
980   //   x0 - The address from which to resume execution.
981   //   x1 - isolate
982   //   lr - The return address for the JSFunction itself. It has not yet been
983   //        preserved on the stack because the frame setup code was replaced
984   //        with a call to this stub, to handle code ageing.
985   {
986     FrameScope scope(masm, StackFrame::MANUAL);
987     __ Push(x0, x1, fp, lr);
988     __ Mov(x1, ExternalReference::isolate_address(masm->isolate()));
989     __ CallCFunction(
990         ExternalReference::get_mark_code_as_executed_function(
991             masm->isolate()), 2);
992     __ Pop(lr, fp, x1, x0);
993
994     // Perform prologue operations usually performed by the young code stub.
995     __ EmitFrameSetupForCodeAgePatching(masm);
996   }
997
998   // Jump to point after the code-age stub.
999   __ Add(x0, x0, kNoCodeAgeSequenceLength);
1000   __ Br(x0);
1001 }
1002
1003
1004 void Builtins::Generate_MarkCodeAsExecutedTwice(MacroAssembler* masm) {
1005   GenerateMakeCodeYoungAgainCommon(masm);
1006 }
1007
1008
1009 static void Generate_NotifyStubFailureHelper(MacroAssembler* masm,
1010                                              SaveFPRegsMode save_doubles) {
1011   {
1012     FrameScope scope(masm, StackFrame::INTERNAL);
1013
1014     // Preserve registers across notification, this is important for compiled
1015     // stubs that tail call the runtime on deopts passing their parameters in
1016     // registers.
1017     // TODO(jbramley): Is it correct (and appropriate) to use safepoint
1018     // registers here? According to the comment above, we should only need to
1019     // preserve the registers with parameters.
1020     __ PushXRegList(kSafepointSavedRegisters);
1021     // Pass the function and deoptimization type to the runtime system.
1022     __ CallRuntime(Runtime::kNotifyStubFailure, 0, save_doubles);
1023     __ PopXRegList(kSafepointSavedRegisters);
1024   }
1025
1026   // Ignore state (pushed by Deoptimizer::EntryGenerator::Generate).
1027   __ Drop(1);
1028
1029   // Jump to the miss handler. Deoptimizer::EntryGenerator::Generate loads this
1030   // into lr before it jumps here.
1031   __ Br(lr);
1032 }
1033
1034
1035 void Builtins::Generate_NotifyStubFailure(MacroAssembler* masm) {
1036   Generate_NotifyStubFailureHelper(masm, kDontSaveFPRegs);
1037 }
1038
1039
1040 void Builtins::Generate_NotifyStubFailureSaveDoubles(MacroAssembler* masm) {
1041   Generate_NotifyStubFailureHelper(masm, kSaveFPRegs);
1042 }
1043
1044
1045 static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm,
1046                                              Deoptimizer::BailoutType type) {
1047   {
1048     FrameScope scope(masm, StackFrame::INTERNAL);
1049     // Pass the deoptimization type to the runtime system.
1050     __ Mov(x0, Smi::FromInt(static_cast<int>(type)));
1051     __ Push(x0);
1052     __ CallRuntime(Runtime::kNotifyDeoptimized, 1);
1053   }
1054
1055   // Get the full codegen state from the stack and untag it.
1056   Register state = x6;
1057   __ Peek(state, 0);
1058   __ SmiUntag(state);
1059
1060   // Switch on the state.
1061   Label with_tos_register, unknown_state;
1062   __ CompareAndBranch(
1063       state, FullCodeGenerator::NO_REGISTERS, ne, &with_tos_register);
1064   __ Drop(1);  // Remove state.
1065   __ Ret();
1066
1067   __ Bind(&with_tos_register);
1068   // Reload TOS register.
1069   __ Peek(x0, kPointerSize);
1070   __ CompareAndBranch(state, FullCodeGenerator::TOS_REG, ne, &unknown_state);
1071   __ Drop(2);  // Remove state and TOS.
1072   __ Ret();
1073
1074   __ Bind(&unknown_state);
1075   __ Abort(kInvalidFullCodegenState);
1076 }
1077
1078
1079 void Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) {
1080   Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::EAGER);
1081 }
1082
1083
1084 void Builtins::Generate_NotifyLazyDeoptimized(MacroAssembler* masm) {
1085   Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::LAZY);
1086 }
1087
1088
1089 void Builtins::Generate_NotifySoftDeoptimized(MacroAssembler* masm) {
1090   Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::SOFT);
1091 }
1092
1093
1094 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) {
1095   // Lookup the function in the JavaScript frame.
1096   __ Ldr(x0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
1097   {
1098     FrameScope scope(masm, StackFrame::INTERNAL);
1099     // Pass function as argument.
1100     __ Push(x0);
1101     __ CallRuntime(Runtime::kCompileForOnStackReplacement, 1);
1102   }
1103
1104   // If the code object is null, just return to the unoptimized code.
1105   Label skip;
1106   __ CompareAndBranch(x0, Smi::FromInt(0), ne, &skip);
1107   __ Ret();
1108
1109   __ Bind(&skip);
1110
1111   // Load deoptimization data from the code object.
1112   // <deopt_data> = <code>[#deoptimization_data_offset]
1113   __ Ldr(x1, MemOperand(x0, Code::kDeoptimizationDataOffset - kHeapObjectTag));
1114
1115   // Load the OSR entrypoint offset from the deoptimization data.
1116   // <osr_offset> = <deopt_data>[#header_size + #osr_pc_offset]
1117   __ Ldrsw(w1, UntagSmiFieldMemOperand(x1, FixedArray::OffsetOfElementAt(
1118       DeoptimizationInputData::kOsrPcOffsetIndex)));
1119
1120   // Compute the target address = code_obj + header_size + osr_offset
1121   // <entry_addr> = <code_obj> + #header_size + <osr_offset>
1122   __ Add(x0, x0, x1);
1123   __ Add(lr, x0, Code::kHeaderSize - kHeapObjectTag);
1124
1125   // And "return" to the OSR entry point of the function.
1126   __ Ret();
1127 }
1128
1129
1130 void Builtins::Generate_OsrAfterStackCheck(MacroAssembler* masm) {
1131   // We check the stack limit as indicator that recompilation might be done.
1132   Label ok;
1133   __ CompareRoot(jssp, Heap::kStackLimitRootIndex);
1134   __ B(hs, &ok);
1135   {
1136     FrameScope scope(masm, StackFrame::INTERNAL);
1137     __ CallRuntime(Runtime::kStackGuard, 0);
1138   }
1139   __ Jump(masm->isolate()->builtins()->OnStackReplacement(),
1140           RelocInfo::CODE_TARGET);
1141
1142   __ Bind(&ok);
1143   __ Ret();
1144 }
1145
1146
1147 void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
1148   enum {
1149     call_type_JS_func = 0,
1150     call_type_func_proxy = 1,
1151     call_type_non_func = 2
1152   };
1153   Register argc = x0;
1154   Register function = x1;
1155   Register call_type = x4;
1156   Register scratch1 = x10;
1157   Register scratch2 = x11;
1158   Register receiver_type = x13;
1159
1160   ASM_LOCATION("Builtins::Generate_FunctionCall");
1161   // 1. Make sure we have at least one argument.
1162   { Label done;
1163     __ Cbnz(argc, &done);
1164     __ LoadRoot(scratch1, Heap::kUndefinedValueRootIndex);
1165     __ Push(scratch1);
1166     __ Mov(argc, 1);
1167     __ Bind(&done);
1168   }
1169
1170   // 2. Get the function to call (passed as receiver) from the stack, check
1171   //    if it is a function.
1172   Label slow, non_function;
1173   __ Peek(function, Operand(argc, LSL, kXRegSizeLog2));
1174   __ JumpIfSmi(function, &non_function);
1175   __ JumpIfNotObjectType(function, scratch1, receiver_type,
1176                          JS_FUNCTION_TYPE, &slow);
1177
1178   // 3a. Patch the first argument if necessary when calling a function.
1179   Label shift_arguments;
1180   __ Mov(call_type, static_cast<int>(call_type_JS_func));
1181   { Label convert_to_object, use_global_proxy, patch_receiver;
1182     // Change context eagerly in case we need the global receiver.
1183     __ Ldr(cp, FieldMemOperand(function, JSFunction::kContextOffset));
1184
1185     // Do not transform the receiver for strict mode functions.
1186     // Also do not transform the receiver for native (Compilerhints already in
1187     // x3).
1188     __ Ldr(scratch1,
1189            FieldMemOperand(function, JSFunction::kSharedFunctionInfoOffset));
1190     __ Ldr(scratch2.W(),
1191            FieldMemOperand(scratch1, SharedFunctionInfo::kCompilerHintsOffset));
1192     __ TestAndBranchIfAnySet(
1193         scratch2.W(),
1194         (1 << SharedFunctionInfo::kStrictModeFunction) |
1195         (1 << SharedFunctionInfo::kNative),
1196         &shift_arguments);
1197
1198     // Compute the receiver in sloppy mode.
1199     Register receiver = x2;
1200     __ Sub(scratch1, argc, 1);
1201     __ Peek(receiver, Operand(scratch1, LSL, kXRegSizeLog2));
1202     __ JumpIfSmi(receiver, &convert_to_object);
1203
1204     __ JumpIfRoot(receiver, Heap::kUndefinedValueRootIndex,
1205                   &use_global_proxy);
1206     __ JumpIfRoot(receiver, Heap::kNullValueRootIndex, &use_global_proxy);
1207
1208     STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE);
1209     __ JumpIfObjectType(receiver, scratch1, scratch2,
1210                         FIRST_SPEC_OBJECT_TYPE, &shift_arguments, ge);
1211
1212     __ Bind(&convert_to_object);
1213
1214     {
1215       // Enter an internal frame in order to preserve argument count.
1216       FrameScope scope(masm, StackFrame::INTERNAL);
1217       __ SmiTag(argc);
1218
1219       __ Push(argc, receiver);
1220       __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
1221       __ Mov(receiver, x0);
1222
1223       __ Pop(argc);
1224       __ SmiUntag(argc);
1225
1226       // Exit the internal frame.
1227     }
1228
1229     // Restore the function and flag in the registers.
1230     __ Peek(function, Operand(argc, LSL, kXRegSizeLog2));
1231     __ Mov(call_type, static_cast<int>(call_type_JS_func));
1232     __ B(&patch_receiver);
1233
1234     __ Bind(&use_global_proxy);
1235     __ Ldr(receiver, GlobalObjectMemOperand());
1236     __ Ldr(receiver,
1237            FieldMemOperand(receiver, GlobalObject::kGlobalProxyOffset));
1238
1239
1240     __ Bind(&patch_receiver);
1241     __ Sub(scratch1, argc, 1);
1242     __ Poke(receiver, Operand(scratch1, LSL, kXRegSizeLog2));
1243
1244     __ B(&shift_arguments);
1245   }
1246
1247   // 3b. Check for function proxy.
1248   __ Bind(&slow);
1249   __ Mov(call_type, static_cast<int>(call_type_func_proxy));
1250   __ Cmp(receiver_type, JS_FUNCTION_PROXY_TYPE);
1251   __ B(eq, &shift_arguments);
1252   __ Bind(&non_function);
1253   __ Mov(call_type, static_cast<int>(call_type_non_func));
1254
1255   // 3c. Patch the first argument when calling a non-function.  The
1256   //     CALL_NON_FUNCTION builtin expects the non-function callee as
1257   //     receiver, so overwrite the first argument which will ultimately
1258   //     become the receiver.
1259   // call type (0: JS function, 1: function proxy, 2: non-function)
1260   __ Sub(scratch1, argc, 1);
1261   __ Poke(function, Operand(scratch1, LSL, kXRegSizeLog2));
1262
1263   // 4. Shift arguments and return address one slot down on the stack
1264   //    (overwriting the original receiver).  Adjust argument count to make
1265   //    the original first argument the new receiver.
1266   // call type (0: JS function, 1: function proxy, 2: non-function)
1267   __ Bind(&shift_arguments);
1268   { Label loop;
1269     // Calculate the copy start address (destination). Copy end address is jssp.
1270     __ Add(scratch2, jssp, Operand(argc, LSL, kPointerSizeLog2));
1271     __ Sub(scratch1, scratch2, kPointerSize);
1272
1273     __ Bind(&loop);
1274     __ Ldr(x12, MemOperand(scratch1, -kPointerSize, PostIndex));
1275     __ Str(x12, MemOperand(scratch2, -kPointerSize, PostIndex));
1276     __ Cmp(scratch1, jssp);
1277     __ B(ge, &loop);
1278     // Adjust the actual number of arguments and remove the top element
1279     // (which is a copy of the last argument).
1280     __ Sub(argc, argc, 1);
1281     __ Drop(1);
1282   }
1283
1284   // 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin,
1285   //     or a function proxy via CALL_FUNCTION_PROXY.
1286   // call type (0: JS function, 1: function proxy, 2: non-function)
1287   { Label js_function, non_proxy;
1288     __ Cbz(call_type, &js_function);
1289     // Expected number of arguments is 0 for CALL_NON_FUNCTION.
1290     __ Mov(x2, 0);
1291     __ Cmp(call_type, static_cast<int>(call_type_func_proxy));
1292     __ B(ne, &non_proxy);
1293
1294     __ Push(function);  // Re-add proxy object as additional argument.
1295     __ Add(argc, argc, 1);
1296     __ GetBuiltinFunction(function, Builtins::CALL_FUNCTION_PROXY);
1297     __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
1298             RelocInfo::CODE_TARGET);
1299
1300     __ Bind(&non_proxy);
1301     __ GetBuiltinFunction(function, Builtins::CALL_NON_FUNCTION);
1302     __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
1303             RelocInfo::CODE_TARGET);
1304     __ Bind(&js_function);
1305   }
1306
1307   // 5b. Get the code to call from the function and check that the number of
1308   //     expected arguments matches what we're providing.  If so, jump
1309   //     (tail-call) to the code in register edx without checking arguments.
1310   __ Ldr(x3, FieldMemOperand(function, JSFunction::kSharedFunctionInfoOffset));
1311   __ Ldrsw(x2,
1312            FieldMemOperand(x3,
1313              SharedFunctionInfo::kFormalParameterCountOffset));
1314   Label dont_adapt_args;
1315   __ Cmp(x2, argc);  // Check formal and actual parameter counts.
1316   __ B(eq, &dont_adapt_args);
1317   __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
1318           RelocInfo::CODE_TARGET);
1319   __ Bind(&dont_adapt_args);
1320
1321   __ Ldr(x3, FieldMemOperand(function, JSFunction::kCodeEntryOffset));
1322   ParameterCount expected(0);
1323   __ InvokeCode(x3, expected, expected, JUMP_FUNCTION, NullCallWrapper());
1324 }
1325
1326
1327 static void Generate_CheckStackOverflow(MacroAssembler* masm,
1328                                         const int calleeOffset) {
1329   Register argc = x0;
1330   Register function = x15;
1331
1332   // Check the stack for overflow.
1333   // We are not trying to catch interruptions (e.g. debug break and
1334   // preemption) here, so the "real stack limit" is checked.
1335   Label enough_stack_space;
1336   __ LoadRoot(x10, Heap::kRealStackLimitRootIndex);
1337   __ Ldr(function, MemOperand(fp, calleeOffset));
1338   // Make x10 the space we have left. The stack might already be overflowed
1339   // here which will cause x10 to become negative.
1340   // TODO(jbramley): Check that the stack usage here is safe.
1341   __ Sub(x10, jssp, x10);
1342   // Check if the arguments will overflow the stack.
1343   __ Cmp(x10, Operand::UntagSmiAndScale(argc, kPointerSizeLog2));
1344   __ B(gt, &enough_stack_space);
1345   // There is not enough stack space, so use a builtin to throw an appropriate
1346   // error.
1347   __ Push(function, argc);
1348   __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
1349   // We should never return from the APPLY_OVERFLOW builtin.
1350   if (__ emit_debug_code()) {
1351     __ Unreachable();
1352   }
1353
1354   __ Bind(&enough_stack_space);
1355 }
1356
1357
1358 static void Generate_PushAppliedArguments(MacroAssembler* masm,
1359                                           const int argumentsOffset,
1360                                           const int indexOffset,
1361                                           const int limitOffset) {
1362   Label entry, loop;
1363   Register current = x0;
1364   __ Ldr(current, MemOperand(fp, indexOffset));
1365   __ B(&entry);
1366
1367   __ Bind(&loop);
1368   // Load the current argument from the arguments array and push it.
1369   // TODO(all): Couldn't we optimize this for JS arrays?
1370
1371   __ Ldr(x1, MemOperand(fp, argumentsOffset));
1372   __ Push(x1, current);
1373
1374   // Call the runtime to access the property in the arguments array.
1375   __ CallRuntime(Runtime::kGetProperty, 2);
1376   __ Push(x0);
1377
1378   // Use inline caching to access the arguments.
1379   __ Ldr(current, MemOperand(fp, indexOffset));
1380   __ Add(current, current, Smi::FromInt(1));
1381   __ Str(current, MemOperand(fp, indexOffset));
1382
1383   // Test if the copy loop has finished copying all the elements from the
1384   // arguments object.
1385   __ Bind(&entry);
1386   __ Ldr(x1, MemOperand(fp, limitOffset));
1387   __ Cmp(current, x1);
1388   __ B(ne, &loop);
1389
1390   // On exit, the pushed arguments count is in x0, untagged
1391   __ SmiUntag(current);
1392 }
1393
1394
1395 static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) {
1396   const int kFormalParameters = targetIsArgument ? 3 : 2;
1397   const int kStackSize = kFormalParameters + 1;
1398
1399   {
1400     FrameScope frame_scope(masm, StackFrame::INTERNAL);
1401
1402     const int kArgumentsOffset =  kFPOnStackSize + kPCOnStackSize;
1403     const int kReceiverOffset = kArgumentsOffset + kPointerSize;
1404     const int kFunctionOffset = kReceiverOffset + kPointerSize;
1405     const int kIndexOffset    =
1406         StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize);
1407     const int kLimitOffset    =
1408         StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize);
1409
1410     Register args = x12;
1411     Register receiver = x14;
1412     Register function = x15;
1413
1414     // Get the length of the arguments via a builtin call.
1415     __ Ldr(function, MemOperand(fp, kFunctionOffset));
1416     __ Ldr(args, MemOperand(fp, kArgumentsOffset));
1417     __ Push(function, args);
1418     if (targetIsArgument) {
1419       __ InvokeBuiltin(Builtins::REFLECT_APPLY_PREPARE, CALL_FUNCTION);
1420     } else {
1421       __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION);
1422     }
1423     Register argc = x0;
1424
1425     Generate_CheckStackOverflow(masm, kFunctionOffset);
1426
1427     // Push current limit and index.
1428     __ Mov(x1, 0);  // Initial index.
1429     __ Push(argc, x1);
1430
1431     Label push_receiver;
1432     __ Ldr(receiver, MemOperand(fp, kReceiverOffset));
1433
1434     // Check that the function is a JS function. Otherwise it must be a proxy.
1435     // When it is not the function proxy will be invoked later.
1436     __ JumpIfNotObjectType(function, x10, x11, JS_FUNCTION_TYPE,
1437                            &push_receiver);
1438
1439     // Change context eagerly to get the right global object if necessary.
1440     __ Ldr(cp, FieldMemOperand(function, JSFunction::kContextOffset));
1441     // Load the shared function info.
1442     __ Ldr(x2, FieldMemOperand(function,
1443                                JSFunction::kSharedFunctionInfoOffset));
1444
1445     // Compute and push the receiver.
1446     // Do not transform the receiver for strict mode functions.
1447     Label convert_receiver_to_object, use_global_proxy;
1448     __ Ldr(w10, FieldMemOperand(x2, SharedFunctionInfo::kCompilerHintsOffset));
1449     __ Tbnz(x10, SharedFunctionInfo::kStrictModeFunction, &push_receiver);
1450     // Do not transform the receiver for native functions.
1451     __ Tbnz(x10, SharedFunctionInfo::kNative, &push_receiver);
1452
1453     // Compute the receiver in sloppy mode.
1454     __ JumpIfSmi(receiver, &convert_receiver_to_object);
1455     __ JumpIfRoot(receiver, Heap::kNullValueRootIndex, &use_global_proxy);
1456     __ JumpIfRoot(receiver, Heap::kUndefinedValueRootIndex,
1457                   &use_global_proxy);
1458
1459     // Check if the receiver is already a JavaScript object.
1460     STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE);
1461     __ JumpIfObjectType(receiver, x10, x11, FIRST_SPEC_OBJECT_TYPE,
1462                         &push_receiver, ge);
1463
1464     // Call a builtin to convert the receiver to a regular object.
1465     __ Bind(&convert_receiver_to_object);
1466     __ Push(receiver);
1467     __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
1468     __ Mov(receiver, x0);
1469     __ B(&push_receiver);
1470
1471     __ Bind(&use_global_proxy);
1472     __ Ldr(x10, GlobalObjectMemOperand());
1473     __ Ldr(receiver, FieldMemOperand(x10, GlobalObject::kGlobalProxyOffset));
1474
1475     // Push the receiver
1476     __ Bind(&push_receiver);
1477     __ Push(receiver);
1478
1479     // Copy all arguments from the array to the stack.
1480     Generate_PushAppliedArguments(
1481         masm, kArgumentsOffset, kIndexOffset, kLimitOffset);
1482
1483     // At the end of the loop, the number of arguments is stored in 'current',
1484     // represented as a smi.
1485
1486     function = x1;  // From now on we want the function to be kept in x1;
1487     __ Ldr(function, MemOperand(fp, kFunctionOffset));
1488
1489     // Call the function.
1490     Label call_proxy;
1491     ParameterCount actual(x0);
1492     __ JumpIfNotObjectType(function, x10, x11, JS_FUNCTION_TYPE, &call_proxy);
1493     __ InvokeFunction(function, actual, CALL_FUNCTION, NullCallWrapper());
1494     frame_scope.GenerateLeaveFrame();
1495     __ Drop(kStackSize);
1496     __ Ret();
1497
1498     // Call the function proxy.
1499     __ Bind(&call_proxy);
1500     // x0 : argc
1501     // x1 : function
1502     __ Push(function);  // Add function proxy as last argument.
1503     __ Add(x0, x0, 1);
1504     __ Mov(x2, 0);
1505     __ GetBuiltinFunction(x1, Builtins::CALL_FUNCTION_PROXY);
1506     __ Call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
1507             RelocInfo::CODE_TARGET);
1508   }
1509   __ Drop(kStackSize);
1510   __ Ret();
1511 }
1512
1513
1514 static void Generate_ConstructHelper(MacroAssembler* masm) {
1515   const int kFormalParameters = 3;
1516   const int kStackSize = kFormalParameters + 1;
1517
1518   {
1519     FrameScope frame_scope(masm, StackFrame::INTERNAL);
1520
1521     const int kNewTargetOffset = kFPOnStackSize + kPCOnStackSize;
1522     const int kArgumentsOffset =  kNewTargetOffset + kPointerSize;
1523     const int kFunctionOffset = kArgumentsOffset + kPointerSize;
1524
1525     const int kIndexOffset    =
1526         StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize);
1527     const int kLimitOffset    =
1528         StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize);
1529
1530     // Is x11 safe to use?
1531     Register newTarget = x11;
1532     Register args = x12;
1533     Register function = x15;
1534
1535     // If newTarget is not supplied, set it to constructor
1536     Label validate_arguments;
1537     __ Ldr(x0, MemOperand(fp, kNewTargetOffset));
1538     __ CompareRoot(x0, Heap::kUndefinedValueRootIndex);
1539     __ B(ne, &validate_arguments);
1540     __ Ldr(x0, MemOperand(fp, kFunctionOffset));
1541     __ Str(x0, MemOperand(fp, kNewTargetOffset));
1542
1543     // Validate arguments
1544     __ Bind(&validate_arguments);
1545     __ Ldr(function, MemOperand(fp, kFunctionOffset));
1546     __ Ldr(args, MemOperand(fp, kArgumentsOffset));
1547     __ Ldr(newTarget, MemOperand(fp, kNewTargetOffset));
1548     __ Push(function, args, newTarget);
1549     __ InvokeBuiltin(Builtins::REFLECT_CONSTRUCT_PREPARE, CALL_FUNCTION);
1550     Register argc = x0;
1551
1552     Generate_CheckStackOverflow(masm, kFunctionOffset);
1553
1554     // Push current limit and index, constructor & newTarget
1555     __ Mov(x1, 0);  // Initial index.
1556     __ Ldr(newTarget, MemOperand(fp, kNewTargetOffset));
1557     __ Push(argc, x1, newTarget, function);
1558
1559     // Copy all arguments from the array to the stack.
1560     Generate_PushAppliedArguments(
1561         masm, kArgumentsOffset, kIndexOffset, kLimitOffset);
1562
1563     __ Ldr(x1, MemOperand(fp, kFunctionOffset));
1564     // Use undefined feedback vector
1565     __ LoadRoot(x2, Heap::kUndefinedValueRootIndex);
1566
1567     // Call the function.
1568     CallConstructStub stub(masm->isolate(), SUPER_CONSTRUCTOR_CALL);
1569     __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
1570
1571     __ Drop(1);
1572   }
1573   __ Drop(kStackSize);
1574   __ Ret();
1575 }
1576
1577
1578 void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
1579   ASM_LOCATION("Builtins::Generate_FunctionApply");
1580   Generate_ApplyHelper(masm, false);
1581 }
1582
1583
1584 void Builtins::Generate_ReflectApply(MacroAssembler* masm) {
1585   ASM_LOCATION("Builtins::Generate_ReflectApply");
1586   Generate_ApplyHelper(masm, true);
1587 }
1588
1589
1590 void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) {
1591   ASM_LOCATION("Builtins::Generate_ReflectConstruct");
1592   Generate_ConstructHelper(masm);
1593 }
1594
1595
1596 static void ArgumentAdaptorStackCheck(MacroAssembler* masm,
1597                                       Label* stack_overflow) {
1598   // ----------- S t a t e -------------
1599   //  -- x0 : actual number of arguments
1600   //  -- x1 : function (passed through to callee)
1601   //  -- x2 : expected number of arguments
1602   // -----------------------------------
1603   // Check the stack for overflow.
1604   // We are not trying to catch interruptions (e.g. debug break and
1605   // preemption) here, so the "real stack limit" is checked.
1606   Label enough_stack_space;
1607   __ LoadRoot(x10, Heap::kRealStackLimitRootIndex);
1608   // Make x10 the space we have left. The stack might already be overflowed
1609   // here which will cause x10 to become negative.
1610   __ Sub(x10, jssp, x10);
1611   // Check if the arguments will overflow the stack.
1612   __ Cmp(x10, Operand(x2, LSL, kPointerSizeLog2));
1613   __ B(le, stack_overflow);
1614 }
1615
1616
1617 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
1618   __ SmiTag(x10, x0);
1619   __ Mov(x11, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
1620   __ Push(lr, fp);
1621   __ Push(x11, x1, x10);
1622   __ Add(fp, jssp,
1623          StandardFrameConstants::kFixedFrameSizeFromFp + kPointerSize);
1624 }
1625
1626
1627 static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) {
1628   // ----------- S t a t e -------------
1629   //  -- x0 : result being passed through
1630   // -----------------------------------
1631   // Get the number of arguments passed (as a smi), tear down the frame and
1632   // then drop the parameters and the receiver.
1633   __ Ldr(x10, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp +
1634                                kPointerSize)));
1635   __ Mov(jssp, fp);
1636   __ Pop(fp, lr);
1637   __ DropBySMI(x10, kXRegSize);
1638   __ Drop(1);
1639 }
1640
1641
1642 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
1643   ASM_LOCATION("Builtins::Generate_ArgumentsAdaptorTrampoline");
1644   // ----------- S t a t e -------------
1645   //  -- x0 : actual number of arguments
1646   //  -- x1 : function (passed through to callee)
1647   //  -- x2 : expected number of arguments
1648   // -----------------------------------
1649
1650   Label stack_overflow;
1651   ArgumentAdaptorStackCheck(masm, &stack_overflow);
1652
1653   Register argc_actual = x0;  // Excluding the receiver.
1654   Register argc_expected = x2;  // Excluding the receiver.
1655   Register function = x1;
1656   Register code_entry = x3;
1657
1658   Label invoke, dont_adapt_arguments;
1659
1660   Label enough, too_few;
1661   __ Ldr(code_entry, FieldMemOperand(function, JSFunction::kCodeEntryOffset));
1662   __ Cmp(argc_actual, argc_expected);
1663   __ B(lt, &too_few);
1664   __ Cmp(argc_expected, SharedFunctionInfo::kDontAdaptArgumentsSentinel);
1665   __ B(eq, &dont_adapt_arguments);
1666
1667   {  // Enough parameters: actual >= expected
1668     EnterArgumentsAdaptorFrame(masm);
1669
1670     Register copy_start = x10;
1671     Register copy_end = x11;
1672     Register copy_to = x12;
1673     Register scratch1 = x13, scratch2 = x14;
1674
1675     __ Lsl(argc_expected, argc_expected, kPointerSizeLog2);
1676
1677     // Adjust for fp, lr, and the receiver.
1678     __ Add(copy_start, fp, 3 * kPointerSize);
1679     __ Add(copy_start, copy_start, Operand(argc_actual, LSL, kPointerSizeLog2));
1680     __ Sub(copy_end, copy_start, argc_expected);
1681     __ Sub(copy_end, copy_end, kPointerSize);
1682     __ Mov(copy_to, jssp);
1683
1684     // Claim space for the arguments, the receiver, and one extra slot.
1685     // The extra slot ensures we do not write under jssp. It will be popped
1686     // later.
1687     __ Add(scratch1, argc_expected, 2 * kPointerSize);
1688     __ Claim(scratch1, 1);
1689
1690     // Copy the arguments (including the receiver) to the new stack frame.
1691     Label copy_2_by_2;
1692     __ Bind(&copy_2_by_2);
1693     __ Ldp(scratch1, scratch2,
1694            MemOperand(copy_start, - 2 * kPointerSize, PreIndex));
1695     __ Stp(scratch1, scratch2,
1696            MemOperand(copy_to, - 2 * kPointerSize, PreIndex));
1697     __ Cmp(copy_start, copy_end);
1698     __ B(hi, &copy_2_by_2);
1699
1700     // Correct the space allocated for the extra slot.
1701     __ Drop(1);
1702
1703     __ B(&invoke);
1704   }
1705
1706   {  // Too few parameters: Actual < expected
1707     __ Bind(&too_few);
1708     EnterArgumentsAdaptorFrame(masm);
1709
1710     Register copy_from = x10;
1711     Register copy_end = x11;
1712     Register copy_to = x12;
1713     Register scratch1 = x13, scratch2 = x14;
1714
1715     __ Lsl(argc_expected, argc_expected, kPointerSizeLog2);
1716     __ Lsl(argc_actual, argc_actual, kPointerSizeLog2);
1717
1718     // Adjust for fp, lr, and the receiver.
1719     __ Add(copy_from, fp, 3 * kPointerSize);
1720     __ Add(copy_from, copy_from, argc_actual);
1721     __ Mov(copy_to, jssp);
1722     __ Sub(copy_end, copy_to, 1 * kPointerSize);   // Adjust for the receiver.
1723     __ Sub(copy_end, copy_end, argc_actual);
1724
1725     // Claim space for the arguments, the receiver, and one extra slot.
1726     // The extra slot ensures we do not write under jssp. It will be popped
1727     // later.
1728     __ Add(scratch1, argc_expected, 2 * kPointerSize);
1729     __ Claim(scratch1, 1);
1730
1731     // Copy the arguments (including the receiver) to the new stack frame.
1732     Label copy_2_by_2;
1733     __ Bind(&copy_2_by_2);
1734     __ Ldp(scratch1, scratch2,
1735            MemOperand(copy_from, - 2 * kPointerSize, PreIndex));
1736     __ Stp(scratch1, scratch2,
1737            MemOperand(copy_to, - 2 * kPointerSize, PreIndex));
1738     __ Cmp(copy_to, copy_end);
1739     __ B(hi, &copy_2_by_2);
1740
1741     __ Mov(copy_to, copy_end);
1742
1743     // Fill the remaining expected arguments with undefined.
1744     __ LoadRoot(scratch1, Heap::kUndefinedValueRootIndex);
1745     __ Add(copy_end, jssp, kPointerSize);
1746
1747     Label fill;
1748     __ Bind(&fill);
1749     __ Stp(scratch1, scratch1,
1750            MemOperand(copy_to, - 2 * kPointerSize, PreIndex));
1751     __ Cmp(copy_to, copy_end);
1752     __ B(hi, &fill);
1753
1754     // Correct the space allocated for the extra slot.
1755     __ Drop(1);
1756   }
1757
1758   // Arguments have been adapted. Now call the entry point.
1759   __ Bind(&invoke);
1760   __ Call(code_entry);
1761
1762   // Store offset of return address for deoptimizer.
1763   masm->isolate()->heap()->SetArgumentsAdaptorDeoptPCOffset(masm->pc_offset());
1764
1765   // Exit frame and return.
1766   LeaveArgumentsAdaptorFrame(masm);
1767   __ Ret();
1768
1769   // Call the entry point without adapting the arguments.
1770   __ Bind(&dont_adapt_arguments);
1771   __ Jump(code_entry);
1772
1773   __ Bind(&stack_overflow);
1774   {
1775     FrameScope frame(masm, StackFrame::MANUAL);
1776     EnterArgumentsAdaptorFrame(masm);
1777     __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
1778     __ Unreachable();
1779   }
1780 }
1781
1782
1783 #undef __
1784
1785 } }  // namespace v8::internal
1786
1787 #endif  // V8_TARGET_ARCH_ARM