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