165a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be 33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file. 45ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org 5196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h" 65aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 793a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_X64 89dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/codegen.h" 10196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/macro-assembler.h" 115aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 1271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 { 1371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal { 1471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 1530ce411529579186181838984710b0b0980857aaricow@chromium.org// ------------------------------------------------------------------------- 1630ce411529579186181838984710b0b0980857aaricow@chromium.org// Platform-specific RuntimeCallHelper functions. 1730ce411529579186181838984710b0b0980857aaricow@chromium.org 18a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid StubRuntimeCallHelper::BeforeCall(MacroAssembler* masm) const { 19c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com masm->EnterFrame(StackFrame::INTERNAL); 20e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!masm->has_frame()); 21c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com masm->set_has_frame(true); 2230ce411529579186181838984710b0b0980857aaricow@chromium.org} 2330ce411529579186181838984710b0b0980857aaricow@chromium.org 2430ce411529579186181838984710b0b0980857aaricow@chromium.org 25a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgvoid StubRuntimeCallHelper::AfterCall(MacroAssembler* masm) const { 26c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com masm->LeaveFrame(StackFrame::INTERNAL); 27e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(masm->has_frame()); 28c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com masm->set_has_frame(false); 2930ce411529579186181838984710b0b0980857aaricow@chromium.org} 3030ce411529579186181838984710b0b0980857aaricow@chromium.org 3130ce411529579186181838984710b0b0980857aaricow@chromium.org 323811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org#define __ masm. 333811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 349a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org 351f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.orgUnaryMathFunction CreateExpFunction() { 36e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org if (!FLAG_fast_math) return &std::exp; 371f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org size_t actual_size; 385de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org byte* buffer = 395de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org static_cast<byte*>(base::OS::Allocate(1 * KB, &actual_size, true)); 40e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org if (buffer == NULL) return &std::exp; 411f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org ExternalReference::InitializeMathExpData(); 421f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org 431f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org MacroAssembler masm(NULL, buffer, static_cast<int>(actual_size)); 441f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org // xmm0: raw double input. 451f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org XMMRegister input = xmm0; 461f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org XMMRegister result = xmm1; 47763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(rax); 48763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ pushq(rbx); 491f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org 501f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org MathExpGenerator::EmitMathExp(&masm, input, result, xmm2, rax, rbx); 511f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org 52763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ popq(rbx); 53763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ popq(rax); 541f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ movsd(xmm0, result); 551f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ Ret(); 561f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org 571f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org CodeDesc desc; 581f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org masm.GetCode(&desc); 59e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!RelocInfo::RequiresRelocation(desc)); 601f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org 615de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org CpuFeatures::FlushICache(buffer, actual_size); 625de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org base::OS::ProtectCode(buffer, actual_size); 631f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org return FUNCTION_CAST<UnaryMathFunction>(buffer); 641f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org} 651f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org 661f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org 67154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.orgUnaryMathFunction CreateSqrtFunction() { 68154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org size_t actual_size; 69154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org // Allocate buffer in executable space. 705de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org byte* buffer = 715de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org static_cast<byte*>(base::OS::Allocate(1 * KB, &actual_size, true)); 72e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org if (buffer == NULL) return &std::sqrt; 73154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org 74154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org MacroAssembler masm(NULL, buffer, static_cast<int>(actual_size)); 75154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org // xmm0: raw double input. 76154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org // Move double input into registers. 77154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org __ sqrtsd(xmm0, xmm0); 78154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org __ Ret(); 79154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org 80154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org CodeDesc desc; 81154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org masm.GetCode(&desc); 82e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!RelocInfo::RequiresRelocation(desc)); 83154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org 845de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org CpuFeatures::FlushICache(buffer, actual_size); 855de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org base::OS::ProtectCode(buffer, actual_size); 86154ff99473e866f5eb00a44045e27866a7fdce29yangguo@chromium.org return FUNCTION_CAST<UnaryMathFunction>(buffer); 879a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org} 889a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org 899a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org 903811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org#ifdef _WIN64 913811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.orgtypedef double (*ModuloFunction)(double, double); 923811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org// Define custom fmod implementation. 933811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.orgModuloFunction CreateModuloFunction() { 943811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org size_t actual_size; 955de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org byte* buffer = static_cast<byte*>( 965de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org base::OS::Allocate(Assembler::kMinimalBufferSize, &actual_size, true)); 973811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org CHECK(buffer); 98c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org Assembler masm(NULL, buffer, static_cast<int>(actual_size)); 993811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // Generated code is put into a fixed, unmovable, buffer, and not into 1003811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // the V8 heap. We can't, and don't, refer to any relocatable addresses 1013811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // (e.g. the JavaScript nan-object). 1023811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 1033811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // Windows 64 ABI passes double arguments in xmm0, xmm1 and 1043811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // returns result in xmm0. 1053811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // Argument backing space is allocated on the stack above 1063811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // the return address. 1073811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 1083811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // Compute x mod y. 1093811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // Load y and x (use argument backing store as temporary storage). 110af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org __ movsd(Operand(rsp, kRegisterSize * 2), xmm1); 111af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org __ movsd(Operand(rsp, kRegisterSize), xmm0); 112af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org __ fld_d(Operand(rsp, kRegisterSize * 2)); 113af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org __ fld_d(Operand(rsp, kRegisterSize)); 1143811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 1153811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // Clear exception flags before operation. 1163811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org { 1173811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org Label no_exceptions; 1183811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org __ fwait(); 1193811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org __ fnstsw_ax(); 1203811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // Clear if Illegal Operand or Zero Division exceptions are set. 1213811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org __ testb(rax, Immediate(5)); 1223811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org __ j(zero, &no_exceptions); 1233811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org __ fnclex(); 1243811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org __ bind(&no_exceptions); 1253811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 1263811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 1273811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // Compute st(0) % st(1) 1283811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org { 1293811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org Label partial_remainder_loop; 1303811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org __ bind(&partial_remainder_loop); 1313811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org __ fprem(); 1323811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org __ fwait(); 1333811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org __ fnstsw_ax(); 1343811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org __ testl(rax, Immediate(0x400 /* C2 */)); 1353811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // If C2 is set, computation only has partial result. Loop to 1363811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // continue computation. 1373811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org __ j(not_zero, &partial_remainder_loop); 1383811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 1393811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 1403811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org Label valid_result; 1413811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org Label return_result; 1423811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // If Invalid Operand or Zero Division exceptions are set, 1433811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // return NaN. 1443811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org __ testb(rax, Immediate(5)); 1453811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org __ j(zero, &valid_result); 1463811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org __ fstp(0); // Drop result in st(0). 1473811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org int64_t kNaNValue = V8_INT64_C(0x7ff8000000000000); 148e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ movq(rcx, kNaNValue); 149af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org __ movq(Operand(rsp, kRegisterSize), rcx); 150af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org __ movsd(xmm0, Operand(rsp, kRegisterSize)); 1513811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org __ jmp(&return_result); 1523811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 1533811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // If result is valid, return that. 1543811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org __ bind(&valid_result); 155af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org __ fstp_d(Operand(rsp, kRegisterSize)); 156af4fba3c6d2a18866505de3e6798757dd1448c6dmachenbach@chromium.org __ movsd(xmm0, Operand(rsp, kRegisterSize)); 1573811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 1583811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org // Clean up FPU stack and exceptions and return xmm0 1593811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org __ bind(&return_result); 1603811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org __ fstp(0); // Unload y. 1613811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 1623811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org Label clear_exceptions; 1633811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org __ testb(rax, Immediate(0x3f /* Any Exception*/)); 1643811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org __ j(not_zero, &clear_exceptions); 1653811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org __ ret(0); 1663811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org __ bind(&clear_exceptions); 1673811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org __ fnclex(); 1683811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org __ ret(0); 1693811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 1703811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org CodeDesc desc; 1713811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org masm.GetCode(&desc); 1725de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org base::OS::ProtectCode(buffer, actual_size); 173c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org // Call the function from C++ through this pointer. 1743811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org return FUNCTION_CAST<ModuloFunction>(buffer); 1753811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org} 1763811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org 1773811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org#endif 1782abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org 179394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com#undef __ 180394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 181394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com// ------------------------------------------------------------------------- 182394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com// Code generators 183394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 184394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com#define __ ACCESS_MASM(masm) 185394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 186830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.orgvoid ElementsTransitionGenerator::GenerateMapChangeElementsTransition( 1879bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org MacroAssembler* masm, 1889bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Register receiver, 1899bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Register key, 1909bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Register value, 1919bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Register target_map, 1929bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org AllocationSiteMode mode, 193ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Label* allocation_memento_found) { 1949bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org // Return address is on the stack. 1959bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Register scratch = rdi; 196e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!AreAliased(receiver, key, value, target_map, scratch)); 1979bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org 19846a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org if (mode == TRACK_ALLOCATION_SITE) { 199e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(allocation_memento_found != NULL); 2009bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org __ JumpIfJSArrayHasAllocationMemento( 2019bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org receiver, scratch, allocation_memento_found); 20246a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org } 20346a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org 204394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Set transitioned map. 2059bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org __ movp(FieldOperand(receiver, HeapObject::kMapOffset), target_map); 2069bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org __ RecordWriteField(receiver, 207394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com HeapObject::kMapOffset, 2089bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org target_map, 2099bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org scratch, 210394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com kDontSaveFPRegs, 211394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com EMIT_REMEMBERED_SET, 212394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com OMIT_SMI_CHECK); 213394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com} 214394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 215394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 216830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.orgvoid ElementsTransitionGenerator::GenerateSmiToDouble( 2179bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org MacroAssembler* masm, 2189bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Register receiver, 2199bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Register key, 2209bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Register value, 2219bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Register target_map, 2229bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org AllocationSiteMode mode, 2239bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Label* fail) { 2249bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org // Return address is on the stack. 225e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(receiver.is(rdx)); 226e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(key.is(rcx)); 227e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(value.is(rax)); 228e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(target_map.is(rbx)); 2299bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org 230394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // The fail label is not actually used since we do not allocate. 2315ea3908c5e0a04c20bc93e848d009e1d4ac663f7danno@chromium.org Label allocated, new_backing_store, only_change_map, done; 23265a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org 23346a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org if (mode == TRACK_ALLOCATION_SITE) { 234b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org __ JumpIfJSArrayHasAllocationMemento(rdx, rdi, fail); 23559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org } 23659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 23765a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org // Check for empty arrays, which only require a map transition and no changes 23865a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org // to the backing store. 23943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(r8, FieldOperand(rdx, JSObject::kElementsOffset)); 24065a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org __ CompareRoot(r8, Heap::kEmptyFixedArrayRootIndex); 24165a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org __ j(equal, &only_change_map); 242394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 243394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ SmiToInteger32(r9, FieldOperand(r8, FixedDoubleArray::kLengthOffset)); 244a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org if (kPointerSize == kDoubleSize) { 245a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org // Check backing store for COW-ness. For COW arrays we have to 246a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org // allocate a new backing store. 247a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org __ CompareRoot(FieldOperand(r8, HeapObject::kMapOffset), 248a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org Heap::kFixedCOWArrayMapRootIndex); 249a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org __ j(equal, &new_backing_store); 250a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org } else { 251a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org // For x32 port we have to allocate a new backing store as SMI size is 252a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org // not equal with double size. 253e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(kDoubleSize == 2 * kPointerSize); 254a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org __ jmp(&new_backing_store); 255a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org } 256a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org 2575ea3908c5e0a04c20bc93e848d009e1d4ac663f7danno@chromium.org // Check if the backing store is in new-space. If not, we need to allocate 2585ea3908c5e0a04c20bc93e848d009e1d4ac663f7danno@chromium.org // a new one since the old one is in pointer-space. 2595ea3908c5e0a04c20bc93e848d009e1d4ac663f7danno@chromium.org // If in new space, we can reuse the old backing store because it is 2605ea3908c5e0a04c20bc93e848d009e1d4ac663f7danno@chromium.org // the same size. 2615ea3908c5e0a04c20bc93e848d009e1d4ac663f7danno@chromium.org __ JumpIfNotInNewSpace(r8, rdi, &new_backing_store); 2625ea3908c5e0a04c20bc93e848d009e1d4ac663f7danno@chromium.org 26343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(r14, r8); // Destination array equals source array. 264394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 265394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // r8 : source FixedArray 266394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // r9 : elements array length 267394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // r14: destination FixedDoubleArray 268394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Set backing store's map 269394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ LoadRoot(rdi, Heap::kFixedDoubleArrayMapRootIndex); 27043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(FieldOperand(r14, HeapObject::kMapOffset), rdi); 271394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 2725ea3908c5e0a04c20bc93e848d009e1d4ac663f7danno@chromium.org __ bind(&allocated); 273394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Set transitioned map. 27443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(FieldOperand(rdx, HeapObject::kMapOffset), rbx); 275394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ RecordWriteField(rdx, 276394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com HeapObject::kMapOffset, 277394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com rbx, 278394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com rdi, 279394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com kDontSaveFPRegs, 280394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com EMIT_REMEMBERED_SET, 281394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com OMIT_SMI_CHECK); 282394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 283394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Convert smis to doubles and holes to hole NaNs. The Array's length 284394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // remains unchanged. 285394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com STATIC_ASSERT(FixedDoubleArray::kLengthOffset == FixedArray::kLengthOffset); 286394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com STATIC_ASSERT(FixedDoubleArray::kHeaderSize == FixedArray::kHeaderSize); 287394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 288394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Label loop, entry, convert_hole; 289e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org __ movq(r15, bit_cast<int64_t, uint64_t>(kHoleNanInt64)); 290394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // r15: the-hole NaN 291394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ jmp(&entry); 292394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 2935ea3908c5e0a04c20bc93e848d009e1d4ac663f7danno@chromium.org // Allocate new backing store. 2945ea3908c5e0a04c20bc93e848d009e1d4ac663f7danno@chromium.org __ bind(&new_backing_store); 295895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(rdi, Operand(r9, times_8, FixedArray::kHeaderSize)); 296f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org __ Allocate(rdi, r14, r11, r15, fail, TAG_OBJECT); 2975ea3908c5e0a04c20bc93e848d009e1d4ac663f7danno@chromium.org // Set backing store's map 2985ea3908c5e0a04c20bc93e848d009e1d4ac663f7danno@chromium.org __ LoadRoot(rdi, Heap::kFixedDoubleArrayMapRootIndex); 29943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(FieldOperand(r14, HeapObject::kMapOffset), rdi); 300394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Set receiver's backing store. 30143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(FieldOperand(rdx, JSObject::kElementsOffset), r14); 30243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(r11, r14); 303394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ RecordWriteField(rdx, 304394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com JSObject::kElementsOffset, 305394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com r11, 306394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com r15, 307394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com kDontSaveFPRegs, 308394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com EMIT_REMEMBERED_SET, 309394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com OMIT_SMI_CHECK); 310394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Set backing store's length. 311394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Integer32ToSmi(r11, r9); 31243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(FieldOperand(r14, FixedDoubleArray::kLengthOffset), r11); 313394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ jmp(&allocated); 314394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 31565a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org __ bind(&only_change_map); 31665a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org // Set transitioned map. 31743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(FieldOperand(rdx, HeapObject::kMapOffset), rbx); 31865a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org __ RecordWriteField(rdx, 31965a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org HeapObject::kMapOffset, 32065a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org rbx, 32165a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org rdi, 32265a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org kDontSaveFPRegs, 32365a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org OMIT_REMEMBERED_SET, 32465a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org OMIT_SMI_CHECK); 32565a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org __ jmp(&done); 32665a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org 327394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Conversion loop. 328394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ bind(&loop); 32943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rbx, 3301510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org FieldOperand(r8, r9, times_pointer_size, FixedArray::kHeaderSize)); 331394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // r9 : current element's index 332394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // rbx: current element (smi-tagged) 333394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ JumpIfNotSmi(rbx, &convert_hole); 334394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ SmiToInteger32(rbx, rbx); 335528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ Cvtlsi2sd(xmm0, rbx); 336394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ movsd(FieldOperand(r14, r9, times_8, FixedDoubleArray::kHeaderSize), 337394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com xmm0); 338394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ jmp(&entry); 339394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ bind(&convert_hole); 340c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 341c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (FLAG_debug_code) { 342c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex); 343594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Assert(equal, kObjectFoundInSmiOnlyArray); 344c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org } 345c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 346394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ movq(FieldOperand(r14, r9, times_8, FixedDoubleArray::kHeaderSize), r15); 347394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ bind(&entry); 3487a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ decp(r9); 349becbc5247ca44bb32846a82794e96425980e9d50erik.corry@gmail.com __ j(not_sign, &loop); 35065a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org 35165a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org __ bind(&done); 352394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com} 353394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 354394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 355394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comvoid ElementsTransitionGenerator::GenerateDoubleToObject( 3569bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org MacroAssembler* masm, 3579bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Register receiver, 3589bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Register key, 3599bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Register value, 3609bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Register target_map, 3619bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org AllocationSiteMode mode, 3629bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org Label* fail) { 3639bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org // Return address is on the stack. 364e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(receiver.is(rdx)); 365e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(key.is(rcx)); 366e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(value.is(rax)); 367e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(target_map.is(rbx)); 3689bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org 36965a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org Label loop, entry, convert_hole, gc_required, only_change_map; 37065a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org 37146a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org if (mode == TRACK_ALLOCATION_SITE) { 372b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org __ JumpIfJSArrayHasAllocationMemento(rdx, rdi, fail); 37346a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org } 37446a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org 37565a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org // Check for empty arrays, which only require a map transition and no changes 37665a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org // to the backing store. 37743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(r8, FieldOperand(rdx, JSObject::kElementsOffset)); 37865a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org __ CompareRoot(r8, Heap::kEmptyFixedArrayRootIndex); 37965a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org __ j(equal, &only_change_map); 38065a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org 381763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Push(rax); 382394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 38343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(r8, FieldOperand(rdx, JSObject::kElementsOffset)); 384394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ SmiToInteger32(r9, FieldOperand(r8, FixedDoubleArray::kLengthOffset)); 385394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // r8 : source FixedDoubleArray 386394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // r9 : number of elements 387895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leap(rdi, Operand(r9, times_pointer_size, FixedArray::kHeaderSize)); 388f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org __ Allocate(rdi, r11, r14, r15, &gc_required, TAG_OBJECT); 389394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // r11: destination FixedArray 390394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ LoadRoot(rdi, Heap::kFixedArrayMapRootIndex); 39143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(FieldOperand(r11, HeapObject::kMapOffset), rdi); 392394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Integer32ToSmi(r14, r9); 39343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(FieldOperand(r11, FixedArray::kLengthOffset), r14); 394394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 395394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Prepare for conversion loop. 396e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org __ movq(rsi, bit_cast<int64_t, uint64_t>(kHoleNanInt64)); 397394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ LoadRoot(rdi, Heap::kTheHoleValueRootIndex); 398394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // rsi: the-hole NaN 399394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // rdi: pointer to the-hole 400394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ jmp(&entry); 401394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 402394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Call into runtime if GC is required. 403394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ bind(&gc_required); 404763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(rax); 40543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 406394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ jmp(fail); 407394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 408394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Box doubles into heap numbers. 409394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ bind(&loop); 410394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ movq(r14, FieldOperand(r8, 411394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com r9, 4121510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org times_8, 413394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com FixedDoubleArray::kHeaderSize)); 414394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // r9 : current element's index 415394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // r14: current element 416394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ cmpq(r14, rsi); 417394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ j(equal, &convert_hole); 418394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 419394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Non-hole double, copy value into a heap number. 420394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ AllocateHeapNumber(rax, r15, &gc_required); 421394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // rax: new heap number 422bb8234d89692f5088ce3fe3ff5a8e8da2f038cfemachenbach@chromium.org __ movq(FieldOperand(rax, HeapNumber::kValueOffset), r14); 42343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(FieldOperand(r11, 424394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com r9, 425394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com times_pointer_size, 426394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com FixedArray::kHeaderSize), 427394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com rax); 42843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(r15, r9); 429394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ RecordWriteArray(r11, 430394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com rax, 431394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com r15, 432394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com kDontSaveFPRegs, 433394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com EMIT_REMEMBERED_SET, 434394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com OMIT_SMI_CHECK); 435394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ jmp(&entry, Label::kNear); 436394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 437394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Replace the-hole NaN with the-hole pointer. 438394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ bind(&convert_hole); 43943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(FieldOperand(r11, 440394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com r9, 441394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com times_pointer_size, 442394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com FixedArray::kHeaderSize), 443394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com rdi); 444394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 445394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ bind(&entry); 4467a1bfbe9bc8295770315c55f7ce40822b7951aabmachenbach@chromium.org __ decp(r9); 447becbc5247ca44bb32846a82794e96425980e9d50erik.corry@gmail.com __ j(not_sign, &loop); 448394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 449394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Replace receiver's backing store with newly created and filled FixedArray. 45043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(FieldOperand(rdx, JSObject::kElementsOffset), r11); 451394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ RecordWriteField(rdx, 452394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com JSObject::kElementsOffset, 453394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com r11, 454394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com r15, 455394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com kDontSaveFPRegs, 456394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com EMIT_REMEMBERED_SET, 457394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com OMIT_SMI_CHECK); 458763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org __ Pop(rax); 45943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 46065a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org 46165a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org __ bind(&only_change_map); 46265a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org // Set transitioned map. 46343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(FieldOperand(rdx, HeapObject::kMapOffset), rbx); 46465a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org __ RecordWriteField(rdx, 46565a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org HeapObject::kMapOffset, 46665a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org rbx, 46765a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org rdi, 46865a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org kDontSaveFPRegs, 46965a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org OMIT_REMEMBERED_SET, 47065a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org OMIT_SMI_CHECK); 471394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com} 472b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 4731b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 4741b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orgvoid StringCharLoadGenerator::Generate(MacroAssembler* masm, 4751b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org Register string, 4761b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org Register index, 4771b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org Register result, 4781b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org Label* call_runtime) { 4791b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // Fetch the instance type of the receiver into result register. 48043c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(result, FieldOperand(string, HeapObject::kMapOffset)); 4811b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ movzxbl(result, FieldOperand(result, Map::kInstanceTypeOffset)); 4821b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 4831b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // We need special handling for indirect strings. 4841b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org Label check_sequential; 4851b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ testb(result, Immediate(kIsIndirectStringMask)); 4861b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ j(zero, &check_sequential, Label::kNear); 4871b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 4881b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // Dispatch on the indirect string shape: slice or cons. 4891b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org Label cons_string; 4901b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ testb(result, Immediate(kSlicedNotConsMask)); 4911b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ j(zero, &cons_string, Label::kNear); 4921b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 4931b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // Handle slices. 4941b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org Label indirect_string_loaded; 4951b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ SmiToInteger32(result, FieldOperand(string, SlicedString::kOffsetOffset)); 496fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org __ addp(index, result); 49743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(string, FieldOperand(string, SlicedString::kParentOffset)); 4981b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ jmp(&indirect_string_loaded, Label::kNear); 4991b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 5001b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // Handle cons strings. 5011b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // Check whether the right hand side is the empty string (i.e. if 5021b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // this is really a flat string in a cons string). If that is not 5031b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // the case we would rather go to the runtime system now to flatten 5041b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // the string. 5051b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ bind(&cons_string); 5061b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ CompareRoot(FieldOperand(string, ConsString::kSecondOffset), 5074a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Heap::kempty_stringRootIndex); 5081b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ j(not_equal, call_runtime); 50943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(string, FieldOperand(string, ConsString::kFirstOffset)); 5101b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 5111b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ bind(&indirect_string_loaded); 51243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(result, FieldOperand(string, HeapObject::kMapOffset)); 5131b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ movzxbl(result, FieldOperand(result, Map::kInstanceTypeOffset)); 5141b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 5151b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // Distinguish sequential and external strings. Only these two string 5161b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // representations can reach here (slices and flat cons strings have been 5171b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // reduced to the underlying sequential or external string). 5181b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org Label seq_string; 5191b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ bind(&check_sequential); 5201b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org STATIC_ASSERT(kSeqStringTag == 0); 5211b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ testb(result, Immediate(kStringRepresentationMask)); 5221b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ j(zero, &seq_string, Label::kNear); 5231b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 5241b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // Handle external strings. 5252c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Label one_byte_external, done; 5261b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (FLAG_debug_code) { 5271b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // Assert that we do not have a cons or slice (indirect strings) here. 5281b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // Sequential strings have already been ruled out. 5291b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ testb(result, Immediate(kIsIndirectStringMask)); 530594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Assert(zero, kExternalStringExpectedButNotFound); 5311b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org } 5321b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // Rule out short external strings. 533d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org STATIC_ASSERT(kShortExternalStringTag != 0); 5341b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ testb(result, Immediate(kShortExternalStringTag)); 5351b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ j(not_zero, call_runtime); 5361b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // Check encoding. 5371b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org STATIC_ASSERT(kTwoByteStringTag == 0); 5381b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ testb(result, Immediate(kStringEncodingMask)); 53943c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ movp(result, FieldOperand(string, ExternalString::kResourceDataOffset)); 5402c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org __ j(not_equal, &one_byte_external, Label::kNear); 5411b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // Two-byte string. 5421b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ movzxwl(result, Operand(result, index, times_2, 0)); 5431b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ jmp(&done, Label::kNear); 5442c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org __ bind(&one_byte_external); 5452c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // One-byte string. 5461b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ movzxbl(result, Operand(result, index, times_1, 0)); 5471b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ jmp(&done, Label::kNear); 5481b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 5492c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // Dispatch on the encoding: one-byte or two-byte. 5502c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org Label one_byte; 5511b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ bind(&seq_string); 552e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org STATIC_ASSERT((kStringEncodingMask & kOneByteStringTag) != 0); 5531b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0); 5541b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ testb(result, Immediate(kStringEncodingMask)); 5552c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org __ j(not_zero, &one_byte, Label::kNear); 5561b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 5571b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // Two-byte string. 5581b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // Load the two-byte character code into the result register. 5591b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1); 5601b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ movzxwl(result, FieldOperand(string, 5611b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org index, 5621b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org times_2, 5631b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org SeqTwoByteString::kHeaderSize)); 5641b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ jmp(&done, Label::kNear); 5651b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 5662c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org // One-byte string. 5671b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org // Load the byte into the result register. 5682c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org __ bind(&one_byte); 5691b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ movzxbl(result, FieldOperand(string, 5701b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org index, 5711b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org times_1, 572fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org SeqOneByteString::kHeaderSize)); 5731b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org __ bind(&done); 5741b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org} 5751b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org 5761f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org 5771f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.orgvoid MathExpGenerator::EmitMathExp(MacroAssembler* masm, 5781f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org XMMRegister input, 5791f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org XMMRegister result, 5801f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org XMMRegister double_scratch, 5811f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org Register temp1, 5821f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org Register temp2) { 583e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!input.is(result)); 584e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!input.is(double_scratch)); 585e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!result.is(double_scratch)); 586e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!temp1.is(temp2)); 587e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(ExternalReference::math_exp_constants(0).address() != NULL); 5889d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org DCHECK(!masm->serializer_enabled()); // External references not serializable. 5891f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org 5901f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org Label done; 5911f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org 592e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ Move(kScratchRegister, ExternalReference::math_exp_constants(0)); 5931f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ movsd(double_scratch, Operand(kScratchRegister, 0 * kDoubleSize)); 5941f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ xorpd(result, result); 5951f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ ucomisd(double_scratch, input); 5961f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ j(above_equal, &done); 5971f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ ucomisd(input, Operand(kScratchRegister, 1 * kDoubleSize)); 5981f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ movsd(result, Operand(kScratchRegister, 2 * kDoubleSize)); 5991f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ j(above_equal, &done); 6001f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ movsd(double_scratch, Operand(kScratchRegister, 3 * kDoubleSize)); 6011f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ movsd(result, Operand(kScratchRegister, 4 * kDoubleSize)); 6021f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ mulsd(double_scratch, input); 6031f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ addsd(double_scratch, result); 6041f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ movq(temp2, double_scratch); 6051f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ subsd(double_scratch, result); 6061f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ movsd(result, Operand(kScratchRegister, 6 * kDoubleSize)); 607895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ leaq(temp1, Operand(temp2, 0x1ff800)); 608895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ andq(temp2, Immediate(0x7ff)); 6092f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org __ shrq(temp1, Immediate(11)); 6101f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ mulsd(double_scratch, Operand(kScratchRegister, 5 * kDoubleSize)); 611e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ Move(kScratchRegister, ExternalReference::math_exp_log_table()); 6122f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org __ shlq(temp1, Immediate(52)); 613895f00d1d8c5a7a7209c36d690688e3552de3df4machenbach@chromium.org __ orq(temp1, Operand(kScratchRegister, temp2, times_8, 0)); 614e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ Move(kScratchRegister, ExternalReference::math_exp_constants(0)); 6151f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ subsd(double_scratch, input); 6161f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ movsd(input, double_scratch); 6171f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ subsd(result, double_scratch); 6181f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ mulsd(input, double_scratch); 6191f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ mulsd(result, input); 6201f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ movq(input, temp1); 6211f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ mulsd(result, Operand(kScratchRegister, 7 * kDoubleSize)); 6221f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ subsd(result, double_scratch); 6231f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ addsd(result, Operand(kScratchRegister, 8 * kDoubleSize)); 6241f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ mulsd(result, input); 6251f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org 6261f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org __ bind(&done); 6271f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org} 6281f34ad3eadf9b0e6b8ed415817d276f54dd6d06bdanno@chromium.org 629e2902be65446e26fd63a3b4eab2f14257cf4ebafager@chromium.org#undef __ 63071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 631e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 6325924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.orgCodeAgingHelper::CodeAgingHelper() { 633e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(young_sequence_.length() == kNoCodeAgeSequenceLength); 6345924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org // The sequence of instructions that is patched out for aging code is the 6355924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org // following boilerplate stack-building prologue that is found both in 6365924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org // FUNCTION and OPTIMIZED_FUNCTION code: 6375924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org CodePatcher patcher(young_sequence_.start(), young_sequence_.length()); 6385924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org patcher.masm()->pushq(rbp); 6395924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org patcher.masm()->movp(rbp, rsp); 6405924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org patcher.masm()->Push(rsi); 6415924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org patcher.masm()->Push(rdi); 642e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org} 643e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 644e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 6455924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org#ifdef DEBUG 6465924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.orgbool CodeAgingHelper::IsOld(byte* candidate) const { 6475924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org return *candidate == kCallOpcode; 6485924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org} 6495924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org#endif 6505924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org 6515924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org 6525924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.orgbool Code::IsYoungSequence(Isolate* isolate, byte* sequence) { 6535924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org bool result = isolate->code_aging_helper()->IsYoung(sequence); 654e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(result || isolate->code_aging_helper()->IsOld(sequence)); 655e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org return result; 656e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org} 657e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 658e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 6595924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.orgvoid Code::GetCodeAgeAndParity(Isolate* isolate, byte* sequence, Age* age, 660e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org MarkingParity* parity) { 6615924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org if (IsYoungSequence(isolate, sequence)) { 662e94b5ff1e1e95fb2c8ef6bce66ce8533786d9792bmeurer@chromium.org *age = kNoAgeCodeAge; 663e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org *parity = NO_MARKING_PARITY; 664e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } else { 665e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org sequence++; // Skip the kCallOpcode byte 666e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org Address target_address = sequence + *reinterpret_cast<int*>(sequence) + 667e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org Assembler::kCallTargetAddressOffset; 668e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org Code* stub = GetCodeFromTargetAddress(target_address); 669e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org GetCodeAgeAndParity(stub, age, parity); 670e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } 671e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org} 672e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 673e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 674528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.orgvoid Code::PatchPlatformCodeAge(Isolate* isolate, 675528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org byte* sequence, 676e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org Code::Age age, 677e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org MarkingParity parity) { 6785924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org uint32_t young_length = isolate->code_aging_helper()->young_sequence_length(); 679e94b5ff1e1e95fb2c8ef6bce66ce8533786d9792bmeurer@chromium.org if (age == kNoAgeCodeAge) { 6805924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org isolate->code_aging_helper()->CopyYoungSequenceTo(sequence); 6815de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org CpuFeatures::FlushICache(sequence, young_length); 682e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } else { 683528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Code* stub = GetCodeAgeStub(isolate, age, parity); 684e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org CodePatcher patcher(sequence, young_length); 685e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org patcher.masm()->call(stub->instruction_start()); 686c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org patcher.masm()->Nop( 687c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org kNoCodeAgeSequenceLength - Assembler::kShortCallInstructionLength); 688e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } 689e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org} 690e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 691e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 692662436e7b124b3535773535c671c53db322070b5verwaest@chromium.orgOperand StackArgumentsAccessor::GetArgumentOperand(int index) { 693e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(index >= 0); 694662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org int receiver = (receiver_mode_ == ARGUMENTS_CONTAIN_RECEIVER) ? 1 : 0; 695662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org int displacement_to_last_argument = base_reg_.is(rsp) ? 696662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org kPCOnStackSize : kFPOnStackSize + kPCOnStackSize; 697662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org displacement_to_last_argument += extra_displacement_to_last_argument_; 698662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org if (argument_count_reg_.is(no_reg)) { 699662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org // argument[0] is at base_reg_ + displacement_to_last_argument + 700662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org // (argument_count_immediate_ + receiver - 1) * kPointerSize. 701e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(argument_count_immediate_ + receiver > 0); 702662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org return Operand(base_reg_, displacement_to_last_argument + 703662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org (argument_count_immediate_ + receiver - 1 - index) * kPointerSize); 704662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org } else { 705662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org // argument[0] is at base_reg_ + displacement_to_last_argument + 706662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org // argument_count_reg_ * times_pointer_size + (receiver - 1) * kPointerSize. 707662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org return Operand(base_reg_, argument_count_reg_, times_pointer_size, 708662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org displacement_to_last_argument + (receiver - 1 - index) * kPointerSize); 709662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org } 710662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org} 711662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org 712662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org 71371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org} } // namespace v8::internal 7149dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 7159dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com#endif // V8_TARGET_ARCH_X64 716