1fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Redistribution and use in source and binary forms, with or without 343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// modification, are permitted provided that the following conditions are 443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// met: 543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// * Redistributions of source code must retain the above copyright 743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// notice, this list of conditions and the following disclaimer. 843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// * Redistributions in binary form must reproduce the above 943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// copyright notice, this list of conditions and the following 1043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// disclaimer in the documentation and/or other materials provided 1143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// with the distribution. 1243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// * Neither the name of Google Inc. nor the names of its 1343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// contributors may be used to endorse or promote products derived 1443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// from this software without specific prior written permission. 1543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 1643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "v8.h" 2943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_ARM 319dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 3244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org#include "codegen.h" 3343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "debug.h" 34a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "deoptimizer.h" 35a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "full-codegen.h" 3643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "runtime.h" 3743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 { 3971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal { 4043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4265dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#define __ ACCESS_MASM(masm) 4343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 45b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid Builtins::Generate_Adaptor(MacroAssembler* masm, 46b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org CFunctionId id, 47b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org BuiltinExtraArguments extra_args) { 48b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // ----------- S t a t e ------------- 49b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // -- r0 : number of arguments excluding receiver 50b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // -- r1 : called function (only guaranteed when 51b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // extra_args requires it) 52b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // -- cp : context 53b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // -- sp[0] : last argument 54b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // -- ... 55b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // -- sp[4 * (argc - 1)] : first argument (argc == r0) 56b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // -- sp[4 * argc] : receiver 57b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // ----------------------------------- 58b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 59b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // Insert extra arguments. 60b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org int num_extra_args = 0; 61b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org if (extra_args == NEEDS_CALLED_FUNCTION) { 62b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org num_extra_args = 1; 63b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ push(r1); 64b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } else { 65b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org ASSERT(extra_args == NO_EXTRA_ARGUMENTS); 66b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 67b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 68ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org // JumpToExternalReference expects r0 to contain the number of arguments 69b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org // including the receiver and the extra arguments. 70b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org __ add(r0, r0, Operand(num_extra_args + 1)); 71ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ JumpToExternalReference(ExternalReference(id, masm->isolate())); 72c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org} 73c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org 74c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org 753c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.org// Load the built-in InternalArray function from the current context. 763c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.orgstatic void GenerateLoadInternalArrayFunction(MacroAssembler* masm, 773c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.org Register result) { 7846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Load the native context. 793c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.org 803c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.org __ ldr(result, 8146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 8246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ ldr(result, 8346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org FieldMemOperand(result, GlobalObject::kNativeContextOffset)); 8446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Load the InternalArray function from the native context. 853c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.org __ ldr(result, 863c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.org MemOperand(result, 873c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.org Context::SlotOffset( 883c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.org Context::INTERNAL_ARRAY_FUNCTION_INDEX))); 893c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.org} 903c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.org 913c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.org 92c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org// Load the built-in Array function from the current context. 93c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.orgstatic void GenerateLoadArrayFunction(MacroAssembler* masm, Register result) { 9446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Load the native context. 95c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org 96c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org __ ldr(result, 9746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 9846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ ldr(result, 9946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org FieldMemOperand(result, GlobalObject::kNativeContextOffset)); 10046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Load the Array function from the native context. 101c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org __ ldr(result, 102c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org MemOperand(result, 103c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org Context::SlotOffset(Context::ARRAY_FUNCTION_INDEX))); 104c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org} 105c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org 106c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org 1073c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.orgvoid Builtins::Generate_InternalArrayCode(MacroAssembler* masm) { 1083c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.org // ----------- S t a t e ------------- 1093c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.org // -- r0 : number of arguments 1103c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.org // -- lr : return address 1113c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.org // -- sp[...]: constructor arguments 1123c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.org // ----------------------------------- 1133c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.org Label generic_array_code, one_or_more_arguments, two_or_more_arguments; 1143c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.org 1153c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.org // Get the InternalArray function. 1163c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.org GenerateLoadInternalArrayFunction(masm, r1); 1173c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.org 1183c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.org if (FLAG_debug_code) { 1193c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.org // Initial map for the builtin InternalArray functions should be maps. 1203c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.org __ ldr(r2, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset)); 121bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org __ SmiTst(r2); 122594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Assert(ne, kUnexpectedInitialMapForInternalArrayFunction); 1233c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.org __ CompareObjectType(r2, r3, r4, MAP_TYPE); 124594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Assert(eq, kUnexpectedInitialMapForInternalArrayFunction); 1253c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.org } 1263c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.org 1273c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.org // Run the native code for the InternalArray function called as a normal 1283c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.org // function. 1291510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org // tail call a stub 1301510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org InternalArrayConstructorStub stub(masm->isolate()); 1311510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ TailCallStub(&stub); 1323c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.org} 1333c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.org 1343c93e774a3c6dc64c4d10d9cc7d5e071f0e8a28esvenpanne@chromium.org 1352bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.comvoid Builtins::Generate_ArrayCode(MacroAssembler* masm) { 136c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // ----------- S t a t e ------------- 137c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // -- r0 : number of arguments 138c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // -- lr : return address 139c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // -- sp[...]: constructor arguments 140c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // ----------------------------------- 141c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org Label generic_array_code, one_or_more_arguments, two_or_more_arguments; 142c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org 143c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // Get the Array function. 144c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org GenerateLoadArrayFunction(masm, r1); 145c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org 146c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org if (FLAG_debug_code) { 1478f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org // Initial map for the builtin Array functions should be maps. 148c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org __ ldr(r2, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset)); 149bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org __ SmiTst(r2); 150594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Assert(ne, kUnexpectedInitialMapForArrayFunction); 151c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org __ CompareObjectType(r2, r3, r4, MAP_TYPE); 152594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Assert(eq, kUnexpectedInitialMapForArrayFunction); 153c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org } 154c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org 155c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // Run the native code for the Array function called as a normal function. 1561510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org // tail call a stub 1571510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Handle<Object> undefined_sentinel( 1581510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org masm->isolate()->heap()->undefined_value(), 1591510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org masm->isolate()); 1601510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ mov(r2, Operand(undefined_sentinel)); 1611510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ArrayConstructorStub stub(masm->isolate()); 1621510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ TailCallStub(&stub); 1632bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com} 1642bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com 1652bc58ef330b2d92ba287754282872699c151db4achristian.plesner.hansen@gmail.com 166d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.orgvoid Builtins::Generate_StringConstructCode(MacroAssembler* masm) { 167beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org // ----------- S t a t e ------------- 168beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org // -- r0 : number of arguments 169beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org // -- r1 : constructor function 170beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org // -- lr : return address 171beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org // -- sp[(argc - n - 1) * 4] : arg[n] (zero based) 172beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org // -- sp[argc * 4] : receiver 173beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org // ----------------------------------- 1747979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Counters* counters = masm->isolate()->counters(); 1757979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ IncrementCounter(counters->string_ctor_calls(), 1, r2, r3); 176beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org 177beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org Register function = r1; 178beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org if (FLAG_debug_code) { 179beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org __ LoadGlobalFunction(Context::STRING_FUNCTION_INDEX, r2); 180beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org __ cmp(function, Operand(r2)); 181594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Assert(eq, kUnexpectedStringFunction); 182beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org } 183beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org 184beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org // Load the first arguments in r0 and get rid of the rest. 185beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org Label no_arguments; 18659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ cmp(r0, Operand::Zero()); 187beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org __ b(eq, &no_arguments); 188beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org // First args = sp[(argc - 1) * 4]. 189beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org __ sub(r0, r0, Operand(1)); 190beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org __ ldr(r0, MemOperand(sp, r0, LSL, kPointerSizeLog2, PreIndex)); 191beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org // sp now point to args[0], drop args[0] + receiver. 192beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org __ Drop(2); 193beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org 194beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org Register argument = r2; 195beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org Label not_cached, argument_is_string; 196528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ LookupNumberStringCache(r0, // Input. 197528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org argument, // Result. 198528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org r3, // Scratch. 199528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org r4, // Scratch. 200528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org r5, // Scratch. 201528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org ¬_cached); 2027979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ IncrementCounter(counters->string_ctor_cached_number(), 1, r3, r4); 203beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org __ bind(&argument_is_string); 204beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org 205beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org // ----------- S t a t e ------------- 206beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org // -- r2 : argument converted to string 207beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org // -- r1 : constructor function 208beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org // -- lr : return address 209beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org // ----------------------------------- 210beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org 211beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org Label gc_required; 2122bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org __ Allocate(JSValue::kSize, 2132bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org r0, // Result. 2142bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org r3, // Scratch. 2152bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org r4, // Scratch. 2162bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org &gc_required, 2172bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org TAG_OBJECT); 218beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org 219beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org // Initialising the String Object. 220beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org Register map = r3; 221beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org __ LoadGlobalFunctionInitialMap(function, map, r4); 222beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org if (FLAG_debug_code) { 223beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org __ ldrb(r4, FieldMemOperand(map, Map::kInstanceSizeOffset)); 224beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org __ cmp(r4, Operand(JSValue::kSize >> kPointerSizeLog2)); 225594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Assert(eq, kUnexpectedStringWrapperInstanceSize); 226beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org __ ldrb(r4, FieldMemOperand(map, Map::kUnusedPropertyFieldsOffset)); 22759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ cmp(r4, Operand::Zero()); 228594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Assert(eq, kUnexpectedUnusedPropertiesOfStringWrapper); 229beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org } 230beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org __ str(map, FieldMemOperand(r0, HeapObject::kMapOffset)); 231beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org 232beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org __ LoadRoot(r3, Heap::kEmptyFixedArrayRootIndex); 233beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org __ str(r3, FieldMemOperand(r0, JSObject::kPropertiesOffset)); 234beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org __ str(r3, FieldMemOperand(r0, JSObject::kElementsOffset)); 235beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org 236beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org __ str(argument, FieldMemOperand(r0, JSValue::kValueOffset)); 237beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org 238beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org // Ensure the object is fully initialized. 239beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize); 240beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org 241beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org __ Ret(); 242beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org 243beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org // The argument was not found in the number to string cache. Check 244beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org // if it's a string already before calling the conversion builtin. 245beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org Label convert_argument; 246beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org __ bind(¬_cached); 247378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org __ JumpIfSmi(r0, &convert_argument); 248beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org 249beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org // Is it a String? 250beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org __ ldr(r2, FieldMemOperand(r0, HeapObject::kMapOffset)); 251beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org __ ldrb(r3, FieldMemOperand(r2, Map::kInstanceTypeOffset)); 25280c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org STATIC_ASSERT(kNotStringTag != 0); 253beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org __ tst(r3, Operand(kIsNotStringMask)); 254beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org __ b(ne, &convert_argument); 255beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org __ mov(argument, r0); 2567979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ IncrementCounter(counters->string_ctor_conversions(), 1, r3, r4); 257beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org __ b(&argument_is_string); 258beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org 259beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org // Invoke the conversion builtin and put the result into r2. 260beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org __ bind(&convert_argument); 261beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org __ push(function); // Preserve the function. 2627979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ IncrementCounter(counters->string_ctor_conversions(), 1, r3, r4); 263c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com { 264c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FrameScope scope(masm, StackFrame::INTERNAL); 265c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ push(r0); 266c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ InvokeBuiltin(Builtins::TO_STRING, CALL_FUNCTION); 267c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 268beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org __ pop(function); 269beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org __ mov(argument, r0); 270beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org __ b(&argument_is_string); 271beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org 272beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org // Load the empty string into r2, remove the receiver from the 273beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org // stack, and jump back to the case where the argument is a string. 274beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org __ bind(&no_arguments); 2754a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ LoadRoot(argument, Heap::kempty_stringRootIndex); 276beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org __ Drop(1); 277beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org __ b(&argument_is_string); 278beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org 279beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org // At this point the argument is already a string. Call runtime to 280beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org // create a string wrapper. 281beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org __ bind(&gc_required); 2827979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ IncrementCounter(counters->string_ctor_gc_required(), 1, r3, r4); 283c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com { 284c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FrameScope scope(masm, StackFrame::INTERNAL); 285c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ push(argument); 286c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ CallRuntime(Runtime::kNewStringWrapper, 1); 287c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 288beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org __ Ret(); 289d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org} 290d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 291d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org 2924a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.orgstatic void CallRuntimePassFunction(MacroAssembler* masm, 2934a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org Runtime::FunctionId function_id) { 2944a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org FrameScope scope(masm, StackFrame::INTERNAL); 2954a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org // Push a copy of the function onto the stack. 2964a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org __ push(r1); 297057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org // Push call kind information and function as parameter to the runtime call. 298057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org __ Push(r5, r1); 2994a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org 3004a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org __ CallRuntime(function_id, 1); 3014a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org // Restore call kind information. 3024a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org __ pop(r5); 3034a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org // Restore receiver. 3044a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org __ pop(r1); 3054a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org} 3064a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org 3074a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org 308304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.orgstatic void GenerateTailCallToSharedCode(MacroAssembler* masm) { 309304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org __ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); 310304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org __ ldr(r2, FieldMemOperand(r2, SharedFunctionInfo::kCodeOffset)); 311304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org __ add(r2, r2, Operand(Code::kHeaderSize - kHeapObjectTag)); 3124a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org __ Jump(r2); 313304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org} 314304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 315304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 316304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.orgvoid Builtins::Generate_InRecompileQueue(MacroAssembler* masm) { 3174a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org // Checking whether the queued function is ready for install is optional, 3184a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org // since we come across interrupts and stack checks elsewhere. However, 3194a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org // not checking may delay installing ready functions, and always checking 3204a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org // would be quite expensive. A good compromise is to first check against 3214a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org // stack limit as a cue for an interrupt signal. 3224a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org Label ok; 3234a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org __ LoadRoot(ip, Heap::kStackLimitRootIndex); 3244a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org __ cmp(sp, Operand(ip)); 3254a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org __ b(hs, &ok); 3264a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org 3274a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org CallRuntimePassFunction(masm, Runtime::kTryInstallRecompiledCode); 3284a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org // Tail call to returned code. 3294a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org __ add(r0, r0, Operand(Code::kHeaderSize - kHeapObjectTag)); 3304a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org __ Jump(r0); 3314a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org 3324a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org __ bind(&ok); 333304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org GenerateTailCallToSharedCode(masm); 334304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org} 335304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 336304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 3379259716434187c932704601f700375e53d865de8rossberg@chromium.orgvoid Builtins::Generate_ConcurrentRecompile(MacroAssembler* masm) { 3384a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org CallRuntimePassFunction(masm, Runtime::kConcurrentRecompile); 339304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org GenerateTailCallToSharedCode(masm); 340304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org} 341304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 342304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 343fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.orgstatic void Generate_JSConstructStubHelper(MacroAssembler* masm, 344fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org bool is_api_function, 345fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org bool count_constructions) { 346b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // ----------- S t a t e ------------- 347b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // -- r0 : number of arguments 348b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // -- r1 : constructor function 349b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // -- lr : return address 350b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // -- sp[...]: constructor arguments 351b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // ----------------------------------- 352b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 3534a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org // Should never count constructions for api objects. 3544a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org ASSERT(!is_api_function || !count_constructions); 3554a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 3567979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Isolate* isolate = masm->isolate(); 3577979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org 3587c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org // Enter a construct frame. 359c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com { 360c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FrameScope scope(masm, StackFrame::CONSTRUCT); 361c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 362c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Preserve the two incoming parameters on the stack. 363bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org __ SmiTag(r0); 364c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ push(r0); // Smi-tagged arguments count. 365c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ push(r1); // Constructor function. 366c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 367c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Try to allocate the object without transitioning into C code. If any of 368c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // the preconditions is not met, the code bails out to the runtime call. 369c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label rt_call, allocated; 370c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (FLAG_inline_new) { 371c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label undo_allocation; 372a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org#ifdef ENABLE_DEBUGGER_SUPPORT 373c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ExternalReference debug_step_in_fp = 374c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ExternalReference::debug_step_in_fp_address(isolate); 375c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ mov(r2, Operand(debug_step_in_fp)); 376c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ ldr(r2, MemOperand(r2)); 377c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ tst(r2, r2); 378c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ b(ne, &rt_call); 379a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org#endif 380a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org 381c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Load the initial map and verify that it is in fact a map. 382c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r1: constructor function 383c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ ldr(r2, FieldMemOperand(r1, JSFunction::kPrototypeOrInitialMapOffset)); 384c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ JumpIfSmi(r2, &rt_call); 385c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ CompareObjectType(r2, r3, r4, MAP_TYPE); 386c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ b(ne, &rt_call); 387c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 388c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check that the constructor is not constructing a JSFunction (see 389c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // comments in Runtime_NewObject in runtime.cc). In which case the 390c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // initial map's instance type would be JS_FUNCTION_TYPE. 391c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r1: constructor function 392c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r2: initial map 393c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ CompareInstanceType(r2, r3, JS_FUNCTION_TYPE); 394c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ b(eq, &rt_call); 3954a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 396c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (count_constructions) { 397c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label allocate; 398c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Decrease generous allocation count. 399c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ ldr(r3, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); 400c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com MemOperand constructor_count = 401c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FieldMemOperand(r3, SharedFunctionInfo::kConstructionCountOffset); 402c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ ldrb(r4, constructor_count); 403c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ sub(r4, r4, Operand(1), SetCC); 404c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ strb(r4, constructor_count); 405c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ b(ne, &allocate); 406c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 407057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org __ push(r1); 408c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 409057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org __ Push(r2, r1); // r1 = constructor 410c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // The call will replace the stub, so the countdown is only done once. 411c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ CallRuntime(Runtime::kFinalizeInstanceSize, 1); 412c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 413c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ pop(r2); 414c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ pop(r1); 415c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 416c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ bind(&allocate); 417c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 418a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org 419c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Now allocate the JSObject on the heap. 420c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r1: constructor function 421c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r2: initial map 422c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ ldrb(r3, FieldMemOperand(r2, Map::kInstanceSizeOffset)); 423f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org __ Allocate(r3, r4, r5, r6, &rt_call, SIZE_IN_WORDS); 424c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 425c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Allocated the JSObject, now initialize the fields. Map is set to 426c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // initial map and properties and elements are set to empty fixed array. 427c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r1: constructor function 428c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r2: initial map 429c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r3: object size 430c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r4: JSObject (not tagged) 431c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ LoadRoot(r6, Heap::kEmptyFixedArrayRootIndex); 432c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ mov(r5, r4); 433c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT_EQ(0 * kPointerSize, JSObject::kMapOffset); 434c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ str(r2, MemOperand(r5, kPointerSize, PostIndex)); 435c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT_EQ(1 * kPointerSize, JSObject::kPropertiesOffset); 436c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ str(r6, MemOperand(r5, kPointerSize, PostIndex)); 437c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT_EQ(2 * kPointerSize, JSObject::kElementsOffset); 438c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ str(r6, MemOperand(r5, kPointerSize, PostIndex)); 439c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 440c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Fill all the in-object properties with the appropriate filler. 441c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r1: constructor function 442c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r2: initial map 443c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r3: object size (in words) 444c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r4: JSObject (not tagged) 445c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r5: First in-object property of JSObject (not tagged) 446c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT_EQ(3 * kPointerSize, JSObject::kHeaderSize); 4473d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org __ LoadRoot(r6, Heap::kUndefinedValueRootIndex); 4484a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org if (count_constructions) { 449c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ ldr(r0, FieldMemOperand(r2, Map::kInstanceSizesOffset)); 450c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Ubfx(r0, r0, Map::kPreAllocatedPropertyFieldsByte * kBitsPerByte, 451c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com kBitsPerByte); 452c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ add(r0, r5, Operand(r0, LSL, kPointerSizeLog2)); 453c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r0: offset of first field after pre-allocated fields 454c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (FLAG_debug_code) { 4553d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org __ add(ip, r4, Operand(r3, LSL, kPointerSizeLog2)); // End of object. 4563d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org __ cmp(r0, ip); 457594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Assert(le, kUnexpectedNumberOfPreAllocatedPropertyFields); 458c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 4593d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org __ InitializeFieldsWithFiller(r5, r0, r6); 4604a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org // To allow for truncation. 4613d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org __ LoadRoot(r6, Heap::kOnePointerFillerMapRootIndex); 4624a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org } 4633d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org __ add(r0, r4, Operand(r3, LSL, kPointerSizeLog2)); // End of object. 4643d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org __ InitializeFieldsWithFiller(r5, r0, r6); 465c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 466c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Add the object tag to make the JSObject real, so that we can continue 467c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // and jump into the continuation code at any time from now on. Any 468c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // failures need to undo the allocation, so that the heap is in a 469c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // consistent state and verifiable. 470c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ add(r4, r4, Operand(kHeapObjectTag)); 471c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 472c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check if a non-empty properties array is needed. Continue with 473c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // allocated object if not fall through to runtime call if it is. 474c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r1: constructor function 475c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r4: JSObject 476c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r5: start of next object (not tagged) 477c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ ldrb(r3, FieldMemOperand(r2, Map::kUnusedPropertyFieldsOffset)); 478c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // The field instance sizes contains both pre-allocated property fields 479c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // and in-object properties. 480c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ ldr(r0, FieldMemOperand(r2, Map::kInstanceSizesOffset)); 481c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Ubfx(r6, r0, Map::kPreAllocatedPropertyFieldsByte * kBitsPerByte, 482c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com kBitsPerByte); 483c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ add(r3, r3, Operand(r6)); 484c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Ubfx(r6, r0, Map::kInObjectPropertiesByte * kBitsPerByte, 485c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com kBitsPerByte); 486c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ sub(r3, r3, Operand(r6), SetCC); 487c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 488c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Done if no extra properties are to be allocated. 489c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ b(eq, &allocated); 490594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Assert(pl, kPropertyAllocationCountFailed); 491c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 492c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Scale the number of elements by pointer size and add the header for 493c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // FixedArrays to the start of the next object calculation from above. 494c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r1: constructor 495c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r3: number of elements in properties array 496c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r4: JSObject 497c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r5: start of next object 498c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ add(r0, r3, Operand(FixedArray::kHeaderSize / kPointerSize)); 499f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org __ Allocate( 500c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com r0, 501c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com r5, 502c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com r6, 503c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com r2, 504c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com &undo_allocation, 505c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com static_cast<AllocationFlags>(RESULT_CONTAINS_TOP | SIZE_IN_WORDS)); 506c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 507c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Initialize the FixedArray. 508c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r1: constructor 509c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r3: number of elements in properties array 510c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r4: JSObject 511c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r5: FixedArray (not tagged) 512c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ LoadRoot(r6, Heap::kFixedArrayMapRootIndex); 513c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ mov(r2, r5); 514c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT_EQ(0 * kPointerSize, JSObject::kMapOffset); 515c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ str(r6, MemOperand(r2, kPointerSize, PostIndex)); 516c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT_EQ(1 * kPointerSize, FixedArray::kLengthOffset); 517bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org __ SmiTag(r0, r3); 518c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ str(r0, MemOperand(r2, kPointerSize, PostIndex)); 519c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 520c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Initialize the fields to undefined. 521c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r1: constructor function 522c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r2: First element of FixedArray (not tagged) 523c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r3: number of elements in properties array 524c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r4: JSObject 525c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r5: FixedArray (not tagged) 526c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ add(r6, r2, Operand(r3, LSL, kPointerSizeLog2)); // End of object. 527c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT_EQ(2 * kPointerSize, FixedArray::kHeaderSize); 528c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com { Label loop, entry; 5293d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org __ LoadRoot(r0, Heap::kUndefinedValueRootIndex); 530c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ b(&entry); 531c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ bind(&loop); 5323d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org __ str(r0, MemOperand(r2, kPointerSize, PostIndex)); 533c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ bind(&entry); 534c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ cmp(r2, r6); 535c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ b(lt, &loop); 536c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 537a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org 538c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Store the initialized FixedArray into the properties field of 539c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // the JSObject 540c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r1: constructor function 541c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r4: JSObject 542c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r5: FixedArray (not tagged) 543c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ add(r5, r5, Operand(kHeapObjectTag)); // Add the heap tag. 544c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ str(r5, FieldMemOperand(r4, JSObject::kPropertiesOffset)); 545c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 546c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Continue with JSObject being successfully allocated 547c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r1: constructor function 548c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r4: JSObject 549c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ jmp(&allocated); 550c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 551c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Undo the setting of the new top so that the heap is verifiable. For 552c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // example, the map's unused properties potentially do not match the 553c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // allocated objects unused properties. 554c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r4: JSObject (previous new top) 555c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ bind(&undo_allocation); 556c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ UndoAllocationInNewSpace(r4, r5); 557c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 558a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org 559c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Allocate the new receiver object using the runtime call. 560a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // r1: constructor function 561c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ bind(&rt_call); 562c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ push(r1); // argument for Runtime_NewObject 563c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ CallRuntime(Runtime::kNewObject, 1); 564c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ mov(r4, r0); 565c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 566c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Receiver for constructor call allocated. 567a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // r4: JSObject 568c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ bind(&allocated); 569c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ push(r4); 57078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org __ push(r4); 571c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 57278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // Reload the number of arguments and the constructor from the stack. 573c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // sp[0]: receiver 57478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // sp[1]: receiver 57578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // sp[2]: constructor function 57678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // sp[3]: number of arguments (smi-tagged) 57778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org __ ldr(r1, MemOperand(sp, 2 * kPointerSize)); 57878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org __ ldr(r3, MemOperand(sp, 3 * kPointerSize)); 579c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 580f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // Set up pointer to last argument. 581c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ add(r2, fp, Operand(StandardFrameConstants::kCallerSPOffset)); 582c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 583f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // Set up number of arguments for function call below 584bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org __ SmiUntag(r0, r3); 585c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 586c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Copy arguments and receiver to the expression stack. 587c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r0: number of arguments 588a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // r1: constructor function 58978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // r2: address of last argument (caller sp) 590c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r3: number of arguments (smi-tagged) 591c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // sp[0]: receiver 59278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // sp[1]: receiver 59378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // sp[2]: constructor function 59478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // sp[3]: number of arguments (smi-tagged) 595c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label loop, entry; 596c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ b(&entry); 597c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ bind(&loop); 598c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ ldr(ip, MemOperand(r2, r3, LSL, kPointerSizeLog2 - 1)); 599c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ push(ip); 600c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ bind(&entry); 601c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ sub(r3, r3, Operand(2), SetCC); 602c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ b(ge, &loop); 603a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org 604c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Call the function. 605c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r0: number of arguments 606a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org // r1: constructor function 607c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (is_api_function) { 608c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); 609c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Handle<Code> code = 610c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com masm->isolate()->builtins()->HandleApiCallConstruct(); 611c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ParameterCount expected(0); 612c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ InvokeCode(code, expected, expected, 613c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RelocInfo::CODE_TARGET, CALL_FUNCTION, CALL_AS_METHOD); 614c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 615c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ParameterCount actual(r0); 616c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ InvokeFunction(r1, actual, CALL_FUNCTION, 617c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com NullCallWrapper(), CALL_AS_METHOD); 618c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 61943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 620967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org // Store offset of return address for deoptimizer. 621967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org if (!is_api_function && !count_constructions) { 622967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset()); 623967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org } 624967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org 625c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Restore context from the frame. 626c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r0: result 627c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // sp[0]: receiver 628c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // sp[1]: constructor function 629c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // sp[2]: number of arguments (smi-tagged) 630c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 631c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 632c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // If the result is an object (in the ECMA sense), we should get rid 633c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // of the receiver and use the result; see ECMA-262 section 13.2.2-7 634c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // on page 74. 635c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label use_receiver, exit; 636c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 637c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // If the result is a smi, it is *not* an object in the ECMA sense. 638c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r0: result 639c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // sp[0]: receiver (newly allocated object) 640c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // sp[1]: constructor function 641c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // sp[2]: number of arguments (smi-tagged) 642c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ JumpIfSmi(r0, &use_receiver); 643c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 644c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // If the type of the result (stored in its map) is less than 645c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // FIRST_SPEC_OBJECT_TYPE, it is not an object in the ECMA sense. 6464a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ CompareObjectType(r0, r1, r3, FIRST_SPEC_OBJECT_TYPE); 647c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ b(ge, &exit); 648c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 649c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Throw away the result of the constructor invocation and use the 650c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // on-stack receiver as the result. 651c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ bind(&use_receiver); 652c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ ldr(r0, MemOperand(sp)); 653c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 654c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Remove receiver from the stack, remove caller arguments, and 655c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // return. 656c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ bind(&exit); 657c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r0: result 658c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // sp[0]: receiver (newly allocated object) 659c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // sp[1]: constructor function 660c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // sp[2]: number of arguments (smi-tagged) 661c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ ldr(r1, MemOperand(sp, 2 * kPointerSize)); 662c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 663c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Leave construct frame. 664b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org } 66543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 666b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ add(sp, sp, Operand(r1, LSL, kPointerSizeLog2 - 1)); 667b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ add(sp, sp, Operand(kPointerSize)); 6687979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ IncrementCounter(isolate->counters()->constructed_objects(), 1, r1, r2); 6699085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org __ Jump(lr); 67043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 67143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 67243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 6734a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.orgvoid Builtins::Generate_JSConstructStubCountdown(MacroAssembler* masm) { 6744a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Generate_JSConstructStubHelper(masm, false, true); 6754a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org} 6764a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 6774a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org 678b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { 6794a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Generate_JSConstructStubHelper(masm, false, false); 680b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 681b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 682b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 683b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { 6844a1fe7d5e92fdb673d5f05d5ddf7b1ed703ba18dwhesse@chromium.org Generate_JSConstructStubHelper(masm, true, false); 685b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 686b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 687b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 68843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, 68943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen bool is_construct) { 69043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Called from Generate_JS_Entry 69143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // r0: code entry 69243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // r1: function 69343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // r2: receiver 69443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // r3: argc 69543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // r4: argv 696cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org // r5-r6, r8 (if not FLAG_enable_ool_constant_pool) and cp may be clobbered 6971510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ProfileEntryHookStub::MaybeCallEntryHook(masm); 69843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 699c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Clear the context before we push it when entering the internal frame. 70059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ mov(cp, Operand::Zero()); 701b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 702b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // Enter an internal frame. 703c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com { 704c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FrameScope scope(masm, StackFrame::INTERNAL); 70543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 706c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Set up the context from the function argument. 707c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); 70843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 709f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com __ InitializeRootRegister(); 710ab99eea3d9d0cc20698ebb39bf0fb80e3e66bffcager@chromium.org 711c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Push the function and the receiver onto the stack. 712c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ push(r1); 713c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ push(r2); 71443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 715c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Copy arguments to the stack in a loop. 716c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r1: function 717c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r3: argc 718c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r4: argv, i.e. points to first arg 719c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label loop, entry; 720c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ add(r2, r4, Operand(r3, LSL, kPointerSizeLog2)); 721c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r2 points past last arg. 722c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ b(&entry); 723c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ bind(&loop); 724c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ ldr(r0, MemOperand(r4, kPointerSize, PostIndex)); // read next parameter 725c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ ldr(r0, MemOperand(r0)); // dereference handle 726c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ push(r0); // push parameter 727c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ bind(&entry); 728c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ cmp(r4, r2); 729c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ b(ne, &loop); 73043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 731c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Initialize all JavaScript callee-saved registers, since they will be seen 732c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // by the garbage collector as part of handlers. 733c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ LoadRoot(r4, Heap::kUndefinedValueRootIndex); 734c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ mov(r5, Operand(r4)); 735c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ mov(r6, Operand(r4)); 7363d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org if (!FLAG_enable_ool_constant_pool) { 737cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ mov(r8, Operand(r4)); 7383d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.org } 739c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (kR9Available == 1) { 740c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ mov(r9, Operand(r4)); 741c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 74243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 743c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Invoke the code and pass argc as r0. 744c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ mov(r0, Operand(r3)); 745c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (is_construct) { 7464a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // No type feedback cell is available 7474a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Handle<Object> undefined_sentinel( 7484a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org masm->isolate()->heap()->undefined_value(), masm->isolate()); 7494a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ mov(r2, Operand(undefined_sentinel)); 750fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org CallConstructStub stub(NO_CALL_FUNCTION_FLAGS); 751fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org __ CallStub(&stub); 752c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 753c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ParameterCount actual(r0); 754c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ InvokeFunction(r1, actual, CALL_FUNCTION, 755c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com NullCallWrapper(), CALL_AS_METHOD); 756c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 757c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Exit the JS frame and remove the parameters (except function), and 758c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // return. 759c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Respect ABI stack constraint. 760c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 7619085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org __ Jump(lr); 76243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 76343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // r0: result 76443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 76543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 76643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 76743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) { 76843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Generate_JSEntryTrampolineHelper(masm, false); 76943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 77043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 77143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 77243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) { 77343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Generate_JSEntryTrampolineHelper(masm, true); 77443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 77543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 77643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 777ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.orgvoid Builtins::Generate_LazyCompile(MacroAssembler* masm) { 7784a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org CallRuntimePassFunction(masm, Runtime::kLazyCompile); 779ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org // Do a tail-call of the compiled function. 7804a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org __ add(r2, r0, Operand(Code::kHeaderSize - kHeapObjectTag)); 781ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org __ Jump(r2); 782ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org} 783ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 784ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org 785a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid Builtins::Generate_LazyRecompile(MacroAssembler* masm) { 7864a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org CallRuntimePassFunction(masm, Runtime::kLazyRecompile); 787a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Do a tail-call of the compiled function. 7884a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org __ add(r2, r0, Operand(Code::kHeaderSize - kHeapObjectTag)); 789a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ Jump(r2); 790a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 791a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 792a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 793e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgstatic void GenerateMakeCodeYoungAgainCommon(MacroAssembler* masm) { 794e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org // For now, we are relying on the fact that make_code_young doesn't do any 795e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org // garbage collection which allows us to save/restore the registers without 796e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org // worrying about which of them contain pointers. We also don't build an 797e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org // internal frame to make the code faster, since we shouldn't have to do stack 798e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org // crawls in MakeCodeYoung. This seems a bit fragile. 799e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 800e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org // The following registers must be saved and restored when calling through to 801e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org // the runtime: 802e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org // r0 - contains return address (beginning of patch sequence) 803528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // r1 - isolate 804e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org FrameScope scope(masm, StackFrame::MANUAL); 805e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org __ stm(db_w, sp, r0.bit() | r1.bit() | fp.bit() | lr.bit()); 806528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ PrepareCallCFunction(1, 0, r2); 807528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ mov(r1, Operand(ExternalReference::isolate_address(masm->isolate()))); 808e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org __ CallCFunction( 809528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org ExternalReference::get_make_code_young_function(masm->isolate()), 2); 810e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org __ ldm(ia_w, sp, r0.bit() | r1.bit() | fp.bit() | lr.bit()); 811e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org __ mov(pc, r0); 812e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org} 813e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 814e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org#define DEFINE_CODE_AGE_BUILTIN_GENERATOR(C) \ 815e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgvoid Builtins::Generate_Make##C##CodeYoungAgainEvenMarking( \ 816e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org MacroAssembler* masm) { \ 817e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org GenerateMakeCodeYoungAgainCommon(masm); \ 818e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org} \ 819e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgvoid Builtins::Generate_Make##C##CodeYoungAgainOddMarking( \ 820e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org MacroAssembler* masm) { \ 821e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org GenerateMakeCodeYoungAgainCommon(masm); \ 822e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org} 823e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.orgCODE_AGE_LIST(DEFINE_CODE_AGE_BUILTIN_GENERATOR) 824e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org#undef DEFINE_CODE_AGE_BUILTIN_GENERATOR 825e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 826e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 827c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.orgvoid Builtins::Generate_MarkCodeAsExecutedOnce(MacroAssembler* masm) { 828c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org // For now, as in GenerateMakeCodeYoungAgainCommon, we are relying on the fact 829c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org // that make_code_young doesn't do any garbage collection which allows us to 830c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org // save/restore the registers without worrying about which of them contain 831c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org // pointers. 832c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 833c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org // The following registers must be saved and restored when calling through to 834c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org // the runtime: 835c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org // r0 - contains return address (beginning of patch sequence) 836c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org // r1 - isolate 837c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org FrameScope scope(masm, StackFrame::MANUAL); 838c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ stm(db_w, sp, r0.bit() | r1.bit() | fp.bit() | lr.bit()); 839c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ PrepareCallCFunction(1, 0, r2); 840c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ mov(r1, Operand(ExternalReference::isolate_address(masm->isolate()))); 841c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ CallCFunction(ExternalReference::get_mark_code_as_executed_function( 842c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org masm->isolate()), 2); 843c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ ldm(ia_w, sp, r0.bit() | r1.bit() | fp.bit() | lr.bit()); 844c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 845c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org // Perform prologue operations usually performed by the young code stub. 846c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ stm(db_w, sp, r1.bit() | cp.bit() | fp.bit() | lr.bit()); 8477ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org __ add(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); 848c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 849c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org // Jump to point after the code-age stub. 850c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ add(r0, r0, Operand(kNoCodeAgeSequenceLength * Assembler::kInstrSize)); 851c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ mov(pc, r0); 852c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org} 853c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 854c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 855c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.orgvoid Builtins::Generate_MarkCodeAsExecutedTwice(MacroAssembler* masm) { 856c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org GenerateMakeCodeYoungAgainCommon(masm); 857c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org} 858c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 859c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 860f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.orgstatic void Generate_NotifyStubFailureHelper(MacroAssembler* masm, 861f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org SaveFPRegsMode save_doubles) { 862a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org { 863a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org FrameScope scope(masm, StackFrame::INTERNAL); 864a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 865a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Preserve registers across notification, this is important for compiled 866a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // stubs that tail call the runtime on deopts passing their parameters in 867a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // registers. 868a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ stm(db_w, sp, kJSCallerSaved | kCalleeSaved); 869a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org // Pass the function and deoptimization type to the runtime system. 870f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org __ CallRuntime(Runtime::kNotifyStubFailure, 0, save_doubles); 871a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ ldm(ia_w, sp, kJSCallerSaved | kCalleeSaved); 872a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org } 873a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 874a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org __ add(sp, sp, Operand(kPointerSize)); // Ignore state 875068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org __ mov(pc, lr); // Jump to miss handler 876a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org} 877a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 878a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 879f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.orgvoid Builtins::Generate_NotifyStubFailure(MacroAssembler* masm) { 880f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Generate_NotifyStubFailureHelper(masm, kDontSaveFPRegs); 881f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org} 882f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org 883f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org 884f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.orgvoid Builtins::Generate_NotifyStubFailureSaveDoubles(MacroAssembler* masm) { 885f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Generate_NotifyStubFailureHelper(masm, kSaveFPRegs); 886f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org} 887f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org 888f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org 889a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgstatic void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm, 890a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Deoptimizer::BailoutType type) { 891c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com { 892c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FrameScope scope(masm, StackFrame::INTERNAL); 893c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Pass the function and deoptimization type to the runtime system. 894c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ mov(r0, Operand(Smi::FromInt(static_cast<int>(type)))); 895c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ push(r0); 896c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ CallRuntime(Runtime::kNotifyDeoptimized, 1); 897c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 898a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 899a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Get the full codegen state from the stack and untag it -> r6. 900a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ ldr(r6, MemOperand(sp, 0 * kPointerSize)); 901a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ SmiUntag(r6); 902a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Switch on the state. 903a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Label with_tos_register, unknown_state; 904a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ cmp(r6, Operand(FullCodeGenerator::NO_REGISTERS)); 905a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ b(ne, &with_tos_register); 906a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ add(sp, sp, Operand(1 * kPointerSize)); // Remove state. 907a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ Ret(); 908a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 909a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ bind(&with_tos_register); 910a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ ldr(r0, MemOperand(sp, 1 * kPointerSize)); 911a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ cmp(r6, Operand(FullCodeGenerator::TOS_REG)); 912a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ b(ne, &unknown_state); 913a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ add(sp, sp, Operand(2 * kPointerSize)); // Remove state. 914a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ Ret(); 915a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 916a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ bind(&unknown_state); 917a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ stop("no cases left"); 918a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 919a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 920a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 921a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) { 922a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::EAGER); 923a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 924a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 925a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 926aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.orgvoid Builtins::Generate_NotifySoftDeoptimized(MacroAssembler* masm) { 927aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::SOFT); 928aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org} 929aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org 930aefd6076246d134fe4e1bf0641f0a4d4e35a09c2danno@chromium.org 931a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid Builtins::Generate_NotifyLazyDeoptimized(MacroAssembler* masm) { 932a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::LAZY); 933a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 934a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 935a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 936a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { 937e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org // Lookup the function in the JavaScript frame. 938496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 939c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com { 940c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FrameScope scope(masm, StackFrame::INTERNAL); 941e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org // Lookup and calculate pc offset. 942e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org __ ldr(r1, MemOperand(fp, StandardFrameConstants::kCallerPCOffset)); 943e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org __ ldr(r2, FieldMemOperand(r0, JSFunction::kSharedFunctionInfoOffset)); 944e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org __ ldr(r2, FieldMemOperand(r2, SharedFunctionInfo::kCodeOffset)); 945e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org __ sub(r1, r1, Operand(Code::kHeaderSize - kHeapObjectTag)); 946e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org __ sub(r1, r1, r2); 947e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org __ SmiTag(r1); 948e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org 949e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org // Pass both function and pc offset as arguments. 950c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ push(r0); 951e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org __ push(r1); 952e97852de34e44a479f092bd2449134e707cd9cf1dslomov@chromium.org __ CallRuntime(Runtime::kCompileForOnStackReplacement, 2); 953c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 954496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 955c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // If the code object is null, just return to the unoptimized code. 956496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org Label skip; 957c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org __ cmp(r0, Operand(Smi::FromInt(0))); 958496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org __ b(ne, &skip); 959496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org __ Ret(); 960496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org 961496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org __ bind(&skip); 962c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 963c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // Load deoptimization data from the code object. 964c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // <deopt_data> = <code>[#deoptimization_data_offset] 965c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org __ ldr(r1, MemOperand(r0, Code::kDeoptimizationDataOffset - kHeapObjectTag)); 966c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 967c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // Load the OSR entrypoint offset from the deoptimization data. 968c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // <osr_offset> = <deopt_data>[#header_size + #osr_pc_offset] 969c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org __ ldr(r1, MemOperand(r1, FixedArray::OffsetOfElementAt( 970c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org DeoptimizationInputData::kOsrPcOffsetIndex) - kHeapObjectTag)); 971c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 972c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // Compute the target address = code_obj + header_size + osr_offset 973c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // <entry_addr> = <code_obj> + #header_size + <osr_offset> 974c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org __ add(r0, r0, Operand::SmiUntag(r1)); 975c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org __ add(lr, r0, Operand(Code::kHeaderSize - kHeapObjectTag)); 976c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org 977c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org // And "return" to the OSR entry point of the function. 978c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org __ Ret(); 979a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 980a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 981a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 9828e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.orgvoid Builtins::Generate_OsrAfterStackCheck(MacroAssembler* masm) { 9838e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org // We check the stack limit as indicator that recompilation might be done. 9848e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org Label ok; 9858e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org __ LoadRoot(ip, Heap::kStackLimitRootIndex); 9868e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org __ cmp(sp, Operand(ip)); 9878e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org __ b(hs, &ok); 9888e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org { 9898e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org FrameScope scope(masm, StackFrame::INTERNAL); 9908e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org __ CallRuntime(Runtime::kStackGuard, 0); 9918e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org } 9928e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org __ Jump(masm->isolate()->builtins()->OnStackReplacement(), 9938e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org RelocInfo::CODE_TARGET); 9948e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org 9958e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org __ bind(&ok); 9968e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org __ Ret(); 9978e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org} 9988e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org 9998e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org 1000b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.orgvoid Builtins::Generate_FunctionCall(MacroAssembler* masm) { 1001b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // 1. Make sure we have at least one argument. 10025c838251403b0be9a882540f1922577abba4c872ager@chromium.org // r0: actual number of arguments 1003b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org { Label done; 100459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ cmp(r0, Operand::Zero()); 1005b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ b(ne, &done); 1006ab99eea3d9d0cc20698ebb39bf0fb80e3e66bffcager@chromium.org __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); 1007b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ push(r2); 1008b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ add(r0, r0, Operand(1)); 1009b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ bind(&done); 1010b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org } 1011b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 10125c838251403b0be9a882540f1922577abba4c872ager@chromium.org // 2. Get the function to call (passed as receiver) from the stack, check 10135c838251403b0be9a882540f1922577abba4c872ager@chromium.org // if it is a function. 10145c838251403b0be9a882540f1922577abba4c872ager@chromium.org // r0: actual number of arguments 101534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org Label slow, non_function; 10165c838251403b0be9a882540f1922577abba4c872ager@chromium.org __ ldr(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2)); 10177b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org __ JumpIfSmi(r1, &non_function); 10185c838251403b0be9a882540f1922577abba4c872ager@chromium.org __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE); 101934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org __ b(ne, &slow); 1020b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 10215c838251403b0be9a882540f1922577abba4c872ager@chromium.org // 3a. Patch the first argument if necessary when calling a function. 1022b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // r0: actual number of arguments 1023b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // r1: function 10245c838251403b0be9a882540f1922577abba4c872ager@chromium.org Label shift_arguments; 102559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ mov(r4, Operand::Zero()); // indicate regular JS_FUNCTION 10265c838251403b0be9a882540f1922577abba4c872ager@chromium.org { Label convert_to_object, use_global_receiver, patch_receiver; 10275c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Change context eagerly in case we need the global receiver. 10285c838251403b0be9a882540f1922577abba4c872ager@chromium.org __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); 10295c838251403b0be9a882540f1922577abba4c872ager@chromium.org 103049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // Do not transform the receiver for strict mode functions. 103149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org __ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); 10321c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org __ ldr(r3, FieldMemOperand(r2, SharedFunctionInfo::kCompilerHintsOffset)); 10331c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org __ tst(r3, Operand(1 << (SharedFunctionInfo::kStrictModeFunction + 103449edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org kSmiTagSize))); 103549edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org __ b(ne, &shift_arguments); 103649edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org 10376fe7a8e00388b38f66fc0127f3fe797d54b25492ricow@chromium.org // Do not transform the receiver for native (Compilerhints already in r3). 1038d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org __ tst(r3, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize))); 10396fe7a8e00388b38f66fc0127f3fe797d54b25492ricow@chromium.org __ b(ne, &shift_arguments); 10401c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org 104149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org // Compute the receiver in non-strict mode. 1042b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ add(r2, sp, Operand(r0, LSL, kPointerSizeLog2)); 1043b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ ldr(r2, MemOperand(r2, -kPointerSize)); 1044b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // r0: actual number of arguments 1045b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // r1: function 1046b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // r2: first argument 10477b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org __ JumpIfSmi(r2, &convert_to_object); 1048b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 10496fe7a8e00388b38f66fc0127f3fe797d54b25492ricow@chromium.org __ LoadRoot(r3, Heap::kUndefinedValueRootIndex); 1050b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ cmp(r2, r3); 1051b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ b(eq, &use_global_receiver); 10521c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org __ LoadRoot(r3, Heap::kNullValueRootIndex); 1053b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ cmp(r2, r3); 1054b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ b(eq, &use_global_receiver); 1055b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 1056d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE); 1057d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org __ CompareObjectType(r2, r3, r3, FIRST_SPEC_OBJECT_TYPE); 105840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org __ b(ge, &shift_arguments); 1059b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 10605c838251403b0be9a882540f1922577abba4c872ager@chromium.org __ bind(&convert_to_object); 1061b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 1062c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com { 1063c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Enter an internal frame in order to preserve argument count. 1064c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FrameScope scope(masm, StackFrame::INTERNAL); 1065bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org __ SmiTag(r0); 1066c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ push(r0); 1067c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1068c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ push(r2); 1069c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); 1070c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ mov(r2, r0); 1071c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1072c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ pop(r0); 1073bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org __ SmiUntag(r0); 1074c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1075c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Exit the internal frame. 1076c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 1077b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 107834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // Restore the function to r1, and the flag to r4. 10795c838251403b0be9a882540f1922577abba4c872ager@chromium.org __ ldr(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2)); 108059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ mov(r4, Operand::Zero()); 10815c838251403b0be9a882540f1922577abba4c872ager@chromium.org __ jmp(&patch_receiver); 1082b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 10835c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Use the global receiver object from the called function as the 10845c838251403b0be9a882540f1922577abba4c872ager@chromium.org // receiver. 1085b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ bind(&use_global_receiver); 1086b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org const int kGlobalIndex = 108746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org Context::kHeaderSize + Context::GLOBAL_OBJECT_INDEX * kPointerSize; 1088b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ ldr(r2, FieldMemOperand(cp, kGlobalIndex)); 108946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ ldr(r2, FieldMemOperand(r2, GlobalObject::kNativeContextOffset)); 10903811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org __ ldr(r2, FieldMemOperand(r2, kGlobalIndex)); 10915a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org __ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalReceiverOffset)); 1092b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 1093b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ bind(&patch_receiver); 1094b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ add(r3, sp, Operand(r0, LSL, kPointerSizeLog2)); 1095b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ str(r2, MemOperand(r3, -kPointerSize)); 1096b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 10975c838251403b0be9a882540f1922577abba4c872ager@chromium.org __ jmp(&shift_arguments); 1098b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org } 1099b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 110034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // 3b. Check for function proxy. 110134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org __ bind(&slow); 110259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ mov(r4, Operand(1, RelocInfo::NONE32)); // indicate function proxy 110334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org __ cmp(r2, Operand(JS_FUNCTION_PROXY_TYPE)); 110434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org __ b(eq, &shift_arguments); 110534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org __ bind(&non_function); 110659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ mov(r4, Operand(2, RelocInfo::NONE32)); // indicate non-function 110734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 110834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // 3c. Patch the first argument when calling a non-function. The 11095c838251403b0be9a882540f1922577abba4c872ager@chromium.org // CALL_NON_FUNCTION builtin expects the non-function callee as 11105c838251403b0be9a882540f1922577abba4c872ager@chromium.org // receiver, so overwrite the first argument which will ultimately 11115c838251403b0be9a882540f1922577abba4c872ager@chromium.org // become the receiver. 11125c838251403b0be9a882540f1922577abba4c872ager@chromium.org // r0: actual number of arguments 11135c838251403b0be9a882540f1922577abba4c872ager@chromium.org // r1: function 111434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // r4: call type (0: JS function, 1: function proxy, 2: non-function) 11155c838251403b0be9a882540f1922577abba4c872ager@chromium.org __ add(r2, sp, Operand(r0, LSL, kPointerSizeLog2)); 11165c838251403b0be9a882540f1922577abba4c872ager@chromium.org __ str(r1, MemOperand(r2, -kPointerSize)); 11175c838251403b0be9a882540f1922577abba4c872ager@chromium.org 11185c838251403b0be9a882540f1922577abba4c872ager@chromium.org // 4. Shift arguments and return address one slot down on the stack 11195c838251403b0be9a882540f1922577abba4c872ager@chromium.org // (overwriting the original receiver). Adjust argument count to make 11205c838251403b0be9a882540f1922577abba4c872ager@chromium.org // the original first argument the new receiver. 11215c838251403b0be9a882540f1922577abba4c872ager@chromium.org // r0: actual number of arguments 1122b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // r1: function 112334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // r4: call type (0: JS function, 1: function proxy, 2: non-function) 11245c838251403b0be9a882540f1922577abba4c872ager@chromium.org __ bind(&shift_arguments); 1125b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org { Label loop; 1126b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // Calculate the copy start address (destination). Copy end address is sp. 1127b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ add(r2, sp, Operand(r0, LSL, kPointerSizeLog2)); 1128b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 1129b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ bind(&loop); 1130b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ ldr(ip, MemOperand(r2, -kPointerSize)); 1131b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ str(ip, MemOperand(r2)); 1132b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ sub(r2, r2, Operand(kPointerSize)); 1133b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ cmp(r2, sp); 1134b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ b(ne, &loop); 11355c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Adjust the actual number of arguments and remove the top element 11365c838251403b0be9a882540f1922577abba4c872ager@chromium.org // (which is a copy of the last argument). 11375c838251403b0be9a882540f1922577abba4c872ager@chromium.org __ sub(r0, r0, Operand(1)); 11385c838251403b0be9a882540f1922577abba4c872ager@chromium.org __ pop(); 1139b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org } 1140b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 114134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin, 114234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // or a function proxy via CALL_FUNCTION_PROXY. 1143b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // r0: actual number of arguments 1144b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // r1: function 114534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org // r4: call type (0: JS function, 1: function proxy, 2: non-function) 114634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org { Label function, non_proxy; 114734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org __ tst(r4, r4); 114834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org __ b(eq, &function); 11495b2fbee8f0b54371d42843c8fd90249a24093678ager@chromium.org // Expected number of arguments is 0 for CALL_NON_FUNCTION. 115059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ mov(r2, Operand::Zero()); 115140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org __ SetCallKind(r5, CALL_AS_METHOD); 115234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org __ cmp(r4, Operand(1)); 115334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org __ b(ne, &non_proxy); 115434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 115534e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org __ push(r1); // re-add proxy object as additional argument 115634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org __ add(r0, r0, Operand(1)); 115734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org __ GetBuiltinEntry(r3, Builtins::CALL_FUNCTION_PROXY); 115834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), 115934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org RelocInfo::CODE_TARGET); 116034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 116134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org __ bind(&non_proxy); 116234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); 11637979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), 11647979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org RelocInfo::CODE_TARGET); 11655c838251403b0be9a882540f1922577abba4c872ager@chromium.org __ bind(&function); 11665c838251403b0be9a882540f1922577abba4c872ager@chromium.org } 1167b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 11685c838251403b0be9a882540f1922577abba4c872ager@chromium.org // 5b. Get the code to call from the function and check that the number of 11695c838251403b0be9a882540f1922577abba4c872ager@chromium.org // expected arguments matches what we're providing. If so, jump 11705c838251403b0be9a882540f1922577abba4c872ager@chromium.org // (tail-call) to the code in register edx without checking arguments. 11715c838251403b0be9a882540f1922577abba4c872ager@chromium.org // r0: actual number of arguments 11725c838251403b0be9a882540f1922577abba4c872ager@chromium.org // r1: function 11735c838251403b0be9a882540f1922577abba4c872ager@chromium.org __ ldr(r3, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); 11745c838251403b0be9a882540f1922577abba4c872ager@chromium.org __ ldr(r2, 11755c838251403b0be9a882540f1922577abba4c872ager@chromium.org FieldMemOperand(r3, SharedFunctionInfo::kFormalParameterCountOffset)); 1176bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org __ SmiUntag(r2); 1177145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com __ ldr(r3, FieldMemOperand(r1, JSFunction::kCodeEntryOffset)); 117840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org __ SetCallKind(r5, CALL_AS_METHOD); 11795c838251403b0be9a882540f1922577abba4c872ager@chromium.org __ cmp(r2, r0); // Check formal and actual parameter counts. 11807979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), 11817979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org RelocInfo::CODE_TARGET, 11827979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org ne); 1183b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 11845c838251403b0be9a882540f1922577abba4c872ager@chromium.org ParameterCount expected(0); 1185d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org __ InvokeCode(r3, expected, expected, JUMP_FUNCTION, 1186d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org NullCallWrapper(), CALL_AS_METHOD); 1187b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org} 1188b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 1189b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 119043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Builtins::Generate_FunctionApply(MacroAssembler* masm) { 11917ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org const int kIndexOffset = 11927ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); 11937ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org const int kLimitOffset = 11947ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); 11957ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org const int kArgsOffset = 2 * kPointerSize; 11967ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org const int kRecvOffset = 3 * kPointerSize; 11977ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org const int kFunctionOffset = 4 * kPointerSize; 1198b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 1199c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com { 1200c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FrameScope frame_scope(masm, StackFrame::INTERNAL); 1201b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 1202c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ ldr(r0, MemOperand(fp, kFunctionOffset)); // get the function 1203c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ push(r0); 1204c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ ldr(r0, MemOperand(fp, kArgsOffset)); // get the args array 1205c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ push(r0); 1206c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); 1207c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1208c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check the stack for overflow. We are not trying to catch 1209c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // interruptions (e.g. debug break and preemption) here, so the "real stack 1210c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // limit" is checked. 1211c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label okay; 1212c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ LoadRoot(r2, Heap::kRealStackLimitRootIndex); 1213c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Make r2 the space we have left. The stack might already be overflowed 1214c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // here which will cause r2 to become negative. 1215c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ sub(r2, sp, r2); 1216c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check if the arguments will overflow the stack. 1217bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org __ cmp(r2, Operand::PointerOffsetFromSmiKey(r0)); 1218c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ b(gt, &okay); // Signed comparison. 1219c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1220c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Out of stack space. 1221c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ ldr(r1, MemOperand(fp, kFunctionOffset)); 1222057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org __ Push(r1, r0); 1223c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ InvokeBuiltin(Builtins::APPLY_OVERFLOW, CALL_FUNCTION); 1224c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // End of stack check. 1225b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 1226c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Push current limit and index. 1227c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ bind(&okay); 1228c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ push(r0); // limit 122959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ mov(r1, Operand::Zero()); // initial index 1230c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ push(r1); 1231b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 1232c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Get the receiver. 1233c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ ldr(r0, MemOperand(fp, kRecvOffset)); 123434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 1235c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check that the function is a JS function (otherwise it must be a proxy). 1236c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label push_receiver; 1237c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ ldr(r1, MemOperand(fp, kFunctionOffset)); 1238c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE); 1239c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ b(ne, &push_receiver); 124034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 1241c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Change context eagerly to get the right global object if necessary. 1242c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); 1243c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Load the shared function info while the function is still in r1. 1244c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); 1245b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 1246c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Compute the receiver. 1247c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Do not transform the receiver for strict mode functions. 1248c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label call_to_object, use_global_receiver; 1249c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ ldr(r2, FieldMemOperand(r2, SharedFunctionInfo::kCompilerHintsOffset)); 1250c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ tst(r2, Operand(1 << (SharedFunctionInfo::kStrictModeFunction + 1251c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com kSmiTagSize))); 1252c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ b(ne, &push_receiver); 1253b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 1254c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Do not transform the receiver for strict mode functions. 1255c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ tst(r2, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize))); 1256c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ b(ne, &push_receiver); 1257b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 1258c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Compute the receiver in non-strict mode. 1259c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ JumpIfSmi(r0, &call_to_object); 1260c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ LoadRoot(r1, Heap::kNullValueRootIndex); 1261c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ cmp(r0, r1); 1262c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ b(eq, &use_global_receiver); 1263c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ LoadRoot(r1, Heap::kUndefinedValueRootIndex); 1264c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ cmp(r0, r1); 1265c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ b(eq, &use_global_receiver); 1266b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 1267c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check if the receiver is already a JavaScript object. 1268c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r0: receiver 1269c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE); 1270c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ CompareObjectType(r0, r1, r1, FIRST_SPEC_OBJECT_TYPE); 1271c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ b(ge, &push_receiver); 1272b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 1273c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Convert the receiver to a regular object. 1274c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r0: receiver 1275c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ bind(&call_to_object); 1276c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ push(r0); 1277c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); 1278c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ b(&push_receiver); 1279b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 1280c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Use the current global receiver object as the receiver. 1281c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ bind(&use_global_receiver); 1282c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com const int kGlobalOffset = 128346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org Context::kHeaderSize + Context::GLOBAL_OBJECT_INDEX * kPointerSize; 1284c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ ldr(r0, FieldMemOperand(cp, kGlobalOffset)); 128546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ ldr(r0, FieldMemOperand(r0, GlobalObject::kNativeContextOffset)); 1286c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ ldr(r0, FieldMemOperand(r0, kGlobalOffset)); 1287c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ ldr(r0, FieldMemOperand(r0, GlobalObject::kGlobalReceiverOffset)); 1288c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1289c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Push the receiver. 1290c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r0: receiver 1291c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ bind(&push_receiver); 1292c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ push(r0); 1293b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 1294c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Copy all arguments from the array to the stack. 1295c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label entry, loop; 1296c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ ldr(r0, MemOperand(fp, kIndexOffset)); 1297c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ b(&entry); 129834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 1299c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Load the current argument from the arguments array and push it to the 1300c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // stack. 1301c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // r0: current argument index 1302c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ bind(&loop); 1303c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ ldr(r1, MemOperand(fp, kArgsOffset)); 1304057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org __ Push(r1, r0); 1305c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1306c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Call the runtime to access the property in the arguments array. 1307c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ CallRuntime(Runtime::kGetProperty, 2); 1308c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ push(r0); 1309c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1310c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Use inline caching to access the arguments. 1311c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ ldr(r0, MemOperand(fp, kIndexOffset)); 1312c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ add(r0, r0, Operand(1 << kSmiTagSize)); 1313c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ str(r0, MemOperand(fp, kIndexOffset)); 131434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 1315c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Test if the copy loop has finished copying all the elements from the 1316c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // arguments object. 1317c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ bind(&entry); 1318c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ ldr(r1, MemOperand(fp, kLimitOffset)); 1319c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ cmp(r0, r1); 1320c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ b(ne, &loop); 1321c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1322c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Invoke the function. 1323c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label call_proxy; 1324c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ParameterCount actual(r0); 1325bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org __ SmiUntag(r0); 1326c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ ldr(r1, MemOperand(fp, kFunctionOffset)); 1327c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE); 1328c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ b(ne, &call_proxy); 1329c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ InvokeFunction(r1, actual, CALL_FUNCTION, 1330c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com NullCallWrapper(), CALL_AS_METHOD); 1331c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1332c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com frame_scope.GenerateLeaveFrame(); 1333c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ add(sp, sp, Operand(3 * kPointerSize)); 1334c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Jump(lr); 1335c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1336c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Invoke the function proxy. 1337c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ bind(&call_proxy); 1338c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ push(r1); // add function proxy as last argument 1339c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ add(r0, r0, Operand(1)); 134059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org __ mov(r2, Operand::Zero()); 1341c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ SetCallKind(r5, CALL_AS_METHOD); 1342c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ GetBuiltinEntry(r3, Builtins::CALL_FUNCTION_PROXY); 1343c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), 1344c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com RelocInfo::CODE_TARGET); 1345c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1346c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Tear down the internal frame and remove function, receiver and args. 1347c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 134834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org __ add(sp, sp, Operand(3 * kPointerSize)); 13499085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org __ Jump(lr); 1350b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org} 1351b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 1352b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 1353b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.orgstatic void EnterArgumentsAdaptorFrame(MacroAssembler* masm) { 1354bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org __ SmiTag(r0); 135518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org __ mov(r4, Operand(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 1356b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ stm(db_w, sp, r0.bit() | r1.bit() | r4.bit() | fp.bit() | lr.bit()); 13577ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org __ add(fp, sp, 13587ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org Operand(StandardFrameConstants::kFixedFrameSizeFromFp + kPointerSize)); 1359b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org} 1360b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 1361b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 13627c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.orgstatic void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) { 1363b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // ----------- S t a t e ------------- 1364b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // -- r0 : result being passed through 1365b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // ----------------------------------- 1366b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // Get the number of arguments passed (as a smi), tear down the frame and 1367b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // then tear down the parameters. 13687ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org __ ldr(r1, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp + 13697ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org kPointerSize))); 1370b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ mov(sp, fp); 1371b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ ldm(ia_w, sp, fp.bit() | lr.bit()); 1372bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org __ add(sp, sp, Operand::PointerOffsetFromSmiKey(r1)); 1373b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ add(sp, sp, Operand(kPointerSize)); // adjust for receiver 137443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 137543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 137643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 137743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { 1378b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // ----------- S t a t e ------------- 1379b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // -- r0 : actual number of arguments 1380b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // -- r1 : function (passed through to callee) 1381b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // -- r2 : expected number of arguments 1382b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // -- r3 : code entry to call 138340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org // -- r5 : call kind information 1384b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // ----------------------------------- 1385b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 1386b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org Label invoke, dont_adapt_arguments; 1387b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 1388b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org Label enough, too_few; 1389013f3e12d3af426bf5545b5f457aa08ee98bdca2fschneider@chromium.org __ cmp(r0, r2); 1390b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ b(lt, &too_few); 1391b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ cmp(r2, Operand(SharedFunctionInfo::kDontAdaptArgumentsSentinel)); 1392b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ b(eq, &dont_adapt_arguments); 1393b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 13943291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org { // Enough parameters: actual >= expected 1395b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ bind(&enough); 1396b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org EnterArgumentsAdaptorFrame(masm); 1397b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 1398b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // Calculate copy start address into r0 and copy end address into r2. 1399b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // r0: actual number of arguments as a smi 1400b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // r1: function 1401b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // r2: expected number of arguments 1402b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // r3: code entry to call 1403bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org __ add(r0, fp, Operand::PointerOffsetFromSmiKey(r0)); 1404b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // adjust for return address and receiver 1405b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ add(r0, r0, Operand(2 * kPointerSize)); 1406b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ sub(r2, r0, Operand(r2, LSL, kPointerSizeLog2)); 1407b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 1408b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // Copy the arguments (including the receiver) to the new stack frame. 1409b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // r0: copy start address 1410b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // r1: function 1411b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // r2: copy end address 1412b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // r3: code entry to call 1413b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 1414b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org Label copy; 1415b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ bind(©); 1416b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ ldr(ip, MemOperand(r0, 0)); 1417b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ push(ip); 1418b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ cmp(r0, r2); // Compare before moving to next argument. 1419b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ sub(r0, r0, Operand(kPointerSize)); 1420b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ b(ne, ©); 1421b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 1422b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ b(&invoke); 1423b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org } 1424b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 1425b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org { // Too few parameters: Actual < expected 1426b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ bind(&too_few); 1427b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org EnterArgumentsAdaptorFrame(masm); 1428b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 1429b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // Calculate copy start address into r0 and copy end address is fp. 1430b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // r0: actual number of arguments as a smi 1431b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // r1: function 1432b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // r2: expected number of arguments 1433b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // r3: code entry to call 1434bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org __ add(r0, fp, Operand::PointerOffsetFromSmiKey(r0)); 1435b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 1436b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // Copy the arguments (including the receiver) to the new stack frame. 1437b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // r0: copy start address 1438b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // r1: function 1439b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // r2: expected number of arguments 1440b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // r3: code entry to call 1441b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org Label copy; 1442b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ bind(©); 1443b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // Adjust load for return address and receiver. 1444b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ ldr(ip, MemOperand(r0, 2 * kPointerSize)); 1445b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ push(ip); 1446b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ cmp(r0, fp); // Compare before moving to next argument. 1447b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ sub(r0, r0, Operand(kPointerSize)); 1448b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ b(ne, ©); 1449b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 1450b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // Fill the remaining expected arguments with undefined. 1451b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // r1: function 1452b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // r2: expected number of arguments 1453b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // r3: code entry to call 1454ab99eea3d9d0cc20698ebb39bf0fb80e3e66bffcager@chromium.org __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 1455b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ sub(r2, fp, Operand(r2, LSL, kPointerSizeLog2)); 14567ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org // Adjust for frame. 14577ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org __ sub(r2, r2, Operand(StandardFrameConstants::kFixedFrameSizeFromFp + 14587ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org 2 * kPointerSize)); 1459b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 1460b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org Label fill; 1461b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ bind(&fill); 1462b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ push(ip); 1463b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ cmp(sp, r2); 1464b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ b(ne, &fill); 1465b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org } 146643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1467b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // Call the entry point. 1468b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ bind(&invoke); 1469b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ Call(r3); 147043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1471967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org // Store offset of return address for deoptimizer. 1472659ceec4628056d3c6e7076c850fba1c412cbb8ayangguo@chromium.org masm->isolate()->heap()->SetArgumentsAdaptorDeoptPCOffset(masm->pc_offset()); 1473967e270a034432457500dbf950d2c4951a929e52ulan@chromium.org 14747c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org // Exit frame and return. 14757c537e2abe09729ed6cb827b4dd206470d8c4a42ager@chromium.org LeaveArgumentsAdaptorFrame(masm); 14769085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org __ Jump(lr); 1477b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 1478b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 1479b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // ------------------------------------------- 1480b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // Dont adapt arguments. 1481b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // ------------------------------------------- 1482b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org __ bind(&dont_adapt_arguments); 14839085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org __ Jump(r3); 148443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 148543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 148643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 148743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#undef __ 148843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 148943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} } // namespace v8::internal 14909dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 14919dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com#endif // V8_TARGET_ARCH_ARM 1492