| Index: src/a64/builtins-a64.cc | 
| diff --git a/src/a64/builtins-a64.cc b/src/a64/builtins-a64.cc | 
| deleted file mode 100644 | 
| index ec452da4795724fa9ef29cdf8acceb9871771e76..0000000000000000000000000000000000000000 | 
| --- a/src/a64/builtins-a64.cc | 
| +++ /dev/null | 
| @@ -1,1562 +0,0 @@ | 
| -// Copyright 2013 the V8 project authors. All rights reserved. | 
| -// Redistribution and use in source and binary forms, with or without | 
| -// modification, are permitted provided that the following conditions are | 
| -// met: | 
| -// | 
| -//     * Redistributions of source code must retain the above copyright | 
| -//       notice, this list of conditions and the following disclaimer. | 
| -//     * Redistributions in binary form must reproduce the above | 
| -//       copyright notice, this list of conditions and the following | 
| -//       disclaimer in the documentation and/or other materials provided | 
| -//       with the distribution. | 
| -//     * Neither the name of Google Inc. nor the names of its | 
| -//       contributors may be used to endorse or promote products derived | 
| -//       from this software without specific prior written permission. | 
| -// | 
| -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 
| -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 
| -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 
| -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 
| -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 
| -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 
| -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 
| -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 
| -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 
| -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 
| -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
| - | 
| -#include "v8.h" | 
| - | 
| -#if V8_TARGET_ARCH_A64 | 
| - | 
| -#include "codegen.h" | 
| -#include "debug.h" | 
| -#include "deoptimizer.h" | 
| -#include "full-codegen.h" | 
| -#include "runtime.h" | 
| -#include "stub-cache.h" | 
| - | 
| -namespace v8 { | 
| -namespace internal { | 
| - | 
| - | 
| -#define __ ACCESS_MASM(masm) | 
| - | 
| - | 
| -// Load the built-in Array function from the current context. | 
| -static void GenerateLoadArrayFunction(MacroAssembler* masm, Register result) { | 
| -  // Load the native context. | 
| -  __ Ldr(result, GlobalObjectMemOperand()); | 
| -  __ Ldr(result, | 
| -         FieldMemOperand(result, GlobalObject::kNativeContextOffset)); | 
| -  // Load the InternalArray function from the native context. | 
| -  __ Ldr(result, | 
| -         MemOperand(result, | 
| -                    Context::SlotOffset(Context::ARRAY_FUNCTION_INDEX))); | 
| -} | 
| - | 
| - | 
| -// Load the built-in InternalArray function from the current context. | 
| -static void GenerateLoadInternalArrayFunction(MacroAssembler* masm, | 
| -                                              Register result) { | 
| -  // Load the native context. | 
| -  __ Ldr(result, GlobalObjectMemOperand()); | 
| -  __ Ldr(result, | 
| -         FieldMemOperand(result, GlobalObject::kNativeContextOffset)); | 
| -  // Load the InternalArray function from the native context. | 
| -  __ Ldr(result, ContextMemOperand(result, | 
| -                                   Context::INTERNAL_ARRAY_FUNCTION_INDEX)); | 
| -} | 
| - | 
| - | 
| -void Builtins::Generate_Adaptor(MacroAssembler* masm, | 
| -                                CFunctionId id, | 
| -                                BuiltinExtraArguments extra_args) { | 
| -  // ----------- S t a t e ------------- | 
| -  //  -- x0                 : number of arguments excluding receiver | 
| -  //  -- x1                 : called function (only guaranteed when | 
| -  //                          extra_args requires it) | 
| -  //  -- cp                 : context | 
| -  //  -- sp[0]              : last argument | 
| -  //  -- ... | 
| -  //  -- sp[4 * (argc - 1)] : first argument (argc == x0) | 
| -  //  -- sp[4 * argc]       : receiver | 
| -  // ----------------------------------- | 
| - | 
| -  // Insert extra arguments. | 
| -  int num_extra_args = 0; | 
| -  if (extra_args == NEEDS_CALLED_FUNCTION) { | 
| -    num_extra_args = 1; | 
| -    __ Push(x1); | 
| -  } else { | 
| -    ASSERT(extra_args == NO_EXTRA_ARGUMENTS); | 
| -  } | 
| - | 
| -  // JumpToExternalReference expects x0 to contain the number of arguments | 
| -  // including the receiver and the extra arguments. | 
| -  __ Add(x0, x0, num_extra_args + 1); | 
| -  __ JumpToExternalReference(ExternalReference(id, masm->isolate())); | 
| -} | 
| - | 
| - | 
| -void Builtins::Generate_InternalArrayCode(MacroAssembler* masm) { | 
| -  // ----------- S t a t e ------------- | 
| -  //  -- x0     : number of arguments | 
| -  //  -- lr     : return address | 
| -  //  -- sp[...]: constructor arguments | 
| -  // ----------------------------------- | 
| -  ASM_LOCATION("Builtins::Generate_InternalArrayCode"); | 
| -  Label generic_array_code; | 
| - | 
| -  // Get the InternalArray function. | 
| -  GenerateLoadInternalArrayFunction(masm, x1); | 
| - | 
| -  if (FLAG_debug_code) { | 
| -    // Initial map for the builtin InternalArray functions should be maps. | 
| -    __ Ldr(x10, FieldMemOperand(x1, JSFunction::kPrototypeOrInitialMapOffset)); | 
| -    __ Tst(x10, kSmiTagMask); | 
| -    __ Assert(ne, kUnexpectedInitialMapForInternalArrayFunction); | 
| -    __ CompareObjectType(x10, x11, x12, MAP_TYPE); | 
| -    __ Assert(eq, kUnexpectedInitialMapForInternalArrayFunction); | 
| -  } | 
| - | 
| -  // Run the native code for the InternalArray function called as a normal | 
| -  // function. | 
| -  InternalArrayConstructorStub stub(masm->isolate()); | 
| -  __ TailCallStub(&stub); | 
| -} | 
| - | 
| - | 
| -void Builtins::Generate_ArrayCode(MacroAssembler* masm) { | 
| -  // ----------- S t a t e ------------- | 
| -  //  -- x0     : number of arguments | 
| -  //  -- lr     : return address | 
| -  //  -- sp[...]: constructor arguments | 
| -  // ----------------------------------- | 
| -  ASM_LOCATION("Builtins::Generate_ArrayCode"); | 
| -  Label generic_array_code, one_or_more_arguments, two_or_more_arguments; | 
| - | 
| -  // Get the Array function. | 
| -  GenerateLoadArrayFunction(masm, x1); | 
| - | 
| -  if (FLAG_debug_code) { | 
| -    // Initial map for the builtin Array functions should be maps. | 
| -    __ Ldr(x10, FieldMemOperand(x1, JSFunction::kPrototypeOrInitialMapOffset)); | 
| -    __ Tst(x10, kSmiTagMask); | 
| -    __ Assert(ne, kUnexpectedInitialMapForArrayFunction); | 
| -    __ CompareObjectType(x10, x11, x12, MAP_TYPE); | 
| -    __ Assert(eq, kUnexpectedInitialMapForArrayFunction); | 
| -  } | 
| - | 
| -  // Run the native code for the Array function called as a normal function. | 
| -  __ LoadRoot(x2, Heap::kUndefinedValueRootIndex); | 
| -  ArrayConstructorStub stub(masm->isolate()); | 
| -  __ TailCallStub(&stub); | 
| -} | 
| - | 
| - | 
| -void Builtins::Generate_StringConstructCode(MacroAssembler* masm) { | 
| -  // ----------- S t a t e ------------- | 
| -  //  -- x0                     : number of arguments | 
| -  //  -- x1                     : constructor function | 
| -  //  -- lr                     : return address | 
| -  //  -- sp[(argc - n - 1) * 8] : arg[n] (zero based) | 
| -  //  -- sp[argc * 8]           : receiver | 
| -  // ----------------------------------- | 
| -  ASM_LOCATION("Builtins::Generate_StringConstructCode"); | 
| -  Counters* counters = masm->isolate()->counters(); | 
| -  __ IncrementCounter(counters->string_ctor_calls(), 1, x10, x11); | 
| - | 
| -  Register argc = x0; | 
| -  Register function = x1; | 
| -  if (FLAG_debug_code) { | 
| -    __ LoadGlobalFunction(Context::STRING_FUNCTION_INDEX, x10); | 
| -    __ Cmp(function, x10); | 
| -    __ Assert(eq, kUnexpectedStringFunction); | 
| -  } | 
| - | 
| -  // Load the first arguments in x0 and get rid of the rest. | 
| -  Label no_arguments; | 
| -  __ Cbz(argc, &no_arguments); | 
| -  // First args = sp[(argc - 1) * 8]. | 
| -  __ Sub(argc, argc, 1); | 
| -  __ Claim(argc, kXRegSize); | 
| -  // jssp now point to args[0], load and drop args[0] + receiver. | 
| -  Register arg = argc; | 
| -  __ Ldr(arg, MemOperand(jssp, 2 * kPointerSize, PostIndex)); | 
| -  argc = NoReg; | 
| - | 
| -  Register argument = x2; | 
| -  Label not_cached, argument_is_string; | 
| -  __ LookupNumberStringCache(arg,        // Input. | 
| -                             argument,   // Result. | 
| -                             x10,        // Scratch. | 
| -                             x11,        // Scratch. | 
| -                             x12,        // Scratch. | 
| -                             ¬_cached); | 
| -  __ IncrementCounter(counters->string_ctor_cached_number(), 1, x10, x11); | 
| -  __ Bind(&argument_is_string); | 
| - | 
| -  // ----------- S t a t e ------------- | 
| -  //  -- x2     : argument converted to string | 
| -  //  -- x1     : constructor function | 
| -  //  -- lr     : return address | 
| -  // ----------------------------------- | 
| - | 
| -  Label gc_required; | 
| -  Register new_obj = x0; | 
| -  __ Allocate(JSValue::kSize, new_obj, x10, x11, &gc_required, TAG_OBJECT); | 
| - | 
| -  // Initialize the String object. | 
| -  Register map = x3; | 
| -  __ LoadGlobalFunctionInitialMap(function, map, x10); | 
| -  if (FLAG_debug_code) { | 
| -    __ Ldrb(x4, FieldMemOperand(map, Map::kInstanceSizeOffset)); | 
| -    __ Cmp(x4, JSValue::kSize >> kPointerSizeLog2); | 
| -    __ Assert(eq, kUnexpectedStringWrapperInstanceSize); | 
| -    __ Ldrb(x4, FieldMemOperand(map, Map::kUnusedPropertyFieldsOffset)); | 
| -    __ Cmp(x4, 0); | 
| -    __ Assert(eq, kUnexpectedUnusedPropertiesOfStringWrapper); | 
| -  } | 
| -  __ Str(map, FieldMemOperand(new_obj, HeapObject::kMapOffset)); | 
| - | 
| -  Register empty = x3; | 
| -  __ LoadRoot(empty, Heap::kEmptyFixedArrayRootIndex); | 
| -  __ Str(empty, FieldMemOperand(new_obj, JSObject::kPropertiesOffset)); | 
| -  __ Str(empty, FieldMemOperand(new_obj, JSObject::kElementsOffset)); | 
| - | 
| -  __ Str(argument, FieldMemOperand(new_obj, JSValue::kValueOffset)); | 
| - | 
| -  // Ensure the object is fully initialized. | 
| -  STATIC_ASSERT(JSValue::kSize == (4 * kPointerSize)); | 
| - | 
| -  __ Ret(); | 
| - | 
| -  // The argument was not found in the number to string cache. Check | 
| -  // if it's a string already before calling the conversion builtin. | 
| -  Label convert_argument; | 
| -  __ Bind(¬_cached); | 
| -  __ JumpIfSmi(arg, &convert_argument); | 
| - | 
| -  // Is it a String? | 
| -  __ Ldr(x10, FieldMemOperand(x0, HeapObject::kMapOffset)); | 
| -  __ Ldrb(x11, FieldMemOperand(x10, Map::kInstanceTypeOffset)); | 
| -  __ Tbnz(x11, MaskToBit(kIsNotStringMask), &convert_argument); | 
| -  __ Mov(argument, arg); | 
| -  __ IncrementCounter(counters->string_ctor_string_value(), 1, x10, x11); | 
| -  __ B(&argument_is_string); | 
| - | 
| -  // Invoke the conversion builtin and put the result into x2. | 
| -  __ Bind(&convert_argument); | 
| -  __ Push(function);  // Preserve the function. | 
| -  __ IncrementCounter(counters->string_ctor_conversions(), 1, x10, x11); | 
| -  { | 
| -    FrameScope scope(masm, StackFrame::INTERNAL); | 
| -    __ Push(arg); | 
| -    __ InvokeBuiltin(Builtins::TO_STRING, CALL_FUNCTION); | 
| -  } | 
| -  __ Pop(function); | 
| -  __ Mov(argument, x0); | 
| -  __ B(&argument_is_string); | 
| - | 
| -  // Load the empty string into x2, remove the receiver from the | 
| -  // stack, and jump back to the case where the argument is a string. | 
| -  __ Bind(&no_arguments); | 
| -  __ LoadRoot(argument, Heap::kempty_stringRootIndex); | 
| -  __ Drop(1); | 
| -  __ B(&argument_is_string); | 
| - | 
| -  // At this point the argument is already a string. Call runtime to create a | 
| -  // string wrapper. | 
| -  __ Bind(&gc_required); | 
| -  __ IncrementCounter(counters->string_ctor_gc_required(), 1, x10, x11); | 
| -  { | 
| -    FrameScope scope(masm, StackFrame::INTERNAL); | 
| -    __ Push(argument); | 
| -    __ CallRuntime(Runtime::kNewStringWrapper, 1); | 
| -  } | 
| -  __ Ret(); | 
| -} | 
| - | 
| - | 
| -static void CallRuntimePassFunction(MacroAssembler* masm, | 
| -                                    Runtime::FunctionId function_id) { | 
| -  FrameScope scope(masm, StackFrame::INTERNAL); | 
| -  //   - Push a copy of the function onto the stack. | 
| -  //   - Push another copy as a parameter to the runtime call. | 
| -  __ Push(x1, x1); | 
| - | 
| -  __ CallRuntime(function_id, 1); | 
| - | 
| -  //   - Restore receiver. | 
| -  __ Pop(x1); | 
| -} | 
| - | 
| - | 
| -static void GenerateTailCallToSharedCode(MacroAssembler* masm) { | 
| -  __ Ldr(x2, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset)); | 
| -  __ Ldr(x2, FieldMemOperand(x2, SharedFunctionInfo::kCodeOffset)); | 
| -  __ Add(x2, x2, Code::kHeaderSize - kHeapObjectTag); | 
| -  __ Br(x2); | 
| -} | 
| - | 
| - | 
| -static void GenerateTailCallToReturnedCode(MacroAssembler* masm) { | 
| -  __ Add(x0, x0, Code::kHeaderSize - kHeapObjectTag); | 
| -  __ Br(x0); | 
| -} | 
| - | 
| - | 
| -void Builtins::Generate_InOptimizationQueue(MacroAssembler* masm) { | 
| -  // Checking whether the queued function is ready for install is optional, | 
| -  // since we come across interrupts and stack checks elsewhere. However, not | 
| -  // checking may delay installing ready functions, and always checking would be | 
| -  // quite expensive. A good compromise is to first check against stack limit as | 
| -  // a cue for an interrupt signal. | 
| -  Label ok; | 
| -  __ CompareRoot(masm->StackPointer(), Heap::kStackLimitRootIndex); | 
| -  __ B(hs, &ok); | 
| - | 
| -  CallRuntimePassFunction(masm, Runtime::kTryInstallOptimizedCode); | 
| -  GenerateTailCallToReturnedCode(masm); | 
| - | 
| -  __ Bind(&ok); | 
| -  GenerateTailCallToSharedCode(masm); | 
| -} | 
| - | 
| - | 
| -static void Generate_JSConstructStubHelper(MacroAssembler* masm, | 
| -                                           bool is_api_function, | 
| -                                           bool count_constructions, | 
| -                                           bool create_memento) { | 
| -  // ----------- S t a t e ------------- | 
| -  //  -- x0     : number of arguments | 
| -  //  -- x1     : constructor function | 
| -  //  -- x2     : allocation site or undefined | 
| -  //  -- lr     : return address | 
| -  //  -- sp[...]: constructor arguments | 
| -  // ----------------------------------- | 
| - | 
| -  ASM_LOCATION("Builtins::Generate_JSConstructStubHelper"); | 
| -  // Should never count constructions for api objects. | 
| -  ASSERT(!is_api_function || !count_constructions); | 
| -  // Should never create mementos for api functions. | 
| -  ASSERT(!is_api_function || !create_memento); | 
| -  // Should never create mementos before slack tracking is finished. | 
| -  ASSERT(!count_constructions || !create_memento); | 
| - | 
| -  Isolate* isolate = masm->isolate(); | 
| - | 
| -  // Enter a construct frame. | 
| -  { | 
| -    FrameScope scope(masm, StackFrame::CONSTRUCT); | 
| - | 
| -    // Preserve the three incoming parameters on the stack. | 
| -    if (create_memento) { | 
| -      __ AssertUndefinedOrAllocationSite(x2, x10); | 
| -      __ Push(x2); | 
| -    } | 
| - | 
| -    Register argc = x0; | 
| -    Register constructor = x1; | 
| -    // x1: constructor function | 
| -    __ SmiTag(argc); | 
| -    __ Push(argc, constructor); | 
| -    // sp[0] : Constructor function. | 
| -    // sp[1]: number of arguments (smi-tagged) | 
| - | 
| -    // Try to allocate the object without transitioning into C code. If any of | 
| -    // the preconditions is not met, the code bails out to the runtime call. | 
| -    Label rt_call, allocated; | 
| -    if (FLAG_inline_new) { | 
| -      Label undo_allocation; | 
| -#if ENABLE_DEBUGGER_SUPPORT | 
| -      ExternalReference debug_step_in_fp = | 
| -          ExternalReference::debug_step_in_fp_address(isolate); | 
| -      __ Mov(x2, Operand(debug_step_in_fp)); | 
| -      __ Ldr(x2, MemOperand(x2)); | 
| -      __ Cbnz(x2, &rt_call); | 
| -#endif | 
| -      // Load the initial map and verify that it is in fact a map. | 
| -      Register init_map = x2; | 
| -      __ Ldr(init_map, | 
| -             FieldMemOperand(constructor, | 
| -                             JSFunction::kPrototypeOrInitialMapOffset)); | 
| -      __ JumpIfSmi(init_map, &rt_call); | 
| -      __ JumpIfNotObjectType(init_map, x10, x11, MAP_TYPE, &rt_call); | 
| - | 
| -      // Check that the constructor is not constructing a JSFunction (see | 
| -      // comments in Runtime_NewObject in runtime.cc). In which case the initial | 
| -      // map's instance type would be JS_FUNCTION_TYPE. | 
| -      __ CompareInstanceType(init_map, x10, JS_FUNCTION_TYPE); | 
| -      __ B(eq, &rt_call); | 
| - | 
| -      if (count_constructions) { | 
| -        Label allocate; | 
| -        // Decrease generous allocation count. | 
| -        __ Ldr(x3, FieldMemOperand(constructor, | 
| -                                   JSFunction::kSharedFunctionInfoOffset)); | 
| -        MemOperand constructor_count = | 
| -            FieldMemOperand(x3, SharedFunctionInfo::kConstructionCountOffset); | 
| -        __ Ldrb(x4, constructor_count); | 
| -        __ Subs(x4, x4, 1); | 
| -        __ Strb(x4, constructor_count); | 
| -        __ B(ne, &allocate); | 
| - | 
| -        // Push the constructor and map to the stack, and the constructor again | 
| -        // as argument to the runtime call. | 
| -        __ Push(constructor, init_map, constructor); | 
| -        // The call will replace the stub, so the countdown is only done once. | 
| -        __ CallRuntime(Runtime::kFinalizeInstanceSize, 1); | 
| -        __ Pop(init_map, constructor); | 
| -        __ Bind(&allocate); | 
| -      } | 
| - | 
| -      // Now allocate the JSObject on the heap. | 
| -      Register obj_size = x3; | 
| -      Register new_obj = x4; | 
| -      __ Ldrb(obj_size, FieldMemOperand(init_map, Map::kInstanceSizeOffset)); | 
| -      if (create_memento) { | 
| -        __ Add(x7, obj_size, | 
| -               Operand(AllocationMemento::kSize / kPointerSize)); | 
| -        __ Allocate(x7, new_obj, x10, x11, &rt_call, SIZE_IN_WORDS); | 
| -      } else { | 
| -        __ Allocate(obj_size, new_obj, x10, x11, &rt_call, SIZE_IN_WORDS); | 
| -      } | 
| - | 
| -      // Allocated the JSObject, now initialize the fields. Map is set to | 
| -      // initial map and properties and elements are set to empty fixed array. | 
| -      // NB. the object pointer is not tagged, so MemOperand is used. | 
| -      Register empty = x5; | 
| -      __ LoadRoot(empty, Heap::kEmptyFixedArrayRootIndex); | 
| -      __ Str(init_map, MemOperand(new_obj, JSObject::kMapOffset)); | 
| -      STATIC_ASSERT(JSObject::kElementsOffset == | 
| -          (JSObject::kPropertiesOffset + kPointerSize)); | 
| -      __ Stp(empty, empty, MemOperand(new_obj, JSObject::kPropertiesOffset)); | 
| - | 
| -      Register first_prop = x5; | 
| -      __ Add(first_prop, new_obj, JSObject::kHeaderSize); | 
| - | 
| -      // Fill all of the in-object properties with the appropriate filler. | 
| -      Register undef = x7; | 
| -      __ LoadRoot(undef, Heap::kUndefinedValueRootIndex); | 
| - | 
| -      // Obtain number of pre-allocated property fields and in-object | 
| -      // properties. | 
| -      Register prealloc_fields = x10; | 
| -      Register inobject_props = x11; | 
| -      Register inst_sizes = x11; | 
| -      __ Ldr(inst_sizes, FieldMemOperand(init_map, Map::kInstanceSizesOffset)); | 
| -      __ Ubfx(prealloc_fields, inst_sizes, | 
| -              Map::kPreAllocatedPropertyFieldsByte * kBitsPerByte, | 
| -              kBitsPerByte); | 
| -      __ Ubfx(inobject_props, inst_sizes, | 
| -              Map::kInObjectPropertiesByte * kBitsPerByte, kBitsPerByte); | 
| - | 
| -      // Calculate number of property fields in the object. | 
| -      Register prop_fields = x6; | 
| -      __ Sub(prop_fields, obj_size, JSObject::kHeaderSize / kPointerSize); | 
| - | 
| -      if (count_constructions) { | 
| -        // Fill the pre-allocated fields with undef. | 
| -        __ FillFields(first_prop, prealloc_fields, undef); | 
| - | 
| -        // Register first_non_prealloc is the offset of the first field after | 
| -        // pre-allocated fields. | 
| -        Register first_non_prealloc = x12; | 
| -        __ Add(first_non_prealloc, first_prop, | 
| -               Operand(prealloc_fields, LSL, kPointerSizeLog2)); | 
| - | 
| -        first_prop = NoReg; | 
| - | 
| -        if (FLAG_debug_code) { | 
| -          Register obj_end = x5; | 
| -          __ Add(obj_end, new_obj, Operand(obj_size, LSL, kPointerSizeLog2)); | 
| -          __ Cmp(first_non_prealloc, obj_end); | 
| -          __ Assert(le, kUnexpectedNumberOfPreAllocatedPropertyFields); | 
| -        } | 
| - | 
| -        // Fill the remaining fields with one pointer filler map. | 
| -        Register one_pointer_filler = x5; | 
| -        Register non_prealloc_fields = x6; | 
| -        __ LoadRoot(one_pointer_filler, Heap::kOnePointerFillerMapRootIndex); | 
| -        __ Sub(non_prealloc_fields, prop_fields, prealloc_fields); | 
| -        __ FillFields(first_non_prealloc, non_prealloc_fields, | 
| -                      one_pointer_filler); | 
| -        prop_fields = NoReg; | 
| -      } else if (create_memento) { | 
| -        // Fill the pre-allocated fields with undef. | 
| -        __ FillFields(first_prop, prop_fields, undef); | 
| -        __ Add(first_prop, new_obj, Operand(obj_size, LSL, kPointerSizeLog2)); | 
| -        __ LoadRoot(x14, Heap::kAllocationMementoMapRootIndex); | 
| -        ASSERT_EQ(0 * kPointerSize, AllocationMemento::kMapOffset); | 
| -        __ Str(x14, MemOperand(first_prop, kPointerSize, PostIndex)); | 
| -        // Load the AllocationSite | 
| -        __ Peek(x14, 2 * kXRegSize); | 
| -        ASSERT_EQ(1 * kPointerSize, AllocationMemento::kAllocationSiteOffset); | 
| -        __ Str(x14, MemOperand(first_prop, kPointerSize, PostIndex)); | 
| -        first_prop = NoReg; | 
| -      } else { | 
| -        // Fill all of the property fields with undef. | 
| -        __ FillFields(first_prop, prop_fields, undef); | 
| -        first_prop = NoReg; | 
| -        prop_fields = NoReg; | 
| -      } | 
| - | 
| -      // Add the object tag to make the JSObject real, so that we can continue | 
| -      // and jump into the continuation code at any time from now on. Any | 
| -      // failures need to undo the allocation, so that the heap is in a | 
| -      // consistent state and verifiable. | 
| -      __ Add(new_obj, new_obj, kHeapObjectTag); | 
| - | 
| -      // Check if a non-empty properties array is needed. Continue with | 
| -      // allocated object if not, or fall through to runtime call if it is. | 
| -      Register element_count = x3; | 
| -      __ Ldrb(element_count, | 
| -              FieldMemOperand(init_map, Map::kUnusedPropertyFieldsOffset)); | 
| -      // The field instance sizes contains both pre-allocated property fields | 
| -      // and in-object properties. | 
| -      __ Add(element_count, element_count, prealloc_fields); | 
| -      __ Subs(element_count, element_count, inobject_props); | 
| - | 
| -      // Done if no extra properties are to be allocated. | 
| -      __ B(eq, &allocated); | 
| -      __ Assert(pl, kPropertyAllocationCountFailed); | 
| - | 
| -      // Scale the number of elements by pointer size and add the header for | 
| -      // FixedArrays to the start of the next object calculation from above. | 
| -      Register new_array = x5; | 
| -      Register array_size = x6; | 
| -      __ Add(array_size, element_count, FixedArray::kHeaderSize / kPointerSize); | 
| -      __ Allocate(array_size, new_array, x11, x12, &undo_allocation, | 
| -                  static_cast<AllocationFlags>(RESULT_CONTAINS_TOP | | 
| -                                               SIZE_IN_WORDS)); | 
| - | 
| -      Register array_map = x10; | 
| -      __ LoadRoot(array_map, Heap::kFixedArrayMapRootIndex); | 
| -      __ Str(array_map, MemOperand(new_array, FixedArray::kMapOffset)); | 
| -      __ SmiTag(x0, element_count); | 
| -      __ Str(x0, MemOperand(new_array, FixedArray::kLengthOffset)); | 
| - | 
| -      // Initialize the fields to undefined. | 
| -      Register elements = x10; | 
| -      __ Add(elements, new_array, FixedArray::kHeaderSize); | 
| -      __ FillFields(elements, element_count, undef); | 
| - | 
| -      // Store the initialized FixedArray into the properties field of the | 
| -      // JSObject. | 
| -      __ Add(new_array, new_array, kHeapObjectTag); | 
| -      __ Str(new_array, FieldMemOperand(new_obj, JSObject::kPropertiesOffset)); | 
| - | 
| -      // Continue with JSObject being successfully allocated. | 
| -      __ B(&allocated); | 
| - | 
| -      // Undo the setting of the new top so that the heap is verifiable. For | 
| -      // example, the map's unused properties potentially do not match the | 
| -      // allocated objects unused properties. | 
| -      __ Bind(&undo_allocation); | 
| -      __ UndoAllocationInNewSpace(new_obj, x14); | 
| -    } | 
| - | 
| -    // Allocate the new receiver object using the runtime call. | 
| -    __ Bind(&rt_call); | 
| -    Label count_incremented; | 
| -    if (create_memento) { | 
| -      // Get the cell or allocation site. | 
| -      __ Peek(x4, 2 * kXRegSize); | 
| -      __ Push(x4); | 
| -      __ Push(constructor);  // Argument for Runtime_NewObject. | 
| -      __ CallRuntime(Runtime::kNewObjectWithAllocationSite, 2); | 
| -      __ Mov(x4, x0); | 
| -      // If we ended up using the runtime, and we want a memento, then the | 
| -      // runtime call made it for us, and we shouldn't do create count | 
| -      // increment. | 
| -      __ jmp(&count_incremented); | 
| -    } else { | 
| -      __ Push(constructor);  // Argument for Runtime_NewObject. | 
| -      __ CallRuntime(Runtime::kNewObject, 1); | 
| -      __ Mov(x4, x0); | 
| -    } | 
| - | 
| -    // Receiver for constructor call allocated. | 
| -    // x4: JSObject | 
| -    __ Bind(&allocated); | 
| - | 
| -    if (create_memento) { | 
| -      __ Peek(x10, 2 * kXRegSize); | 
| -      __ JumpIfRoot(x10, Heap::kUndefinedValueRootIndex, &count_incremented); | 
| -      // r2 is an AllocationSite. We are creating a memento from it, so we | 
| -      // need to increment the memento create count. | 
| -      __ Ldr(x5, FieldMemOperand(x10, | 
| -                                 AllocationSite::kPretenureCreateCountOffset)); | 
| -      __ Add(x5, x5, Operand(Smi::FromInt(1))); | 
| -      __ Str(x5, FieldMemOperand(x10, | 
| -                                 AllocationSite::kPretenureCreateCountOffset)); | 
| -      __ bind(&count_incremented); | 
| -    } | 
| - | 
| -    __ Push(x4, x4); | 
| - | 
| -    // Reload the number of arguments from the stack. | 
| -    // Set it up in x0 for the function call below. | 
| -    // jssp[0]: receiver | 
| -    // jssp[1]: receiver | 
| -    // jssp[2]: constructor function | 
| -    // jssp[3]: number of arguments (smi-tagged) | 
| -    __ Peek(constructor, 2 * kXRegSize);  // Load constructor. | 
| -    __ Peek(argc, 3 * kXRegSize);  // Load number of arguments. | 
| -    __ SmiUntag(argc); | 
| - | 
| -    // Set up pointer to last argument. | 
| -    __ Add(x2, fp, StandardFrameConstants::kCallerSPOffset); | 
| - | 
| -    // Copy arguments and receiver to the expression stack. | 
| -    // Copy 2 values every loop to use ldp/stp. | 
| -    // x0: number of arguments | 
| -    // x1: constructor function | 
| -    // x2: address of last argument (caller sp) | 
| -    // jssp[0]: receiver | 
| -    // jssp[1]: receiver | 
| -    // jssp[2]: constructor function | 
| -    // jssp[3]: number of arguments (smi-tagged) | 
| -    // Compute the start address of the copy in x3. | 
| -    __ Add(x3, x2, Operand(argc, LSL, kPointerSizeLog2)); | 
| -    Label loop, entry, done_copying_arguments; | 
| -    __ B(&entry); | 
| -    __ Bind(&loop); | 
| -    __ Ldp(x10, x11, MemOperand(x3, -2 * kPointerSize, PreIndex)); | 
| -    __ Push(x11, x10); | 
| -    __ Bind(&entry); | 
| -    __ Cmp(x3, x2); | 
| -    __ B(gt, &loop); | 
| -    // Because we copied values 2 by 2 we may have copied one extra value. | 
| -    // Drop it if that is the case. | 
| -    __ B(eq, &done_copying_arguments); | 
| -    __ Drop(1); | 
| -    __ Bind(&done_copying_arguments); | 
| - | 
| -    // Call the function. | 
| -    // x0: number of arguments | 
| -    // x1: constructor function | 
| -    if (is_api_function) { | 
| -      __ Ldr(cp, FieldMemOperand(constructor, JSFunction::kContextOffset)); | 
| -      Handle<Code> code = | 
| -          masm->isolate()->builtins()->HandleApiCallConstruct(); | 
| -      __ Call(code, RelocInfo::CODE_TARGET); | 
| -    } else { | 
| -      ParameterCount actual(argc); | 
| -      __ InvokeFunction(constructor, actual, CALL_FUNCTION, NullCallWrapper()); | 
| -    } | 
| - | 
| -    // Store offset of return address for deoptimizer. | 
| -    if (!is_api_function && !count_constructions) { | 
| -      masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset()); | 
| -    } | 
| - | 
| -    // Restore the context from the frame. | 
| -    // x0: result | 
| -    // jssp[0]: receiver | 
| -    // jssp[1]: constructor function | 
| -    // jssp[2]: number of arguments (smi-tagged) | 
| -    __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 
| - | 
| -    // If the result is an object (in the ECMA sense), we should get rid | 
| -    // of the receiver and use the result; see ECMA-262 section 13.2.2-7 | 
| -    // on page 74. | 
| -    Label use_receiver, exit; | 
| - | 
| -    // If the result is a smi, it is *not* an object in the ECMA sense. | 
| -    // x0: result | 
| -    // jssp[0]: receiver (newly allocated object) | 
| -    // jssp[1]: constructor function | 
| -    // jssp[2]: number of arguments (smi-tagged) | 
| -    __ JumpIfSmi(x0, &use_receiver); | 
| - | 
| -    // If the type of the result (stored in its map) is less than | 
| -    // FIRST_SPEC_OBJECT_TYPE, it is not an object in the ECMA sense. | 
| -    __ JumpIfObjectType(x0, x1, x3, FIRST_SPEC_OBJECT_TYPE, &exit, ge); | 
| - | 
| -    // Throw away the result of the constructor invocation and use the | 
| -    // on-stack receiver as the result. | 
| -    __ Bind(&use_receiver); | 
| -    __ Peek(x0, 0); | 
| - | 
| -    // Remove the receiver from the stack, remove caller arguments, and | 
| -    // return. | 
| -    __ Bind(&exit); | 
| -    // x0: result | 
| -    // jssp[0]: receiver (newly allocated object) | 
| -    // jssp[1]: constructor function | 
| -    // jssp[2]: number of arguments (smi-tagged) | 
| -    __ Peek(x1, 2 * kXRegSize); | 
| - | 
| -    // Leave construct frame. | 
| -  } | 
| - | 
| -  __ DropBySMI(x1); | 
| -  __ Drop(1); | 
| -  __ IncrementCounter(isolate->counters()->constructed_objects(), 1, x1, x2); | 
| -  __ Ret(); | 
| -} | 
| - | 
| - | 
| -void Builtins::Generate_JSConstructStubCountdown(MacroAssembler* masm) { | 
| -  Generate_JSConstructStubHelper(masm, false, true, false); | 
| -} | 
| - | 
| - | 
| -void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { | 
| -  Generate_JSConstructStubHelper(masm, false, false, FLAG_pretenuring_call_new); | 
| -} | 
| - | 
| - | 
| -void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { | 
| -  Generate_JSConstructStubHelper(masm, true, false, false); | 
| -} | 
| - | 
| - | 
| -// Input: | 
| -//   x0: code entry. | 
| -//   x1: function. | 
| -//   x2: receiver. | 
| -//   x3: argc. | 
| -//   x4: argv. | 
| -// Output: | 
| -//   x0: result. | 
| -static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, | 
| -                                             bool is_construct) { | 
| -  // Called from JSEntryStub::GenerateBody(). | 
| -  Register function = x1; | 
| -  Register receiver = x2; | 
| -  Register argc = x3; | 
| -  Register argv = x4; | 
| - | 
| -  ProfileEntryHookStub::MaybeCallEntryHook(masm); | 
| - | 
| -  // Clear the context before we push it when entering the internal frame. | 
| -  __ Mov(cp, 0); | 
| - | 
| -  { | 
| -    // Enter an internal frame. | 
| -    FrameScope scope(masm, StackFrame::INTERNAL); | 
| - | 
| -    // Set up the context from the function argument. | 
| -    __ Ldr(cp, FieldMemOperand(function, JSFunction::kContextOffset)); | 
| - | 
| -    __ InitializeRootRegister(); | 
| - | 
| -    // Push the function and the receiver onto the stack. | 
| -    __ Push(function, receiver); | 
| - | 
| -    // Copy arguments to the stack in a loop, in reverse order. | 
| -    // x3: argc. | 
| -    // x4: argv. | 
| -    Label loop, entry; | 
| -    // Compute the copy end address. | 
| -    __ Add(x10, argv, Operand(argc, LSL, kPointerSizeLog2)); | 
| - | 
| -    __ B(&entry); | 
| -    __ Bind(&loop); | 
| -    __ Ldr(x11, MemOperand(argv, kPointerSize, PostIndex)); | 
| -    __ Ldr(x12, MemOperand(x11));  // Dereference the handle. | 
| -    __ Push(x12);  // Push the argument. | 
| -    __ Bind(&entry); | 
| -    __ Cmp(x10, argv); | 
| -    __ B(ne, &loop); | 
| - | 
| -    // Initialize all JavaScript callee-saved registers, since they will be seen | 
| -    // by the garbage collector as part of handlers. | 
| -    // The original values have been saved in JSEntryStub::GenerateBody(). | 
| -    __ LoadRoot(x19, Heap::kUndefinedValueRootIndex); | 
| -    __ Mov(x20, x19); | 
| -    __ Mov(x21, x19); | 
| -    __ Mov(x22, x19); | 
| -    __ Mov(x23, x19); | 
| -    __ Mov(x24, x19); | 
| -    __ Mov(x25, x19); | 
| -    // Don't initialize the reserved registers. | 
| -    // x26 : root register (root). | 
| -    // x27 : context pointer (cp). | 
| -    // x28 : JS stack pointer (jssp). | 
| -    // x29 : frame pointer (fp). | 
| - | 
| -    __ Mov(x0, argc); | 
| -    if (is_construct) { | 
| -      // No type feedback cell is available. | 
| -      __ LoadRoot(x2, Heap::kUndefinedValueRootIndex); | 
| - | 
| -      CallConstructStub stub(NO_CALL_FUNCTION_FLAGS); | 
| -      __ CallStub(&stub); | 
| -    } else { | 
| -      ParameterCount actual(x0); | 
| -      __ InvokeFunction(function, actual, CALL_FUNCTION, NullCallWrapper()); | 
| -    } | 
| -    // Exit the JS internal frame and remove the parameters (except function), | 
| -    // and return. | 
| -  } | 
| - | 
| -  // Result is in x0. Return. | 
| -  __ Ret(); | 
| -} | 
| - | 
| - | 
| -void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) { | 
| -  Generate_JSEntryTrampolineHelper(masm, false); | 
| -} | 
| - | 
| - | 
| -void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) { | 
| -  Generate_JSEntryTrampolineHelper(masm, true); | 
| -} | 
| - | 
| - | 
| -void Builtins::Generate_CompileUnoptimized(MacroAssembler* masm) { | 
| -  CallRuntimePassFunction(masm, Runtime::kCompileUnoptimized); | 
| -  GenerateTailCallToReturnedCode(masm); | 
| -} | 
| - | 
| - | 
| -static void CallCompileOptimized(MacroAssembler* masm, bool concurrent) { | 
| -  FrameScope scope(masm, StackFrame::INTERNAL); | 
| -  Register function = x1; | 
| - | 
| -  // Preserve function. At the same time, push arguments for | 
| -  // kCompileOptimized. | 
| -  __ LoadObject(x10, masm->isolate()->factory()->ToBoolean(concurrent)); | 
| -  __ Push(function, function, x10); | 
| - | 
| -  __ CallRuntime(Runtime::kCompileOptimized, 2); | 
| - | 
| -  // Restore receiver. | 
| -  __ Pop(function); | 
| -} | 
| - | 
| - | 
| -void Builtins::Generate_CompileOptimized(MacroAssembler* masm) { | 
| -  CallCompileOptimized(masm, false); | 
| -  GenerateTailCallToReturnedCode(masm); | 
| -} | 
| - | 
| - | 
| -void Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) { | 
| -  CallCompileOptimized(masm, true); | 
| -  GenerateTailCallToReturnedCode(masm); | 
| -} | 
| - | 
| - | 
| -static void GenerateMakeCodeYoungAgainCommon(MacroAssembler* masm) { | 
| -  // For now, we are relying on the fact that make_code_young doesn't do any | 
| -  // garbage collection which allows us to save/restore the registers without | 
| -  // worrying about which of them contain pointers. We also don't build an | 
| -  // internal frame to make the code fast, since we shouldn't have to do stack | 
| -  // crawls in MakeCodeYoung. This seems a bit fragile. | 
| - | 
| -  // The following caller-saved registers must be saved and restored when | 
| -  // calling through to the runtime: | 
| -  //   x0 - The address from which to resume execution. | 
| -  //   x1 - isolate | 
| -  //   lr - The return address for the JSFunction itself. It has not yet been | 
| -  //        preserved on the stack because the frame setup code was replaced | 
| -  //        with a call to this stub, to handle code ageing. | 
| -  { | 
| -    FrameScope scope(masm, StackFrame::MANUAL); | 
| -    __ Push(x0, x1, fp, lr); | 
| -    __ Mov(x1, ExternalReference::isolate_address(masm->isolate())); | 
| -    __ CallCFunction( | 
| -        ExternalReference::get_make_code_young_function(masm->isolate()), 2); | 
| -    __ Pop(lr, fp, x1, x0); | 
| -  } | 
| - | 
| -  // The calling function has been made young again, so return to execute the | 
| -  // real frame set-up code. | 
| -  __ Br(x0); | 
| -} | 
| - | 
| -#define DEFINE_CODE_AGE_BUILTIN_GENERATOR(C)                 \ | 
| -void Builtins::Generate_Make##C##CodeYoungAgainEvenMarking(  \ | 
| -    MacroAssembler* masm) {                                  \ | 
| -  GenerateMakeCodeYoungAgainCommon(masm);                    \ | 
| -}                                                            \ | 
| -void Builtins::Generate_Make##C##CodeYoungAgainOddMarking(   \ | 
| -    MacroAssembler* masm) {                                  \ | 
| -  GenerateMakeCodeYoungAgainCommon(masm);                    \ | 
| -} | 
| -CODE_AGE_LIST(DEFINE_CODE_AGE_BUILTIN_GENERATOR) | 
| -#undef DEFINE_CODE_AGE_BUILTIN_GENERATOR | 
| - | 
| - | 
| -void Builtins::Generate_MarkCodeAsExecutedOnce(MacroAssembler* masm) { | 
| -  // For now, as in GenerateMakeCodeYoungAgainCommon, we are relying on the fact | 
| -  // that make_code_young doesn't do any garbage collection which allows us to | 
| -  // save/restore the registers without worrying about which of them contain | 
| -  // pointers. | 
| - | 
| -  // The following caller-saved registers must be saved and restored when | 
| -  // calling through to the runtime: | 
| -  //   x0 - The address from which to resume execution. | 
| -  //   x1 - isolate | 
| -  //   lr - The return address for the JSFunction itself. It has not yet been | 
| -  //        preserved on the stack because the frame setup code was replaced | 
| -  //        with a call to this stub, to handle code ageing. | 
| -  { | 
| -    FrameScope scope(masm, StackFrame::MANUAL); | 
| -    __ Push(x0, x1, fp, lr); | 
| -    __ Mov(x1, ExternalReference::isolate_address(masm->isolate())); | 
| -    __ CallCFunction( | 
| -        ExternalReference::get_mark_code_as_executed_function( | 
| -            masm->isolate()), 2); | 
| -    __ Pop(lr, fp, x1, x0); | 
| - | 
| -    // Perform prologue operations usually performed by the young code stub. | 
| -    __ EmitFrameSetupForCodeAgePatching(masm); | 
| -  } | 
| - | 
| -  // Jump to point after the code-age stub. | 
| -  __ Add(x0, x0, kCodeAgeSequenceSize); | 
| -  __ Br(x0); | 
| -} | 
| - | 
| - | 
| -void Builtins::Generate_MarkCodeAsExecutedTwice(MacroAssembler* masm) { | 
| -  GenerateMakeCodeYoungAgainCommon(masm); | 
| -} | 
| - | 
| - | 
| -static void Generate_NotifyStubFailureHelper(MacroAssembler* masm, | 
| -                                             SaveFPRegsMode save_doubles) { | 
| -  { | 
| -    FrameScope scope(masm, StackFrame::INTERNAL); | 
| - | 
| -    // Preserve registers across notification, this is important for compiled | 
| -    // stubs that tail call the runtime on deopts passing their parameters in | 
| -    // registers. | 
| -    // TODO(jbramley): Is it correct (and appropriate) to use safepoint | 
| -    // registers here? According to the comment above, we should only need to | 
| -    // preserve the registers with parameters. | 
| -    __ PushXRegList(kSafepointSavedRegisters); | 
| -    // Pass the function and deoptimization type to the runtime system. | 
| -    __ CallRuntime(Runtime::kNotifyStubFailure, 0, save_doubles); | 
| -    __ PopXRegList(kSafepointSavedRegisters); | 
| -  } | 
| - | 
| -  // Ignore state (pushed by Deoptimizer::EntryGenerator::Generate). | 
| -  __ Drop(1); | 
| - | 
| -  // Jump to the miss handler. Deoptimizer::EntryGenerator::Generate loads this | 
| -  // into lr before it jumps here. | 
| -  __ Br(lr); | 
| -} | 
| - | 
| - | 
| -void Builtins::Generate_NotifyStubFailure(MacroAssembler* masm) { | 
| -  Generate_NotifyStubFailureHelper(masm, kDontSaveFPRegs); | 
| -} | 
| - | 
| - | 
| -void Builtins::Generate_NotifyStubFailureSaveDoubles(MacroAssembler* masm) { | 
| -  Generate_NotifyStubFailureHelper(masm, kSaveFPRegs); | 
| -} | 
| - | 
| - | 
| -static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm, | 
| -                                             Deoptimizer::BailoutType type) { | 
| -  { | 
| -    FrameScope scope(masm, StackFrame::INTERNAL); | 
| -    // Pass the deoptimization type to the runtime system. | 
| -    __ Mov(x0, Smi::FromInt(static_cast<int>(type))); | 
| -    __ Push(x0); | 
| -    __ CallRuntime(Runtime::kNotifyDeoptimized, 1); | 
| -  } | 
| - | 
| -  // Get the full codegen state from the stack and untag it. | 
| -  Register state = x6; | 
| -  __ Peek(state, 0); | 
| -  __ SmiUntag(state); | 
| - | 
| -  // Switch on the state. | 
| -  Label with_tos_register, unknown_state; | 
| -  __ CompareAndBranch( | 
| -      state, FullCodeGenerator::NO_REGISTERS, ne, &with_tos_register); | 
| -  __ Drop(1);  // Remove state. | 
| -  __ Ret(); | 
| - | 
| -  __ Bind(&with_tos_register); | 
| -  // Reload TOS register. | 
| -  __ Peek(x0, kPointerSize); | 
| -  __ CompareAndBranch(state, FullCodeGenerator::TOS_REG, ne, &unknown_state); | 
| -  __ Drop(2);  // Remove state and TOS. | 
| -  __ Ret(); | 
| - | 
| -  __ Bind(&unknown_state); | 
| -  __ Abort(kInvalidFullCodegenState); | 
| -} | 
| - | 
| - | 
| -void Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) { | 
| -  Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::EAGER); | 
| -} | 
| - | 
| - | 
| -void Builtins::Generate_NotifyLazyDeoptimized(MacroAssembler* masm) { | 
| -  Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::LAZY); | 
| -} | 
| - | 
| - | 
| -void Builtins::Generate_NotifySoftDeoptimized(MacroAssembler* masm) { | 
| -  Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::SOFT); | 
| -} | 
| - | 
| - | 
| -void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { | 
| -  // Lookup the function in the JavaScript frame. | 
| -  __ Ldr(x0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 
| -  { | 
| -    FrameScope scope(masm, StackFrame::INTERNAL); | 
| -    // Pass function as argument. | 
| -    __ Push(x0); | 
| -    __ CallRuntime(Runtime::kCompileForOnStackReplacement, 1); | 
| -  } | 
| - | 
| -  // If the code object is null, just return to the unoptimized code. | 
| -  Label skip; | 
| -  __ CompareAndBranch(x0, Smi::FromInt(0), ne, &skip); | 
| -  __ Ret(); | 
| - | 
| -  __ Bind(&skip); | 
| - | 
| -  // Load deoptimization data from the code object. | 
| -  // <deopt_data> = <code>[#deoptimization_data_offset] | 
| -  __ Ldr(x1, MemOperand(x0, Code::kDeoptimizationDataOffset - kHeapObjectTag)); | 
| - | 
| -  // Load the OSR entrypoint offset from the deoptimization data. | 
| -  // <osr_offset> = <deopt_data>[#header_size + #osr_pc_offset] | 
| -  __ Ldrsw(w1, UntagSmiFieldMemOperand(x1, FixedArray::OffsetOfElementAt( | 
| -      DeoptimizationInputData::kOsrPcOffsetIndex))); | 
| - | 
| -  // Compute the target address = code_obj + header_size + osr_offset | 
| -  // <entry_addr> = <code_obj> + #header_size + <osr_offset> | 
| -  __ Add(x0, x0, x1); | 
| -  __ Add(lr, x0, Code::kHeaderSize - kHeapObjectTag); | 
| - | 
| -  // And "return" to the OSR entry point of the function. | 
| -  __ Ret(); | 
| -} | 
| - | 
| - | 
| -void Builtins::Generate_OsrAfterStackCheck(MacroAssembler* masm) { | 
| -  // We check the stack limit as indicator that recompilation might be done. | 
| -  Label ok; | 
| -  __ CompareRoot(jssp, Heap::kStackLimitRootIndex); | 
| -  __ B(hs, &ok); | 
| -  { | 
| -    FrameScope scope(masm, StackFrame::INTERNAL); | 
| -    __ CallRuntime(Runtime::kStackGuard, 0); | 
| -  } | 
| -  __ Jump(masm->isolate()->builtins()->OnStackReplacement(), | 
| -          RelocInfo::CODE_TARGET); | 
| - | 
| -  __ Bind(&ok); | 
| -  __ Ret(); | 
| -} | 
| - | 
| - | 
| -void Builtins::Generate_FunctionCall(MacroAssembler* masm) { | 
| -  enum { | 
| -    call_type_JS_func = 0, | 
| -    call_type_func_proxy = 1, | 
| -    call_type_non_func = 2 | 
| -  }; | 
| -  Register argc = x0; | 
| -  Register function = x1; | 
| -  Register call_type = x4; | 
| -  Register scratch1 = x10; | 
| -  Register scratch2 = x11; | 
| -  Register receiver_type = x13; | 
| - | 
| -  ASM_LOCATION("Builtins::Generate_FunctionCall"); | 
| -  // 1. Make sure we have at least one argument. | 
| -  { Label done; | 
| -    __ Cbnz(argc, &done); | 
| -    __ LoadRoot(scratch1, Heap::kUndefinedValueRootIndex); | 
| -    __ Push(scratch1); | 
| -    __ Mov(argc, 1); | 
| -    __ Bind(&done); | 
| -  } | 
| - | 
| -  // 2. Get the function to call (passed as receiver) from the stack, check | 
| -  //    if it is a function. | 
| -  Label slow, non_function; | 
| -  __ Peek(function, Operand(argc, LSL, kXRegSizeLog2)); | 
| -  __ JumpIfSmi(function, &non_function); | 
| -  __ JumpIfNotObjectType(function, scratch1, receiver_type, | 
| -                         JS_FUNCTION_TYPE, &slow); | 
| - | 
| -  // 3a. Patch the first argument if necessary when calling a function. | 
| -  Label shift_arguments; | 
| -  __ Mov(call_type, static_cast<int>(call_type_JS_func)); | 
| -  { Label convert_to_object, use_global_receiver, patch_receiver; | 
| -    // Change context eagerly in case we need the global receiver. | 
| -    __ Ldr(cp, FieldMemOperand(function, JSFunction::kContextOffset)); | 
| - | 
| -    // Do not transform the receiver for strict mode functions. | 
| -    // Also do not transform the receiver for native (Compilerhints already in | 
| -    // x3). | 
| -    __ Ldr(scratch1, | 
| -           FieldMemOperand(function, JSFunction::kSharedFunctionInfoOffset)); | 
| -    __ Ldr(scratch2.W(), | 
| -           FieldMemOperand(scratch1, SharedFunctionInfo::kCompilerHintsOffset)); | 
| -    __ TestAndBranchIfAnySet( | 
| -        scratch2.W(), | 
| -        (1 << SharedFunctionInfo::kStrictModeFunction) | | 
| -        (1 << SharedFunctionInfo::kNative), | 
| -        &shift_arguments); | 
| - | 
| -    // Compute the receiver in sloppy mode. | 
| -    Register receiver = x2; | 
| -    __ Sub(scratch1, argc, 1); | 
| -    __ Peek(receiver, Operand(scratch1, LSL, kXRegSizeLog2)); | 
| -    __ JumpIfSmi(receiver, &convert_to_object); | 
| - | 
| -    __ JumpIfRoot(receiver, Heap::kUndefinedValueRootIndex, | 
| -                  &use_global_receiver); | 
| -    __ JumpIfRoot(receiver, Heap::kNullValueRootIndex, &use_global_receiver); | 
| - | 
| -    STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE); | 
| -    __ JumpIfObjectType(receiver, scratch1, scratch2, | 
| -                        FIRST_SPEC_OBJECT_TYPE, &shift_arguments, ge); | 
| - | 
| -    __ Bind(&convert_to_object); | 
| - | 
| -    { | 
| -      // Enter an internal frame in order to preserve argument count. | 
| -      FrameScope scope(masm, StackFrame::INTERNAL); | 
| -      __ SmiTag(argc); | 
| - | 
| -      __ Push(argc, receiver); | 
| -      __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); | 
| -      __ Mov(receiver, x0); | 
| - | 
| -      __ Pop(argc); | 
| -      __ SmiUntag(argc); | 
| - | 
| -      // Exit the internal frame. | 
| -    } | 
| - | 
| -    // Restore the function and flag in the registers. | 
| -    __ Peek(function, Operand(argc, LSL, kXRegSizeLog2)); | 
| -    __ Mov(call_type, static_cast<int>(call_type_JS_func)); | 
| -    __ B(&patch_receiver); | 
| - | 
| -    __ Bind(&use_global_receiver); | 
| -    __ Ldr(receiver, GlobalObjectMemOperand()); | 
| -    __ Ldr(receiver, | 
| -           FieldMemOperand(receiver, GlobalObject::kGlobalReceiverOffset)); | 
| - | 
| - | 
| -    __ Bind(&patch_receiver); | 
| -    __ Sub(scratch1, argc, 1); | 
| -    __ Poke(receiver, Operand(scratch1, LSL, kXRegSizeLog2)); | 
| - | 
| -    __ B(&shift_arguments); | 
| -  } | 
| - | 
| -  // 3b. Check for function proxy. | 
| -  __ Bind(&slow); | 
| -  __ Mov(call_type, static_cast<int>(call_type_func_proxy)); | 
| -  __ Cmp(receiver_type, JS_FUNCTION_PROXY_TYPE); | 
| -  __ B(eq, &shift_arguments); | 
| -  __ Bind(&non_function); | 
| -  __ Mov(call_type, static_cast<int>(call_type_non_func)); | 
| - | 
| -  // 3c. Patch the first argument when calling a non-function.  The | 
| -  //     CALL_NON_FUNCTION builtin expects the non-function callee as | 
| -  //     receiver, so overwrite the first argument which will ultimately | 
| -  //     become the receiver. | 
| -  // call type (0: JS function, 1: function proxy, 2: non-function) | 
| -  __ Sub(scratch1, argc, 1); | 
| -  __ Poke(function, Operand(scratch1, LSL, kXRegSizeLog2)); | 
| - | 
| -  // 4. Shift arguments and return address one slot down on the stack | 
| -  //    (overwriting the original receiver).  Adjust argument count to make | 
| -  //    the original first argument the new receiver. | 
| -  // call type (0: JS function, 1: function proxy, 2: non-function) | 
| -  __ Bind(&shift_arguments); | 
| -  { Label loop; | 
| -    // Calculate the copy start address (destination). Copy end address is jssp. | 
| -    __ Add(scratch2, jssp, Operand(argc, LSL, kPointerSizeLog2)); | 
| -    __ Sub(scratch1, scratch2, kPointerSize); | 
| - | 
| -    __ Bind(&loop); | 
| -    __ Ldr(x12, MemOperand(scratch1, -kPointerSize, PostIndex)); | 
| -    __ Str(x12, MemOperand(scratch2, -kPointerSize, PostIndex)); | 
| -    __ Cmp(scratch1, jssp); | 
| -    __ B(ge, &loop); | 
| -    // Adjust the actual number of arguments and remove the top element | 
| -    // (which is a copy of the last argument). | 
| -    __ Sub(argc, argc, 1); | 
| -    __ Drop(1); | 
| -  } | 
| - | 
| -  // 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin, | 
| -  //     or a function proxy via CALL_FUNCTION_PROXY. | 
| -  // call type (0: JS function, 1: function proxy, 2: non-function) | 
| -  { Label js_function, non_proxy; | 
| -    __ Cbz(call_type, &js_function); | 
| -    // Expected number of arguments is 0 for CALL_NON_FUNCTION. | 
| -    __ Mov(x2, 0); | 
| -    __ Cmp(call_type, static_cast<int>(call_type_func_proxy)); | 
| -    __ B(ne, &non_proxy); | 
| - | 
| -    __ Push(function);  // Re-add proxy object as additional argument. | 
| -    __ Add(argc, argc, 1); | 
| -    __ GetBuiltinFunction(function, Builtins::CALL_FUNCTION_PROXY); | 
| -    __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 
| -            RelocInfo::CODE_TARGET); | 
| - | 
| -    __ Bind(&non_proxy); | 
| -    __ GetBuiltinFunction(function, Builtins::CALL_NON_FUNCTION); | 
| -    __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 
| -            RelocInfo::CODE_TARGET); | 
| -    __ Bind(&js_function); | 
| -  } | 
| - | 
| -  // 5b. Get the code to call from the function and check that the number of | 
| -  //     expected arguments matches what we're providing.  If so, jump | 
| -  //     (tail-call) to the code in register edx without checking arguments. | 
| -  __ Ldr(x3, FieldMemOperand(function, JSFunction::kSharedFunctionInfoOffset)); | 
| -  __ Ldrsw(x2, | 
| -           FieldMemOperand(x3, | 
| -             SharedFunctionInfo::kFormalParameterCountOffset)); | 
| -  Label dont_adapt_args; | 
| -  __ Cmp(x2, argc);  // Check formal and actual parameter counts. | 
| -  __ B(eq, &dont_adapt_args); | 
| -  __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 
| -          RelocInfo::CODE_TARGET); | 
| -  __ Bind(&dont_adapt_args); | 
| - | 
| -  __ Ldr(x3, FieldMemOperand(function, JSFunction::kCodeEntryOffset)); | 
| -  ParameterCount expected(0); | 
| -  __ InvokeCode(x3, expected, expected, JUMP_FUNCTION, NullCallWrapper()); | 
| -} | 
| - | 
| - | 
| -void Builtins::Generate_FunctionApply(MacroAssembler* masm) { | 
| -  ASM_LOCATION("Builtins::Generate_FunctionApply"); | 
| -  const int kIndexOffset    = | 
| -      StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); | 
| -  const int kLimitOffset    = | 
| -      StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); | 
| -  const int kArgsOffset     =  2 * kPointerSize; | 
| -  const int kReceiverOffset =  3 * kPointerSize; | 
| -  const int kFunctionOffset =  4 * kPointerSize; | 
| - | 
| -  { | 
| -    FrameScope frame_scope(masm, StackFrame::INTERNAL); | 
| - | 
| -    Register args = x12; | 
| -    Register receiver = x14; | 
| -    Register function = x15; | 
| - | 
| -    // Get the length of the arguments via a builtin call. | 
| -    __ Ldr(function, MemOperand(fp, kFunctionOffset)); | 
| -    __ Ldr(args, MemOperand(fp, kArgsOffset)); | 
| -    __ Push(function, args); | 
| -    __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); | 
| -    Register argc = x0; | 
| - | 
| -    // Check the stack for overflow. | 
| -    // We are not trying to catch interruptions (e.g. debug break and | 
| -    // preemption) here, so the "real stack limit" is checked. | 
| -    Label enough_stack_space; | 
| -    __ LoadRoot(x10, Heap::kRealStackLimitRootIndex); | 
| -    __ Ldr(function, MemOperand(fp, kFunctionOffset)); | 
| -    // Make x10 the space we have left. The stack might already be overflowed | 
| -    // here which will cause x10 to become negative. | 
| -    // TODO(jbramley): Check that the stack usage here is safe. | 
| -    __ Sub(x10, jssp, x10); | 
| -    // Check if the arguments will overflow the stack. | 
| -    __ Cmp(x10, Operand(argc, LSR, kSmiShift - kPointerSizeLog2)); | 
| -    __ B(gt, &enough_stack_space); | 
| -    // There is not enough stack space, so use a builtin to throw an appropriate | 
| -    // error. | 
| -    __ Push(function, argc); | 
| -    __ InvokeBuiltin(Builtins::APPLY_OVERFLOW, CALL_FUNCTION); | 
| -    // We should never return from the APPLY_OVERFLOW builtin. | 
| -    if (__ emit_debug_code()) { | 
| -      __ Unreachable(); | 
| -    } | 
| - | 
| -    __ Bind(&enough_stack_space); | 
| -    // Push current limit and index. | 
| -    __ Mov(x1, 0);  // Initial index. | 
| -    __ Push(argc, x1); | 
| - | 
| -    Label push_receiver; | 
| -    __ Ldr(receiver, MemOperand(fp, kReceiverOffset)); | 
| - | 
| -    // Check that the function is a JS function. Otherwise it must be a proxy. | 
| -    // When it is not the function proxy will be invoked later. | 
| -    __ JumpIfNotObjectType(function, x10, x11, JS_FUNCTION_TYPE, | 
| -                           &push_receiver); | 
| - | 
| -    // Change context eagerly to get the right global object if necessary. | 
| -    __ Ldr(cp, FieldMemOperand(function, JSFunction::kContextOffset)); | 
| -    // Load the shared function info. | 
| -    __ Ldr(x2, FieldMemOperand(function, | 
| -                               JSFunction::kSharedFunctionInfoOffset)); | 
| - | 
| -    // Compute and push the receiver. | 
| -    // Do not transform the receiver for strict mode functions. | 
| -    Label convert_receiver_to_object, use_global_receiver; | 
| -    __ Ldr(w10, FieldMemOperand(x2, SharedFunctionInfo::kCompilerHintsOffset)); | 
| -    __ Tbnz(x10, SharedFunctionInfo::kStrictModeFunction, &push_receiver); | 
| -    // Do not transform the receiver for native functions. | 
| -    __ Tbnz(x10, SharedFunctionInfo::kNative, &push_receiver); | 
| - | 
| -    // Compute the receiver in sloppy mode. | 
| -    __ JumpIfSmi(receiver, &convert_receiver_to_object); | 
| -    __ JumpIfRoot(receiver, Heap::kNullValueRootIndex, &use_global_receiver); | 
| -    __ JumpIfRoot(receiver, Heap::kUndefinedValueRootIndex, | 
| -                  &use_global_receiver); | 
| - | 
| -    // Check if the receiver is already a JavaScript object. | 
| -    STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE); | 
| -    __ JumpIfObjectType(receiver, x10, x11, FIRST_SPEC_OBJECT_TYPE, | 
| -                        &push_receiver, ge); | 
| - | 
| -    // Call a builtin to convert the receiver to a regular object. | 
| -    __ Bind(&convert_receiver_to_object); | 
| -    __ Push(receiver); | 
| -    __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); | 
| -    __ Mov(receiver, x0); | 
| -    __ B(&push_receiver); | 
| - | 
| -    __ Bind(&use_global_receiver); | 
| -    __ Ldr(x10, GlobalObjectMemOperand()); | 
| -    __ Ldr(receiver, FieldMemOperand(x10, GlobalObject::kGlobalReceiverOffset)); | 
| - | 
| -    // Push the receiver | 
| -    __ Bind(&push_receiver); | 
| -    __ Push(receiver); | 
| - | 
| -    // Copy all arguments from the array to the stack. | 
| -    Label entry, loop; | 
| -    Register current = x0; | 
| -    __ Ldr(current, MemOperand(fp, kIndexOffset)); | 
| -    __ B(&entry); | 
| - | 
| -    __ Bind(&loop); | 
| -    // Load the current argument from the arguments array and push it. | 
| -    // TODO(all): Couldn't we optimize this for JS arrays? | 
| - | 
| -    __ Ldr(x1, MemOperand(fp, kArgsOffset)); | 
| -    __ Push(x1, current); | 
| - | 
| -    // Call the runtime to access the property in the arguments array. | 
| -    __ CallRuntime(Runtime::kGetProperty, 2); | 
| -    __ Push(x0); | 
| - | 
| -    // Use inline caching to access the arguments. | 
| -    __ Ldr(current, MemOperand(fp, kIndexOffset)); | 
| -    __ Add(current, current, Smi::FromInt(1)); | 
| -    __ Str(current, MemOperand(fp, kIndexOffset)); | 
| - | 
| -    // Test if the copy loop has finished copying all the elements from the | 
| -    // arguments object. | 
| -    __ Bind(&entry); | 
| -    __ Ldr(x1, MemOperand(fp, kLimitOffset)); | 
| -    __ Cmp(current, x1); | 
| -    __ B(ne, &loop); | 
| - | 
| -    // At the end of the loop, the number of arguments is stored in 'current', | 
| -    // represented as a smi. | 
| - | 
| -    function = x1;  // From now on we want the function to be kept in x1; | 
| -    __ Ldr(function, MemOperand(fp, kFunctionOffset)); | 
| - | 
| -    // Call the function. | 
| -    Label call_proxy; | 
| -    ParameterCount actual(current); | 
| -    __ SmiUntag(current); | 
| -    __ JumpIfNotObjectType(function, x10, x11, JS_FUNCTION_TYPE, &call_proxy); | 
| -    __ InvokeFunction(function, actual, CALL_FUNCTION, NullCallWrapper()); | 
| -    frame_scope.GenerateLeaveFrame(); | 
| -    __ Drop(3); | 
| -    __ Ret(); | 
| - | 
| -    // Call the function proxy. | 
| -    __ Bind(&call_proxy); | 
| -    // x0 : argc | 
| -    // x1 : function | 
| -    __ Push(function);  // Add function proxy as last argument. | 
| -    __ Add(x0, x0, 1); | 
| -    __ Mov(x2, 0); | 
| -    __ GetBuiltinFunction(x1, Builtins::CALL_FUNCTION_PROXY); | 
| -    __ Call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), | 
| -            RelocInfo::CODE_TARGET); | 
| -  } | 
| -  __ Drop(3); | 
| -  __ Ret(); | 
| -} | 
| - | 
| - | 
| -static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) { | 
| -  __ SmiTag(x10, x0); | 
| -  __ Mov(x11, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); | 
| -  __ Push(lr, fp); | 
| -  __ Push(x11, x1, x10); | 
| -  __ Add(fp, jssp, | 
| -         StandardFrameConstants::kFixedFrameSizeFromFp + kPointerSize); | 
| -} | 
| - | 
| - | 
| -static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) { | 
| -  // ----------- S t a t e ------------- | 
| -  //  -- x0 : result being passed through | 
| -  // ----------------------------------- | 
| -  // Get the number of arguments passed (as a smi), tear down the frame and | 
| -  // then drop the parameters and the receiver. | 
| -  __ Ldr(x10, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp + | 
| -                               kPointerSize))); | 
| -  __ Mov(jssp, fp); | 
| -  __ Pop(fp, lr); | 
| -  __ DropBySMI(x10, kXRegSize); | 
| -  __ Drop(1); | 
| -} | 
| - | 
| - | 
| -void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { | 
| -  ASM_LOCATION("Builtins::Generate_ArgumentsAdaptorTrampoline"); | 
| -  // ----------- S t a t e ------------- | 
| -  //  -- x0 : actual number of arguments | 
| -  //  -- x1 : function (passed through to callee) | 
| -  //  -- x2 : expected number of arguments | 
| -  // ----------------------------------- | 
| - | 
| -  Register argc_actual = x0;  // Excluding the receiver. | 
| -  Register argc_expected = x2;  // Excluding the receiver. | 
| -  Register function = x1; | 
| -  Register code_entry = x3; | 
| - | 
| -  Label invoke, dont_adapt_arguments; | 
| - | 
| -  Label enough, too_few; | 
| -  __ Ldr(code_entry, FieldMemOperand(function, JSFunction::kCodeEntryOffset)); | 
| -  __ Cmp(argc_actual, argc_expected); | 
| -  __ B(lt, &too_few); | 
| -  __ Cmp(argc_expected, SharedFunctionInfo::kDontAdaptArgumentsSentinel); | 
| -  __ B(eq, &dont_adapt_arguments); | 
| - | 
| -  {  // Enough parameters: actual >= expected | 
| -    EnterArgumentsAdaptorFrame(masm); | 
| - | 
| -    Register copy_start = x10; | 
| -    Register copy_end = x11; | 
| -    Register copy_to = x12; | 
| -    Register scratch1 = x13, scratch2 = x14; | 
| - | 
| -    __ Lsl(argc_expected, argc_expected, kPointerSizeLog2); | 
| - | 
| -    // Adjust for fp, lr, and the receiver. | 
| -    __ Add(copy_start, fp, 3 * kPointerSize); | 
| -    __ Add(copy_start, copy_start, Operand(argc_actual, LSL, kPointerSizeLog2)); | 
| -    __ Sub(copy_end, copy_start, argc_expected); | 
| -    __ Sub(copy_end, copy_end, kPointerSize); | 
| -    __ Mov(copy_to, jssp); | 
| - | 
| -    // Claim space for the arguments, the receiver, and one extra slot. | 
| -    // The extra slot ensures we do not write under jssp. It will be popped | 
| -    // later. | 
| -    __ Add(scratch1, argc_expected, 2 * kPointerSize); | 
| -    __ Claim(scratch1, 1); | 
| - | 
| -    // Copy the arguments (including the receiver) to the new stack frame. | 
| -    Label copy_2_by_2; | 
| -    __ Bind(©_2_by_2); | 
| -    __ Ldp(scratch1, scratch2, | 
| -           MemOperand(copy_start, - 2 * kPointerSize, PreIndex)); | 
| -    __ Stp(scratch1, scratch2, | 
| -           MemOperand(copy_to, - 2 * kPointerSize, PreIndex)); | 
| -    __ Cmp(copy_start, copy_end); | 
| -    __ B(hi, ©_2_by_2); | 
| - | 
| -    // Correct the space allocated for the extra slot. | 
| -    __ Drop(1); | 
| - | 
| -    __ B(&invoke); | 
| -  } | 
| - | 
| -  {  // Too few parameters: Actual < expected | 
| -    __ Bind(&too_few); | 
| -    EnterArgumentsAdaptorFrame(masm); | 
| - | 
| -    Register copy_from = x10; | 
| -    Register copy_end = x11; | 
| -    Register copy_to = x12; | 
| -    Register scratch1 = x13, scratch2 = x14; | 
| - | 
| -    __ Lsl(argc_expected, argc_expected, kPointerSizeLog2); | 
| -    __ Lsl(argc_actual, argc_actual, kPointerSizeLog2); | 
| - | 
| -    // Adjust for fp, lr, and the receiver. | 
| -    __ Add(copy_from, fp, 3 * kPointerSize); | 
| -    __ Add(copy_from, copy_from, argc_actual); | 
| -    __ Mov(copy_to, jssp); | 
| -    __ Sub(copy_end, copy_to, 1 * kPointerSize);   // Adjust for the receiver. | 
| -    __ Sub(copy_end, copy_end, argc_actual); | 
| - | 
| -    // Claim space for the arguments, the receiver, and one extra slot. | 
| -    // The extra slot ensures we do not write under jssp. It will be popped | 
| -    // later. | 
| -    __ Add(scratch1, argc_expected, 2 * kPointerSize); | 
| -    __ Claim(scratch1, 1); | 
| - | 
| -    // Copy the arguments (including the receiver) to the new stack frame. | 
| -    Label copy_2_by_2; | 
| -    __ Bind(©_2_by_2); | 
| -    __ Ldp(scratch1, scratch2, | 
| -           MemOperand(copy_from, - 2 * kPointerSize, PreIndex)); | 
| -    __ Stp(scratch1, scratch2, | 
| -           MemOperand(copy_to, - 2 * kPointerSize, PreIndex)); | 
| -    __ Cmp(copy_to, copy_end); | 
| -    __ B(hi, ©_2_by_2); | 
| - | 
| -    __ Mov(copy_to, copy_end); | 
| - | 
| -    // Fill the remaining expected arguments with undefined. | 
| -    __ LoadRoot(scratch1, Heap::kUndefinedValueRootIndex); | 
| -    __ Add(copy_end, jssp, kPointerSize); | 
| - | 
| -    Label fill; | 
| -    __ Bind(&fill); | 
| -    __ Stp(scratch1, scratch1, | 
| -           MemOperand(copy_to, - 2 * kPointerSize, PreIndex)); | 
| -    __ Cmp(copy_to, copy_end); | 
| -    __ B(hi, &fill); | 
| - | 
| -    // Correct the space allocated for the extra slot. | 
| -    __ Drop(1); | 
| -  } | 
| - | 
| -  // Arguments have been adapted. Now call the entry point. | 
| -  __ Bind(&invoke); | 
| -  __ Call(code_entry); | 
| - | 
| -  // Store offset of return address for deoptimizer. | 
| -  masm->isolate()->heap()->SetArgumentsAdaptorDeoptPCOffset(masm->pc_offset()); | 
| - | 
| -  // Exit frame and return. | 
| -  LeaveArgumentsAdaptorFrame(masm); | 
| -  __ Ret(); | 
| - | 
| -  // Call the entry point without adapting the arguments. | 
| -  __ Bind(&dont_adapt_arguments); | 
| -  __ Jump(code_entry); | 
| -} | 
| - | 
| - | 
| -#undef __ | 
| - | 
| -} }  // namespace v8::internal | 
| - | 
| -#endif  // V8_TARGET_ARCH_ARM | 
|  |