1fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 25c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Redistribution and use in source and binary forms, with or without 35c838251403b0be9a882540f1922577abba4c872ager@chromium.org// modification, are permitted provided that the following conditions are 45c838251403b0be9a882540f1922577abba4c872ager@chromium.org// met: 55c838251403b0be9a882540f1922577abba4c872ager@chromium.org// 65c838251403b0be9a882540f1922577abba4c872ager@chromium.org// * Redistributions of source code must retain the above copyright 75c838251403b0be9a882540f1922577abba4c872ager@chromium.org// notice, this list of conditions and the following disclaimer. 85c838251403b0be9a882540f1922577abba4c872ager@chromium.org// * Redistributions in binary form must reproduce the above 95c838251403b0be9a882540f1922577abba4c872ager@chromium.org// copyright notice, this list of conditions and the following 105c838251403b0be9a882540f1922577abba4c872ager@chromium.org// disclaimer in the documentation and/or other materials provided 115c838251403b0be9a882540f1922577abba4c872ager@chromium.org// with the distribution. 125c838251403b0be9a882540f1922577abba4c872ager@chromium.org// * Neither the name of Google Inc. nor the names of its 135c838251403b0be9a882540f1922577abba4c872ager@chromium.org// contributors may be used to endorse or promote products derived 145c838251403b0be9a882540f1922577abba4c872ager@chromium.org// from this software without specific prior written permission. 155c838251403b0be9a882540f1922577abba4c872ager@chromium.org// 165c838251403b0be9a882540f1922577abba4c872ager@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 175c838251403b0be9a882540f1922577abba4c872ager@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 185c838251403b0be9a882540f1922577abba4c872ager@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 195c838251403b0be9a882540f1922577abba4c872ager@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 205c838251403b0be9a882540f1922577abba4c872ager@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 215c838251403b0be9a882540f1922577abba4c872ager@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 225c838251403b0be9a882540f1922577abba4c872ager@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 235c838251403b0be9a882540f1922577abba4c872ager@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 245c838251403b0be9a882540f1922577abba4c872ager@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 255c838251403b0be9a882540f1922577abba4c872ager@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 265c838251403b0be9a882540f1922577abba4c872ager@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 275c838251403b0be9a882540f1922577abba4c872ager@chromium.org 285c838251403b0be9a882540f1922577abba4c872ager@chromium.org#include "v8.h" 295c838251403b0be9a882540f1922577abba4c872ager@chromium.org 3093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_MIPS 319dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 3283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org#include "codegen.h" 33394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com#include "macro-assembler.h" 3483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org#include "simulator-mips.h" 355c838251403b0be9a882540f1922577abba4c872ager@chromium.org 365c838251403b0be9a882540f1922577abba4c872ager@chromium.orgnamespace v8 { 375c838251403b0be9a882540f1922577abba4c872ager@chromium.orgnamespace internal { 385c838251403b0be9a882540f1922577abba4c872ager@chromium.org 39394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 40154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.orgUnaryMathFunction CreateTranscendentalFunction(TranscendentalCache::Type type) { 419a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org switch (type) { 429a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org case TranscendentalCache::SIN: return &sin; 439a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org case TranscendentalCache::COS: return &cos; 449a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org case TranscendentalCache::TAN: return &tan; 459a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org case TranscendentalCache::LOG: return &log; 469a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org default: UNIMPLEMENTED(); 479a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org } 489a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org return NULL; 499a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org} 509a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org 519a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org 5283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org#define __ masm. 5383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org 5483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org 5583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org#if defined(USE_SIMULATOR) 5683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.orgbyte* fast_exp_mips_machine_code = NULL; 5783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.orgdouble fast_exp_simulator(double x) { 5883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org return Simulator::current(Isolate::Current())->CallFP( 5983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org fast_exp_mips_machine_code, x, 0); 6083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org} 6183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org#endif 6283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org 6383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org 6483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.orgUnaryMathFunction CreateExpFunction() { 6583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org if (!FLAG_fast_math) return &exp; 6683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org size_t actual_size; 6783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org byte* buffer = static_cast<byte*>(OS::Allocate(1 * KB, &actual_size, true)); 6883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org if (buffer == NULL) return &exp; 6983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org ExternalReference::InitializeMathExpData(); 7083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org 7183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org MacroAssembler masm(NULL, buffer, static_cast<int>(actual_size)); 7283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org 7383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org { 7483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org DoubleRegister input = f12; 7583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org DoubleRegister result = f0; 7683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org DoubleRegister double_scratch1 = f4; 7783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org DoubleRegister double_scratch2 = f6; 7883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org Register temp1 = t0; 7983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org Register temp2 = t1; 8083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org Register temp3 = t2; 8183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org 8283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org if (!IsMipsSoftFloatABI) { 8383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org // Input value is in f12 anyway, nothing to do. 8483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org } else { 8583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ Move(input, a0, a1); 8683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org } 8783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ Push(temp3, temp2, temp1); 8883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org MathExpGenerator::EmitMathExp( 8983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org &masm, input, result, double_scratch1, double_scratch2, 9083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org temp1, temp2, temp3); 9183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ Pop(temp3, temp2, temp1); 9283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org if (!IsMipsSoftFloatABI) { 9383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org // Result is already in f0, nothing to do. 9483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org } else { 95e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ Move(v0, v1, result); 9683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org } 9783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ Ret(); 9883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org } 9983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org 10083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org CodeDesc desc; 10183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org masm.GetCode(&desc); 1022e04b58f1dc7cee8fdf047b5dbc9dc93e767821dulan@chromium.org ASSERT(!RelocInfo::RequiresRelocation(desc)); 10383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org 10483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org CPU::FlushICache(buffer, actual_size); 10583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org OS::ProtectCode(buffer, actual_size); 10683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org 10783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org#if !defined(USE_SIMULATOR) 10883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org return FUNCTION_CAST<UnaryMathFunction>(buffer); 10983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org#else 11083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org fast_exp_mips_machine_code = buffer; 11183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org return &fast_exp_simulator; 11283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org#endif 11383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org} 11483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org 11583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org 11683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org#undef __ 11783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org 11883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org 119154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.orgUnaryMathFunction CreateSqrtFunction() { 120154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org return &sqrt; 121154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org} 122154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org 123e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 1247516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// ------------------------------------------------------------------------- 1257516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// Platform-specific RuntimeCallHelper functions. 1267516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 1277516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid StubRuntimeCallHelper::BeforeCall(MacroAssembler* masm) const { 128c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com masm->EnterFrame(StackFrame::INTERNAL); 129c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(!masm->has_frame()); 130c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com masm->set_has_frame(true); 1317516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 1327516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 1337516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 1347516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid StubRuntimeCallHelper::AfterCall(MacroAssembler* masm) const { 135c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com masm->LeaveFrame(StackFrame::INTERNAL); 136c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com ASSERT(masm->has_frame()); 137c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com masm->set_has_frame(false); 1385c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 1395c838251403b0be9a882540f1922577abba4c872ager@chromium.org 140e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 141394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com// ------------------------------------------------------------------------- 142394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com// Code generators 143394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 14483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org#define __ ACCESS_MASM(masm) 14583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org 146830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.orgvoid ElementsTransitionGenerator::GenerateMapChangeElementsTransition( 14728381b491d5ea9f256a3937000de7953639ef93fyangguo@chromium.org MacroAssembler* masm, AllocationSiteMode mode, 148ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Label* allocation_memento_found) { 149394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // ----------- S t a t e ------------- 150394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // -- a0 : value 151394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // -- a1 : key 152394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // -- a2 : receiver 153394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // -- ra : return address 154394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // -- a3 : target map, scratch for subsequent call 155394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // -- t0 : scratch (elements) 156394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // ----------------------------------- 15728381b491d5ea9f256a3937000de7953639ef93fyangguo@chromium.org if (mode == TRACK_ALLOCATION_SITE) { 158ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org ASSERT(allocation_memento_found != NULL); 159ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org masm->TestJSArrayForAllocationMemento(a2, t0, eq, 160ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org allocation_memento_found); 16128381b491d5ea9f256a3937000de7953639ef93fyangguo@chromium.org } 16228381b491d5ea9f256a3937000de7953639ef93fyangguo@chromium.org 163394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Set transitioned map. 164394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ sw(a3, FieldMemOperand(a2, HeapObject::kMapOffset)); 165394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ RecordWriteField(a2, 166394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com HeapObject::kMapOffset, 167394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com a3, 168394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com t5, 169394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com kRAHasNotBeenSaved, 170394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com kDontSaveFPRegs, 171394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com EMIT_REMEMBERED_SET, 172394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com OMIT_SMI_CHECK); 173394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com} 174394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 175394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 176830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.orgvoid ElementsTransitionGenerator::GenerateSmiToDouble( 17728381b491d5ea9f256a3937000de7953639ef93fyangguo@chromium.org MacroAssembler* masm, AllocationSiteMode mode, Label* fail) { 178394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // ----------- S t a t e ------------- 179394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // -- a0 : value 180394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // -- a1 : key 181394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // -- a2 : receiver 182394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // -- ra : return address 183394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // -- a3 : target map, scratch for subsequent call 184394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // -- t0 : scratch (elements) 185394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // ----------------------------------- 18656454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org Label loop, entry, convert_hole, gc_required, only_change_map, done; 187394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 188394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Register scratch = t6; 189394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 19028381b491d5ea9f256a3937000de7953639ef93fyangguo@chromium.org if (mode == TRACK_ALLOCATION_SITE) { 191ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org masm->TestJSArrayForAllocationMemento(a2, t0, eq, fail); 19259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org } 19359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 19456454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org // Check for empty arrays, which only require a map transition and no changes 19556454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org // to the backing store. 196394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ lw(t0, FieldMemOperand(a2, JSObject::kElementsOffset)); 19756454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org __ LoadRoot(at, Heap::kEmptyFixedArrayRootIndex); 19856454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org __ Branch(&only_change_map, eq, at, Operand(t0)); 19956454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org 20056454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org __ push(ra); 201394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ lw(t1, FieldMemOperand(t0, FixedArray::kLengthOffset)); 202394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // t0: source FixedArray 203394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // t1: number of elements (smi-tagged) 204394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 205394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Allocate new FixedDoubleArray. 206394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ sll(scratch, t1, 2); 207394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Addu(scratch, scratch, FixedDoubleArray::kHeaderSize); 208594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Allocate(scratch, t2, t3, t5, &gc_required, DOUBLE_ALIGNMENT); 209394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // t2: destination FixedDoubleArray, not tagged as heap object 210f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org 211fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // Set destination FixedDoubleArray's length and map. 212394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ LoadRoot(t5, Heap::kFixedDoubleArrayMapRootIndex); 213394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ sw(t1, MemOperand(t2, FixedDoubleArray::kLengthOffset)); 214fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org __ sw(t5, MemOperand(t2, HeapObject::kMapOffset)); 215394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Update receiver's map. 216394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 217394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ sw(a3, FieldMemOperand(a2, HeapObject::kMapOffset)); 218394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ RecordWriteField(a2, 219394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com HeapObject::kMapOffset, 220394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com a3, 221394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com t5, 222394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com kRAHasBeenSaved, 223394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com kDontSaveFPRegs, 22456454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org OMIT_REMEMBERED_SET, 225394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com OMIT_SMI_CHECK); 226394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Replace receiver's backing store with newly created FixedDoubleArray. 227394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Addu(a3, t2, Operand(kHeapObjectTag)); 228394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ sw(a3, FieldMemOperand(a2, JSObject::kElementsOffset)); 229394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ RecordWriteField(a2, 230394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com JSObject::kElementsOffset, 231394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com a3, 232394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com t5, 233394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com kRAHasBeenSaved, 234394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com kDontSaveFPRegs, 235394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com EMIT_REMEMBERED_SET, 236394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com OMIT_SMI_CHECK); 237394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 238394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 239394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Prepare for conversion loop. 240394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Addu(a3, t0, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 241394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Addu(t3, t2, Operand(FixedDoubleArray::kHeaderSize)); 242394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ sll(t2, t1, 2); 243394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Addu(t2, t2, t3); 244394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ li(t0, Operand(kHoleNanLower32)); 245394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ li(t1, Operand(kHoleNanUpper32)); 246394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // t0: kHoleNanLower32 247394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // t1: kHoleNanUpper32 248394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // t2: end of destination FixedDoubleArray, not tagged 249394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // t3: begin of FixedDoubleArray element fields, not tagged 250394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 251394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Branch(&entry); 252394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 25356454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org __ bind(&only_change_map); 25456454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org __ sw(a3, FieldMemOperand(a2, HeapObject::kMapOffset)); 25556454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org __ RecordWriteField(a2, 25656454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org HeapObject::kMapOffset, 25756454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org a3, 25856454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org t5, 259a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org kRAHasNotBeenSaved, 26056454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org kDontSaveFPRegs, 26156454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org OMIT_REMEMBERED_SET, 26256454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org OMIT_SMI_CHECK); 26356454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org __ Branch(&done); 26456454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org 265394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Call into runtime if GC is required. 266394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ bind(&gc_required); 267394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ pop(ra); 268394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Branch(fail); 269394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 270394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Convert and copy elements. 271394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ bind(&loop); 272394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ lw(t5, MemOperand(a3)); 273394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Addu(a3, a3, kIntSize); 274394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // t5: current element 275fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org __ UntagAndJumpIfNotSmi(t5, t5, &convert_hole); 276394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 277394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Normal smi, convert to double and store. 278e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ mtc1(t5, f0); 279e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ cvt_d_w(f0, f0); 280e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ sdc1(f0, MemOperand(t3)); 281e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ Addu(t3, t3, kDoubleSize); 282e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 283394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Branch(&entry); 284394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 285394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Hole found, store the-hole NaN. 286394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ bind(&convert_hole); 287c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org if (FLAG_debug_code) { 288fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // Restore a "smi-untagged" heap object. 289fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org __ SmiTag(t5); 290fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org __ Or(t5, t5, Operand(1)); 291c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 292594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Assert(eq, kObjectFoundInSmiOnlyArray, at, Operand(t5)); 293c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org } 294394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ sw(t0, MemOperand(t3)); // mantissa 295394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ sw(t1, MemOperand(t3, kIntSize)); // exponent 296394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Addu(t3, t3, kDoubleSize); 297394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 298394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ bind(&entry); 299394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Branch(&loop, lt, t3, Operand(t2)); 300394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 301394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ pop(ra); 30256454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org __ bind(&done); 303394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com} 304394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 305394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 306394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comvoid ElementsTransitionGenerator::GenerateDoubleToObject( 30728381b491d5ea9f256a3937000de7953639ef93fyangguo@chromium.org MacroAssembler* masm, AllocationSiteMode mode, Label* fail) { 308394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // ----------- S t a t e ------------- 309394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // -- a0 : value 310394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // -- a1 : key 311394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // -- a2 : receiver 312394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // -- ra : return address 313394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // -- a3 : target map, scratch for subsequent call 314394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // -- t0 : scratch (elements) 315394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // ----------------------------------- 31656454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org Label entry, loop, convert_hole, gc_required, only_change_map; 317394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 31828381b491d5ea9f256a3937000de7953639ef93fyangguo@chromium.org if (mode == TRACK_ALLOCATION_SITE) { 319ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org masm->TestJSArrayForAllocationMemento(a2, t0, eq, fail); 32028381b491d5ea9f256a3937000de7953639ef93fyangguo@chromium.org } 32128381b491d5ea9f256a3937000de7953639ef93fyangguo@chromium.org 32256454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org // Check for empty arrays, which only require a map transition and no changes 32356454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org // to the backing store. 324394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ lw(t0, FieldMemOperand(a2, JSObject::kElementsOffset)); 32556454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org __ LoadRoot(at, Heap::kEmptyFixedArrayRootIndex); 32656454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org __ Branch(&only_change_map, eq, at, Operand(t0)); 32756454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org 32856454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org __ MultiPush(a0.bit() | a1.bit() | a2.bit() | a3.bit() | ra.bit()); 32956454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org 330394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ lw(t1, FieldMemOperand(t0, FixedArray::kLengthOffset)); 331394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // t0: source FixedArray 332394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // t1: number of elements (smi-tagged) 333394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 334394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Allocate new FixedArray. 335394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ sll(a0, t1, 1); 336394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Addu(a0, a0, FixedDoubleArray::kHeaderSize); 337f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org __ Allocate(a0, t2, t3, t5, &gc_required, NO_ALLOCATION_FLAGS); 338394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // t2: destination FixedArray, not tagged as heap object 339fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org // Set destination FixedDoubleArray's length and map. 340394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ LoadRoot(t5, Heap::kFixedArrayMapRootIndex); 341394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ sw(t1, MemOperand(t2, FixedDoubleArray::kLengthOffset)); 342fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org __ sw(t5, MemOperand(t2, HeapObject::kMapOffset)); 343394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 344394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Prepare for conversion loop. 345394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Addu(t0, t0, Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag + 4)); 346394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Addu(a3, t2, Operand(FixedArray::kHeaderSize)); 347394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Addu(t2, t2, Operand(kHeapObjectTag)); 348394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ sll(t1, t1, 1); 349394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Addu(t1, a3, t1); 350394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ LoadRoot(t3, Heap::kTheHoleValueRootIndex); 351394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ LoadRoot(t5, Heap::kHeapNumberMapRootIndex); 352394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Using offsetted addresses. 353394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // a3: begin of destination FixedArray element fields, not tagged 354394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // t0: begin of source FixedDoubleArray element fields, not tagged, +4 355394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // t1: end of destination FixedArray, not tagged 356394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // t2: destination FixedArray 357394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // t3: the-hole pointer 358394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // t5: heap number map 359394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Branch(&entry); 360394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 361394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Call into runtime if GC is required. 362394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ bind(&gc_required); 363394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ MultiPop(a0.bit() | a1.bit() | a2.bit() | a3.bit() | ra.bit()); 364394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 365394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Branch(fail); 366394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 367394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ bind(&loop); 368394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ lw(a1, MemOperand(t0)); 369394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Addu(t0, t0, kDoubleSize); 370394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // a1: current element's upper 32 bit 371394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // t0: address of next element's upper 32 bit 372394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Branch(&convert_hole, eq, a1, Operand(kHoleNanUpper32)); 373394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 374394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Non-hole double, copy value into a heap number. 375394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ AllocateHeapNumber(a2, a0, t6, t5, &gc_required); 376394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // a2: new heap number 377394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ lw(a0, MemOperand(t0, -12)); 378394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ sw(a0, FieldMemOperand(a2, HeapNumber::kMantissaOffset)); 379394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ sw(a1, FieldMemOperand(a2, HeapNumber::kExponentOffset)); 380394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ mov(a0, a3); 381394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ sw(a2, MemOperand(a3)); 382394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Addu(a3, a3, kIntSize); 383394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ RecordWrite(t2, 384394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com a0, 385394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com a2, 386394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com kRAHasBeenSaved, 387394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com kDontSaveFPRegs, 388394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com EMIT_REMEMBERED_SET, 389394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com OMIT_SMI_CHECK); 390394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Branch(&entry); 391394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 392394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Replace the-hole NaN with the-hole pointer. 393394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ bind(&convert_hole); 394394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ sw(t3, MemOperand(a3)); 395394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Addu(a3, a3, kIntSize); 396394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 397394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ bind(&entry); 398394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Branch(&loop, lt, a3, Operand(t1)); 399394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 400394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ MultiPop(a2.bit() | a3.bit() | a0.bit() | a1.bit()); 401394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Replace receiver's backing store with newly created and filled FixedArray. 402394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ sw(t2, FieldMemOperand(a2, JSObject::kElementsOffset)); 403394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ RecordWriteField(a2, 404394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com JSObject::kElementsOffset, 405394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com t2, 406394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com t5, 407394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com kRAHasBeenSaved, 408394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com kDontSaveFPRegs, 409394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com EMIT_REMEMBERED_SET, 410394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com OMIT_SMI_CHECK); 411394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ pop(ra); 41256454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org 41356454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org __ bind(&only_change_map); 41456454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org // Update receiver's map. 41556454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org __ sw(a3, FieldMemOperand(a2, HeapObject::kMapOffset)); 41656454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org __ RecordWriteField(a2, 41756454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org HeapObject::kMapOffset, 41856454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org a3, 41956454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org t5, 42056454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org kRAHasNotBeenSaved, 42156454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org kDontSaveFPRegs, 42256454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org OMIT_REMEMBERED_SET, 42356454717593e7552d6846198b8e0f661fa36a3cayangguo@chromium.org OMIT_SMI_CHECK); 424394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com} 425394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 42664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 42764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.orgvoid StringCharLoadGenerator::Generate(MacroAssembler* masm, 42864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Register string, 42964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Register index, 43064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Register result, 43164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Label* call_runtime) { 43264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Fetch the instance type of the receiver into result register. 43364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ lw(result, FieldMemOperand(string, HeapObject::kMapOffset)); 43464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ lbu(result, FieldMemOperand(result, Map::kInstanceTypeOffset)); 43564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 43664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // We need special handling for indirect strings. 43764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Label check_sequential; 43864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ And(at, result, Operand(kIsIndirectStringMask)); 43964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ Branch(&check_sequential, eq, at, Operand(zero_reg)); 44064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 44164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Dispatch on the indirect string shape: slice or cons. 44264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Label cons_string; 44364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ And(at, result, Operand(kSlicedNotConsMask)); 44464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ Branch(&cons_string, eq, at, Operand(zero_reg)); 44564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 44664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Handle slices. 44764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Label indirect_string_loaded; 44864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ lw(result, FieldMemOperand(string, SlicedString::kOffsetOffset)); 449fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org __ lw(string, FieldMemOperand(string, SlicedString::kParentOffset)); 45064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ sra(at, result, kSmiTagSize); 45164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ Addu(index, index, at); 45264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ jmp(&indirect_string_loaded); 45364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 45464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Handle cons strings. 45564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Check whether the right hand side is the empty string (i.e. if 45664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // this is really a flat string in a cons string). If that is not 45764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // the case we would rather go to the runtime system now to flatten 45864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // the string. 45964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ bind(&cons_string); 46064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ lw(result, FieldMemOperand(string, ConsString::kSecondOffset)); 461750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org __ LoadRoot(at, Heap::kempty_stringRootIndex); 46264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ Branch(call_runtime, ne, result, Operand(at)); 46364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Get the first of the two strings and load its instance type. 46464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ lw(string, FieldMemOperand(string, ConsString::kFirstOffset)); 46564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 46664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ bind(&indirect_string_loaded); 46764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ lw(result, FieldMemOperand(string, HeapObject::kMapOffset)); 46864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ lbu(result, FieldMemOperand(result, Map::kInstanceTypeOffset)); 46964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 47064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Distinguish sequential and external strings. Only these two string 47164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // representations can reach here (slices and flat cons strings have been 47264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // reduced to the underlying sequential or external string). 47364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Label external_string, check_encoding; 47464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ bind(&check_sequential); 47564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org STATIC_ASSERT(kSeqStringTag == 0); 47664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ And(at, result, Operand(kStringRepresentationMask)); 47764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ Branch(&external_string, ne, at, Operand(zero_reg)); 47864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 47964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Prepare sequential strings 480fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize); 48164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ Addu(string, 48264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org string, 48364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org SeqTwoByteString::kHeaderSize - kHeapObjectTag); 48464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ jmp(&check_encoding); 48564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 48664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Handle external strings. 48764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ bind(&external_string); 48864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (FLAG_debug_code) { 48964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Assert that we do not have a cons or slice (indirect strings) here. 49064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Sequential strings have already been ruled out. 49164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ And(at, result, Operand(kIsIndirectStringMask)); 492594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Assert(eq, kExternalStringExpectedButNotFound, 49364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org at, Operand(zero_reg)); 49464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } 49564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Rule out short external strings. 49664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org STATIC_CHECK(kShortExternalStringTag != 0); 49764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ And(at, result, Operand(kShortExternalStringMask)); 49864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ Branch(call_runtime, ne, at, Operand(zero_reg)); 49964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ lw(string, FieldMemOperand(string, ExternalString::kResourceDataOffset)); 50064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 50164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org Label ascii, done; 50264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ bind(&check_encoding); 50364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org STATIC_ASSERT(kTwoByteStringTag == 0); 50464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ And(at, result, Operand(kStringEncodingMask)); 50564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ Branch(&ascii, ne, at, Operand(zero_reg)); 50664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Two-byte string. 50764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ sll(at, index, 1); 50864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ Addu(at, string, at); 50964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ lhu(result, MemOperand(at)); 51064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ jmp(&done); 51164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ bind(&ascii); 51264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org // Ascii string. 51364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ Addu(at, string, index); 51464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ lbu(result, MemOperand(at)); 51564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org __ bind(&done); 51664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org} 51764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 51883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org 51983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.orgstatic MemOperand ExpConstant(int index, Register base) { 52083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org return MemOperand(base, index * kDoubleSize); 52183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org} 52283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org 52383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org 52483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.orgvoid MathExpGenerator::EmitMathExp(MacroAssembler* masm, 52583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org DoubleRegister input, 52683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org DoubleRegister result, 52783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org DoubleRegister double_scratch1, 52883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org DoubleRegister double_scratch2, 52983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org Register temp1, 53083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org Register temp2, 53183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org Register temp3) { 53283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org ASSERT(!input.is(result)); 53383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org ASSERT(!input.is(double_scratch1)); 53483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org ASSERT(!input.is(double_scratch2)); 53583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org ASSERT(!result.is(double_scratch1)); 53683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org ASSERT(!result.is(double_scratch2)); 53783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org ASSERT(!double_scratch1.is(double_scratch2)); 53883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org ASSERT(!temp1.is(temp2)); 53983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org ASSERT(!temp1.is(temp3)); 54083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org ASSERT(!temp2.is(temp3)); 54183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org ASSERT(ExternalReference::math_exp_constants(0).address() != NULL); 54283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org 54383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org Label done; 54483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org 54583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ li(temp3, Operand(ExternalReference::math_exp_constants(0))); 54683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org 54783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ ldc1(double_scratch1, ExpConstant(0, temp3)); 54883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ Move(result, kDoubleRegZero); 54983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ BranchF(&done, NULL, ge, double_scratch1, input); 55083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ ldc1(double_scratch2, ExpConstant(1, temp3)); 55183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ ldc1(result, ExpConstant(2, temp3)); 55283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ BranchF(&done, NULL, ge, input, double_scratch2); 55383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ ldc1(double_scratch1, ExpConstant(3, temp3)); 55483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ ldc1(result, ExpConstant(4, temp3)); 55583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ mul_d(double_scratch1, double_scratch1, input); 55683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ add_d(double_scratch1, double_scratch1, result); 55783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ Move(temp2, temp1, double_scratch1); 55883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ sub_d(double_scratch1, double_scratch1, result); 55983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ ldc1(result, ExpConstant(6, temp3)); 56083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ ldc1(double_scratch2, ExpConstant(5, temp3)); 56183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ mul_d(double_scratch1, double_scratch1, double_scratch2); 56283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ sub_d(double_scratch1, double_scratch1, input); 56383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ sub_d(result, result, double_scratch1); 56483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ mul_d(input, double_scratch1, double_scratch1); 56583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ mul_d(result, result, input); 56683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ srl(temp1, temp2, 11); 56783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ ldc1(double_scratch2, ExpConstant(7, temp3)); 56883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ mul_d(result, result, double_scratch2); 56983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ sub_d(result, result, double_scratch1); 57083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ ldc1(double_scratch2, ExpConstant(8, temp3)); 57183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ add_d(result, result, double_scratch2); 57283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ li(at, 0x7ff); 57383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ And(temp2, temp2, at); 57483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ Addu(temp1, temp1, Operand(0x3ff)); 57583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ sll(temp1, temp1, 20); 57683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org 57783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org // Must not call ExpConstant() after overwriting temp3! 57883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ li(temp3, Operand(ExternalReference::math_exp_log_table())); 57983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ sll(at, temp2, 3); 58083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ addu(at, at, temp3); 58183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ lw(at, MemOperand(at)); 58283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ Addu(temp3, temp3, Operand(kPointerSize)); 58383130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ sll(temp2, temp2, 3); 58483130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ addu(temp2, temp2, temp3); 58583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ lw(temp2, MemOperand(temp2)); 58683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ Or(temp1, temp1, temp2); 58783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ Move(input, at, temp1); 58883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ mul_d(result, result, input); 58983130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org __ bind(&done); 59083130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org} 59183130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org 59283130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org 593fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org// nop(CODE_AGE_MARKER_NOP) 594fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.orgstatic const uint32_t kCodeAgePatchFirstInstruction = 0x00010180; 595fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 596fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.orgstatic byte* GetNoCodeAgeSequence(uint32_t* length) { 597fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // The sequence of instructions that is patched out for aging code is the 598fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // following boilerplate stack-building prologue that is found in FUNCTIONS 599fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org static bool initialized = false; 600fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org static uint32_t sequence[kNoCodeAgeSequenceLength]; 601fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org byte* byte_sequence = reinterpret_cast<byte*>(sequence); 602fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org *length = kNoCodeAgeSequenceLength * Assembler::kInstrSize; 603fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org if (!initialized) { 604fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org CodePatcher patcher(byte_sequence, kNoCodeAgeSequenceLength); 605fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org patcher.masm()->Push(ra, fp, cp, a1); 606ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org patcher.masm()->nop(Assembler::CODE_AGE_SEQUENCE_NOP); 607fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org patcher.masm()->Addu(fp, sp, Operand(2 * kPointerSize)); 608fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org initialized = true; 609fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 610fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org return byte_sequence; 611fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org} 612fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 613fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 614fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.orgbool Code::IsYoungSequence(byte* sequence) { 615fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org uint32_t young_length; 616fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org byte* young_sequence = GetNoCodeAgeSequence(&young_length); 617fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org bool result = !memcmp(sequence, young_sequence, young_length); 618fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org ASSERT(result || 619fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org Memory::uint32_at(sequence) == kCodeAgePatchFirstInstruction); 620fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org return result; 621fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org} 622fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 623fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 624fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.orgvoid Code::GetCodeAgeAndParity(byte* sequence, Age* age, 625fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org MarkingParity* parity) { 626fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org if (IsYoungSequence(sequence)) { 627fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org *age = kNoAge; 628fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org *parity = NO_MARKING_PARITY; 629fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } else { 630fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org Address target_address = Memory::Address_at( 631fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org sequence + Assembler::kInstrSize * (kNoCodeAgeSequenceLength - 1)); 632fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org Code* stub = GetCodeFromTargetAddress(target_address); 633fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org GetCodeAgeAndParity(stub, age, parity); 634fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 635fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org} 636fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 637fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 638fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.orgvoid Code::PatchPlatformCodeAge(byte* sequence, 639fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org Code::Age age, 640fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org MarkingParity parity) { 641fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org uint32_t young_length; 642fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org byte* young_sequence = GetNoCodeAgeSequence(&young_length); 643fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org if (age == kNoAge) { 644c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org CopyBytes(sequence, young_sequence, young_length); 645fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org CPU::FlushICache(sequence, young_length); 646fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } else { 647fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org Code* stub = GetCodeAgeStub(age, parity); 648fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org CodePatcher patcher(sequence, young_length / Assembler::kInstrSize); 649fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // Mark this code sequence for FindPlatformCodeAgeSequence() 650fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org patcher.masm()->nop(Assembler::CODE_AGE_MARKER_NOP); 651fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // Save the function's original return address 652fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // (it will be clobbered by Call(t9)) 653fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org patcher.masm()->mov(at, ra); 654fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // Load the stub address to t9 and call it 655fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org patcher.masm()->li(t9, 656fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org Operand(reinterpret_cast<uint32_t>(stub->instruction_start()))); 657fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org patcher.masm()->Call(t9); 658fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // Record the stub address in the empty space for GetCodeAgeAndParity() 659fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org patcher.masm()->dd(reinterpret_cast<uint32_t>(stub->instruction_start())); 660fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 661fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org} 662fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 663fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 664394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com#undef __ 6655c838251403b0be9a882540f1922577abba4c872ager@chromium.org 6665c838251403b0be9a882540f1922577abba4c872ager@chromium.org} } // namespace v8::internal 6679dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 6689dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com#endif // V8_TARGET_ARCH_MIPS 669