60055a6cd3cebbcffffa6d4287cc7ff41fc4cc38
[platform/framework/web/crosswalk.git] / src / 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.h"
14 #include "src/stub-cache.h"
15
16 namespace v8 {
17 namespace internal {
18
19
20 #define __ ACCESS_MASM(masm)
21
22
23 void Builtins::Generate_Adaptor(MacroAssembler* masm,
24                                 CFunctionId id,
25                                 BuiltinExtraArguments extra_args) {
26   // ----------- S t a t e -------------
27   //  -- r0                 : number of arguments excluding receiver
28   //  -- r1                 : called function (only guaranteed when
29   //                          extra_args requires it)
30   //  -- cp                 : context
31   //  -- sp[0]              : last argument
32   //  -- ...
33   //  -- sp[4 * (argc - 1)] : first argument (argc == r0)
34   //  -- sp[4 * argc]       : receiver
35   // -----------------------------------
36
37   // Insert extra arguments.
38   int num_extra_args = 0;
39   if (extra_args == NEEDS_CALLED_FUNCTION) {
40     num_extra_args = 1;
41     __ push(r1);
42   } else {
43     DCHECK(extra_args == NO_EXTRA_ARGUMENTS);
44   }
45
46   // JumpToExternalReference expects r0 to contain the number of arguments
47   // including the receiver and the extra arguments.
48   __ add(r0, r0, Operand(num_extra_args + 1));
49   __ JumpToExternalReference(ExternalReference(id, masm->isolate()));
50 }
51
52
53 // Load the built-in InternalArray function from the current context.
54 static void GenerateLoadInternalArrayFunction(MacroAssembler* masm,
55                                               Register result) {
56   // Load the native context.
57
58   __ ldr(result,
59          MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
60   __ ldr(result,
61          FieldMemOperand(result, GlobalObject::kNativeContextOffset));
62   // Load the InternalArray function from the native context.
63   __ ldr(result,
64          MemOperand(result,
65                     Context::SlotOffset(
66                         Context::INTERNAL_ARRAY_FUNCTION_INDEX)));
67 }
68
69
70 // Load the built-in Array function from the current context.
71 static void GenerateLoadArrayFunction(MacroAssembler* masm, Register result) {
72   // Load the native context.
73
74   __ ldr(result,
75          MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
76   __ ldr(result,
77          FieldMemOperand(result, GlobalObject::kNativeContextOffset));
78   // Load the Array function from the native context.
79   __ ldr(result,
80          MemOperand(result,
81                     Context::SlotOffset(Context::ARRAY_FUNCTION_INDEX)));
82 }
83
84
85 void Builtins::Generate_InternalArrayCode(MacroAssembler* masm) {
86   // ----------- S t a t e -------------
87   //  -- r0     : number of arguments
88   //  -- lr     : return address
89   //  -- sp[...]: constructor arguments
90   // -----------------------------------
91   Label generic_array_code, one_or_more_arguments, two_or_more_arguments;
92
93   // Get the InternalArray function.
94   GenerateLoadInternalArrayFunction(masm, r1);
95
96   if (FLAG_debug_code) {
97     // Initial map for the builtin InternalArray functions should be maps.
98     __ ldr(r2, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset));
99     __ SmiTst(r2);
100     __ Assert(ne, kUnexpectedInitialMapForInternalArrayFunction);
101     __ CompareObjectType(r2, r3, r4, MAP_TYPE);
102     __ Assert(eq, kUnexpectedInitialMapForInternalArrayFunction);
103   }
104
105   // Run the native code for the InternalArray function called as a normal
106   // function.
107   // tail call a stub
108   InternalArrayConstructorStub stub(masm->isolate());
109   __ TailCallStub(&stub);
110 }
111
112
113 void Builtins::Generate_ArrayCode(MacroAssembler* masm) {
114   // ----------- S t a t e -------------
115   //  -- r0     : number of arguments
116   //  -- lr     : return address
117   //  -- sp[...]: constructor arguments
118   // -----------------------------------
119   Label generic_array_code, one_or_more_arguments, two_or_more_arguments;
120
121   // Get the Array function.
122   GenerateLoadArrayFunction(masm, r1);
123
124   if (FLAG_debug_code) {
125     // Initial map for the builtin Array functions should be maps.
126     __ ldr(r2, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset));
127     __ SmiTst(r2);
128     __ Assert(ne, kUnexpectedInitialMapForArrayFunction);
129     __ CompareObjectType(r2, r3, r4, MAP_TYPE);
130     __ Assert(eq, kUnexpectedInitialMapForArrayFunction);
131   }
132
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_JSConstructStubHelper(MacroAssembler* masm,
315                                            bool is_api_function,
316                                            bool create_memento) {
317   // ----------- S t a t e -------------
318   //  -- r0     : number of arguments
319   //  -- r1     : constructor function
320   //  -- r2     : allocation site or undefined
321   //  -- lr     : return address
322   //  -- sp[...]: constructor arguments
323   // -----------------------------------
324
325   // Should never create mementos for api functions.
326   DCHECK(!is_api_function || !create_memento);
327
328   Isolate* isolate = masm->isolate();
329
330   // Enter a construct frame.
331   {
332     FrameAndConstantPoolScope scope(masm, StackFrame::CONSTRUCT);
333
334     if (create_memento) {
335       __ AssertUndefinedOrAllocationSite(r2, r3);
336       __ push(r2);
337     }
338
339     // Preserve the two incoming parameters on the stack.
340     __ SmiTag(r0);
341     __ push(r0);  // Smi-tagged arguments count.
342     __ push(r1);  // Constructor function.
343
344     // Try to allocate the object without transitioning into C code. If any of
345     // the preconditions is not met, the code bails out to the runtime call.
346     Label rt_call, allocated;
347     if (FLAG_inline_new) {
348       Label undo_allocation;
349       ExternalReference debug_step_in_fp =
350           ExternalReference::debug_step_in_fp_address(isolate);
351       __ mov(r2, Operand(debug_step_in_fp));
352       __ ldr(r2, MemOperand(r2));
353       __ tst(r2, r2);
354       __ b(ne, &rt_call);
355
356       // Load the initial map and verify that it is in fact a map.
357       // r1: constructor function
358       __ ldr(r2, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset));
359       __ JumpIfSmi(r2, &rt_call);
360       __ CompareObjectType(r2, r3, r4, MAP_TYPE);
361       __ b(ne, &rt_call);
362
363       // Check that the constructor is not constructing a JSFunction (see
364       // comments in Runtime_NewObject in runtime.cc). In which case the
365       // initial map's instance type would be JS_FUNCTION_TYPE.
366       // r1: constructor function
367       // r2: initial map
368       __ CompareInstanceType(r2, r3, JS_FUNCTION_TYPE);
369       __ b(eq, &rt_call);
370
371       if (!is_api_function) {
372         Label allocate;
373         MemOperand bit_field3 = FieldMemOperand(r2, Map::kBitField3Offset);
374         // Check if slack tracking is enabled.
375         __ ldr(r4, bit_field3);
376         __ DecodeField<Map::ConstructionCount>(r3, r4);
377         __ cmp(r3, Operand(JSFunction::kNoSlackTracking));
378         __ b(eq, &allocate);
379         // Decrease generous allocation count.
380         __ sub(r4, r4, Operand(1 << Map::ConstructionCount::kShift));
381         __ str(r4, bit_field3);
382         __ cmp(r3, Operand(JSFunction::kFinishSlackTracking));
383         __ b(ne, &allocate);
384
385         __ push(r1);
386
387         __ Push(r2, r1);  // r1 = constructor
388         __ CallRuntime(Runtime::kFinalizeInstanceSize, 1);
389
390         __ pop(r2);
391         __ pop(r1);
392
393         __ bind(&allocate);
394       }
395
396       // Now allocate the JSObject on the heap.
397       // r1: constructor function
398       // r2: initial map
399       __ ldrb(r3, FieldMemOperand(r2, Map::kInstanceSizeOffset));
400       if (create_memento) {
401         __ add(r3, r3, Operand(AllocationMemento::kSize / kPointerSize));
402       }
403
404       __ Allocate(r3, r4, r5, r6, &rt_call, SIZE_IN_WORDS);
405
406       // Allocated the JSObject, now initialize the fields. Map is set to
407       // initial map and properties and elements are set to empty fixed array.
408       // r1: constructor function
409       // r2: initial map
410       // r3: object size (not including memento if create_memento)
411       // r4: JSObject (not tagged)
412       __ LoadRoot(r6, Heap::kEmptyFixedArrayRootIndex);
413       __ mov(r5, r4);
414       DCHECK_EQ(0 * kPointerSize, JSObject::kMapOffset);
415       __ str(r2, MemOperand(r5, kPointerSize, PostIndex));
416       DCHECK_EQ(1 * kPointerSize, JSObject::kPropertiesOffset);
417       __ str(r6, MemOperand(r5, kPointerSize, PostIndex));
418       DCHECK_EQ(2 * kPointerSize, JSObject::kElementsOffset);
419       __ str(r6, MemOperand(r5, kPointerSize, PostIndex));
420
421       // Fill all the in-object properties with the appropriate filler.
422       // r1: constructor function
423       // r2: initial map
424       // r3: object size (in words, including memento if create_memento)
425       // r4: JSObject (not tagged)
426       // r5: First in-object property of JSObject (not tagged)
427       DCHECK_EQ(3 * kPointerSize, JSObject::kHeaderSize);
428       __ LoadRoot(r6, Heap::kUndefinedValueRootIndex);
429
430       if (!is_api_function) {
431         Label no_inobject_slack_tracking;
432
433         // Check if slack tracking is enabled.
434         __ ldr(ip, FieldMemOperand(r2, Map::kBitField3Offset));
435         __ DecodeField<Map::ConstructionCount>(ip);
436         __ cmp(ip, Operand(JSFunction::kNoSlackTracking));
437         __ b(eq, &no_inobject_slack_tracking);
438
439         // Allocate object with a slack.
440         __ ldr(r0, FieldMemOperand(r2, Map::kInstanceSizesOffset));
441         __ Ubfx(r0, r0, Map::kPreAllocatedPropertyFieldsByte * kBitsPerByte,
442                 kBitsPerByte);
443         __ add(r0, r5, Operand(r0, LSL, kPointerSizeLog2));
444         // r0: offset of first field after pre-allocated fields
445         if (FLAG_debug_code) {
446           __ add(ip, r4, Operand(r3, LSL, kPointerSizeLog2));  // End of object.
447           __ cmp(r0, ip);
448           __ Assert(le, kUnexpectedNumberOfPreAllocatedPropertyFields);
449         }
450         __ InitializeFieldsWithFiller(r5, r0, r6);
451         // To allow for truncation.
452         __ LoadRoot(r6, Heap::kOnePointerFillerMapRootIndex);
453         // Fill the remaining fields with one pointer filler map.
454
455         __ bind(&no_inobject_slack_tracking);
456       }
457
458       if (create_memento) {
459         __ sub(ip, r3, Operand(AllocationMemento::kSize / kPointerSize));
460         __ add(r0, r4, Operand(ip, LSL, kPointerSizeLog2));  // End of object.
461         __ InitializeFieldsWithFiller(r5, r0, r6);
462
463         // Fill in memento fields.
464         // r5: points to the allocated but uninitialized memento.
465         __ LoadRoot(r6, Heap::kAllocationMementoMapRootIndex);
466         DCHECK_EQ(0 * kPointerSize, AllocationMemento::kMapOffset);
467         __ str(r6, MemOperand(r5, kPointerSize, PostIndex));
468         // Load the AllocationSite
469         __ ldr(r6, MemOperand(sp, 2 * kPointerSize));
470         DCHECK_EQ(1 * kPointerSize, AllocationMemento::kAllocationSiteOffset);
471         __ str(r6, MemOperand(r5, kPointerSize, PostIndex));
472       } else {
473         __ add(r0, r4, Operand(r3, LSL, kPointerSizeLog2));  // End of object.
474         __ InitializeFieldsWithFiller(r5, r0, r6);
475       }
476
477       // Add the object tag to make the JSObject real, so that we can continue
478       // and jump into the continuation code at any time from now on. Any
479       // failures need to undo the allocation, so that the heap is in a
480       // consistent state and verifiable.
481       __ add(r4, r4, Operand(kHeapObjectTag));
482
483       // Check if a non-empty properties array is needed. Continue with
484       // allocated object if not fall through to runtime call if it is.
485       // r1: constructor function
486       // r4: JSObject
487       // r5: start of next object (not tagged)
488       __ ldrb(r3, FieldMemOperand(r2, Map::kUnusedPropertyFieldsOffset));
489       // The field instance sizes contains both pre-allocated property fields
490       // and in-object properties.
491       __ ldr(r0, FieldMemOperand(r2, Map::kInstanceSizesOffset));
492       __ Ubfx(r6, r0, Map::kPreAllocatedPropertyFieldsByte * kBitsPerByte,
493               kBitsPerByte);
494       __ add(r3, r3, Operand(r6));
495       __ Ubfx(r6, r0, Map::kInObjectPropertiesByte * kBitsPerByte,
496               kBitsPerByte);
497       __ sub(r3, r3, Operand(r6), SetCC);
498
499       // Done if no extra properties are to be allocated.
500       __ b(eq, &allocated);
501       __ Assert(pl, kPropertyAllocationCountFailed);
502
503       // Scale the number of elements by pointer size and add the header for
504       // FixedArrays to the start of the next object calculation from above.
505       // r1: constructor
506       // r3: number of elements in properties array
507       // r4: JSObject
508       // r5: start of next object
509       __ add(r0, r3, Operand(FixedArray::kHeaderSize / kPointerSize));
510       __ Allocate(
511           r0,
512           r5,
513           r6,
514           r2,
515           &undo_allocation,
516           static_cast<AllocationFlags>(RESULT_CONTAINS_TOP | SIZE_IN_WORDS));
517
518       // Initialize the FixedArray.
519       // r1: constructor
520       // r3: number of elements in properties array
521       // r4: JSObject
522       // r5: FixedArray (not tagged)
523       __ LoadRoot(r6, Heap::kFixedArrayMapRootIndex);
524       __ mov(r2, r5);
525       DCHECK_EQ(0 * kPointerSize, JSObject::kMapOffset);
526       __ str(r6, MemOperand(r2, kPointerSize, PostIndex));
527       DCHECK_EQ(1 * kPointerSize, FixedArray::kLengthOffset);
528       __ SmiTag(r0, r3);
529       __ str(r0, MemOperand(r2, kPointerSize, PostIndex));
530
531       // Initialize the fields to undefined.
532       // r1: constructor function
533       // r2: First element of FixedArray (not tagged)
534       // r3: number of elements in properties array
535       // r4: JSObject
536       // r5: FixedArray (not tagged)
537       __ add(r6, r2, Operand(r3, LSL, kPointerSizeLog2));  // End of object.
538       DCHECK_EQ(2 * kPointerSize, FixedArray::kHeaderSize);
539       { Label loop, entry;
540         __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
541         __ b(&entry);
542         __ bind(&loop);
543         __ str(r0, MemOperand(r2, kPointerSize, PostIndex));
544         __ bind(&entry);
545         __ cmp(r2, r6);
546         __ b(lt, &loop);
547       }
548
549       // Store the initialized FixedArray into the properties field of
550       // the JSObject
551       // r1: constructor function
552       // r4: JSObject
553       // r5: FixedArray (not tagged)
554       __ add(r5, r5, Operand(kHeapObjectTag));  // Add the heap tag.
555       __ str(r5, FieldMemOperand(r4, JSObject::kPropertiesOffset));
556
557       // Continue with JSObject being successfully allocated
558       // r1: constructor function
559       // r4: JSObject
560       __ jmp(&allocated);
561
562       // Undo the setting of the new top so that the heap is verifiable. For
563       // example, the map's unused properties potentially do not match the
564       // allocated objects unused properties.
565       // r4: JSObject (previous new top)
566       __ bind(&undo_allocation);
567       __ UndoAllocationInNewSpace(r4, r5);
568     }
569
570     // Allocate the new receiver object using the runtime call.
571     // r1: constructor function
572     __ bind(&rt_call);
573     if (create_memento) {
574       // Get the cell or allocation site.
575       __ ldr(r2, MemOperand(sp, 2 * kPointerSize));
576       __ push(r2);
577     }
578
579     __ push(r1);  // argument for Runtime_NewObject
580     if (create_memento) {
581       __ CallRuntime(Runtime::kNewObjectWithAllocationSite, 2);
582     } else {
583       __ CallRuntime(Runtime::kNewObject, 1);
584     }
585     __ mov(r4, r0);
586
587     // If we ended up using the runtime, and we want a memento, then the
588     // runtime call made it for us, and we shouldn't do create count
589     // increment.
590     Label count_incremented;
591     if (create_memento) {
592       __ jmp(&count_incremented);
593     }
594
595     // Receiver for constructor call allocated.
596     // r4: JSObject
597     __ bind(&allocated);
598
599     if (create_memento) {
600       __ ldr(r2, MemOperand(sp, kPointerSize * 2));
601       __ LoadRoot(r5, Heap::kUndefinedValueRootIndex);
602       __ cmp(r2, r5);
603       __ b(eq, &count_incremented);
604       // r2 is an AllocationSite. We are creating a memento from it, so we
605       // need to increment the memento create count.
606       __ ldr(r3, FieldMemOperand(r2,
607                                  AllocationSite::kPretenureCreateCountOffset));
608       __ add(r3, r3, Operand(Smi::FromInt(1)));
609       __ str(r3, FieldMemOperand(r2,
610                                  AllocationSite::kPretenureCreateCountOffset));
611       __ bind(&count_incremented);
612     }
613
614     __ push(r4);
615     __ push(r4);
616
617     // Reload the number of arguments and the constructor from the stack.
618     // sp[0]: receiver
619     // sp[1]: receiver
620     // sp[2]: constructor function
621     // sp[3]: number of arguments (smi-tagged)
622     __ ldr(r1, MemOperand(sp, 2 * kPointerSize));
623     __ ldr(r3, MemOperand(sp, 3 * kPointerSize));
624
625     // Set up pointer to last argument.
626     __ add(r2, fp, Operand(StandardFrameConstants::kCallerSPOffset));
627
628     // Set up number of arguments for function call below
629     __ SmiUntag(r0, r3);
630
631     // Copy arguments and receiver to the expression stack.
632     // r0: number of arguments
633     // r1: constructor function
634     // r2: address of last argument (caller sp)
635     // r3: number of arguments (smi-tagged)
636     // sp[0]: receiver
637     // sp[1]: receiver
638     // sp[2]: constructor function
639     // sp[3]: number of arguments (smi-tagged)
640     Label loop, entry;
641     __ b(&entry);
642     __ bind(&loop);
643     __ ldr(ip, MemOperand(r2, r3, LSL, kPointerSizeLog2 - 1));
644     __ push(ip);
645     __ bind(&entry);
646     __ sub(r3, r3, Operand(2), SetCC);
647     __ b(ge, &loop);
648
649     // Call the function.
650     // r0: number of arguments
651     // r1: constructor function
652     if (is_api_function) {
653       __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
654       Handle<Code> code =
655           masm->isolate()->builtins()->HandleApiCallConstruct();
656       __ Call(code, RelocInfo::CODE_TARGET);
657     } else {
658       ParameterCount actual(r0);
659       __ InvokeFunction(r1, actual, CALL_FUNCTION, NullCallWrapper());
660     }
661
662     // Store offset of return address for deoptimizer.
663     if (!is_api_function) {
664       masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset());
665     }
666
667     // Restore context from the frame.
668     // r0: result
669     // sp[0]: receiver
670     // sp[1]: constructor function
671     // sp[2]: number of arguments (smi-tagged)
672     __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
673
674     // If the result is an object (in the ECMA sense), we should get rid
675     // of the receiver and use the result; see ECMA-262 section 13.2.2-7
676     // on page 74.
677     Label use_receiver, exit;
678
679     // If the result is a smi, it is *not* an object in the ECMA sense.
680     // r0: result
681     // sp[0]: receiver (newly allocated object)
682     // sp[1]: constructor function
683     // sp[2]: number of arguments (smi-tagged)
684     __ JumpIfSmi(r0, &use_receiver);
685
686     // If the type of the result (stored in its map) is less than
687     // FIRST_SPEC_OBJECT_TYPE, it is not an object in the ECMA sense.
688     __ CompareObjectType(r0, r1, r3, FIRST_SPEC_OBJECT_TYPE);
689     __ b(ge, &exit);
690
691     // Throw away the result of the constructor invocation and use the
692     // on-stack receiver as the result.
693     __ bind(&use_receiver);
694     __ ldr(r0, MemOperand(sp));
695
696     // Remove receiver from the stack, remove caller arguments, and
697     // return.
698     __ bind(&exit);
699     // r0: result
700     // sp[0]: receiver (newly allocated object)
701     // sp[1]: constructor function
702     // sp[2]: number of arguments (smi-tagged)
703     __ ldr(r1, MemOperand(sp, 2 * kPointerSize));
704
705     // Leave construct frame.
706   }
707
708   __ add(sp, sp, Operand(r1, LSL, kPointerSizeLog2 - 1));
709   __ add(sp, sp, Operand(kPointerSize));
710   __ IncrementCounter(isolate->counters()->constructed_objects(), 1, r1, r2);
711   __ Jump(lr);
712 }
713
714
715 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
716   Generate_JSConstructStubHelper(masm, false, FLAG_pretenuring_call_new);
717 }
718
719
720 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
721   Generate_JSConstructStubHelper(masm, true, false);
722 }
723
724
725 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
726                                              bool is_construct) {
727   // Called from Generate_JS_Entry
728   // r0: code entry
729   // r1: function
730   // r2: receiver
731   // r3: argc
732   // r4: argv
733   // r5-r6, r8 (if not FLAG_enable_ool_constant_pool) and cp may be clobbered
734   ProfileEntryHookStub::MaybeCallEntryHook(masm);
735
736   // Clear the context before we push it when entering the internal frame.
737   __ mov(cp, Operand::Zero());
738
739   // Enter an internal frame.
740   {
741     FrameScope scope(masm, StackFrame::INTERNAL);
742
743     // Set up the context from the function argument.
744     __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
745
746     __ InitializeRootRegister();
747
748     // Push the function and the receiver onto the stack.
749     __ push(r1);
750     __ push(r2);
751
752     // Copy arguments to the stack in a loop.
753     // r1: function
754     // r3: argc
755     // r4: argv, i.e. points to first arg
756     Label loop, entry;
757     __ add(r2, r4, Operand(r3, LSL, kPointerSizeLog2));
758     // r2 points past last arg.
759     __ b(&entry);
760     __ bind(&loop);
761     __ ldr(r0, MemOperand(r4, kPointerSize, PostIndex));  // read next parameter
762     __ ldr(r0, MemOperand(r0));  // dereference handle
763     __ push(r0);  // push parameter
764     __ bind(&entry);
765     __ cmp(r4, r2);
766     __ b(ne, &loop);
767
768     // Initialize all JavaScript callee-saved registers, since they will be seen
769     // by the garbage collector as part of handlers.
770     __ LoadRoot(r4, Heap::kUndefinedValueRootIndex);
771     __ mov(r5, Operand(r4));
772     __ mov(r6, Operand(r4));
773     if (!FLAG_enable_ool_constant_pool) {
774       __ mov(r8, Operand(r4));
775     }
776     if (kR9Available == 1) {
777       __ mov(r9, Operand(r4));
778     }
779
780     // Invoke the code and pass argc as r0.
781     __ mov(r0, Operand(r3));
782     if (is_construct) {
783       // No type feedback cell is available
784       __ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
785       CallConstructStub stub(masm->isolate(), NO_CALL_CONSTRUCTOR_FLAGS);
786       __ CallStub(&stub);
787     } else {
788       ParameterCount actual(r0);
789       __ InvokeFunction(r1, actual, CALL_FUNCTION, NullCallWrapper());
790     }
791     // Exit the JS frame and remove the parameters (except function), and
792     // return.
793     // Respect ABI stack constraint.
794   }
795   __ Jump(lr);
796
797   // r0: result
798 }
799
800
801 void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) {
802   Generate_JSEntryTrampolineHelper(masm, false);
803 }
804
805
806 void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) {
807   Generate_JSEntryTrampolineHelper(masm, true);
808 }
809
810
811 void Builtins::Generate_CompileUnoptimized(MacroAssembler* masm) {
812   CallRuntimePassFunction(masm, Runtime::kCompileUnoptimized);
813   GenerateTailCallToReturnedCode(masm);
814 }
815
816
817 static void CallCompileOptimized(MacroAssembler* masm, bool concurrent) {
818   FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
819   // Push a copy of the function onto the stack.
820   __ push(r1);
821   // Push function as parameter to the runtime call.
822   __ Push(r1);
823   // Whether to compile in a background thread.
824   __ Push(masm->isolate()->factory()->ToBoolean(concurrent));
825
826   __ CallRuntime(Runtime::kCompileOptimized, 2);
827   // Restore receiver.
828   __ pop(r1);
829 }
830
831
832 void Builtins::Generate_CompileOptimized(MacroAssembler* masm) {
833   CallCompileOptimized(masm, false);
834   GenerateTailCallToReturnedCode(masm);
835 }
836
837
838 void Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) {
839   CallCompileOptimized(masm, true);
840   GenerateTailCallToReturnedCode(masm);
841 }
842
843
844 static void GenerateMakeCodeYoungAgainCommon(MacroAssembler* masm) {
845   // For now, we are relying on the fact that make_code_young doesn't do any
846   // garbage collection which allows us to save/restore the registers without
847   // worrying about which of them contain pointers. We also don't build an
848   // internal frame to make the code faster, since we shouldn't have to do stack
849   // crawls in MakeCodeYoung. This seems a bit fragile.
850
851   // The following registers must be saved and restored when calling through to
852   // the runtime:
853   //   r0 - contains return address (beginning of patch sequence)
854   //   r1 - isolate
855   FrameScope scope(masm, StackFrame::MANUAL);
856   __ stm(db_w, sp, r0.bit() | r1.bit() | fp.bit() | lr.bit());
857   __ PrepareCallCFunction(2, 0, r2);
858   __ mov(r1, Operand(ExternalReference::isolate_address(masm->isolate())));
859   __ CallCFunction(
860       ExternalReference::get_make_code_young_function(masm->isolate()), 2);
861   __ ldm(ia_w, sp, r0.bit() | r1.bit() | fp.bit() | lr.bit());
862   __ mov(pc, r0);
863 }
864
865 #define DEFINE_CODE_AGE_BUILTIN_GENERATOR(C)                 \
866 void Builtins::Generate_Make##C##CodeYoungAgainEvenMarking(  \
867     MacroAssembler* masm) {                                  \
868   GenerateMakeCodeYoungAgainCommon(masm);                    \
869 }                                                            \
870 void Builtins::Generate_Make##C##CodeYoungAgainOddMarking(   \
871     MacroAssembler* masm) {                                  \
872   GenerateMakeCodeYoungAgainCommon(masm);                    \
873 }
874 CODE_AGE_LIST(DEFINE_CODE_AGE_BUILTIN_GENERATOR)
875 #undef DEFINE_CODE_AGE_BUILTIN_GENERATOR
876
877
878 void Builtins::Generate_MarkCodeAsExecutedOnce(MacroAssembler* masm) {
879   // For now, as in GenerateMakeCodeYoungAgainCommon, we are relying on the fact
880   // that make_code_young doesn't do any garbage collection which allows us to
881   // save/restore the registers without worrying about which of them contain
882   // pointers.
883
884   // The following registers must be saved and restored when calling through to
885   // the runtime:
886   //   r0 - contains return address (beginning of patch sequence)
887   //   r1 - isolate
888   FrameScope scope(masm, StackFrame::MANUAL);
889   __ stm(db_w, sp, r0.bit() | r1.bit() | fp.bit() | lr.bit());
890   __ PrepareCallCFunction(2, 0, r2);
891   __ mov(r1, Operand(ExternalReference::isolate_address(masm->isolate())));
892   __ CallCFunction(ExternalReference::get_mark_code_as_executed_function(
893         masm->isolate()), 2);
894   __ ldm(ia_w, sp, r0.bit() | r1.bit() | fp.bit() | lr.bit());
895
896   // Perform prologue operations usually performed by the young code stub.
897   __ PushFixedFrame(r1);
898   __ add(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
899
900   // Jump to point after the code-age stub.
901   __ add(r0, r0, Operand(kNoCodeAgeSequenceLength));
902   __ mov(pc, r0);
903 }
904
905
906 void Builtins::Generate_MarkCodeAsExecutedTwice(MacroAssembler* masm) {
907   GenerateMakeCodeYoungAgainCommon(masm);
908 }
909
910
911 static void Generate_NotifyStubFailureHelper(MacroAssembler* masm,
912                                              SaveFPRegsMode save_doubles) {
913   {
914     FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
915
916     // Preserve registers across notification, this is important for compiled
917     // stubs that tail call the runtime on deopts passing their parameters in
918     // registers.
919     __ stm(db_w, sp, kJSCallerSaved | kCalleeSaved);
920     // Pass the function and deoptimization type to the runtime system.
921     __ CallRuntime(Runtime::kNotifyStubFailure, 0, save_doubles);
922     __ ldm(ia_w, sp, kJSCallerSaved | kCalleeSaved);
923   }
924
925   __ add(sp, sp, Operand(kPointerSize));  // Ignore state
926   __ mov(pc, lr);  // Jump to miss handler
927 }
928
929
930 void Builtins::Generate_NotifyStubFailure(MacroAssembler* masm) {
931   Generate_NotifyStubFailureHelper(masm, kDontSaveFPRegs);
932 }
933
934
935 void Builtins::Generate_NotifyStubFailureSaveDoubles(MacroAssembler* masm) {
936   Generate_NotifyStubFailureHelper(masm, kSaveFPRegs);
937 }
938
939
940 static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm,
941                                              Deoptimizer::BailoutType type) {
942   {
943     FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
944     // Pass the function and deoptimization type to the runtime system.
945     __ mov(r0, Operand(Smi::FromInt(static_cast<int>(type))));
946     __ push(r0);
947     __ CallRuntime(Runtime::kNotifyDeoptimized, 1);
948   }
949
950   // Get the full codegen state from the stack and untag it -> r6.
951   __ ldr(r6, MemOperand(sp, 0 * kPointerSize));
952   __ SmiUntag(r6);
953   // Switch on the state.
954   Label with_tos_register, unknown_state;
955   __ cmp(r6, Operand(FullCodeGenerator::NO_REGISTERS));
956   __ b(ne, &with_tos_register);
957   __ add(sp, sp, Operand(1 * kPointerSize));  // Remove state.
958   __ Ret();
959
960   __ bind(&with_tos_register);
961   __ ldr(r0, MemOperand(sp, 1 * kPointerSize));
962   __ cmp(r6, Operand(FullCodeGenerator::TOS_REG));
963   __ b(ne, &unknown_state);
964   __ add(sp, sp, Operand(2 * kPointerSize));  // Remove state.
965   __ Ret();
966
967   __ bind(&unknown_state);
968   __ stop("no cases left");
969 }
970
971
972 void Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) {
973   Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::EAGER);
974 }
975
976
977 void Builtins::Generate_NotifySoftDeoptimized(MacroAssembler* masm) {
978   Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::SOFT);
979 }
980
981
982 void Builtins::Generate_NotifyLazyDeoptimized(MacroAssembler* masm) {
983   Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::LAZY);
984 }
985
986
987 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) {
988   // Lookup the function in the JavaScript frame.
989   __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
990   {
991     FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
992     // Pass function as argument.
993     __ push(r0);
994     __ CallRuntime(Runtime::kCompileForOnStackReplacement, 1);
995   }
996
997   // If the code object is null, just return to the unoptimized code.
998   Label skip;
999   __ cmp(r0, Operand(Smi::FromInt(0)));
1000   __ b(ne, &skip);
1001   __ Ret();
1002
1003   __ bind(&skip);
1004
1005   // Load deoptimization data from the code object.
1006   // <deopt_data> = <code>[#deoptimization_data_offset]
1007   __ ldr(r1, FieldMemOperand(r0, Code::kDeoptimizationDataOffset));
1008
1009   { ConstantPoolUnavailableScope constant_pool_unavailable(masm);
1010     if (FLAG_enable_ool_constant_pool) {
1011       __ ldr(pp, FieldMemOperand(r0, Code::kConstantPoolOffset));
1012     }
1013
1014     // Load the OSR entrypoint offset from the deoptimization data.
1015     // <osr_offset> = <deopt_data>[#header_size + #osr_pc_offset]
1016     __ ldr(r1, FieldMemOperand(r1, FixedArray::OffsetOfElementAt(
1017         DeoptimizationInputData::kOsrPcOffsetIndex)));
1018
1019     // Compute the target address = code_obj + header_size + osr_offset
1020     // <entry_addr> = <code_obj> + #header_size + <osr_offset>
1021     __ add(r0, r0, Operand::SmiUntag(r1));
1022     __ add(lr, r0, Operand(Code::kHeaderSize - kHeapObjectTag));
1023
1024     // And "return" to the OSR entry point of the function.
1025     __ Ret();
1026   }
1027 }
1028
1029
1030 void Builtins::Generate_OsrAfterStackCheck(MacroAssembler* masm) {
1031   // We check the stack limit as indicator that recompilation might be done.
1032   Label ok;
1033   __ LoadRoot(ip, Heap::kStackLimitRootIndex);
1034   __ cmp(sp, Operand(ip));
1035   __ b(hs, &ok);
1036   {
1037     FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
1038     __ CallRuntime(Runtime::kStackGuard, 0);
1039   }
1040   __ Jump(masm->isolate()->builtins()->OnStackReplacement(),
1041           RelocInfo::CODE_TARGET);
1042
1043   __ bind(&ok);
1044   __ Ret();
1045 }
1046
1047
1048 void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
1049   // 1. Make sure we have at least one argument.
1050   // r0: actual number of arguments
1051   { Label done;
1052     __ cmp(r0, Operand::Zero());
1053     __ b(ne, &done);
1054     __ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
1055     __ push(r2);
1056     __ add(r0, r0, Operand(1));
1057     __ bind(&done);
1058   }
1059
1060   // 2. Get the function to call (passed as receiver) from the stack, check
1061   //    if it is a function.
1062   // r0: actual number of arguments
1063   Label slow, non_function;
1064   __ ldr(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2));
1065   __ JumpIfSmi(r1, &non_function);
1066   __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE);
1067   __ b(ne, &slow);
1068
1069   // 3a. Patch the first argument if necessary when calling a function.
1070   // r0: actual number of arguments
1071   // r1: function
1072   Label shift_arguments;
1073   __ mov(r4, Operand::Zero());  // indicate regular JS_FUNCTION
1074   { Label convert_to_object, use_global_proxy, patch_receiver;
1075     // Change context eagerly in case we need the global receiver.
1076     __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
1077
1078     // Do not transform the receiver for strict mode functions.
1079     __ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
1080     __ ldr(r3, FieldMemOperand(r2, SharedFunctionInfo::kCompilerHintsOffset));
1081     __ tst(r3, Operand(1 << (SharedFunctionInfo::kStrictModeFunction +
1082                              kSmiTagSize)));
1083     __ b(ne, &shift_arguments);
1084
1085     // Do not transform the receiver for native (Compilerhints already in r3).
1086     __ tst(r3, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize)));
1087     __ b(ne, &shift_arguments);
1088
1089     // Compute the receiver in sloppy mode.
1090     __ add(r2, sp, Operand(r0, LSL, kPointerSizeLog2));
1091     __ ldr(r2, MemOperand(r2, -kPointerSize));
1092     // r0: actual number of arguments
1093     // r1: function
1094     // r2: first argument
1095     __ JumpIfSmi(r2, &convert_to_object);
1096
1097     __ LoadRoot(r3, Heap::kUndefinedValueRootIndex);
1098     __ cmp(r2, r3);
1099     __ b(eq, &use_global_proxy);
1100     __ LoadRoot(r3, Heap::kNullValueRootIndex);
1101     __ cmp(r2, r3);
1102     __ b(eq, &use_global_proxy);
1103
1104     STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE);
1105     __ CompareObjectType(r2, r3, r3, FIRST_SPEC_OBJECT_TYPE);
1106     __ b(ge, &shift_arguments);
1107
1108     __ bind(&convert_to_object);
1109
1110     {
1111       // Enter an internal frame in order to preserve argument count.
1112       FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
1113       __ SmiTag(r0);
1114       __ push(r0);
1115
1116       __ push(r2);
1117       __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
1118       __ mov(r2, r0);
1119
1120       __ pop(r0);
1121       __ SmiUntag(r0);
1122
1123       // Exit the internal frame.
1124     }
1125
1126     // Restore the function to r1, and the flag to r4.
1127     __ ldr(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2));
1128     __ mov(r4, Operand::Zero());
1129     __ jmp(&patch_receiver);
1130
1131     __ bind(&use_global_proxy);
1132   __ ldr(r2, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX));
1133   __ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalProxyOffset));
1134
1135     __ bind(&patch_receiver);
1136     __ add(r3, sp, Operand(r0, LSL, kPointerSizeLog2));
1137     __ str(r2, MemOperand(r3, -kPointerSize));
1138
1139     __ jmp(&shift_arguments);
1140   }
1141
1142   // 3b. Check for function proxy.
1143   __ bind(&slow);
1144   __ mov(r4, Operand(1, RelocInfo::NONE32));  // indicate function proxy
1145   __ cmp(r2, Operand(JS_FUNCTION_PROXY_TYPE));
1146   __ b(eq, &shift_arguments);
1147   __ bind(&non_function);
1148   __ mov(r4, Operand(2, RelocInfo::NONE32));  // indicate non-function
1149
1150   // 3c. Patch the first argument when calling a non-function.  The
1151   //     CALL_NON_FUNCTION builtin expects the non-function callee as
1152   //     receiver, so overwrite the first argument which will ultimately
1153   //     become the receiver.
1154   // r0: actual number of arguments
1155   // r1: function
1156   // r4: call type (0: JS function, 1: function proxy, 2: non-function)
1157   __ add(r2, sp, Operand(r0, LSL, kPointerSizeLog2));
1158   __ str(r1, MemOperand(r2, -kPointerSize));
1159
1160   // 4. Shift arguments and return address one slot down on the stack
1161   //    (overwriting the original receiver).  Adjust argument count to make
1162   //    the original first argument the new receiver.
1163   // r0: actual number of arguments
1164   // r1: function
1165   // r4: call type (0: JS function, 1: function proxy, 2: non-function)
1166   __ bind(&shift_arguments);
1167   { Label loop;
1168     // Calculate the copy start address (destination). Copy end address is sp.
1169     __ add(r2, sp, Operand(r0, LSL, kPointerSizeLog2));
1170
1171     __ bind(&loop);
1172     __ ldr(ip, MemOperand(r2, -kPointerSize));
1173     __ str(ip, MemOperand(r2));
1174     __ sub(r2, r2, Operand(kPointerSize));
1175     __ cmp(r2, sp);
1176     __ b(ne, &loop);
1177     // Adjust the actual number of arguments and remove the top element
1178     // (which is a copy of the last argument).
1179     __ sub(r0, r0, Operand(1));
1180     __ pop();
1181   }
1182
1183   // 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin,
1184   //     or a function proxy via CALL_FUNCTION_PROXY.
1185   // r0: actual number of arguments
1186   // r1: function
1187   // r4: call type (0: JS function, 1: function proxy, 2: non-function)
1188   { Label function, non_proxy;
1189     __ tst(r4, r4);
1190     __ b(eq, &function);
1191     // Expected number of arguments is 0 for CALL_NON_FUNCTION.
1192     __ mov(r2, Operand::Zero());
1193     __ cmp(r4, Operand(1));
1194     __ b(ne, &non_proxy);
1195
1196     __ push(r1);  // re-add proxy object as additional argument
1197     __ add(r0, r0, Operand(1));
1198     __ GetBuiltinFunction(r1, Builtins::CALL_FUNCTION_PROXY);
1199     __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
1200             RelocInfo::CODE_TARGET);
1201
1202     __ bind(&non_proxy);
1203     __ GetBuiltinFunction(r1, Builtins::CALL_NON_FUNCTION);
1204     __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
1205             RelocInfo::CODE_TARGET);
1206     __ bind(&function);
1207   }
1208
1209   // 5b. Get the code to call from the function and check that the number of
1210   //     expected arguments matches what we're providing.  If so, jump
1211   //     (tail-call) to the code in register edx without checking arguments.
1212   // r0: actual number of arguments
1213   // r1: function
1214   __ ldr(r3, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
1215   __ ldr(r2,
1216          FieldMemOperand(r3, SharedFunctionInfo::kFormalParameterCountOffset));
1217   __ SmiUntag(r2);
1218   __ cmp(r2, r0);  // Check formal and actual parameter counts.
1219   __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
1220           RelocInfo::CODE_TARGET,
1221           ne);
1222
1223   __ ldr(r3, FieldMemOperand(r1, JSFunction::kCodeEntryOffset));
1224   ParameterCount expected(0);
1225   __ InvokeCode(r3, expected, expected, JUMP_FUNCTION, NullCallWrapper());
1226 }
1227
1228
1229 void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
1230   const int kIndexOffset    =
1231       StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize);
1232   const int kLimitOffset    =
1233       StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize);
1234   const int kArgsOffset     = 2 * kPointerSize;
1235   const int kRecvOffset     = 3 * kPointerSize;
1236   const int kFunctionOffset = 4 * kPointerSize;
1237
1238   {
1239     FrameAndConstantPoolScope frame_scope(masm, StackFrame::INTERNAL);
1240
1241     __ ldr(r0, MemOperand(fp, kFunctionOffset));  // get the function
1242     __ push(r0);
1243     __ ldr(r0, MemOperand(fp, kArgsOffset));  // get the args array
1244     __ push(r0);
1245     __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION);
1246
1247     // Check the stack for overflow. We are not trying to catch
1248     // interruptions (e.g. debug break and preemption) here, so the "real stack
1249     // limit" is checked.
1250     Label okay;
1251     __ LoadRoot(r2, Heap::kRealStackLimitRootIndex);
1252     // Make r2 the space we have left. The stack might already be overflowed
1253     // here which will cause r2 to become negative.
1254     __ sub(r2, sp, r2);
1255     // Check if the arguments will overflow the stack.
1256     __ cmp(r2, Operand::PointerOffsetFromSmiKey(r0));
1257     __ b(gt, &okay);  // Signed comparison.
1258
1259     // Out of stack space.
1260     __ ldr(r1, MemOperand(fp, kFunctionOffset));
1261     __ Push(r1, r0);
1262     __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
1263     // End of stack check.
1264
1265     // Push current limit and index.
1266     __ bind(&okay);
1267     __ push(r0);  // limit
1268     __ mov(r1, Operand::Zero());  // initial index
1269     __ push(r1);
1270
1271     // Get the receiver.
1272     __ ldr(r0, MemOperand(fp, kRecvOffset));
1273
1274     // Check that the function is a JS function (otherwise it must be a proxy).
1275     Label push_receiver;
1276     __ ldr(r1, MemOperand(fp, kFunctionOffset));
1277     __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE);
1278     __ b(ne, &push_receiver);
1279
1280     // Change context eagerly to get the right global object if necessary.
1281     __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
1282     // Load the shared function info while the function is still in r1.
1283     __ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
1284
1285     // Compute the receiver.
1286     // Do not transform the receiver for strict mode functions.
1287     Label call_to_object, use_global_proxy;
1288     __ ldr(r2, FieldMemOperand(r2, SharedFunctionInfo::kCompilerHintsOffset));
1289     __ tst(r2, Operand(1 << (SharedFunctionInfo::kStrictModeFunction +
1290                              kSmiTagSize)));
1291     __ b(ne, &push_receiver);
1292
1293     // Do not transform the receiver for strict mode functions.
1294     __ tst(r2, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize)));
1295     __ b(ne, &push_receiver);
1296
1297     // Compute the receiver in sloppy mode.
1298     __ JumpIfSmi(r0, &call_to_object);
1299     __ LoadRoot(r1, Heap::kNullValueRootIndex);
1300     __ cmp(r0, r1);
1301     __ b(eq, &use_global_proxy);
1302     __ LoadRoot(r1, Heap::kUndefinedValueRootIndex);
1303     __ cmp(r0, r1);
1304     __ b(eq, &use_global_proxy);
1305
1306     // Check if the receiver is already a JavaScript object.
1307     // r0: receiver
1308     STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE);
1309     __ CompareObjectType(r0, r1, r1, FIRST_SPEC_OBJECT_TYPE);
1310     __ b(ge, &push_receiver);
1311
1312     // Convert the receiver to a regular object.
1313     // r0: receiver
1314     __ bind(&call_to_object);
1315     __ push(r0);
1316     __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
1317     __ b(&push_receiver);
1318
1319     __ bind(&use_global_proxy);
1320     __ ldr(r0, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX));
1321     __ ldr(r0, FieldMemOperand(r0, GlobalObject::kGlobalProxyOffset));
1322
1323     // Push the receiver.
1324     // r0: receiver
1325     __ bind(&push_receiver);
1326     __ push(r0);
1327
1328     // Copy all arguments from the array to the stack.
1329     Label entry, loop;
1330     __ ldr(r0, MemOperand(fp, kIndexOffset));
1331     __ b(&entry);
1332
1333     // Load the current argument from the arguments array and push it to the
1334     // stack.
1335     // r0: current argument index
1336     __ bind(&loop);
1337     __ ldr(r1, MemOperand(fp, kArgsOffset));
1338     __ Push(r1, r0);
1339
1340     // Call the runtime to access the property in the arguments array.
1341     __ CallRuntime(Runtime::kGetProperty, 2);
1342     __ push(r0);
1343
1344     // Use inline caching to access the arguments.
1345     __ ldr(r0, MemOperand(fp, kIndexOffset));
1346     __ add(r0, r0, Operand(1 << kSmiTagSize));
1347     __ str(r0, MemOperand(fp, kIndexOffset));
1348
1349     // Test if the copy loop has finished copying all the elements from the
1350     // arguments object.
1351     __ bind(&entry);
1352     __ ldr(r1, MemOperand(fp, kLimitOffset));
1353     __ cmp(r0, r1);
1354     __ b(ne, &loop);
1355
1356     // Call the function.
1357     Label call_proxy;
1358     ParameterCount actual(r0);
1359     __ SmiUntag(r0);
1360     __ ldr(r1, MemOperand(fp, kFunctionOffset));
1361     __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE);
1362     __ b(ne, &call_proxy);
1363     __ InvokeFunction(r1, actual, CALL_FUNCTION, NullCallWrapper());
1364
1365     frame_scope.GenerateLeaveFrame();
1366     __ add(sp, sp, Operand(3 * kPointerSize));
1367     __ Jump(lr);
1368
1369     // Call the function proxy.
1370     __ bind(&call_proxy);
1371     __ push(r1);  // add function proxy as last argument
1372     __ add(r0, r0, Operand(1));
1373     __ mov(r2, Operand::Zero());
1374     __ GetBuiltinFunction(r1, Builtins::CALL_FUNCTION_PROXY);
1375     __ Call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
1376             RelocInfo::CODE_TARGET);
1377
1378     // Tear down the internal frame and remove function, receiver and args.
1379   }
1380   __ add(sp, sp, Operand(3 * kPointerSize));
1381   __ Jump(lr);
1382 }
1383
1384
1385 static void ArgumentAdaptorStackCheck(MacroAssembler* masm,
1386                                       Label* stack_overflow) {
1387   // ----------- S t a t e -------------
1388   //  -- r0 : actual number of arguments
1389   //  -- r1 : function (passed through to callee)
1390   //  -- r2 : expected number of arguments
1391   // -----------------------------------
1392   // Check the stack for overflow. We are not trying to catch
1393   // interruptions (e.g. debug break and preemption) here, so the "real stack
1394   // limit" is checked.
1395   __ LoadRoot(r5, Heap::kRealStackLimitRootIndex);
1396   // Make r5 the space we have left. The stack might already be overflowed
1397   // here which will cause r5 to become negative.
1398   __ sub(r5, sp, r5);
1399   // Check if the arguments will overflow the stack.
1400   __ cmp(r5, Operand(r2, LSL, kPointerSizeLog2));
1401   __ b(le, stack_overflow);  // Signed comparison.
1402 }
1403
1404
1405 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
1406   __ SmiTag(r0);
1407   __ mov(r4, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
1408   __ stm(db_w, sp, r0.bit() | r1.bit() | r4.bit() |
1409                    (FLAG_enable_ool_constant_pool ? pp.bit() : 0) |
1410                    fp.bit() | lr.bit());
1411   __ add(fp, sp,
1412          Operand(StandardFrameConstants::kFixedFrameSizeFromFp + kPointerSize));
1413 }
1414
1415
1416 static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) {
1417   // ----------- S t a t e -------------
1418   //  -- r0 : result being passed through
1419   // -----------------------------------
1420   // Get the number of arguments passed (as a smi), tear down the frame and
1421   // then tear down the parameters.
1422   __ ldr(r1, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp +
1423                               kPointerSize)));
1424
1425   if (FLAG_enable_ool_constant_pool) {
1426     __ add(sp, fp, Operand(StandardFrameConstants::kConstantPoolOffset));
1427     __ ldm(ia_w, sp, pp.bit() | fp.bit() | lr.bit());
1428   } else {
1429     __ mov(sp, fp);;
1430     __ ldm(ia_w, sp, fp.bit() | lr.bit());
1431   }
1432   __ add(sp, sp, Operand::PointerOffsetFromSmiKey(r1));
1433   __ add(sp, sp, Operand(kPointerSize));  // adjust for receiver
1434 }
1435
1436
1437 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
1438   // ----------- S t a t e -------------
1439   //  -- r0 : actual number of arguments
1440   //  -- r1 : function (passed through to callee)
1441   //  -- r2 : expected number of arguments
1442   // -----------------------------------
1443
1444   Label stack_overflow;
1445   ArgumentAdaptorStackCheck(masm, &stack_overflow);
1446   Label invoke, dont_adapt_arguments;
1447
1448   Label enough, too_few;
1449   __ ldr(r3, FieldMemOperand(r1, JSFunction::kCodeEntryOffset));
1450   __ cmp(r0, r2);
1451   __ b(lt, &too_few);
1452   __ cmp(r2, Operand(SharedFunctionInfo::kDontAdaptArgumentsSentinel));
1453   __ b(eq, &dont_adapt_arguments);
1454
1455   {  // Enough parameters: actual >= expected
1456     __ bind(&enough);
1457     EnterArgumentsAdaptorFrame(masm);
1458
1459     // Calculate copy start address into r0 and copy end address into r2.
1460     // r0: actual number of arguments as a smi
1461     // r1: function
1462     // r2: expected number of arguments
1463     // r3: code entry to call
1464     __ add(r0, fp, Operand::PointerOffsetFromSmiKey(r0));
1465     // adjust for return address and receiver
1466     __ add(r0, r0, Operand(2 * kPointerSize));
1467     __ sub(r2, r0, Operand(r2, LSL, kPointerSizeLog2));
1468
1469     // Copy the arguments (including the receiver) to the new stack frame.
1470     // r0: copy start address
1471     // r1: function
1472     // r2: copy end address
1473     // r3: code entry to call
1474
1475     Label copy;
1476     __ bind(&copy);
1477     __ ldr(ip, MemOperand(r0, 0));
1478     __ push(ip);
1479     __ cmp(r0, r2);  // Compare before moving to next argument.
1480     __ sub(r0, r0, Operand(kPointerSize));
1481     __ b(ne, &copy);
1482
1483     __ b(&invoke);
1484   }
1485
1486   {  // Too few parameters: Actual < expected
1487     __ bind(&too_few);
1488     EnterArgumentsAdaptorFrame(masm);
1489
1490     // Calculate copy start address into r0 and copy end address is fp.
1491     // r0: actual number of arguments as a smi
1492     // r1: function
1493     // r2: expected number of arguments
1494     // r3: code entry to call
1495     __ add(r0, fp, Operand::PointerOffsetFromSmiKey(r0));
1496
1497     // Copy the arguments (including the receiver) to the new stack frame.
1498     // r0: copy start address
1499     // r1: function
1500     // r2: expected number of arguments
1501     // r3: code entry to call
1502     Label copy;
1503     __ bind(&copy);
1504     // Adjust load for return address and receiver.
1505     __ ldr(ip, MemOperand(r0, 2 * kPointerSize));
1506     __ push(ip);
1507     __ cmp(r0, fp);  // Compare before moving to next argument.
1508     __ sub(r0, r0, Operand(kPointerSize));
1509     __ b(ne, &copy);
1510
1511     // Fill the remaining expected arguments with undefined.
1512     // r1: function
1513     // r2: expected number of arguments
1514     // r3: code entry to call
1515     __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
1516     __ sub(r2, fp, Operand(r2, LSL, kPointerSizeLog2));
1517     // Adjust for frame.
1518     __ sub(r2, r2, Operand(StandardFrameConstants::kFixedFrameSizeFromFp +
1519                            2 * kPointerSize));
1520
1521     Label fill;
1522     __ bind(&fill);
1523     __ push(ip);
1524     __ cmp(sp, r2);
1525     __ b(ne, &fill);
1526   }
1527
1528   // Call the entry point.
1529   __ bind(&invoke);
1530   __ Call(r3);
1531
1532   // Store offset of return address for deoptimizer.
1533   masm->isolate()->heap()->SetArgumentsAdaptorDeoptPCOffset(masm->pc_offset());
1534
1535   // Exit frame and return.
1536   LeaveArgumentsAdaptorFrame(masm);
1537   __ Jump(lr);
1538
1539
1540   // -------------------------------------------
1541   // Dont adapt arguments.
1542   // -------------------------------------------
1543   __ bind(&dont_adapt_arguments);
1544   __ Jump(r3);
1545
1546   __ bind(&stack_overflow);
1547   {
1548     FrameScope frame(masm, StackFrame::MANUAL);
1549     EnterArgumentsAdaptorFrame(masm);
1550     __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
1551     __ bkpt(0);
1552   }
1553 }
1554
1555
1556 #undef __
1557
1558 } }  // namespace v8::internal
1559
1560 #endif  // V8_TARGET_ARCH_ARM