1fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be 33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file. 45c838251403b0be9a882540f1922577abba4c872ager@chromium.org 55c838251403b0be9a882540f1922577abba4c872ager@chromium.org 65c838251403b0be9a882540f1922577abba4c872ager@chromium.org 7196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h" 85c838251403b0be9a882540f1922577abba4c872ager@chromium.org 993a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_MIPS 109dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/codegen.h" 12196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/debug.h" 13196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/deoptimizer.h" 14196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/full-codegen.h" 15196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/runtime.h" 166474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 175c838251403b0be9a882540f1922577abba4c872ager@chromium.org 185c838251403b0be9a882540f1922577abba4c872ager@chromium.orgnamespace v8 { 195c838251403b0be9a882540f1922577abba4c872ager@chromium.orgnamespace internal { 205c838251403b0be9a882540f1922577abba4c872ager@chromium.org 215c838251403b0be9a882540f1922577abba4c872ager@chromium.org 225c838251403b0be9a882540f1922577abba4c872ager@chromium.org#define __ ACCESS_MASM(masm) 235c838251403b0be9a882540f1922577abba4c872ager@chromium.org 245c838251403b0be9a882540f1922577abba4c872ager@chromium.org 255c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Builtins::Generate_Adaptor(MacroAssembler* masm, 265c838251403b0be9a882540f1922577abba4c872ager@chromium.org CFunctionId id, 275c838251403b0be9a882540f1922577abba4c872ager@chromium.org BuiltinExtraArguments extra_args) { 287304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // ----------- S t a t e ------------- 297304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // -- a0 : number of arguments excluding receiver 307304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // -- a1 : called function (only guaranteed when 317304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // -- extra_args requires it) 327304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // -- cp : context 337304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // -- sp[0] : last argument 347304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // -- ... 357304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // -- sp[4 * (argc - 1)] : first argument 367304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // -- sp[4 * agrc] : receiver 377304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // ----------------------------------- 387304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 397304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // Insert extra arguments. 407304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org int num_extra_args = 0; 417304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (extra_args == NEEDS_CALLED_FUNCTION) { 427304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org num_extra_args = 1; 437304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ push(a1); 447304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } else { 45e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(extra_args == NO_EXTRA_ARGUMENTS); 467304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 477304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 486ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org // JumpToExternalReference expects s0 to contain the number of arguments 497304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // including the receiver and the extra arguments. 506ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org __ Addu(s0, a0, num_extra_args + 1); 516ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org __ sll(s1, s0, kPointerSizeLog2); 526ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org __ Subu(s1, s1, kPointerSize); 537304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ JumpToExternalReference(ExternalReference(id, masm->isolate())); 547304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org} 557304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 567304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 57fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org// Load the built-in InternalArray function from the current context. 58fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.orgstatic void GenerateLoadInternalArrayFunction(MacroAssembler* masm, 59fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org Register result) { 6046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Load the native context. 61fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org 62fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org __ lw(result, 6346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 6446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ lw(result, 6546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org FieldMemOperand(result, GlobalObject::kNativeContextOffset)); 6646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Load the InternalArray function from the native context. 67fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org __ lw(result, 68fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org MemOperand(result, 69fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org Context::SlotOffset( 70fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org Context::INTERNAL_ARRAY_FUNCTION_INDEX))); 71fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org} 72fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org 73fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org 747304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org// Load the built-in Array function from the current context. 757304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.orgstatic void GenerateLoadArrayFunction(MacroAssembler* masm, Register result) { 7646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Load the native context. 777304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 787304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ lw(result, 7946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 8046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ lw(result, 8146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org FieldMemOperand(result, GlobalObject::kNativeContextOffset)); 8246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Load the Array function from the native context. 837304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ lw(result, 84fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org MemOperand(result, 85fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org Context::SlotOffset(Context::ARRAY_FUNCTION_INDEX))); 867304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org} 877304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 887304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 89fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.orgvoid Builtins::Generate_InternalArrayCode(MacroAssembler* masm) { 90fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org // ----------- S t a t e ------------- 91fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org // -- a0 : number of arguments 92fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org // -- ra : return address 93fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org // -- sp[...]: constructor arguments 94fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org // ----------------------------------- 95fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org Label generic_array_code, one_or_more_arguments, two_or_more_arguments; 96fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org 97fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org // Get the InternalArray function. 98fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org GenerateLoadInternalArrayFunction(masm, a1); 99fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org 100fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org if (FLAG_debug_code) { 101fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org // Initial map for the builtin InternalArray functions should be maps. 102fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org __ lw(a2, FieldMemOperand(a1, JSFunction::kPrototypeOrInitialMapOffset)); 1037ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org __ SmiTst(a2, t0); 104594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Assert(ne, kUnexpectedInitialMapForInternalArrayFunction, 105fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org t0, Operand(zero_reg)); 106fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org __ GetObjectType(a2, a3, t0); 107594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Assert(eq, kUnexpectedInitialMapForInternalArrayFunction, 108fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org t0, Operand(MAP_TYPE)); 109fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org } 110fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org 111fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org // Run the native code for the InternalArray function called as a normal 112fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org // function. 1131510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org // Tail call a stub. 1141510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org InternalArrayConstructorStub stub(masm->isolate()); 1151510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ TailCallStub(&stub); 1165c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 1175c838251403b0be9a882540f1922577abba4c872ager@chromium.org 1185c838251403b0be9a882540f1922577abba4c872ager@chromium.org 1195c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Builtins::Generate_ArrayCode(MacroAssembler* masm) { 1207304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // ----------- S t a t e ------------- 1217304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // -- a0 : number of arguments 1227304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // -- ra : return address 1237304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // -- sp[...]: constructor arguments 1247304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // ----------------------------------- 1257304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Label generic_array_code; 1267304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 1277304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // Get the Array function. 1287304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org GenerateLoadArrayFunction(masm, a1); 1297304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 1307304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (FLAG_debug_code) { 1317304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // Initial map for the builtin Array functions should be maps. 1327304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ lw(a2, FieldMemOperand(a1, JSFunction::kPrototypeOrInitialMapOffset)); 1337ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org __ SmiTst(a2, t0); 134594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Assert(ne, kUnexpectedInitialMapForArrayFunction1, 1357304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org t0, Operand(zero_reg)); 1367304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ GetObjectType(a2, a3, t0); 137594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Assert(eq, kUnexpectedInitialMapForArrayFunction2, 1387304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org t0, Operand(MAP_TYPE)); 1397304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 1407304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 1417304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // Run the native code for the Array function called as a normal function. 1421510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org // Tail call a stub. 14369f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); 1441510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ArrayConstructorStub stub(masm->isolate()); 1451510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ TailCallStub(&stub); 1465c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 1475c838251403b0be9a882540f1922577abba4c872ager@chromium.org 1485c838251403b0be9a882540f1922577abba4c872ager@chromium.org 1497516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Builtins::Generate_StringConstructCode(MacroAssembler* masm) { 1507304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // ----------- S t a t e ------------- 1517304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // -- a0 : number of arguments 1527304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // -- a1 : constructor function 1537304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // -- ra : return address 1547304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // -- sp[(argc - n - 1) * 4] : arg[n] (zero based) 1557304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // -- sp[argc * 4] : receiver 1567304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // ----------------------------------- 1577304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Counters* counters = masm->isolate()->counters(); 1587304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ IncrementCounter(counters->string_ctor_calls(), 1, a2, a3); 1597304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 1607304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Register function = a1; 1617304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (FLAG_debug_code) { 1627304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ LoadGlobalFunction(Context::STRING_FUNCTION_INDEX, a2); 163594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Assert(eq, kUnexpectedStringFunction, function, Operand(a2)); 1647304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 1657304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 1667304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // Load the first arguments in a0 and get rid of the rest. 1677304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Label no_arguments; 1687304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ Branch(&no_arguments, eq, a0, Operand(zero_reg)); 1697304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // First args = sp[(argc - 1) * 4]. 1707304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ Subu(a0, a0, Operand(1)); 1717304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ sll(a0, a0, kPointerSizeLog2); 1727304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ Addu(sp, a0, sp); 1737304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ lw(a0, MemOperand(sp)); 1747304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // sp now point to args[0], drop args[0] + receiver. 1757304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ Drop(2); 1767304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 1777304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Register argument = a2; 1787304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Label not_cached, argument_is_string; 179528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ LookupNumberStringCache(a0, // Input. 180528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org argument, // Result. 181528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org a3, // Scratch. 182528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org t0, // Scratch. 183528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org t1, // Scratch. 184528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org ¬_cached); 1857304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ IncrementCounter(counters->string_ctor_cached_number(), 1, a3, t0); 1867304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ bind(&argument_is_string); 1877304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 1887304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // ----------- S t a t e ------------- 1897304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // -- a2 : argument converted to string 1907304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // -- a1 : constructor function 1917304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // -- ra : return address 1927304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // ----------------------------------- 1937304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 1947304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Label gc_required; 1954c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org __ Allocate(JSValue::kSize, 1964c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org v0, // Result. 1974c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org a3, // Scratch. 1984c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org t0, // Scratch. 1994c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org &gc_required, 2004c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org TAG_OBJECT); 2017304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 2027304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // Initialising the String Object. 2037304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Register map = a3; 2047304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ LoadGlobalFunctionInitialMap(function, map, t0); 2057304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (FLAG_debug_code) { 2067304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ lbu(t0, FieldMemOperand(map, Map::kInstanceSizeOffset)); 207594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Assert(eq, kUnexpectedStringWrapperInstanceSize, 2087304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org t0, Operand(JSValue::kSize >> kPointerSizeLog2)); 2097304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ lbu(t0, FieldMemOperand(map, Map::kUnusedPropertyFieldsOffset)); 210594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Assert(eq, kUnexpectedUnusedPropertiesOfStringWrapper, 2117304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org t0, Operand(zero_reg)); 2127304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 2137304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ sw(map, FieldMemOperand(v0, HeapObject::kMapOffset)); 2147304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 2157304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ LoadRoot(a3, Heap::kEmptyFixedArrayRootIndex); 2167304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ sw(a3, FieldMemOperand(v0, JSObject::kPropertiesOffset)); 2177304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ sw(a3, FieldMemOperand(v0, JSObject::kElementsOffset)); 2187304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 2197304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ sw(argument, FieldMemOperand(v0, JSValue::kValueOffset)); 2207304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 2217304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // Ensure the object is fully initialized. 2227304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); 2237304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 2247304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ Ret(); 2257304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 2267304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // The argument was not found in the number to string cache. Check 2277304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // if it's a string already before calling the conversion builtin. 2287304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Label convert_argument; 2297304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ bind(¬_cached); 2307304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ JumpIfSmi(a0, &convert_argument); 2317304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 2327304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // Is it a String? 2337304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ lw(a2, FieldMemOperand(a0, HeapObject::kMapOffset)); 2347304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ lbu(a3, FieldMemOperand(a2, Map::kInstanceTypeOffset)); 2351805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org STATIC_ASSERT(kNotStringTag != 0); 2367304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ And(t0, a3, Operand(kIsNotStringMask)); 2377304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ Branch(&convert_argument, ne, t0, Operand(zero_reg)); 2387304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ mov(argument, a0); 2397304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ IncrementCounter(counters->string_ctor_conversions(), 1, a3, t0); 2407304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ Branch(&argument_is_string); 2417304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 2427304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // Invoke the conversion builtin and put the result into a2. 2437304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ bind(&convert_argument); 2447304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ push(function); // Preserve the function. 2457304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ IncrementCounter(counters->string_ctor_conversions(), 1, a3, t0); 246c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com { 247c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FrameScope scope(masm, StackFrame::INTERNAL); 248c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org __ push(a0); 249c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ InvokeBuiltin(Builtins::TO_STRING, CALL_FUNCTION); 250c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 2517304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ pop(function); 2527304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ mov(argument, v0); 2537304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ Branch(&argument_is_string); 2547304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 2557304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // Load the empty string into a2, remove the receiver from the 2567304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // stack, and jump back to the case where the argument is a string. 2577304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ bind(&no_arguments); 258750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org __ LoadRoot(argument, Heap::kempty_stringRootIndex); 2597304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ Drop(1); 2607304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ Branch(&argument_is_string); 2617304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 2627304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // At this point the argument is already a string. Call runtime to 2637304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // create a string wrapper. 2647304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ bind(&gc_required); 2657304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ IncrementCounter(counters->string_ctor_gc_required(), 1, a3, t0); 266c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com { 267c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FrameScope scope(masm, StackFrame::INTERNAL); 268c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ push(argument); 269c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ CallRuntime(Runtime::kNewStringWrapper, 1); 270c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 2717304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ Ret(); 2727516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 2737516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 2747516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 2754954674151afa960af66efb4831df06bde727333yangguo@chromium.orgstatic void CallRuntimePassFunction( 2764954674151afa960af66efb4831df06bde727333yangguo@chromium.org MacroAssembler* masm, Runtime::FunctionId function_id) { 2774a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org FrameScope scope(masm, StackFrame::INTERNAL); 2784a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org // Push a copy of the function onto the stack. 279057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org // Push call kind information and function as parameter to the runtime call. 280e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org __ Push(a1, a1); 2814a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org 2824a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org __ CallRuntime(function_id, 1); 283057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org // Restore call kind information and receiver. 284e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org __ Pop(a1); 2854a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org} 2864a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org 2874a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org 288129d398d682e6ca3910808c913212ce532f1e155danno@chromium.orgstatic void GenerateTailCallToSharedCode(MacroAssembler* masm) { 289129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org __ lw(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); 290129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org __ lw(a2, FieldMemOperand(a2, SharedFunctionInfo::kCodeOffset)); 291129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org __ Addu(at, a2, Operand(Code::kHeaderSize - kHeapObjectTag)); 292129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org __ Jump(at); 293129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org} 294129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org 295129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org 2964954674151afa960af66efb4831df06bde727333yangguo@chromium.orgstatic void GenerateTailCallToReturnedCode(MacroAssembler* masm) { 2974954674151afa960af66efb4831df06bde727333yangguo@chromium.org __ Addu(at, v0, Operand(Code::kHeaderSize - kHeapObjectTag)); 2984954674151afa960af66efb4831df06bde727333yangguo@chromium.org __ Jump(at); 2994954674151afa960af66efb4831df06bde727333yangguo@chromium.org} 3004954674151afa960af66efb4831df06bde727333yangguo@chromium.org 3014954674151afa960af66efb4831df06bde727333yangguo@chromium.org 3024954674151afa960af66efb4831df06bde727333yangguo@chromium.orgvoid Builtins::Generate_InOptimizationQueue(MacroAssembler* masm) { 3034a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org // Checking whether the queued function is ready for install is optional, 3044a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org // since we come across interrupts and stack checks elsewhere. However, 3054a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org // not checking may delay installing ready functions, and always checking 3064a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org // would be quite expensive. A good compromise is to first check against 3074a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org // stack limit as a cue for an interrupt signal. 3084a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org Label ok; 3094a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org __ LoadRoot(t0, Heap::kStackLimitRootIndex); 3104a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org __ Branch(&ok, hs, sp, Operand(t0)); 3114a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org 31247390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org CallRuntimePassFunction(masm, Runtime::kTryInstallOptimizedCode); 3134954674151afa960af66efb4831df06bde727333yangguo@chromium.org GenerateTailCallToReturnedCode(masm); 3146e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org 3154a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org __ bind(&ok); 3164a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org GenerateTailCallToSharedCode(masm); 3176e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org} 3186e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org 3196e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org 320fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.orgstatic void Generate_JSConstructStubHelper(MacroAssembler* masm, 321fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org bool is_api_function, 32269f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org bool create_memento) { 3237304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // ----------- S t a t e ------------- 3247304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // -- a0 : number of arguments 3257304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // -- a1 : constructor function 32669f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org // -- a2 : allocation site or undefined 3277304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // -- ra : return address 3287304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // -- sp[...]: constructor arguments 3297304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // ----------------------------------- 3307304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 33169f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org // Should never create mementos for api functions. 332e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!is_api_function || !create_memento); 33369f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org 3347304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Isolate* isolate = masm->isolate(); 3357304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 3367304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // ----------- S t a t e ------------- 3377304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // -- a0 : number of arguments 3387304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // -- a1 : constructor function 3397304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // -- ra : return address 3407304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // -- sp[...]: constructor arguments 3417304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // ----------------------------------- 3427304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 3437304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // Enter a construct frame. 344c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com { 345c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FrameScope scope(masm, StackFrame::CONSTRUCT); 3467304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 34769f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org if (create_memento) { 34869f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org __ AssertUndefinedOrAllocationSite(a2, a3); 34969f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org __ push(a2); 35069f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org } 35169f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org 352c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Preserve the two incoming parameters on the stack. 353c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ sll(a0, a0, kSmiTagSize); // Tag arguments count. 354c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ MultiPushReversed(a0.bit() | a1.bit()); 3557304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 356c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label rt_call, allocated; 357c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Try to allocate the object without transitioning into C code. If any of 358c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // the preconditions is not met, the code bails out to the runtime call. 359c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (FLAG_inline_new) { 360c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label undo_allocation; 361c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ExternalReference debug_step_in_fp = 362c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ExternalReference::debug_step_in_fp_address(isolate); 363c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ li(a2, Operand(debug_step_in_fp)); 364c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ lw(a2, MemOperand(a2)); 365c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Branch(&rt_call, ne, a2, Operand(zero_reg)); 3667304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 367c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Load the initial map and verify that it is in fact a map. 368c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // a1: constructor function 369c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ lw(a2, FieldMemOperand(a1, JSFunction::kPrototypeOrInitialMapOffset)); 370c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ JumpIfSmi(a2, &rt_call); 371c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ GetObjectType(a2, a3, t4); 372c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Branch(&rt_call, ne, t4, Operand(MAP_TYPE)); 373c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 374c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check that the constructor is not constructing a JSFunction (see 375c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // comments in Runtime_NewObject in runtime.cc). In which case the 376c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // initial map's instance type would be JS_FUNCTION_TYPE. 377c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // a1: constructor function 378c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // a2: initial map 379c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ lbu(a3, FieldMemOperand(a2, Map::kInstanceTypeOffset)); 380c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Branch(&rt_call, eq, a3, Operand(JS_FUNCTION_TYPE)); 3817304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 382864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!is_api_function) { 383c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label allocate; 384864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org MemOperand bit_field3 = FieldMemOperand(a2, Map::kBitField3Offset); 385864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check if slack tracking is enabled. 386864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ lw(t0, bit_field3); 387864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ DecodeField<Map::ConstructionCount>(t2, t0); 388864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Branch(&allocate, eq, t2, Operand(JSFunction::kNoSlackTracking)); 389c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Decrease generous allocation count. 390864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Subu(t0, t0, Operand(1 << Map::ConstructionCount::kShift)); 391864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Branch(USE_DELAY_SLOT, 392864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org &allocate, ne, t2, Operand(JSFunction::kFinishSlackTracking)); 393864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ sw(t0, bit_field3); // In delay slot. 394c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 395057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org __ Push(a1, a2, a1); // a1 = Constructor. 39647390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org __ CallRuntime(Runtime::kFinalizeInstanceSize, 1); 397c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 398057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org __ Pop(a1, a2); 399864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Slack tracking counter is kNoSlackTracking after runtime call. 400e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(JSFunction::kNoSlackTracking == 0); 401864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ mov(t2, zero_reg); 402c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 403c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ bind(&allocate); 4047304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 4057304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 406c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Now allocate the JSObject on the heap. 407c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // a1: constructor function 408c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // a2: initial map 409c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ lbu(a3, FieldMemOperand(a2, Map::kInstanceSizeOffset)); 41069f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org if (create_memento) { 41169f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org __ Addu(a3, a3, Operand(AllocationMemento::kSize / kPointerSize)); 41269f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org } 41369f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org 414f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org __ Allocate(a3, t4, t5, t6, &rt_call, SIZE_IN_WORDS); 415c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 416c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Allocated the JSObject, now initialize the fields. Map is set to 417c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // initial map and properties and elements are set to empty fixed array. 418c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // a1: constructor function 419c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // a2: initial map 42069f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org // a3: object size (not including memento if create_memento) 421c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // t4: JSObject (not tagged) 422c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ LoadRoot(t6, Heap::kEmptyFixedArrayRootIndex); 423c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ mov(t5, t4); 424c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ sw(a2, MemOperand(t5, JSObject::kMapOffset)); 425c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ sw(t6, MemOperand(t5, JSObject::kPropertiesOffset)); 426c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ sw(t6, MemOperand(t5, JSObject::kElementsOffset)); 427c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Addu(t5, t5, Operand(3*kPointerSize)); 428e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(0 * kPointerSize, JSObject::kMapOffset); 429e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(1 * kPointerSize, JSObject::kPropertiesOffset); 430e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(2 * kPointerSize, JSObject::kElementsOffset); 431c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 432c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Fill all the in-object properties with appropriate filler. 433c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // a1: constructor function 434c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // a2: initial map 43569f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org // a3: object size (in words, including memento if create_memento) 436c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // t4: JSObject (not tagged) 437c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // t5: First in-object property of JSObject (not tagged) 438864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // t2: slack tracking counter (non-API function case) 439e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(3 * kPointerSize, JSObject::kHeaderSize); 44069f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org 441864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Use t7 to hold undefined, which is used in several places below. 442864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ LoadRoot(t7, Heap::kUndefinedValueRootIndex); 443864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 444864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!is_api_function) { 445864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Label no_inobject_slack_tracking; 446864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 447864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Check if slack tracking is enabled. 448864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Branch(&no_inobject_slack_tracking, 449864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org eq, t2, Operand(JSFunction::kNoSlackTracking)); 450864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 451864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Allocate object with a slack. 452731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org __ lbu(a0, FieldMemOperand(a2, Map::kPreAllocatedPropertyFieldsOffset)); 453fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ sll(at, a0, kPointerSizeLog2); 454fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ addu(a0, t5, at); 455b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org // a0: offset of first field after pre-allocated fields 456b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org if (FLAG_debug_code) { 457864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ sll(at, a3, kPointerSizeLog2); 458864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Addu(t6, t4, Operand(at)); // End of object. 459594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Assert(le, kUnexpectedNumberOfPreAllocatedPropertyFields, 460b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org a0, Operand(t6)); 461c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 462b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org __ InitializeFieldsWithFiller(t5, a0, t7); 463b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org // To allow for truncation. 464b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org __ LoadRoot(t7, Heap::kOnePointerFillerMapRootIndex); 465864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org // Fill the remaining fields with one pointer filler map. 466864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 467864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ bind(&no_inobject_slack_tracking); 468864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org } 469864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org 470864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (create_memento) { 471864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Subu(a0, a3, Operand(AllocationMemento::kSize / kPointerSize)); 472864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ sll(a0, a0, kPointerSizeLog2); 473864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Addu(a0, t4, Operand(a0)); // End of object. 47469f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org __ InitializeFieldsWithFiller(t5, a0, t7); 47569f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org 47669f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org // Fill in memento fields. 47769f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org // t5: points to the allocated but uninitialized memento. 47869f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org __ LoadRoot(t7, Heap::kAllocationMementoMapRootIndex); 479e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(0 * kPointerSize, AllocationMemento::kMapOffset); 48069f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org __ sw(t7, MemOperand(t5)); 48169f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org __ Addu(t5, t5, kPointerSize); 48269f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org // Load the AllocationSite. 48369f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org __ lw(t7, MemOperand(sp, 2 * kPointerSize)); 484e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(1 * kPointerSize, AllocationMemento::kAllocationSiteOffset); 48569f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org __ sw(t7, MemOperand(t5)); 48669f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org __ Addu(t5, t5, kPointerSize); 48769f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org } else { 48869f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org __ sll(at, a3, kPointerSizeLog2); 48969f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org __ Addu(a0, t4, Operand(at)); // End of object. 49069f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org __ InitializeFieldsWithFiller(t5, a0, t7); 491c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 4927304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 493c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Add the object tag to make the JSObject real, so that we can continue 494c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // and jump into the continuation code at any time from now on. Any 495c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // failures need to undo the allocation, so that the heap is in a 496c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // consistent state and verifiable. 497c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Addu(t4, t4, Operand(kHeapObjectTag)); 498c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 499c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check if a non-empty properties array is needed. Continue with 500c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // allocated object if not fall through to runtime call if it is. 501c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // a1: constructor function 502c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // t4: JSObject 503c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // t5: start of next object (not tagged) 504c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ lbu(a3, FieldMemOperand(a2, Map::kUnusedPropertyFieldsOffset)); 505c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // The field instance sizes contains both pre-allocated property fields 506c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // and in-object properties. 507731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org __ lbu(t6, FieldMemOperand(a2, Map::kPreAllocatedPropertyFieldsOffset)); 508b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org __ Addu(a3, a3, Operand(t6)); 509731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org __ lbu(t6, FieldMemOperand(a2, Map::kInObjectPropertiesOffset)); 510b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org __ subu(a3, a3, t6); 511c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 512c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Done if no extra properties are to be allocated. 513c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Branch(&allocated, eq, a3, Operand(zero_reg)); 514594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Assert(greater_equal, kPropertyAllocationCountFailed, 515c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com a3, Operand(zero_reg)); 516c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 517c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Scale the number of elements by pointer size and add the header for 518c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // FixedArrays to the start of the next object calculation from above. 519c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // a1: constructor 520c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // a3: number of elements in properties array 521c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // t4: JSObject 522c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // t5: start of next object 523c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Addu(a0, a3, Operand(FixedArray::kHeaderSize / kPointerSize)); 524f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org __ Allocate( 525c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com a0, 526c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com t5, 527c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com t6, 528c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com a2, 529c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com &undo_allocation, 530c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static_cast<AllocationFlags>(RESULT_CONTAINS_TOP | SIZE_IN_WORDS)); 531c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 532c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Initialize the FixedArray. 533c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // a1: constructor 5342efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // a3: number of elements in properties array (untagged) 535c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // t4: JSObject 536c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // t5: start of next object 537c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ LoadRoot(t6, Heap::kFixedArrayMapRootIndex); 538c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ mov(a2, t5); 539c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ sw(t6, MemOperand(a2, JSObject::kMapOffset)); 540c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ sll(a0, a3, kSmiTagSize); 541c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ sw(a0, MemOperand(a2, FixedArray::kLengthOffset)); 542c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Addu(a2, a2, Operand(2 * kPointerSize)); 543c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 544e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(0 * kPointerSize, JSObject::kMapOffset); 545e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(1 * kPointerSize, FixedArray::kLengthOffset); 546c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 547c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Initialize the fields to undefined. 548c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // a1: constructor 549c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // a2: First element of FixedArray (not tagged) 550c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // a3: number of elements in properties array 551c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // t4: JSObject 552c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // t5: FixedArray (not tagged) 553c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ sll(t3, a3, kPointerSizeLog2); 554c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ addu(t6, a2, t3); // End of object. 555e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(2 * kPointerSize, FixedArray::kHeaderSize); 556c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com { Label loop, entry; 557864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!is_api_function || create_memento) { 558c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ LoadRoot(t7, Heap::kUndefinedValueRootIndex); 559c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else if (FLAG_debug_code) { 560864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ LoadRoot(t2, Heap::kUndefinedValueRootIndex); 561864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org __ Assert(eq, kUndefinedValueNotLoaded, t7, Operand(t2)); 562c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 563c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ jmp(&entry); 564c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ bind(&loop); 565c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ sw(t7, MemOperand(a2)); 566c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ addiu(a2, a2, kPointerSize); 567c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ bind(&entry); 568c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Branch(&loop, less, a2, Operand(t6)); 5697304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 570c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 571c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Store the initialized FixedArray into the properties field of 572c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // the JSObject. 573c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // a1: constructor function 574c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // t4: JSObject 575c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // t5: FixedArray (not tagged) 576c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Addu(t5, t5, Operand(kHeapObjectTag)); // Add the heap tag. 577c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ sw(t5, FieldMemOperand(t4, JSObject::kPropertiesOffset)); 578c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 579c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Continue with JSObject being successfully allocated. 580c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // a1: constructor function 581c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // a4: JSObject 582c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ jmp(&allocated); 583c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 584c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Undo the setting of the new top so that the heap is verifiable. For 585c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // example, the map's unused properties potentially do not match the 586c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // allocated objects unused properties. 587c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // t4: JSObject (previous new top) 588c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ bind(&undo_allocation); 589c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ UndoAllocationInNewSpace(t4, t5); 5907304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 5917304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 592c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Allocate the new receiver object using the runtime call. 5937304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // a1: constructor function 59469f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org __ bind(&rt_call); 59569f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org if (create_memento) { 59669f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org // Get the cell or allocation site. 59769f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org __ lw(a2, MemOperand(sp, 2 * kPointerSize)); 59869f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org __ push(a2); 59969f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org } 60069f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org 601c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ push(a1); // Argument for Runtime_NewObject. 60269f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org if (create_memento) { 60347390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org __ CallRuntime(Runtime::kNewObjectWithAllocationSite, 2); 60469f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org } else { 60547390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org __ CallRuntime(Runtime::kNewObject, 1); 60669f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org } 607c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ mov(t4, v0); 6087304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 60969f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org // If we ended up using the runtime, and we want a memento, then the 61069f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org // runtime call made it for us, and we shouldn't do create count 61169f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org // increment. 61269f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org Label count_incremented; 61369f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org if (create_memento) { 61469f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org __ jmp(&count_incremented); 61569f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org } 61669f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org 617c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Receiver for constructor call allocated. 618c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // t4: JSObject 61938de99aae2d4efc5796aa6935c1648447ec32fc8machenbach@chromium.org __ bind(&allocated); 62069f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org 62169f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org if (create_memento) { 62269f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org __ lw(a2, MemOperand(sp, kPointerSize * 2)); 62369f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org __ LoadRoot(t5, Heap::kUndefinedValueRootIndex); 62469f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org __ Branch(&count_incremented, eq, a2, Operand(t5)); 62569f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org // a2 is an AllocationSite. We are creating a memento from it, so we 62669f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org // need to increment the memento create count. 62769f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org __ lw(a3, FieldMemOperand(a2, 62869f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org AllocationSite::kPretenureCreateCountOffset)); 62969f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org __ Addu(a3, a3, Operand(Smi::FromInt(1))); 63069f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org __ sw(a3, FieldMemOperand(a2, 63169f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org AllocationSite::kPretenureCreateCountOffset)); 63269f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org __ bind(&count_incremented); 63369f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org } 63469f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org 6356f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org __ Push(t4, t4); 6367304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 637c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Reload the number of arguments from the stack. 638c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // sp[0]: receiver 63978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // sp[1]: receiver 64078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // sp[2]: constructor function 64178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // sp[3]: number of arguments (smi-tagged) 64278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org __ lw(a1, MemOperand(sp, 2 * kPointerSize)); 64378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org __ lw(a3, MemOperand(sp, 3 * kPointerSize)); 6447304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 645f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // Set up pointer to last argument. 646c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Addu(a2, fp, Operand(StandardFrameConstants::kCallerSPOffset)); 6477304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 648f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // Set up number of arguments for function call below. 649c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ srl(a0, a3, kSmiTagSize); 6507304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 651c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Copy arguments and receiver to the expression stack. 652c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // a0: number of arguments 653c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // a1: constructor function 654c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // a2: address of last argument (caller sp) 655c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // a3: number of arguments (smi-tagged) 656c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // sp[0]: receiver 65778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // sp[1]: receiver 65878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // sp[2]: constructor function 65978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // sp[3]: number of arguments (smi-tagged) 660c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label loop, entry; 661c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ jmp(&entry); 662c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ bind(&loop); 663c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ sll(t0, a3, kPointerSizeLog2 - kSmiTagSize); 664c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Addu(t0, a2, Operand(t0)); 665c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ lw(t1, MemOperand(t0)); 666c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ push(t1); 667c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ bind(&entry); 668c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Addu(a3, a3, Operand(-2)); 669c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Branch(&loop, greater_equal, a3, Operand(zero_reg)); 6707304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 671c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Call the function. 672c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // a0: number of arguments 673c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // a1: constructor function 674c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (is_api_function) { 675c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); 676c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Handle<Code> code = 677c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com masm->isolate()->builtins()->HandleApiCallConstruct(); 67826ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org __ Call(code, RelocInfo::CODE_TARGET); 679c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 680c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ParameterCount actual(a0); 681e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org __ InvokeFunction(a1, actual, CALL_FUNCTION, NullCallWrapper()); 682c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 6837304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 684812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // Store offset of return address for deoptimizer. 685864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org if (!is_api_function) { 686812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset()); 687812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org } 688812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 689c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Restore context from the frame. 690c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 691c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 692c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // If the result is an object (in the ECMA sense), we should get rid 693c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // of the receiver and use the result; see ECMA-262 section 13.2.2-7 694c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // on page 74. 695c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label use_receiver, exit; 696c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 697c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // If the result is a smi, it is *not* an object in the ECMA sense. 698c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // v0: result 699c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // sp[0]: receiver (newly allocated object) 700c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // sp[1]: constructor function 701c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // sp[2]: number of arguments (smi-tagged) 702c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ JumpIfSmi(v0, &use_receiver); 703c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 704c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // If the type of the result (stored in its map) is less than 705c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // FIRST_SPEC_OBJECT_TYPE, it is not an object in the ECMA sense. 7069faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org __ GetObjectType(v0, a1, a3); 707c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Branch(&exit, greater_equal, a3, Operand(FIRST_SPEC_OBJECT_TYPE)); 708c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 709c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Throw away the result of the constructor invocation and use the 710c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // on-stack receiver as the result. 711c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ bind(&use_receiver); 712c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ lw(v0, MemOperand(sp)); 713c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 714c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Remove receiver from the stack, remove caller arguments, and 715c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // return. 716c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ bind(&exit); 717c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // v0: result 718c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // sp[0]: receiver (newly allocated object) 719c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // sp[1]: constructor function 720c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // sp[2]: number of arguments (smi-tagged) 721c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ lw(a1, MemOperand(sp, 2 * kPointerSize)); 722c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 723c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Leave construct frame. 7247304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 7257304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 7267304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ sll(t0, a1, kPointerSizeLog2 - 1); 7277304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ Addu(sp, sp, t0); 7287304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ Addu(sp, sp, kPointerSize); 7297304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ IncrementCounter(isolate->counters()->constructed_objects(), 1, a1, a2); 7307304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ Ret(); 7315c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 7325c838251403b0be9a882540f1922577abba4c872ager@chromium.org 7335c838251403b0be9a882540f1922577abba4c872ager@chromium.org 7347516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { 735864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Generate_JSConstructStubHelper(masm, false, FLAG_pretenuring_call_new); 7365c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 7375c838251403b0be9a882540f1922577abba4c872ager@chromium.org 7385c838251403b0be9a882540f1922577abba4c872ager@chromium.org 7397516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { 740864abd7677f434b5aef191e3388e71cd4dd1e6c8machenbach@chromium.org Generate_JSConstructStubHelper(masm, true, false); 7417304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org} 7427304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 7437304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 7447304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.orgstatic void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, 7457304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org bool is_construct) { 7467304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // Called from JSEntryStub::GenerateBody 7477304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 7487304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // ----------- S t a t e ------------- 7497304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // -- a0: code entry 7507304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // -- a1: function 7512efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // -- a2: receiver_pointer 7527304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // -- a3: argc 7537304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // -- s0: argv 7547304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // ----------------------------------- 75507237aaaed914a17c1afd64234883bff619581d5palfia@homejinni.com ProfileEntryHookStub::MaybeCallEntryHook(masm); 7567304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 7577304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // Clear the context before we push it when entering the JS frame. 7587304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ mov(cp, zero_reg); 7597304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 7607304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // Enter an internal frame. 761c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com { 762c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FrameScope scope(masm, StackFrame::INTERNAL); 7637304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 764c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Set up the context from the function argument. 765c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); 7667304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 767c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Push the function and the receiver onto the stack. 768c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Push(a1, a2); 7697304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 770c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Copy arguments to the stack in a loop. 771c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // a3: argc 7722efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // s0: argv, i.e. points to first arg 773c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label loop, entry; 774c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ sll(t0, a3, kPointerSizeLog2); 775c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ addu(t2, s0, t0); 776c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ b(&entry); 777c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ nop(); // Branch delay slot nop. 778c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // t2 points past last arg. 779c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ bind(&loop); 780c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ lw(t0, MemOperand(s0)); // Read next parameter. 781c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ addiu(s0, s0, kPointerSize); 782c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ lw(t0, MemOperand(t0)); // Dereference handle. 783c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ push(t0); // Push parameter. 784c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ bind(&entry); 785c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Branch(&loop, ne, s0, Operand(t2)); 786c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 787c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Initialize all JavaScript callee-saved registers, since they will be seen 788c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // by the garbage collector as part of handlers. 789c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ LoadRoot(t0, Heap::kUndefinedValueRootIndex); 790c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ mov(s1, t0); 791c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ mov(s2, t0); 792c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ mov(s3, t0); 793c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ mov(s4, t0); 794c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ mov(s5, t0); 795c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // s6 holds the root address. Do not clobber. 796c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // s7 is cp. Do not init. 797c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 798c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Invoke the code and pass argc as a0. 799c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ mov(a0, a3); 800c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (is_construct) { 801750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org // No type feedback cell is available 80269f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); 80326ff407a06ed21bb3a1d7d147a6c0c092a2dff6dpalfia@homejinni.com CallConstructStub stub(masm->isolate(), NO_CALL_CONSTRUCTOR_FLAGS); 804fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org __ CallStub(&stub); 805c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 806c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ParameterCount actual(a0); 807e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org __ InvokeFunction(a1, actual, CALL_FUNCTION, NullCallWrapper()); 808c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 8097304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 810c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Leave internal frame. 811c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 8127304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 8137304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ Jump(ra); 8145c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 8155c838251403b0be9a882540f1922577abba4c872ager@chromium.org 8165c838251403b0be9a882540f1922577abba4c872ager@chromium.org 8175c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) { 8187304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Generate_JSEntryTrampolineHelper(masm, false); 8195c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 8205c838251403b0be9a882540f1922577abba4c872ager@chromium.org 8215c838251403b0be9a882540f1922577abba4c872ager@chromium.org 8225c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) { 8237304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Generate_JSEntryTrampolineHelper(masm, true); 8247516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 8257516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 8267516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 827a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.orgvoid Builtins::Generate_CompileLazy(MacroAssembler* masm) { 828a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org CallRuntimePassFunction(masm, Runtime::kCompileLazy); 8294954674151afa960af66efb4831df06bde727333yangguo@chromium.org GenerateTailCallToReturnedCode(masm); 8307516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 8317516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 8327516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 833e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.orgstatic void CallCompileOptimized(MacroAssembler* masm, bool concurrent) { 8344954674151afa960af66efb4831df06bde727333yangguo@chromium.org FrameScope scope(masm, StackFrame::INTERNAL); 8354954674151afa960af66efb4831df06bde727333yangguo@chromium.org // Push a copy of the function onto the stack. 836e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org // Push function as parameter to the runtime call. 837e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org __ Push(a1, a1); 8384954674151afa960af66efb4831df06bde727333yangguo@chromium.org // Whether to compile in a background thread. 8394954674151afa960af66efb4831df06bde727333yangguo@chromium.org __ Push(masm->isolate()->factory()->ToBoolean(concurrent)); 8404954674151afa960af66efb4831df06bde727333yangguo@chromium.org 84147390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org __ CallRuntime(Runtime::kCompileOptimized, 2); 842e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org // Restore receiver. 843e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org __ Pop(a1); 8444954674151afa960af66efb4831df06bde727333yangguo@chromium.org} 8454954674151afa960af66efb4831df06bde727333yangguo@chromium.org 8464954674151afa960af66efb4831df06bde727333yangguo@chromium.org 8474954674151afa960af66efb4831df06bde727333yangguo@chromium.orgvoid Builtins::Generate_CompileOptimized(MacroAssembler* masm) { 8484954674151afa960af66efb4831df06bde727333yangguo@chromium.org CallCompileOptimized(masm, false); 8494954674151afa960af66efb4831df06bde727333yangguo@chromium.org GenerateTailCallToReturnedCode(masm); 8504954674151afa960af66efb4831df06bde727333yangguo@chromium.org} 8514954674151afa960af66efb4831df06bde727333yangguo@chromium.org 8524954674151afa960af66efb4831df06bde727333yangguo@chromium.org 8534954674151afa960af66efb4831df06bde727333yangguo@chromium.orgvoid Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) { 8544954674151afa960af66efb4831df06bde727333yangguo@chromium.org CallCompileOptimized(masm, true); 8554954674151afa960af66efb4831df06bde727333yangguo@chromium.org GenerateTailCallToReturnedCode(masm); 8567516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 8577516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 8587516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 8594954674151afa960af66efb4831df06bde727333yangguo@chromium.org 860fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.orgstatic void GenerateMakeCodeYoungAgainCommon(MacroAssembler* masm) { 861fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // For now, we are relying on the fact that make_code_young doesn't do any 862fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // garbage collection which allows us to save/restore the registers without 863fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // worrying about which of them contain pointers. We also don't build an 864fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // internal frame to make the code faster, since we shouldn't have to do stack 865fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // crawls in MakeCodeYoung. This seems a bit fragile. 866fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 867f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org // Set a0 to point to the head of the PlatformCodeAge sequence. 868fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org __ Subu(a0, a0, 8695924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org Operand(kNoCodeAgeSequenceLength - Assembler::kInstrSize)); 870fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 871fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // The following registers must be saved and restored when calling through to 872fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // the runtime: 873fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // a0 - contains return address (beginning of patch sequence) 874528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // a1 - isolate 875fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org RegList saved_regs = 876fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org (a0.bit() | a1.bit() | ra.bit() | fp.bit()) & ~sp.bit(); 877fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org FrameScope scope(masm, StackFrame::MANUAL); 878fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org __ MultiPush(saved_regs); 879ea9b8ba58955b7efcc3e1550dd33a44fb4530136hpayer@chromium.org __ PrepareCallCFunction(2, 0, a2); 880528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ li(a1, Operand(ExternalReference::isolate_address(masm->isolate()))); 881fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org __ CallCFunction( 882528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org ExternalReference::get_make_code_young_function(masm->isolate()), 2); 883fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org __ MultiPop(saved_regs); 884fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org __ Jump(a0); 885fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org} 886fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 887fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org#define DEFINE_CODE_AGE_BUILTIN_GENERATOR(C) \ 888fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.orgvoid Builtins::Generate_Make##C##CodeYoungAgainEvenMarking( \ 889fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org MacroAssembler* masm) { \ 890fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org GenerateMakeCodeYoungAgainCommon(masm); \ 891fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org} \ 892fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.orgvoid Builtins::Generate_Make##C##CodeYoungAgainOddMarking( \ 893fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org MacroAssembler* masm) { \ 894fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org GenerateMakeCodeYoungAgainCommon(masm); \ 895fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org} 896fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.orgCODE_AGE_LIST(DEFINE_CODE_AGE_BUILTIN_GENERATOR) 897fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org#undef DEFINE_CODE_AGE_BUILTIN_GENERATOR 898fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 899fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 900c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.orgvoid Builtins::Generate_MarkCodeAsExecutedOnce(MacroAssembler* masm) { 901c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org // For now, as in GenerateMakeCodeYoungAgainCommon, we are relying on the fact 902c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org // that make_code_young doesn't do any garbage collection which allows us to 903c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org // save/restore the registers without worrying about which of them contain 904c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org // pointers. 905c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 906f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org // Set a0 to point to the head of the PlatformCodeAge sequence. 907c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ Subu(a0, a0, 9085924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org Operand(kNoCodeAgeSequenceLength - Assembler::kInstrSize)); 909c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 910c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org // The following registers must be saved and restored when calling through to 911c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org // the runtime: 912c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org // a0 - contains return address (beginning of patch sequence) 913c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org // a1 - isolate 914c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org RegList saved_regs = 915c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org (a0.bit() | a1.bit() | ra.bit() | fp.bit()) & ~sp.bit(); 916c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org FrameScope scope(masm, StackFrame::MANUAL); 917c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ MultiPush(saved_regs); 918ea9b8ba58955b7efcc3e1550dd33a44fb4530136hpayer@chromium.org __ PrepareCallCFunction(2, 0, a2); 919c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ li(a1, Operand(ExternalReference::isolate_address(masm->isolate()))); 920c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ CallCFunction( 921c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org ExternalReference::get_mark_code_as_executed_function(masm->isolate()), 922c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 2); 923c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ MultiPop(saved_regs); 924c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 925c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org // Perform prologue operations usually performed by the young code stub. 926c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ Push(ra, fp, cp, a1); 9277ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org __ Addu(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); 928c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 929c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org // Jump to point after the code-age stub. 9305924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org __ Addu(a0, a0, Operand(kNoCodeAgeSequenceLength)); 931c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ Jump(a0); 932c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org} 933c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 934c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 935c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.orgvoid Builtins::Generate_MarkCodeAsExecutedTwice(MacroAssembler* masm) { 936c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org GenerateMakeCodeYoungAgainCommon(masm); 937c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org} 938c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 939c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 940f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.orgstatic void Generate_NotifyStubFailureHelper(MacroAssembler* masm, 941f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org SaveFPRegsMode save_doubles) { 94259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org { 94359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org FrameScope scope(masm, StackFrame::INTERNAL); 94459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 94559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org // Preserve registers across notification, this is important for compiled 94659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org // stubs that tail call the runtime on deopts passing their parameters in 94759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org // registers. 94859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ MultiPush(kJSCallerSaved | kCalleeSaved); 94959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org // Pass the function and deoptimization type to the runtime system. 95047390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org __ CallRuntime(Runtime::kNotifyStubFailure, 0, save_doubles); 95159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ MultiPop(kJSCallerSaved | kCalleeSaved); 95259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org } 95359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 95459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ Addu(sp, sp, Operand(kPointerSize)); // Ignore state 955e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org __ Jump(ra); // Jump to miss handler 95659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org} 95759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 95859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 959f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.orgvoid Builtins::Generate_NotifyStubFailure(MacroAssembler* masm) { 960f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Generate_NotifyStubFailureHelper(masm, kDontSaveFPRegs); 961f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org} 962f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org 963f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org 964f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.orgvoid Builtins::Generate_NotifyStubFailureSaveDoubles(MacroAssembler* masm) { 965f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Generate_NotifyStubFailureHelper(masm, kSaveFPRegs); 966f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org} 967f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org 968f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org 969c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgstatic void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm, 970c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Deoptimizer::BailoutType type) { 971c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org { 972c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org FrameScope scope(masm, StackFrame::INTERNAL); 973c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Pass the function and deoptimization type to the runtime system. 974c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ li(a0, Operand(Smi::FromInt(static_cast<int>(type)))); 975c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ push(a0); 97647390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org __ CallRuntime(Runtime::kNotifyDeoptimized, 1); 977c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 978c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 979c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Get the full codegen state from the stack and untag it -> t2. 980c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(t2, MemOperand(sp, 0 * kPointerSize)); 981c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ SmiUntag(t2); 982c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // Switch on the state. 983c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label with_tos_register, unknown_state; 984c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(&with_tos_register, 985c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ne, t2, Operand(FullCodeGenerator::NO_REGISTERS)); 9868a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ Ret(USE_DELAY_SLOT); 9878a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org // Safe to fill delay slot Addu will emit one instruction. 988c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Addu(sp, sp, Operand(1 * kPointerSize)); // Remove state. 989c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 990c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&with_tos_register); 991c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(v0, MemOperand(sp, 1 * kPointerSize)); 992c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(&unknown_state, ne, t2, Operand(FullCodeGenerator::TOS_REG)); 993c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 9948a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ Ret(USE_DELAY_SLOT); 9958a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org // Safe to fill delay slot Addu will emit one instruction. 996c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Addu(sp, sp, Operand(2 * kPointerSize)); // Remove state. 997c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 998c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ bind(&unknown_state); 999c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ stop("no cases left"); 1000c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org} 1001c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1002c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 10037516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) { 1004c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::EAGER); 10057516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 10067516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 10077516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 10080410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.comvoid Builtins::Generate_NotifySoftDeoptimized(MacroAssembler* masm) { 10090410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.com Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::SOFT); 10100410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.com} 10110410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.com 10120410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.com 10137516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Builtins::Generate_NotifyLazyDeoptimized(MacroAssembler* masm) { 1014c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::LAZY); 10157516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 10167516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 10177516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 10187516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { 1019e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org // Lookup the function in the JavaScript frame. 1020c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ lw(a0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 1021c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org { 1022c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org FrameScope scope(masm, StackFrame::INTERNAL); 1023afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org // Pass function as argument. 1024c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ push(a0); 1025afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org __ CallRuntime(Runtime::kCompileForOnStackReplacement, 1); 1026c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 1027c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 1028c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // If the code object is null, just return to the unoptimized code. 1029c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org __ Ret(eq, v0, Operand(Smi::FromInt(0))); 1030c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 1031c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // Load deoptimization data from the code object. 1032c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // <deopt_data> = <code>[#deoptimization_data_offset] 1033c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org __ lw(a1, MemOperand(v0, Code::kDeoptimizationDataOffset - kHeapObjectTag)); 1034c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 1035c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // Load the OSR entrypoint offset from the deoptimization data. 1036c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // <osr_offset> = <deopt_data>[#header_size + #osr_pc_offset] 1037c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org __ lw(a1, MemOperand(a1, FixedArray::OffsetOfElementAt( 1038c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org DeoptimizationInputData::kOsrPcOffsetIndex) - kHeapObjectTag)); 1039c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org __ SmiUntag(a1); 1040c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 1041c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // Compute the target address = code_obj + header_size + osr_offset 1042c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // <entry_addr> = <code_obj> + #header_size + <osr_offset> 1043c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org __ addu(v0, v0, a1); 1044c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org __ addiu(ra, v0, Code::kHeaderSize - kHeapObjectTag); 1045c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 1046c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // And "return" to the OSR entry point of the function. 1047c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org __ Ret(); 10485c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 10495c838251403b0be9a882540f1922577abba4c872ager@chromium.org 10505c838251403b0be9a882540f1922577abba4c872ager@chromium.org 10518e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.orgvoid Builtins::Generate_OsrAfterStackCheck(MacroAssembler* masm) { 10528e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org // We check the stack limit as indicator that recompilation might be done. 10538e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org Label ok; 10548e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org __ LoadRoot(at, Heap::kStackLimitRootIndex); 10558e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org __ Branch(&ok, hs, sp, Operand(at)); 10568e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org { 10578e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org FrameScope scope(masm, StackFrame::INTERNAL); 105847390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org __ CallRuntime(Runtime::kStackGuard, 0); 10598e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org } 10608e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org __ Jump(masm->isolate()->builtins()->OnStackReplacement(), 10618e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org RelocInfo::CODE_TARGET); 10628e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org 10638e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org __ bind(&ok); 10648e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org __ Ret(); 10658e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org} 10668e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org 10678e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org 10685c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Builtins::Generate_FunctionCall(MacroAssembler* masm) { 10697304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // 1. Make sure we have at least one argument. 10707304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // a0: actual number of arguments 10717304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org { Label done; 10727304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ Branch(&done, ne, a0, Operand(zero_reg)); 10737304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ LoadRoot(t2, Heap::kUndefinedValueRootIndex); 10747304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ push(t2); 10757304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ Addu(a0, a0, Operand(1)); 10767304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ bind(&done); 10777304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 10787304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 10797304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // 2. Get the function to call (passed as receiver) from the stack, check 10807304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // if it is a function. 10817304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // a0: actual number of arguments 1082c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label slow, non_function; 10837304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ sll(at, a0, kPointerSizeLog2); 10847304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ addu(at, sp, at); 10857304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ lw(a1, MemOperand(at)); 1086c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ JumpIfSmi(a1, &non_function); 10877304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ GetObjectType(a1, a2, a2); 1088c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Branch(&slow, ne, a2, Operand(JS_FUNCTION_TYPE)); 10897304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 10907304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // 3a. Patch the first argument if necessary when calling a function. 10917304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // a0: actual number of arguments 10927304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // a1: function 10937304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Label shift_arguments; 109459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ li(t0, Operand(0, RelocInfo::NONE32)); // Indicate regular JS_FUNCTION. 1095f6e8ed2294f2eccae83564eead8b79ea050b9f21yangguo@chromium.org { Label convert_to_object, use_global_proxy, patch_receiver; 10967304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // Change context eagerly in case we need the global receiver. 10977304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); 10987304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 10997304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // Do not transform the receiver for strict mode functions. 11007304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ lw(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); 11017304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ lw(a3, FieldMemOperand(a2, SharedFunctionInfo::kCompilerHintsOffset)); 1102c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ And(t3, a3, Operand(1 << (SharedFunctionInfo::kStrictModeFunction + 11037304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org kSmiTagSize))); 1104c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Branch(&shift_arguments, ne, t3, Operand(zero_reg)); 11057304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 110640cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org // Do not transform the receiver for native (Compilerhints already in a3). 1107c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ And(t3, a3, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize))); 1108c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Branch(&shift_arguments, ne, t3, Operand(zero_reg)); 11097304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 1110486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org // Compute the receiver in sloppy mode. 11117304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // Load first argument in a2. a2 = -kPointerSize(sp + n_args << 2). 11127304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ sll(at, a0, kPointerSizeLog2); 11137304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ addu(a2, sp, at); 11147304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ lw(a2, MemOperand(a2, -kPointerSize)); 11157304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // a0: actual number of arguments 11167304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // a1: function 11177304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // a2: first argument 11187304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ JumpIfSmi(a2, &convert_to_object, t2); 11197304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 112040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org __ LoadRoot(a3, Heap::kUndefinedValueRootIndex); 1121f6e8ed2294f2eccae83564eead8b79ea050b9f21yangguo@chromium.org __ Branch(&use_global_proxy, eq, a2, Operand(a3)); 11227304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ LoadRoot(a3, Heap::kNullValueRootIndex); 1123f6e8ed2294f2eccae83564eead8b79ea050b9f21yangguo@chromium.org __ Branch(&use_global_proxy, eq, a2, Operand(a3)); 11247304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 1125d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE); 11267304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ GetObjectType(a2, a3, a3); 1127d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com __ Branch(&shift_arguments, ge, a3, Operand(FIRST_SPEC_OBJECT_TYPE)); 11287304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 11297304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ bind(&convert_to_object); 1130c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Enter an internal frame in order to preserve argument count. 1131c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com { 1132c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FrameScope scope(masm, StackFrame::INTERNAL); 1133c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ sll(a0, a0, kSmiTagSize); // Smi tagged. 11346f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org __ Push(a0, a2); 1135c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); 1136c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ mov(a2, v0); 1137c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1138c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ pop(a0); 1139c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ sra(a0, a0, kSmiTagSize); // Un-tag. 1140c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Leave internal frame. 1141c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 1142f6e8ed2294f2eccae83564eead8b79ea050b9f21yangguo@chromium.org 1143c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Restore the function to a1, and the flag to t0. 11447304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ sll(at, a0, kPointerSizeLog2); 11457304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ addu(at, sp, at); 11467304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ lw(a1, MemOperand(at)); 1147f6e8ed2294f2eccae83564eead8b79ea050b9f21yangguo@chromium.org __ Branch(USE_DELAY_SLOT, &patch_receiver); 1148f6e8ed2294f2eccae83564eead8b79ea050b9f21yangguo@chromium.org __ li(t0, Operand(0, RelocInfo::NONE32)); // In delay slot. 11497304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 1150f6e8ed2294f2eccae83564eead8b79ea050b9f21yangguo@chromium.org __ bind(&use_global_proxy); 11519cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org __ lw(a2, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX)); 1152f6e8ed2294f2eccae83564eead8b79ea050b9f21yangguo@chromium.org __ lw(a2, FieldMemOperand(a2, GlobalObject::kGlobalProxyOffset)); 11537304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 11547304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ bind(&patch_receiver); 11557304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ sll(at, a0, kPointerSizeLog2); 11567304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ addu(a3, sp, at); 11577304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ sw(a2, MemOperand(a3, -kPointerSize)); 11587304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 11597304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ Branch(&shift_arguments); 11607304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 11617304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 1162c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // 3b. Check for function proxy. 1163c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ bind(&slow); 116459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ li(t0, Operand(1, RelocInfo::NONE32)); // Indicate function proxy. 1165c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Branch(&shift_arguments, eq, a2, Operand(JS_FUNCTION_PROXY_TYPE)); 1166c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1167c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ bind(&non_function); 116859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ li(t0, Operand(2, RelocInfo::NONE32)); // Indicate non-function. 1169c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1170c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // 3c. Patch the first argument when calling a non-function. The 11717304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // CALL_NON_FUNCTION builtin expects the non-function callee as 11727304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // receiver, so overwrite the first argument which will ultimately 11737304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // become the receiver. 11747304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // a0: actual number of arguments 11757304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // a1: function 1176c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // t0: call type (0: JS function, 1: function proxy, 2: non-function) 11777304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ sll(at, a0, kPointerSizeLog2); 11787304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ addu(a2, sp, at); 11797304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ sw(a1, MemOperand(a2, -kPointerSize)); 11807304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 11817304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // 4. Shift arguments and return address one slot down on the stack 11827304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // (overwriting the original receiver). Adjust argument count to make 11837304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // the original first argument the new receiver. 11847304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // a0: actual number of arguments 11857304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // a1: function 1186c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // t0: call type (0: JS function, 1: function proxy, 2: non-function) 11877304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ bind(&shift_arguments); 11887304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org { Label loop; 11897304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // Calculate the copy start address (destination). Copy end address is sp. 11907304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ sll(at, a0, kPointerSizeLog2); 11917304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ addu(a2, sp, at); 11927304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 11937304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ bind(&loop); 11947304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ lw(at, MemOperand(a2, -kPointerSize)); 11957304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ sw(at, MemOperand(a2)); 11967304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ Subu(a2, a2, Operand(kPointerSize)); 11977304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ Branch(&loop, ne, a2, Operand(sp)); 11987304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // Adjust the actual number of arguments and remove the top element 11997304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // (which is a copy of the last argument). 12007304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ Subu(a0, a0, Operand(1)); 12017304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ Pop(); 12027304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 12037304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 1204c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin, 1205c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // or a function proxy via CALL_FUNCTION_PROXY. 12067304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // a0: actual number of arguments 12077304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // a1: function 1208c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // t0: call type (0: JS function, 1: function proxy, 2: non-function) 1209c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com { Label function, non_proxy; 1210c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Branch(&function, eq, t0, Operand(zero_reg)); 1211c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Expected number of arguments is 0 for CALL_NON_FUNCTION. 1212c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ mov(a2, zero_reg); 1213c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Branch(&non_proxy, ne, t0, Operand(1)); 1214c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1215c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ push(a1); // Re-add proxy object as additional argument. 1216c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Addu(a0, a0, Operand(1)); 121726ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org __ GetBuiltinFunction(a1, Builtins::CALL_FUNCTION_PROXY); 1218c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), 1219c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RelocInfo::CODE_TARGET); 1220c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1221c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ bind(&non_proxy); 122226ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org __ GetBuiltinFunction(a1, Builtins::CALL_NON_FUNCTION); 12237304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), 12247304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org RelocInfo::CODE_TARGET); 12257304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ bind(&function); 12267304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 12277304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 12287304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // 5b. Get the code to call from the function and check that the number of 12297304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // expected arguments matches what we're providing. If so, jump 12307304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // (tail-call) to the code in register edx without checking arguments. 12317304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // a0: actual number of arguments 12327304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // a1: function 12337304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ lw(a3, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); 12347304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ lw(a2, 12357304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org FieldMemOperand(a3, SharedFunctionInfo::kFormalParameterCountOffset)); 12367304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ sra(a2, a2, kSmiTagSize); 12377304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // Check formal and actual parameter counts. 12387304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), 12397304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org RelocInfo::CODE_TARGET, ne, a2, Operand(a0)); 12407304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 124126ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org __ lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); 12427304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org ParameterCount expected(0); 1243e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org __ InvokeCode(a3, expected, expected, JUMP_FUNCTION, NullCallWrapper()); 12445c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 12455c838251403b0be9a882540f1922577abba4c872ager@chromium.org 12465c838251403b0be9a882540f1922577abba4c872ager@chromium.org 12475c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Builtins::Generate_FunctionApply(MacroAssembler* masm) { 12487ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org const int kIndexOffset = 12497ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); 12507ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org const int kLimitOffset = 12517ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); 12527ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org const int kArgsOffset = 2 * kPointerSize; 12537ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org const int kRecvOffset = 3 * kPointerSize; 12547ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org const int kFunctionOffset = 4 * kPointerSize; 12557304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 1256c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com { 1257c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org FrameScope frame_scope(masm, StackFrame::INTERNAL); 1258c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ lw(a0, MemOperand(fp, kFunctionOffset)); // Get the function. 1259c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ push(a0); 1260c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ lw(a0, MemOperand(fp, kArgsOffset)); // Get the args array. 1261c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ push(a0); 1262c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Returns (in v0) number of arguments to copy to stack as Smi. 1263c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); 1264c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1265c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check the stack for overflow. We are not trying to catch 1266c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // interruptions (e.g. debug break and preemption) here, so the "real stack 1267c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // limit" is checked. 1268c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label okay; 1269c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ LoadRoot(a2, Heap::kRealStackLimitRootIndex); 1270c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Make a2 the space we have left. The stack might already be overflowed 1271c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // here which will cause a2 to become negative. 1272c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ subu(a2, sp, a2); 1273c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check if the arguments will overflow the stack. 1274c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ sll(t3, v0, kPointerSizeLog2 - kSmiTagSize); 1275c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Branch(&okay, gt, a2, Operand(t3)); // Signed comparison. 1276c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1277c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Out of stack space. 1278c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ lw(a1, MemOperand(fp, kFunctionOffset)); 1279057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org __ Push(a1, v0); 1280e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION); 1281c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // End of stack check. 1282c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1283c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Push current limit and index. 1284c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ bind(&okay); 12856f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org __ mov(a1, zero_reg); 12866f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org __ Push(v0, a1); // Limit and initial index. 12877304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 1288c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Get the receiver. 1289c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ lw(a0, MemOperand(fp, kRecvOffset)); 12907304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 1291c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check that the function is a JS function (otherwise it must be a proxy). 1292c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label push_receiver; 1293c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ lw(a1, MemOperand(fp, kFunctionOffset)); 1294c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ GetObjectType(a1, a2, a2); 1295c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Branch(&push_receiver, ne, a2, Operand(JS_FUNCTION_TYPE)); 12967304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 1297c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Change context eagerly to get the right global object if necessary. 1298c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); 1299c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Load the shared function info while the function is still in a1. 1300c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ lw(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); 13017304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 1302c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Compute the receiver. 1303c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Do not transform the receiver for strict mode functions. 1304f6e8ed2294f2eccae83564eead8b79ea050b9f21yangguo@chromium.org Label call_to_object, use_global_proxy; 1305c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ lw(a2, FieldMemOperand(a2, SharedFunctionInfo::kCompilerHintsOffset)); 1306c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ And(t3, a2, Operand(1 << (SharedFunctionInfo::kStrictModeFunction + 1307c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com kSmiTagSize))); 1308c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Branch(&push_receiver, ne, t3, Operand(zero_reg)); 1309c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1310c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Do not transform the receiver for native (Compilerhints already in a2). 1311c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ And(t3, a2, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize))); 1312c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Branch(&push_receiver, ne, t3, Operand(zero_reg)); 1313c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1314486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org // Compute the receiver in sloppy mode. 1315c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ JumpIfSmi(a0, &call_to_object); 1316c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ LoadRoot(a1, Heap::kNullValueRootIndex); 1317f6e8ed2294f2eccae83564eead8b79ea050b9f21yangguo@chromium.org __ Branch(&use_global_proxy, eq, a0, Operand(a1)); 1318c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); 1319f6e8ed2294f2eccae83564eead8b79ea050b9f21yangguo@chromium.org __ Branch(&use_global_proxy, eq, a0, Operand(a2)); 1320c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1321c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check if the receiver is already a JavaScript object. 1322c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // a0: receiver 1323c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE); 1324c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ GetObjectType(a0, a1, a1); 1325c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Branch(&push_receiver, ge, a1, Operand(FIRST_SPEC_OBJECT_TYPE)); 1326c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1327c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Convert the receiver to a regular object. 1328c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // a0: receiver 1329c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ bind(&call_to_object); 1330c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ push(a0); 1331c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); 1332c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ mov(a0, v0); // Put object in a0 to match other paths to push_receiver. 1333c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Branch(&push_receiver); 1334c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1335f6e8ed2294f2eccae83564eead8b79ea050b9f21yangguo@chromium.org __ bind(&use_global_proxy); 13369cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org __ lw(a0, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX)); 1337f6e8ed2294f2eccae83564eead8b79ea050b9f21yangguo@chromium.org __ lw(a0, FieldMemOperand(a0, GlobalObject::kGlobalProxyOffset)); 1338c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1339c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Push the receiver. 1340c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // a0: receiver 1341c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ bind(&push_receiver); 1342c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ push(a0); 1343c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1344c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Copy all arguments from the array to the stack. 1345c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label entry, loop; 1346c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ lw(a0, MemOperand(fp, kIndexOffset)); 1347c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Branch(&entry); 1348c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1349c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Load the current argument from the arguments array and push it to the 1350c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // stack. 1351c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // a0: current argument index 1352c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ bind(&loop); 1353c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ lw(a1, MemOperand(fp, kArgsOffset)); 1354057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org __ Push(a1, a0); 1355c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1356c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Call the runtime to access the property in the arguments array. 1357c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ CallRuntime(Runtime::kGetProperty, 2); 1358c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ push(v0); 1359c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1360c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Use inline caching to access the arguments. 1361c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ lw(a0, MemOperand(fp, kIndexOffset)); 1362c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Addu(a0, a0, Operand(1 << kSmiTagSize)); 1363c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ sw(a0, MemOperand(fp, kIndexOffset)); 1364c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1365c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Test if the copy loop has finished copying all the elements from the 1366c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // arguments object. 1367c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ bind(&entry); 1368c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ lw(a1, MemOperand(fp, kLimitOffset)); 1369c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Branch(&loop, ne, a0, Operand(a1)); 1370c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1371e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org // Call the function. 1372c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label call_proxy; 1373c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ParameterCount actual(a0); 1374c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ sra(a0, a0, kSmiTagSize); 1375c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ lw(a1, MemOperand(fp, kFunctionOffset)); 1376c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ GetObjectType(a1, a2, a2); 1377c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Branch(&call_proxy, ne, a2, Operand(JS_FUNCTION_TYPE)); 1378c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1379e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org __ InvokeFunction(a1, actual, CALL_FUNCTION, NullCallWrapper()); 1380c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1381c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org frame_scope.GenerateLeaveFrame(); 1382c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Ret(USE_DELAY_SLOT); 1383c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Addu(sp, sp, Operand(3 * kPointerSize)); // In delay slot. 1384c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1385e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org // Call the function proxy. 1386c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ bind(&call_proxy); 1387c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ push(a1); // Add function proxy as last argument. 1388c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Addu(a0, a0, Operand(1)); 138959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ li(a2, Operand(0, RelocInfo::NONE32)); 139026ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org __ GetBuiltinFunction(a1, Builtins::CALL_FUNCTION_PROXY); 1391c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), 1392c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RelocInfo::CODE_TARGET); 1393c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Tear down the internal frame and remove function, receiver and args. 1394c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 1395c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1396c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Ret(USE_DELAY_SLOT); 1397c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Addu(sp, sp, Operand(3 * kPointerSize)); // In delay slot. 13987304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org} 13997304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 14007304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 1401731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.orgstatic void ArgumentAdaptorStackCheck(MacroAssembler* masm, 1402731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org Label* stack_overflow) { 1403731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org // ----------- S t a t e ------------- 1404731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org // -- a0 : actual number of arguments 1405731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org // -- a1 : function (passed through to callee) 1406731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org // -- a2 : expected number of arguments 1407731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org // ----------------------------------- 1408731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org // Check the stack for overflow. We are not trying to catch 1409731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org // interruptions (e.g. debug break and preemption) here, so the "real stack 1410731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org // limit" is checked. 1411731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org __ LoadRoot(t1, Heap::kRealStackLimitRootIndex); 1412731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org // Make t1 the space we have left. The stack might already be overflowed 1413731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org // here which will cause t1 to become negative. 1414731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org __ subu(t1, sp, t1); 1415731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org // Check if the arguments will overflow the stack. 1416731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org __ sll(at, a2, kPointerSizeLog2); 1417731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org // Signed comparison. 1418731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org __ Branch(stack_overflow, le, t1, Operand(at)); 1419731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org} 1420731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org 1421731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org 14227304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.orgstatic void EnterArgumentsAdaptorFrame(MacroAssembler* masm) { 14237304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ sll(a0, a0, kSmiTagSize); 14247304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ li(t0, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 14257304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ MultiPush(a0.bit() | a1.bit() | t0.bit() | fp.bit() | ra.bit()); 14267ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org __ Addu(fp, sp, 14277ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org Operand(StandardFrameConstants::kFixedFrameSizeFromFp + kPointerSize)); 14287304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org} 14297304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 14307304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 14317304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.orgstatic void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) { 14327304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // ----------- S t a t e ------------- 14337304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // -- v0 : result being passed through 14347304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // ----------------------------------- 14357304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // Get the number of arguments passed (as a smi), tear down the frame and 14367304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // then tear down the parameters. 14377ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org __ lw(a1, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp + 14387ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org kPointerSize))); 14397304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ mov(sp, fp); 14407304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ MultiPop(fp.bit() | ra.bit()); 14417304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ sll(t0, a1, kPointerSizeLog2 - kSmiTagSize); 14427304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ Addu(sp, sp, t0); 14437304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // Adjust for the receiver. 14447304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ Addu(sp, sp, Operand(kPointerSize)); 14455c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 14465c838251403b0be9a882540f1922577abba4c872ager@chromium.org 14475c838251403b0be9a882540f1922577abba4c872ager@chromium.org 14485c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { 14497304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // State setup as expected by MacroAssembler::InvokePrologue. 14507304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // ----------- S t a t e ------------- 14517304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // -- a0: actual arguments count 14527304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // -- a1: function (passed through to callee) 14537304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // -- a2: expected arguments count 14547304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // ----------------------------------- 14557304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 1456731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org Label stack_overflow; 1457731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org ArgumentAdaptorStackCheck(masm, &stack_overflow); 14587304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Label invoke, dont_adapt_arguments; 14597304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 14607304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Label enough, too_few; 146126ca35cc4ec47151d9c6d3890b0f052fc79cb8afmachenbach@chromium.org __ lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); 14627304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ Branch(&dont_adapt_arguments, eq, 14637304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org a2, Operand(SharedFunctionInfo::kDontAdaptArgumentsSentinel)); 14647304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // We use Uless as the number of argument should always be greater than 0. 14657304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ Branch(&too_few, Uless, a0, Operand(a2)); 14667304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 14677304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org { // Enough parameters: actual >= expected. 14687304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // a0: actual number of arguments as a smi 14697304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // a1: function 14707304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // a2: expected number of arguments 14717304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // a3: code entry to call 14727304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ bind(&enough); 14737304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org EnterArgumentsAdaptorFrame(masm); 14747304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 14757304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // Calculate copy start address into a0 and copy end address into a2. 14767304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ sll(a0, a0, kPointerSizeLog2 - kSmiTagSize); 14777304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ Addu(a0, fp, a0); 14787304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // Adjust for return address and receiver. 14797304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ Addu(a0, a0, Operand(2 * kPointerSize)); 14807304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // Compute copy end address. 14817304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ sll(a2, a2, kPointerSizeLog2); 14827304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ subu(a2, a0, a2); 14837304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 14847304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // Copy the arguments (including the receiver) to the new stack frame. 14857304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // a0: copy start address 14867304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // a1: function 14877304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // a2: copy end address 14887304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // a3: code entry to call 14897304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 14907304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Label copy; 14917304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ bind(©); 14927304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ lw(t0, MemOperand(a0)); 14937304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ push(t0); 14947304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ Branch(USE_DELAY_SLOT, ©, ne, a0, Operand(a2)); 14957304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ addiu(a0, a0, -kPointerSize); // In delay slot. 14967304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 14977304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ jmp(&invoke); 14987304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 14997304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 15007304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org { // Too few parameters: Actual < expected. 15017304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ bind(&too_few); 15027304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org EnterArgumentsAdaptorFrame(masm); 15037304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 15047304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // Calculate copy start address into a0 and copy end address is fp. 15057304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // a0: actual number of arguments as a smi 15067304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // a1: function 15077304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // a2: expected number of arguments 15087304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // a3: code entry to call 15097304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ sll(a0, a0, kPointerSizeLog2 - kSmiTagSize); 15107304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ Addu(a0, fp, a0); 15117304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // Adjust for return address and receiver. 15127304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ Addu(a0, a0, Operand(2 * kPointerSize)); 15137304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // Compute copy end address. Also adjust for return address. 1514d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com __ Addu(t3, fp, kPointerSize); 15157304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 15167304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // Copy the arguments (including the receiver) to the new stack frame. 15177304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // a0: copy start address 15187304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // a1: function 15197304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // a2: expected number of arguments 15207304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // a3: code entry to call 1521d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com // t3: copy end address 15227304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Label copy; 15237304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ bind(©); 15247304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ lw(t0, MemOperand(a0)); // Adjusted above for return addr and receiver. 1525bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ Subu(sp, sp, kPointerSize); 15267304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ Subu(a0, a0, kPointerSize); 1527bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ Branch(USE_DELAY_SLOT, ©, ne, a0, Operand(t3)); 1528bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ sw(t0, MemOperand(sp)); // In the delay slot. 15297304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 15307304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // Fill the remaining expected arguments with undefined. 15317304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // a1: function 15327304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // a2: expected number of arguments 15337304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // a3: code entry to call 15347304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ LoadRoot(t0, Heap::kUndefinedValueRootIndex); 15357304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ sll(t2, a2, kPointerSizeLog2); 15367304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ Subu(a2, fp, Operand(t2)); 15377ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org // Adjust for frame. 15387ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org __ Subu(a2, a2, Operand(StandardFrameConstants::kFixedFrameSizeFromFp + 15397ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org 2 * kPointerSize)); 15407304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 15417304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Label fill; 15427304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ bind(&fill); 1543bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ Subu(sp, sp, kPointerSize); 1544bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ Branch(USE_DELAY_SLOT, &fill, ne, sp, Operand(a2)); 1545bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com __ sw(t0, MemOperand(sp)); 15467304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 15477304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 15487304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // Call the entry point. 15497304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ bind(&invoke); 15507304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 15517304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ Call(a3); 15527304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 1553812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // Store offset of return address for deoptimizer. 1554fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org masm->isolate()->heap()->SetArgumentsAdaptorDeoptPCOffset(masm->pc_offset()); 1555812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 15567304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // Exit frame and return. 15577304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org LeaveArgumentsAdaptorFrame(masm); 15587304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ Ret(); 15597304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 15607304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 15617304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // ------------------------------------------- 15627304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // Don't adapt arguments. 15637304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // ------------------------------------------- 15647304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ bind(&dont_adapt_arguments); 15657304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org __ Jump(a3); 1566731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org 1567731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org __ bind(&stack_overflow); 1568731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org { 1569731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org FrameScope frame(masm, StackFrame::MANUAL); 1570731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org EnterArgumentsAdaptorFrame(masm); 1571731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION); 1572731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org __ break_(0xCC); 1573731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org } 15745c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 15755c838251403b0be9a882540f1922577abba4c872ager@chromium.org 15765c838251403b0be9a882540f1922577abba4c872ager@chromium.org 15775c838251403b0be9a882540f1922577abba4c872ager@chromium.org#undef __ 15785c838251403b0be9a882540f1922577abba4c872ager@chromium.org 15795c838251403b0be9a882540f1922577abba4c872ager@chromium.org} } // namespace v8::internal 15805c838251403b0be9a882540f1922577abba4c872ager@chromium.org 15819dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com#endif // V8_TARGET_ARCH_MIPS 1582