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