1f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com// Copyright 2012 the V8 project authors. All rights reserved. 25ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// Redistribution and use in source and binary forms, with or without 35ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// modification, are permitted provided that the following conditions are 45ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// met: 55ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// 65ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// * Redistributions of source code must retain the above copyright 75ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// notice, this list of conditions and the following disclaimer. 85ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// * Redistributions in binary form must reproduce the above 95ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// copyright notice, this list of conditions and the following 105ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// disclaimer in the documentation and/or other materials provided 115ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// with the distribution. 125ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// * Neither the name of Google Inc. nor the names of its 135ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// contributors may be used to endorse or promote products derived 145ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// from this software without specific prior written permission. 155ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// 165ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 175ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 185ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 195ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 205ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 215ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 225ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 235ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 245ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 255ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 265ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 275ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org 285aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org#include "v8.h" 295aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 3093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_X64 319dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 324a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org#include "arguments.h" 335aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org#include "ic-inl.h" 3444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org#include "codegen.h" 355aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org#include "stub-cache.h" 365aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 375aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.orgnamespace v8 { 385aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.orgnamespace internal { 395aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 400b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org#define __ ACCESS_MASM(masm) 410b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 420b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 43ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgstatic void ProbeTable(Isolate* isolate, 44ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org MacroAssembler* masm, 450b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org Code::Flags flags, 460b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org StubCache::Table table, 47812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Register receiver, 480b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org Register name, 49812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // The offset is scaled by 4, based on 50812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // kHeapObjectTagSize, which is two bits 510b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org Register offset) { 52812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // We need to scale up the pointer by 2 because the offset is scaled by less 53812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // than the pointer size. 54812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org ASSERT(kPointerSizeLog2 == kHeapObjectTagSize + 1); 55812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org ScaleFactor scale_factor = times_2; 56812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 571510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ASSERT_EQ(3 * kPointerSize, sizeof(StubCache::Entry)); 589d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com // The offset register holds the entry offset times four (due to masking 599d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com // and shifting optimizations). 60ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ExternalReference key_offset(isolate->stub_cache()->key_reference(table)); 61812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org ExternalReference value_offset(isolate->stub_cache()->value_reference(table)); 620b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org Label miss; 630b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 64812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // Multiply by 3 because there are 3 fields per entry (name, code, map). 65812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org __ lea(offset, Operand(offset, offset, times_2, 0)); 66812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 67ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ LoadAddress(kScratchRegister, key_offset); 68812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 690b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // Check that the key in the entry matches the name. 709d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com // Multiply entry offset by 16 to get the entry address. Since the 719d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com // offset register already holds the entry offset times four, multiply 729d58c2b1c27d8b2890b9bd46e57d3842b09e0292christian.plesner.hansen@gmail.com // by a further four. 73812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org __ cmpl(name, Operand(kScratchRegister, offset, scale_factor, 0)); 74812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org __ j(not_equal, &miss); 75812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 76812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // Get the map entry from the cache. 77812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // Use key_offset + kPointerSize * 2, rather than loading map_offset. 78812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org __ movq(kScratchRegister, 79812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Operand(kScratchRegister, offset, scale_factor, kPointerSize * 2)); 80812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org __ cmpq(kScratchRegister, FieldOperand(receiver, HeapObject::kMapOffset)); 810b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org __ j(not_equal, &miss); 82812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 830b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // Get the code entry from the cache. 84812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org __ LoadAddress(kScratchRegister, value_offset); 850b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org __ movq(kScratchRegister, 86812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Operand(kScratchRegister, offset, scale_factor, 0)); 87812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 880b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // Check that the flags match what we're looking for. 890b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org __ movl(offset, FieldOperand(kScratchRegister, Code::kFlagsOffset)); 900b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org __ and_(offset, Immediate(~Code::kFlagsNotUsedInLookup)); 910b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org __ cmpl(offset, Immediate(flags)); 920b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org __ j(not_equal, &miss); 930b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 94812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org#ifdef DEBUG 95812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org if (FLAG_test_secondary_stub_cache && table == StubCache::kPrimary) { 96812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org __ jmp(&miss); 97812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org } else if (FLAG_test_primary_stub_cache && table == StubCache::kSecondary) { 98812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org __ jmp(&miss); 99812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org } 100812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org#endif 101812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 1020b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // Jump to the first instruction in the code stub. 1030b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org __ addq(kScratchRegister, Immediate(Code::kHeaderSize - kHeapObjectTag)); 1040b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org __ jmp(kScratchRegister); 1050b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 1060b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org __ bind(&miss); 1070b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org} 1080b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 1090b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 110057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.orgvoid StubCompiler::GenerateDictionaryNegativeLookup(MacroAssembler* masm, 111057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org Label* miss_label, 112057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org Register receiver, 113057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org Handle<Name> name, 114057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org Register scratch0, 115057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org Register scratch1) { 116750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org ASSERT(name->IsUniqueName()); 117057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org ASSERT(!receiver.is(scratch0)); 118394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Counters* counters = masm->isolate()->counters(); 119394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ IncrementCounter(counters->negative_lookups(), 1); 120394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ IncrementCounter(counters->negative_lookups_miss(), 1); 121394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 122057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org __ movq(scratch0, FieldOperand(receiver, HeapObject::kMapOffset)); 123394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 124394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com const int kInterceptorOrAccessCheckNeededMask = 125394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); 126394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 127394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Bail out if the receiver has a named interceptor or requires access checks. 128057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org __ testb(FieldOperand(scratch0, Map::kBitFieldOffset), 129394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Immediate(kInterceptorOrAccessCheckNeededMask)); 130394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ j(not_zero, miss_label); 131394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 132394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Check that receiver is a JSObject. 133057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org __ CmpInstanceType(scratch0, FIRST_SPEC_OBJECT_TYPE); 134394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ j(below, miss_label); 135394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 136394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Load properties array. 137057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org Register properties = scratch0; 138394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ movq(properties, FieldOperand(receiver, JSObject::kPropertiesOffset)); 139394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 140394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Check that the properties array is a dictionary. 141394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ CompareRoot(FieldOperand(properties, HeapObject::kMapOffset), 142394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Heap::kHashTableMapRootIndex); 143394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ j(not_equal, miss_label); 144394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 145394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Label done; 146750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org NameDictionaryLookupStub::GenerateNegativeLookup(masm, 147750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org miss_label, 148750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org &done, 149750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org properties, 150750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org name, 151057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org scratch1); 152394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ bind(&done); 153394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ DecrementCounter(counters->negative_lookups_miss(), 1); 154394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com} 155394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 156394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1570b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.orgvoid StubCache::GenerateProbe(MacroAssembler* masm, 1580b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org Code::Flags flags, 1590b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org Register receiver, 1600b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org Register name, 1610b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org Register scratch, 162e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org Register extra, 163812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Register extra2, 164812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Register extra3) { 1657979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Isolate* isolate = masm->isolate(); 1660b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org Label miss; 167e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org USE(extra); // The register extra is not used on the X64 platform. 168e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org USE(extra2); // The register extra2 is not used on the X64 platform. 169812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org USE(extra3); // The register extra2 is not used on the X64 platform. 170812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // Make sure that code is valid. The multiplying code relies on the 1711510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org // entry size being 3 * kPointerSize. 1721510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ASSERT(sizeof(Entry) == 3 * kPointerSize); 1730b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 1740b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // Make sure the flags do not name a specific type. 1750b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org ASSERT(Code::ExtractTypeFromFlags(flags) == 0); 1760b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 1770b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // Make sure that there are no register conflicts. 1780b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org ASSERT(!scratch.is(receiver)); 1790b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org ASSERT(!scratch.is(name)); 1800b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 181e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org // Check scratch register is valid, extra and extra2 are unused. 182e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org ASSERT(!scratch.is(no_reg)); 183e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org ASSERT(extra2.is(no_reg)); 184812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org ASSERT(extra3.is(no_reg)); 185812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org 186812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org Counters* counters = masm->isolate()->counters(); 187812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org __ IncrementCounter(counters->megamorphic_stub_cache_probes(), 1); 188e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org 1890b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // Check that the receiver isn't a smi. 1904af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org __ JumpIfSmi(receiver, &miss); 1910b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 1920b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // Get the map of the receiver and compute the hash. 193750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org __ movl(scratch, FieldOperand(name, Name::kHashFieldOffset)); 1940b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // Use only the low 32 bits of the map pointer. 1950b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org __ addl(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); 1960b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org __ xor_(scratch, Immediate(flags)); 197812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // We mask out the last two bits because they are not part of the hash and 198812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org // they are always 01 for maps. Also in the two 'and' instructions below. 1990b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org __ and_(scratch, Immediate((kPrimaryTableSize - 1) << kHeapObjectTagSize)); 2000b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 2010b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // Probe the primary table. 202812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org ProbeTable(isolate, masm, flags, kPrimary, receiver, name, scratch); 2030b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 2040b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // Primary miss: Compute hash for secondary probe. 205750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org __ movl(scratch, FieldOperand(name, Name::kHashFieldOffset)); 2060b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org __ addl(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); 2070b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org __ xor_(scratch, Immediate(flags)); 2080b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org __ and_(scratch, Immediate((kPrimaryTableSize - 1) << kHeapObjectTagSize)); 2090b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org __ subl(scratch, name); 2100b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org __ addl(scratch, Immediate(flags)); 2110b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org __ and_(scratch, Immediate((kSecondaryTableSize - 1) << kHeapObjectTagSize)); 2120b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 2130b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // Probe the secondary table. 214812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org ProbeTable(isolate, masm, flags, kSecondary, receiver, name, scratch); 2150b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 2160b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // Cache miss: Fall-through and let caller handle the miss by 2170b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // entering the runtime system. 2180b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org __ bind(&miss); 219812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org __ IncrementCounter(counters->megamorphic_stub_cache_misses(), 1); 2200b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org} 2210b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 2220b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 2235d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.orgvoid StubCompiler::GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm, 2245d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org int index, 2255d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org Register prototype) { 2265d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Load the global or builtins object from the current context. 2275d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ movq(prototype, 22846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 22946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Load the native context from the global or builtins object. 2305d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ movq(prototype, 23146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org FieldOperand(prototype, GlobalObject::kNativeContextOffset)); 23246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Load the function from the native context. 2335d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ movq(prototype, Operand(prototype, Context::SlotOffset(index))); 2345d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Load the initial map. The global functions all have initial maps. 2355d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ movq(prototype, 23646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org FieldOperand(prototype, JSFunction::kPrototypeOrInitialMapOffset)); 2375d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Load the prototype from the initial map. 2385d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ movq(prototype, FieldOperand(prototype, Map::kPrototypeOffset)); 2395d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org} 2400b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 2410b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 2425d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.orgvoid StubCompiler::GenerateDirectLoadGlobalFunctionPrototype( 243c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org MacroAssembler* masm, 244c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org int index, 245c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register prototype, 246c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label* miss) { 2477979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Isolate* isolate = masm->isolate(); 2485d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Check we're still in the same context. 24946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ Move(prototype, isolate->global_object()); 25046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ cmpq(Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)), 2515d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org prototype); 2525d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ j(not_equal, miss); 2535d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Get the global function with the given index. 254c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSFunction> function( 25546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org JSFunction::cast(isolate->native_context()->get(index))); 2565d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Load its initial map. The global functions all have initial maps. 2575d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ Move(prototype, Handle<Map>(function->initial_map())); 2585d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Load the prototype from the initial map. 2595d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ movq(prototype, FieldOperand(prototype, Map::kPrototypeOffset)); 2600b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org} 2610b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 2620b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 2630b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.orgvoid StubCompiler::GenerateLoadArrayLength(MacroAssembler* masm, 2640b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org Register receiver, 2650b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org Register scratch, 2660b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org Label* miss_label) { 2670b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // Check that the receiver isn't a smi. 2684af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org __ JumpIfSmi(receiver, miss_label); 2690b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 2700b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // Check that the object is a JS array. 2710b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org __ CmpObjectType(receiver, JS_ARRAY_TYPE, scratch); 2720b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org __ j(not_equal, miss_label); 2730b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 2740b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // Load length directly from the JS array. 2750b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org __ movq(rax, FieldOperand(receiver, JSArray::kLengthOffset)); 2760b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org __ ret(0); 2770b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org} 2780b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 2790b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 2800b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org// Generate code to check if an object is a string. If the object is 2810b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org// a string, the map's instance type is left in the scratch register. 2820b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.orgstatic void GenerateStringCheck(MacroAssembler* masm, 2830b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org Register receiver, 2840b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org Register scratch, 2850b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org Label* smi, 2860b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org Label* non_string_object) { 2870b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // Check that the object isn't a smi. 2884af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org __ JumpIfSmi(receiver, smi); 2890b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 2900b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // Check that the object is a string. 2910b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org __ movq(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); 2920b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org __ movzxbq(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); 29380c42ed5ace766a3a02b30a53a25e5e81e234723yangguo@chromium.org STATIC_ASSERT(kNotStringTag != 0); 2940b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org __ testl(scratch, Immediate(kNotStringTag)); 2950b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org __ j(not_zero, non_string_object); 2960b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org} 2970b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 2980b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 2990b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.orgvoid StubCompiler::GenerateLoadStringLength(MacroAssembler* masm, 3000b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org Register receiver, 3015c838251403b0be9a882540f1922577abba4c872ager@chromium.org Register scratch1, 3025c838251403b0be9a882540f1922577abba4c872ager@chromium.org Register scratch2, 303528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Label* miss) { 3045c838251403b0be9a882540f1922577abba4c872ager@chromium.org Label check_wrapper; 3050b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 3060b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // Check if the object is a string leaving the instance type in the 3070b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // scratch register. 308528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org GenerateStringCheck(masm, receiver, scratch1, miss, &check_wrapper); 3090b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 3100b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // Load length directly from the string. 311ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org __ movq(rax, FieldOperand(receiver, String::kLengthOffset)); 3120b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org __ ret(0); 3130b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 314528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Check if the object is a JSValue wrapper. 315528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ bind(&check_wrapper); 316528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ cmpl(scratch1, Immediate(JS_VALUE_TYPE)); 317528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ j(not_equal, miss); 318e76560e31adc252866988b6fed3bba91a0e2855chpayer@chromium.org 319528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Check if the wrapped value is a string and load the length 320528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // directly if it is. 321528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ movq(scratch2, FieldOperand(receiver, JSValue::kValueOffset)); 322528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org GenerateStringCheck(masm, scratch2, scratch1, miss, miss); 323528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ movq(rax, FieldOperand(scratch2, String::kLengthOffset)); 324528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ ret(0); 3250b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org} 3260b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 3270b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 3285d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.orgvoid StubCompiler::GenerateLoadFunctionPrototype(MacroAssembler* masm, 3295d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org Register receiver, 3305d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org Register result, 3315d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org Register scratch, 3325d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org Label* miss_label) { 3335d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ TryGetFunctionPrototype(receiver, result, miss_label); 3345d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org if (!result.is(rax)) __ movq(rax, result); 3355d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ ret(0); 3365d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org} 3375d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 3385d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 33957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.orgvoid StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm, 34057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Register dst, 34157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Register src, 34257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org bool inobject, 34357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org int index, 34457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Representation representation) { 34557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org ASSERT(!FLAG_track_double_fields || !representation.IsDouble()); 3464a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org int offset = index * kPointerSize; 3474a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org if (!inobject) { 3484a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // Calculate the offset into the properties array. 3494a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org offset = offset + FixedArray::kHeaderSize; 3504a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ movq(dst, FieldOperand(src, JSObject::kPropertiesOffset)); 3514a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org src = dst; 3525d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org } 3534a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ movq(dst, FieldOperand(src, offset)); 3545d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org} 3555d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 3565d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 3575d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.orgstatic void PushInterceptorArguments(MacroAssembler* masm, 3585d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org Register receiver, 3595d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org Register holder, 3605d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org Register name, 361c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSObject> holder_obj) { 3624a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org STATIC_ASSERT(StubCache::kInterceptorArgsNameIndex == 0); 3634a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org STATIC_ASSERT(StubCache::kInterceptorArgsInfoIndex == 1); 3644a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org STATIC_ASSERT(StubCache::kInterceptorArgsThisIndex == 2); 3654a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org STATIC_ASSERT(StubCache::kInterceptorArgsHolderIndex == 3); 3664a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org STATIC_ASSERT(StubCache::kInterceptorArgsLength == 4); 3675d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ push(name); 368c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<InterceptorInfo> interceptor(holder_obj->GetNamedInterceptor()); 369c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(!masm->isolate()->heap()->InNewSpace(*interceptor)); 370c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Move(kScratchRegister, interceptor); 3715d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ push(kScratchRegister); 3725d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ push(receiver); 3735d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ push(holder); 3745d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org} 3755d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 3765d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 377c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgstatic void CompileCallLoadPropertyWithInterceptor( 378c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org MacroAssembler* masm, 379c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register receiver, 380c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register holder, 381c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register name, 38237be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org Handle<JSObject> holder_obj, 38337be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org IC::UtilityId id) { 3840b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org PushInterceptorArguments(masm, receiver, holder, name, holder_obj); 38537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org __ CallExternalReference( 38637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org ExternalReference(IC_Utility(id), masm->isolate()), 38737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org StubCache::kInterceptorArgsLength); 3880b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org} 3890b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 3900b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 3914a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// Number of pointers to be reserved on stack for fast API call. 392bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.orgstatic const int kFastApiCallArguments = FunctionCallbackArguments::kArgsLength; 3930b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 3945d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 3954a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// Reserves space for the extra arguments to API function in the 3964111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org// caller's frame. 3974111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org// 3984111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org// These arguments are set by CheckPrototypes and GenerateFastApiCall. 3994111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.orgstatic void ReserveSpaceForFastApiCall(MacroAssembler* masm, Register scratch) { 4004111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org // ----------- S t a t e ------------- 4014111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org // -- rsp[0] : return address 4024111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org // -- rsp[8] : last argument in the internal frame of the caller 4034111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org // ----------------------------------- 404d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org __ movq(scratch, StackOperandForReturnAddress(0)); 4054a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com __ subq(rsp, Immediate(kFastApiCallArguments * kPointerSize)); 406d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org __ movq(StackOperandForReturnAddress(0), scratch); 407ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org __ Move(scratch, Smi::FromInt(0)); 408662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org StackArgumentsAccessor args(rsp, kFastApiCallArguments, 409662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org ARGUMENTS_DONT_CONTAIN_RECEIVER); 410662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org for (int i = 0; i < kFastApiCallArguments; i++) { 411662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org __ movq(args.GetArgumentOperand(i), scratch); 4124a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com } 4134111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org} 4144111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org 4154111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org 4164111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org// Undoes the effects of ReserveSpaceForFastApiCall. 4174111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.orgstatic void FreeSpaceForFastApiCall(MacroAssembler* masm, Register scratch) { 4184111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org // ----------- S t a t e ------------- 419c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org // -- rsp[0] : return address. 420c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org // -- rsp[8] : last fast api call extra argument. 4214111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org // -- ... 422c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org // -- rsp[kFastApiCallArguments * 8] : first fast api call extra 423c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org // argument. 4244a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com // -- rsp[kFastApiCallArguments * 8 + 8] : last argument in the internal 4254a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com // frame. 4264111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org // ----------------------------------- 427d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org __ movq(scratch, StackOperandForReturnAddress(0)); 428d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org __ movq(StackOperandForReturnAddress(kFastApiCallArguments * kPointerSize), 429d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org scratch); 4304a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com __ addq(rsp, Immediate(kPointerSize * kFastApiCallArguments)); 4314111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org} 4324111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org 4334111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org 4347ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.orgstatic void GenerateFastApiCallBody(MacroAssembler* masm, 4357ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org const CallOptimization& optimization, 4367ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org int argc, 4377ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org bool restore_context); 4387ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org 4397ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org 4404a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com// Generates call to API function. 441c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgstatic void GenerateFastApiCall(MacroAssembler* masm, 442c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org const CallOptimization& optimization, 4437ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org int argc) { 444cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org typedef FunctionCallbackArguments FCA; 445cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org StackArgumentsAccessor args(rsp, argc + kFastApiCallArguments); 446528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 447528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Save calling context. 448fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org int offset = argc + kFastApiCallArguments; 449fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org __ movq(args.GetArgumentOperand(offset - FCA::kContextSaveIndex), rsi); 450528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 4514111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org // Get the function and setup the context. 452c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSFunction> function = optimization.constant_function(); 453c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ Move(rdi, function); 4544111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); 455cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org // Construct the FunctionCallbackInfo on the stack. 456fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org __ movq(args.GetArgumentOperand(offset - FCA::kCalleeIndex), rdi); 457c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); 45809d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org Handle<Object> call_data(api_call_info->data(), masm->isolate()); 459c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (masm->isolate()->heap()->InNewSpace(*call_data)) { 460c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Move(rcx, api_call_info); 4614111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org __ movq(rbx, FieldOperand(rcx, CallHandlerInfo::kDataOffset)); 462fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org __ movq(args.GetArgumentOperand(offset - FCA::kDataIndex), rbx); 4634111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org } else { 464fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org __ Move(args.GetArgumentOperand(offset - FCA::kDataIndex), call_data); 4654111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org } 466e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ Move(kScratchRegister, 46732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org ExternalReference::isolate_address(masm->isolate())); 468fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org __ movq(args.GetArgumentOperand(offset - FCA::kIsolateIndex), 469cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org kScratchRegister); 470528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex); 471fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org __ movq(args.GetArgumentOperand(offset - FCA::kReturnValueDefaultValueIndex), 472fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org kScratchRegister); 473fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org __ movq(args.GetArgumentOperand(offset - FCA::kReturnValueOffset), 474cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org kScratchRegister); 4754111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org 4764a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com // Prepare arguments. 477528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org STATIC_ASSERT(kFastApiCallArguments == 7); 4787ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org __ lea(rax, Operand(rsp, 1 * kPointerSize)); 4797ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org 4807ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org GenerateFastApiCallBody(masm, optimization, argc, false); 4817ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org} 4827ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org 4837ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org 4847ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org// Generate call to api function. 4857ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org// This function uses push() to generate smaller, faster code than 4867ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org// the version above. It is an optimization that should will be removed 4877ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org// when api call ICs are generated in hydrogen. 4887ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.orgstatic void GenerateFastApiCall(MacroAssembler* masm, 4897ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org const CallOptimization& optimization, 4907ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org Register receiver, 4917ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org Register scratch1, 4927ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org Register scratch2, 4937ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org Register scratch3, 4947ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org int argc, 4957ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org Register* values) { 4967ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org ASSERT(optimization.is_simple_api_call()); 4977ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org 4987ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org // Copy return value. 4997ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org __ pop(scratch1); 5007ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org 5017ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org // receiver 5027ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org __ push(receiver); 5037ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org 5047ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org // Write the arguments to stack frame. 5057ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org for (int i = 0; i < argc; i++) { 5067ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org Register arg = values[argc-1-i]; 5077ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org ASSERT(!receiver.is(arg)); 5087ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org ASSERT(!scratch1.is(arg)); 5097ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org ASSERT(!scratch2.is(arg)); 5107ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org ASSERT(!scratch3.is(arg)); 5117ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org __ push(arg); 5127ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org } 5137ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org 5147ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org typedef FunctionCallbackArguments FCA; 5157ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org 5167ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org STATIC_ASSERT(FCA::kHolderIndex == 0); 5177ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org STATIC_ASSERT(FCA::kIsolateIndex == 1); 5187ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2); 5197ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org STATIC_ASSERT(FCA::kReturnValueOffset == 3); 5207ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org STATIC_ASSERT(FCA::kDataIndex == 4); 5217ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org STATIC_ASSERT(FCA::kCalleeIndex == 5); 5227ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org STATIC_ASSERT(FCA::kContextSaveIndex == 6); 5237ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org STATIC_ASSERT(FCA::kArgsLength == 7); 5247ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org 5257ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org // context save 5267ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org __ push(rsi); 5277ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org 5287ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org // Get the function and setup the context. 5297ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org Handle<JSFunction> function = optimization.constant_function(); 5307ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org __ Move(scratch2, function); 5317ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org __ push(scratch2); 5327ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org 5337ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org Isolate* isolate = masm->isolate(); 5347ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); 5357ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org Handle<Object> call_data(api_call_info->data(), isolate); 5367ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org // Push data from ExecutableAccessorInfo. 5377ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org bool call_data_undefined = false; 5387ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org if (isolate->heap()->InNewSpace(*call_data)) { 5397ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org __ Move(scratch2, api_call_info); 5407ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org __ movq(scratch3, FieldOperand(scratch2, CallHandlerInfo::kDataOffset)); 5417ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org } else if (call_data->IsUndefined()) { 5427ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org call_data_undefined = true; 5437ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org __ LoadRoot(scratch3, Heap::kUndefinedValueRootIndex); 5447ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org } else { 5457ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org __ Move(scratch3, call_data); 5467ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org } 5477ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org // call data 5487ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org __ push(scratch3); 5497ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org if (!call_data_undefined) { 5507ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org __ LoadRoot(scratch3, Heap::kUndefinedValueRootIndex); 5517ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org } 5527ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org // return value 5537ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org __ push(scratch3); 5547ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org // return value default 5557ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org __ push(scratch3); 5567ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org // isolate 5577ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org __ Move(scratch3, 5587ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org ExternalReference::isolate_address(masm->isolate())); 5597ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org __ push(scratch3); 5607ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org // holder 5617ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org __ push(receiver); 5627ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org 5637ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org ASSERT(!scratch1.is(rax)); 5647ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org // store receiver address for GenerateFastApiCallBody 5657ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org __ movq(rax, rsp); 566bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org 5677ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org // return address 5687ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org __ push(scratch1); 5697ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org 5707ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org GenerateFastApiCallBody(masm, optimization, argc, true); 5717ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org} 5727ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org 5737ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org 5747ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.orgstatic void GenerateFastApiCallBody(MacroAssembler* masm, 5757ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org const CallOptimization& optimization, 5767ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org int argc, 5777ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org bool restore_context) { 5787ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org // ----------- S t a t e ------------- 5797ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org // -- rsp[0] : return address 5807ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org // -- rsp[8] - rsp[56] : FunctionCallbackInfo, incl. 5817ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org // : object passing the type check 5827ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org // (set by CheckPrototypes) 5837ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org // -- rsp[64] : last argument 5847ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org // -- ... 5857ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org // -- rsp[(argc + 7) * 8] : first argument 5867ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org // -- rsp[(argc + 8) * 8] : receiver 5877ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org // 5887ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org // rax : receiver address 5897ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org // ----------------------------------- 5907ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org typedef FunctionCallbackArguments FCA; 5917ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org 5927ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); 593bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org // Function address is a foreign pointer outside V8's heap. 594bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org Address function_address = v8::ToCData<Address>(api_call_info->callback()); 5954111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org 5964a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com // Allocate the v8::Arguments structure in the arguments' space since 5974a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com // it's not controlled by GC. 5984a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com const int kApiStackSpace = 4; 5994a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 600662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org __ PrepareCallApiFunction(kApiStackSpace); 6014a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 6027ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org __ movq(StackSpaceOperand(0), rax); // FunctionCallbackInfo::implicit_args_. 6037ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org __ addq(rax, Immediate((argc + kFastApiCallArguments - 1) * kPointerSize)); 6047ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org __ movq(StackSpaceOperand(1), rax); // FunctionCallbackInfo::values_. 605fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org __ Set(StackSpaceOperand(2), argc); // FunctionCallbackInfo::length_. 606fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org // FunctionCallbackInfo::is_construct_call_. 6074a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com __ Set(StackSpaceOperand(3), 0); 6084a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com 609528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org#if defined(__MINGW64__) || defined(_WIN64) 610528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Register arguments_arg = rcx; 611528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Register callback_arg = rdx; 612528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org#else 613528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Register arguments_arg = rdi; 614528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Register callback_arg = rsi; 615528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org#endif 616528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org 6174a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com // v8::InvocationCallback's argument. 6184a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com __ lea(arguments_arg, StackSpaceOperand(0)); 619c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org 620662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback); 621b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 622d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org StackArgumentsAccessor args_from_rbp(rbp, kFastApiCallArguments, 623d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org ARGUMENTS_DONT_CONTAIN_RECEIVER); 624d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Operand context_restore_operand = args_from_rbp.GetArgumentOperand( 625d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org kFastApiCallArguments - 1 - FCA::kContextSaveIndex); 626d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Operand return_value_operand = args_from_rbp.GetArgumentOperand( 627d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org kFastApiCallArguments - 1 - FCA::kReturnValueOffset); 628cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org __ CallApiFunctionAndReturn( 629cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org function_address, 630cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org thunk_address, 631cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org callback_arg, 632cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org argc + kFastApiCallArguments + 1, 633cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org return_value_operand, 634cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org restore_context ? &context_restore_operand : NULL); 6354111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org} 6364111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org 6374111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org 6380b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.orgclass CallInterceptorCompiler BASE_EMBEDDED { 6390b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org public: 6408a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org CallInterceptorCompiler(CallStubCompiler* stub_compiler, 6414111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org const ParameterCount& arguments, 642d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org Register name, 643cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org ExtraICState extra_ic_state) 6444111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org : stub_compiler_(stub_compiler), 6454111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org arguments_(arguments), 646d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org name_(name), 647d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org extra_ic_state_(extra_ic_state) {} 6484111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org 649c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org void Compile(MacroAssembler* masm, 650c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSObject> object, 651c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSObject> holder, 652750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Handle<Name> name, 653c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LookupResult* lookup, 654c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register receiver, 655c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register scratch1, 656c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register scratch2, 657c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register scratch3, 658c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label* miss) { 6594111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org ASSERT(holder->HasNamedInterceptor()); 6604111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined()); 6614111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org 6624111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org // Check that the receiver isn't a smi. 6634111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org __ JumpIfSmi(receiver, miss); 6644111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org 6654111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org CallOptimization optimization(lookup); 6664111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org if (optimization.is_constant_call()) { 667c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org CompileCacheable(masm, object, receiver, scratch1, scratch2, scratch3, 668c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org holder, lookup, name, optimization, miss); 6694111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org } else { 670c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org CompileRegular(masm, object, receiver, scratch1, scratch2, scratch3, 671c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org name, holder, miss); 6724111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org } 6734111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org } 6740b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 6754111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org private: 676c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org void CompileCacheable(MacroAssembler* masm, 677c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSObject> object, 678c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register receiver, 679c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register scratch1, 680c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register scratch2, 681c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register scratch3, 682c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSObject> interceptor_holder, 683c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LookupResult* lookup, 684750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Handle<Name> name, 685c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org const CallOptimization& optimization, 686c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label* miss_label) { 6874111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org ASSERT(optimization.is_constant_call()); 6884111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org ASSERT(!lookup->holder()->IsGlobalObject()); 6894111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org 6904111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org int depth1 = kInvalidProtoDepth; 6914111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org int depth2 = kInvalidProtoDepth; 6924111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org bool can_do_fast_api_call = false; 6934111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org if (optimization.is_simple_api_call() && 6944111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org !lookup->holder()->IsGlobalObject()) { 695c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org depth1 = optimization.GetPrototypeDepthOfExpectedType( 696c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org object, interceptor_holder); 6974111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org if (depth1 == kInvalidProtoDepth) { 698c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org depth2 = optimization.GetPrototypeDepthOfExpectedType( 699c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org interceptor_holder, Handle<JSObject>(lookup->holder())); 7000b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org } 701c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org can_do_fast_api_call = 702c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org depth1 != kInvalidProtoDepth || depth2 != kInvalidProtoDepth; 7030b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org } 7040b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 7057979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org Counters* counters = masm->isolate()->counters(); 7067979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ IncrementCounter(counters->call_const_interceptor(), 1); 7074111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org 7084111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org if (can_do_fast_api_call) { 7097979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ IncrementCounter(counters->call_const_interceptor_fast_api(), 1); 7104111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org ReserveSpaceForFastApiCall(masm, scratch1); 7110b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org } 7120b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 7139155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org // Check that the maps from receiver to interceptor's holder 7149155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org // haven't changed and thus we can invoke interceptor. 7154111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org Label miss_cleanup; 7164111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org Label* miss = can_do_fast_api_call ? &miss_cleanup : miss_label; 7174111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org Register holder = 718f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org stub_compiler_->CheckPrototypes( 719f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org IC::CurrentTypeOf(object, masm->isolate()), receiver, 720f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org interceptor_holder, scratch1, scratch2, scratch3, 721f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org name, depth1, miss); 7225c838251403b0be9a882540f1922577abba4c872ager@chromium.org 7239155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org // Invoke an interceptor and if it provides a value, 7249155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org // branch to |regular_invoke|. 7254111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org Label regular_invoke; 7269155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org LoadWithInterceptor(masm, receiver, holder, interceptor_holder, 7279155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org ®ular_invoke); 7280b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 7299155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org // Interceptor returned nothing for this property. Try to use cached 7309155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org // constant function. 7310b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 7329155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org // Check that the maps from interceptor's holder to constant function's 7339155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org // holder haven't changed and thus we can use cached constant function. 734c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (*interceptor_holder != lookup->holder()) { 735f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org stub_compiler_->CheckPrototypes( 7362c45addeb1788c63746dd1ba81bf801951ac8e3bverwaest@chromium.org IC::CurrentTypeOf(interceptor_holder, masm->isolate()), holder, 737f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org handle(lookup->holder()), scratch1, scratch2, scratch3, 738f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org name, depth2, miss); 73930ce411529579186181838984710b0b0980857aaricow@chromium.org } else { 74030ce411529579186181838984710b0b0980857aaricow@chromium.org // CheckPrototypes has a side effect of fetching a 'holder' 74130ce411529579186181838984710b0b0980857aaricow@chromium.org // for API (object which is instanceof for the signature). It's 74230ce411529579186181838984710b0b0980857aaricow@chromium.org // safe to omit it here, as if present, it should be fetched 74330ce411529579186181838984710b0b0980857aaricow@chromium.org // by the previous CheckPrototypes. 74430ce411529579186181838984710b0b0980857aaricow@chromium.org ASSERT(depth2 == kInvalidProtoDepth); 74530ce411529579186181838984710b0b0980857aaricow@chromium.org } 7460b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 7479155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org // Invoke function. 7484111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org if (can_do_fast_api_call) { 7497ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org GenerateFastApiCall(masm, optimization, arguments_.immediate()); 7504111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org } else { 75132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Handle<JSFunction> fun = optimization.constant_function(); 7522c45addeb1788c63746dd1ba81bf801951ac8e3bverwaest@chromium.org stub_compiler_->GenerateJumpFunction(object, fun); 7534111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org } 7540b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 7559155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org // Deferred code for fast API call case---clean preallocated space. 7564111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org if (can_do_fast_api_call) { 7574111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org __ bind(&miss_cleanup); 7584111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org FreeSpaceForFastApiCall(masm, scratch1); 7594111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org __ jmp(miss_label); 7604111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org } 7610b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 7629155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org // Invoke a regular function. 7634111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org __ bind(®ular_invoke); 7644111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org if (can_do_fast_api_call) { 7654111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org FreeSpaceForFastApiCall(masm, scratch1); 7664111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org } 7670b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org } 7680b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 7690b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org void CompileRegular(MacroAssembler* masm, 770c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSObject> object, 7710b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org Register receiver, 7724111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org Register scratch1, 7734111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org Register scratch2, 7746a2b0aa331a1ae1829a9b9637ad18cfc7ec9d840ager@chromium.org Register scratch3, 775750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Handle<Name> name, 776c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSObject> interceptor_holder, 7770b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org Label* miss_label) { 7784111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org Register holder = 779f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org stub_compiler_->CheckPrototypes( 780f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org IC::CurrentTypeOf(object, masm->isolate()), receiver, 781f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org interceptor_holder, scratch1, scratch2, scratch3, name, miss_label); 7824111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org 783c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FrameScope scope(masm, StackFrame::INTERNAL); 7845c838251403b0be9a882540f1922577abba4c872ager@chromium.org // Save the name_ register across the call. 7855c838251403b0be9a882540f1922577abba4c872ager@chromium.org __ push(name_); 7860b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 78737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org CompileCallLoadPropertyWithInterceptor( 78837be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org masm, receiver, holder, name_, interceptor_holder, 78937be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org IC::kLoadPropertyWithInterceptorForCall); 7900b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 7914111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org // Restore the name_ register. 7925c838251403b0be9a882540f1922577abba4c872ager@chromium.org __ pop(name_); 793c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 794c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Leave the internal frame. 7950b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org } 7960b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 7974111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org void LoadWithInterceptor(MacroAssembler* masm, 7984111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org Register receiver, 7994111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org Register holder, 800c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSObject> holder_obj, 8014111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org Label* interceptor_succeeded) { 802c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com { 803c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FrameScope scope(masm, StackFrame::INTERNAL); 8042c45addeb1788c63746dd1ba81bf801951ac8e3bverwaest@chromium.org __ push(receiver); 8052c45addeb1788c63746dd1ba81bf801951ac8e3bverwaest@chromium.org __ push(holder); 8062c45addeb1788c63746dd1ba81bf801951ac8e3bverwaest@chromium.org __ push(name_); 807c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 80837be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org CompileCallLoadPropertyWithInterceptor( 80937be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org masm, receiver, holder, name_, holder_obj, 81037be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org IC::kLoadPropertyWithInterceptorOnly); 811c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 8122c45addeb1788c63746dd1ba81bf801951ac8e3bverwaest@chromium.org __ pop(name_); 8132c45addeb1788c63746dd1ba81bf801951ac8e3bverwaest@chromium.org __ pop(holder); 8142c45addeb1788c63746dd1ba81bf801951ac8e3bverwaest@chromium.org __ pop(receiver); 815c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Leave the internal frame. 816c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 8174111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org 8184111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org __ CompareRoot(rax, Heap::kNoInterceptorResultSentinelRootIndex); 8194111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org __ j(not_equal, interceptor_succeeded); 8204111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org } 8214111b80e5083e1ec54273d3275875ccc24cdbbafkmillikin@chromium.org 8228a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org CallStubCompiler* stub_compiler_; 8230b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org const ParameterCount& arguments_; 8245c838251403b0be9a882540f1922577abba4c872ager@chromium.org Register name_; 825cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org ExtraICState extra_ic_state_; 8260b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org}; 8270b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 8280b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 8292efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgvoid StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm, 8302efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Label* label, 8312efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Handle<Name> name) { 8322bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org if (!label->is_unused()) { 8332bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org __ bind(label); 8342bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org __ Move(this->name(), name); 8352bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org } 836ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org} 837ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 838ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 839057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.orgvoid StubCompiler::GenerateCheckPropertyCell(MacroAssembler* masm, 840057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org Handle<JSGlobalObject> global, 841057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org Handle<Name> name, 842057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org Register scratch, 843057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org Label* miss) { 844b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Handle<PropertyCell> cell = 845057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org JSGlobalObject::EnsurePropertyCell(global, name); 846e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(cell->value()->IsTheHole()); 847e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ Move(scratch, cell); 84841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org __ Cmp(FieldOperand(scratch, Cell::kValueOffset), 849e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org masm->isolate()->factory()->the_hole_value()); 850e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ j(not_equal, miss); 851e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 852e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 853e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 8542efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgvoid StoreStubCompiler::GenerateNegativeHolderLookup( 855bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org MacroAssembler* masm, 856bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org Handle<JSObject> holder, 857bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org Register holder_reg, 858bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org Handle<Name> name, 859bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org Label* miss) { 860bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org if (holder->IsJSGlobalObject()) { 861bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org GenerateCheckPropertyCell( 862057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org masm, Handle<JSGlobalObject>::cast(holder), name, scratch1(), miss); 863bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { 864bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org GenerateDictionaryNegativeLookup( 865bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org masm, miss, holder_reg, name, scratch1(), scratch2()); 8667028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org } 867bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org} 8687028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 869bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 870bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// Receiver_reg is preserved on jumps to miss_label, but may be destroyed if 871bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org// store is successful. 8722efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgvoid StoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm, 8732efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Handle<JSObject> object, 8742efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org LookupResult* lookup, 8752efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Handle<Map> transition, 8762efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Handle<Name> name, 8772efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Register receiver_reg, 8782efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Register storage_reg, 8792efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Register value_reg, 8802efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Register scratch1, 8812efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Register scratch2, 8822efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Register unused, 8832efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Label* miss_label, 8842efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Label* slow) { 885f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org int descriptor = transition->LastAdded(); 886f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org DescriptorArray* descriptors = transition->instance_descriptors(); 887f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org PropertyDetails details = descriptors->GetDetails(descriptor); 888f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org Representation representation = details.representation(); 889f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org ASSERT(!representation.IsNone()); 890f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 891fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org if (details.type() == CONSTANT) { 892fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org Handle<Object> constant(descriptors->GetValue(descriptor), masm->isolate()); 893c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ Cmp(value_reg, constant); 894bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org __ j(not_equal, miss_label); 895b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org } else if (FLAG_track_fields && representation.IsSmi()) { 896bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org __ JumpIfNotSmi(value_reg, miss_label); 897906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { 898bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org __ JumpIfSmi(value_reg, miss_label); 89957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } else if (FLAG_track_double_fields && representation.IsDouble()) { 90057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Label do_store, heap_number; 90157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ AllocateHeapNumber(storage_reg, scratch1, slow); 90257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 90357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ JumpIfNotSmi(value_reg, &heap_number); 90457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ SmiToInteger32(scratch1, value_reg); 905528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ Cvtlsi2sd(xmm0, scratch1); 90657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ jmp(&do_store); 90757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 90857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ bind(&heap_number); 90957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(), 910bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org miss_label, DONT_DO_SMI_CHECK); 91157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset)); 91257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 91357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ bind(&do_store); 91457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ movsd(FieldOperand(storage_reg, HeapNumber::kValueOffset), xmm0); 91557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } 91657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 9175d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Stub never generated for non-global objects that require access 9185d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // checks. 9195d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 9205d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 9215d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Perform map transition for the receiver if necessary. 922b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org if (details.type() == FIELD && 923b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org object->map()->unused_property_fields() == 0) { 9245d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // The properties must be extended before we can store the value. 9255d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // We jump to a runtime call that extends the properties array. 926594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ PopReturnAddressTo(scratch1); 9275d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ push(receiver_reg); 928394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Push(transition); 9292bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org __ push(value_reg); 930594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ PushReturnAddressFrom(scratch1); 9315d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ TailCallExternalReference( 932ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), 933ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org masm->isolate()), 934ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 3, 935ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 1); 9365d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org return; 9375d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org } 9385d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 939e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Update the map of the object. 940e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ Move(scratch1, transition); 941e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ movq(FieldOperand(receiver_reg, HeapObject::kMapOffset), scratch1); 942e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 94357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org // Update the write barrier for the map field. 944e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ RecordWriteField(receiver_reg, 945e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org HeapObject::kMapOffset, 946e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org scratch1, 94757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org scratch2, 948e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org kDontSaveFPRegs, 949e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org OMIT_REMEMBERED_SET, 950e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org OMIT_SMI_CHECK); 951e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 952fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org if (details.type() == CONSTANT) { 953b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org ASSERT(value_reg.is(rax)); 954b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ ret(0); 955b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org return; 956b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org } 957b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 958e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org int index = transition->instance_descriptors()->GetFieldIndex( 959e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org transition->LastAdded()); 9605d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 9615d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Adjust for the number of properties stored in the object. Even in the 9625d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // face of a transition we can use the old map here because the size of the 9635d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // object and the number of in-object properties is not going to change. 9645d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org index -= object->map()->inobject_properties(); 9655d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 966e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // TODO(verwaest): Share this code as a code stub. 967a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org SmiCheck smi_check = representation.IsTagged() 968a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org ? INLINE_SMI_CHECK : OMIT_SMI_CHECK; 9695d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org if (index < 0) { 9705d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Set the property straight into the object. 9715d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org int offset = object->map()->instance_size() + (index * kPointerSize); 97257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org if (FLAG_track_double_fields && representation.IsDouble()) { 97357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ movq(FieldOperand(receiver_reg, offset), storage_reg); 97457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } else { 97557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ movq(FieldOperand(receiver_reg, offset), value_reg); 97657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } 9775d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 978f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org if (!FLAG_track_fields || !representation.IsSmi()) { 979f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org // Update the write barrier for the array address. 98057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org if (!FLAG_track_double_fields || !representation.IsDouble()) { 981bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org __ movq(storage_reg, value_reg); 98257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } 983f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ RecordWriteField( 984bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org receiver_reg, offset, storage_reg, scratch1, kDontSaveFPRegs, 985a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org EMIT_REMEMBERED_SET, smi_check); 986f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } 9875d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org } else { 9885d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Write to the properties array. 9895d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org int offset = index * kPointerSize + FixedArray::kHeaderSize; 9905d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Get the properties array (optimistically). 9917028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org __ movq(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); 99257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org if (FLAG_track_double_fields && representation.IsDouble()) { 99357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ movq(FieldOperand(scratch1, offset), storage_reg); 99457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } else { 99557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ movq(FieldOperand(scratch1, offset), value_reg); 99657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } 9975d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 998f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org if (!FLAG_track_fields || !representation.IsSmi()) { 999f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org // Update the write barrier for the array address. 100057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org if (!FLAG_track_double_fields || !representation.IsDouble()) { 1001bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org __ movq(storage_reg, value_reg); 100257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } 1003f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ RecordWriteField( 1004bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org scratch1, offset, storage_reg, receiver_reg, kDontSaveFPRegs, 1005a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org EMIT_REMEMBERED_SET, smi_check); 1006f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } 10075d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org } 10085d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 10095d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Return the value (register rax). 10102bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org ASSERT(value_reg.is(rax)); 10115d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ ret(0); 10125d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org} 10135d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 10145d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 1015e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// Both name_reg and receiver_reg are preserved on jumps to miss_label, 1016e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// but may be destroyed if store is successful. 10172efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgvoid StoreStubCompiler::GenerateStoreField(MacroAssembler* masm, 10182efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Handle<JSObject> object, 10192efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org LookupResult* lookup, 10202efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Register receiver_reg, 10212efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Register name_reg, 10222efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Register value_reg, 10232efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Register scratch1, 10242efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Register scratch2, 10252efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Label* miss_label) { 1026e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Stub never generated for non-global objects that require access 1027e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // checks. 1028e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 1029e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 1030e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org int index = lookup->GetFieldIndex().field_index(); 1031e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 1032e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Adjust for the number of properties stored in the object. Even in the 1033e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // face of a transition we can use the old map here because the size of the 1034e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // object and the number of in-object properties is not going to change. 1035e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org index -= object->map()->inobject_properties(); 1036e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 1037f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org Representation representation = lookup->representation(); 1038f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org ASSERT(!representation.IsNone()); 1039f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org if (FLAG_track_fields && representation.IsSmi()) { 1040f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ JumpIfNotSmi(value_reg, miss_label); 1041906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { 1042906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org __ JumpIfSmi(value_reg, miss_label); 1043f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } else if (FLAG_track_double_fields && representation.IsDouble()) { 104457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org // Load the double storage. 104557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org if (index < 0) { 104657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org int offset = object->map()->instance_size() + (index * kPointerSize); 104757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ movq(scratch1, FieldOperand(receiver_reg, offset)); 104857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } else { 104957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ movq(scratch1, 105057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); 105157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org int offset = index * kPointerSize + FixedArray::kHeaderSize; 105257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ movq(scratch1, FieldOperand(scratch1, offset)); 105357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } 105457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 105557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org // Store the value into the storage. 105657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Label do_store, heap_number; 105757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ JumpIfNotSmi(value_reg, &heap_number); 105857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ SmiToInteger32(scratch2, value_reg); 1059528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ Cvtlsi2sd(xmm0, scratch2); 106057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ jmp(&do_store); 106157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 106257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ bind(&heap_number); 1063f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(), 1064a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org miss_label, DONT_DO_SMI_CHECK); 106557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset)); 1066f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ bind(&do_store); 106757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ movsd(FieldOperand(scratch1, HeapNumber::kValueOffset), xmm0); 106857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org // Return the value (register rax). 106957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org ASSERT(value_reg.is(rax)); 107057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ ret(0); 107157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org return; 1072f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } 1073f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 1074e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // TODO(verwaest): Share this code as a code stub. 1075a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org SmiCheck smi_check = representation.IsTagged() 1076a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org ? INLINE_SMI_CHECK : OMIT_SMI_CHECK; 1077e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (index < 0) { 1078e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Set the property straight into the object. 1079e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org int offset = object->map()->instance_size() + (index * kPointerSize); 1080e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ movq(FieldOperand(receiver_reg, offset), value_reg); 1081e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 1082f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org if (!FLAG_track_fields || !representation.IsSmi()) { 1083f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org // Update the write barrier for the array address. 1084f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org // Pass the value being stored in the now unused name_reg. 1085f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ movq(name_reg, value_reg); 1086f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ RecordWriteField( 1087a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org receiver_reg, offset, name_reg, scratch1, kDontSaveFPRegs, 1088a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org EMIT_REMEMBERED_SET, smi_check); 1089f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } 1090e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } else { 1091e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Write to the properties array. 1092e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org int offset = index * kPointerSize + FixedArray::kHeaderSize; 1093e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Get the properties array (optimistically). 1094e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ movq(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); 1095e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ movq(FieldOperand(scratch1, offset), value_reg); 1096e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 1097f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org if (!FLAG_track_fields || !representation.IsSmi()) { 1098f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org // Update the write barrier for the array address. 1099f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org // Pass the value being stored in the now unused name_reg. 1100f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ movq(name_reg, value_reg); 1101f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ RecordWriteField( 1102a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org scratch1, offset, name_reg, receiver_reg, kDontSaveFPRegs, 1103a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org EMIT_REMEMBERED_SET, smi_check); 1104f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } 1105e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 1106e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 1107e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Return the value (register rax). 1108e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(value_reg.is(rax)); 1109e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ ret(0); 1110394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com} 1111394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1112394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 11132bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.orgvoid StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) { 11144a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ jmp(code, RelocInfo::CODE_TARGET); 11154a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org} 11164a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 11174a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 11182bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org#undef __ 11192bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org#define __ ACCESS_MASM((masm())) 11202bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org 11212bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org 1122f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.orgRegister StubCompiler::CheckPrototypes(Handle<Type> type, 1123394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Register object_reg, 1124394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Handle<JSObject> holder, 1125394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Register holder_reg, 1126394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Register scratch1, 1127394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Register scratch2, 1128750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Handle<Name> name, 1129394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com int save_at_depth, 11304a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Label* miss, 11314a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org PrototypeCheckType check) { 1132f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Handle<Map> receiver_map(IC::TypeToMap(*type, isolate())); 1133ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org // Make sure that the type feedback oracle harvests the receiver map. 1134ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org // TODO(svenpanne) Remove this hack when all ICs are reworked. 1135f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org __ Move(scratch1, receiver_map); 1136ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 1137394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Make sure there's no overlap between holder and object registers. 1138394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); 1139394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) 1140394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com && !scratch2.is(scratch1)); 1141394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1142394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Keep track of the current object in register reg. On the first 1143394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // iteration, reg is an alias for object_reg, on later iterations, 1144394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // it is an alias for holder_reg. 1145394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Register reg = object_reg; 1146394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com int depth = 0; 1147394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1148d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org StackArgumentsAccessor args(rsp, kFastApiCallArguments, 1149d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org ARGUMENTS_DONT_CONTAIN_RECEIVER); 1150d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org const int kHolderIndex = kFastApiCallArguments - 1 - 1151d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org FunctionCallbackArguments::kHolderIndex; 1152d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 1153394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (save_at_depth == depth) { 1154d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org __ movq(args.GetArgumentOperand(kHolderIndex), object_reg); 1155394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 1156394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1157f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Handle<JSObject> current = Handle<JSObject>::null(); 1158f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org if (type->IsConstant()) current = Handle<JSObject>::cast(type->AsConstant()); 1159f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Handle<JSObject> prototype = Handle<JSObject>::null(); 1160f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Handle<Map> current_map = receiver_map; 1161f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Handle<Map> holder_map(holder->map()); 1162f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org // Traverse the prototype chain and check the maps in the prototype chain for 1163f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org // fast and global objects or do negative lookup for normal objects. 1164f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org while (!current_map.is_identical_to(holder_map)) { 1165394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ++depth; 1166394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1167394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Only global objects and objects that do not require access 1168394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // checks are allowed in stubs. 1169f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org ASSERT(current_map->IsJSGlobalProxyMap() || 1170f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org !current_map->is_access_check_needed()); 1171394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1172f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org prototype = handle(JSObject::cast(current_map->prototype())); 1173f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org if (current_map->is_dictionary_map() && 1174f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org !current_map->IsJSGlobalObjectMap() && 1175f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org !current_map->IsJSGlobalProxyMap()) { 1176750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org if (!name->IsUniqueName()) { 1177750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org ASSERT(name->IsString()); 1178750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org name = factory()->InternalizeString(Handle<String>::cast(name)); 1179394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 1180f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org ASSERT(current.is_null() || 1181f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org current->property_dictionary()->FindEntry(*name) == 1182750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org NameDictionary::kNotFound); 1183394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1184394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com GenerateDictionaryNegativeLookup(masm(), miss, reg, name, 1185394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com scratch1, scratch2); 1186394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1187394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); 1188394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com reg = holder_reg; // From now on the object will be in holder_reg. 1189394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); 1190394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } else { 1191394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com bool in_new_space = heap()->InNewSpace(*prototype); 1192394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (in_new_space) { 1193394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Save the map in scratch1 for later. 1194394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ movq(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); 1195394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 1196f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org if (depth != 1 || check == CHECK_ALL_MAPS) { 1197a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ CheckMap(reg, current_map, miss, DONT_DO_SMI_CHECK); 11984a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org } 1199f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com 1200394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Check access rights to the global object. This has to happen after 1201394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // the map check so that we know that the object is actually a global 1202394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // object. 1203f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org if (current_map->IsJSGlobalProxyMap()) { 1204394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ CheckAccessGlobalProxy(reg, scratch2, miss); 1205f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org } else if (current_map->IsJSGlobalObjectMap()) { 1206f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org GenerateCheckPropertyCell( 1207f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org masm(), Handle<JSGlobalObject>::cast(current), name, 1208f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org scratch2, miss); 1209394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 1210394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com reg = holder_reg; // From now on the object will be in holder_reg. 1211394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1212394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (in_new_space) { 1213394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // The prototype is in new space; we cannot store a reference to it 1214394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // in the code. Load it from the map. 1215394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ movq(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); 1216394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } else { 1217394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // The prototype is in old space; load it directly. 1218394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Move(reg, prototype); 1219394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 1220394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 1221394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1222394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (save_at_depth == depth) { 1223d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org __ movq(args.GetArgumentOperand(kHolderIndex), reg); 1224394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 1225394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1226394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Go to the next object in the prototype chain. 1227394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com current = prototype; 1228f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org current_map = handle(current->map()); 1229394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 1230394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1231394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Log the check depth. 1232394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); 1233394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1234f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org if (depth != 0 || check == CHECK_ALL_MAPS) { 12354a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // Check the holder map. 1236f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org __ CheckMap(reg, current_map, miss, DONT_DO_SMI_CHECK); 12374a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org } 1238394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1239394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Perform security check for access to the global object. 1240f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org ASSERT(current_map->IsJSGlobalProxyMap() || 1241f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org !current_map->is_access_check_needed()); 1242f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org if (current_map->IsJSGlobalProxyMap()) { 1243394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ CheckAccessGlobalProxy(reg, scratch1, miss); 1244394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 1245394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1246394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Return the register containing the holder. 1247394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com return reg; 1248394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com} 1249394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1250394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1251b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.orgvoid LoadStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) { 12524a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org if (!miss->is_unused()) { 1253b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org Label success; 1254b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org __ jmp(&success); 12554a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ bind(miss); 12562bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org TailCallBuiltin(masm(), MissBuiltin(kind())); 1257b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org __ bind(&success); 12584a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org } 12595aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org} 12605aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 12615aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 1262b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.orgvoid StoreStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) { 1263bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org if (!miss->is_unused()) { 1264b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org Label success; 1265b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org __ jmp(&success); 1266bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org GenerateRestoreName(masm(), miss, name); 1267bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org TailCallBuiltin(masm(), MissBuiltin(kind())); 1268b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org __ bind(&success); 1269bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } 1270bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org} 1271bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 1272bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 12732efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgRegister LoadStubCompiler::CallbackHandlerFrontend( 1274f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Handle<Type> type, 12758432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org Register object_reg, 12768432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org Handle<JSObject> holder, 1277750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Handle<Name> name, 12782c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org Handle<Object> callback) { 12798432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org Label miss; 12808432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org 1281f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Register reg = HandlerFrontendHeader(type, object_reg, holder, name, &miss); 12828432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org 12838432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { 12848432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org ASSERT(!reg.is(scratch2())); 12858432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org ASSERT(!reg.is(scratch3())); 12868432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org ASSERT(!reg.is(scratch4())); 12878432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org 12888432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org // Load the properties dictionary. 12898432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org Register dictionary = scratch4(); 12908432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org __ movq(dictionary, FieldOperand(reg, JSObject::kPropertiesOffset)); 12918432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org 12928432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org // Probe the dictionary. 12938432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org Label probe_done; 1294750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org NameDictionaryLookupStub::GeneratePositiveLookup(masm(), 1295750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org &miss, 1296750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org &probe_done, 1297750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org dictionary, 1298750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org this->name(), 1299750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org scratch2(), 1300750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org scratch3()); 13018432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org __ bind(&probe_done); 13028432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org 13038432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org // If probing finds an entry in the dictionary, scratch3 contains the 13048432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org // index into the dictionary. Check that the value is the callback. 13058432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org Register index = scratch3(); 13068432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org const int kElementsStartOffset = 1307750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org NameDictionary::kHeaderSize + 1308750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org NameDictionary::kElementsStartIndex * kPointerSize; 13098432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org const int kValueOffset = kElementsStartOffset + kPointerSize; 13108432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org __ movq(scratch2(), 13118432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org Operand(dictionary, index, times_pointer_size, 13128432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org kValueOffset - kHeapObjectTag)); 13138432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org __ movq(scratch3(), callback, RelocInfo::EMBEDDED_OBJECT); 13148432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org __ cmpq(scratch2(), scratch3()); 13158432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org __ j(not_equal, &miss); 13168432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org } 13178432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org 1318b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org HandlerFrontendFooter(name, &miss); 13198432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org return reg; 132088767247437a4504f433cc5abea22a473e5ed982erik.corry@gmail.com} 132188767247437a4504f433cc5abea22a473e5ed982erik.corry@gmail.com 132288767247437a4504f433cc5abea22a473e5ed982erik.corry@gmail.com 13232efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgvoid LoadStubCompiler::GenerateLoadField(Register reg, 1324057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org Handle<JSObject> holder, 1325057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org PropertyIndex field, 1326057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org Representation representation) { 132757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org if (!reg.is(receiver())) __ movq(receiver(), reg); 132857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org if (kind() == Code::LOAD_IC) { 132957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org LoadFieldStub stub(field.is_inobject(holder), 133057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org field.translate(holder), 133157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org representation); 133257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org GenerateTailCall(masm(), stub.GetCode(isolate())); 133357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } else { 133457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org KeyedLoadFieldStub stub(field.is_inobject(holder), 133557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org field.translate(holder), 133657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org representation); 133757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org GenerateTailCall(masm(), stub.GetCode(isolate())); 133857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } 13398432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org} 13408432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org 13418432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org 13422efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgvoid LoadStubCompiler::GenerateLoadCallback( 13432c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org const CallOptimization& call_optimization) { 1344639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org GenerateFastApiCall( 13457ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org masm(), call_optimization, receiver(), 13467ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org scratch1(), scratch2(), name(), 0, NULL); 13472c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org} 13482c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org 13492c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org 13502efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgvoid LoadStubCompiler::GenerateLoadCallback( 13518432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org Register reg, 13528432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org Handle<ExecutableAccessorInfo> callback) { 13535d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Insert additional parameters into the stack frame above return address. 1354c9db920c61872265c3fdc00d745a9b1eebbfc0bedanno@chromium.org ASSERT(!scratch4().is(reg)); 1355594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ PopReturnAddressTo(scratch4()); 13562c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org 1357fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0); 1358fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1); 1359fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2); 1360fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3); 1361fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4); 1362fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5); 1363fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 6); 13648432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org __ push(receiver()); // receiver 1365c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (heap()->InNewSpace(callback->data())) { 13664a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org ASSERT(!scratch2().is(reg)); 13674a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org __ Move(scratch2(), callback); 13684a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org __ push(FieldOperand(scratch2(), 13698432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org ExecutableAccessorInfo::kDataOffset)); // data 13705d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org } else { 137109d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org __ Push(Handle<Object>(callback->data(), isolate())); 13725d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org } 13734a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org ASSERT(!kScratchRegister.is(reg)); 1374bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org __ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex); 1375bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org __ push(kScratchRegister); // return value 13768a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ push(kScratchRegister); // return value default 137753ad17558c81e6099cef4442237d7da643a5becfsvenpanne@chromium.org __ PushAddress(ExternalReference::isolate_address(isolate())); 13784a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org __ push(reg); // holder 13798432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org __ push(name()); // name 13804a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // Save a pointer to where we pushed the arguments pointer. This will be 1381fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org // passed as the const PropertyAccessorInfo& to the C++ callback. 1382ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org 1383bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org Address getter_address = v8::ToCData<Address>(callback->getter()); 1384bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org 1385662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org#if defined(__MINGW64__) || defined(_WIN64) 1386b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Register getter_arg = r8; 1387ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com Register accessor_info_arg = rdx; 1388ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com Register name_arg = rcx; 13895d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org#else 1390b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Register getter_arg = rdx; 13915d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org Register accessor_info_arg = rsi; 13925d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org Register name_arg = rdi; 13935d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org#endif 1394ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org 1395c9db920c61872265c3fdc00d745a9b1eebbfc0bedanno@chromium.org ASSERT(!name_arg.is(scratch4())); 13965d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ movq(name_arg, rsp); 1397594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ PushReturnAddressFrom(scratch4()); 1398ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org 1399bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org // v8::Arguments::values_ and handler for name. 1400bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org const int kStackSpace = PropertyCallbackArguments::kArgsLength + 1; 1401ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org 14025d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Allocate v8::AccessorInfo in non-GCed stack space. 14035d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org const int kArgStackSpace = 1; 1404ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org 1405662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org __ PrepareCallApiFunction(kArgStackSpace); 1406fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org __ lea(rax, Operand(name_arg, 1 * kPointerSize)); 1407ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org 1408fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org // v8::PropertyAccessorInfo::args_. 14095d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ movq(StackSpaceOperand(0), rax); 1410ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org 14115d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // The context register (rsi) has been saved in PrepareCallApiFunction and 14125d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // could be used to pass arguments. 14135d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ lea(accessor_info_arg, StackSpaceOperand(0)); 1414ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org 1415662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback); 1416b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 1417d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org // The name handler is counted as an argument. 1418d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org StackArgumentsAccessor args(rbp, PropertyCallbackArguments::kArgsLength); 1419d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Operand return_value_operand = args.GetArgumentOperand( 1420d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org PropertyCallbackArguments::kArgsLength - 1 - 1421d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org PropertyCallbackArguments::kReturnValueOffset); 1422bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org __ CallApiFunctionAndReturn(getter_address, 1423b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org thunk_address, 1424b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org getter_arg, 1425bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org kStackSpace, 1426d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org return_value_operand, 1427528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org NULL); 14285d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org} 1429ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org 1430ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org 14312efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgvoid LoadStubCompiler::GenerateLoadConstant(Handle<Object> value) { 14325d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Return the constant value. 1433c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org __ Move(rax, value); 14345d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ ret(0); 14355d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org} 1436ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org 1437ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org 14382efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgvoid LoadStubCompiler::GenerateLoadInterceptor( 14398432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org Register holder_reg, 1440b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org Handle<Object> object, 14418432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org Handle<JSObject> interceptor_holder, 14428432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org LookupResult* lookup, 1443750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Handle<Name> name) { 14445d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org ASSERT(interceptor_holder->HasNamedInterceptor()); 14455d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); 1446ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org 14475d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // So far the most popular follow ups for interceptor loads are FIELD 14485d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // and CALLBACKS, so inline only them, other cases may be added 14495d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // later. 14505d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org bool compile_followup_inline = false; 145105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org if (lookup->IsFound() && lookup->IsCacheable()) { 1452de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org if (lookup->IsField()) { 14535d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org compile_followup_inline = true; 14545d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org } else if (lookup->type() == CALLBACKS && 14557c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org lookup->GetCallbackObject()->IsExecutableAccessorInfo()) { 14567c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org ExecutableAccessorInfo* callback = 14577c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org ExecutableAccessorInfo::cast(lookup->GetCallbackObject()); 14587028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org compile_followup_inline = callback->getter() != NULL && 14597028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org callback->IsCompatibleReceiver(*object); 14605d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org } 14615d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org } 14625ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org 14635d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org if (compile_followup_inline) { 14645d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Compile the interceptor call, followed by inline code to load the 14655d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // property from further up the prototype chain if the call fails. 14665d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Check that the maps haven't changed. 14678432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org ASSERT(holder_reg.is(receiver()) || holder_reg.is(scratch1())); 1468ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org 1469212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org // Preserve the receiver register explicitly whenever it is different from 1470212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org // the holder and it is needed should the interceptor return without any 1471212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org // result. The CALLBACKS case needs the receiver to be passed into C++ code, 1472212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org // the FIELD case might cause a miss during the prototype check. 1473212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org bool must_perfrom_prototype_check = *interceptor_holder != lookup->holder(); 14748432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org bool must_preserve_receiver_reg = !receiver().is(holder_reg) && 1475212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org (lookup->type() == CALLBACKS || must_perfrom_prototype_check); 1476212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org 14775d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Save necessary data before invoking an interceptor. 14785d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Requires a frame to make GC aware of pushed pointers. 1479c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com { 1480c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FrameScope frame_scope(masm(), StackFrame::INTERNAL); 1481303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org 1482212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org if (must_preserve_receiver_reg) { 14838432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org __ push(receiver()); 1484c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 1485c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ push(holder_reg); 14868432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org __ push(this->name()); 1487ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org 1488c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Invoke an interceptor. Note: map checks from receiver to 1489c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // interceptor's holder has been compiled before (see a caller 1490c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // of this method.) 149137be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org CompileCallLoadPropertyWithInterceptor( 149237be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org masm(), receiver(), holder_reg, this->name(), interceptor_holder, 149337be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org IC::kLoadPropertyWithInterceptorOnly); 1494c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1495c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check if interceptor provided a value for property. If it's 1496c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // the case, return immediately. 1497c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label interceptor_failed; 1498c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ CompareRoot(rax, Heap::kNoInterceptorResultSentinelRootIndex); 1499c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ j(equal, &interceptor_failed); 1500c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com frame_scope.GenerateLeaveFrame(); 1501c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ ret(0); 1502c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1503c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ bind(&interceptor_failed); 15048432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org __ pop(this->name()); 1505c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ pop(holder_reg); 1506212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org if (must_preserve_receiver_reg) { 15078432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org __ pop(receiver()); 1508c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 1509ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org 1510c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Leave the internal frame. 1511c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 1512ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org 15138432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org GenerateLoadPostInterceptor(holder_reg, interceptor_holder, name, lookup); 15145d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org } else { // !compile_followup_inline 15155d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Call the runtime system to load the interceptor. 15165d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Check that the maps haven't changed. 1517594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ PopReturnAddressTo(scratch2()); 15188432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org PushInterceptorArguments(masm(), receiver(), holder_reg, 15198432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org this->name(), interceptor_holder); 1520594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ PushReturnAddressFrom(scratch2()); 1521ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org 15225d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org ExternalReference ref = ExternalReference( 15237516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), isolate()); 15244a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org __ TailCallExternalReference(ref, StubCache::kInterceptorArgsLength, 1); 1525303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org } 1526ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org} 1527ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org 1528ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org 1529750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgvoid CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) { 15305d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org if (kind_ == Code::KEYED_CALL_IC) { 1531394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Cmp(rcx, name); 15325d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ j(not_equal, miss); 15335d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org } 15345d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org} 1535ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org 1536ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org 15378a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.orgvoid CallStubCompiler::GenerateFunctionCheck(Register function, 15388a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org Register scratch, 15398a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org Label* miss) { 15408a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org __ JumpIfSmi(function, miss); 15418a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org __ CmpObjectType(function, JS_FUNCTION_TYPE, scratch); 15428a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org __ j(not_equal, miss); 15438a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org} 15448a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org 15458a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org 1546c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid CallStubCompiler::GenerateLoadFunctionFromCell( 154741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Handle<Cell> cell, 1548c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSFunction> function, 1549c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label* miss) { 15505d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Get the value from the cell. 1551c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Move(rdi, cell); 155241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org __ movq(rdi, FieldOperand(rdi, Cell::kValueOffset)); 155365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 15545d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Check that the cell contains the same function. 1555c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (heap()->InNewSpace(*function)) { 15565d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // We can't embed a pointer to a function in new space so we have 15575d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // to verify that the shared function info is unchanged. This has 15585d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // the nice side effect that multiple closures based on the same 15595d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // function can all use this call IC. Before we load through the 15605d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // function, we have to verify that it still is a function. 15618a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org GenerateFunctionCheck(rdi, rax, miss); 156265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 15635d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Check the shared function info. Make sure it hasn't changed. 15645d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ Move(rax, Handle<SharedFunctionInfo>(function->shared())); 15655d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ cmpq(FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset), rax); 156665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org } else { 1567c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Cmp(rdi, function); 156865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org } 1569c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ j(not_equal, miss); 15705d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org} 157165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 157265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 1573394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comvoid CallStubCompiler::GenerateMissBranch() { 1574394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Handle<Code> code = 157540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(), 157640cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org kind_, 1577ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org extra_state()); 1578394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Jump(code, RelocInfo::CODE_TARGET); 1579394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com} 1580394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1581394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1582394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comHandle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, 1583394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Handle<JSObject> holder, 1584eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org PropertyIndex index, 1585750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Handle<Name> name) { 158665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org Label miss; 15875d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 1588cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org Register reg = HandlerFrontendHeader( 1589cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org object, holder, name, RECEIVER_MAP_CHECK, &miss); 159065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 159157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org GenerateFastPropertyLoad(masm(), rdi, reg, index.is_inobject(holder), 159257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org index.translate(holder), Representation::Tagged()); 15938a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org GenerateJumpFunction(object, rdi, &miss); 159430ce411529579186181838984710b0b0980857aaricow@chromium.org 1595cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org HandlerFrontendFooter(&miss); 159665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org 159765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org // Return the generated code. 15989af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org return GetCode(Code::FAST, name); 159965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org} 1600ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org 1601ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org 16021510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgHandle<Code> CallStubCompiler::CompileArrayCodeCall( 16031510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Handle<Object> object, 16041510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Handle<JSObject> holder, 16051510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Handle<Cell> cell, 16061510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Handle<JSFunction> function, 16071510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Handle<String> name, 16081510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Code::StubType type) { 16091510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Label miss; 16101510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 1611cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); 1612cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org if (!cell.is_null()) { 16131510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ASSERT(cell->value() == *function); 16141510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org GenerateLoadFunctionFromCell(cell, function, &miss); 16151510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } 16161510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 1617bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite(); 1618b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org site->SetElementsKind(GetInitialFastElementsKind()); 1619bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site); 1620cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org const int argc = arguments().immediate(); 16211510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ movq(rax, Immediate(argc)); 1622bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org __ Move(rbx, site_feedback_cell); 16231510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ Move(rdi, function); 16241510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 16251510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ArrayConstructorStub stub(isolate()); 16261510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ TailCallStub(&stub); 16271510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 1628cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org HandlerFrontendFooter(&miss); 16291510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 16301510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org // Return the generated code. 16311510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org return GetCode(type, name); 16321510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org} 16331510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 16341510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 1635c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgHandle<Code> CallStubCompiler::CompileArrayPushCall( 1636c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<Object> object, 1637c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSObject> holder, 163841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Handle<Cell> cell, 1639c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSFunction> function, 16401510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Handle<String> name, 16411510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Code::StubType type) { 16428a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org // If object is not an array or is observed or sealed, bail out to regular 16438a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org // call. 1644b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if (!object->IsJSArray() || 1645b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org !cell.is_null() || 16468a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org Handle<JSArray>::cast(object)->map()->is_observed() || 16478a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org !Handle<JSArray>::cast(object)->map()->is_extensible()) { 1648b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org return Handle<Code>::null(); 1649b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org } 16502ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org 16512ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org Label miss; 1652cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org 1653cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); 16542ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org 16555d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org const int argc = arguments().immediate(); 1656662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org StackArgumentsAccessor args(rsp, argc); 16575d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org if (argc == 0) { 16585d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Noop, return the length. 16595d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ movq(rax, FieldOperand(rdx, JSArray::kLengthOffset)); 16605d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ ret((argc + 1) * kPointerSize); 16612ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org } else { 16625d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org Label call_builtin; 16632ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org 16645d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org if (argc == 1) { // Otherwise fall through to call builtin. 1665fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org Label attempt_to_grow_elements, with_write_barrier, check_double; 16662ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org 166778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // Get the elements array of the object. 166878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org __ movq(rdi, FieldOperand(rdx, JSArray::kElementsOffset)); 166978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org 167078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // Check that the elements are in fast mode and writable. 167178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org __ Cmp(FieldOperand(rdi, HeapObject::kMapOffset), 167278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org factory()->fixed_array_map()); 1673fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org __ j(not_equal, &check_double); 167478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org 16755d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Get the array's length into rax and calculate new length. 16765d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ SmiToInteger32(rax, FieldOperand(rdx, JSArray::kLengthOffset)); 16775d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org STATIC_ASSERT(FixedArray::kMaxLength < Smi::kMaxValue); 16785d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ addl(rax, Immediate(argc)); 16792ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org 168078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // Get the elements' length into rcx. 168178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org __ SmiToInteger32(rcx, FieldOperand(rdi, FixedArray::kLengthOffset)); 16822ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org 16835d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Check if we could survive without allocation. 16845d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ cmpl(rax, rcx); 16855d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ j(greater, &attempt_to_grow_elements); 16865d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 1687c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check if value is a smi. 1688662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org __ movq(rcx, args.GetArgumentOperand(1)); 1689c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ JumpIfNotSmi(rcx, &with_write_barrier); 1690c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 16915d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Save new length. 16925d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rax); 16935d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 169478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // Store the value. 169578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org __ movq(FieldOperand(rdi, 169678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org rax, 169778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org times_pointer_size, 169878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org FixedArray::kHeaderSize - argc * kPointerSize), 169978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org rcx); 17005d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 17015d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ Integer32ToSmi(rax, rax); // Return new length as smi. 17025d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ ret((argc + 1) * kPointerSize); 17035d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 1704fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org __ bind(&check_double); 1705fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 1706fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // Check that the elements are in double mode. 1707fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org __ Cmp(FieldOperand(rdi, HeapObject::kMapOffset), 1708fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org factory()->fixed_double_array_map()); 1709fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org __ j(not_equal, &call_builtin); 1710fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 1711fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // Get the array's length into rax and calculate new length. 1712fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org __ SmiToInteger32(rax, FieldOperand(rdx, JSArray::kLengthOffset)); 1713fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org STATIC_ASSERT(FixedArray::kMaxLength < Smi::kMaxValue); 1714fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org __ addl(rax, Immediate(argc)); 1715fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 1716fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // Get the elements' length into rcx. 1717fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org __ SmiToInteger32(rcx, FieldOperand(rdi, FixedArray::kLengthOffset)); 1718fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 1719fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // Check if we could survive without allocation. 1720fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org __ cmpl(rax, rcx); 1721fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org __ j(greater, &call_builtin); 1722fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 1723662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org __ movq(rcx, args.GetArgumentOperand(1)); 1724fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org __ StoreNumberToDoubleElements( 1725fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org rcx, rdi, rax, xmm0, &call_builtin, argc * kDoubleSize); 1726fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 1727fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // Save new length. 1728fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rax); 1729fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org __ Integer32ToSmi(rax, rax); // Return new length as smi. 1730fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org __ ret((argc + 1) * kPointerSize); 1731fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 17325d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ bind(&with_write_barrier); 17335d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 173478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org __ movq(rbx, FieldOperand(rdx, HeapObject::kMapOffset)); 173578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org 173678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org if (FLAG_smi_only_arrays && !FLAG_trace_elements_transitions) { 173778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org Label fast_object, not_fast_object; 173878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org __ CheckFastObjectElements(rbx, ¬_fast_object, Label::kNear); 173978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org __ jmp(&fast_object); 174078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // In case of fast smi-only, convert to fast object, otherwise bail out. 174178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org __ bind(¬_fast_object); 1742830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org __ CheckFastSmiElements(rbx, &call_builtin); 1743fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org __ Cmp(FieldOperand(rcx, HeapObject::kMapOffset), 1744fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org factory()->heap_number_map()); 1745fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org __ j(equal, &call_builtin); 174678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // rdx: receiver 174778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // rbx: map 1748830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org 1749830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Label try_holey_map; 1750830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS, 175178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org FAST_ELEMENTS, 175278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org rbx, 175365a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org rdi, 1754830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org &try_holey_map); 1755830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org 1756830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org ElementsTransitionGenerator:: 175746a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org GenerateMapChangeElementsTransition(masm(), 175846a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org DONT_TRACK_ALLOCATION_SITE, 175946a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org NULL); 1760830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org // Restore edi. 1761830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org __ movq(rdi, FieldOperand(rdx, JSArray::kElementsOffset)); 1762830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org __ jmp(&fast_object); 1763830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org 1764830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org __ bind(&try_holey_map); 1765830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org __ LoadTransitionedArrayMapConditional(FAST_HOLEY_SMI_ELEMENTS, 1766830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org FAST_HOLEY_ELEMENTS, 1767830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org rbx, 1768830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org rdi, 176978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org &call_builtin); 1770830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org ElementsTransitionGenerator:: 177146a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org GenerateMapChangeElementsTransition(masm(), 177246a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org DONT_TRACK_ALLOCATION_SITE, 177346a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org NULL); 1774830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org __ movq(rdi, FieldOperand(rdx, JSArray::kElementsOffset)); 177578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org __ bind(&fast_object); 177678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org } else { 177778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org __ CheckFastObjectElements(rbx, &call_builtin); 177878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org } 177978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org 1780c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Save new length. 1781c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rax); 17825d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 178378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // Store the value. 178478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org __ lea(rdx, FieldOperand(rdi, 1785c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com rax, times_pointer_size, 1786c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FixedArray::kHeaderSize - argc * kPointerSize)); 1787c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ movq(Operand(rdx, 0), rcx); 1788c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 178978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org __ RecordWrite(rdi, rdx, rcx, kDontSaveFPRegs, EMIT_REMEMBERED_SET, 1790c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org OMIT_SMI_CHECK); 1791c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1792c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Integer32ToSmi(rax, rax); // Return new length as smi. 17935d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ ret((argc + 1) * kPointerSize); 17945d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 17955d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ bind(&attempt_to_grow_elements); 17965d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org if (!FLAG_inline_new) { 17975d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ jmp(&call_builtin); 17985d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org } 17995d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 1800662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org __ movq(rbx, args.GetArgumentOperand(1)); 1801a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org // Growing elements that are SMI-only requires special handling in case 1802a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org // the new element is non-Smi. For now, delegate to the builtin. 1803a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org Label no_fast_elements_check; 180478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org __ JumpIfSmi(rbx, &no_fast_elements_check); 1805394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ movq(rcx, FieldOperand(rdx, HeapObject::kMapOffset)); 1806394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ CheckFastObjectElements(rcx, &call_builtin, Label::kFar); 1807a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org __ bind(&no_fast_elements_check); 1808c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 18095d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org ExternalReference new_space_allocation_top = 18107516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org ExternalReference::new_space_allocation_top_address(isolate()); 18115d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org ExternalReference new_space_allocation_limit = 18127516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org ExternalReference::new_space_allocation_limit_address(isolate()); 18135d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 18145d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org const int kAllocationDelta = 4; 18155d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Load top. 1816ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ Load(rcx, new_space_allocation_top); 18175d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 18185d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Check if it's the end of elements. 181978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org __ lea(rdx, FieldOperand(rdi, 18205d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org rax, times_pointer_size, 18215d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org FixedArray::kHeaderSize - argc * kPointerSize)); 18225d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ cmpq(rdx, rcx); 18235d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ j(not_equal, &call_builtin); 18245d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ addq(rcx, Immediate(kAllocationDelta * kPointerSize)); 1825ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Operand limit_operand = 1826ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org masm()->ExternalOperand(new_space_allocation_limit); 1827ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ cmpq(rcx, limit_operand); 18285d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ j(above, &call_builtin); 18295d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 18305d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // We fit and could grow elements. 1831ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ Store(new_space_allocation_top, rcx); 18325d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 18335d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Push the argument... 183478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org __ movq(Operand(rdx, 0), rbx); 18355d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // ... and fill the rest with holes. 18365d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex); 18375d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org for (int i = 1; i < kAllocationDelta; i++) { 18385d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ movq(Operand(rdx, i * kPointerSize), kScratchRegister); 18395d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org } 18405d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 1841c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // We know the elements array is in new space so we don't need the 1842c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // remembered set, but we just pushed a value onto it so we may have to 1843c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // tell the incremental marker to rescan the object that we just grew. We 1844c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // don't need to worry about the holes because they are in old space and 1845c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // already marked black. 184678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org __ RecordWrite(rdi, rdx, rbx, kDontSaveFPRegs, OMIT_REMEMBERED_SET); 1847c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 18485d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Restore receiver to rdx as finish sequence assumes it's here. 1849662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org __ movq(rdx, args.GetReceiverOperand()); 18505d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 18515d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Increment element's and array's sizes. 185278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org __ SmiAddConstant(FieldOperand(rdi, FixedArray::kLengthOffset), 18535d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org Smi::FromInt(kAllocationDelta)); 18545d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 18555d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Make new length a smi before returning it. 18565d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ Integer32ToSmi(rax, rax); 18575d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ movq(FieldOperand(rdx, JSArray::kLengthOffset), rax); 18585d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 18595d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ ret((argc + 1) * kPointerSize); 18605d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org } 18615d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 18625d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ bind(&call_builtin); 1863ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ TailCallExternalReference(ExternalReference(Builtins::c_ArrayPush, 18647516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org isolate()), 18655d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org argc + 1, 18665d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 1); 18675d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org } 18682ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org 1869cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org HandlerFrontendFooter(&miss); 18702ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org 18712ec107fe650fe56eed094ca017940f26af46644bsgjesse@chromium.org // Return the generated code. 18721510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org return GetCode(type, name); 1873c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org} 1874c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org 1875c20610af4f0ca150977ca140a1174f98ee46f5aafschneider@chromium.org 1876c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgHandle<Code> CallStubCompiler::CompileArrayPopCall( 1877c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<Object> object, 1878c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSObject> holder, 187941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Handle<Cell> cell, 1880c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSFunction> function, 18811510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Handle<String> name, 18821510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Code::StubType type) { 18838a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org // If object is not an array or is observed or sealed, bail out to regular 18848a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org // call. 1885b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if (!object->IsJSArray() || 1886b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org !cell.is_null() || 18878a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org Handle<JSArray>::cast(object)->map()->is_observed() || 18888a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org !Handle<JSArray>::cast(object)->map()->is_extensible()) { 1889b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org return Handle<Code>::null(); 1890b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org } 1891f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org 18925d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org Label miss, return_undefined, call_builtin; 1893f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org 1894cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); 1895f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org 18965d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Get the elements array of the object. 18975d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ movq(rbx, FieldOperand(rdx, JSArray::kElementsOffset)); 1898f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org 18995d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Check that the elements are in fast mode and writable. 19005d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset), 19015d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org Heap::kFixedArrayMapRootIndex); 19025d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ j(not_equal, &call_builtin); 1903f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org 19045d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Get the array's length into rcx and calculate new length. 19055d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ SmiToInteger32(rcx, FieldOperand(rdx, JSArray::kLengthOffset)); 19065d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ subl(rcx, Immediate(1)); 19075d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ j(negative, &return_undefined); 1908f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org 19095d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Get the last element. 19105d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ LoadRoot(r9, Heap::kTheHoleValueRootIndex); 19115d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ movq(rax, FieldOperand(rbx, 19125d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org rcx, times_pointer_size, 19135d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org FixedArray::kHeaderSize)); 19145d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Check if element is already the hole. 19155d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ cmpq(rax, r9); 19165d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // If so, call slow-case to also check prototypes for value. 19175d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ j(equal, &call_builtin); 1918f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org 19195d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Set the array's length. 19205d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rcx); 1921f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org 19225d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Fill with the hole and return original value. 19235d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ movq(FieldOperand(rbx, 19245d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org rcx, times_pointer_size, 19255d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org FixedArray::kHeaderSize), 19265d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org r9); 1927cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org const int argc = arguments().immediate(); 19285d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ ret((argc + 1) * kPointerSize); 1929f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org 19305d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ bind(&return_undefined); 19315d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); 19325d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ ret((argc + 1) * kPointerSize); 1933f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org 19345d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ bind(&call_builtin); 1935ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ TailCallExternalReference( 19367516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org ExternalReference(Builtins::c_ArrayPop, isolate()), 1937ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org argc + 1, 1938ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 1); 1939f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org 1940cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org HandlerFrontendFooter(&miss); 1941f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org 1942f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org // Return the generated code. 19431510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org return GetCode(type, name); 1944f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org} 1945f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org 1946f05f2913e034b9332e55c02c9395e701725c02c1kmillikin@chromium.org 1947c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgHandle<Code> CallStubCompiler::CompileStringCharCodeAtCall( 1948c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<Object> object, 1949c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSObject> holder, 195041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Handle<Cell> cell, 1951c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSFunction> function, 19521510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Handle<String> name, 19531510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Code::StubType type) { 19545d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // If object is not a string, bail out to regular call. 1955c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (!object->IsString() || !cell.is_null()) return Handle<Code>::null(); 19562c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org 19575d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org Label miss; 19580511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Label name_miss; 19595d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org Label index_out_of_range; 19600511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Label* index_out_of_range_label = &index_out_of_range; 196140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org if (kind_ == Code::CALL_IC && 1962ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org (CallICBase::StringStubState::decode(extra_state()) == 196340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org DEFAULT_STRING_STUB)) { 19640511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com index_out_of_range_label = &miss; 19650511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 1966cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org 1967cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org HandlerFrontendHeader(object, holder, name, STRING_CHECK, &name_miss); 19680b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 19695d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org Register receiver = rbx; 19705d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org Register index = rdi; 19715d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org Register result = rax; 1972cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org const int argc = arguments().immediate(); 1973cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org StackArgumentsAccessor args(rsp, argc); 1974cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org 1975662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org __ movq(receiver, args.GetReceiverOperand()); 19765d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org if (argc > 0) { 1977662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org __ movq(index, args.GetArgumentOperand(1)); 19785d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org } else { 19795d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ LoadRoot(index, Heap::kUndefinedValueRootIndex); 19805d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org } 19810b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 1982c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org StringCharCodeAtGenerator generator(receiver, 1983c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org index, 1984c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org result, 1985c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org &miss, // When not a string. 1986c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org &miss, // When not a number. 1987c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org index_out_of_range_label, 1988c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org STRING_INDEX_IS_NUMBER); 1989c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org generator.GenerateFast(masm()); 19905d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ ret((argc + 1) * kPointerSize); 19910b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 19925d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org StubRuntimeCallHelper call_helper; 1993c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org generator.GenerateSlow(masm(), call_helper); 19940b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 19950511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com if (index_out_of_range.is_linked()) { 19960511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com __ bind(&index_out_of_range); 19970511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com __ LoadRoot(rax, Heap::kNanValueRootIndex); 19980511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com __ ret((argc + 1) * kPointerSize); 19990511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 20000b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 20010b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org __ bind(&miss); 20020511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // Restore function name in rcx. 2003c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Move(rcx, name); 20048a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org HandlerFrontendFooter(&name_miss); 20050b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 20060b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // Return the generated code. 20071510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org return GetCode(type, name); 20085aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org} 20095aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 20105aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 2011c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgHandle<Code> CallStubCompiler::CompileStringCharAtCall( 2012c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<Object> object, 2013c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSObject> holder, 201441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Handle<Cell> cell, 2015c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSFunction> function, 20161510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Handle<String> name, 20171510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Code::StubType type) { 20185d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // If object is not a string, bail out to regular call. 2019c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (!object->IsString() || !cell.is_null()) return Handle<Code>::null(); 20205d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 20215d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org const int argc = arguments().immediate(); 2022662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org StackArgumentsAccessor args(rsp, argc); 2023662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org 2024e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org Label miss; 20250511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Label name_miss; 20265d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org Label index_out_of_range; 20270511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Label* index_out_of_range_label = &index_out_of_range; 202840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org if (kind_ == Code::CALL_IC && 2029ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org (CallICBase::StringStubState::decode(extra_state()) == 203040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org DEFAULT_STRING_STUB)) { 20310511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com index_out_of_range_label = &miss; 20320511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 2033cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org 2034cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org HandlerFrontendHeader(object, holder, name, STRING_CHECK, &name_miss); 2035e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 20365d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org Register receiver = rax; 20375d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org Register index = rdi; 2038c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org Register scratch = rdx; 20395d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org Register result = rax; 2040662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org __ movq(receiver, args.GetReceiverOperand()); 20415d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org if (argc > 0) { 2042662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org __ movq(index, args.GetArgumentOperand(1)); 20435d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org } else { 20445d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ LoadRoot(index, Heap::kUndefinedValueRootIndex); 2045e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org } 2046e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 2047c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org StringCharAtGenerator generator(receiver, 2048c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org index, 2049c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org scratch, 2050c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org result, 2051c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org &miss, // When not a string. 2052c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org &miss, // When not a number. 2053c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org index_out_of_range_label, 2054c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org STRING_INDEX_IS_NUMBER); 2055c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org generator.GenerateFast(masm()); 20565d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ ret((argc + 1) * kPointerSize); 20575d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 20585d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org StubRuntimeCallHelper call_helper; 2059c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org generator.GenerateSlow(masm(), call_helper); 2060e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 20610511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com if (index_out_of_range.is_linked()) { 20620511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com __ bind(&index_out_of_range); 20634a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ LoadRoot(rax, Heap::kempty_stringRootIndex); 20640511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com __ ret((argc + 1) * kPointerSize); 20650511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 2066e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org __ bind(&miss); 20670511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // Restore function name in rcx. 2068c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Move(rcx, name); 20698a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org HandlerFrontendFooter(&name_miss); 2070e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 2071e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // Return the generated code. 20721510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org return GetCode(type, name); 20732abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org} 20742abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org 20752abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org 2076c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgHandle<Code> CallStubCompiler::CompileStringFromCharCodeCall( 2077c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<Object> object, 2078c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSObject> holder, 207941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Handle<Cell> cell, 2080c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSFunction> function, 20811510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Handle<String> name, 20821510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Code::StubType type) { 20835d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // If the object is not a JSObject or we got an unexpected number of 20845d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // arguments, bail out to the regular call. 2085c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org const int argc = arguments().immediate(); 2086662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org StackArgumentsAccessor args(rsp, argc); 2087c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); 20885aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 2089e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org Label miss; 2090e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 2091cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); 2092cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org if (!cell.is_null()) { 2093c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(cell->value() == *function); 20945d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org GenerateLoadFunctionFromCell(cell, function, &miss); 20955d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org } 20965aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 20975d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Load the char code argument. 20985d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org Register code = rbx; 2099d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org __ movq(code, args.GetArgumentOperand(1)); 2100c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org 21015d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Check the code is a smi. 21025d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org Label slow; 21035d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ JumpIfNotSmi(code, &slow); 2104c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org 21055d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Convert the smi code to uint16. 21065d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ SmiAndConstant(code, code, Smi::FromInt(0xffff)); 2107c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org 2108c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org StringCharFromCodeGenerator generator(code, rax); 2109c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org generator.GenerateFast(masm()); 21105d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ ret(2 * kPointerSize); 2111c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org 21125d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org StubRuntimeCallHelper call_helper; 2113c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org generator.GenerateSlow(masm(), call_helper); 21145d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 21155d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ bind(&slow); 21168a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org // We do not have to patch the receiver because the function makes no use of 21178a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org // it. 21188a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org GenerateJumpFunctionIgnoreReceiver(function); 2119c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org 2120cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org HandlerFrontendFooter(&miss); 2121c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org 2122c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org // Return the generated code. 21231510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org return GetCode(type, name); 2124c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org} 2125c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org 2126c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org 2127c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgHandle<Code> CallStubCompiler::CompileMathFloorCall( 2128c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<Object> object, 2129c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSObject> holder, 213041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Handle<Cell> cell, 2131c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSFunction> function, 21321510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Handle<String> name, 21331510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Code::StubType type) { 21341e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org const int argc = arguments().immediate(); 2135d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org StackArgumentsAccessor args(rsp, argc); 21361e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 21371e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // If the object is not a JSObject or we got an unexpected number of 21381e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // arguments, bail out to the regular call. 21391e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org if (!object->IsJSObject() || argc != 1) { 21401e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org return Handle<Code>::null(); 21411e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org } 21421e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 2143cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org Label miss, slow; 21441e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 2145cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); 2146cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org if (!cell.is_null()) { 21471e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org ASSERT(cell->value() == *function); 21481e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org GenerateLoadFunctionFromCell(cell, function, &miss); 21491e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org } 21501e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 21511e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // Load the (only) argument into rax. 2152d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org __ movq(rax, args.GetArgumentOperand(1)); 21531e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 21541e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // Check if the argument is a smi. 21551e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org Label smi; 21561e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org STATIC_ASSERT(kSmiTag == 0); 21571e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ JumpIfSmi(rax, &smi); 21581e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 21591e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // Check if the argument is a heap number and load its value into xmm0. 21601e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ CheckMap(rax, factory()->heap_number_map(), &slow, DONT_DO_SMI_CHECK); 21611e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ movsd(xmm0, FieldOperand(rax, HeapNumber::kValueOffset)); 21621e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 21631e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // Check if the argument is strictly positive. Note this also discards NaN. 21641e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ xorpd(xmm1, xmm1); 21651e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ ucomisd(xmm0, xmm1); 21661e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ j(below_equal, &slow); 21671e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 21681e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // Do a truncating conversion. 21691e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ cvttsd2si(rax, xmm0); 21701e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 21711e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // Checks for 0x80000000 which signals a failed conversion. 21721e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org Label conversion_failure; 21731e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ cmpl(rax, Immediate(0x80000000)); 21741e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ j(equal, &conversion_failure); 21751e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 21761e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // Smi tag and return. 21771e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ Integer32ToSmi(rax, rax); 21781e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ bind(&smi); 21791e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ ret(2 * kPointerSize); 21801e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 21811e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // Check if the argument is < 2^kMantissaBits. 21821e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org Label already_round; 21831e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ bind(&conversion_failure); 21841e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org int64_t kTwoMantissaBits= V8_INT64_C(0x4330000000000000); 2185e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ movq(rbx, kTwoMantissaBits); 21861e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ movq(xmm1, rbx); 21871e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ ucomisd(xmm0, xmm1); 21881e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ j(above_equal, &already_round); 21891e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 21901e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // Save a copy of the argument. 21911e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ movaps(xmm2, xmm0); 21921e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 21931e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // Compute (argument + 2^kMantissaBits) - 2^kMantissaBits. 21941e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ addsd(xmm0, xmm1); 21951e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ subsd(xmm0, xmm1); 21961e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 21971e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // Compare the argument and the tentative result to get the right mask: 21981e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // if xmm2 < xmm0: 21991e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // xmm2 = 1...1 22001e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // else: 22011e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // xmm2 = 0...0 22021e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ cmpltsd(xmm2, xmm0); 22031e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 22041e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // Subtract 1 if the argument was less than the tentative result. 22051e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org int64_t kOne = V8_INT64_C(0x3ff0000000000000); 2206e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ movq(rbx, kOne); 22071e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ movq(xmm1, rbx); 22081e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ andpd(xmm1, xmm2); 22091e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ subsd(xmm0, xmm1); 22101e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 22111e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // Return a new heap number. 22121e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ AllocateHeapNumber(rax, rbx, &slow); 22131e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ movsd(FieldOperand(rax, HeapNumber::kValueOffset), xmm0); 22141e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ ret(2 * kPointerSize); 22151e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 22161e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // Return the argument (when it's an already round heap number). 22171e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ bind(&already_round); 2218d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org __ movq(rax, args.GetArgumentOperand(1)); 22191e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ ret(2 * kPointerSize); 22201e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 22211e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org __ bind(&slow); 22228a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org // We do not have to patch the receiver because the function makes no use of 22238a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org // it. 22248a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org GenerateJumpFunctionIgnoreReceiver(function); 22251e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 2226cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org HandlerFrontendFooter(&miss); 22271e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org 22281e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org // Return the generated code. 22291e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org return GetCode(type, name); 22305aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org} 22315aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 22325aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 2233c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgHandle<Code> CallStubCompiler::CompileMathAbsCall( 2234c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<Object> object, 2235c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSObject> holder, 223641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Handle<Cell> cell, 2237c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSFunction> function, 22381510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Handle<String> name, 22391510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Code::StubType type) { 22405d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // If the object is not a JSObject or we got an unexpected number of 22415d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // arguments, bail out to the regular call. 2242c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org const int argc = arguments().immediate(); 2243662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org StackArgumentsAccessor args(rsp, argc); 2244c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); 22455d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 22460b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org Label miss; 22470b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 2248cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); 2249cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org if (!cell.is_null()) { 2250c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(cell->value() == *function); 22515d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org GenerateLoadFunctionFromCell(cell, function, &miss); 22525d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org } 2253cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org 22545d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Load the (only) argument into rax. 2255d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org __ movq(rax, args.GetArgumentOperand(1)); 22565aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 22575d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Check if the argument is a smi. 22585d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org Label not_smi; 22595d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org STATIC_ASSERT(kSmiTag == 0); 22605d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ JumpIfNotSmi(rax, ¬_smi); 22615aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 2262594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // Branchless abs implementation, refer to below: 2263594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org // http://graphics.stanford.edu/~seander/bithacks.html#IntegerAbs 22645d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Set ebx to 1...1 (== -1) if the argument is negative, or to 0...0 22655d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // otherwise. 2266594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ movq(rbx, rax); 2267594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ sar(rbx, Immediate(kBitsPerPointer - 1)); 2268e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 22695d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Do bitwise not or do nothing depending on ebx. 2270594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ xor_(rax, rbx); 2271e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 22725d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Add 1 or do nothing depending on ebx. 2273594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ subq(rax, rbx); 22745d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 22755d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // If the result is still negative, go to the slow case. 22765d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // This only happens for the most negative smi. 22775d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org Label slow; 22785d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ j(negative, &slow); 22795d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 22805d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ ret(2 * kPointerSize); 22815d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 22825d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Check if the argument is a heap number and load its value. 22835d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ bind(¬_smi); 2284c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ CheckMap(rax, factory()->heap_number_map(), &slow, DONT_DO_SMI_CHECK); 2285e94b5ff1e1e95fb2c8ef6bce66ce8533786d9792bmeurer@chromium.org __ MoveDouble(rbx, FieldOperand(rax, HeapNumber::kValueOffset)); 2286e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 22875d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Check the sign of the argument. If the argument is positive, 22885d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // just return it. 22895d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org Label negative_sign; 22905d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org const int sign_mask_shift = 22915d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org (HeapNumber::kExponentOffset - HeapNumber::kValueOffset) * kBitsPerByte; 2292e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org __ Set(rdi, static_cast<int64_t>(HeapNumber::kSignMask) << sign_mask_shift); 22935d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ testq(rbx, rdi); 22945d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ j(not_zero, &negative_sign); 22955d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ ret(2 * kPointerSize); 2296e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 22975d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // If the argument is negative, clear the sign, and return a new 22985d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // number. We still have the sign mask in rdi. 22995d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ bind(&negative_sign); 23005d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ xor_(rbx, rdi); 23015d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ AllocateHeapNumber(rax, rdx, &slow); 2302e94b5ff1e1e95fb2c8ef6bce66ce8533786d9792bmeurer@chromium.org __ MoveDouble(FieldOperand(rax, HeapNumber::kValueOffset), rbx); 23035d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ ret(2 * kPointerSize); 2304e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 23055d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ bind(&slow); 23068a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org // We do not have to patch the receiver because the function makes no use of 23078a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org // it. 23088a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org GenerateJumpFunctionIgnoreReceiver(function); 2309e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 2310cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org HandlerFrontendFooter(&miss); 2311e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 2312e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // Return the generated code. 23131510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org return GetCode(type, name); 23142abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org} 23152abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org 23162abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org 2317c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgHandle<Code> CallStubCompiler::CompileFastApiCall( 2318ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org const CallOptimization& optimization, 2319c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<Object> object, 2320c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSObject> holder, 232141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Handle<Cell> cell, 2322c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSFunction> function, 2323c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<String> name) { 2324ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ASSERT(optimization.is_simple_api_call()); 2325ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Bail out if object is a global object as we don't want to 2326ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // repatch it to global receiver. 2327c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (object->IsGlobalObject()) return Handle<Code>::null(); 2328c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (!cell.is_null()) return Handle<Code>::null(); 2329c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (!object->IsJSObject()) return Handle<Code>::null(); 2330ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org int depth = optimization.GetPrototypeDepthOfExpectedType( 2331c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSObject>::cast(object), holder); 2332c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (depth == kInvalidProtoDepth) return Handle<Code>::null(); 2333ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 2334ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Label miss, miss_before_stack_reserved; 2335c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org GenerateNameCheck(name, &miss_before_stack_reserved); 2336ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 2337ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org const int argc = arguments().immediate(); 2338662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org StackArgumentsAccessor args(rsp, argc); 2339662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org __ movq(rdx, args.GetReceiverOperand()); 2340ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 2341ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Check that the receiver isn't a smi. 2342ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ JumpIfSmi(rdx, &miss_before_stack_reserved); 2343ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 23447516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Counters* counters = isolate()->counters(); 23457979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ IncrementCounter(counters->call_const(), 1); 23467979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ IncrementCounter(counters->call_const_fast_api(), 1); 2347ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 2348ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Allocate space for v8::Arguments implicit values. Must be initialized 2349ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // before calling any runtime function. 2350ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ subq(rsp, Immediate(kFastApiCallArguments * kPointerSize)); 2351ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 2352ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Check that the maps haven't changed and find a Holder as a side effect. 2353f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org CheckPrototypes(IC::CurrentTypeOf(object, isolate()), rdx, holder, 2354f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org rbx, rax, rdi, name, depth, &miss); 2355ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 2356ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Move the return address on top of the stack. 2357d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org __ movq(rax, 2358d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org StackOperandForReturnAddress(kFastApiCallArguments * kPointerSize)); 2359d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org __ movq(StackOperandForReturnAddress(0), rax); 2360ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 23617ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org GenerateFastApiCall(masm(), optimization, argc); 2362ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 2363ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ bind(&miss); 2364ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org __ addq(rsp, Immediate(kFastApiCallArguments * kPointerSize)); 2365ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 23668a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org HandlerFrontendFooter(&miss_before_stack_reserved); 2367ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 2368ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Return the generated code. 2369c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org return GetCode(function); 2370ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org} 2371ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 2372ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 2373b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.orgvoid StubCompiler::GenerateBooleanCheck(Register object, Label* miss) { 2374b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org Label success; 2375b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org // Check that the object is a boolean. 2376b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org __ CompareRoot(object, Heap::kTrueValueRootIndex); 2377b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org __ j(equal, &success); 2378b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org __ CompareRoot(object, Heap::kFalseValueRootIndex); 2379b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org __ j(not_equal, miss); 2380b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org __ bind(&success); 2381b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org} 2382b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org 2383b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org 2384cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.orgvoid CallStubCompiler::PatchGlobalProxy(Handle<Object> object) { 2385cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org if (object->IsGlobalObject()) { 2386cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org StackArgumentsAccessor args(rsp, arguments()); 2387cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); 2388cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ movq(args.GetReceiverOperand(), rdx); 2389cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org } 2390cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org} 2391cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org 2392cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org 2393cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.orgRegister CallStubCompiler::HandlerFrontendHeader(Handle<Object> object, 2394cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org Handle<JSObject> holder, 2395cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org Handle<Name> name, 2396cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org CheckType check, 2397cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org Label* miss) { 2398cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org GenerateNameCheck(name, miss); 2399cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org 2400cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org Register reg = rdx; 24010b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 2402662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org StackArgumentsAccessor args(rsp, arguments()); 2403cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ movq(reg, args.GetReceiverOperand()); 24040b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 24055d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Check that the receiver isn't a smi. 24065d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org if (check != NUMBER_CHECK) { 2407cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ JumpIfSmi(reg, miss); 24085d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org } 24090b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 24105d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Make sure that it's okay not to patch the on stack receiver 24115d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // unless we're doing a receiver map check. 24125d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); 24130b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 24147516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Counters* counters = isolate()->counters(); 24155d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org switch (check) { 24165d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org case RECEIVER_MAP_CHECK: 24177979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ IncrementCounter(counters->call_const(), 1); 24180b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 24195d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Check that the maps haven't changed. 2420cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org reg = CheckPrototypes(IC::CurrentTypeOf(object, isolate()), reg, holder, 2421cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org rbx, rax, rdi, name, miss); 24225d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org break; 24230b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 2424f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org case STRING_CHECK: { 24254a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // Check that the object is a string. 2426cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ CmpObjectType(reg, FIRST_NONSTRING_TYPE, rax); 2427cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ j(above_equal, miss); 24282f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org // Check that the maps starting from the prototype haven't changed. 24292f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org GenerateDirectLoadGlobalFunctionPrototype( 2430cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org masm(), Context::STRING_FUNCTION_INDEX, rax, miss); 2431c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org break; 2432f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org } 2433f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org case SYMBOL_CHECK: { 24344a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // Check that the object is a symbol. 2435cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ CmpObjectType(reg, SYMBOL_TYPE, rax); 2436cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ j(not_equal, miss); 2437f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // Check that the maps starting from the prototype haven't changed. 2438f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org GenerateDirectLoadGlobalFunctionPrototype( 2439cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org masm(), Context::SYMBOL_FUNCTION_INDEX, rax, miss); 24404a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org break; 2441f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org } 24422f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org case NUMBER_CHECK: { 24432f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org Label fast; 24442f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org // Check that the object is a smi or a heap number. 2445cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ JumpIfSmi(reg, &fast); 2446cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ CmpObjectType(reg, HEAP_NUMBER_TYPE, rax); 2447cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ j(not_equal, miss); 24482f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org __ bind(&fast); 24492f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org // Check that the maps starting from the prototype haven't changed. 24502f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org GenerateDirectLoadGlobalFunctionPrototype( 2451cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org masm(), Context::NUMBER_FUNCTION_INDEX, rax, miss); 2452c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org break; 24532f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org } 24542f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org case BOOLEAN_CHECK: { 2455cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org GenerateBooleanCheck(reg, miss); 24562f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org // Check that the maps starting from the prototype haven't changed. 24572f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org GenerateDirectLoadGlobalFunctionPrototype( 2458cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org masm(), Context::BOOLEAN_FUNCTION_INDEX, rax, miss); 24595d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org break; 24602f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org } 24615d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org } 24620b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 2463cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org if (check != RECEIVER_MAP_CHECK) { 2464cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); 2465cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org reg = CheckPrototypes( 2466cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org IC::CurrentTypeOf(prototype, isolate()), 2467cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org rax, holder, rbx, rdx, rdi, name, miss); 2468cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org } 2469b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org 2470cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org return reg; 24712f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org} 24722f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org 24732f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org 24748a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.orgvoid CallStubCompiler::GenerateJumpFunction(Handle<Object> object, 24758a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org Register function, 24768a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org Label* miss) { 24778a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org // Check that the function really is a function. 24788a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org GenerateFunctionCheck(function, rbx, miss); 24792f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org 24808a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org if (!function.is(rdi)) __ movq(rdi, function); 2481cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org PatchGlobalProxy(object); 24820b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 24838a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org // Invoke the function. 24848a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org __ InvokeFunction(rdi, arguments(), JUMP_FUNCTION, 24858a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org NullCallWrapper(), call_kind()); 24860b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org} 24870b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 24880b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 2489c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgHandle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, 2490c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSObject> holder, 2491750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Handle<Name> name) { 24920b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org Label miss; 2493c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org GenerateNameCheck(name, &miss); 24940b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 2495394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com LookupResult lookup(isolate()); 24960b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org LookupPostInterceptor(holder, name, &lookup); 24975d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 24985d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Get the receiver from the stack. 2499662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org StackArgumentsAccessor args(rsp, arguments()); 2500662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org __ movq(rdx, args.GetReceiverOperand()); 25015d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 2502ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org CallInterceptorCompiler compiler(this, arguments(), rcx, extra_state()); 2503c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org compiler.Compile(masm(), object, holder, name, &lookup, rdx, rbx, rdi, rax, 2504c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org &miss); 25055d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 25065d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Restore receiver. 2507662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org __ movq(rdx, args.GetReceiverOperand()); 25085d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 25098a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org GenerateJumpFunction(object, rax, &miss); 25105d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 25118a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org HandlerFrontendFooter(&miss); 25120b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 25130b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // Return the generated code. 25149af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org return GetCode(Code::FAST, name); 25150b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org} 25160b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 25170b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 2518c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgHandle<Code> CallStubCompiler::CompileCallGlobal( 2519c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSObject> object, 2520c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<GlobalObject> holder, 2521b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Handle<PropertyCell> cell, 2522c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSFunction> function, 2523750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Handle<Name> name) { 2524ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (HasCustomCallGenerator(function)) { 2525750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Handle<Code> code = CompileCustomCall( 25261510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org object, holder, cell, function, Handle<String>::cast(name), 25271510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Code::NORMAL); 2528c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // A null handle means bail out to the regular compiler code below. 2529c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (!code.is_null()) return code; 25305d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org } 25315d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 25320b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org Label miss; 2533cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); 25348a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org // Potentially loads a closure that matches the shared function info of the 25358a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org // function, rather than function. 25365d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org GenerateLoadFunctionFromCell(cell, function, &miss); 25377516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Counters* counters = isolate()->counters(); 25387979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ IncrementCounter(counters->call_global_inline(), 1); 25398a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org GenerateJumpFunction(object, rdi, function); 2540cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org HandlerFrontendFooter(&miss); 25410b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 25420b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // Return the generated code. 25437a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org return GetCode(Code::NORMAL, name); 25440b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org} 25450b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 25460b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 2547394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comHandle<Code> StoreStubCompiler::CompileStoreCallback( 25482bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Handle<JSObject> object, 2549355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org Handle<JSObject> holder, 2550bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org Handle<Name> name, 25517c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org Handle<ExecutableAccessorInfo> callback) { 2552f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org HandlerFrontend(IC::CurrentTypeOf(object, isolate()), 2553f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org receiver(), holder, name); 25540b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 2555594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ PopReturnAddressTo(scratch1()); 25562bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org __ push(receiver()); 2557394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Push(callback); // callback info 2558bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org __ Push(name); 25592bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org __ push(value()); 2560594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ PushReturnAddressFrom(scratch1()); 25615d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 25625d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Do tail-call to the runtime system. 25635d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org ExternalReference store_callback_property = 25647516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); 25655d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ TailCallExternalReference(store_callback_property, 4, 1); 2566e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 2567e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org // Return the generated code. 25689af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org return GetCode(kind(), Code::FAST, name); 2569639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org} 2570639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org 2571639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org 2572639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.orgHandle<Code> StoreStubCompiler::CompileStoreCallback( 2573639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org Handle<JSObject> object, 2574639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org Handle<JSObject> holder, 2575639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org Handle<Name> name, 2576639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org const CallOptimization& call_optimization) { 2577f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org HandlerFrontend(IC::CurrentTypeOf(object, isolate()), 2578f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org receiver(), holder, name); 2579639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org 2580639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org Register values[] = { value() }; 2581639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org GenerateFastApiCall( 25827ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org masm(), call_optimization, receiver(), scratch1(), 25837ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org scratch2(), this->name(), 1, values); 2584639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org 2585639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org // Return the generated code. 25869af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org return GetCode(kind(), Code::FAST, name); 25875aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org} 25885aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 25895aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 259046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org#undef __ 259146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org#define __ ACCESS_MASM(masm) 259246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 259346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 259446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.orgvoid StoreStubCompiler::GenerateStoreViaSetter( 259546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org MacroAssembler* masm, 2596619781ad24991bca2894d2f677ac960da366b11esvenpanne@chromium.org Handle<JSFunction> setter) { 25977028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // ----------- S t a t e ------------- 25987028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // -- rax : value 25997028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // -- rcx : name 26007028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // -- rdx : receiver 26017028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // -- rsp[0] : return address 26027028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // ----------------------------------- 26037028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org { 260446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org FrameScope scope(masm, StackFrame::INTERNAL); 26057028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 26067028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // Save value register, so we can restore it later. 26077028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org __ push(rax); 26087028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 260946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org if (!setter.is_null()) { 261046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Call the JavaScript setter with receiver and value on the stack. 261146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ push(rdx); 261246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ push(rax); 261346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org ParameterCount actual(1); 261432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org ParameterCount expected(setter); 261532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org __ InvokeFunction(setter, expected, actual, 261632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org CALL_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); 261746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org } else { 261846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // If we generate a global code snippet for deoptimization only, remember 261946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // the place to continue after deoptimization. 262046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset()); 262146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org } 26227028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 26237028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // We have to return the passed value, not the return value of the setter. 26247028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org __ pop(rax); 26257028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 26267028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // Restore context register. 26277028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 26287028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org } 26297028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org __ ret(0); 263046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org} 263146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 263246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 263346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org#undef __ 263446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org#define __ ACCESS_MASM(masm()) 263546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 263646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 2637394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comHandle<Code> StoreStubCompiler::CompileStoreInterceptor( 26382bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Handle<JSObject> object, 2639750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Handle<Name> name) { 2640594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ PopReturnAddressTo(scratch1()); 26412bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org __ push(receiver()); 26422bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org __ push(this->name()); 26432bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org __ push(value()); 2644594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ PushReturnAddressFrom(scratch1()); 26450b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 26460b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // Do tail-call to the runtime system. 26470b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org ExternalReference store_ic_property = 26487516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate()); 2649cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ TailCallExternalReference(store_ic_property, 3, 1); 26500b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org 26510b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org // Return the generated code. 26529af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org return GetCode(kind(), Code::FAST, name); 26535aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org} 26545aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 26555aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 2656394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comHandle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic( 2657394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com MapHandleList* receiver_maps, 2658394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com CodeHandleList* handler_stubs, 2659394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com MapHandleList* transitioned_maps) { 2660ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org Label miss; 26612bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org __ JumpIfSmi(receiver(), &miss, Label::kNear); 2662a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 26632bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org __ movq(scratch1(), FieldOperand(receiver(), HeapObject::kMapOffset)); 2664ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org int receiver_count = receiver_maps->length(); 2665b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org for (int i = 0; i < receiver_count; ++i) { 2666ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org // Check map and tail call if there's a match 26672bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org __ Cmp(scratch1(), receiver_maps->at(i)); 2668394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (transitioned_maps->at(i).is_null()) { 2669394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ j(equal, handler_stubs->at(i), RelocInfo::CODE_TARGET); 2670b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org } else { 2671b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org Label next_map; 2672b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org __ j(not_equal, &next_map, Label::kNear); 26732bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org __ movq(transition_map(), 26742bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org transitioned_maps->at(i), 26752bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org RelocInfo::EMBEDDED_OBJECT); 2676394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ jmp(handler_stubs->at(i), RelocInfo::CODE_TARGET); 2677b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org __ bind(&next_map); 2678b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org } 2679a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 2680a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2681a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org __ bind(&miss); 26822bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org 26832bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org TailCallBuiltin(masm(), MissBuiltin(kind())); 2684a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2685a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Return the generated code. 26862bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org return GetICCode( 26872bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC); 2688a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 2689a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2690a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2691f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.orgHandle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<Type> type, 2692f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Handle<JSObject> last, 2693f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Handle<Name> name) { 2694f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org NonexistentHandlerFrontend(type, last, name); 269530ce411529579186181838984710b0b0980857aaricow@chromium.org 26965d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Return undefined if maps of the full prototype chain are still the 26975d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // same and no global property with this name contains a value. 26985d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); 26995d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ ret(0); 27005d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 27015d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Return the generated code. 27029af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org return GetCode(kind(), Code::FAST, name); 27035d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org} 27045d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 27055d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 270694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.orgRegister* LoadStubCompiler::registers() { 270794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org // receiver, name, scratch1, scratch2, scratch3, scratch4. 27082f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org static Register registers[] = { rax, rcx, rdx, rbx, rdi, r8 }; 270994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org return registers; 271094b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org} 27115d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 27125d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 271394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.orgRegister* KeyedLoadStubCompiler::registers() { 271494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org // receiver, name, scratch1, scratch2, scratch3, scratch4. 271594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org static Register registers[] = { rdx, rax, rbx, rcx, rdi, r8 }; 271694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org return registers; 27175d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org} 27185d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 27195d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 27202bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.orgRegister* StoreStubCompiler::registers() { 27212bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org // receiver, name, value, scratch1, scratch2, scratch3. 27222bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org static Register registers[] = { rdx, rcx, rax, rbx, rdi, r8 }; 27232bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org return registers; 27242bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org} 27252bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org 27262bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org 27272bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.orgRegister* KeyedStoreStubCompiler::registers() { 27282bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org // receiver, name, value, scratch1, scratch2, scratch3. 27292bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org static Register registers[] = { rdx, rcx, rax, rbx, rdi, r8 }; 27302bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org return registers; 27312bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org} 27322bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org 27332bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org 2734750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgvoid KeyedLoadStubCompiler::GenerateNameCheck(Handle<Name> name, 273594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org Register name_reg, 273694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org Label* miss) { 273794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ Cmp(name_reg, name); 273894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ j(not_equal, miss); 27395d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org} 27405d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 27415d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 27422bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.orgvoid KeyedStoreStubCompiler::GenerateNameCheck(Handle<Name> name, 27432bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Register name_reg, 27442bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Label* miss) { 27452bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org __ Cmp(name_reg, name); 27462bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org __ j(not_equal, miss); 27472bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org} 27482bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org 27492bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org 2750de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org#undef __ 2751de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org#define __ ACCESS_MASM(masm) 2752de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org 2753de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org 2754de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.orgvoid LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm, 27552efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Register receiver, 2756de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org Handle<JSFunction> getter) { 2757de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org // ----------- S t a t e ------------- 2758de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org // -- rax : receiver 2759de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org // -- rcx : name 2760de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org // -- rsp[0] : return address 2761de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org // ----------------------------------- 2762de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org { 2763de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org FrameScope scope(masm, StackFrame::INTERNAL); 2764de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org 2765de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org if (!getter.is_null()) { 2766de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org // Call the JavaScript getter with the receiver on the stack. 27672efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org __ push(receiver); 2768de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org ParameterCount actual(0); 276932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org ParameterCount expected(getter); 277032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org __ InvokeFunction(getter, expected, actual, 277132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org CALL_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); 2772de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org } else { 2773de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org // If we generate a global code snippet for deoptimization only, remember 2774de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org // the place to continue after deoptimization. 2775de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset()); 2776de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org } 2777de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org 2778de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org // Restore context register. 2779de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 2780de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org } 2781de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org __ ret(0); 2782de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org} 2783de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org 2784de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org 2785de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org#undef __ 2786de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org#define __ ACCESS_MASM(masm()) 2787de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org 2788de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org 2789394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comHandle<Code> LoadStubCompiler::CompileLoadGlobal( 2790f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Handle<Type> type, 27918432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org Handle<GlobalObject> global, 2792b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Handle<PropertyCell> cell, 2793750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Handle<Name> name, 2794394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com bool is_dont_delete) { 2795b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org Label miss; 27968432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org // TODO(verwaest): Directly store to rax. Currently we cannot do this, since 27978432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org // rax is used as receiver(), which we would otherwise clobber before a 27988432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org // potential miss. 2799f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org HandlerFrontendHeader(type, receiver(), global, name, &miss); 28005d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 28015d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Get the value from the cell. 2802394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Move(rbx, cell); 2803b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ movq(rbx, FieldOperand(rbx, PropertyCell::kValueOffset)); 28045d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 28055d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Check for deleted property if property can actually be deleted. 28065d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org if (!is_dont_delete) { 28075d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex); 28085d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ j(equal, &miss); 28095d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org } else if (FLAG_debug_code) { 28105d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex); 2811594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org __ Check(not_equal, kDontDeleteCellsCannotContainTheHole); 28125d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org } 28135d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 2814b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org HandlerFrontendFooter(name, &miss); 28158432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org 28167516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Counters* counters = isolate()->counters(); 28177979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org __ IncrementCounter(counters->named_load_global_stub(), 1); 28185d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ movq(rax, rbx); 28195d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org __ ret(0); 28205d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 28215d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Return the generated code. 2822e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org return GetCode(kind(), Code::NORMAL, name); 28235d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org} 282430ce411529579186181838984710b0b0980857aaricow@chromium.org 282530ce411529579186181838984710b0b0980857aaricow@chromium.org 2826bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.orgHandle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC( 2827af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org TypeHandleList* types, 28284a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org CodeHandleList* handlers, 2829750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Handle<Name> name, 28304a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Code::StubType type, 28314a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org IcCheckType check) { 2832ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org Label miss; 2833e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 28344a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org if (check == PROPERTY) { 28354a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org GenerateNameCheck(name, this->name(), &miss); 28364a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org } 28374a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 2838b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org Label number_case; 2839af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org Label* smi_target = IncludesNumberType(types) ? &number_case : &miss; 2840b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org __ JumpIfSmi(receiver(), smi_target); 2841b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org 28424a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Register map_reg = scratch1(); 28434a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ movq(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset)); 2844af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org int receiver_count = types->length(); 2845f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org int number_of_handled_maps = 0; 2846ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org for (int current = 0; current < receiver_count; ++current) { 2847af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org Handle<Type> type = types->at(current); 2848af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org Handle<Map> map = IC::TypeToMap(*type, isolate()); 2849f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org if (!map->is_deprecated()) { 2850f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org number_of_handled_maps++; 2851f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org // Check map and tail call if there's a match 2852af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org __ Cmp(map_reg, map); 2853af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org if (type->Is(Type::Number())) { 2854b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org ASSERT(!number_case.is_unused()); 2855b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org __ bind(&number_case); 2856b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org } 2857f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ j(equal, handlers->at(current), RelocInfo::CODE_TARGET); 2858f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } 2859ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org } 2860f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org ASSERT(number_of_handled_maps > 0); 28615d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 2862ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org __ bind(&miss); 28632bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org TailCallBuiltin(masm(), MissBuiltin(kind())); 28645d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org 28655d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org // Return the generated code. 28664a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org InlineCacheState state = 2867f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org number_of_handled_maps > 1 ? POLYMORPHIC : MONOMORPHIC; 2868750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org return GetICCode(kind(), type, name, state); 2869e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org} 2870e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 2871e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 2872ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org#undef __ 2873ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org#define __ ACCESS_MASM(masm) 2874ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 2875ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 28766db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.orgvoid KeyedLoadStubCompiler::GenerateLoadDictionaryElement( 28776db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org MacroAssembler* masm) { 28786db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // ----------- S t a t e ------------- 28796db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // -- rax : key 28806db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // -- rdx : receiver 28816db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // -- rsp[0] : return address 28826db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // ----------------------------------- 2883af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org Label slow, miss; 28846db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 28856db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // This stub is meant to be tail-jumped to, the receiver must already 28866db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // have been verified by the caller to not be a smi. 28876db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 2888af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org __ JumpIfNotSmi(rax, &miss); 28896db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org __ SmiToInteger32(rbx, rax); 28906db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org __ movq(rcx, FieldOperand(rdx, JSObject::kElementsOffset)); 28916db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 28926db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Check whether the elements is a number dictionary. 28936db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // rdx: receiver 28946db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // rax: key 28956db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // rbx: key as untagged int32 28966db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // rcx: elements 28976db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org __ LoadFromNumberDictionary(&slow, rcx, rax, rbx, r9, rdi, rax); 28986db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org __ ret(0); 28996db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 29006db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org __ bind(&slow); 29016db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // ----------- S t a t e ------------- 29026db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // -- rax : key 29036db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // -- rdx : receiver 2904c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org // -- rsp[0] : return address 29056db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // ----------------------------------- 29062bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow); 29076db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 2908af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org __ bind(&miss); 29096db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // ----------- S t a t e ------------- 29106db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // -- rax : key 29116db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // -- rdx : receiver 2912c1789eecd43bf9c5497636592bf14fa754d04c89machenbach@chromium.org // -- rsp[0] : return address 29136db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // ----------------------------------- 2914af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 29156db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org} 29166db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 291728faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org 2918e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org#undef __ 2919e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org 29205aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org} } // namespace v8::internal 29219dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 29229dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com#endif // V8_TARGET_ARCH_X64 2923