1fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org// Copyright 2012 the V8 project authors. All rights reserved.
25c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Redistribution and use in source and binary forms, with or without
35c838251403b0be9a882540f1922577abba4c872ager@chromium.org// modification, are permitted provided that the following conditions are
45c838251403b0be9a882540f1922577abba4c872ager@chromium.org// met:
55c838251403b0be9a882540f1922577abba4c872ager@chromium.org//
65c838251403b0be9a882540f1922577abba4c872ager@chromium.org//     * Redistributions of source code must retain the above copyright
75c838251403b0be9a882540f1922577abba4c872ager@chromium.org//       notice, this list of conditions and the following disclaimer.
85c838251403b0be9a882540f1922577abba4c872ager@chromium.org//     * Redistributions in binary form must reproduce the above
95c838251403b0be9a882540f1922577abba4c872ager@chromium.org//       copyright notice, this list of conditions and the following
105c838251403b0be9a882540f1922577abba4c872ager@chromium.org//       disclaimer in the documentation and/or other materials provided
115c838251403b0be9a882540f1922577abba4c872ager@chromium.org//       with the distribution.
125c838251403b0be9a882540f1922577abba4c872ager@chromium.org//     * Neither the name of Google Inc. nor the names of its
135c838251403b0be9a882540f1922577abba4c872ager@chromium.org//       contributors may be used to endorse or promote products derived
145c838251403b0be9a882540f1922577abba4c872ager@chromium.org//       from this software without specific prior written permission.
155c838251403b0be9a882540f1922577abba4c872ager@chromium.org//
165c838251403b0be9a882540f1922577abba4c872ager@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
175c838251403b0be9a882540f1922577abba4c872ager@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
185c838251403b0be9a882540f1922577abba4c872ager@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
195c838251403b0be9a882540f1922577abba4c872ager@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
205c838251403b0be9a882540f1922577abba4c872ager@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
215c838251403b0be9a882540f1922577abba4c872ager@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
225c838251403b0be9a882540f1922577abba4c872ager@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
235c838251403b0be9a882540f1922577abba4c872ager@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
245c838251403b0be9a882540f1922577abba4c872ager@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
255c838251403b0be9a882540f1922577abba4c872ager@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
265c838251403b0be9a882540f1922577abba4c872ager@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
275c838251403b0be9a882540f1922577abba4c872ager@chromium.org
285c838251403b0be9a882540f1922577abba4c872ager@chromium.org
295c838251403b0be9a882540f1922577abba4c872ager@chromium.org
305c838251403b0be9a882540f1922577abba4c872ager@chromium.org#include "v8.h"
315c838251403b0be9a882540f1922577abba4c872ager@chromium.org
3293a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_MIPS
339dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
3483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org#include "codegen.h"
355c838251403b0be9a882540f1922577abba4c872ager@chromium.org#include "debug.h"
367516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org#include "deoptimizer.h"
377516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org#include "full-codegen.h"
385c838251403b0be9a882540f1922577abba4c872ager@chromium.org#include "runtime.h"
395c838251403b0be9a882540f1922577abba4c872ager@chromium.org
405c838251403b0be9a882540f1922577abba4c872ager@chromium.orgnamespace v8 {
415c838251403b0be9a882540f1922577abba4c872ager@chromium.orgnamespace internal {
425c838251403b0be9a882540f1922577abba4c872ager@chromium.org
435c838251403b0be9a882540f1922577abba4c872ager@chromium.org
445c838251403b0be9a882540f1922577abba4c872ager@chromium.org#define __ ACCESS_MASM(masm)
455c838251403b0be9a882540f1922577abba4c872ager@chromium.org
465c838251403b0be9a882540f1922577abba4c872ager@chromium.org
475c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Builtins::Generate_Adaptor(MacroAssembler* masm,
485c838251403b0be9a882540f1922577abba4c872ager@chromium.org                                CFunctionId id,
495c838251403b0be9a882540f1922577abba4c872ager@chromium.org                                BuiltinExtraArguments extra_args) {
507304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // ----------- S t a t e -------------
517304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //  -- a0                 : number of arguments excluding receiver
527304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //  -- a1                 : called function (only guaranteed when
537304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //  --                      extra_args requires it)
547304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //  -- cp                 : context
557304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //  -- sp[0]              : last argument
567304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //  -- ...
577304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //  -- sp[4 * (argc - 1)] : first argument
587304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //  -- sp[4 * agrc]       : receiver
597304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // -----------------------------------
607304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
617304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // Insert extra arguments.
627304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  int num_extra_args = 0;
637304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  if (extra_args == NEEDS_CALLED_FUNCTION) {
647304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    num_extra_args = 1;
657304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ push(a1);
667304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  } else {
677304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    ASSERT(extra_args == NO_EXTRA_ARGUMENTS);
687304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  }
697304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
706ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org  // JumpToExternalReference expects s0 to contain the number of arguments
717304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // including the receiver and the extra arguments.
726ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org  __ Addu(s0, a0, num_extra_args + 1);
736ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org  __ sll(s1, s0, kPointerSizeLog2);
746ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org  __ Subu(s1, s1, kPointerSize);
757304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ JumpToExternalReference(ExternalReference(id, masm->isolate()));
767304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org}
777304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
787304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
79fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org// Load the built-in InternalArray function from the current context.
80fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.orgstatic void GenerateLoadInternalArrayFunction(MacroAssembler* masm,
81fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org                                              Register result) {
8246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // Load the native context.
83fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org
84fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org  __ lw(result,
8546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
8646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  __ lw(result,
8746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        FieldMemOperand(result, GlobalObject::kNativeContextOffset));
8846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // Load the InternalArray function from the native context.
89fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org  __ lw(result,
90fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org         MemOperand(result,
91fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org                    Context::SlotOffset(
92fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org                        Context::INTERNAL_ARRAY_FUNCTION_INDEX)));
93fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org}
94fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org
95fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org
967304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org// Load the built-in Array function from the current context.
977304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.orgstatic void GenerateLoadArrayFunction(MacroAssembler* masm, Register result) {
9846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // Load the native context.
997304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
1007304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ lw(result,
10146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
10246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  __ lw(result,
10346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        FieldMemOperand(result, GlobalObject::kNativeContextOffset));
10446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // Load the Array function from the native context.
1057304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ lw(result,
106fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org        MemOperand(result,
107fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org                   Context::SlotOffset(Context::ARRAY_FUNCTION_INDEX)));
1087304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org}
1097304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
1107304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
111fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.orgvoid Builtins::Generate_InternalArrayCode(MacroAssembler* masm) {
112fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org  // ----------- S t a t e -------------
113fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org  //  -- a0     : number of arguments
114fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org  //  -- ra     : return address
115fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org  //  -- sp[...]: constructor arguments
116fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org  // -----------------------------------
117fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org  Label generic_array_code, one_or_more_arguments, two_or_more_arguments;
118fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org
119fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org  // Get the InternalArray function.
120fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org  GenerateLoadInternalArrayFunction(masm, a1);
121fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org
122fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org  if (FLAG_debug_code) {
123fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org    // Initial map for the builtin InternalArray functions should be maps.
124fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org    __ lw(a2, FieldMemOperand(a1, JSFunction::kPrototypeOrInitialMapOffset));
1257ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org    __ SmiTst(a2, t0);
126594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    __ Assert(ne, kUnexpectedInitialMapForInternalArrayFunction,
127fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org              t0, Operand(zero_reg));
128fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org    __ GetObjectType(a2, a3, t0);
129594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    __ Assert(eq, kUnexpectedInitialMapForInternalArrayFunction,
130fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org              t0, Operand(MAP_TYPE));
131fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org  }
132fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org
133fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org  // Run the native code for the InternalArray function called as a normal
134fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org  // function.
1351510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  // Tail call a stub.
1361510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  InternalArrayConstructorStub stub(masm->isolate());
1371510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  __ TailCallStub(&stub);
1385c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
1395c838251403b0be9a882540f1922577abba4c872ager@chromium.org
1405c838251403b0be9a882540f1922577abba4c872ager@chromium.org
1415c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Builtins::Generate_ArrayCode(MacroAssembler* masm) {
1427304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // ----------- S t a t e -------------
1437304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //  -- a0     : number of arguments
1447304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //  -- ra     : return address
1457304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //  -- sp[...]: constructor arguments
1467304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // -----------------------------------
1477304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  Label generic_array_code;
1487304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
1497304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // Get the Array function.
1507304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  GenerateLoadArrayFunction(masm, a1);
1517304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
1527304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  if (FLAG_debug_code) {
1537304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // Initial map for the builtin Array functions should be maps.
1547304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ lw(a2, FieldMemOperand(a1, JSFunction::kPrototypeOrInitialMapOffset));
1557ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org    __ SmiTst(a2, t0);
156594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    __ Assert(ne, kUnexpectedInitialMapForArrayFunction1,
1577304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org              t0, Operand(zero_reg));
1587304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ GetObjectType(a2, a3, t0);
159594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    __ Assert(eq, kUnexpectedInitialMapForArrayFunction2,
1607304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org              t0, Operand(MAP_TYPE));
1617304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  }
1627304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
1637304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // Run the native code for the Array function called as a normal function.
1641510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  // Tail call a stub.
1651510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  Handle<Object> undefined_sentinel(
1661510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      masm->isolate()->heap()->undefined_value(),
1671510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org      masm->isolate());
1681510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  __ li(a2, Operand(undefined_sentinel));
1691510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  ArrayConstructorStub stub(masm->isolate());
1701510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  __ TailCallStub(&stub);
1715c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
1725c838251403b0be9a882540f1922577abba4c872ager@chromium.org
1735c838251403b0be9a882540f1922577abba4c872ager@chromium.org
1747516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Builtins::Generate_StringConstructCode(MacroAssembler* masm) {
1757304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // ----------- S t a t e -------------
1767304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //  -- a0                     : number of arguments
1777304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //  -- a1                     : constructor function
1787304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //  -- ra                     : return address
1797304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //  -- sp[(argc - n - 1) * 4] : arg[n] (zero based)
1807304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //  -- sp[argc * 4]           : receiver
1817304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // -----------------------------------
1827304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  Counters* counters = masm->isolate()->counters();
1837304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ IncrementCounter(counters->string_ctor_calls(), 1, a2, a3);
1847304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
1857304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  Register function = a1;
1867304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  if (FLAG_debug_code) {
1877304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ LoadGlobalFunction(Context::STRING_FUNCTION_INDEX, a2);
188594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    __ Assert(eq, kUnexpectedStringFunction, function, Operand(a2));
1897304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  }
1907304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
1917304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // Load the first arguments in a0 and get rid of the rest.
1927304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  Label no_arguments;
1937304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ Branch(&no_arguments, eq, a0, Operand(zero_reg));
1947304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // First args = sp[(argc - 1) * 4].
1957304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ Subu(a0, a0, Operand(1));
1967304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ sll(a0, a0, kPointerSizeLog2);
1977304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ Addu(sp, a0, sp);
1987304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ lw(a0, MemOperand(sp));
1997304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // sp now point to args[0], drop args[0] + receiver.
2007304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ Drop(2);
2017304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
2027304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  Register argument = a2;
2037304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  Label not_cached, argument_is_string;
204528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  __ LookupNumberStringCache(a0,        // Input.
205528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                             argument,  // Result.
206528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                             a3,        // Scratch.
207528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                             t0,        // Scratch.
208528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                             t1,        // Scratch.
209528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                             &not_cached);
2107304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ IncrementCounter(counters->string_ctor_cached_number(), 1, a3, t0);
2117304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ bind(&argument_is_string);
2127304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
2137304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // ----------- S t a t e -------------
2147304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //  -- a2     : argument converted to string
2157304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //  -- a1     : constructor function
2167304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //  -- ra     : return address
2177304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // -----------------------------------
2187304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
2197304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  Label gc_required;
2204c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org  __ Allocate(JSValue::kSize,
2214c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org              v0,  // Result.
2224c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org              a3,  // Scratch.
2234c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org              t0,  // Scratch.
2244c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org              &gc_required,
2254c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org              TAG_OBJECT);
2267304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
2277304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // Initialising the String Object.
2287304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  Register map = a3;
2297304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ LoadGlobalFunctionInitialMap(function, map, t0);
2307304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  if (FLAG_debug_code) {
2317304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ lbu(t0, FieldMemOperand(map, Map::kInstanceSizeOffset));
232594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    __ Assert(eq, kUnexpectedStringWrapperInstanceSize,
2337304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org        t0, Operand(JSValue::kSize >> kPointerSizeLog2));
2347304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ lbu(t0, FieldMemOperand(map, Map::kUnusedPropertyFieldsOffset));
235594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org    __ Assert(eq, kUnexpectedUnusedPropertiesOfStringWrapper,
2367304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org        t0, Operand(zero_reg));
2377304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  }
2387304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ sw(map, FieldMemOperand(v0, HeapObject::kMapOffset));
2397304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
2407304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ LoadRoot(a3, Heap::kEmptyFixedArrayRootIndex);
2417304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ sw(a3, FieldMemOperand(v0, JSObject::kPropertiesOffset));
2427304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ sw(a3, FieldMemOperand(v0, JSObject::kElementsOffset));
2437304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
2447304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ sw(argument, FieldMemOperand(v0, JSValue::kValueOffset));
2457304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
2467304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // Ensure the object is fully initialized.
2477304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize);
2487304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
2497304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ Ret();
2507304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
2517304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // The argument was not found in the number to string cache. Check
2527304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // if it's a string already before calling the conversion builtin.
2537304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  Label convert_argument;
2547304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ bind(&not_cached);
2557304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ JumpIfSmi(a0, &convert_argument);
2567304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
2577304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // Is it a String?
2587304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ lw(a2, FieldMemOperand(a0, HeapObject::kMapOffset));
2597304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ lbu(a3, FieldMemOperand(a2, Map::kInstanceTypeOffset));
2601805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  STATIC_ASSERT(kNotStringTag != 0);
2617304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ And(t0, a3, Operand(kIsNotStringMask));
2627304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ Branch(&convert_argument, ne, t0, Operand(zero_reg));
2637304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ mov(argument, a0);
2647304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ IncrementCounter(counters->string_ctor_conversions(), 1, a3, t0);
2657304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ Branch(&argument_is_string);
2667304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
2677304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // Invoke the conversion builtin and put the result into a2.
2687304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ bind(&convert_argument);
2697304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ push(function);  // Preserve the function.
2707304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ IncrementCounter(counters->string_ctor_conversions(), 1, a3, t0);
271c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  {
272c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    FrameScope scope(masm, StackFrame::INTERNAL);
273c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org    __ push(a0);
274c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ InvokeBuiltin(Builtins::TO_STRING, CALL_FUNCTION);
275c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
2767304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ pop(function);
2777304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ mov(argument, v0);
2787304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ Branch(&argument_is_string);
2797304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
2807304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // Load the empty string into a2, remove the receiver from the
2817304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // stack, and jump back to the case where the argument is a string.
2827304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ bind(&no_arguments);
283750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  __ LoadRoot(argument, Heap::kempty_stringRootIndex);
2847304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ Drop(1);
2857304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ Branch(&argument_is_string);
2867304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
2877304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // At this point the argument is already a string. Call runtime to
2887304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // create a string wrapper.
2897304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ bind(&gc_required);
2907304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ IncrementCounter(counters->string_ctor_gc_required(), 1, a3, t0);
291c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  {
292c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    FrameScope scope(masm, StackFrame::INTERNAL);
293c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ push(argument);
294c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ CallRuntime(Runtime::kNewStringWrapper, 1);
295c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
2967304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ Ret();
2977516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org}
2987516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
2997516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
3004a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.orgstatic void CallRuntimePassFunction(MacroAssembler* masm,
3014a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org                                    Runtime::FunctionId function_id) {
3024a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  FrameScope scope(masm, StackFrame::INTERNAL);
3034a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  // Push a copy of the function onto the stack.
304057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  // Push call kind information and function as parameter to the runtime call.
305057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  __ Push(a1, t1, a1);
3064a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org
3074a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  __ CallRuntime(function_id, 1);
308057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  // Restore call kind information and receiver.
309057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  __ Pop(a1, t1);
3104a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org}
3114a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org
3124a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org
313129d398d682e6ca3910808c913212ce532f1e155danno@chromium.orgstatic void GenerateTailCallToSharedCode(MacroAssembler* masm) {
314129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org  __ lw(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
315129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org  __ lw(a2, FieldMemOperand(a2, SharedFunctionInfo::kCodeOffset));
316129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org  __ Addu(at, a2, Operand(Code::kHeaderSize - kHeapObjectTag));
317129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org  __ Jump(at);
318129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org}
319129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org
320129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org
321129d398d682e6ca3910808c913212ce532f1e155danno@chromium.orgvoid Builtins::Generate_InRecompileQueue(MacroAssembler* masm) {
3224a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  // Checking whether the queued function is ready for install is optional,
3234a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  // since we come across interrupts and stack checks elsewhere.  However,
3244a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  // not checking may delay installing ready functions, and always checking
3254a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  // would be quite expensive.  A good compromise is to first check against
3264a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  // stack limit as a cue for an interrupt signal.
3274a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  Label ok;
3284a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  __ LoadRoot(t0, Heap::kStackLimitRootIndex);
3294a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  __ Branch(&ok, hs, sp, Operand(t0));
3304a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org
3314a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  CallRuntimePassFunction(masm, Runtime::kTryInstallRecompiledCode);
3324a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  // Tail call to returned code.
3334a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  __ Addu(at, v0, Operand(Code::kHeaderSize - kHeapObjectTag));
3344a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  __ Jump(at);
3356e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
3364a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  __ bind(&ok);
3374a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  GenerateTailCallToSharedCode(masm);
3386e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org}
3396e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
3406e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org
3419259716434187c932704601f700375e53d865de8rossberg@chromium.orgvoid Builtins::Generate_ConcurrentRecompile(MacroAssembler* masm) {
3424a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  CallRuntimePassFunction(masm, Runtime::kConcurrentRecompile);
343129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org  GenerateTailCallToSharedCode(masm);
344129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org}
345129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org
346129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org
347fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.orgstatic void Generate_JSConstructStubHelper(MacroAssembler* masm,
348fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org                                           bool is_api_function,
349fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org                                           bool count_constructions) {
3507304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // ----------- S t a t e -------------
3517304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //  -- a0     : number of arguments
3527304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //  -- a1     : constructor function
3537304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //  -- ra     : return address
3547304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //  -- sp[...]: constructor arguments
3557304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // -----------------------------------
3567304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
3577304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // Should never count constructions for api objects.
3587304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  ASSERT(!is_api_function || !count_constructions);
3597304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
3607304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  Isolate* isolate = masm->isolate();
3617304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
3627304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // ----------- S t a t e -------------
3637304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //  -- a0     : number of arguments
3647304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //  -- a1     : constructor function
3657304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //  -- ra     : return address
3667304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //  -- sp[...]: constructor arguments
3677304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // -----------------------------------
3687304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
3697304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // Enter a construct frame.
370c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  {
371c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    FrameScope scope(masm, StackFrame::CONSTRUCT);
3727304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
373c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Preserve the two incoming parameters on the stack.
374c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ sll(a0, a0, kSmiTagSize);  // Tag arguments count.
375c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ MultiPushReversed(a0.bit() | a1.bit());
3767304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
377c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Use t7 to hold undefined, which is used in several places below.
378c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ LoadRoot(t7, Heap::kUndefinedValueRootIndex);
3797304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
380c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Label rt_call, allocated;
381c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Try to allocate the object without transitioning into C code. If any of
382c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // the preconditions is not met, the code bails out to the runtime call.
383c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (FLAG_inline_new) {
384c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Label undo_allocation;
3857304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org#ifdef ENABLE_DEBUGGER_SUPPORT
386c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      ExternalReference debug_step_in_fp =
387c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          ExternalReference::debug_step_in_fp_address(isolate);
388c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ li(a2, Operand(debug_step_in_fp));
389c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ lw(a2, MemOperand(a2));
390c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ Branch(&rt_call, ne, a2, Operand(zero_reg));
3917304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org#endif
3927304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
393c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // Load the initial map and verify that it is in fact a map.
394c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // a1: constructor function
395c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ lw(a2, FieldMemOperand(a1, JSFunction::kPrototypeOrInitialMapOffset));
396c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      __ JumpIfSmi(a2, &rt_call);
397c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ GetObjectType(a2, a3, t4);
398c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ Branch(&rt_call, ne, t4, Operand(MAP_TYPE));
399c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
400c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // Check that the constructor is not constructing a JSFunction (see
401c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // comments in Runtime_NewObject in runtime.cc). In which case the
402c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // initial map's instance type would be JS_FUNCTION_TYPE.
403c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // a1: constructor function
404c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // a2: initial map
405c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ lbu(a3, FieldMemOperand(a2, Map::kInstanceTypeOffset));
406c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ Branch(&rt_call, eq, a3, Operand(JS_FUNCTION_TYPE));
4077304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
4087304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org      if (count_constructions) {
409c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        Label allocate;
410c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        // Decrease generous allocation count.
411c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        __ lw(a3, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
412c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        MemOperand constructor_count =
413c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com           FieldMemOperand(a3, SharedFunctionInfo::kConstructionCountOffset);
414c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        __ lbu(t0, constructor_count);
415c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        __ Subu(t0, t0, Operand(1));
416c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        __ sb(t0, constructor_count);
417c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        __ Branch(&allocate, ne, t0, Operand(zero_reg));
418c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
419057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org        __ Push(a1, a2, a1);  // a1 = Constructor.
420c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        // The call will replace the stub, so the countdown is only done once.
421c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        __ CallRuntime(Runtime::kFinalizeInstanceSize, 1);
422c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
423057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org        __ Pop(a1, a2);
424c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
425c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        __ bind(&allocate);
4267304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org      }
4277304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
428c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // Now allocate the JSObject on the heap.
429c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // a1: constructor function
430c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // a2: initial map
431c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ lbu(a3, FieldMemOperand(a2, Map::kInstanceSizeOffset));
432f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      __ Allocate(a3, t4, t5, t6, &rt_call, SIZE_IN_WORDS);
433c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
434c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // Allocated the JSObject, now initialize the fields. Map is set to
435c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // initial map and properties and elements are set to empty fixed array.
436c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // a1: constructor function
437c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // a2: initial map
438c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // a3: object size
439c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // t4: JSObject (not tagged)
440c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ LoadRoot(t6, Heap::kEmptyFixedArrayRootIndex);
441c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ mov(t5, t4);
442c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ sw(a2, MemOperand(t5, JSObject::kMapOffset));
443c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ sw(t6, MemOperand(t5, JSObject::kPropertiesOffset));
444c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ sw(t6, MemOperand(t5, JSObject::kElementsOffset));
445c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ Addu(t5, t5, Operand(3*kPointerSize));
446c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      ASSERT_EQ(0 * kPointerSize, JSObject::kMapOffset);
447c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      ASSERT_EQ(1 * kPointerSize, JSObject::kPropertiesOffset);
448c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      ASSERT_EQ(2 * kPointerSize, JSObject::kElementsOffset);
449c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
450c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // Fill all the in-object properties with appropriate filler.
451c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // a1: constructor function
452c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // a2: initial map
453c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // a3: object size (in words)
454c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // t4: JSObject (not tagged)
455c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // t5: First in-object property of JSObject (not tagged)
456c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ sll(t0, a3, kPointerSizeLog2);
457c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ addu(t6, t4, t0);   // End of object.
458c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      ASSERT_EQ(3 * kPointerSize, JSObject::kHeaderSize);
459b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      __ LoadRoot(t7, Heap::kUndefinedValueRootIndex);
460b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      if (count_constructions) {
461b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org        __ lw(a0, FieldMemOperand(a2, Map::kInstanceSizesOffset));
462b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org        __ Ext(a0, a0, Map::kPreAllocatedPropertyFieldsByte * kBitsPerByte,
463b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                kBitsPerByte);
464b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org        __ sll(t0, a0, kPointerSizeLog2);
465b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org        __ addu(a0, t5, t0);
466b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org        // a0: offset of first field after pre-allocated fields
467b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org        if (FLAG_debug_code) {
468594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org          __ Assert(le, kUnexpectedNumberOfPreAllocatedPropertyFields,
469b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org              a0, Operand(t6));
470c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        }
471b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org        __ InitializeFieldsWithFiller(t5, a0, t7);
472b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org        // To allow for truncation.
473b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org        __ LoadRoot(t7, Heap::kOnePointerFillerMapRootIndex);
474c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      }
475b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      __ InitializeFieldsWithFiller(t5, t6, t7);
4767304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
477c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // Add the object tag to make the JSObject real, so that we can continue
478c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // and jump into the continuation code at any time from now on. Any
479c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // failures need to undo the allocation, so that the heap is in a
480c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // consistent state and verifiable.
481c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ Addu(t4, t4, Operand(kHeapObjectTag));
482c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
483c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // Check if a non-empty properties array is needed. Continue with
484c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // allocated object if not fall through to runtime call if it is.
485c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // a1: constructor function
486c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // t4: JSObject
487c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // t5: start of next object (not tagged)
488c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ lbu(a3, FieldMemOperand(a2, Map::kUnusedPropertyFieldsOffset));
489c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // The field instance sizes contains both pre-allocated property fields
490c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // and in-object properties.
491c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ lw(a0, FieldMemOperand(a2, Map::kInstanceSizesOffset));
492b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      __ Ext(t6, a0, Map::kPreAllocatedPropertyFieldsByte * kBitsPerByte,
493b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org             kBitsPerByte);
494b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      __ Addu(a3, a3, Operand(t6));
495b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      __ Ext(t6, a0, Map::kInObjectPropertiesByte * kBitsPerByte,
496b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org              kBitsPerByte);
497b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      __ subu(a3, a3, t6);
498c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
499c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // Done if no extra properties are to be allocated.
500c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ Branch(&allocated, eq, a3, Operand(zero_reg));
501594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org      __ Assert(greater_equal, kPropertyAllocationCountFailed,
502c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          a3, Operand(zero_reg));
503c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
504c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // Scale the number of elements by pointer size and add the header for
505c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // FixedArrays to the start of the next object calculation from above.
506c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // a1: constructor
507c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // a3: number of elements in properties array
508c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // t4: JSObject
509c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // t5: start of next object
510c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ Addu(a0, a3, Operand(FixedArray::kHeaderSize / kPointerSize));
511f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      __ Allocate(
512c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          a0,
513c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          t5,
514c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          t6,
515c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          a2,
516c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          &undo_allocation,
517c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          static_cast<AllocationFlags>(RESULT_CONTAINS_TOP | SIZE_IN_WORDS));
518c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
519c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // Initialize the FixedArray.
520c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // a1: constructor
5212efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org      // a3: number of elements in properties array (untagged)
522c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // t4: JSObject
523c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // t5: start of next object
524c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ LoadRoot(t6, Heap::kFixedArrayMapRootIndex);
525c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ mov(a2, t5);
526c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ sw(t6, MemOperand(a2, JSObject::kMapOffset));
527c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ sll(a0, a3, kSmiTagSize);
528c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ sw(a0, MemOperand(a2, FixedArray::kLengthOffset));
529c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ Addu(a2, a2, Operand(2 * kPointerSize));
530c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
531c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      ASSERT_EQ(0 * kPointerSize, JSObject::kMapOffset);
532c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      ASSERT_EQ(1 * kPointerSize, FixedArray::kLengthOffset);
533c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
534c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // Initialize the fields to undefined.
535c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // a1: constructor
536c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // a2: First element of FixedArray (not tagged)
537c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // a3: number of elements in properties array
538c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // t4: JSObject
539c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // t5: FixedArray (not tagged)
540c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ sll(t3, a3, kPointerSizeLog2);
541c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ addu(t6, a2, t3);  // End of object.
542c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      ASSERT_EQ(2 * kPointerSize, FixedArray::kHeaderSize);
543c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      { Label loop, entry;
544c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        if (count_constructions) {
545c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          __ LoadRoot(t7, Heap::kUndefinedValueRootIndex);
546c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        } else if (FLAG_debug_code) {
547c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          __ LoadRoot(t8, Heap::kUndefinedValueRootIndex);
548594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org          __ Assert(eq, kUndefinedValueNotLoaded, t7, Operand(t8));
549c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        }
550c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        __ jmp(&entry);
551c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        __ bind(&loop);
552c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        __ sw(t7, MemOperand(a2));
553c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        __ addiu(a2, a2, kPointerSize);
554c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        __ bind(&entry);
555c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        __ Branch(&loop, less, a2, Operand(t6));
5567304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org      }
557c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
558c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // Store the initialized FixedArray into the properties field of
559c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // the JSObject.
560c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // a1: constructor function
561c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // t4: JSObject
562c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // t5: FixedArray (not tagged)
563c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ Addu(t5, t5, Operand(kHeapObjectTag));  // Add the heap tag.
564c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ sw(t5, FieldMemOperand(t4, JSObject::kPropertiesOffset));
565c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
566c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // Continue with JSObject being successfully allocated.
567c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // a1: constructor function
568c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // a4: JSObject
569c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ jmp(&allocated);
570c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
571c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // Undo the setting of the new top so that the heap is verifiable. For
572c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // example, the map's unused properties potentially do not match the
573c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // allocated objects unused properties.
574c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // t4: JSObject (previous new top)
575c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ bind(&undo_allocation);
576c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ UndoAllocationInNewSpace(t4, t5);
5777304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    }
5787304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
579c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ bind(&rt_call);
580c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Allocate the new receiver object using the runtime call.
5817304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // a1: constructor function
582c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ push(a1);  // Argument for Runtime_NewObject.
583c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ CallRuntime(Runtime::kNewObject, 1);
584c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ mov(t4, v0);
5857304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
586c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Receiver for constructor call allocated.
587c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // t4: JSObject
588c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ bind(&allocated);
589c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ push(t4);
59078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    __ push(t4);
5917304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
592c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Reload the number of arguments from the stack.
593c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // sp[0]: receiver
59478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    // sp[1]: receiver
59578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    // sp[2]: constructor function
59678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    // sp[3]: number of arguments (smi-tagged)
59778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    __ lw(a1, MemOperand(sp, 2 * kPointerSize));
59878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    __ lw(a3, MemOperand(sp, 3 * kPointerSize));
5997304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
600f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    // Set up pointer to last argument.
601c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ Addu(a2, fp, Operand(StandardFrameConstants::kCallerSPOffset));
6027304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
603f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    // Set up number of arguments for function call below.
604c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ srl(a0, a3, kSmiTagSize);
6057304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
606c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Copy arguments and receiver to the expression stack.
607c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // a0: number of arguments
608c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // a1: constructor function
609c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // a2: address of last argument (caller sp)
610c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // a3: number of arguments (smi-tagged)
611c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // sp[0]: receiver
61278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    // sp[1]: receiver
61378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    // sp[2]: constructor function
61478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org    // sp[3]: number of arguments (smi-tagged)
615c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Label loop, entry;
616c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ jmp(&entry);
617c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ bind(&loop);
618c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ sll(t0, a3, kPointerSizeLog2 - kSmiTagSize);
619c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ Addu(t0, a2, Operand(t0));
620c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ lw(t1, MemOperand(t0));
621c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ push(t1);
622c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ bind(&entry);
623c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ Addu(a3, a3, Operand(-2));
624c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ Branch(&loop, greater_equal, a3, Operand(zero_reg));
6257304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
626c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Call the function.
627c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // a0: number of arguments
628c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // a1: constructor function
629c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (is_api_function) {
630c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
631c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Handle<Code> code =
632c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          masm->isolate()->builtins()->HandleApiCallConstruct();
633c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      ParameterCount expected(0);
634c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ InvokeCode(code, expected, expected,
635c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                    RelocInfo::CODE_TARGET, CALL_FUNCTION, CALL_AS_METHOD);
636c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    } else {
637c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      ParameterCount actual(a0);
638c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ InvokeFunction(a1, actual, CALL_FUNCTION,
639c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                        NullCallWrapper(), CALL_AS_METHOD);
640c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
6417304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
642812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    // Store offset of return address for deoptimizer.
643812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    if (!is_api_function && !count_constructions) {
644812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org      masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset());
645812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org    }
646812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
647c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Restore context from the frame.
648c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
649c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
650c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // If the result is an object (in the ECMA sense), we should get rid
651c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // of the receiver and use the result; see ECMA-262 section 13.2.2-7
652c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // on page 74.
653c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Label use_receiver, exit;
654c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
655c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // If the result is a smi, it is *not* an object in the ECMA sense.
656c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // v0: result
657c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // sp[0]: receiver (newly allocated object)
658c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // sp[1]: constructor function
659c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // sp[2]: number of arguments (smi-tagged)
660c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ JumpIfSmi(v0, &use_receiver);
661c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
662c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // If the type of the result (stored in its map) is less than
663c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // FIRST_SPEC_OBJECT_TYPE, it is not an object in the ECMA sense.
6649faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org    __ GetObjectType(v0, a1, a3);
665c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ Branch(&exit, greater_equal, a3, Operand(FIRST_SPEC_OBJECT_TYPE));
666c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
667c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Throw away the result of the constructor invocation and use the
668c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // on-stack receiver as the result.
669c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ bind(&use_receiver);
670c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ lw(v0, MemOperand(sp));
671c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
672c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Remove receiver from the stack, remove caller arguments, and
673c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // return.
674c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ bind(&exit);
675c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // v0: result
676c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // sp[0]: receiver (newly allocated object)
677c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // sp[1]: constructor function
678c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // sp[2]: number of arguments (smi-tagged)
679c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ lw(a1, MemOperand(sp, 2 * kPointerSize));
680c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
681c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Leave construct frame.
6827304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  }
6837304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
6847304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ sll(t0, a1, kPointerSizeLog2 - 1);
6857304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ Addu(sp, sp, t0);
6867304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ Addu(sp, sp, kPointerSize);
6877304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ IncrementCounter(isolate->counters()->constructed_objects(), 1, a1, a2);
6887304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ Ret();
6895c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
6905c838251403b0be9a882540f1922577abba4c872ager@chromium.org
6915c838251403b0be9a882540f1922577abba4c872ager@chromium.org
6927516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Builtins::Generate_JSConstructStubCountdown(MacroAssembler* masm) {
6937304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  Generate_JSConstructStubHelper(masm, false, true);
6945c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
6955c838251403b0be9a882540f1922577abba4c872ager@chromium.org
6965c838251403b0be9a882540f1922577abba4c872ager@chromium.org
6977516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
6987304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  Generate_JSConstructStubHelper(masm, false, false);
6995c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
7005c838251403b0be9a882540f1922577abba4c872ager@chromium.org
7015c838251403b0be9a882540f1922577abba4c872ager@chromium.org
7027516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
7037304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  Generate_JSConstructStubHelper(masm, true, false);
7047304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org}
7057304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
7067304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
7077304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.orgstatic void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
7087304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org                                             bool is_construct) {
7097304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // Called from JSEntryStub::GenerateBody
7107304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
7117304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // ----------- S t a t e -------------
7127304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //  -- a0: code entry
7137304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //  -- a1: function
7142efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  //  -- a2: receiver_pointer
7157304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //  -- a3: argc
7167304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //  -- s0: argv
7177304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // -----------------------------------
71807237aaaed914a17c1afd64234883bff619581d5palfia@homejinni.com  ProfileEntryHookStub::MaybeCallEntryHook(masm);
7197304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
7207304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // Clear the context before we push it when entering the JS frame.
7217304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ mov(cp, zero_reg);
7227304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
7237304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // Enter an internal frame.
724c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  {
725c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    FrameScope scope(masm, StackFrame::INTERNAL);
7267304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
727c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Set up the context from the function argument.
728c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
7297304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
730c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Push the function and the receiver onto the stack.
731c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ Push(a1, a2);
7327304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
733c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Copy arguments to the stack in a loop.
734c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // a3: argc
7352efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org    // s0: argv, i.e. points to first arg
736c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Label loop, entry;
737c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ sll(t0, a3, kPointerSizeLog2);
738c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ addu(t2, s0, t0);
739c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ b(&entry);
740c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ nop();   // Branch delay slot nop.
741c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // t2 points past last arg.
742c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ bind(&loop);
743c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ lw(t0, MemOperand(s0));  // Read next parameter.
744c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ addiu(s0, s0, kPointerSize);
745c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ lw(t0, MemOperand(t0));  // Dereference handle.
746c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ push(t0);  // Push parameter.
747c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ bind(&entry);
748c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ Branch(&loop, ne, s0, Operand(t2));
749c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
750c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Initialize all JavaScript callee-saved registers, since they will be seen
751c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // by the garbage collector as part of handlers.
752c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ LoadRoot(t0, Heap::kUndefinedValueRootIndex);
753c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ mov(s1, t0);
754c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ mov(s2, t0);
755c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ mov(s3, t0);
756c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ mov(s4, t0);
757c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ mov(s5, t0);
758c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // s6 holds the root address. Do not clobber.
759c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // s7 is cp. Do not init.
760c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
761c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Invoke the code and pass argc as a0.
762c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ mov(a0, a3);
763c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (is_construct) {
764750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      // No type feedback cell is available
765750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      Handle<Object> undefined_sentinel(
766750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org          masm->isolate()->heap()->undefined_value(), masm->isolate());
767750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      __ li(a2, Operand(undefined_sentinel));
768fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org      CallConstructStub stub(NO_CALL_FUNCTION_FLAGS);
769fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org      __ CallStub(&stub);
770c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    } else {
771c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      ParameterCount actual(a0);
772c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ InvokeFunction(a1, actual, CALL_FUNCTION,
773c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                        NullCallWrapper(), CALL_AS_METHOD);
774c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
7757304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
776c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Leave internal frame.
777c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
7787304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
7797304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ Jump(ra);
7805c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
7815c838251403b0be9a882540f1922577abba4c872ager@chromium.org
7825c838251403b0be9a882540f1922577abba4c872ager@chromium.org
7835c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) {
7847304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  Generate_JSEntryTrampolineHelper(masm, false);
7855c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
7865c838251403b0be9a882540f1922577abba4c872ager@chromium.org
7875c838251403b0be9a882540f1922577abba4c872ager@chromium.org
7885c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) {
7897304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  Generate_JSEntryTrampolineHelper(masm, true);
7907516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org}
7917516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
7927516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
7937516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Builtins::Generate_LazyCompile(MacroAssembler* masm) {
7944a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  CallRuntimePassFunction(masm, Runtime::kLazyCompile);
7957304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // Do a tail-call of the compiled function.
7964a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  __ Addu(t9, v0, Operand(Code::kHeaderSize - kHeapObjectTag));
7977304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ Jump(t9);
7987516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org}
7997516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
8007516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
8017516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Builtins::Generate_LazyRecompile(MacroAssembler* masm) {
8024a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  CallRuntimePassFunction(masm, Runtime::kLazyRecompile);
8037304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // Do a tail-call of the compiled function.
8044a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  __ Addu(t9, v0, Operand(Code::kHeaderSize - kHeapObjectTag));
8057304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ Jump(t9);
8067516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org}
8077516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
8087516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
809fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.orgstatic void GenerateMakeCodeYoungAgainCommon(MacroAssembler* masm) {
810fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  // For now, we are relying on the fact that make_code_young doesn't do any
811fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  // garbage collection which allows us to save/restore the registers without
812fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  // worrying about which of them contain pointers. We also don't build an
813fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  // internal frame to make the code faster, since we shouldn't have to do stack
814fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  // crawls in MakeCodeYoung. This seems a bit fragile.
815fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
816f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  // Set a0 to point to the head of the PlatformCodeAge sequence.
817fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  __ Subu(a0, a0,
818fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      Operand((kNoCodeAgeSequenceLength - 1) * Assembler::kInstrSize));
819fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
820fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  // The following registers must be saved and restored when calling through to
821fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  // the runtime:
822fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  //   a0 - contains return address (beginning of patch sequence)
823528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  //   a1 - isolate
824fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  RegList saved_regs =
825fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      (a0.bit() | a1.bit() | ra.bit() | fp.bit()) & ~sp.bit();
826fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  FrameScope scope(masm, StackFrame::MANUAL);
827fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  __ MultiPush(saved_regs);
828528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  __ PrepareCallCFunction(1, 0, a2);
829528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  __ li(a1, Operand(ExternalReference::isolate_address(masm->isolate())));
830fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  __ CallCFunction(
831528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org      ExternalReference::get_make_code_young_function(masm->isolate()), 2);
832fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  __ MultiPop(saved_regs);
833fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  __ Jump(a0);
834fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org}
835fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
836fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org#define DEFINE_CODE_AGE_BUILTIN_GENERATOR(C)                 \
837fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.orgvoid Builtins::Generate_Make##C##CodeYoungAgainEvenMarking(  \
838fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    MacroAssembler* masm) {                                  \
839fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  GenerateMakeCodeYoungAgainCommon(masm);                    \
840fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org}                                                            \
841fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.orgvoid Builtins::Generate_Make##C##CodeYoungAgainOddMarking(   \
842fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    MacroAssembler* masm) {                                  \
843fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  GenerateMakeCodeYoungAgainCommon(masm);                    \
844fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org}
845fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.orgCODE_AGE_LIST(DEFINE_CODE_AGE_BUILTIN_GENERATOR)
846fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org#undef DEFINE_CODE_AGE_BUILTIN_GENERATOR
847fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
848fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
849c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.orgvoid Builtins::Generate_MarkCodeAsExecutedOnce(MacroAssembler* masm) {
850c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  // For now, as in GenerateMakeCodeYoungAgainCommon, we are relying on the fact
851c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  // that make_code_young doesn't do any garbage collection which allows us to
852c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  // save/restore the registers without worrying about which of them contain
853c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  // pointers.
854c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org
855f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  // Set a0 to point to the head of the PlatformCodeAge sequence.
856c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  __ Subu(a0, a0,
857c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org      Operand((kNoCodeAgeSequenceLength - 1) * Assembler::kInstrSize));
858c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org
859c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  // The following registers must be saved and restored when calling through to
860c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  // the runtime:
861c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  //   a0 - contains return address (beginning of patch sequence)
862c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  //   a1 - isolate
863c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  RegList saved_regs =
864c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org      (a0.bit() | a1.bit() | ra.bit() | fp.bit()) & ~sp.bit();
865c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  FrameScope scope(masm, StackFrame::MANUAL);
866c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  __ MultiPush(saved_regs);
867c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  __ PrepareCallCFunction(1, 0, a2);
868c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  __ li(a1, Operand(ExternalReference::isolate_address(masm->isolate())));
869c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  __ CallCFunction(
870c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org      ExternalReference::get_mark_code_as_executed_function(masm->isolate()),
871c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org      2);
872c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  __ MultiPop(saved_regs);
873c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org
874c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  // Perform prologue operations usually performed by the young code stub.
875c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  __ Push(ra, fp, cp, a1);
8767ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org  __ Addu(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
877c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org
878c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  // Jump to point after the code-age stub.
879c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  __ Addu(a0, a0, Operand((kNoCodeAgeSequenceLength) * Assembler::kInstrSize));
880c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  __ Jump(a0);
881c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org}
882c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org
883c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org
884c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.orgvoid Builtins::Generate_MarkCodeAsExecutedTwice(MacroAssembler* masm) {
885c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  GenerateMakeCodeYoungAgainCommon(masm);
886c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org}
887c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org
888c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org
889f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.orgstatic void Generate_NotifyStubFailureHelper(MacroAssembler* masm,
890f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                                             SaveFPRegsMode save_doubles) {
89159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  {
89259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    FrameScope scope(masm, StackFrame::INTERNAL);
89359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org
89459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    // Preserve registers across notification, this is important for compiled
89559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    // stubs that tail call the runtime on deopts passing their parameters in
89659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    // registers.
89759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    __ MultiPush(kJSCallerSaved | kCalleeSaved);
89859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    // Pass the function and deoptimization type to the runtime system.
899f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    __ CallRuntime(Runtime::kNotifyStubFailure, 0, save_doubles);
90059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    __ MultiPop(kJSCallerSaved | kCalleeSaved);
90159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  }
90259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org
90359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  __ Addu(sp, sp, Operand(kPointerSize));  // Ignore state
904e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org  __ Jump(ra);  // Jump to miss handler
90559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org}
90659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org
90759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org
908f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.orgvoid Builtins::Generate_NotifyStubFailure(MacroAssembler* masm) {
909f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  Generate_NotifyStubFailureHelper(masm, kDontSaveFPRegs);
910f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org}
911f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org
912f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org
913f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.orgvoid Builtins::Generate_NotifyStubFailureSaveDoubles(MacroAssembler* masm) {
914f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  Generate_NotifyStubFailureHelper(masm, kSaveFPRegs);
915f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org}
916f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org
917f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org
918c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgstatic void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm,
919c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                             Deoptimizer::BailoutType type) {
920c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  {
921c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    FrameScope scope(masm, StackFrame::INTERNAL);
922c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    // Pass the function and deoptimization type to the runtime system.
923c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ li(a0, Operand(Smi::FromInt(static_cast<int>(type))));
924c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ push(a0);
925c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ CallRuntime(Runtime::kNotifyDeoptimized, 1);
926c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
927c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
928c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Get the full codegen state from the stack and untag it -> t2.
929c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(t2, MemOperand(sp, 0 * kPointerSize));
930c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ SmiUntag(t2);
931c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Switch on the state.
932c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Label with_tos_register, unknown_state;
933c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Branch(&with_tos_register,
934c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org            ne, t2, Operand(FullCodeGenerator::NO_REGISTERS));
9358a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org  __ Ret(USE_DELAY_SLOT);
9368a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org  // Safe to fill delay slot Addu will emit one instruction.
937c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Addu(sp, sp, Operand(1 * kPointerSize));  // Remove state.
938c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
939c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ bind(&with_tos_register);
940c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(v0, MemOperand(sp, 1 * kPointerSize));
941c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Branch(&unknown_state, ne, t2, Operand(FullCodeGenerator::TOS_REG));
942c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
9438a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org  __ Ret(USE_DELAY_SLOT);
9448a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org  // Safe to fill delay slot Addu will emit one instruction.
945c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ Addu(sp, sp, Operand(2 * kPointerSize));  // Remove state.
946c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
947c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ bind(&unknown_state);
948c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ stop("no cases left");
949c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org}
950c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
951c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
9527516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) {
953c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::EAGER);
9547516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org}
9557516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
9567516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
9570410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.comvoid Builtins::Generate_NotifySoftDeoptimized(MacroAssembler* masm) {
9580410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.com  Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::SOFT);
9590410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.com}
9600410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.com
9610410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.com
9627516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Builtins::Generate_NotifyLazyDeoptimized(MacroAssembler* masm) {
963c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::LAZY);
9647516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org}
9657516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
9667516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
9677516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Builtins::Generate_OnStackReplacement(MacroAssembler* masm) {
968e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org  // Lookup the function in the JavaScript frame.
969c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ lw(a0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
970c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  {
971c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    FrameScope scope(masm, StackFrame::INTERNAL);
972e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org    // Lookup and calculate pc offset.
973e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org    __ lw(a1, MemOperand(fp, StandardFrameConstants::kCallerPCOffset));
974e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org    __ lw(a2, FieldMemOperand(a0, JSFunction::kSharedFunctionInfoOffset));
975e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org    __ lw(a2, FieldMemOperand(a2, SharedFunctionInfo::kCodeOffset));
976e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org    __ Subu(a1, a1, Operand(Code::kHeaderSize - kHeapObjectTag));
977e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org    __ Subu(a1, a1, a2);
978e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org    __ SmiTag(a1);
979e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org
980e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org    // Pass both function and pc offset as arguments.
981c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ push(a0);
982e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org    __ push(a1);
983e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org    __ CallRuntime(Runtime::kCompileForOnStackReplacement, 2);
984c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
985c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
986c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  // If the code object is null, just return to the unoptimized code.
987c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  __ Ret(eq, v0, Operand(Smi::FromInt(0)));
988c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org
989c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  // Load deoptimization data from the code object.
990c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  // <deopt_data> = <code>[#deoptimization_data_offset]
991c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  __ lw(a1, MemOperand(v0, Code::kDeoptimizationDataOffset - kHeapObjectTag));
992c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org
993c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  // Load the OSR entrypoint offset from the deoptimization data.
994c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  // <osr_offset> = <deopt_data>[#header_size + #osr_pc_offset]
995c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  __ lw(a1, MemOperand(a1, FixedArray::OffsetOfElementAt(
996c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org      DeoptimizationInputData::kOsrPcOffsetIndex) - kHeapObjectTag));
997c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  __ SmiUntag(a1);
998c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org
999c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  // Compute the target address = code_obj + header_size + osr_offset
1000c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  // <entry_addr> = <code_obj> + #header_size + <osr_offset>
1001c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  __ addu(v0, v0, a1);
1002c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  __ addiu(ra, v0, Code::kHeaderSize - kHeapObjectTag);
1003c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org
1004c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  // And "return" to the OSR entry point of the function.
1005c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  __ Ret();
10065c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
10075c838251403b0be9a882540f1922577abba4c872ager@chromium.org
10085c838251403b0be9a882540f1922577abba4c872ager@chromium.org
10098e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.orgvoid Builtins::Generate_OsrAfterStackCheck(MacroAssembler* masm) {
10108e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  // We check the stack limit as indicator that recompilation might be done.
10118e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  Label ok;
10128e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  __ LoadRoot(at, Heap::kStackLimitRootIndex);
10138e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  __ Branch(&ok, hs, sp, Operand(at));
10148e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  {
10158e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org    FrameScope scope(masm, StackFrame::INTERNAL);
10168e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org    __ CallRuntime(Runtime::kStackGuard, 0);
10178e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  }
10188e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  __ Jump(masm->isolate()->builtins()->OnStackReplacement(),
10198e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org          RelocInfo::CODE_TARGET);
10208e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org
10218e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  __ bind(&ok);
10228e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org  __ Ret();
10238e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org}
10248e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org
10258e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org
10265c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Builtins::Generate_FunctionCall(MacroAssembler* masm) {
10277304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // 1. Make sure we have at least one argument.
10287304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // a0: actual number of arguments
10297304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  { Label done;
10307304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ Branch(&done, ne, a0, Operand(zero_reg));
10317304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ LoadRoot(t2, Heap::kUndefinedValueRootIndex);
10327304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ push(t2);
10337304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ Addu(a0, a0, Operand(1));
10347304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ bind(&done);
10357304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  }
10367304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
10377304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // 2. Get the function to call (passed as receiver) from the stack, check
10387304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //    if it is a function.
10397304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // a0: actual number of arguments
1040c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Label slow, non_function;
10417304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ sll(at, a0, kPointerSizeLog2);
10427304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ addu(at, sp, at);
10437304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ lw(a1, MemOperand(at));
1044c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  __ JumpIfSmi(a1, &non_function);
10457304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ GetObjectType(a1, a2, a2);
1046c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  __ Branch(&slow, ne, a2, Operand(JS_FUNCTION_TYPE));
10477304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
10487304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // 3a. Patch the first argument if necessary when calling a function.
10497304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // a0: actual number of arguments
10507304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // a1: function
10517304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  Label shift_arguments;
105259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  __ li(t0, Operand(0, RelocInfo::NONE32));  // Indicate regular JS_FUNCTION.
10537304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  { Label convert_to_object, use_global_receiver, patch_receiver;
10547304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // Change context eagerly in case we need the global receiver.
10557304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
10567304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
10577304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // Do not transform the receiver for strict mode functions.
10587304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ lw(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
10597304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ lw(a3, FieldMemOperand(a2, SharedFunctionInfo::kCompilerHintsOffset));
1060c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ And(t3, a3, Operand(1 << (SharedFunctionInfo::kStrictModeFunction +
10617304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org                                 kSmiTagSize)));
1062c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ Branch(&shift_arguments, ne, t3, Operand(zero_reg));
10637304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
106440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org    // Do not transform the receiver for native (Compilerhints already in a3).
1065c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ And(t3, a3, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize)));
1066c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ Branch(&shift_arguments, ne, t3, Operand(zero_reg));
10677304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
10687304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // Compute the receiver in non-strict mode.
10697304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // Load first argument in a2. a2 = -kPointerSize(sp + n_args << 2).
10707304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ sll(at, a0, kPointerSizeLog2);
10717304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ addu(a2, sp, at);
10727304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ lw(a2, MemOperand(a2, -kPointerSize));
10737304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // a0: actual number of arguments
10747304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // a1: function
10757304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // a2: first argument
10767304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ JumpIfSmi(a2, &convert_to_object, t2);
10777304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
107840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org    __ LoadRoot(a3, Heap::kUndefinedValueRootIndex);
10797304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ Branch(&use_global_receiver, eq, a2, Operand(a3));
10807304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ LoadRoot(a3, Heap::kNullValueRootIndex);
10817304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ Branch(&use_global_receiver, eq, a2, Operand(a3));
10827304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
1083d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com    STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE);
10847304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ GetObjectType(a2, a3, a3);
1085d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com    __ Branch(&shift_arguments, ge, a3, Operand(FIRST_SPEC_OBJECT_TYPE));
10867304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
10877304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ bind(&convert_to_object);
1088c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Enter an internal frame in order to preserve argument count.
1089c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    {
1090c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      FrameScope scope(masm, StackFrame::INTERNAL);
1091c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ sll(a0, a0, kSmiTagSize);  // Smi tagged.
1092c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ push(a0);
1093c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1094c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ push(a2);
1095c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
1096c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ mov(a2, v0);
1097c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1098c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ pop(a0);
1099c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ sra(a0, a0, kSmiTagSize);  // Un-tag.
1100c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // Leave internal frame.
1101c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
1102c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Restore the function to a1, and the flag to t0.
11037304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ sll(at, a0, kPointerSizeLog2);
11047304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ addu(at, sp, at);
11057304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ lw(a1, MemOperand(at));
110659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    __ li(t0, Operand(0, RelocInfo::NONE32));
11077304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ Branch(&patch_receiver);
11087304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
11097304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // Use the global receiver object from the called function as the
11107304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // receiver.
11117304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ bind(&use_global_receiver);
11127304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    const int kGlobalIndex =
111346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        Context::kHeaderSize + Context::GLOBAL_OBJECT_INDEX * kPointerSize;
11147304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ lw(a2, FieldMemOperand(cp, kGlobalIndex));
111546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    __ lw(a2, FieldMemOperand(a2, GlobalObject::kNativeContextOffset));
11167304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ lw(a2, FieldMemOperand(a2, kGlobalIndex));
11177304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ lw(a2, FieldMemOperand(a2, GlobalObject::kGlobalReceiverOffset));
11187304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
11197304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ bind(&patch_receiver);
11207304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ sll(at, a0, kPointerSizeLog2);
11217304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ addu(a3, sp, at);
11227304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ sw(a2, MemOperand(a3, -kPointerSize));
11237304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
11247304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ Branch(&shift_arguments);
11257304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  }
11267304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
1127c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // 3b. Check for function proxy.
1128c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  __ bind(&slow);
112959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  __ li(t0, Operand(1, RelocInfo::NONE32));  // Indicate function proxy.
1130c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  __ Branch(&shift_arguments, eq, a2, Operand(JS_FUNCTION_PROXY_TYPE));
1131c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1132c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  __ bind(&non_function);
113359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  __ li(t0, Operand(2, RelocInfo::NONE32));  // Indicate non-function.
1134c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1135c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // 3c. Patch the first argument when calling a non-function.  The
11367304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //     CALL_NON_FUNCTION builtin expects the non-function callee as
11377304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //     receiver, so overwrite the first argument which will ultimately
11387304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //     become the receiver.
11397304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // a0: actual number of arguments
11407304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // a1: function
1141c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // t0: call type (0: JS function, 1: function proxy, 2: non-function)
11427304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ sll(at, a0, kPointerSizeLog2);
11437304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ addu(a2, sp, at);
11447304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ sw(a1, MemOperand(a2, -kPointerSize));
11457304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
11467304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // 4. Shift arguments and return address one slot down on the stack
11477304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //    (overwriting the original receiver).  Adjust argument count to make
11487304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //    the original first argument the new receiver.
11497304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // a0: actual number of arguments
11507304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // a1: function
1151c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // t0: call type (0: JS function, 1: function proxy, 2: non-function)
11527304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ bind(&shift_arguments);
11537304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  { Label loop;
11547304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // Calculate the copy start address (destination). Copy end address is sp.
11557304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ sll(at, a0, kPointerSizeLog2);
11567304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ addu(a2, sp, at);
11577304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
11587304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ bind(&loop);
11597304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ lw(at, MemOperand(a2, -kPointerSize));
11607304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ sw(at, MemOperand(a2));
11617304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ Subu(a2, a2, Operand(kPointerSize));
11627304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ Branch(&loop, ne, a2, Operand(sp));
11637304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // Adjust the actual number of arguments and remove the top element
11647304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // (which is a copy of the last argument).
11657304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ Subu(a0, a0, Operand(1));
11667304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ Pop();
11677304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  }
11687304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
1169c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin,
1170c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  //     or a function proxy via CALL_FUNCTION_PROXY.
11717304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // a0: actual number of arguments
11727304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // a1: function
1173c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // t0: call type (0: JS function, 1: function proxy, 2: non-function)
1174c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  { Label function, non_proxy;
1175c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ Branch(&function, eq, t0, Operand(zero_reg));
1176c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Expected number of arguments is 0 for CALL_NON_FUNCTION.
1177c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ mov(a2, zero_reg);
117840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org    __ SetCallKind(t1, CALL_AS_METHOD);
1179c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ Branch(&non_proxy, ne, t0, Operand(1));
1180c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1181c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ push(a1);  // Re-add proxy object as additional argument.
1182c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ Addu(a0, a0, Operand(1));
1183c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ GetBuiltinEntry(a3, Builtins::CALL_FUNCTION_PROXY);
1184c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
1185c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com            RelocInfo::CODE_TARGET);
1186c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1187c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ bind(&non_proxy);
1188c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ GetBuiltinEntry(a3, Builtins::CALL_NON_FUNCTION);
11897304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
11907304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org            RelocInfo::CODE_TARGET);
11917304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ bind(&function);
11927304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  }
11937304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
11947304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // 5b. Get the code to call from the function and check that the number of
11957304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //     expected arguments matches what we're providing.  If so, jump
11967304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //     (tail-call) to the code in register edx without checking arguments.
11977304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // a0: actual number of arguments
11987304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // a1: function
11997304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ lw(a3, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
12007304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ lw(a2,
12017304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org         FieldMemOperand(a3, SharedFunctionInfo::kFormalParameterCountOffset));
12027304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ sra(a2, a2, kSmiTagSize);
12037304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset));
120440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  __ SetCallKind(t1, CALL_AS_METHOD);
12057304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // Check formal and actual parameter counts.
12067304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
12077304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org          RelocInfo::CODE_TARGET, ne, a2, Operand(a0));
12087304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
12097304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  ParameterCount expected(0);
1210d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  __ InvokeCode(a3, expected, expected, JUMP_FUNCTION,
1211d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com                NullCallWrapper(), CALL_AS_METHOD);
12125c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
12135c838251403b0be9a882540f1922577abba4c872ager@chromium.org
12145c838251403b0be9a882540f1922577abba4c872ager@chromium.org
12155c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Builtins::Generate_FunctionApply(MacroAssembler* masm) {
12167ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org  const int kIndexOffset    =
12177ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org      StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize);
12187ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org  const int kLimitOffset    =
12197ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org      StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize);
12207ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org  const int kArgsOffset     = 2 * kPointerSize;
12217ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org  const int kRecvOffset     = 3 * kPointerSize;
12227ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org  const int kFunctionOffset = 4 * kPointerSize;
12237304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
1224c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  {
1225c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    FrameScope frame_scope(masm, StackFrame::INTERNAL);
1226c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ lw(a0, MemOperand(fp, kFunctionOffset));  // Get the function.
1227c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ push(a0);
1228c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ lw(a0, MemOperand(fp, kArgsOffset));  // Get the args array.
1229c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ push(a0);
1230c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Returns (in v0) number of arguments to copy to stack as Smi.
1231c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION);
1232c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1233c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Check the stack for overflow. We are not trying to catch
1234c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // interruptions (e.g. debug break and preemption) here, so the "real stack
1235c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // limit" is checked.
1236c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Label okay;
1237c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ LoadRoot(a2, Heap::kRealStackLimitRootIndex);
1238c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Make a2 the space we have left. The stack might already be overflowed
1239c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // here which will cause a2 to become negative.
1240c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ subu(a2, sp, a2);
1241c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Check if the arguments will overflow the stack.
1242c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ sll(t3, v0, kPointerSizeLog2 - kSmiTagSize);
1243c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ Branch(&okay, gt, a2, Operand(t3));  // Signed comparison.
1244c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1245c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Out of stack space.
1246c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ lw(a1, MemOperand(fp, kFunctionOffset));
1247057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    __ Push(a1, v0);
1248c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ InvokeBuiltin(Builtins::APPLY_OVERFLOW, CALL_FUNCTION);
1249c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // End of stack check.
1250c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1251c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Push current limit and index.
1252c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ bind(&okay);
1253c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ push(v0);  // Limit.
1254c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ mov(a1, zero_reg);  // Initial index.
1255c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ push(a1);
12567304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
1257c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Get the receiver.
1258c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ lw(a0, MemOperand(fp, kRecvOffset));
12597304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
1260c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Check that the function is a JS function (otherwise it must be a proxy).
1261c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Label push_receiver;
1262c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ lw(a1, MemOperand(fp, kFunctionOffset));
1263c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ GetObjectType(a1, a2, a2);
1264c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ Branch(&push_receiver, ne, a2, Operand(JS_FUNCTION_TYPE));
12657304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
1266c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Change context eagerly to get the right global object if necessary.
1267c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
1268c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Load the shared function info while the function is still in a1.
1269c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ lw(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
12707304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
1271c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Compute the receiver.
1272c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Do not transform the receiver for strict mode functions.
1273c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Label call_to_object, use_global_receiver;
1274c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ lw(a2, FieldMemOperand(a2, SharedFunctionInfo::kCompilerHintsOffset));
1275c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ And(t3, a2, Operand(1 << (SharedFunctionInfo::kStrictModeFunction +
1276c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                 kSmiTagSize)));
1277c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ Branch(&push_receiver, ne, t3, Operand(zero_reg));
1278c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1279c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Do not transform the receiver for native (Compilerhints already in a2).
1280c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ And(t3, a2, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize)));
1281c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ Branch(&push_receiver, ne, t3, Operand(zero_reg));
1282c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1283c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Compute the receiver in non-strict mode.
1284c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    __ JumpIfSmi(a0, &call_to_object);
1285c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ LoadRoot(a1, Heap::kNullValueRootIndex);
1286c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ Branch(&use_global_receiver, eq, a0, Operand(a1));
1287c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
1288c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ Branch(&use_global_receiver, eq, a0, Operand(a2));
1289c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1290c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Check if the receiver is already a JavaScript object.
1291c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // a0: receiver
1292c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE);
1293c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ GetObjectType(a0, a1, a1);
1294c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ Branch(&push_receiver, ge, a1, Operand(FIRST_SPEC_OBJECT_TYPE));
1295c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1296c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Convert the receiver to a regular object.
1297c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // a0: receiver
1298c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ bind(&call_to_object);
1299c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ push(a0);
1300c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
1301c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ mov(a0, v0);  // Put object in a0 to match other paths to push_receiver.
1302c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ Branch(&push_receiver);
1303c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1304c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Use the current global receiver object as the receiver.
1305c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ bind(&use_global_receiver);
1306c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    const int kGlobalOffset =
130746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org        Context::kHeaderSize + Context::GLOBAL_OBJECT_INDEX * kPointerSize;
1308c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ lw(a0, FieldMemOperand(cp, kGlobalOffset));
130946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org    __ lw(a0, FieldMemOperand(a0, GlobalObject::kNativeContextOffset));
1310c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ lw(a0, FieldMemOperand(a0, kGlobalOffset));
1311c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ lw(a0, FieldMemOperand(a0, GlobalObject::kGlobalReceiverOffset));
1312c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1313c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Push the receiver.
1314c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // a0: receiver
1315c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ bind(&push_receiver);
1316c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ push(a0);
1317c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1318c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Copy all arguments from the array to the stack.
1319c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Label entry, loop;
1320c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ lw(a0, MemOperand(fp, kIndexOffset));
1321c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ Branch(&entry);
1322c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1323c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Load the current argument from the arguments array and push it to the
1324c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // stack.
1325c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // a0: current argument index
1326c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ bind(&loop);
1327c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ lw(a1, MemOperand(fp, kArgsOffset));
1328057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    __ Push(a1, a0);
1329c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1330c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Call the runtime to access the property in the arguments array.
1331c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ CallRuntime(Runtime::kGetProperty, 2);
1332c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ push(v0);
1333c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1334c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Use inline caching to access the arguments.
1335c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ lw(a0, MemOperand(fp, kIndexOffset));
1336c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ Addu(a0, a0, Operand(1 << kSmiTagSize));
1337c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ sw(a0, MemOperand(fp, kIndexOffset));
1338c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1339c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Test if the copy loop has finished copying all the elements from the
1340c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // arguments object.
1341c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ bind(&entry);
1342c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ lw(a1, MemOperand(fp, kLimitOffset));
1343c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ Branch(&loop, ne, a0, Operand(a1));
1344c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1345c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Invoke the function.
1346c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Label call_proxy;
1347c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    ParameterCount actual(a0);
1348c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ sra(a0, a0, kSmiTagSize);
1349c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ lw(a1, MemOperand(fp, kFunctionOffset));
1350c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ GetObjectType(a1, a2, a2);
1351c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ Branch(&call_proxy, ne, a2, Operand(JS_FUNCTION_TYPE));
1352c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1353c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ InvokeFunction(a1, actual, CALL_FUNCTION,
1354c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                      NullCallWrapper(), CALL_AS_METHOD);
1355c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1356c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    frame_scope.GenerateLeaveFrame();
1357c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ Ret(USE_DELAY_SLOT);
1358c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ Addu(sp, sp, Operand(3 * kPointerSize));  // In delay slot.
1359c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1360c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Invoke the function proxy.
1361c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ bind(&call_proxy);
1362c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ push(a1);  // Add function proxy as last argument.
1363c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ Addu(a0, a0, Operand(1));
136459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    __ li(a2, Operand(0, RelocInfo::NONE32));
1365c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ SetCallKind(t1, CALL_AS_METHOD);
1366c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ GetBuiltinEntry(a3, Builtins::CALL_FUNCTION_PROXY);
1367c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ Call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
1368c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com            RelocInfo::CODE_TARGET);
1369c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Tear down the internal frame and remove function, receiver and args.
1370c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
1371c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1372c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  __ Ret(USE_DELAY_SLOT);
1373c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  __ Addu(sp, sp, Operand(3 * kPointerSize));  // In delay slot.
13747304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org}
13757304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
13767304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
13777304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.orgstatic void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
13787304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ sll(a0, a0, kSmiTagSize);
13797304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ li(t0, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
13807304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ MultiPush(a0.bit() | a1.bit() | t0.bit() | fp.bit() | ra.bit());
13817ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org  __ Addu(fp, sp,
13827ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org      Operand(StandardFrameConstants::kFixedFrameSizeFromFp + kPointerSize));
13837304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org}
13847304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
13857304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
13867304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.orgstatic void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) {
13877304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // ----------- S t a t e -------------
13887304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //  -- v0 : result being passed through
13897304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // -----------------------------------
13907304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // Get the number of arguments passed (as a smi), tear down the frame and
13917304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // then tear down the parameters.
13927ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org  __ lw(a1, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp +
13937ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org                             kPointerSize)));
13947304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ mov(sp, fp);
13957304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ MultiPop(fp.bit() | ra.bit());
13967304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ sll(t0, a1, kPointerSizeLog2 - kSmiTagSize);
13977304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ Addu(sp, sp, t0);
13987304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // Adjust for the receiver.
13997304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ Addu(sp, sp, Operand(kPointerSize));
14005c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
14015c838251403b0be9a882540f1922577abba4c872ager@chromium.org
14025c838251403b0be9a882540f1922577abba4c872ager@chromium.org
14035c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
14047304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // State setup as expected by MacroAssembler::InvokePrologue.
14057304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // ----------- S t a t e -------------
14067304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //  -- a0: actual arguments count
14077304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //  -- a1: function (passed through to callee)
14087304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //  -- a2: expected arguments count
14097304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //  -- a3: callee code entry
141040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org  //  -- t1: call kind information
14117304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // -----------------------------------
14127304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
14137304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  Label invoke, dont_adapt_arguments;
14147304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
14157304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  Label enough, too_few;
14167304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ Branch(&dont_adapt_arguments, eq,
14177304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org      a2, Operand(SharedFunctionInfo::kDontAdaptArgumentsSentinel));
14187304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // We use Uless as the number of argument should always be greater than 0.
14197304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ Branch(&too_few, Uless, a0, Operand(a2));
14207304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
14217304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  {  // Enough parameters: actual >= expected.
14227304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // a0: actual number of arguments as a smi
14237304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // a1: function
14247304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // a2: expected number of arguments
14257304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // a3: code entry to call
14267304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ bind(&enough);
14277304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    EnterArgumentsAdaptorFrame(masm);
14287304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
14297304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // Calculate copy start address into a0 and copy end address into a2.
14307304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ sll(a0, a0, kPointerSizeLog2 - kSmiTagSize);
14317304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ Addu(a0, fp, a0);
14327304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // Adjust for return address and receiver.
14337304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ Addu(a0, a0, Operand(2 * kPointerSize));
14347304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // Compute copy end address.
14357304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ sll(a2, a2, kPointerSizeLog2);
14367304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ subu(a2, a0, a2);
14377304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
14387304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // Copy the arguments (including the receiver) to the new stack frame.
14397304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // a0: copy start address
14407304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // a1: function
14417304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // a2: copy end address
14427304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // a3: code entry to call
14437304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
14447304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    Label copy;
14457304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ bind(&copy);
14467304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ lw(t0, MemOperand(a0));
14477304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ push(t0);
14487304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ Branch(USE_DELAY_SLOT, &copy, ne, a0, Operand(a2));
14497304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ addiu(a0, a0, -kPointerSize);  // In delay slot.
14507304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
14517304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ jmp(&invoke);
14527304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  }
14537304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
14547304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  {  // Too few parameters: Actual < expected.
14557304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ bind(&too_few);
14567304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    EnterArgumentsAdaptorFrame(masm);
14577304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
14587304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // Calculate copy start address into a0 and copy end address is fp.
14597304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // a0: actual number of arguments as a smi
14607304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // a1: function
14617304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // a2: expected number of arguments
14627304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // a3: code entry to call
14637304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ sll(a0, a0, kPointerSizeLog2 - kSmiTagSize);
14647304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ Addu(a0, fp, a0);
14657304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // Adjust for return address and receiver.
14667304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ Addu(a0, a0, Operand(2 * kPointerSize));
14677304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // Compute copy end address. Also adjust for return address.
1468d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com    __ Addu(t3, fp, kPointerSize);
14697304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
14707304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // Copy the arguments (including the receiver) to the new stack frame.
14717304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // a0: copy start address
14727304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // a1: function
14737304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // a2: expected number of arguments
14747304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // a3: code entry to call
1475d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com    // t3: copy end address
14767304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    Label copy;
14777304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ bind(&copy);
14787304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ lw(t0, MemOperand(a0));  // Adjusted above for return addr and receiver.
1479bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    __ Subu(sp, sp, kPointerSize);
14807304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ Subu(a0, a0, kPointerSize);
1481bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    __ Branch(USE_DELAY_SLOT, &copy, ne, a0, Operand(t3));
1482bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    __ sw(t0, MemOperand(sp));  // In the delay slot.
14837304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
14847304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // Fill the remaining expected arguments with undefined.
14857304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // a1: function
14867304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // a2: expected number of arguments
14877304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    // a3: code entry to call
14887304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ LoadRoot(t0, Heap::kUndefinedValueRootIndex);
14897304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ sll(t2, a2, kPointerSizeLog2);
14907304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ Subu(a2, fp, Operand(t2));
14917ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org    // Adjust for frame.
14927ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org    __ Subu(a2, a2, Operand(StandardFrameConstants::kFixedFrameSizeFromFp +
14937ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org                            2 * kPointerSize));
14947304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
14957304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    Label fill;
14967304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ bind(&fill);
1497bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    __ Subu(sp, sp, kPointerSize);
1498bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    __ Branch(USE_DELAY_SLOT, &fill, ne, sp, Operand(a2));
1499bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com    __ sw(t0, MemOperand(sp));
15007304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  }
15017304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
15027304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // Call the entry point.
15037304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ bind(&invoke);
15047304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
15057304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ Call(a3);
15067304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
1507812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  // Store offset of return address for deoptimizer.
1508fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  masm->isolate()->heap()->SetArgumentsAdaptorDeoptPCOffset(masm->pc_offset());
1509812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org
15107304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // Exit frame and return.
15117304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  LeaveArgumentsAdaptorFrame(masm);
15127304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ Ret();
15137304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
15147304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
15157304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // -------------------------------------------
15167304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // Don't adapt arguments.
15177304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // -------------------------------------------
15187304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ bind(&dont_adapt_arguments);
15197304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ Jump(a3);
15205c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
15215c838251403b0be9a882540f1922577abba4c872ager@chromium.org
15225c838251403b0be9a882540f1922577abba4c872ager@chromium.org
15235c838251403b0be9a882540f1922577abba4c872ager@chromium.org#undef __
15245c838251403b0be9a882540f1922577abba4c872ager@chromium.org
15255c838251403b0be9a882540f1922577abba4c872ager@chromium.org} }  // namespace v8::internal
15265c838251403b0be9a882540f1922577abba4c872ager@chromium.org
15279dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com#endif  // V8_TARGET_ARCH_MIPS
1528