105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 25c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Redistribution and use in source and binary forms, with or without 35c838251403b0be9a882540f1922577abba4c872ager@chromium.org// modification, are permitted provided that the following conditions are 45c838251403b0be9a882540f1922577abba4c872ager@chromium.org// met: 55c838251403b0be9a882540f1922577abba4c872ager@chromium.org// 65c838251403b0be9a882540f1922577abba4c872ager@chromium.org// * Redistributions of source code must retain the above copyright 75c838251403b0be9a882540f1922577abba4c872ager@chromium.org// notice, this list of conditions and the following disclaimer. 85c838251403b0be9a882540f1922577abba4c872ager@chromium.org// * Redistributions in binary form must reproduce the above 95c838251403b0be9a882540f1922577abba4c872ager@chromium.org// copyright notice, this list of conditions and the following 105c838251403b0be9a882540f1922577abba4c872ager@chromium.org// disclaimer in the documentation and/or other materials provided 115c838251403b0be9a882540f1922577abba4c872ager@chromium.org// with the distribution. 125c838251403b0be9a882540f1922577abba4c872ager@chromium.org// * Neither the name of Google Inc. nor the names of its 135c838251403b0be9a882540f1922577abba4c872ager@chromium.org// contributors may be used to endorse or promote products derived 145c838251403b0be9a882540f1922577abba4c872ager@chromium.org// from this software without specific prior written permission. 155c838251403b0be9a882540f1922577abba4c872ager@chromium.org// 165c838251403b0be9a882540f1922577abba4c872ager@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 175c838251403b0be9a882540f1922577abba4c872ager@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 185c838251403b0be9a882540f1922577abba4c872ager@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 195c838251403b0be9a882540f1922577abba4c872ager@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 205c838251403b0be9a882540f1922577abba4c872ager@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 215c838251403b0be9a882540f1922577abba4c872ager@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 225c838251403b0be9a882540f1922577abba4c872ager@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 235c838251403b0be9a882540f1922577abba4c872ager@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 245c838251403b0be9a882540f1922577abba4c872ager@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 255c838251403b0be9a882540f1922577abba4c872ager@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 265c838251403b0be9a882540f1922577abba4c872ager@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 275c838251403b0be9a882540f1922577abba4c872ager@chromium.org 285c838251403b0be9a882540f1922577abba4c872ager@chromium.org#include "v8.h" 295c838251403b0be9a882540f1922577abba4c872ager@chromium.org 3093a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_MIPS 319dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 325c838251403b0be9a882540f1922577abba4c872ager@chromium.org#include "ic-inl.h" 3383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org#include "codegen.h" 345c838251403b0be9a882540f1922577abba4c872ager@chromium.org#include "stub-cache.h" 355c838251403b0be9a882540f1922577abba4c872ager@chromium.org 365c838251403b0be9a882540f1922577abba4c872ager@chromium.orgnamespace v8 { 375c838251403b0be9a882540f1922577abba4c872ager@chromium.orgnamespace internal { 385c838251403b0be9a882540f1922577abba4c872ager@chromium.org 395c838251403b0be9a882540f1922577abba4c872ager@chromium.org#define __ ACCESS_MASM(masm) 405c838251403b0be9a882540f1922577abba4c872ager@chromium.org 415c838251403b0be9a882540f1922577abba4c872ager@chromium.org 42c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.orgstatic void ProbeTable(Isolate* isolate, 43c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org MacroAssembler* masm, 44c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Code::Flags flags, 45c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org StubCache::Table table, 4635814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org Register receiver, 47c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Register name, 4835814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org // Number of the cache entry, not scaled. 49c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Register offset, 50c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Register scratch, 5135814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org Register scratch2, 5235814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org Register offset_scratch) { 53c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ExternalReference key_offset(isolate->stub_cache()->key_reference(table)); 54c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ExternalReference value_offset(isolate->stub_cache()->value_reference(table)); 5535814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org ExternalReference map_offset(isolate->stub_cache()->map_reference(table)); 56c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 57c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org uint32_t key_off_addr = reinterpret_cast<uint32_t>(key_offset.address()); 58c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org uint32_t value_off_addr = reinterpret_cast<uint32_t>(value_offset.address()); 5935814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org uint32_t map_off_addr = reinterpret_cast<uint32_t>(map_offset.address()); 60c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 61c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check the relative positions of the address fields. 62c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(value_off_addr > key_off_addr); 63c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT((value_off_addr - key_off_addr) % 4 == 0); 64c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT((value_off_addr - key_off_addr) < (256 * 4)); 6535814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org ASSERT(map_off_addr > key_off_addr); 6635814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org ASSERT((map_off_addr - key_off_addr) % 4 == 0); 6735814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org ASSERT((map_off_addr - key_off_addr) < (256 * 4)); 68c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 69c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label miss; 7035814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org Register base_addr = scratch; 7135814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org scratch = no_reg; 7235814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org 7335814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org // Multiply by 3 because there are 3 fields per entry (name, code, map). 7435814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ sll(offset_scratch, offset, 1); 7535814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ Addu(offset_scratch, offset_scratch, offset); 7635814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org 7735814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org // Calculate the base address of the entry. 7835814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ li(base_addr, Operand(key_offset)); 7935814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ sll(at, offset_scratch, kPointerSizeLog2); 8035814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ Addu(base_addr, base_addr, at); 81c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 82c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check that the key in the entry matches the name. 8335814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ lw(at, MemOperand(base_addr, 0)); 8435814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ Branch(&miss, ne, name, Operand(at)); 8535814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org 8635814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org // Check the map matches. 8735814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ lw(at, MemOperand(base_addr, map_off_addr - key_off_addr)); 8835814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ lw(scratch2, FieldMemOperand(receiver, HeapObject::kMapOffset)); 8935814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ Branch(&miss, ne, at, Operand(scratch2)); 90c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 91c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Get the code entry from the cache. 9235814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org Register code = scratch2; 9335814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org scratch2 = no_reg; 9435814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ lw(code, MemOperand(base_addr, value_off_addr - key_off_addr)); 95c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 96c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check that the flags match what we're looking for. 9735814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org Register flags_reg = base_addr; 9835814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org base_addr = no_reg; 9935814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ lw(flags_reg, FieldMemOperand(code, Code::kFlagsOffset)); 10035814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ And(flags_reg, flags_reg, Operand(~Code::kFlagsNotUsedInLookup)); 10135814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ Branch(&miss, ne, flags_reg, Operand(flags)); 10235814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org 10335814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org#ifdef DEBUG 10435814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org if (FLAG_test_secondary_stub_cache && table == StubCache::kPrimary) { 10535814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ jmp(&miss); 10635814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org } else if (FLAG_test_primary_stub_cache && table == StubCache::kSecondary) { 10735814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ jmp(&miss); 10835814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org } 10935814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org#endif 110c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 111c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Jump to the first instruction in the code stub. 11235814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ Addu(at, code, Operand(Code::kHeaderSize - kHeapObjectTag)); 11335814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ Jump(at); 114c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 115c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Miss: fall through. 116c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&miss); 117c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org} 118c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 119c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 120057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.orgvoid StubCompiler::GenerateDictionaryNegativeLookup(MacroAssembler* masm, 121057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org Label* miss_label, 122057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org Register receiver, 123057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org Handle<Name> name, 124057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org Register scratch0, 125057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org Register scratch1) { 1269faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org ASSERT(name->IsUniqueName()); 127057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org ASSERT(!receiver.is(scratch0)); 128394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Counters* counters = masm->isolate()->counters(); 129394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); 130394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); 131394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 132394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Label done; 133394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 134394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com const int kInterceptorOrAccessCheckNeededMask = 135394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); 136394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 137394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Bail out if the receiver has a named interceptor or requires access checks. 138394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Register map = scratch1; 139394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ lw(map, FieldMemOperand(receiver, HeapObject::kMapOffset)); 140394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ lbu(scratch0, FieldMemOperand(map, Map::kBitFieldOffset)); 141394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ And(scratch0, scratch0, Operand(kInterceptorOrAccessCheckNeededMask)); 142394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Branch(miss_label, ne, scratch0, Operand(zero_reg)); 143394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 144394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Check that receiver is a JSObject. 145394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ lbu(scratch0, FieldMemOperand(map, Map::kInstanceTypeOffset)); 146394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Branch(miss_label, lt, scratch0, Operand(FIRST_SPEC_OBJECT_TYPE)); 147394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 148394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Load properties array. 149394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Register properties = scratch0; 150394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ lw(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); 151394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Check that the properties array is a dictionary. 152394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ lw(map, FieldMemOperand(properties, HeapObject::kMapOffset)); 153394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Register tmp = properties; 154394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ LoadRoot(tmp, Heap::kHashTableMapRootIndex); 155394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Branch(miss_label, ne, map, Operand(tmp)); 156394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 157394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Restore the temporarily used register. 158394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ lw(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); 159394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 160394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1619faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org NameDictionaryLookupStub::GenerateNegativeLookup(masm, 1629faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org miss_label, 1639faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org &done, 1649faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org receiver, 1659faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org properties, 1669faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org name, 1679faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org scratch1); 168394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ bind(&done); 169394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); 170394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com} 171394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 172394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1735c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid StubCache::GenerateProbe(MacroAssembler* masm, 1745c838251403b0be9a882540f1922577abba4c872ager@chromium.org Code::Flags flags, 1755c838251403b0be9a882540f1922577abba4c872ager@chromium.org Register receiver, 1765c838251403b0be9a882540f1922577abba4c872ager@chromium.org Register name, 1775c838251403b0be9a882540f1922577abba4c872ager@chromium.org Register scratch, 178e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org Register extra, 17935814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org Register extra2, 18035814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org Register extra3) { 181c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Isolate* isolate = masm->isolate(); 182c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label miss; 183c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 18435814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org // Make sure that code is valid. The multiplying code relies on the 18535814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org // entry size being 12. 18635814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org ASSERT(sizeof(Entry) == 12); 187c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 188c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Make sure the flags does not name a specific type. 189c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(Code::ExtractTypeFromFlags(flags) == 0); 190c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 191c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Make sure that there are no register conflicts. 192c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(!scratch.is(receiver)); 193c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(!scratch.is(name)); 194c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(!extra.is(receiver)); 195c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(!extra.is(name)); 196c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(!extra.is(scratch)); 197c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(!extra2.is(receiver)); 198c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(!extra2.is(name)); 199c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(!extra2.is(scratch)); 200c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(!extra2.is(extra)); 201c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 20235814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org // Check register validity. 203c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(!scratch.is(no_reg)); 204c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(!extra.is(no_reg)); 205c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(!extra2.is(no_reg)); 20635814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org ASSERT(!extra3.is(no_reg)); 20735814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org 20835814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org Counters* counters = masm->isolate()->counters(); 20935814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ IncrementCounter(counters->megamorphic_stub_cache_probes(), 1, 21035814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org extra2, extra3); 211c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 212c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check that the receiver isn't a smi. 21335814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ JumpIfSmi(receiver, &miss); 214c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 215c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Get the map of the receiver and compute the hash. 2169faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org __ lw(scratch, FieldMemOperand(name, Name::kHashFieldOffset)); 21735814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ lw(at, FieldMemOperand(receiver, HeapObject::kMapOffset)); 21835814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ Addu(scratch, scratch, at); 21935814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org uint32_t mask = kPrimaryTableSize - 1; 22035814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org // We shift out the last two bits because they are not part of the hash and 22135814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org // they are always 01 for maps. 22235814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ srl(scratch, scratch, kHeapObjectTagSize); 22335814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ Xor(scratch, scratch, Operand((flags >> kHeapObjectTagSize) & mask)); 22435814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ And(scratch, scratch, Operand(mask)); 225c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 226c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Probe the primary table. 22735814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org ProbeTable(isolate, 22835814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org masm, 22935814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org flags, 23035814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org kPrimary, 23135814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org receiver, 23235814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org name, 23335814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org scratch, 23435814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org extra, 23535814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org extra2, 23635814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org extra3); 237c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 238c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Primary miss: Compute hash for secondary probe. 23935814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ srl(at, name, kHeapObjectTagSize); 24035814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ Subu(scratch, scratch, at); 24135814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org uint32_t mask2 = kSecondaryTableSize - 1; 24235814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ Addu(scratch, scratch, Operand((flags >> kHeapObjectTagSize) & mask2)); 24335814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ And(scratch, scratch, Operand(mask2)); 244c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 245c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Probe the secondary table. 24635814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org ProbeTable(isolate, 24735814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org masm, 24835814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org flags, 24935814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org kSecondary, 25035814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org receiver, 25135814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org name, 25235814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org scratch, 25335814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org extra, 25435814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org extra2, 25535814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org extra3); 256c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 257c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Cache miss: Fall-through and let caller handle the miss by 258c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // entering the runtime system. 259c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&miss); 26035814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ IncrementCounter(counters->megamorphic_stub_cache_misses(), 1, 26135814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org extra2, extra3); 2625c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 2635c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2645c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2655c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid StubCompiler::GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm, 2665c838251403b0be9a882540f1922577abba4c872ager@chromium.org int index, 2675c838251403b0be9a882540f1922577abba4c872ager@chromium.org Register prototype) { 268c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Load the global or builtins object from the current context. 269c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(prototype, 27046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 27146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Load the native context from the global or builtins object. 27246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ lw(prototype, 27346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org FieldMemOperand(prototype, GlobalObject::kNativeContextOffset)); 27446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Load the function from the native context. 275c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(prototype, MemOperand(prototype, Context::SlotOffset(index))); 276c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Load the initial map. The global functions all have initial maps. 277c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(prototype, 278c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org FieldMemOperand(prototype, JSFunction::kPrototypeOrInitialMapOffset)); 279c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Load the prototype from the initial map. 280c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset)); 2815c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 2825c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2835c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2847516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid StubCompiler::GenerateDirectLoadGlobalFunctionPrototype( 285c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org MacroAssembler* masm, 286c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org int index, 287c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register prototype, 288c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label* miss) { 289c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Isolate* isolate = masm->isolate(); 290c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check we're still in the same context. 29146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ lw(prototype, 29246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 293c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(!prototype.is(at)); 29446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ li(at, isolate->global_object()); 295c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Branch(miss, ne, prototype, Operand(at)); 296c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Get the global function with the given index. 297c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSFunction> function( 29846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org JSFunction::cast(isolate->native_context()->get(index))); 299c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Load its initial map. The global functions all have initial maps. 300c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ li(prototype, Handle<Map>(function->initial_map())); 301c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Load the prototype from the initial map. 302c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset)); 3037516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 3047516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 3057516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 30657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.orgvoid StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm, 30757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Register dst, 30857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Register src, 30957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org bool inobject, 31057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org int index, 31157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Representation representation) { 31257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org ASSERT(!FLAG_track_double_fields || !representation.IsDouble()); 3139faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org int offset = index * kPointerSize; 3149faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org if (!inobject) { 3159faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org // Calculate the offset into the properties array. 3169faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org offset = offset + FixedArray::kHeaderSize; 3179faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org __ lw(dst, FieldMemOperand(src, JSObject::kPropertiesOffset)); 3189faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org src = dst; 319c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 3209faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org __ lw(dst, FieldMemOperand(src, offset)); 3215c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 3225c838251403b0be9a882540f1922577abba4c872ager@chromium.org 3235c838251403b0be9a882540f1922577abba4c872ager@chromium.org 3245c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid StubCompiler::GenerateLoadArrayLength(MacroAssembler* masm, 3255c838251403b0be9a882540f1922577abba4c872ager@chromium.org Register receiver, 3265c838251403b0be9a882540f1922577abba4c872ager@chromium.org Register scratch, 3275c838251403b0be9a882540f1922577abba4c872ager@chromium.org Label* miss_label) { 328c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check that the receiver isn't a smi. 329c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ JumpIfSmi(receiver, miss_label); 330c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 331c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check that the object is a JS array. 332c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ GetObjectType(receiver, scratch, scratch); 333c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Branch(miss_label, ne, scratch, Operand(JS_ARRAY_TYPE)); 334c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 335c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Load length directly from the JS array. 3368a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ Ret(USE_DELAY_SLOT); 337c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset)); 338c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org} 339c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 340c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 341c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org// Generate code to check if an object is a string. If the object is a 342c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org// heap object, its map's instance type is left in the scratch1 register. 343c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org// If this is not needed, scratch1 and scratch2 may be the same register. 344c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.orgstatic void GenerateStringCheck(MacroAssembler* masm, 345c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Register receiver, 346c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Register scratch1, 347c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Register scratch2, 348c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label* smi, 349c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label* non_string_object) { 350c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check that the receiver isn't a smi. 351c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ JumpIfSmi(receiver, smi, t0); 352c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 353c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check that the object is a string. 354c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(scratch1, FieldMemOperand(receiver, HeapObject::kMapOffset)); 355c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lbu(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset)); 356c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ And(scratch2, scratch1, Operand(kIsNotStringMask)); 357c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // The cast is to resolve the overload for the argument of 0x0. 358c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Branch(non_string_object, 359c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ne, 360c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org scratch2, 361c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Operand(static_cast<int32_t>(kStringTag))); 3625c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 3635c838251403b0be9a882540f1922577abba4c872ager@chromium.org 3645c838251403b0be9a882540f1922577abba4c872ager@chromium.org 3657516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// Generate code to load the length from a string object and return the length. 3667516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// If the receiver object is not a string or a wrapped string object the 3677516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// execution continues at the miss label. The register containing the 3687516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// receiver is potentially clobbered. 3697516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid StubCompiler::GenerateLoadStringLength(MacroAssembler* masm, 3707516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Register receiver, 3717516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Register scratch1, 3727516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Register scratch2, 373528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Label* miss) { 374c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label check_wrapper; 375c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 376c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check if the object is a string leaving the instance type in the 377c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // scratch1 register. 378528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org GenerateStringCheck(masm, receiver, scratch1, scratch2, miss, &check_wrapper); 379c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 380c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Load length directly from the string. 3818a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ Ret(USE_DELAY_SLOT); 382c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(v0, FieldMemOperand(receiver, String::kLengthOffset)); 383c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 384528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Check if the object is a JSValue wrapper. 385528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ bind(&check_wrapper); 386528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ Branch(miss, ne, scratch1, Operand(JS_VALUE_TYPE)); 387c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 388528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Unwrap the value and check if the wrapped value is a string. 389528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ lw(scratch1, FieldMemOperand(receiver, JSValue::kValueOffset)); 390528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org GenerateStringCheck(masm, scratch1, scratch2, scratch2, miss, miss); 391528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ Ret(USE_DELAY_SLOT); 392528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org __ lw(v0, FieldMemOperand(scratch1, String::kLengthOffset)); 3937516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 3947516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 3957516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 3965c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid StubCompiler::GenerateLoadFunctionPrototype(MacroAssembler* masm, 3975c838251403b0be9a882540f1922577abba4c872ager@chromium.org Register receiver, 3985c838251403b0be9a882540f1922577abba4c872ager@chromium.org Register scratch1, 3995c838251403b0be9a882540f1922577abba4c872ager@chromium.org Register scratch2, 4005c838251403b0be9a882540f1922577abba4c872ager@chromium.org Label* miss_label) { 401c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label); 4028a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ Ret(USE_DELAY_SLOT); 403c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ mov(v0, scratch1); 4045c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 4055c838251403b0be9a882540f1922577abba4c872ager@chromium.org 4065c838251403b0be9a882540f1922577abba4c872ager@chromium.org 407057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.orgvoid StubCompiler::GenerateCheckPropertyCell(MacroAssembler* masm, 408057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org Handle<JSGlobalObject> global, 409057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org Handle<Name> name, 410057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org Register scratch, 411057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org Label* miss) { 412057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org Handle<Cell> cell = JSGlobalObject::EnsurePropertyCell(global, name); 413e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(cell->value()->IsTheHole()); 414e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ li(scratch, Operand(cell)); 415f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org __ lw(scratch, FieldMemOperand(scratch, Cell::kValueOffset)); 416e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 417e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ Branch(miss, ne, scratch, Operand(at)); 418e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 419e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 420e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 4212efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgvoid StoreStubCompiler::GenerateNegativeHolderLookup( 422bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org MacroAssembler* masm, 423bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org Handle<JSObject> holder, 424bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org Register holder_reg, 425bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org Handle<Name> name, 426bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org Label* miss) { 427bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org if (holder->IsJSGlobalObject()) { 428bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org GenerateCheckPropertyCell( 429057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org masm, Handle<JSGlobalObject>::cast(holder), name, scratch1(), miss); 430bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { 431bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org GenerateDictionaryNegativeLookup( 432bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org masm, miss, holder_reg, name, scratch1(), scratch2()); 433bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } 434bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org} 435bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 436bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 437e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// Generate StoreTransition code, value is passed in a0 register. 4385c838251403b0be9a882540f1922577abba4c872ager@chromium.org// After executing generated code, the receiver_reg and name_reg 4395c838251403b0be9a882540f1922577abba4c872ager@chromium.org// may be clobbered. 4402efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgvoid StoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm, 4412efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Handle<JSObject> object, 4422efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org LookupResult* lookup, 4432efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Handle<Map> transition, 4442efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Handle<Name> name, 4452efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Register receiver_reg, 4462efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Register storage_reg, 4472efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Register value_reg, 4482efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Register scratch1, 4492efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Register scratch2, 4502efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Register scratch3, 4512efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Label* miss_label, 4522efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Label* slow) { 453c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // a0 : value. 454c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label exit; 4557028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 456f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org int descriptor = transition->LastAdded(); 457f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org DescriptorArray* descriptors = transition->instance_descriptors(); 458f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org PropertyDetails details = descriptors->GetDetails(descriptor); 459f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org Representation representation = details.representation(); 460f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org ASSERT(!representation.IsNone()); 461f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 462fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org if (details.type() == CONSTANT) { 463fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org Handle<Object> constant(descriptors->GetValue(descriptor), masm->isolate()); 464057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org __ li(scratch1, constant); 465bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org __ Branch(miss_label, ne, value_reg, Operand(scratch1)); 466b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org } else if (FLAG_track_fields && representation.IsSmi()) { 467bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org __ JumpIfNotSmi(value_reg, miss_label); 468906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { 469bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org __ JumpIfSmi(value_reg, miss_label); 47057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } else if (FLAG_track_double_fields && representation.IsDouble()) { 47157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Label do_store, heap_number; 47257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ LoadRoot(scratch3, Heap::kHeapNumberMapRootIndex); 47357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ AllocateHeapNumber(storage_reg, scratch1, scratch2, scratch3, slow); 47457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 47557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ JumpIfNotSmi(value_reg, &heap_number); 47657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ SmiUntag(scratch1, value_reg); 47757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ mtc1(scratch1, f6); 47857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ cvt_d_w(f4, f6); 47957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ jmp(&do_store); 48057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 48157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ bind(&heap_number); 48257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex, 483bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org miss_label, DONT_DO_SMI_CHECK); 48457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ ldc1(f4, FieldMemOperand(value_reg, HeapNumber::kValueOffset)); 48557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 48657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ bind(&do_store); 48757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ sdc1(f4, FieldMemOperand(storage_reg, HeapNumber::kValueOffset)); 48857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } 48957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 490c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Stub never generated for non-global objects that require access 491c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // checks. 492c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 493c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 494c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Perform map transition for the receiver if necessary. 495b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org if (details.type() == FIELD && 496b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org object->map()->unused_property_fields() == 0) { 497c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // The properties must be extended before we can store the value. 498c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // We jump to a runtime call that extends the properties array. 499c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ push(receiver_reg); 5006e28b5694dd5a29d2f37d56d5a005e7cfdd952d1erik.corry@gmail.com __ li(a2, Operand(transition)); 501c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Push(a2, a0); 502c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ TailCallExternalReference( 503c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), 504c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org masm->isolate()), 505c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 3, 1); 506c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org return; 507c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 508c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 509e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Update the map of the object. 510e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ li(scratch1, Operand(transition)); 511e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ sw(scratch1, FieldMemOperand(receiver_reg, HeapObject::kMapOffset)); 512e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 513bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org // Update the write barrier for the map field. 514e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ RecordWriteField(receiver_reg, 515e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org HeapObject::kMapOffset, 516e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org scratch1, 51757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org scratch2, 518e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org kRAHasNotBeenSaved, 519e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org kDontSaveFPRegs, 520e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org OMIT_REMEMBERED_SET, 521e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org OMIT_SMI_CHECK); 522e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 523fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org if (details.type() == CONSTANT) { 524b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org ASSERT(value_reg.is(a0)); 525b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ Ret(USE_DELAY_SLOT); 526b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ mov(v0, a0); 527b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org return; 528b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org } 529b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 530e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org int index = transition->instance_descriptors()->GetFieldIndex( 531e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org transition->LastAdded()); 532e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 533e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Adjust for the number of properties stored in the object. Even in the 534e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // face of a transition we can use the old map here because the size of the 535e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // object and the number of in-object properties is not going to change. 536e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org index -= object->map()->inobject_properties(); 537e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 538e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // TODO(verwaest): Share this code as a code stub. 539a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org SmiCheck smi_check = representation.IsTagged() 540a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org ? INLINE_SMI_CHECK : OMIT_SMI_CHECK; 541e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (index < 0) { 542e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Set the property straight into the object. 543e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org int offset = object->map()->instance_size() + (index * kPointerSize); 54457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org if (FLAG_track_double_fields && representation.IsDouble()) { 54557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ sw(storage_reg, FieldMemOperand(receiver_reg, offset)); 54657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } else { 54757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ sw(value_reg, FieldMemOperand(receiver_reg, offset)); 54857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } 549e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 550f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org if (!FLAG_track_fields || !representation.IsSmi()) { 551f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org // Update the write barrier for the array address. 55257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org if (!FLAG_track_double_fields || !representation.IsDouble()) { 553bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org __ mov(storage_reg, value_reg); 55457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } 555f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ RecordWriteField(receiver_reg, 556f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org offset, 557bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org storage_reg, 558f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org scratch1, 559f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org kRAHasNotBeenSaved, 560a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org kDontSaveFPRegs, 561a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org EMIT_REMEMBERED_SET, 562a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org smi_check); 563f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } 564f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org } else { 565e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Write to the properties array. 566e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org int offset = index * kPointerSize + FixedArray::kHeaderSize; 567e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Get the properties array 568e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ lw(scratch1, 569e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset)); 57057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org if (FLAG_track_double_fields && representation.IsDouble()) { 57157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ sw(storage_reg, FieldMemOperand(scratch1, offset)); 57257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } else { 57357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ sw(value_reg, FieldMemOperand(scratch1, offset)); 57457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } 575e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 576f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org if (!FLAG_track_fields || !representation.IsSmi()) { 577f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org // Update the write barrier for the array address. 57857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org if (!FLAG_track_double_fields || !representation.IsDouble()) { 579bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org __ mov(storage_reg, value_reg); 58057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } 581f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ RecordWriteField(scratch1, 582f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org offset, 583bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org storage_reg, 584f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org receiver_reg, 585f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org kRAHasNotBeenSaved, 586a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org kDontSaveFPRegs, 587a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org EMIT_REMEMBERED_SET, 588a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org smi_check); 589f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } 590e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 591e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 592e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Return the value (register v0). 593e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(value_reg.is(a0)); 594e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ bind(&exit); 5958a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ Ret(USE_DELAY_SLOT); 596e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ mov(v0, a0); 597e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 598e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 599e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 600e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// Generate StoreField code, value is passed in a0 register. 601e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// When leaving generated code after success, the receiver_reg and name_reg 602e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// may be clobbered. Upon branch to miss_label, the receiver and name 603e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// registers have their original values. 6042efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgvoid StoreStubCompiler::GenerateStoreField(MacroAssembler* masm, 6052efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Handle<JSObject> object, 6062efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org LookupResult* lookup, 6072efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Register receiver_reg, 6082efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Register name_reg, 6092efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Register value_reg, 6102efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Register scratch1, 6112efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Register scratch2, 6122efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Label* miss_label) { 613e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // a0 : value 614e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Label exit; 615e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 616e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Stub never generated for non-global objects that require access 617e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // checks. 618e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 619e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 620e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org int index = lookup->GetFieldIndex().field_index(); 621e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 622c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Adjust for the number of properties stored in the object. Even in the 623c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // face of a transition we can use the old map here because the size of the 624c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // object and the number of in-object properties is not going to change. 625c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org index -= object->map()->inobject_properties(); 626c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 627f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org Representation representation = lookup->representation(); 628f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org ASSERT(!representation.IsNone()); 629f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org if (FLAG_track_fields && representation.IsSmi()) { 630f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ JumpIfNotSmi(value_reg, miss_label); 631906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { 632906e2fb760f52fe6e75b744b1ea42576ea5b2c29ulan@chromium.org __ JumpIfSmi(value_reg, miss_label); 633f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } else if (FLAG_track_double_fields && representation.IsDouble()) { 63457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org // Load the double storage. 63557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org if (index < 0) { 63657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org int offset = object->map()->instance_size() + (index * kPointerSize); 63757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ lw(scratch1, FieldMemOperand(receiver_reg, offset)); 63857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } else { 63957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ lw(scratch1, 64057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset)); 64157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org int offset = index * kPointerSize + FixedArray::kHeaderSize; 64257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ lw(scratch1, FieldMemOperand(scratch1, offset)); 64357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } 64457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 64557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org // Store the value into the storage. 64657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Label do_store, heap_number; 64757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ JumpIfNotSmi(value_reg, &heap_number); 64857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ SmiUntag(scratch2, value_reg); 64957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ mtc1(scratch2, f6); 65057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ cvt_d_w(f4, f6); 65157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ jmp(&do_store); 65257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 65357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ bind(&heap_number); 65457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ CheckMap(value_reg, scratch2, Heap::kHeapNumberMapRootIndex, 655f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org miss_label, DONT_DO_SMI_CHECK); 65657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ ldc1(f4, FieldMemOperand(value_reg, HeapNumber::kValueOffset)); 65757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 658f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ bind(&do_store); 65957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ sdc1(f4, FieldMemOperand(scratch1, HeapNumber::kValueOffset)); 66057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org // Return the value (register v0). 66157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org ASSERT(value_reg.is(a0)); 6628a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ Ret(USE_DELAY_SLOT); 66357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ mov(v0, a0); 66457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org return; 665f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } 666f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 667e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // TODO(verwaest): Share this code as a code stub. 668a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org SmiCheck smi_check = representation.IsTagged() 669a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org ? INLINE_SMI_CHECK : OMIT_SMI_CHECK; 670c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (index < 0) { 671c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Set the property straight into the object. 672c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org int offset = object->map()->instance_size() + (index * kPointerSize); 6732bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org __ sw(value_reg, FieldMemOperand(receiver_reg, offset)); 674c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 675f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org if (!FLAG_track_fields || !representation.IsSmi()) { 676f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org // Skip updating write barrier if storing a smi. 677f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ JumpIfSmi(value_reg, &exit); 678f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 679f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org // Update the write barrier for the array address. 680f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org // Pass the now unused name_reg as a scratch register. 681f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ mov(name_reg, value_reg); 682f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ RecordWriteField(receiver_reg, 683f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org offset, 684f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org name_reg, 685f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org scratch1, 686f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org kRAHasNotBeenSaved, 687a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org kDontSaveFPRegs, 688a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org EMIT_REMEMBERED_SET, 689a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org smi_check); 690f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } 691c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } else { 692c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Write to the properties array. 693c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org int offset = index * kPointerSize + FixedArray::kHeaderSize; 694c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Get the properties array. 6957028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org __ lw(scratch1, 6967028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset)); 6972bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org __ sw(value_reg, FieldMemOperand(scratch1, offset)); 698c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 699f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org if (!FLAG_track_fields || !representation.IsSmi()) { 700f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org // Skip updating write barrier if storing a smi. 701f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ JumpIfSmi(value_reg, &exit); 702f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 703f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org // Update the write barrier for the array address. 704f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org // Ok to clobber receiver_reg and name_reg, since we return. 705f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ mov(name_reg, value_reg); 706f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ RecordWriteField(scratch1, 707f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org offset, 708f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org name_reg, 709f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org receiver_reg, 710f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org kRAHasNotBeenSaved, 711a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org kDontSaveFPRegs, 712a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org EMIT_REMEMBERED_SET, 713a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org smi_check); 714f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } 715c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 716c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 717c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Return the value (register v0). 7182bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org ASSERT(value_reg.is(a0)); 719c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&exit); 7208a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ Ret(USE_DELAY_SLOT); 721c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ mov(v0, a0); 7225c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 7235c838251403b0be9a882540f1922577abba4c872ager@chromium.org 7245c838251403b0be9a882540f1922577abba4c872ager@chromium.org 7252efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgvoid StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm, 7262efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Label* label, 7272efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Handle<Name> name) { 7282bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org if (!label->is_unused()) { 7292bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org __ bind(label); 7302bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org __ li(this->name(), Operand(name)); 7312bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org } 732068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org} 733068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org 734068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org 735c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.orgstatic void PushInterceptorArguments(MacroAssembler* masm, 736c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Register receiver, 737c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Register holder, 738c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Register name, 739c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSObject> holder_obj) { 7404a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org STATIC_ASSERT(StubCache::kInterceptorArgsNameIndex == 0); 7414a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org STATIC_ASSERT(StubCache::kInterceptorArgsInfoIndex == 1); 7424a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org STATIC_ASSERT(StubCache::kInterceptorArgsThisIndex == 2); 7434a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org STATIC_ASSERT(StubCache::kInterceptorArgsHolderIndex == 3); 7444a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org STATIC_ASSERT(StubCache::kInterceptorArgsLength == 4); 745c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ push(name); 746c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<InterceptorInfo> interceptor(holder_obj->GetNamedInterceptor()); 747c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(!masm->isolate()->heap()->InNewSpace(*interceptor)); 748c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Register scratch = name; 749c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ li(scratch, Operand(interceptor)); 750c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Push(scratch, receiver, holder); 751c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org} 752c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 753c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 754c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgstatic void CompileCallLoadPropertyWithInterceptor( 755c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org MacroAssembler* masm, 756c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register receiver, 757c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register holder, 758c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register name, 75937be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org Handle<JSObject> holder_obj, 76037be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org IC::UtilityId id) { 761c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org PushInterceptorArguments(masm, receiver, holder, name, holder_obj); 76237be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org __ CallExternalReference( 76337be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org ExternalReference(IC_Utility(id), masm->isolate()), 76437be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org StubCache::kInterceptorArgsLength); 765c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org} 766c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 767c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 768bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.orgstatic const int kFastApiCallArguments = FunctionCallbackArguments::kArgsLength; 769c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 770ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com// Reserves space for the extra arguments to API function in the 771c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org// caller's frame. 772c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org// 773c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org// These arguments are set by CheckPrototypes and GenerateFastApiDirectCall. 774c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.orgstatic void ReserveSpaceForFastApiCall(MacroAssembler* masm, 775c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Register scratch) { 776c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(Smi::FromInt(0) == 0); 777c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org for (int i = 0; i < kFastApiCallArguments; i++) { 778c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ push(zero_reg); 779c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 780c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org} 781c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 782c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 783c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org// Undoes the effects of ReserveSpaceForFastApiCall. 784c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.orgstatic void FreeSpaceForFastApiCall(MacroAssembler* masm) { 785c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Drop(kFastApiCallArguments); 7865c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 7875c838251403b0be9a882540f1922577abba4c872ager@chromium.org 7885c838251403b0be9a882540f1922577abba4c872ager@chromium.org 789c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgstatic void GenerateFastApiDirectCall(MacroAssembler* masm, 790c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org const CallOptimization& optimization, 791528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org int argc, 792528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org bool restore_context) { 793c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // ----------- S t a t e ------------- 794cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org // -- sp[0] - sp[24] : FunctionCallbackInfo, incl. 795cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org // : holder (set by CheckPrototypes) 796528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // -- sp[28] : last JS argument 797c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // -- ... 798528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // -- sp[(argc + 6) * 4] : first JS argument 799528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // -- sp[(argc + 7) * 4] : receiver 800c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // ----------------------------------- 801cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org typedef FunctionCallbackArguments FCA; 802528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Save calling context. 803fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org __ sw(cp, MemOperand(sp, FCA::kContextSaveIndex * kPointerSize)); 804c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Get the function and setup the context. 805c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSFunction> function = optimization.constant_function(); 806057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org __ li(t1, function); 807c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(cp, FieldMemOperand(t1, JSFunction::kContextOffset)); 808fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org __ sw(t1, MemOperand(sp, FCA::kCalleeIndex * kPointerSize)); 809c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 810cfdf67d672b8e2cd6cc1df14c082671511745746machenbach@chromium.org // Construct the FunctionCallbackInfo. 811c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); 81209d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org Handle<Object> call_data(api_call_info->data(), masm->isolate()); 813c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (masm->isolate()->heap()->InNewSpace(*call_data)) { 814c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ li(a0, api_call_info); 815c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(t2, FieldMemOperand(a0, CallHandlerInfo::kDataOffset)); 816c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } else { 817c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ li(t2, call_data); 818c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 819528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Store call data. 820fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org __ sw(t2, MemOperand(sp, FCA::kDataIndex * kPointerSize)); 821528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Store isolate. 82232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org __ li(t3, Operand(ExternalReference::isolate_address(masm->isolate()))); 823fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org __ sw(t3, MemOperand(sp, FCA::kIsolateIndex * kPointerSize)); 824528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org // Store ReturnValue default and ReturnValue. 825bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org __ LoadRoot(t1, Heap::kUndefinedValueRootIndex); 826fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org __ sw(t1, MemOperand(sp, FCA::kReturnValueOffset * kPointerSize)); 827fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org __ sw(t1, MemOperand(sp, FCA::kReturnValueDefaultValueIndex * kPointerSize)); 828c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 829ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com // Prepare arguments. 830fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org __ Move(a2, sp); 831c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 832ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com // Allocate the v8::Arguments structure in the arguments' space since 833ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com // it's not controlled by GC. 834c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org const int kApiStackSpace = 4; 835c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 836c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FrameScope frame_scope(masm, StackFrame::MANUAL); 837c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ EnterExitFrame(false, kApiStackSpace); 838c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 839fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org // a0 = FunctionCallbackInfo& 840c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Arguments is built at sp + 1 (sp is a reserved spot for ra). 841662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org __ Addu(a0, sp, kPointerSize); 842fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org // FunctionCallbackInfo::implicit_args_ 843662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org __ sw(a2, MemOperand(a0, 0 * kPointerSize)); 844fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org // FunctionCallbackInfo::values_ 845fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org __ Addu(t0, a2, Operand((kFastApiCallArguments - 1 + argc) * kPointerSize)); 846662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org __ sw(t0, MemOperand(a0, 1 * kPointerSize)); 847fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org // FunctionCallbackInfo::length_ = argc 848c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ li(t0, Operand(argc)); 849662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org __ sw(t0, MemOperand(a0, 2 * kPointerSize)); 850fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org // FunctionCallbackInfo::is_construct_call = 0 851662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org __ sw(zero_reg, MemOperand(a0, 3 * kPointerSize)); 852c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 853fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org const int kStackUnwindSpace = argc + kFastApiCallArguments + 1; 854662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org Address function_address = v8::ToCData<Address>(api_call_info->callback()); 855c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ApiFunction fun(function_address); 856662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org ExternalReference::Type type = ExternalReference::DIRECT_API_CALL; 857c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ExternalReference ref = 858c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ExternalReference(&fun, 859bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org type, 860c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org masm->isolate()); 861662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback); 862662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org ExternalReference::Type thunk_type = ExternalReference::PROFILING_API_CALL; 863b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org ApiFunction thunk_fun(thunk_address); 864b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type, 865b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org masm->isolate()); 866b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 867c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com AllowExternalCallThatCantCauseGC scope(masm); 868528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org MemOperand context_restore_operand( 869fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org fp, (2 + FCA::kContextSaveIndex) * kPointerSize); 870528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org MemOperand return_value_operand( 871fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org fp, (2 + FCA::kReturnValueOffset) * kPointerSize); 872fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org 873bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org __ CallApiFunctionAndReturn(ref, 874b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org function_address, 875b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org thunk_ref, 876662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org a1, 877bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org kStackUnwindSpace, 878528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org return_value_operand, 879528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org restore_context ? 880528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org &context_restore_operand : NULL); 881c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org} 882c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 883639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org 884639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org// Generate call to api function. 885639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.orgstatic void GenerateFastApiCall(MacroAssembler* masm, 886639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org const CallOptimization& optimization, 887639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org Register receiver, 888639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org Register scratch, 889639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org int argc, 890639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org Register* values) { 891639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org ASSERT(optimization.is_simple_api_call()); 892639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org ASSERT(!receiver.is(scratch)); 893639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org 894fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org typedef FunctionCallbackArguments FCA; 895639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org const int stack_space = kFastApiCallArguments + argc + 1; 896639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org // Assign stack space for the call arguments. 897639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org __ Subu(sp, sp, Operand(stack_space * kPointerSize)); 898639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org // Write holder to stack frame. 899fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org __ sw(receiver, MemOperand(sp, FCA::kHolderIndex * kPointerSize)); 900639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org // Write receiver to stack frame. 901639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org int index = stack_space - 1; 902639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org __ sw(receiver, MemOperand(sp, index * kPointerSize)); 903639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org // Write the arguments to stack frame. 904639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org for (int i = 0; i < argc; i++) { 905639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org ASSERT(!receiver.is(values[i])); 906639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org ASSERT(!scratch.is(values[i])); 907639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org __ sw(receiver, MemOperand(sp, index-- * kPointerSize)); 908639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org } 909639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org 910528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org GenerateFastApiDirectCall(masm, optimization, argc, true); 911639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org} 912639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org 913639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org 9147516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgclass CallInterceptorCompiler BASE_EMBEDDED { 9157516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org public: 9168a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org CallInterceptorCompiler(CallStubCompiler* stub_compiler, 9177516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org const ParameterCount& arguments, 918d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com Register name, 919cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org ExtraICState extra_ic_state) 9207516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org : stub_compiler_(stub_compiler), 9217516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org arguments_(arguments), 922d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com name_(name), 923d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com extra_ic_state_(extra_ic_state) {} 9247516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 925c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org void Compile(MacroAssembler* masm, 926c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSObject> object, 927c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSObject> holder, 9289faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org Handle<Name> name, 929c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LookupResult* lookup, 930c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register receiver, 931c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register scratch1, 932c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register scratch2, 933c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register scratch3, 934c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label* miss) { 935c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(holder->HasNamedInterceptor()); 936c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined()); 937c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 938c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check that the receiver isn't a smi. 939c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ JumpIfSmi(receiver, miss); 940c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org CallOptimization optimization(lookup); 941c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (optimization.is_constant_call()) { 942c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org CompileCacheable(masm, object, receiver, scratch1, scratch2, scratch3, 943c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org holder, lookup, name, optimization, miss); 944c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } else { 945c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org CompileRegular(masm, object, receiver, scratch1, scratch2, scratch3, 946c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org name, holder, miss); 947c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 948c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 949c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 950c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org private: 951c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org void CompileCacheable(MacroAssembler* masm, 952c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSObject> object, 953c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register receiver, 954c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register scratch1, 955c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register scratch2, 956c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register scratch3, 957c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSObject> interceptor_holder, 958c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org LookupResult* lookup, 9599faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org Handle<Name> name, 960c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org const CallOptimization& optimization, 961c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label* miss_label) { 962c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(optimization.is_constant_call()); 963c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(!lookup->holder()->IsGlobalObject()); 964c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Counters* counters = masm->isolate()->counters(); 965c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org int depth1 = kInvalidProtoDepth; 966c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org int depth2 = kInvalidProtoDepth; 967c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org bool can_do_fast_api_call = false; 968c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (optimization.is_simple_api_call() && 969c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org !lookup->holder()->IsGlobalObject()) { 970c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org depth1 = optimization.GetPrototypeDepthOfExpectedType( 971c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org object, interceptor_holder); 972c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (depth1 == kInvalidProtoDepth) { 973c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org depth2 = optimization.GetPrototypeDepthOfExpectedType( 974c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org interceptor_holder, Handle<JSObject>(lookup->holder())); 975c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 976c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org can_do_fast_api_call = 977c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org depth1 != kInvalidProtoDepth || depth2 != kInvalidProtoDepth; 978c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 979c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 980c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ IncrementCounter(counters->call_const_interceptor(), 1, 981c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org scratch1, scratch2); 982c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 983c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (can_do_fast_api_call) { 984c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ IncrementCounter(counters->call_const_interceptor_fast_api(), 1, 985c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org scratch1, scratch2); 986c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ReserveSpaceForFastApiCall(masm, scratch1); 987c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 988c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 989c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check that the maps from receiver to interceptor's holder 990c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // haven't changed and thus we can invoke interceptor. 991c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label miss_cleanup; 992c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label* miss = can_do_fast_api_call ? &miss_cleanup : miss_label; 993c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Register holder = 994f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org stub_compiler_->CheckPrototypes( 995f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org IC::CurrentTypeOf(object, masm->isolate()), receiver, 996f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org interceptor_holder, scratch1, scratch2, scratch3, 997f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org name, depth1, miss); 998c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 999c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Invoke an interceptor and if it provides a value, 1000c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // branch to |regular_invoke|. 1001c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label regular_invoke; 1002c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org LoadWithInterceptor(masm, receiver, holder, interceptor_holder, scratch2, 1003c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ®ular_invoke); 1004c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1005c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Interceptor returned nothing for this property. Try to use cached 1006c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // constant function. 1007c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1008c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check that the maps from interceptor's holder to constant function's 1009c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // holder haven't changed and thus we can use cached constant function. 1010c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (*interceptor_holder != lookup->holder()) { 1011f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org stub_compiler_->CheckPrototypes( 1012089ff3201a058d730ea38791253f36b2fc534ae2palfia@homejinni.com IC::CurrentTypeOf(interceptor_holder, masm->isolate()), holder, 1013f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org handle(lookup->holder()), scratch1, scratch2, scratch3, 1014f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org name, depth2, miss); 1015c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } else { 1016c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // CheckPrototypes has a side effect of fetching a 'holder' 1017c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // for API (object which is instanceof for the signature). It's 1018c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // safe to omit it here, as if present, it should be fetched 1019c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // by the previous CheckPrototypes. 1020c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(depth2 == kInvalidProtoDepth); 1021c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 1022c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1023c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Invoke function. 1024c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (can_do_fast_api_call) { 1025528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org GenerateFastApiDirectCall( 1026528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org masm, optimization, arguments_.immediate(), false); 1027c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } else { 102832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Handle<JSFunction> function = optimization.constant_function(); 1029089ff3201a058d730ea38791253f36b2fc534ae2palfia@homejinni.com __ Move(a0, receiver); 1030089ff3201a058d730ea38791253f36b2fc534ae2palfia@homejinni.com stub_compiler_->GenerateJumpFunction(object, function); 1031c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 1032c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1033c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Deferred code for fast API call case---clean preallocated space. 1034c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (can_do_fast_api_call) { 1035c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&miss_cleanup); 1036c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org FreeSpaceForFastApiCall(masm); 1037c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Branch(miss_label); 1038c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 1039c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1040c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Invoke a regular function. 1041c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(®ular_invoke); 1042c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (can_do_fast_api_call) { 1043c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org FreeSpaceForFastApiCall(masm); 1044c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 10457516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 10467516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 10477516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void CompileRegular(MacroAssembler* masm, 1048c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSObject> object, 10497516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Register receiver, 10507516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Register scratch1, 10517516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Register scratch2, 10527516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Register scratch3, 10536e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org Handle<Name> name, 1054c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSObject> interceptor_holder, 10557516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Label* miss_label) { 1056c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Register holder = 1057f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org stub_compiler_->CheckPrototypes( 1058f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org IC::CurrentTypeOf(object, masm->isolate()), receiver, 1059f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org interceptor_holder, scratch1, scratch2, scratch3, name, miss_label); 1060c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1061c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Call a runtime function to load the interceptor property. 1062c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FrameScope scope(masm, StackFrame::INTERNAL); 1063c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Save the name_ register across the call. 1064c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ push(name_); 1065c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 106637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org CompileCallLoadPropertyWithInterceptor( 106737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org masm, receiver, holder, name_, interceptor_holder, 106837be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org IC::kLoadPropertyWithInterceptorForCall); 1069c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1070c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Restore the name_ register. 1071c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ pop(name_); 1072c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Leave the internal frame. 10737516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 10747516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 10757516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org void LoadWithInterceptor(MacroAssembler* masm, 10767516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Register receiver, 10777516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Register holder, 1078c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSObject> holder_obj, 10797516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Register scratch, 10807516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Label* interceptor_succeeded) { 1081c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com { 1082c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FrameScope scope(masm, StackFrame::INTERNAL); 1083c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1084089ff3201a058d730ea38791253f36b2fc534ae2palfia@homejinni.com __ Push(receiver, holder, name_); 108537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org CompileCallLoadPropertyWithInterceptor( 108637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org masm, receiver, holder, name_, holder_obj, 108737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org IC::kLoadPropertyWithInterceptorOnly); 1088089ff3201a058d730ea38791253f36b2fc534ae2palfia@homejinni.com __ pop(name_); 1089089ff3201a058d730ea38791253f36b2fc534ae2palfia@homejinni.com __ pop(holder); 1090089ff3201a058d730ea38791253f36b2fc534ae2palfia@homejinni.com __ pop(receiver); 1091c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 1092c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // If interceptor returns no-result sentinel, call the constant function. 1093c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ LoadRoot(scratch, Heap::kNoInterceptorResultSentinelRootIndex); 1094c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Branch(interceptor_succeeded, ne, v0, Operand(scratch)); 10957516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org } 10967516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 10978a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org CallStubCompiler* stub_compiler_; 10987516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org const ParameterCount& arguments_; 10997516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org Register name_; 1100cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org ExtraICState extra_ic_state_; 11017516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org}; 11027516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 11037516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 11042bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.orgvoid StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) { 11059faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org __ Jump(code, RelocInfo::CODE_TARGET); 11069faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org} 11079faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org 11089faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org 11092bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org#undef __ 11102bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org#define __ ACCESS_MASM(masm()) 11112bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org 11122bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org 1113f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.orgRegister StubCompiler::CheckPrototypes(Handle<Type> type, 1114394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Register object_reg, 1115394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Handle<JSObject> holder, 1116394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Register holder_reg, 1117394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Register scratch1, 1118394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Register scratch2, 11199faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org Handle<Name> name, 1120394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com int save_at_depth, 11219faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org Label* miss, 11229faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org PrototypeCheckType check) { 1123f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Handle<Map> receiver_map(IC::TypeToMap(*type, isolate())); 1124ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org // Make sure that the type feedback oracle harvests the receiver map. 1125ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org // TODO(svenpanne) Remove this hack when all ICs are reworked. 1126f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org __ li(scratch1, Operand(receiver_map)); 1127ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 1128394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Make sure there's no overlap between holder and object registers. 1129394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); 1130394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) 1131394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com && !scratch2.is(scratch1)); 1132394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1133394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Keep track of the current object in register reg. 1134394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Register reg = object_reg; 1135394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com int depth = 0; 1136394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1137fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org typedef FunctionCallbackArguments FCA; 1138394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (save_at_depth == depth) { 1139fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org __ sw(reg, MemOperand(sp, FCA::kHolderIndex * kPointerSize)); 1140394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 1141394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1142f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Handle<JSObject> current = Handle<JSObject>::null(); 1143f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org if (type->IsConstant()) current = Handle<JSObject>::cast(type->AsConstant()); 1144f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Handle<JSObject> prototype = Handle<JSObject>::null(); 1145f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Handle<Map> current_map = receiver_map; 1146f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Handle<Map> holder_map(holder->map()); 1147f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org // Traverse the prototype chain and check the maps in the prototype chain for 1148f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org // fast and global objects or do negative lookup for normal objects. 1149f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org while (!current_map.is_identical_to(holder_map)) { 1150394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ++depth; 1151394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1152394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Only global objects and objects that do not require access 1153394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // checks are allowed in stubs. 1154f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org ASSERT(current_map->IsJSGlobalProxyMap() || 1155f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org !current_map->is_access_check_needed()); 1156394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1157f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org prototype = handle(JSObject::cast(current_map->prototype())); 1158f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org if (current_map->is_dictionary_map() && 1159f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org !current_map->IsJSGlobalObjectMap() && 1160f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org !current_map->IsJSGlobalProxyMap()) { 11619faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org if (!name->IsUniqueName()) { 11629faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org ASSERT(name->IsString()); 11639faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org name = factory()->InternalizeString(Handle<String>::cast(name)); 1164394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 1165f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org ASSERT(current.is_null() || 1166f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org current->property_dictionary()->FindEntry(*name) == 11679faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org NameDictionary::kNotFound); 1168394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1169394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com GenerateDictionaryNegativeLookup(masm(), miss, reg, name, 1170394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com scratch1, scratch2); 1171394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1172394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); 1173394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com reg = holder_reg; // From now on the object will be in holder_reg. 1174394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ lw(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); 1175394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } else { 11769faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org Register map_reg = scratch1; 1177f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org if (depth != 1 || check == CHECK_ALL_MAPS) { 11789faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org // CheckMap implicitly loads the map of |reg| into |map_reg|. 1179a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ CheckMap(reg, map_reg, current_map, miss, DONT_DO_SMI_CHECK); 11809faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org } else { 11819faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org __ lw(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset)); 11829faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org } 1183f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org 1184394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Check access rights to the global object. This has to happen after 1185394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // the map check so that we know that the object is actually a global 1186394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // object. 1187f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org if (current_map->IsJSGlobalProxyMap()) { 1188394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ CheckAccessGlobalProxy(reg, scratch2, miss); 1189f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org } else if (current_map->IsJSGlobalObjectMap()) { 1190f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org GenerateCheckPropertyCell( 1191f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org masm(), Handle<JSGlobalObject>::cast(current), name, 1192f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org scratch2, miss); 1193394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 1194f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org 1195394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com reg = holder_reg; // From now on the object will be in holder_reg. 1196394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1197394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (heap()->InNewSpace(*prototype)) { 1198394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // The prototype is in new space; we cannot store a reference to it 1199394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // in the code. Load it from the map. 12009faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org __ lw(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset)); 1201394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } else { 1202394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // The prototype is in old space; load it directly. 1203394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ li(reg, Operand(prototype)); 1204394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 1205394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 1206394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1207394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (save_at_depth == depth) { 1208fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org __ sw(reg, MemOperand(sp, FCA::kHolderIndex * kPointerSize)); 1209394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 1210394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1211394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Go to the next object in the prototype chain. 1212394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com current = prototype; 1213f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org current_map = handle(current->map()); 1214394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 1215394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1216394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Log the check depth. 121732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); 1218394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1219f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org if (depth != 0 || check == CHECK_ALL_MAPS) { 12209faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org // Check the holder map. 1221f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org __ CheckMap(reg, scratch1, current_map, miss, DONT_DO_SMI_CHECK); 12229faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org } 1223394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1224394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Perform security check for access to the global object. 1225f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org ASSERT(current_map->IsJSGlobalProxyMap() || 1226f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org !current_map->is_access_check_needed()); 1227f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org if (current_map->IsJSGlobalProxyMap()) { 1228394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ CheckAccessGlobalProxy(reg, scratch1, miss); 1229394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 1230394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1231394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Return the register containing the holder. 1232394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com return reg; 1233394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com} 1234394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1235394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1236b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.orgvoid LoadStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) { 12379faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org if (!miss->is_unused()) { 1238b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org Label success; 1239b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org __ Branch(&success); 12409faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org __ bind(miss); 12412bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org TailCallBuiltin(masm(), MissBuiltin(kind())); 1242b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org __ bind(&success); 12439faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org } 12445c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 12455c838251403b0be9a882540f1922577abba4c872ager@chromium.org 12465c838251403b0be9a882540f1922577abba4c872ager@chromium.org 1247b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.orgvoid StoreStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) { 1248bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org if (!miss->is_unused()) { 1249b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org Label success; 1250b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org __ Branch(&success); 1251bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org GenerateRestoreName(masm(), miss, name); 1252bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org TailCallBuiltin(masm(), MissBuiltin(kind())); 1253b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org __ bind(&success); 1254bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } 1255bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org} 1256bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 1257bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 12582efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgRegister LoadStubCompiler::CallbackHandlerFrontend( 1259f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Handle<Type> type, 12604a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Register object_reg, 12614a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Handle<JSObject> holder, 12629faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org Handle<Name> name, 12632c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org Handle<Object> callback) { 12644a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Label miss; 1265c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1266f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Register reg = HandlerFrontendHeader(type, object_reg, holder, name, &miss); 12675c838251403b0be9a882540f1922577abba4c872ager@chromium.org 12684a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { 12694a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org ASSERT(!reg.is(scratch2())); 12704a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org ASSERT(!reg.is(scratch3())); 12714a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org ASSERT(!reg.is(scratch4())); 12724a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 12734a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // Load the properties dictionary. 12744a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Register dictionary = scratch4(); 12754a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ lw(dictionary, FieldMemOperand(reg, JSObject::kPropertiesOffset)); 12764a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 12774a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // Probe the dictionary. 12784a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Label probe_done; 12799faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org NameDictionaryLookupStub::GeneratePositiveLookup(masm(), 12809faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org &miss, 12819faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org &probe_done, 12829faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org dictionary, 12839faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org this->name(), 12849faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org scratch2(), 12859faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org scratch3()); 12864a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ bind(&probe_done); 12874a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 12884a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // If probing finds an entry in the dictionary, scratch3 contains the 12894a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // pointer into the dictionary. Check that the value is the callback. 12904a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Register pointer = scratch3(); 12919faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org const int kElementsStartOffset = NameDictionary::kHeaderSize + 12929faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org NameDictionary::kElementsStartIndex * kPointerSize; 12934a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org const int kValueOffset = kElementsStartOffset + kPointerSize; 12944a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ lw(scratch2(), FieldMemOperand(pointer, kValueOffset)); 12954a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ Branch(&miss, ne, scratch2(), Operand(callback)); 12964a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org } 12975c838251403b0be9a882540f1922577abba4c872ager@chromium.org 1298b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org HandlerFrontendFooter(name, &miss); 12994a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org return reg; 1300471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org} 1301471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org 1302471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org 13032efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgvoid LoadStubCompiler::GenerateLoadField(Register reg, 13042efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Handle<JSObject> holder, 13052efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org PropertyIndex field, 13062efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Representation representation) { 130757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org if (!reg.is(receiver())) __ mov(receiver(), reg); 130857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org if (kind() == Code::LOAD_IC) { 130957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org LoadFieldStub stub(field.is_inobject(holder), 131057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org field.translate(holder), 131157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org representation); 131257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org GenerateTailCall(masm(), stub.GetCode(isolate())); 131357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } else { 131457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org KeyedLoadFieldStub stub(field.is_inobject(holder), 131557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org field.translate(holder), 131657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org representation); 131757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org GenerateTailCall(masm(), stub.GetCode(isolate())); 131857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } 13194a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org} 13204a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 13214a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 13222efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgvoid LoadStubCompiler::GenerateLoadConstant(Handle<Object> value) { 13234a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // Return the constant value. 1324057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org __ li(v0, value); 13254a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ Ret(); 13264a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org} 13274a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 13284a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 13292efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgvoid LoadStubCompiler::GenerateLoadCallback( 13302c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org const CallOptimization& call_optimization) { 1331639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org GenerateFastApiCall( 1332639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org masm(), call_optimization, receiver(), scratch3(), 0, NULL); 13332c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org} 13342c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org 13352c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org 13362efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgvoid LoadStubCompiler::GenerateLoadCallback( 13374a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Register reg, 13384a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Handle<ExecutableAccessorInfo> callback) { 1339c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Build AccessorInfo::args_ list on the stack and push property name below 1340c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // the exit frame to make GC aware of them and store pointers to them. 1341fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0); 1342fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1); 1343fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2); 1344fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3); 1345fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4); 1346fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5); 1347fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 6); 13484a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org ASSERT(!scratch2().is(reg)); 13494a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org ASSERT(!scratch3().is(reg)); 13504a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org ASSERT(!scratch4().is(reg)); 13514a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ push(receiver()); 1352c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (heap()->InNewSpace(callback->data())) { 13534a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ li(scratch3(), callback); 13544a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ lw(scratch3(), FieldMemOperand(scratch3(), 13554a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org ExecutableAccessorInfo::kDataOffset)); 1356c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } else { 135732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org __ li(scratch3(), Handle<Object>(callback->data(), isolate())); 1358c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 135979d0bf7c99ebe30751b199f72fa06fe34a5ded48palfia@homejinni.com __ Subu(sp, sp, 6 * kPointerSize); 13604a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org __ sw(scratch3(), MemOperand(sp, 5 * kPointerSize)); 1361c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org __ LoadRoot(scratch3(), Heap::kUndefinedValueRootIndex); 13624a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org __ sw(scratch3(), MemOperand(sp, 4 * kPointerSize)); 136379d0bf7c99ebe30751b199f72fa06fe34a5ded48palfia@homejinni.com __ sw(scratch3(), MemOperand(sp, 3 * kPointerSize)); 1364c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org __ li(scratch4(), 136532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Operand(ExternalReference::isolate_address(isolate()))); 13664a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org __ sw(scratch4(), MemOperand(sp, 2 * kPointerSize)); 13674a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org __ sw(reg, MemOperand(sp, 1 * kPointerSize)); 13684a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ sw(name(), MemOperand(sp, 0 * kPointerSize)); 1369fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org __ Addu(scratch2(), sp, 1 * kPointerSize); 1370ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com 13714a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ mov(a2, scratch2()); // Saved in case scratch2 == a1. 1372662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org __ mov(a0, sp); // (first argument - a0) = Handle<Name> 1373c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1374c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org const int kApiStackSpace = 1; 1375c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FrameScope frame_scope(masm(), StackFrame::MANUAL); 1376c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ EnterExitFrame(false, kApiStackSpace); 1377c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1378fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org // Create PropertyAccessorInfo instance on the stack above the exit frame with 1379f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com // scratch2 (internal::Object** args_) as the data. 1380c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ sw(a2, MemOperand(sp, kPointerSize)); 1381662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org // (second argument - a1) = AccessorInfo& 1382662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org __ Addu(a1, sp, kPointerSize); 1383c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1384528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1; 1385662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org Address getter_address = v8::ToCData<Address>(callback->getter()); 1386c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ApiFunction fun(getter_address); 1387662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL; 1388fe578677d80b14b35f6dca0c193719331b81a81edanno@chromium.org ExternalReference ref = ExternalReference(&fun, type, isolate()); 1389b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 1390662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback); 1391b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org ExternalReference::Type thunk_type = 1392662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org ExternalReference::PROFILING_GETTER_CALL; 1393b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org ApiFunction thunk_fun(thunk_address); 1394b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type, 1395b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org isolate()); 1396bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org __ CallApiFunctionAndReturn(ref, 1397b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org getter_address, 1398b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org thunk_ref, 1399662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org a2, 1400bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org kStackUnwindSpace, 1401528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org MemOperand(fp, 6 * kPointerSize), 1402528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org NULL); 14035c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 14045c838251403b0be9a882540f1922577abba4c872ager@chromium.org 14055c838251403b0be9a882540f1922577abba4c872ager@chromium.org 14062efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgvoid LoadStubCompiler::GenerateLoadInterceptor( 14074a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Register holder_reg, 1408b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org Handle<Object> object, 14094a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Handle<JSObject> interceptor_holder, 14104a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org LookupResult* lookup, 14119faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org Handle<Name> name) { 1412c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(interceptor_holder->HasNamedInterceptor()); 1413c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); 1414c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1415c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // So far the most popular follow ups for interceptor loads are FIELD 1416c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // and CALLBACKS, so inline only them, other cases may be added 1417c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // later. 1418c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org bool compile_followup_inline = false; 141905ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org if (lookup->IsFound() && lookup->IsCacheable()) { 1420de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org if (lookup->IsField()) { 1421c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org compile_followup_inline = true; 1422c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } else if (lookup->type() == CALLBACKS && 1423c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org lookup->GetCallbackObject()->IsExecutableAccessorInfo()) { 1424c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org ExecutableAccessorInfo* callback = 1425c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org ExecutableAccessorInfo::cast(lookup->GetCallbackObject()); 14267028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org compile_followup_inline = callback->getter() != NULL && 14277028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org callback->IsCompatibleReceiver(*object); 1428c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 1429c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 1430c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1431c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (compile_followup_inline) { 1432c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Compile the interceptor call, followed by inline code to load the 1433c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // property from further up the prototype chain if the call fails. 1434c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check that the maps haven't changed. 14354a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org ASSERT(holder_reg.is(receiver()) || holder_reg.is(scratch1())); 1436c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1437212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org // Preserve the receiver register explicitly whenever it is different from 1438212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org // the holder and it is needed should the interceptor return without any 1439212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org // result. The CALLBACKS case needs the receiver to be passed into C++ code, 1440212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org // the FIELD case might cause a miss during the prototype check. 1441212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org bool must_perfrom_prototype_check = *interceptor_holder != lookup->holder(); 14424a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org bool must_preserve_receiver_reg = !receiver().is(holder_reg) && 1443212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org (lookup->type() == CALLBACKS || must_perfrom_prototype_check); 1444212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org 1445c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Save necessary data before invoking an interceptor. 1446c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Requires a frame to make GC aware of pushed pointers. 1447c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com { 1448c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FrameScope frame_scope(masm(), StackFrame::INTERNAL); 1449212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org if (must_preserve_receiver_reg) { 14504a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ Push(receiver(), holder_reg, this->name()); 1451c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 14524a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ Push(holder_reg, this->name()); 1453c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 1454c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Invoke an interceptor. Note: map checks from receiver to 1455c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // interceptor's holder has been compiled before (see a caller 1456c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // of this method). 145737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org CompileCallLoadPropertyWithInterceptor( 145837be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org masm(), receiver(), holder_reg, this->name(), interceptor_holder, 145937be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org IC::kLoadPropertyWithInterceptorOnly); 146037be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org 1461c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check if interceptor provided a value for property. If it's 1462c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // the case, return immediately. 1463c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label interceptor_failed; 14644a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ LoadRoot(scratch1(), Heap::kNoInterceptorResultSentinelRootIndex); 14654a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ Branch(&interceptor_failed, eq, v0, Operand(scratch1())); 1466c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com frame_scope.GenerateLeaveFrame(); 1467c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Ret(); 1468c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1469c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ bind(&interceptor_failed); 14704a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ pop(this->name()); 1471c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ pop(holder_reg); 1472212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org if (must_preserve_receiver_reg) { 14734a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ pop(receiver()); 1474c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 1475c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Leave the internal frame. 1476c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 14774a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org GenerateLoadPostInterceptor(holder_reg, interceptor_holder, name, lookup); 1478c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } else { // !compile_followup_inline 1479c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Call the runtime system to load the interceptor. 1480c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check that the maps haven't changed. 14814a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org PushInterceptorArguments(masm(), receiver(), holder_reg, 14824a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org this->name(), interceptor_holder); 1483c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1484c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ExternalReference ref = ExternalReference( 148532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), isolate()); 14864a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org __ TailCallExternalReference(ref, StubCache::kInterceptorArgsLength, 1); 1487c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 14885c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 14895c838251403b0be9a882540f1922577abba4c872ager@chromium.org 14905c838251403b0be9a882540f1922577abba4c872ager@chromium.org 14919faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.orgvoid CallStubCompiler::GenerateNameCheck(Handle<Name> name, Label* miss) { 1492c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (kind_ == Code::KEYED_CALL_IC) { 1493394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Branch(miss, ne, a2, Operand(name)); 1494c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 14957516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 14965d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org 14975d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org 14988a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.orgvoid CallStubCompiler::GenerateFunctionCheck(Register function, 14998a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org Register scratch, 15008a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org Label* miss) { 15018a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org __ JumpIfSmi(function, miss); 15028a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org __ GetObjectType(function, scratch, scratch); 15038a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org __ Branch(miss, ne, scratch, Operand(JS_FUNCTION_TYPE)); 15048a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org} 15058a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org 15068a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org 1507c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgvoid CallStubCompiler::GenerateLoadFunctionFromCell( 1508f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org Handle<Cell> cell, 1509c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSFunction> function, 1510c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label* miss) { 1511c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Get the value from the cell. 1512c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ li(a3, Operand(cell)); 1513f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org __ lw(a1, FieldMemOperand(a3, Cell::kValueOffset)); 1514c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1515c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check that the cell contains the same function. 1516c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (heap()->InNewSpace(*function)) { 1517c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // We can't embed a pointer to a function in new space so we have 1518c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // to verify that the shared function info is unchanged. This has 1519c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // the nice side effect that multiple closures based on the same 1520c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // function can all use this call IC. Before we load through the 1521c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // function, we have to verify that it still is a function. 15228a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org GenerateFunctionCheck(a1, a3, miss); 1523c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1524c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check the shared function info. Make sure it hasn't changed. 1525c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ li(a3, Handle<SharedFunctionInfo>(function->shared())); 1526c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(t0, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); 1527c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Branch(miss, ne, t0, Operand(a3)); 1528c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } else { 1529c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ Branch(miss, ne, a1, Operand(function)); 1530c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 15315c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 15325c838251403b0be9a882540f1922577abba4c872ager@chromium.org 15335c838251403b0be9a882540f1922577abba4c872ager@chromium.org 1534394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comvoid CallStubCompiler::GenerateMissBranch() { 1535394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Handle<Code> code = 153640cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(), 153740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org kind_, 1538ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org extra_state()); 1539394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Jump(code, RelocInfo::CODE_TARGET); 1540394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com} 1541394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1542394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1543394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comHandle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, 1544394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Handle<JSObject> holder, 1545fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org PropertyIndex index, 15469faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org Handle<Name> name) { 1547c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label miss; 1548c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1549cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org Register reg = HandlerFrontendHeader( 1550cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org object, holder, name, RECEIVER_MAP_CHECK, &miss); 155157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org GenerateFastPropertyLoad(masm(), a1, reg, index.is_inobject(holder), 155257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org index.translate(holder), Representation::Tagged()); 15538a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org GenerateJumpFunction(object, a1, &miss); 1554c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1555cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org HandlerFrontendFooter(&miss); 1556c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1557c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Return the generated code. 15589af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org return GetCode(Code::FAST, name); 15595d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org} 15605d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org 15615d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org 15621510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.orgHandle<Code> CallStubCompiler::CompileArrayCodeCall( 15631510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Handle<Object> object, 15641510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Handle<JSObject> holder, 15651510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Handle<Cell> cell, 15661510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Handle<JSFunction> function, 15671510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Handle<String> name, 15681510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Code::StubType type) { 15691510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Label miss; 15701510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 1571cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); 1572cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org if (!cell.is_null()) { 15731510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ASSERT(cell->value() == *function); 15741510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org GenerateLoadFunctionFromCell(cell, function, &miss); 15751510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org } 15761510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 1577bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite(); 1578b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org site->SetElementsKind(GetInitialFastElementsKind()); 1579bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site); 1580cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org const int argc = arguments().immediate(); 15811510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ li(a0, Operand(argc)); 1582bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org __ li(a2, Operand(site_feedback_cell)); 15831510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ li(a1, Operand(function)); 15841510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 15851510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org ArrayConstructorStub stub(isolate()); 15861510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org __ TailCallStub(&stub); 15871510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 1588cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org HandlerFrontendFooter(&miss); 15891510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 15901510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org // Return the generated code. 15911510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org return GetCode(type, name); 15921510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org} 15931510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 15941510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org 1595c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgHandle<Code> CallStubCompiler::CompileArrayPushCall( 1596c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<Object> object, 1597c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSObject> holder, 1598f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org Handle<Cell> cell, 1599c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSFunction> function, 16001510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Handle<String> name, 16011510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Code::StubType type) { 16028a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org // If object is not an array or is observed or sealed, bail out to regular 16038a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org // call. 1604b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if (!object->IsJSArray() || 1605b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org !cell.is_null() || 16068a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org Handle<JSArray>::cast(object)->map()->is_observed() || 16078a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org !Handle<JSArray>::cast(object)->map()->is_extensible()) { 1608b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org return Handle<Code>::null(); 1609b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org } 16105c838251403b0be9a882540f1922577abba4c872ager@chromium.org 1611c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label miss; 1612cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); 1613cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org Register receiver = a0; 1614cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org Register scratch = a1; 16155c838251403b0be9a882540f1922577abba4c872ager@chromium.org 1616c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org const int argc = arguments().immediate(); 1617c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1618c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (argc == 0) { 1619c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Nothing to do, just return the length. 1620c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset)); 16218a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ DropAndRet(argc + 1); 1622c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } else { 1623c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label call_builtin; 1624c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (argc == 1) { // Otherwise fall through to call the builtin. 16258e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org Label attempt_to_grow_elements, with_write_barrier, check_double; 1626c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 162778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org Register elements = t2; 162878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org Register end_elements = t1; 162978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // Get the elements array of the object. 163078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org __ lw(elements, FieldMemOperand(receiver, JSArray::kElementsOffset)); 163178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org 163278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // Check that the elements are in fast mode and writable. 163378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org __ CheckMap(elements, 1634cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org scratch, 163578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org Heap::kFixedArrayMapRootIndex, 16368e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org &check_double, 163778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org DONT_DO_SMI_CHECK); 163878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org 1639cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org // Get the array's length into scratch and calculate new length. 1640cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ lw(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1641c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org STATIC_ASSERT(kSmiTagSize == 1); 1642c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org STATIC_ASSERT(kSmiTag == 0); 1643cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ Addu(scratch, scratch, Operand(Smi::FromInt(argc))); 1644c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 164578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // Get the elements' length. 1646c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(t0, FieldMemOperand(elements, FixedArray::kLengthOffset)); 1647c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1648c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check if we could survive without allocation. 1649cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ Branch(&attempt_to_grow_elements, gt, scratch, Operand(t0)); 1650c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1651b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org // Check if value is a smi. 1652b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org __ lw(t0, MemOperand(sp, (argc - 1) * kPointerSize)); 1653b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org __ JumpIfNotSmi(t0, &with_write_barrier); 1654b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org 1655c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Save new length. 1656cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ sw(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1657c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 165878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // Store the value. 1659c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // We may need a register containing the address end_elements below, 1660c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // so write back the value in end_elements. 1661cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ sll(end_elements, scratch, kPointerSizeLog2 - kSmiTagSize); 1662c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Addu(end_elements, elements, end_elements); 1663c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org const int kEndElementsOffset = 1664c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org FixedArray::kHeaderSize - kHeapObjectTag - argc * kPointerSize; 1665c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Addu(end_elements, end_elements, kEndElementsOffset); 1666c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ sw(t0, MemOperand(end_elements)); 1667c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1668c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check for a smi. 1669cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ mov(v0, scratch); 16708a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ DropAndRet(argc + 1); 1671c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 16728e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org __ bind(&check_double); 16738e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org 16748e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org // Check that the elements are in fast mode and writable. 16758e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org __ CheckMap(elements, 1676cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org scratch, 16778e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org Heap::kFixedDoubleArrayMapRootIndex, 16788e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org &call_builtin, 16798e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org DONT_DO_SMI_CHECK); 16808e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org 1681cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org // Get the array's length into scratch and calculate new length. 1682cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ lw(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset)); 16838e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org STATIC_ASSERT(kSmiTagSize == 1); 16848e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org STATIC_ASSERT(kSmiTag == 0); 1685cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ Addu(scratch, scratch, Operand(Smi::FromInt(argc))); 16868e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org 16878e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org // Get the elements' length. 16888e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org __ lw(t0, FieldMemOperand(elements, FixedArray::kLengthOffset)); 16898e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org 16908e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org // Check if we could survive without allocation. 1691cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ Branch(&call_builtin, gt, scratch, Operand(t0)); 16928e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org 16938e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org __ lw(t0, MemOperand(sp, (argc - 1) * kPointerSize)); 16948e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org __ StoreNumberToDoubleElements( 1695cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org t0, scratch, elements, a3, t1, a2, 16968e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org &call_builtin, argc * kDoubleSize); 16978e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org 16988e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org // Save new length. 1699cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ sw(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset)); 17008e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org 1701cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ mov(v0, scratch); 17028a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ DropAndRet(argc + 1); 17038e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org 1704c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&with_write_barrier); 1705b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org 170678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org __ lw(a3, FieldMemOperand(receiver, HeapObject::kMapOffset)); 170778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org 170878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org if (FLAG_smi_only_arrays && !FLAG_trace_elements_transitions) { 170978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org Label fast_object, not_fast_object; 171078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org __ CheckFastObjectElements(a3, t3, ¬_fast_object); 171178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org __ jmp(&fast_object); 171278d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // In case of fast smi-only, convert to fast object, otherwise bail out. 171378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org __ bind(¬_fast_object); 1714830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org __ CheckFastSmiElements(a3, t3, &call_builtin); 17158e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org 17168e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org __ lw(t3, FieldMemOperand(t0, HeapObject::kMapOffset)); 17178e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org __ LoadRoot(at, Heap::kHeapNumberMapRootIndex); 17188e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org __ Branch(&call_builtin, eq, t3, Operand(at)); 171978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // edx: receiver 17208e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org // a3: map 1721830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org Label try_holey_map; 1722830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS, 172378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org FAST_ELEMENTS, 172478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org a3, 172578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org t3, 1726830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org &try_holey_map); 1727830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org __ mov(a2, receiver); 1728830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org ElementsTransitionGenerator:: 172928381b491d5ea9f256a3937000de7953639ef93fyangguo@chromium.org GenerateMapChangeElementsTransition(masm(), 173028381b491d5ea9f256a3937000de7953639ef93fyangguo@chromium.org DONT_TRACK_ALLOCATION_SITE, 173128381b491d5ea9f256a3937000de7953639ef93fyangguo@chromium.org NULL); 1732830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org __ jmp(&fast_object); 1733830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org 1734830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org __ bind(&try_holey_map); 1735830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org __ LoadTransitionedArrayMapConditional(FAST_HOLEY_SMI_ELEMENTS, 1736830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org FAST_HOLEY_ELEMENTS, 1737830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org a3, 1738830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org t3, 173978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org &call_builtin); 174078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org __ mov(a2, receiver); 1741830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org ElementsTransitionGenerator:: 174228381b491d5ea9f256a3937000de7953639ef93fyangguo@chromium.org GenerateMapChangeElementsTransition(masm(), 174328381b491d5ea9f256a3937000de7953639ef93fyangguo@chromium.org DONT_TRACK_ALLOCATION_SITE, 174428381b491d5ea9f256a3937000de7953639ef93fyangguo@chromium.org NULL); 174578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org __ bind(&fast_object); 174678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org } else { 174778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org __ CheckFastObjectElements(a3, a3, &call_builtin); 174878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org } 1749b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org 1750b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org // Save new length. 1751cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ sw(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1752b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org 175378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org // Store the value. 1754b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org // We may need a register containing the address end_elements below, 1755b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org // so write back the value in end_elements. 1756cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ sll(end_elements, scratch, kPointerSizeLog2 - kSmiTagSize); 1757b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org __ Addu(end_elements, elements, end_elements); 1758b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org __ Addu(end_elements, end_elements, kEndElementsOffset); 1759b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org __ sw(t0, MemOperand(end_elements)); 1760b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org 1761b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org __ RecordWrite(elements, 1762b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org end_elements, 1763b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org t0, 1764b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org kRAHasNotBeenSaved, 1765b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org kDontSaveFPRegs, 1766b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org EMIT_REMEMBERED_SET, 1767b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org OMIT_SMI_CHECK); 1768cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ mov(v0, scratch); 17698a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ DropAndRet(argc + 1); 1770c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1771c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&attempt_to_grow_elements); 1772cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org // scratch: array's length + 1. 1773c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // t0: elements' length. 1774c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1775c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (!FLAG_inline_new) { 1776c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Branch(&call_builtin); 1777c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 1778c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1779b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org __ lw(a2, MemOperand(sp, (argc - 1) * kPointerSize)); 1780b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org // Growing elements that are SMI-only requires special handling in case 1781b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org // the new element is non-Smi. For now, delegate to the builtin. 1782b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org Label no_fast_elements_check; 1783b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org __ JumpIfSmi(a2, &no_fast_elements_check); 1784b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org __ lw(t3, FieldMemOperand(receiver, HeapObject::kMapOffset)); 1785b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org __ CheckFastObjectElements(t3, t3, &call_builtin); 1786b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org __ bind(&no_fast_elements_check); 1787b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org 1788c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ExternalReference new_space_allocation_top = 178932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org ExternalReference::new_space_allocation_top_address(isolate()); 1790c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ExternalReference new_space_allocation_limit = 179132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org ExternalReference::new_space_allocation_limit_address(isolate()); 1792c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1793c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org const int kAllocationDelta = 4; 1794c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Load top and check if it is the end of elements. 1795cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ sll(end_elements, scratch, kPointerSizeLog2 - kSmiTagSize); 1796c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Addu(end_elements, elements, end_elements); 1797c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Addu(end_elements, end_elements, Operand(kEndElementsOffset)); 1798c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ li(t3, Operand(new_space_allocation_top)); 179978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org __ lw(a3, MemOperand(t3)); 180078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org __ Branch(&call_builtin, ne, end_elements, Operand(a3)); 1801c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1802c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ li(t5, Operand(new_space_allocation_limit)); 1803c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(t5, MemOperand(t5)); 180478d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org __ Addu(a3, a3, Operand(kAllocationDelta * kPointerSize)); 180578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org __ Branch(&call_builtin, hi, a3, Operand(t5)); 1806c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1807c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // We fit and could grow elements. 1808c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Update new_space_allocation_top. 180978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org __ sw(a3, MemOperand(t3)); 1810c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Push the argument. 1811b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org __ sw(a2, MemOperand(end_elements)); 1812c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Fill the rest with holes. 181378d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org __ LoadRoot(a3, Heap::kTheHoleValueRootIndex); 1814c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org for (int i = 1; i < kAllocationDelta; i++) { 181578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org __ sw(a3, MemOperand(end_elements, i * kPointerSize)); 1816c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 1817c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1818c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Update elements' and array's sizes. 1819cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ sw(scratch, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1820c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Addu(t0, t0, Operand(Smi::FromInt(kAllocationDelta))); 1821c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ sw(t0, FieldMemOperand(elements, FixedArray::kLengthOffset)); 1822c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1823c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Elements are in new space, so write barrier is not required. 1824cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ mov(v0, scratch); 18258a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ DropAndRet(argc + 1); 1826c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 1827c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&call_builtin); 182832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org __ TailCallExternalReference( 182932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org ExternalReference(Builtins::c_ArrayPush, isolate()), argc + 1, 1); 1830c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 1831c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1832cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org HandlerFrontendFooter(&miss); 1833c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1834c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Return the generated code. 18351510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org return GetCode(type, name); 1836c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org} 1837c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1838c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1839c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgHandle<Code> CallStubCompiler::CompileArrayPopCall( 1840c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<Object> object, 1841c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSObject> holder, 1842f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org Handle<Cell> cell, 1843c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSFunction> function, 18441510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Handle<String> name, 18451510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Code::StubType type) { 18468a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org // If object is not an array or is observed or sealed, bail out to regular 18478a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org // call. 1848b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if (!object->IsJSArray() || 1849b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org !cell.is_null() || 18508a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org Handle<JSArray>::cast(object)->map()->is_observed() || 18518a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org !Handle<JSArray>::cast(object)->map()->is_extensible()) { 1852b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org return Handle<Code>::null(); 1853b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org } 1854c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1855c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label miss, return_undefined, call_builtin; 1856cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org Register receiver = a0; 1857cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org Register scratch = a1; 1858c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Register elements = a3; 1859cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); 1860c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1861c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Get the elements array of the object. 1862c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(elements, FieldMemOperand(receiver, JSArray::kElementsOffset)); 1863c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1864c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check that the elements are in fast mode and writable. 186540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org __ CheckMap(elements, 1866cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org scratch, 186740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org Heap::kFixedArrayMapRootIndex, 186840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org &call_builtin, 186940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org DONT_DO_SMI_CHECK); 1870c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1871c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Get the array's length into t0 and calculate new length. 1872c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(t0, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1873c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Subu(t0, t0, Operand(Smi::FromInt(1))); 1874c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Branch(&return_undefined, lt, t0, Operand(zero_reg)); 1875c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1876c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Get the last element. 1877c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ LoadRoot(t2, Heap::kTheHoleValueRootIndex); 1878c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org STATIC_ASSERT(kSmiTagSize == 1); 1879c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org STATIC_ASSERT(kSmiTag == 0); 1880c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // We can't address the last element in one operation. Compute the more 1881c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // expensive shift first, and use an offset later on. 1882c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ sll(t1, t0, kPointerSizeLog2 - kSmiTagSize); 1883c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Addu(elements, elements, t1); 1884cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ lw(scratch, FieldMemOperand(elements, FixedArray::kHeaderSize)); 1885cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ Branch(&call_builtin, eq, scratch, Operand(t2)); 1886c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1887c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Set the array's length. 1888c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ sw(t0, FieldMemOperand(receiver, JSArray::kLengthOffset)); 1889c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1890c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Fill with the hole. 18917d10be581a91ab5eefa1139ff0b86c64ac8f6e59fschneider@chromium.org __ sw(t2, FieldMemOperand(elements, FixedArray::kHeaderSize)); 1892cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org const int argc = arguments().immediate(); 1893cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ mov(v0, scratch); 18948a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ DropAndRet(argc + 1); 1895c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1896c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&return_undefined); 1897c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ LoadRoot(v0, Heap::kUndefinedValueRootIndex); 18988a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ DropAndRet(argc + 1); 1899c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1900c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&call_builtin); 190132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org __ TailCallExternalReference( 190232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org ExternalReference(Builtins::c_ArrayPop, isolate()), argc + 1, 1); 1903c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1904cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org HandlerFrontendFooter(&miss); 1905c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1906c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Return the generated code. 19071510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org return GetCode(type, name); 1908c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org} 1909c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1910c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1911c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgHandle<Code> CallStubCompiler::CompileStringCharCodeAtCall( 1912c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<Object> object, 1913c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSObject> holder, 1914f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org Handle<Cell> cell, 1915c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSFunction> function, 19161510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Handle<String> name, 19171510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Code::StubType type) { 1918c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // If object is not a string, bail out to regular call. 1919c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (!object->IsString() || !cell.is_null()) return Handle<Code>::null(); 1920c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1921c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label miss; 1922c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label name_miss; 1923c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label index_out_of_range; 1924c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1925c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label* index_out_of_range_label = &index_out_of_range; 1926c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 192740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org if (kind_ == Code::CALL_IC && 1928ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org (CallICBase::StringStubState::decode(extra_state()) == 192940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org DEFAULT_STRING_STUB)) { 1930c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org index_out_of_range_label = &miss; 1931c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 1932c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1933cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org HandlerFrontendHeader(object, holder, name, STRING_CHECK, &name_miss); 1934c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1935cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org Register receiver = a0; 1936c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Register index = t1; 1937cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org Register result = a1; 1938cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org const int argc = arguments().immediate(); 1939c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(receiver, MemOperand(sp, argc * kPointerSize)); 1940c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (argc > 0) { 1941c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(index, MemOperand(sp, (argc - 1) * kPointerSize)); 1942c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } else { 1943c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ LoadRoot(index, Heap::kUndefinedValueRootIndex); 1944c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 1945c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1946c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org StringCharCodeAtGenerator generator(receiver, 1947c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org index, 1948c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org result, 1949c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org &miss, // When not a string. 1950c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org &miss, // When not a number. 1951c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org index_out_of_range_label, 1952c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org STRING_INDEX_IS_NUMBER); 1953c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org generator.GenerateFast(masm()); 1954cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ mov(v0, result); 19558a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ DropAndRet(argc + 1); 1956c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1957c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org StubRuntimeCallHelper call_helper; 1958c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org generator.GenerateSlow(masm(), call_helper); 1959c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1960c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (index_out_of_range.is_linked()) { 1961c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&index_out_of_range); 1962c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ LoadRoot(v0, Heap::kNanValueRootIndex); 19638a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ DropAndRet(argc + 1); 1964c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 1965c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1966c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&miss); 1967c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Restore function name in a2. 1968c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ li(a2, name); 19698a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org HandlerFrontendFooter(&name_miss); 1970c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1971c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Return the generated code. 19721510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org return GetCode(type, name); 19735c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 19745c838251403b0be9a882540f1922577abba4c872ager@chromium.org 19755c838251403b0be9a882540f1922577abba4c872ager@chromium.org 1976c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgHandle<Code> CallStubCompiler::CompileStringCharAtCall( 1977c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<Object> object, 1978c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSObject> holder, 1979f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org Handle<Cell> cell, 1980c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSFunction> function, 19811510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Handle<String> name, 19821510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Code::StubType type) { 1983c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // If object is not a string, bail out to regular call. 1984c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (!object->IsString() || !cell.is_null()) return Handle<Code>::null(); 1985c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1986c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org const int argc = arguments().immediate(); 1987c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label miss; 1988c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label name_miss; 1989c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label index_out_of_range; 1990c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label* index_out_of_range_label = &index_out_of_range; 199140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org if (kind_ == Code::CALL_IC && 1992ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org (CallICBase::StringStubState::decode(extra_state()) == 199340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org DEFAULT_STRING_STUB)) { 1994c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org index_out_of_range_label = &miss; 1995c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 1996c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1997cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org HandlerFrontendHeader(object, holder, name, STRING_CHECK, &name_miss); 1998cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org 1999cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org Register receiver = a0; 2000c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Register index = t1; 2001c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org Register scratch = a3; 2002cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org Register result = a1; 2003c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (argc > 0) { 2004c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(index, MemOperand(sp, (argc - 1) * kPointerSize)); 2005c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } else { 2006c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ LoadRoot(index, Heap::kUndefinedValueRootIndex); 2007c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 2008c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2009c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org StringCharAtGenerator generator(receiver, 2010c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org index, 2011c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org scratch, 2012c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org result, 2013c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org &miss, // When not a string. 2014c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org &miss, // When not a number. 2015c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org index_out_of_range_label, 2016c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org STRING_INDEX_IS_NUMBER); 2017c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org generator.GenerateFast(masm()); 2018cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ mov(v0, result); 20198a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ DropAndRet(argc + 1); 2020c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2021c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org StubRuntimeCallHelper call_helper; 2022c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org generator.GenerateSlow(masm(), call_helper); 2023c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2024c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (index_out_of_range.is_linked()) { 2025c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&index_out_of_range); 2026750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org __ LoadRoot(v0, Heap::kempty_stringRootIndex); 20278a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ DropAndRet(argc + 1); 2028c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 2029c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2030c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&miss); 2031c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Restore function name in a2. 2032c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ li(a2, name); 20338a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org HandlerFrontendFooter(&name_miss); 2034c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2035c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Return the generated code. 20361510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org return GetCode(type, name); 20375c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 20385c838251403b0be9a882540f1922577abba4c872ager@chromium.org 20395c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2040c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgHandle<Code> CallStubCompiler::CompileStringFromCharCodeCall( 2041c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<Object> object, 2042c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSObject> holder, 2043f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org Handle<Cell> cell, 2044c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSFunction> function, 20451510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Handle<String> name, 20461510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Code::StubType type) { 2047c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org const int argc = arguments().immediate(); 2048c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2049c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // If the object is not a JSObject or we got an unexpected number of 2050c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // arguments, bail out to the regular call. 2051c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); 2052c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2053c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label miss; 2054cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); 2055cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org if (!cell.is_null()) { 2056c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(cell->value() == *function); 2057c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org GenerateLoadFunctionFromCell(cell, function, &miss); 2058c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 2059c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2060c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Load the char code argument. 2061c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Register code = a1; 2062c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(code, MemOperand(sp, 0 * kPointerSize)); 2063c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2064c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check the code is a smi. 2065c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label slow; 2066c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org STATIC_ASSERT(kSmiTag == 0); 2067c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ JumpIfNotSmi(code, &slow); 2068c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2069c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Convert the smi code to uint16. 2070c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ And(code, code, Operand(Smi::FromInt(0xffff))); 2071c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2072c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org StringCharFromCodeGenerator generator(code, v0); 2073c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org generator.GenerateFast(masm()); 20748a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ DropAndRet(argc + 1); 2075c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2076c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org StubRuntimeCallHelper call_helper; 2077c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org generator.GenerateSlow(masm(), call_helper); 2078c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2079c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&slow); 20808a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org // We do not have to patch the receiver because the function makes no use of 20818a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org // it. 20828a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org GenerateJumpFunctionIgnoreReceiver(function); 2083c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2084cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org HandlerFrontendFooter(&miss); 2085c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2086c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Return the generated code. 20871510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org return GetCode(type, name); 20885c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 20895c838251403b0be9a882540f1922577abba4c872ager@chromium.org 20905c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2091c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgHandle<Code> CallStubCompiler::CompileMathFloorCall( 2092c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<Object> object, 2093c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSObject> holder, 2094f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org Handle<Cell> cell, 2095c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSFunction> function, 20961510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Handle<String> name, 20971510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Code::StubType type) { 2098c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org const int argc = arguments().immediate(); 2099c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // If the object is not a JSObject or we got an unexpected number of 2100c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // arguments, bail out to the regular call. 2101c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); 2102c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2103c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label miss, slow; 2104cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); 2105cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org if (!cell.is_null()) { 2106c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(cell->value() == *function); 2107c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org GenerateLoadFunctionFromCell(cell, function, &miss); 2108c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 2109c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2110c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Load the (only) argument into v0. 2111c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(v0, MemOperand(sp, 0 * kPointerSize)); 2112c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2113c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // If the argument is a smi, just return. 2114c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org STATIC_ASSERT(kSmiTag == 0); 21157ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org __ SmiTst(v0, t0); 21168a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ DropAndRet(argc + 1, eq, t0, Operand(zero_reg)); 2117c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 211840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org __ CheckMap(v0, a1, Heap::kHeapNumberMapRootIndex, &slow, DONT_DO_SMI_CHECK); 2119c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2120c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label wont_fit_smi, no_fpu_error, restore_fcsr_and_return; 2121c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2122c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // If fpu is enabled, we use the floor instruction. 2123c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2124c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Load the HeapNumber value. 2125c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ ldc1(f0, FieldMemOperand(v0, HeapNumber::kValueOffset)); 2126c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2127c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Backup FCSR. 2128c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ cfc1(a3, FCSR); 2129c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Clearing FCSR clears the exception mask with no side-effects. 2130c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ ctc1(zero_reg, FCSR); 2131c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Convert the argument to an integer. 2132c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ floor_w_d(f0, f0); 2133c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2134c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Start checking for special cases. 2135c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Get the argument exponent and clear the sign bit. 2136c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(t1, FieldMemOperand(v0, HeapNumber::kValueOffset + kPointerSize)); 2137c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ And(t2, t1, Operand(~HeapNumber::kSignMask)); 2138c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ srl(t2, t2, HeapNumber::kMantissaBitsInTopWord); 2139c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2140c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Retrieve FCSR and check for fpu errors. 2141c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ cfc1(t5, FCSR); 2142d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com __ And(t5, t5, Operand(kFCSRExceptionFlagMask)); 2143c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Branch(&no_fpu_error, eq, t5, Operand(zero_reg)); 2144c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2145c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check for NaN, Infinity, and -Infinity. 2146c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // They are invariant through a Math.Floor call, so just 2147c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // return the original argument. 2148c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Subu(t3, t2, Operand(HeapNumber::kExponentMask 2149c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org >> HeapNumber::kMantissaBitsInTopWord)); 2150c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Branch(&restore_fcsr_and_return, eq, t3, Operand(zero_reg)); 2151c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // We had an overflow or underflow in the conversion. Check if we 2152c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // have a big exponent. 2153c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // If greater or equal, the argument is already round and in v0. 2154c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Branch(&restore_fcsr_and_return, ge, t3, 2155c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Operand(HeapNumber::kMantissaBits)); 2156c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Branch(&wont_fit_smi); 2157c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2158c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&no_fpu_error); 2159c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Move the result back to v0. 2160c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ mfc1(v0, f0); 2161c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check if the result fits into a smi. 2162c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Addu(a1, v0, Operand(0x40000000)); 2163c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Branch(&wont_fit_smi, lt, a1, Operand(zero_reg)); 2164c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Tag the result. 2165c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org STATIC_ASSERT(kSmiTag == 0); 2166c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ sll(v0, v0, kSmiTagSize); 2167c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2168c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check for -0. 2169c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Branch(&restore_fcsr_and_return, ne, v0, Operand(zero_reg)); 2170c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // t1 already holds the HeapNumber exponent. 2171c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ And(t0, t1, Operand(HeapNumber::kSignMask)); 2172c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // If our HeapNumber is negative it was -0, so load its address and return. 2173c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Else v0 is loaded with 0, so we can also just return. 2174c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Branch(&restore_fcsr_and_return, eq, t0, Operand(zero_reg)); 2175c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(v0, MemOperand(sp, 0 * kPointerSize)); 2176c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2177c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&restore_fcsr_and_return); 2178c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Restore FCSR and return. 2179c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ ctc1(a3, FCSR); 2180c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 21818a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ DropAndRet(argc + 1); 2182c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2183c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&wont_fit_smi); 2184c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Restore FCSR and fall to slow case. 2185c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ ctc1(a3, FCSR); 2186c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2187c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&slow); 21888a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org // We do not have to patch the receiver because the function makes no use of 21898a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org // it. 21908a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org GenerateJumpFunctionIgnoreReceiver(function); 2191c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2192cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org HandlerFrontendFooter(&miss); 2193c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2194c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Return the generated code. 21951510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org return GetCode(type, name); 21965c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 21975c838251403b0be9a882540f1922577abba4c872ager@chromium.org 21985c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2199c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgHandle<Code> CallStubCompiler::CompileMathAbsCall( 2200c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<Object> object, 2201c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSObject> holder, 2202f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org Handle<Cell> cell, 2203c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSFunction> function, 22041510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Handle<String> name, 22051510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Code::StubType type) { 2206c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org const int argc = arguments().immediate(); 2207c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // If the object is not a JSObject or we got an unexpected number of 2208c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // arguments, bail out to the regular call. 2209c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (!object->IsJSObject() || argc != 1) return Handle<Code>::null(); 2210c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2211c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label miss; 2212c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2213cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); 2214cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org if (!cell.is_null()) { 2215c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(cell->value() == *function); 2216c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org GenerateLoadFunctionFromCell(cell, function, &miss); 2217c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 2218c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2219c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Load the (only) argument into v0. 2220c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(v0, MemOperand(sp, 0 * kPointerSize)); 2221c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2222c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check if the argument is a smi. 2223c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label not_smi; 2224c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org STATIC_ASSERT(kSmiTag == 0); 2225c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ JumpIfNotSmi(v0, ¬_smi); 2226c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2227c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Do bitwise not or do nothing depending on the sign of the 2228c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // argument. 2229c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ sra(t0, v0, kBitsPerInt - 1); 2230c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Xor(a1, v0, t0); 2231c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2232c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Add 1 or do nothing depending on the sign of the argument. 2233c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Subu(v0, a1, t0); 2234c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2235c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // If the result is still negative, go to the slow case. 2236c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // This only happens for the most negative smi. 2237c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label slow; 2238c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Branch(&slow, lt, v0, Operand(zero_reg)); 2239c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2240c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Smi case done. 22418a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ DropAndRet(argc + 1); 2242c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2243c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check if the argument is a heap number and load its exponent and 2244c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // sign. 2245c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(¬_smi); 224640cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org __ CheckMap(v0, a1, Heap::kHeapNumberMapRootIndex, &slow, DONT_DO_SMI_CHECK); 2247c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(a1, FieldMemOperand(v0, HeapNumber::kExponentOffset)); 2248c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2249c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check the sign of the argument. If the argument is positive, 2250c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // just return it. 2251c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label negative_sign; 2252c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ And(t0, a1, Operand(HeapNumber::kSignMask)); 2253c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Branch(&negative_sign, ne, t0, Operand(zero_reg)); 22548a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ DropAndRet(argc + 1); 2255c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2256c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // If the argument is negative, clear the sign, and return a new 2257c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // number. 2258c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&negative_sign); 2259c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Xor(a1, a1, Operand(HeapNumber::kSignMask)); 2260c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(a3, FieldMemOperand(v0, HeapNumber::kMantissaOffset)); 2261c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ LoadRoot(t2, Heap::kHeapNumberMapRootIndex); 2262c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ AllocateHeapNumber(v0, t0, t1, t2, &slow); 2263c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ sw(a1, FieldMemOperand(v0, HeapNumber::kExponentOffset)); 2264c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ sw(a3, FieldMemOperand(v0, HeapNumber::kMantissaOffset)); 22658a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ DropAndRet(argc + 1); 2266c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2267c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&slow); 22688a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org // We do not have to patch the receiver because the function makes no use of 22698a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org // it. 22708a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org GenerateJumpFunctionIgnoreReceiver(function); 2271c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2272cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org HandlerFrontendFooter(&miss); 2273c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2274c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Return the generated code. 22751510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org return GetCode(type, name); 22765c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 22775c838251403b0be9a882540f1922577abba4c872ager@chromium.org 22785c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2279c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgHandle<Code> CallStubCompiler::CompileFastApiCall( 22807516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org const CallOptimization& optimization, 2281c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<Object> object, 2282c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSObject> holder, 2283f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org Handle<Cell> cell, 2284c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSFunction> function, 2285c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<String> name) { 2286c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 228740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org Counters* counters = isolate()->counters(); 2288c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2289c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(optimization.is_simple_api_call()); 2290c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Bail out if object is a global object as we don't want to 2291c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // repatch it to global receiver. 2292c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (object->IsGlobalObject()) return Handle<Code>::null(); 2293c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (!cell.is_null()) return Handle<Code>::null(); 2294c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (!object->IsJSObject()) return Handle<Code>::null(); 2295c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org int depth = optimization.GetPrototypeDepthOfExpectedType( 2296c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSObject>::cast(object), holder); 2297c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (depth == kInvalidProtoDepth) return Handle<Code>::null(); 2298c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2299c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label miss, miss_before_stack_reserved; 2300c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2301c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org GenerateNameCheck(name, &miss_before_stack_reserved); 2302c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2303c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Get the receiver from the stack. 2304c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org const int argc = arguments().immediate(); 2305c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(a1, MemOperand(sp, argc * kPointerSize)); 2306c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2307c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check that the receiver isn't a smi. 2308c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ JumpIfSmi(a1, &miss_before_stack_reserved); 2309c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2310c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ IncrementCounter(counters->call_const(), 1, a0, a3); 2311c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ IncrementCounter(counters->call_const_fast_api(), 1, a0, a3); 2312c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2313c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ReserveSpaceForFastApiCall(masm(), a0); 2314c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2315c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check that the maps haven't changed and find a Holder as a side effect. 2316f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org CheckPrototypes( 2317f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org IC::CurrentTypeOf(object, isolate()), 2318f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org a1, holder, a0, a3, t0, name, depth, &miss); 2319c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2320528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org GenerateFastApiDirectCall(masm(), optimization, argc, false); 2321c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2322c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&miss); 2323c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org FreeSpaceForFastApiCall(masm()); 2324c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 23258a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org HandlerFrontendFooter(&miss_before_stack_reserved); 2326c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2327c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Return the generated code. 2328c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org return GetCode(function); 23295c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 23305c838251403b0be9a882540f1922577abba4c872ager@chromium.org 23315c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2332b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.orgvoid StubCompiler::GenerateBooleanCheck(Register object, Label* miss) { 2333b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org Label success; 2334b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org // Check that the object is a boolean. 2335b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org __ LoadRoot(at, Heap::kTrueValueRootIndex); 2336b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org __ Branch(&success, eq, object, Operand(at)); 2337b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org __ LoadRoot(at, Heap::kFalseValueRootIndex); 2338b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org __ Branch(miss, ne, object, Operand(at)); 2339b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org __ bind(&success); 2340b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org} 2341b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org 2342b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org 2343cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.orgvoid CallStubCompiler::PatchGlobalProxy(Handle<Object> object) { 2344cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org if (object->IsGlobalObject()) { 2345cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org const int argc = arguments().immediate(); 2346cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org const int receiver_offset = argc * kPointerSize; 2347cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ lw(a3, FieldMemOperand(a0, GlobalObject::kGlobalReceiverOffset)); 2348cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ sw(a3, MemOperand(sp, receiver_offset)); 2349cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org } 2350cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org} 2351cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org 2352cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org 2353cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.orgRegister CallStubCompiler::HandlerFrontendHeader(Handle<Object> object, 2354cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org Handle<JSObject> holder, 2355cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org Handle<Name> name, 2356cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org CheckType check, 2357cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org Label* miss) { 2358c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // ----------- S t a t e ------------- 2359c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // -- a2 : name 2360c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // -- ra : return address 2361c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // ----------------------------------- 2362cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org GenerateNameCheck(name, miss); 2363cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org 2364cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org Register reg = a0; 2365c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2366c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Get the receiver from the stack. 2367c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org const int argc = arguments().immediate(); 2368cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org const int receiver_offset = argc * kPointerSize; 2369cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ lw(a0, MemOperand(sp, receiver_offset)); 2370c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2371c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check that the receiver isn't a smi. 2372c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (check != NUMBER_CHECK) { 2373cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ JumpIfSmi(a0, miss); 2374c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 2375c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2376c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Make sure that it's okay not to patch the on stack receiver 2377c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // unless we're doing a receiver map check. 2378c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); 2379c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org switch (check) { 2380c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org case RECEIVER_MAP_CHECK: 2381cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ IncrementCounter(isolate()->counters()->call_const(), 1, a1, a3); 2382c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2383c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check that the maps haven't changed. 2384cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org reg = CheckPrototypes( 2385f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org IC::CurrentTypeOf(object, isolate()), 2386cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org reg, holder, a1, a3, t0, name, miss); 2387c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org break; 2388c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2389f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org case STRING_CHECK: { 2390750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org // Check that the object is a string. 2391cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ GetObjectType(reg, a3, a3); 2392cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ Branch(miss, Ugreater_equal, a3, Operand(FIRST_NONSTRING_TYPE)); 23932f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org // Check that the maps starting from the prototype haven't changed. 23942f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org GenerateDirectLoadGlobalFunctionPrototype( 2395cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org masm(), Context::STRING_FUNCTION_INDEX, a1, miss); 2396c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org break; 2397f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org } 2398f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org case SYMBOL_CHECK: { 23999faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org // Check that the object is a symbol. 2400cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ GetObjectType(reg, a1, a3); 2401cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ Branch(miss, ne, a3, Operand(SYMBOL_TYPE)); 2402f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // Check that the maps starting from the prototype haven't changed. 2403f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org GenerateDirectLoadGlobalFunctionPrototype( 2404cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org masm(), Context::SYMBOL_FUNCTION_INDEX, a1, miss); 24059faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org break; 2406f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org } 24072f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org case NUMBER_CHECK: { 2408c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label fast; 24092f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org // Check that the object is a smi or a heap number. 2410cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ JumpIfSmi(reg, &fast); 2411cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ GetObjectType(reg, a3, a3); 2412cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ Branch(miss, ne, a3, Operand(HEAP_NUMBER_TYPE)); 24132f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org __ bind(&fast); 24142f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org // Check that the maps starting from the prototype haven't changed. 24152f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org GenerateDirectLoadGlobalFunctionPrototype( 2416cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org masm(), Context::NUMBER_FUNCTION_INDEX, a1, miss); 2417c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org break; 24182f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org } 24192f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org case BOOLEAN_CHECK: { 2420cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org GenerateBooleanCheck(reg, miss); 2421b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org 24222f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org // Check that the maps starting from the prototype haven't changed. 24232f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org GenerateDirectLoadGlobalFunctionPrototype( 2424cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org masm(), Context::BOOLEAN_FUNCTION_INDEX, a1, miss); 2425c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org break; 2426c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 24272f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org } 24282f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org 2429cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org if (check != RECEIVER_MAP_CHECK) { 2430cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org Handle<Object> prototype(object->GetPrototype(isolate()), isolate()); 2431cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org reg = CheckPrototypes( 2432cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org IC::CurrentTypeOf(prototype, isolate()), 2433cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org a1, holder, a1, a3, t0, name, miss); 2434cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org } 2435b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org 2436cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org return reg; 24372f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org} 24382f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org 24392f0efdebb142c00de6950453b4c2df20ceb8df6emmassi@chromium.org 24408a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.orgvoid CallStubCompiler::GenerateJumpFunction(Handle<Object> object, 24418a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org Register function, 24428a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org Label* miss) { 24438a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org ASSERT(function.is(a1)); 24448a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org // Check that the function really is a function. 24458a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org GenerateFunctionCheck(function, a3, miss); 2446cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org PatchGlobalProxy(object); 24478a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org // Invoke the function. 24488a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org __ InvokeFunction(a1, arguments(), JUMP_FUNCTION, 24498a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org NullCallWrapper(), call_kind()); 24505c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 24515c838251403b0be9a882540f1922577abba4c872ager@chromium.org 24525c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2453c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgHandle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, 2454c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSObject> holder, 24559faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org Handle<Name> name) { 2456c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label miss; 2457c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2458c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org GenerateNameCheck(name, &miss); 2459c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2460c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Get the number of arguments. 2461c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org const int argc = arguments().immediate(); 2462394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com LookupResult lookup(isolate()); 2463c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org LookupPostInterceptor(holder, name, &lookup); 2464c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2465c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Get the receiver from the stack. 2466c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(a1, MemOperand(sp, argc * kPointerSize)); 2467c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2468ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org CallInterceptorCompiler compiler(this, arguments(), a2, extra_state()); 2469c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org compiler.Compile(masm(), object, holder, name, &lookup, a1, a3, t0, a0, 2470c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org &miss); 2471c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2472c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Move returned value, the function to call, to a1. 2473c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ mov(a1, v0); 2474c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Restore receiver. 2475c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(a0, MemOperand(sp, argc * kPointerSize)); 2476c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 24778a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org GenerateJumpFunction(object, a1, &miss); 2478c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 24798a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org HandlerFrontendFooter(&miss); 2480c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2481c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Return the generated code. 24829af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org return GetCode(Code::FAST, name); 24835c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 24845c838251403b0be9a882540f1922577abba4c872ager@chromium.org 24855c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2486c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgHandle<Code> CallStubCompiler::CompileCallGlobal( 2487c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSObject> object, 2488c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<GlobalObject> holder, 2489b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Handle<PropertyCell> cell, 2490c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSFunction> function, 24919faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org Handle<Name> name) { 2492c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (HasCustomCallGenerator(function)) { 24939faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org Handle<Code> code = CompileCustomCall( 24941510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org object, holder, cell, function, Handle<String>::cast(name), 24951510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org Code::NORMAL); 2496c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org // A null handle means bail out to the regular compiler code below. 2497c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (!code.is_null()) return code; 2498c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 2499c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2500c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label miss; 2501cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); 25028a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org // Potentially loads a closure that matches the shared function info of the 25038a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org // function, rather than function. 2504c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org GenerateLoadFunctionFromCell(cell, function, &miss); 250532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Counters* counters = isolate()->counters(); 2506c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ IncrementCounter(counters->call_global_inline(), 1, a3, t0); 25078a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org GenerateJumpFunction(object, a1, function); 2508cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org HandlerFrontendFooter(&miss); 2509c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2510c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Return the generated code. 25117a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org return GetCode(Code::NORMAL, name); 25125c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 25135c838251403b0be9a882540f1922577abba4c872ager@chromium.org 25145c838251403b0be9a882540f1922577abba4c872ager@chromium.org 25156e28b5694dd5a29d2f37d56d5a005e7cfdd952d1erik.corry@gmail.comHandle<Code> StoreStubCompiler::CompileStoreCallback( 25164c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org Handle<JSObject> object, 2517355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org Handle<JSObject> holder, 2518bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org Handle<Name> name, 2519c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org Handle<ExecutableAccessorInfo> callback) { 2520f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org HandlerFrontend(IC::CurrentTypeOf(object, isolate()), 2521f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org receiver(), holder, name); 2522c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2523c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Stub never generated for non-global objects that require access 2524c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // checks. 2525355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); 2526c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 25274c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org __ push(receiver()); // Receiver. 25284c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org __ li(at, Operand(callback)); // Callback info. 2529bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org __ push(at); 2530bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org __ li(at, Operand(name)); 2531bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org __ Push(at, value()); 2532c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2533c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Do tail-call to the runtime system. 2534c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ExternalReference store_callback_property = 253532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); 2536c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ TailCallExternalReference(store_callback_property, 4, 1); 2537c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2538c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Return the generated code. 25399af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org return GetCode(kind(), Code::FAST, name); 25407516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 25417516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 25427516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 2543639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.orgHandle<Code> StoreStubCompiler::CompileStoreCallback( 2544639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org Handle<JSObject> object, 2545639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org Handle<JSObject> holder, 2546639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org Handle<Name> name, 2547639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org const CallOptimization& call_optimization) { 2548f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org HandlerFrontend(IC::CurrentTypeOf(object, isolate()), 2549f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org receiver(), holder, name); 2550639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org 2551639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org Register values[] = { value() }; 2552639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org GenerateFastApiCall( 2553639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org masm(), call_optimization, receiver(), scratch3(), 1, values); 2554639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org 2555639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org // Return the generated code. 25569af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org return GetCode(kind(), Code::FAST, name); 2557639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org} 2558639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org 2559639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org 256046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org#undef __ 256146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org#define __ ACCESS_MASM(masm) 256246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 256346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 256446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.orgvoid StoreStubCompiler::GenerateStoreViaSetter( 256546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org MacroAssembler* masm, 2566619781ad24991bca2894d2f677ac960da366b11esvenpanne@chromium.org Handle<JSFunction> setter) { 25677028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // ----------- S t a t e ------------- 25687028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // -- a0 : value 25697028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // -- a1 : receiver 25707028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // -- a2 : name 25717028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // -- ra : return address 25727028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // ----------------------------------- 25737028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org { 257446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org FrameScope scope(masm, StackFrame::INTERNAL); 25757028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 25767028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // Save value register, so we can restore it later. 25777028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org __ push(a0); 25787028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 257946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org if (!setter.is_null()) { 258046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Call the JavaScript setter with receiver and value on the stack. 258146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ push(a1); 258246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ push(a0); 258346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org ParameterCount actual(1); 258432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org ParameterCount expected(setter); 258532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org __ InvokeFunction(setter, expected, actual, 258632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org CALL_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); 258746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org } else { 258846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // If we generate a global code snippet for deoptimization only, remember 258946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // the place to continue after deoptimization. 259046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset()); 259146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org } 25927028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 25937028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // We have to return the passed value, not the return value of the setter. 25947028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org __ pop(v0); 25957028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 25967028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // Restore context register. 25977028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 25987028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org } 25997028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org __ Ret(); 260046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org} 260146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 260246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 260346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org#undef __ 260446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org#define __ ACCESS_MASM(masm()) 260546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 260646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 26076e28b5694dd5a29d2f37d56d5a005e7cfdd952d1erik.corry@gmail.comHandle<Code> StoreStubCompiler::CompileStoreInterceptor( 26084c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org Handle<JSObject> object, 26099faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org Handle<Name> name) { 2610c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label miss; 2611c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2612c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check that the map of the object hasn't changed. 26134c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org __ CheckMap(receiver(), scratch1(), Handle<Map>(object->map()), &miss, 2614a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org DO_SMI_CHECK); 2615c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2616c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Perform global security token check if needed. 26174c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org if (object->IsJSGlobalProxy()) { 26184c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org __ CheckAccessGlobalProxy(receiver(), scratch1(), &miss); 2619c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 2620c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2621c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Stub is never generated for non-global objects that require access 2622c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // checks. 26234c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 2624c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 26254c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org __ Push(receiver(), this->name(), value()); 2626c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2627c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Do tail-call to the runtime system. 2628c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ExternalReference store_ic_property = 262932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate()); 2630cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ TailCallExternalReference(store_ic_property, 3, 1); 2631c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2632c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Handle store cache miss. 2633c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&miss); 26342bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org TailCallBuiltin(masm(), MissBuiltin(kind())); 2635c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2636c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Return the generated code. 26379af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org return GetCode(kind(), Code::FAST, name); 26387516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 26397516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 26407516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 2641f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.orgHandle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<Type> type, 2642f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Handle<JSObject> last, 2643f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Handle<Name> name) { 2644f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org NonexistentHandlerFrontend(type, last, name); 264594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 2646c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Return undefined if maps of the full prototype chain is still the same. 2647c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ LoadRoot(v0, Heap::kUndefinedValueRootIndex); 2648c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Ret(); 2649c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2650c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Return the generated code. 26519af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org return GetCode(kind(), Code::FAST, name); 26527516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 26537516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 26547516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 265594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.orgRegister* LoadStubCompiler::registers() { 265694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org // receiver, name, scratch1, scratch2, scratch3, scratch4. 265794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org static Register registers[] = { a0, a2, a3, a1, t0, t1 }; 265894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org return registers; 265994b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org} 2660c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2661c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 266294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.orgRegister* KeyedLoadStubCompiler::registers() { 266394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org // receiver, name, scratch1, scratch2, scratch3, scratch4. 266494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org static Register registers[] = { a1, a0, a2, a3, t0, t1 }; 266594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org return registers; 26665c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 26675c838251403b0be9a882540f1922577abba4c872ager@chromium.org 26685c838251403b0be9a882540f1922577abba4c872ager@chromium.org 26692bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.orgRegister* StoreStubCompiler::registers() { 26702bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org // receiver, name, value, scratch1, scratch2, scratch3. 26712bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org static Register registers[] = { a1, a2, a0, a3, t0, t1 }; 26722bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org return registers; 26732bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org} 26742bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org 26752bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org 26762bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.orgRegister* KeyedStoreStubCompiler::registers() { 26772bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org // receiver, name, value, scratch1, scratch2, scratch3. 26782bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org static Register registers[] = { a2, a1, a0, a3, t0, t1 }; 26792bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org return registers; 26802bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org} 26812bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org 26822bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org 26839faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.orgvoid KeyedLoadStubCompiler::GenerateNameCheck(Handle<Name> name, 268494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org Register name_reg, 268594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org Label* miss) { 268694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org __ Branch(miss, ne, name_reg, Operand(name)); 26875c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 26885c838251403b0be9a882540f1922577abba4c872ager@chromium.org 26895c838251403b0be9a882540f1922577abba4c872ager@chromium.org 26902bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.orgvoid KeyedStoreStubCompiler::GenerateNameCheck(Handle<Name> name, 26912bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Register name_reg, 26922bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org Label* miss) { 26932bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org __ Branch(miss, ne, name_reg, Operand(name)); 26942bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org} 26952bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org 26962bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org 2697de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org#undef __ 2698de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org#define __ ACCESS_MASM(masm) 2699de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org 2700de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org 2701de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.orgvoid LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm, 27022efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Register receiver, 2703de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org Handle<JSFunction> getter) { 2704de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org // ----------- S t a t e ------------- 2705de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org // -- a0 : receiver 2706de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org // -- a2 : name 2707de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org // -- ra : return address 2708de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org // ----------------------------------- 2709de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org { 2710de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org FrameScope scope(masm, StackFrame::INTERNAL); 2711de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org 2712de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org if (!getter.is_null()) { 2713de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org // Call the JavaScript getter with the receiver on the stack. 27142efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org __ push(receiver); 2715de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org ParameterCount actual(0); 271632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org ParameterCount expected(getter); 271732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org __ InvokeFunction(getter, expected, actual, 271832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org CALL_FUNCTION, NullCallWrapper(), CALL_AS_METHOD); 2719de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org } else { 2720de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org // If we generate a global code snippet for deoptimization only, remember 2721de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org // the place to continue after deoptimization. 2722de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset()); 2723de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org } 2724de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org 2725de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org // Restore context register. 2726de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 2727de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org } 2728de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org __ Ret(); 2729de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org} 2730de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org 2731de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org 2732de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org#undef __ 2733de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org#define __ ACCESS_MASM(masm()) 2734de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org 2735de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org 27366e28b5694dd5a29d2f37d56d5a005e7cfdd952d1erik.corry@gmail.comHandle<Code> LoadStubCompiler::CompileLoadGlobal( 2737f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Handle<Type> type, 27384a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Handle<GlobalObject> global, 2739b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Handle<PropertyCell> cell, 27409faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org Handle<Name> name, 27416e28b5694dd5a29d2f37d56d5a005e7cfdd952d1erik.corry@gmail.com bool is_dont_delete) { 2742b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org Label miss; 2743c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2744f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org HandlerFrontendHeader(type, receiver(), global, name, &miss); 2745c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2746c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Get the value from the cell. 27476e28b5694dd5a29d2f37d56d5a005e7cfdd952d1erik.corry@gmail.com __ li(a3, Operand(cell)); 2748f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org __ lw(t0, FieldMemOperand(a3, Cell::kValueOffset)); 2749c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2750c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check for deleted property if property can actually be deleted. 2751c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (!is_dont_delete) { 2752c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 2753c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Branch(&miss, eq, t0, Operand(at)); 2754c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 2755c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2756b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org HandlerFrontendFooter(name, &miss); 27574a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 275832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Counters* counters = isolate()->counters(); 2759c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ IncrementCounter(counters->named_load_global_stub(), 1, a1, a3); 27608a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ Ret(USE_DELAY_SLOT); 27614a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ mov(v0, t0); 2762c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2763c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Return the generated code. 2764e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org return GetCode(kind(), Code::NORMAL, name); 27655c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 27667516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 27677516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 2768bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.orgHandle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC( 2769af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org TypeHandleList* types, 27709faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org CodeHandleList* handlers, 27719faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org Handle<Name> name, 27729faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org Code::StubType type, 27739faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org IcCheckType check) { 277440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org Label miss; 27759faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org 27769faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org if (check == PROPERTY) { 27779faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org GenerateNameCheck(name, this->name(), &miss); 27789faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org } 27799faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org 2780b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org Label number_case; 2781e3b442bc2783b64f4114011f9bbb0f1904d4b019palfia@homejinni.com Register match = scratch1(); 2782af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org Label* smi_target = IncludesNumberType(types) ? &number_case : &miss; 2783e3b442bc2783b64f4114011f9bbb0f1904d4b019palfia@homejinni.com __ JumpIfSmi(receiver(), smi_target, match); // Reg match is 0 if Smi. 2784b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org 2785e3b442bc2783b64f4114011f9bbb0f1904d4b019palfia@homejinni.com Register map_reg = scratch2(); 2786c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2787af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org int receiver_count = types->length(); 2788f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org int number_of_handled_maps = 0; 27899faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org __ lw(map_reg, FieldMemOperand(receiver(), HeapObject::kMapOffset)); 279040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org for (int current = 0; current < receiver_count; ++current) { 2791af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org Handle<Type> type = types->at(current); 2792af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org Handle<Map> map = IC::TypeToMap(*type, isolate()); 2793f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org if (!map->is_deprecated()) { 2794f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org number_of_handled_maps++; 2795e3b442bc2783b64f4114011f9bbb0f1904d4b019palfia@homejinni.com // Check map and tail call if there's a match. 2796e3b442bc2783b64f4114011f9bbb0f1904d4b019palfia@homejinni.com // Separate compare from branch, to provide path for above JumpIfSmi(). 2797e3b442bc2783b64f4114011f9bbb0f1904d4b019palfia@homejinni.com __ Subu(match, map_reg, Operand(map)); 2798af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org if (type->Is(Type::Number())) { 2799b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org ASSERT(!number_case.is_unused()); 2800b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org __ bind(&number_case); 2801b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org } 2802f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ Jump(handlers->at(current), RelocInfo::CODE_TARGET, 2803e3b442bc2783b64f4114011f9bbb0f1904d4b019palfia@homejinni.com eq, match, Operand(zero_reg)); 2804f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } 280540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org } 2806f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org ASSERT(number_of_handled_maps != 0); 2807c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2808c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&miss); 28092bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org TailCallBuiltin(masm(), MissBuiltin(kind())); 2810c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2811c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Return the generated code. 28129faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org InlineCacheState state = 2813f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org number_of_handled_maps > 1 ? POLYMORPHIC : MONOMORPHIC; 28149faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org return GetICCode(kind(), type, name, state); 28157516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 28167516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 28177516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 28186e28b5694dd5a29d2f37d56d5a005e7cfdd952d1erik.corry@gmail.comHandle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic( 28196e28b5694dd5a29d2f37d56d5a005e7cfdd952d1erik.corry@gmail.com MapHandleList* receiver_maps, 28206e28b5694dd5a29d2f37d56d5a005e7cfdd952d1erik.corry@gmail.com CodeHandleList* handler_stubs, 28216e28b5694dd5a29d2f37d56d5a005e7cfdd952d1erik.corry@gmail.com MapHandleList* transitioned_maps) { 282240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org Label miss; 28234c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org __ JumpIfSmi(receiver(), &miss); 282440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 282540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org int receiver_count = receiver_maps->length(); 28264c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org __ lw(scratch1(), FieldMemOperand(receiver(), HeapObject::kMapOffset)); 2827b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org for (int i = 0; i < receiver_count; ++i) { 28286e28b5694dd5a29d2f37d56d5a005e7cfdd952d1erik.corry@gmail.com if (transitioned_maps->at(i).is_null()) { 28296e28b5694dd5a29d2f37d56d5a005e7cfdd952d1erik.corry@gmail.com __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET, eq, 28304c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org scratch1(), Operand(receiver_maps->at(i))); 2831b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org } else { 2832b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org Label next_map; 28334c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org __ Branch(&next_map, ne, scratch1(), Operand(receiver_maps->at(i))); 28344c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org __ li(transition_map(), Operand(transitioned_maps->at(i))); 28356e28b5694dd5a29d2f37d56d5a005e7cfdd952d1erik.corry@gmail.com __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET); 2836b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org __ bind(&next_map); 2837b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org } 2838c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 2839c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2840c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&miss); 28412bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org TailCallBuiltin(masm(), MissBuiltin(kind())); 2842c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 2843c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Return the generated code. 28442bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org return GetICCode( 28452bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC); 28465c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 28475c838251403b0be9a882540f1922577abba4c872ager@chromium.org 28485c838251403b0be9a882540f1922577abba4c872ager@chromium.org 284940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org#undef __ 285040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org#define __ ACCESS_MASM(masm) 285140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 285240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 28536db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.orgvoid KeyedLoadStubCompiler::GenerateLoadDictionaryElement( 28546db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org MacroAssembler* masm) { 28556db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // ---------- S t a t e -------------- 28566db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // -- ra : return address 28576db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // -- a0 : key 28586db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // -- a1 : receiver 28596db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // ----------------------------------- 2860af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org Label slow, miss; 28616db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 28626db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register key = a0; 28636db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register receiver = a1; 28646db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 2865af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org __ JumpIfNotSmi(key, &miss); 28666db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org __ lw(t0, FieldMemOperand(receiver, JSObject::kElementsOffset)); 28676db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org __ sra(a2, a0, kSmiTagSize); 28686db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org __ LoadFromNumberDictionary(&slow, t0, a0, v0, a2, a3, t1); 28696db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org __ Ret(); 28706db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 28716db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Slow case, key and receiver still in a0 and a1. 28726db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org __ bind(&slow); 28736db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org __ IncrementCounter( 28746db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org masm->isolate()->counters()->keyed_load_external_array_slow(), 28756db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 1, a2, a3); 28766db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Entry registers are intact. 28776db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // ---------- S t a t e -------------- 28786db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // -- ra : return address 28796db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // -- a0 : key 28806db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // -- a1 : receiver 28816db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // ----------------------------------- 28822bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow); 28836db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 28846db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Miss case, call the runtime. 2885af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org __ bind(&miss); 28866db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 28876db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // ---------- S t a t e -------------- 28886db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // -- ra : return address 28896db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // -- a0 : key 28906db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // -- a1 : receiver 28916db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // ----------------------------------- 2892af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 28936db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org} 28946db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 28956db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 28965c838251403b0be9a882540f1922577abba4c872ager@chromium.org#undef __ 28975c838251403b0be9a882540f1922577abba4c872ager@chromium.org 28985c838251403b0be9a882540f1922577abba4c872ager@chromium.org} } // namespace v8::internal 28995c838251403b0be9a882540f1922577abba4c872ager@chromium.org 29009dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com#endif // V8_TARGET_ARCH_MIPS 2901