105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be 33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file. 45c838251403b0be9a882540f1922577abba4c872ager@chromium.org 5196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h" 65c838251403b0be9a882540f1922577abba4c872ager@chromium.org 793a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_MIPS 89dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com 9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/ic-inl.h" 10196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/codegen.h" 11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/stub-cache.h" 125c838251403b0be9a882540f1922577abba4c872ager@chromium.org 135c838251403b0be9a882540f1922577abba4c872ager@chromium.orgnamespace v8 { 145c838251403b0be9a882540f1922577abba4c872ager@chromium.orgnamespace internal { 155c838251403b0be9a882540f1922577abba4c872ager@chromium.org 165c838251403b0be9a882540f1922577abba4c872ager@chromium.org#define __ ACCESS_MASM(masm) 175c838251403b0be9a882540f1922577abba4c872ager@chromium.org 185c838251403b0be9a882540f1922577abba4c872ager@chromium.org 19c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.orgstatic void ProbeTable(Isolate* isolate, 20c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org MacroAssembler* masm, 21c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Code::Flags flags, 22c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org StubCache::Table table, 2335814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org Register receiver, 24c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Register name, 2535814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org // Number of the cache entry, not scaled. 26c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Register offset, 27c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Register scratch, 2835814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org Register scratch2, 2935814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org Register offset_scratch) { 30c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ExternalReference key_offset(isolate->stub_cache()->key_reference(table)); 31c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ExternalReference value_offset(isolate->stub_cache()->value_reference(table)); 3235814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org ExternalReference map_offset(isolate->stub_cache()->map_reference(table)); 33c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 34c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org uint32_t key_off_addr = reinterpret_cast<uint32_t>(key_offset.address()); 35c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org uint32_t value_off_addr = reinterpret_cast<uint32_t>(value_offset.address()); 3635814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org uint32_t map_off_addr = reinterpret_cast<uint32_t>(map_offset.address()); 37c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 38c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check the relative positions of the address fields. 39c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(value_off_addr > key_off_addr); 40c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT((value_off_addr - key_off_addr) % 4 == 0); 41c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT((value_off_addr - key_off_addr) < (256 * 4)); 4235814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org ASSERT(map_off_addr > key_off_addr); 4335814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org ASSERT((map_off_addr - key_off_addr) % 4 == 0); 4435814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org ASSERT((map_off_addr - key_off_addr) < (256 * 4)); 45c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 46c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label miss; 4735814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org Register base_addr = scratch; 4835814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org scratch = no_reg; 4935814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org 5035814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org // Multiply by 3 because there are 3 fields per entry (name, code, map). 5135814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ sll(offset_scratch, offset, 1); 5235814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ Addu(offset_scratch, offset_scratch, offset); 5335814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org 5435814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org // Calculate the base address of the entry. 5535814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ li(base_addr, Operand(key_offset)); 5635814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ sll(at, offset_scratch, kPointerSizeLog2); 5735814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ Addu(base_addr, base_addr, at); 58c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 59c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check that the key in the entry matches the name. 6035814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ lw(at, MemOperand(base_addr, 0)); 6135814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ Branch(&miss, ne, name, Operand(at)); 6235814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org 6335814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org // Check the map matches. 6435814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ lw(at, MemOperand(base_addr, map_off_addr - key_off_addr)); 6535814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ lw(scratch2, FieldMemOperand(receiver, HeapObject::kMapOffset)); 6635814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ Branch(&miss, ne, at, Operand(scratch2)); 67c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 68c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Get the code entry from the cache. 6935814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org Register code = scratch2; 7035814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org scratch2 = no_reg; 7135814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ lw(code, MemOperand(base_addr, value_off_addr - key_off_addr)); 72c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 73c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check that the flags match what we're looking for. 7435814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org Register flags_reg = base_addr; 7535814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org base_addr = no_reg; 7635814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ lw(flags_reg, FieldMemOperand(code, Code::kFlagsOffset)); 7735814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ And(flags_reg, flags_reg, Operand(~Code::kFlagsNotUsedInLookup)); 7835814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ Branch(&miss, ne, flags_reg, Operand(flags)); 7935814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org 8035814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org#ifdef DEBUG 8135814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org if (FLAG_test_secondary_stub_cache && table == StubCache::kPrimary) { 8235814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ jmp(&miss); 8335814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org } else if (FLAG_test_primary_stub_cache && table == StubCache::kSecondary) { 8435814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ jmp(&miss); 8535814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org } 8635814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org#endif 87c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 88c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Jump to the first instruction in the code stub. 8935814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ Addu(at, code, Operand(Code::kHeaderSize - kHeapObjectTag)); 9035814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ Jump(at); 91c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 92c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Miss: fall through. 93c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&miss); 94c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org} 95c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 96c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 97057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.orgvoid StubCompiler::GenerateDictionaryNegativeLookup(MacroAssembler* masm, 98057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org Label* miss_label, 99057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org Register receiver, 100057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org Handle<Name> name, 101057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org Register scratch0, 102057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org Register scratch1) { 1039faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org ASSERT(name->IsUniqueName()); 104057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org ASSERT(!receiver.is(scratch0)); 105394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Counters* counters = masm->isolate()->counters(); 106394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); 107394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); 108394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 109394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Label done; 110394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 111394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com const int kInterceptorOrAccessCheckNeededMask = 112394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); 113394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 114394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Bail out if the receiver has a named interceptor or requires access checks. 115394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Register map = scratch1; 116394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ lw(map, FieldMemOperand(receiver, HeapObject::kMapOffset)); 117394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ lbu(scratch0, FieldMemOperand(map, Map::kBitFieldOffset)); 118394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ And(scratch0, scratch0, Operand(kInterceptorOrAccessCheckNeededMask)); 119394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Branch(miss_label, ne, scratch0, Operand(zero_reg)); 120394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 121394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Check that receiver is a JSObject. 122394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ lbu(scratch0, FieldMemOperand(map, Map::kInstanceTypeOffset)); 123394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Branch(miss_label, lt, scratch0, Operand(FIRST_SPEC_OBJECT_TYPE)); 124394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 125394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Load properties array. 126394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Register properties = scratch0; 127394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ lw(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); 128394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Check that the properties array is a dictionary. 129394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ lw(map, FieldMemOperand(properties, HeapObject::kMapOffset)); 130394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Register tmp = properties; 131394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ LoadRoot(tmp, Heap::kHashTableMapRootIndex); 132394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ Branch(miss_label, ne, map, Operand(tmp)); 133394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 134394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Restore the temporarily used register. 135394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ lw(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); 136394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 137394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1389faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org NameDictionaryLookupStub::GenerateNegativeLookup(masm, 1399faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org miss_label, 1409faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org &done, 1419faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org receiver, 1429faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org properties, 1439faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org name, 1449faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org scratch1); 145394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ bind(&done); 146394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); 147394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com} 148394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 149394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 1505c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid StubCache::GenerateProbe(MacroAssembler* masm, 1515c838251403b0be9a882540f1922577abba4c872ager@chromium.org Code::Flags flags, 1525c838251403b0be9a882540f1922577abba4c872ager@chromium.org Register receiver, 1535c838251403b0be9a882540f1922577abba4c872ager@chromium.org Register name, 1545c838251403b0be9a882540f1922577abba4c872ager@chromium.org Register scratch, 155e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org Register extra, 15635814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org Register extra2, 15735814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org Register extra3) { 158c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Isolate* isolate = masm->isolate(); 159c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label miss; 160c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 16135814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org // Make sure that code is valid. The multiplying code relies on the 16235814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org // entry size being 12. 16335814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org ASSERT(sizeof(Entry) == 12); 164c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 165c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Make sure the flags does not name a specific type. 166c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(Code::ExtractTypeFromFlags(flags) == 0); 167c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 168c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Make sure that there are no register conflicts. 169c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(!scratch.is(receiver)); 170c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(!scratch.is(name)); 171c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(!extra.is(receiver)); 172c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(!extra.is(name)); 173c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(!extra.is(scratch)); 174c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(!extra2.is(receiver)); 175c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(!extra2.is(name)); 176c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(!extra2.is(scratch)); 177c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(!extra2.is(extra)); 178c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 17935814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org // Check register validity. 180c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(!scratch.is(no_reg)); 181c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(!extra.is(no_reg)); 182c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(!extra2.is(no_reg)); 18335814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org ASSERT(!extra3.is(no_reg)); 18435814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org 18535814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org Counters* counters = masm->isolate()->counters(); 18635814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ IncrementCounter(counters->megamorphic_stub_cache_probes(), 1, 18735814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org extra2, extra3); 188c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 189c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check that the receiver isn't a smi. 19035814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ JumpIfSmi(receiver, &miss); 191c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 192c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Get the map of the receiver and compute the hash. 1939faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org __ lw(scratch, FieldMemOperand(name, Name::kHashFieldOffset)); 19435814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ lw(at, FieldMemOperand(receiver, HeapObject::kMapOffset)); 19535814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ Addu(scratch, scratch, at); 19635814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org uint32_t mask = kPrimaryTableSize - 1; 19735814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org // We shift out the last two bits because they are not part of the hash and 19835814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org // they are always 01 for maps. 19935814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ srl(scratch, scratch, kHeapObjectTagSize); 20035814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ Xor(scratch, scratch, Operand((flags >> kHeapObjectTagSize) & mask)); 20135814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ And(scratch, scratch, Operand(mask)); 202c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 203c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Probe the primary table. 20435814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org ProbeTable(isolate, 20535814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org masm, 20635814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org flags, 20735814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org kPrimary, 20835814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org receiver, 20935814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org name, 21035814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org scratch, 21135814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org extra, 21235814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org extra2, 21335814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org extra3); 214c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 215c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Primary miss: Compute hash for secondary probe. 21635814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ srl(at, name, kHeapObjectTagSize); 21735814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ Subu(scratch, scratch, at); 21835814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org uint32_t mask2 = kSecondaryTableSize - 1; 21935814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ Addu(scratch, scratch, Operand((flags >> kHeapObjectTagSize) & mask2)); 22035814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ And(scratch, scratch, Operand(mask2)); 221c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 222c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Probe the secondary table. 22335814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org ProbeTable(isolate, 22435814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org masm, 22535814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org flags, 22635814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org kSecondary, 22735814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org receiver, 22835814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org name, 22935814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org scratch, 23035814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org extra, 23135814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org extra2, 23235814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org extra3); 233c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 234c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Cache miss: Fall-through and let caller handle the miss by 235c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // entering the runtime system. 236c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&miss); 23735814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org __ IncrementCounter(counters->megamorphic_stub_cache_misses(), 1, 23835814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org extra2, extra3); 2395c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 2405c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2415c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2425c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid StubCompiler::GenerateLoadGlobalFunctionPrototype(MacroAssembler* masm, 2435c838251403b0be9a882540f1922577abba4c872ager@chromium.org int index, 2445c838251403b0be9a882540f1922577abba4c872ager@chromium.org Register prototype) { 245c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Load the global or builtins object from the current context. 246c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(prototype, 24746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX))); 24846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Load the native context from the global or builtins object. 24946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org __ lw(prototype, 25046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org FieldMemOperand(prototype, GlobalObject::kNativeContextOffset)); 25146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Load the function from the native context. 252c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(prototype, MemOperand(prototype, Context::SlotOffset(index))); 253c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Load the initial map. The global functions all have initial maps. 254c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(prototype, 255c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org FieldMemOperand(prototype, JSFunction::kPrototypeOrInitialMapOffset)); 256c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Load the prototype from the initial map. 257c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset)); 2585c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 2595c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2605c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2617516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid StubCompiler::GenerateDirectLoadGlobalFunctionPrototype( 262c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org MacroAssembler* masm, 263c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org int index, 264c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register prototype, 265c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Label* miss) { 266c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Isolate* isolate = masm->isolate(); 267c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Get the global function with the given index. 268c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSFunction> function( 26946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org JSFunction::cast(isolate->native_context()->get(index))); 27057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org 27157a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org // Check we're still in the same context. 27257a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org Register scratch = prototype; 27357a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org const int offset = Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX); 27457a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org __ lw(scratch, MemOperand(cp, offset)); 27557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org __ lw(scratch, FieldMemOperand(scratch, GlobalObject::kNativeContextOffset)); 27657a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org __ lw(scratch, MemOperand(scratch, Context::SlotOffset(index))); 27757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org __ li(at, function); 27857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org __ Branch(miss, ne, at, Operand(scratch)); 27957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org 280c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Load its initial map. The global functions all have initial maps. 281c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ li(prototype, Handle<Map>(function->initial_map())); 282c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Load the prototype from the initial map. 283c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset)); 2847516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 2857516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 2867516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 28757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.orgvoid StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm, 28857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Register dst, 28957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Register src, 29057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org bool inobject, 29157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org int index, 29257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Representation representation) { 293bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org ASSERT(!representation.IsDouble()); 2949faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org int offset = index * kPointerSize; 2959faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org if (!inobject) { 2969faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org // Calculate the offset into the properties array. 2979faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org offset = offset + FixedArray::kHeaderSize; 2989faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org __ lw(dst, FieldMemOperand(src, JSObject::kPropertiesOffset)); 2999faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org src = dst; 300c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 3019faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org __ lw(dst, FieldMemOperand(src, offset)); 3025c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 3035c838251403b0be9a882540f1922577abba4c872ager@chromium.org 3045c838251403b0be9a882540f1922577abba4c872ager@chromium.org 3055c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid StubCompiler::GenerateLoadArrayLength(MacroAssembler* masm, 3065c838251403b0be9a882540f1922577abba4c872ager@chromium.org Register receiver, 3075c838251403b0be9a882540f1922577abba4c872ager@chromium.org Register scratch, 3085c838251403b0be9a882540f1922577abba4c872ager@chromium.org Label* miss_label) { 309c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check that the receiver isn't a smi. 310c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ JumpIfSmi(receiver, miss_label); 311c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 312c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check that the object is a JS array. 313c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ GetObjectType(receiver, scratch, scratch); 314c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Branch(miss_label, ne, scratch, Operand(JS_ARRAY_TYPE)); 315c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 316c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Load length directly from the JS array. 3178a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ Ret(USE_DELAY_SLOT); 318c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ lw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset)); 319c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org} 320c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 321c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 3225c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid StubCompiler::GenerateLoadFunctionPrototype(MacroAssembler* masm, 3235c838251403b0be9a882540f1922577abba4c872ager@chromium.org Register receiver, 3245c838251403b0be9a882540f1922577abba4c872ager@chromium.org Register scratch1, 3255c838251403b0be9a882540f1922577abba4c872ager@chromium.org Register scratch2, 3265c838251403b0be9a882540f1922577abba4c872ager@chromium.org Label* miss_label) { 327c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label); 3288a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ Ret(USE_DELAY_SLOT); 329c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ mov(v0, scratch1); 3305c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 3315c838251403b0be9a882540f1922577abba4c872ager@chromium.org 3325c838251403b0be9a882540f1922577abba4c872ager@chromium.org 333057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.orgvoid StubCompiler::GenerateCheckPropertyCell(MacroAssembler* masm, 334057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org Handle<JSGlobalObject> global, 335057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org Handle<Name> name, 336057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org Register scratch, 337057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org Label* miss) { 338057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org Handle<Cell> cell = JSGlobalObject::EnsurePropertyCell(global, name); 339e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(cell->value()->IsTheHole()); 340e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ li(scratch, Operand(cell)); 341f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org __ lw(scratch, FieldMemOperand(scratch, Cell::kValueOffset)); 342e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 343e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ Branch(miss, ne, scratch, Operand(at)); 344e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 345e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 346e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 3472efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgvoid StoreStubCompiler::GenerateNegativeHolderLookup( 348bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org MacroAssembler* masm, 349bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org Handle<JSObject> holder, 350bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org Register holder_reg, 351bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org Handle<Name> name, 352bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org Label* miss) { 353bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org if (holder->IsJSGlobalObject()) { 354bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org GenerateCheckPropertyCell( 355057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org masm, Handle<JSGlobalObject>::cast(holder), name, scratch1(), miss); 356bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } else if (!holder->HasFastProperties() && !holder->IsJSGlobalProxy()) { 357bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org GenerateDictionaryNegativeLookup( 358bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org masm, miss, holder_reg, name, scratch1(), scratch2()); 359bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } 360bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org} 361bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 362bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 363e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// Generate StoreTransition code, value is passed in a0 register. 3645c838251403b0be9a882540f1922577abba4c872ager@chromium.org// After executing generated code, the receiver_reg and name_reg 3655c838251403b0be9a882540f1922577abba4c872ager@chromium.org// may be clobbered. 3662efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgvoid StoreStubCompiler::GenerateStoreTransition(MacroAssembler* masm, 3672efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Handle<JSObject> object, 3682efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org LookupResult* lookup, 3692efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Handle<Map> transition, 3702efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Handle<Name> name, 3712efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Register receiver_reg, 3722efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Register storage_reg, 3732efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Register value_reg, 3742efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Register scratch1, 3752efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Register scratch2, 3762efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Register scratch3, 3772efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Label* miss_label, 3782efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Label* slow) { 379c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // a0 : value. 380c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Label exit; 3817028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 382f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org int descriptor = transition->LastAdded(); 383f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org DescriptorArray* descriptors = transition->instance_descriptors(); 384f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org PropertyDetails details = descriptors->GetDetails(descriptor); 385f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org Representation representation = details.representation(); 386f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org ASSERT(!representation.IsNone()); 387f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 388fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org if (details.type() == CONSTANT) { 389fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org Handle<Object> constant(descriptors->GetValue(descriptor), masm->isolate()); 390057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org __ li(scratch1, constant); 391bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org __ Branch(miss_label, ne, value_reg, Operand(scratch1)); 392bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org } else if (representation.IsSmi()) { 393bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org __ JumpIfNotSmi(value_reg, miss_label); 394bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org } else if (representation.IsHeapObject()) { 3958496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org __ JumpIfSmi(value_reg, miss_label); 396731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org HeapType* field_type = descriptors->GetFieldType(descriptor); 3978496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org HeapType::Iterator<Map> it = field_type->Classes(); 3988496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org Handle<Map> current; 3998496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org if (!it.Done()) { 4008496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org __ lw(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset)); 4018496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org Label do_store; 4028496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org while (true) { 4038496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org // Do the CompareMap() directly within the Branch() functions. 4048496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org current = it.Current(); 4058496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org it.Advance(); 4068496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org if (it.Done()) { 4078496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org __ Branch(miss_label, ne, scratch1, Operand(current)); 4088496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org break; 4098496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org } 4108496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org __ Branch(&do_store, eq, scratch1, Operand(current)); 4118496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org } 4128496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org __ bind(&do_store); 413731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org } 414bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org } else if (representation.IsDouble()) { 41557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Label do_store, heap_number; 41657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ LoadRoot(scratch3, Heap::kHeapNumberMapRootIndex); 41757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ AllocateHeapNumber(storage_reg, scratch1, scratch2, scratch3, slow); 41857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 41957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ JumpIfNotSmi(value_reg, &heap_number); 42057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ SmiUntag(scratch1, value_reg); 42157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ mtc1(scratch1, f6); 42257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ cvt_d_w(f4, f6); 42357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ jmp(&do_store); 42457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 42557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ bind(&heap_number); 42657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex, 427bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org miss_label, DONT_DO_SMI_CHECK); 42857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ ldc1(f4, FieldMemOperand(value_reg, HeapNumber::kValueOffset)); 42957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 43057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ bind(&do_store); 43157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ sdc1(f4, FieldMemOperand(storage_reg, HeapNumber::kValueOffset)); 43257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } 43357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 434c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Stub never generated for non-global objects that require access 435c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // checks. 436c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 437c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 438c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Perform map transition for the receiver if necessary. 439b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org if (details.type() == FIELD && 440b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org object->map()->unused_property_fields() == 0) { 441c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // The properties must be extended before we can store the value. 442c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // We jump to a runtime call that extends the properties array. 443c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ push(receiver_reg); 4446e28b5694dd5a29d2f37d56d5a005e7cfdd952d1erik.corry@gmail.com __ li(a2, Operand(transition)); 445c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Push(a2, a0); 446c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ TailCallExternalReference( 447c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), 448c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org masm->isolate()), 449c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 3, 1); 450c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org return; 451c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 452c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 453e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Update the map of the object. 454e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ li(scratch1, Operand(transition)); 455e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ sw(scratch1, FieldMemOperand(receiver_reg, HeapObject::kMapOffset)); 456e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 457bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org // Update the write barrier for the map field. 458e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ RecordWriteField(receiver_reg, 459e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org HeapObject::kMapOffset, 460e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org scratch1, 46157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org scratch2, 462e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org kRAHasNotBeenSaved, 463e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org kDontSaveFPRegs, 464e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org OMIT_REMEMBERED_SET, 465e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org OMIT_SMI_CHECK); 466e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 467fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org if (details.type() == CONSTANT) { 468b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org ASSERT(value_reg.is(a0)); 469b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ Ret(USE_DELAY_SLOT); 470b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org __ mov(v0, a0); 471b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org return; 472b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org } 473b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 474e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org int index = transition->instance_descriptors()->GetFieldIndex( 475e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org transition->LastAdded()); 476e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 477e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Adjust for the number of properties stored in the object. Even in the 478e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // face of a transition we can use the old map here because the size of the 479e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // object and the number of in-object properties is not going to change. 480e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org index -= object->map()->inobject_properties(); 481e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 482e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // TODO(verwaest): Share this code as a code stub. 483a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org SmiCheck smi_check = representation.IsTagged() 484a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org ? INLINE_SMI_CHECK : OMIT_SMI_CHECK; 485e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org if (index < 0) { 486e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Set the property straight into the object. 487e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org int offset = object->map()->instance_size() + (index * kPointerSize); 488bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org if (representation.IsDouble()) { 48957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ sw(storage_reg, FieldMemOperand(receiver_reg, offset)); 49057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } else { 49157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ sw(value_reg, FieldMemOperand(receiver_reg, offset)); 49257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } 493e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 494bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org if (!representation.IsSmi()) { 495f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org // Update the write barrier for the array address. 496bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org if (!representation.IsDouble()) { 497bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org __ mov(storage_reg, value_reg); 49857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } 499f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ RecordWriteField(receiver_reg, 500f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org offset, 501bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org storage_reg, 502f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org scratch1, 503f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org kRAHasNotBeenSaved, 504a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org kDontSaveFPRegs, 505a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org EMIT_REMEMBERED_SET, 506a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org smi_check); 507f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } 508f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org } else { 509e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Write to the properties array. 510e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org int offset = index * kPointerSize + FixedArray::kHeaderSize; 511e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Get the properties array 512e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ lw(scratch1, 513e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset)); 514bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org if (representation.IsDouble()) { 51557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ sw(storage_reg, FieldMemOperand(scratch1, offset)); 51657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } else { 51757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ sw(value_reg, FieldMemOperand(scratch1, offset)); 51857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } 519e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 520bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org if (!representation.IsSmi()) { 521f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org // Update the write barrier for the array address. 522bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org if (!representation.IsDouble()) { 523bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org __ mov(storage_reg, value_reg); 52457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } 525f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ RecordWriteField(scratch1, 526f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org offset, 527bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org storage_reg, 528f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org receiver_reg, 529f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org kRAHasNotBeenSaved, 530a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org kDontSaveFPRegs, 531a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org EMIT_REMEMBERED_SET, 532a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org smi_check); 533f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } 534e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org } 535e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 536e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Return the value (register v0). 537e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(value_reg.is(a0)); 538e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ bind(&exit); 5398a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ Ret(USE_DELAY_SLOT); 540e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org __ mov(v0, a0); 541e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 542e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 543e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 544e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// Generate StoreField code, value is passed in a0 register. 545e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// When leaving generated code after success, the receiver_reg and name_reg 546e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// may be clobbered. Upon branch to miss_label, the receiver and name 547e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// registers have their original values. 5482efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgvoid StoreStubCompiler::GenerateStoreField(MacroAssembler* masm, 5492efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Handle<JSObject> object, 5502efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org LookupResult* lookup, 5512efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Register receiver_reg, 5522efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Register name_reg, 5532efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Register value_reg, 5542efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Register scratch1, 5552efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Register scratch2, 5562efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Label* miss_label) { 557e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // a0 : value 558e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org Label exit; 559e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 560e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Stub never generated for non-global objects that require access 561e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // checks. 562e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 563e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 564e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org FieldIndex index = lookup->GetFieldIndex(); 565c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 566f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org Representation representation = lookup->representation(); 567f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org ASSERT(!representation.IsNone()); 568bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org if (representation.IsSmi()) { 569f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ JumpIfNotSmi(value_reg, miss_label); 570bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org } else if (representation.IsHeapObject()) { 5718496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org __ JumpIfSmi(value_reg, miss_label); 572731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org HeapType* field_type = lookup->GetFieldType(); 5738496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org HeapType::Iterator<Map> it = field_type->Classes(); 5748496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org if (!it.Done()) { 5758496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org __ lw(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset)); 5768496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org Label do_store; 5778496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org Handle<Map> current; 5788496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org while (true) { 5798496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org // Do the CompareMap() directly within the Branch() functions. 5808496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org current = it.Current(); 5818496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org it.Advance(); 5828496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org if (it.Done()) { 5838496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org __ Branch(miss_label, ne, scratch1, Operand(current)); 5848496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org break; 5858496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org } 5868496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org __ Branch(&do_store, eq, scratch1, Operand(current)); 5878496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org } 5888496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org __ bind(&do_store); 589731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org } 590bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org } else if (representation.IsDouble()) { 59157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org // Load the double storage. 592e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org if (index.is_inobject()) { 593e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org __ lw(scratch1, FieldMemOperand(receiver_reg, index.offset())); 59457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } else { 59557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ lw(scratch1, 59657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset)); 597e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org __ lw(scratch1, FieldMemOperand(scratch1, index.offset())); 59857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } 59957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 60057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org // Store the value into the storage. 60157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Label do_store, heap_number; 60257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ JumpIfNotSmi(value_reg, &heap_number); 60357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ SmiUntag(scratch2, value_reg); 60457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ mtc1(scratch2, f6); 60557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ cvt_d_w(f4, f6); 60657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ jmp(&do_store); 60757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 60857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ bind(&heap_number); 60957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ CheckMap(value_reg, scratch2, Heap::kHeapNumberMapRootIndex, 610f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org miss_label, DONT_DO_SMI_CHECK); 61157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ ldc1(f4, FieldMemOperand(value_reg, HeapNumber::kValueOffset)); 61257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 613f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ bind(&do_store); 61457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ sdc1(f4, FieldMemOperand(scratch1, HeapNumber::kValueOffset)); 61557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org // Return the value (register v0). 61657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org ASSERT(value_reg.is(a0)); 6178a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ Ret(USE_DELAY_SLOT); 61857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org __ mov(v0, a0); 61957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org return; 620f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } 621f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 622e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // TODO(verwaest): Share this code as a code stub. 623a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org SmiCheck smi_check = representation.IsTagged() 624a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org ? INLINE_SMI_CHECK : OMIT_SMI_CHECK; 625e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org if (index.is_inobject()) { 626c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Set the property straight into the object. 627e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org __ sw(value_reg, FieldMemOperand(receiver_reg, index.offset())); 628c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 629bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org if (!representation.IsSmi()) { 630f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org // Skip updating write barrier if storing a smi. 631f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ JumpIfSmi(value_reg, &exit); 632f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 633f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org // Update the write barrier for the array address. 634f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org // Pass the now unused name_reg as a scratch register. 635f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ mov(name_reg, value_reg); 636f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ RecordWriteField(receiver_reg, 637e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org index.offset(), 638f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org name_reg, 639f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org scratch1, 640f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org kRAHasNotBeenSaved, 641a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org kDontSaveFPRegs, 642a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org EMIT_REMEMBERED_SET, 643a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org smi_check); 644f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } 645c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } else { 646c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Write to the properties array. 647c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Get the properties array. 6487028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org __ lw(scratch1, 6497028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset)); 650e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org __ sw(value_reg, FieldMemOperand(scratch1, index.offset())); 651c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 652bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org if (!representation.IsSmi()) { 653f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org // Skip updating write barrier if storing a smi. 654f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ JumpIfSmi(value_reg, &exit); 655f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 656f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org // Update the write barrier for the array address. 657f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org // Ok to clobber receiver_reg and name_reg, since we return. 658f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ mov(name_reg, value_reg); 659f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ RecordWriteField(scratch1, 660e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org index.offset(), 661f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org name_reg, 662f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org receiver_reg, 663f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org kRAHasNotBeenSaved, 664a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org kDontSaveFPRegs, 665a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org EMIT_REMEMBERED_SET, 666a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org smi_check); 667f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } 668c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 669c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 670c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Return the value (register v0). 6712bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org ASSERT(value_reg.is(a0)); 672c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&exit); 6738a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ Ret(USE_DELAY_SLOT); 674c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ mov(v0, a0); 6755c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 6765c838251403b0be9a882540f1922577abba4c872ager@chromium.org 6775c838251403b0be9a882540f1922577abba4c872ager@chromium.org 6782efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgvoid StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm, 6792efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Label* label, 6802efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Handle<Name> name) { 6812bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org if (!label->is_unused()) { 6822bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org __ bind(label); 6832bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org __ li(this->name(), Operand(name)); 6842bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org } 685068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org} 686068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org 687068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org 688c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.orgstatic void PushInterceptorArguments(MacroAssembler* masm, 689c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Register receiver, 690c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Register holder, 691c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Register name, 692c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSObject> holder_obj) { 6934a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org STATIC_ASSERT(StubCache::kInterceptorArgsNameIndex == 0); 6944a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org STATIC_ASSERT(StubCache::kInterceptorArgsInfoIndex == 1); 6954a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org STATIC_ASSERT(StubCache::kInterceptorArgsThisIndex == 2); 6964a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org STATIC_ASSERT(StubCache::kInterceptorArgsHolderIndex == 3); 6974a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org STATIC_ASSERT(StubCache::kInterceptorArgsLength == 4); 698c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ push(name); 699c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<InterceptorInfo> interceptor(holder_obj->GetNamedInterceptor()); 700c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ASSERT(!masm->isolate()->heap()->InNewSpace(*interceptor)); 701c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org Register scratch = name; 702c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org __ li(scratch, Operand(interceptor)); 703c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Push(scratch, receiver, holder); 704c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org} 705c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 706c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 707c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgstatic void CompileCallLoadPropertyWithInterceptor( 708c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org MacroAssembler* masm, 709c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register receiver, 710c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register holder, 711c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Register name, 71237be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org Handle<JSObject> holder_obj, 71337be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org IC::UtilityId id) { 714c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org PushInterceptorArguments(masm, receiver, holder, name, holder_obj); 71537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org __ CallExternalReference( 71637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org ExternalReference(IC_Utility(id), masm->isolate()), 71737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org StubCache::kInterceptorArgsLength); 718c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org} 719c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 720c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 7216f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org// Generate call to api function. 722f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgvoid StubCompiler::GenerateFastApiCall(MacroAssembler* masm, 723f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org const CallOptimization& optimization, 724f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Handle<Map> receiver_map, 725f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Register receiver, 726f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Register scratch_in, 727f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org bool is_store, 728f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int argc, 729f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Register* values) { 7306f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org ASSERT(!receiver.is(scratch_in)); 7316f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org // Preparing to push, adjust sp. 7326f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org __ Subu(sp, sp, Operand((argc + 1) * kPointerSize)); 7336f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org __ sw(receiver, MemOperand(sp, argc * kPointerSize)); // Push receiver. 7346f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org // Write the arguments to stack frame. 7356f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org for (int i = 0; i < argc; i++) { 7366f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org Register arg = values[argc-1-i]; 7376f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org ASSERT(!receiver.is(arg)); 7386f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org ASSERT(!scratch_in.is(arg)); 7396f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org __ sw(arg, MemOperand(sp, (argc-1-i) * kPointerSize)); // Push arg. 7406f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org } 741cc96b0ea1fd0249c4914f68201fc8a7a93d7b9b2palfia@homejinni.com ASSERT(optimization.is_simple_api_call()); 742cc96b0ea1fd0249c4914f68201fc8a7a93d7b9b2palfia@homejinni.com 743e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org // Abi for CallApiFunctionStub. 744e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org Register callee = a0; 745e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org Register call_data = t0; 746e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org Register holder = a2; 74757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org Register api_function_address = a1; 748cc96b0ea1fd0249c4914f68201fc8a7a93d7b9b2palfia@homejinni.com 749e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org // Put holder in place. 7506f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org CallOptimization::HolderLookup holder_lookup; 7516f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org Handle<JSObject> api_holder = optimization.LookupHolderOfExpectedType( 7526f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org receiver_map, 7536f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org &holder_lookup); 7546f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org switch (holder_lookup) { 7556f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org case CallOptimization::kHolderIsReceiver: 7566f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org __ Move(holder, receiver); 7576f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org break; 7586f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org case CallOptimization::kHolderFound: 7596f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org __ li(holder, api_holder); 7606f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org break; 7616f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org case CallOptimization::kHolderNotFound: 7626f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org UNREACHABLE(); 7636f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org break; 7646f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org } 765cc96b0ea1fd0249c4914f68201fc8a7a93d7b9b2palfia@homejinni.com 766e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org Isolate* isolate = masm->isolate(); 767c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<JSFunction> function = optimization.constant_function(); 768c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); 769e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org Handle<Object> call_data_obj(api_call_info->data(), isolate); 770e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org 771e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org // Put callee in place. 772e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org __ li(callee, function); 773e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org 774cc96b0ea1fd0249c4914f68201fc8a7a93d7b9b2palfia@homejinni.com bool call_data_undefined = false; 775e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org // Put call_data in place. 776e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org if (isolate->heap()->InNewSpace(*call_data_obj)) { 777e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org __ li(call_data, api_call_info); 778e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org __ lw(call_data, FieldMemOperand(call_data, CallHandlerInfo::kDataOffset)); 779e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org } else if (call_data_obj->IsUndefined()) { 780cc96b0ea1fd0249c4914f68201fc8a7a93d7b9b2palfia@homejinni.com call_data_undefined = true; 781e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org __ LoadRoot(call_data, Heap::kUndefinedValueRootIndex); 782c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } else { 783e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org __ li(call_data, call_data_obj); 784c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 785e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org // Put api_function_address in place. 786662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org Address function_address = v8::ToCData<Address>(api_call_info->callback()); 787c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ApiFunction fun(function_address); 788662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org ExternalReference::Type type = ExternalReference::DIRECT_API_CALL; 789c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ExternalReference ref = 790c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ExternalReference(&fun, 791bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org type, 792c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org masm->isolate()); 793e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org __ li(api_function_address, Operand(ref)); 794fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org 795e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org // Jump to stub. 796f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc); 797e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org __ TailCallStub(&stub); 798c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org} 799c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 800639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org 8012bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.orgvoid StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) { 8029faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org __ Jump(code, RelocInfo::CODE_TARGET); 8039faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org} 8049faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org 8059faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org 8062bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org#undef __ 8072bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org#define __ ACCESS_MASM(masm()) 8082bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org 8092bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org 8106d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.orgRegister StubCompiler::CheckPrototypes(Handle<HeapType> type, 811394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Register object_reg, 812394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Handle<JSObject> holder, 813394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Register holder_reg, 814394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Register scratch1, 815394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Register scratch2, 8169faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org Handle<Name> name, 8179faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org Label* miss, 8189faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org PrototypeCheckType check) { 819f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Handle<Map> receiver_map(IC::TypeToMap(*type, isolate())); 820ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 821394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Make sure there's no overlap between holder and object registers. 822394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); 823394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) 824394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com && !scratch2.is(scratch1)); 825394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 826394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Keep track of the current object in register reg. 827394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Register reg = object_reg; 828394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com int depth = 0; 829394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 830f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Handle<JSObject> current = Handle<JSObject>::null(); 831fa04143c1ab67009bfa167c48e1cf21fdf009796palfia@homejinni.com if (type->IsConstant()) { 832fa04143c1ab67009bfa167c48e1cf21fdf009796palfia@homejinni.com current = Handle<JSObject>::cast(type->AsConstant()->Value()); 833fa04143c1ab67009bfa167c48e1cf21fdf009796palfia@homejinni.com } 834f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Handle<JSObject> prototype = Handle<JSObject>::null(); 835f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Handle<Map> current_map = receiver_map; 836f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Handle<Map> holder_map(holder->map()); 837f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org // Traverse the prototype chain and check the maps in the prototype chain for 838f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org // fast and global objects or do negative lookup for normal objects. 839f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org while (!current_map.is_identical_to(holder_map)) { 840394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ++depth; 841394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 842394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Only global objects and objects that do not require access 843394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // checks are allowed in stubs. 844f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org ASSERT(current_map->IsJSGlobalProxyMap() || 845f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org !current_map->is_access_check_needed()); 846394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 847f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org prototype = handle(JSObject::cast(current_map->prototype())); 848f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org if (current_map->is_dictionary_map() && 849f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org !current_map->IsJSGlobalObjectMap() && 850f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org !current_map->IsJSGlobalProxyMap()) { 8519faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org if (!name->IsUniqueName()) { 8529faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org ASSERT(name->IsString()); 8539faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org name = factory()->InternalizeString(Handle<String>::cast(name)); 854394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 855f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org ASSERT(current.is_null() || 856f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org current->property_dictionary()->FindEntry(name) == 8579faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org NameDictionary::kNotFound); 858394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 859394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com GenerateDictionaryNegativeLookup(masm(), miss, reg, name, 860394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com scratch1, scratch2); 861394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 862394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset)); 863394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com reg = holder_reg; // From now on the object will be in holder_reg. 864394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ lw(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset)); 865394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } else { 8669faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org Register map_reg = scratch1; 867f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org if (depth != 1 || check == CHECK_ALL_MAPS) { 8689faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org // CheckMap implicitly loads the map of |reg| into |map_reg|. 869a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org __ CheckMap(reg, map_reg, current_map, miss, DONT_DO_SMI_CHECK); 8709faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org } else { 8719faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org __ lw(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset)); 8729faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org } 873f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org 874394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Check access rights to the global object. This has to happen after 875394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // the map check so that we know that the object is actually a global 876394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // object. 877f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org if (current_map->IsJSGlobalProxyMap()) { 878394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ CheckAccessGlobalProxy(reg, scratch2, miss); 879f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org } else if (current_map->IsJSGlobalObjectMap()) { 880f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org GenerateCheckPropertyCell( 881f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org masm(), Handle<JSGlobalObject>::cast(current), name, 882f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org scratch2, miss); 883394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 884f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org 885394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com reg = holder_reg; // From now on the object will be in holder_reg. 886394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 887394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (heap()->InNewSpace(*prototype)) { 888394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // The prototype is in new space; we cannot store a reference to it 889394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // in the code. Load it from the map. 8909faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org __ lw(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset)); 891394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } else { 892394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // The prototype is in old space; load it directly. 893394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ li(reg, Operand(prototype)); 894394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 895394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 896394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 897394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Go to the next object in the prototype chain. 898394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com current = prototype; 899f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org current_map = handle(current->map()); 900394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 901394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 902394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Log the check depth. 90332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); 904394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 905f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org if (depth != 0 || check == CHECK_ALL_MAPS) { 9069faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org // Check the holder map. 907f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org __ CheckMap(reg, scratch1, current_map, miss, DONT_DO_SMI_CHECK); 9089faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org } 909394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 910394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Perform security check for access to the global object. 911f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org ASSERT(current_map->IsJSGlobalProxyMap() || 912f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org !current_map->is_access_check_needed()); 913f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org if (current_map->IsJSGlobalProxyMap()) { 914394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com __ CheckAccessGlobalProxy(reg, scratch1, miss); 915394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 916394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 917394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Return the register containing the holder. 918394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com return reg; 919394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com} 920394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 921394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 922b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.orgvoid LoadStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) { 9239faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org if (!miss->is_unused()) { 924b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org Label success; 925b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org __ Branch(&success); 9269faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org __ bind(miss); 9272bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org TailCallBuiltin(masm(), MissBuiltin(kind())); 928b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org __ bind(&success); 9299faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org } 9305c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 9315c838251403b0be9a882540f1922577abba4c872ager@chromium.org 9325c838251403b0be9a882540f1922577abba4c872ager@chromium.org 933b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.orgvoid StoreStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) { 934bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org if (!miss->is_unused()) { 935b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org Label success; 936b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org __ Branch(&success); 937bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org GenerateRestoreName(masm(), miss, name); 938bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org TailCallBuiltin(masm(), MissBuiltin(kind())); 939b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org __ bind(&success); 940bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org } 941bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org} 942bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 943bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 9442efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgRegister LoadStubCompiler::CallbackHandlerFrontend( 9456d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org Handle<HeapType> type, 9464a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Register object_reg, 9474a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Handle<JSObject> holder, 9489faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org Handle<Name> name, 9492c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org Handle<Object> callback) { 9504a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Label miss; 951c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 952f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Register reg = HandlerFrontendHeader(type, object_reg, holder, name, &miss); 9535c838251403b0be9a882540f1922577abba4c872ager@chromium.org 9544a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { 9554a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org ASSERT(!reg.is(scratch2())); 9564a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org ASSERT(!reg.is(scratch3())); 9574a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org ASSERT(!reg.is(scratch4())); 9584a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 9594a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // Load the properties dictionary. 9604a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Register dictionary = scratch4(); 9614a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ lw(dictionary, FieldMemOperand(reg, JSObject::kPropertiesOffset)); 9624a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 9634a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // Probe the dictionary. 9644a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Label probe_done; 9659faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org NameDictionaryLookupStub::GeneratePositiveLookup(masm(), 9669faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org &miss, 9679faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org &probe_done, 9689faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org dictionary, 9699faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org this->name(), 9709faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org scratch2(), 9719faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org scratch3()); 9724a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ bind(&probe_done); 9734a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 9744a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // If probing finds an entry in the dictionary, scratch3 contains the 9754a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // pointer into the dictionary. Check that the value is the callback. 9764a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Register pointer = scratch3(); 9779faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org const int kElementsStartOffset = NameDictionary::kHeaderSize + 9789faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org NameDictionary::kElementsStartIndex * kPointerSize; 9794a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org const int kValueOffset = kElementsStartOffset + kPointerSize; 9804a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ lw(scratch2(), FieldMemOperand(pointer, kValueOffset)); 9814a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ Branch(&miss, ne, scratch2(), Operand(callback)); 9824a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org } 9835c838251403b0be9a882540f1922577abba4c872ager@chromium.org 984b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org HandlerFrontendFooter(name, &miss); 9854a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org return reg; 986471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org} 987471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org 988471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org 9892efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgvoid LoadStubCompiler::GenerateLoadField(Register reg, 9902efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Handle<JSObject> holder, 991e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org FieldIndex field, 9922efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Representation representation) { 99357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org if (!reg.is(receiver())) __ mov(receiver(), reg); 99457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org if (kind() == Code::LOAD_IC) { 995e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org LoadFieldStub stub(isolate(), field); 996f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org GenerateTailCall(masm(), stub.GetCode()); 99757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } else { 998e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org KeyedLoadFieldStub stub(isolate(), field); 999f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org GenerateTailCall(masm(), stub.GetCode()); 100057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } 10014a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org} 10024a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 10034a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 10042efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgvoid LoadStubCompiler::GenerateLoadConstant(Handle<Object> value) { 10054a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // Return the constant value. 1006057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org __ li(v0, value); 10074a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ Ret(); 10084a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org} 10094a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 10104a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 10112efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgvoid LoadStubCompiler::GenerateLoadCallback( 10124a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Register reg, 10134a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Handle<ExecutableAccessorInfo> callback) { 1014c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Build AccessorInfo::args_ list on the stack and push property name below 1015c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // the exit frame to make GC aware of them and store pointers to them. 1016fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0); 1017fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1); 1018fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2); 1019fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3); 1020fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4); 1021fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5); 1022fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 6); 10234a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org ASSERT(!scratch2().is(reg)); 10244a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org ASSERT(!scratch3().is(reg)); 10254a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org ASSERT(!scratch4().is(reg)); 10264a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ push(receiver()); 1027c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org if (heap()->InNewSpace(callback->data())) { 10284a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ li(scratch3(), callback); 10294a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ lw(scratch3(), FieldMemOperand(scratch3(), 10304a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org ExecutableAccessorInfo::kDataOffset)); 1031c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } else { 103232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org __ li(scratch3(), Handle<Object>(callback->data(), isolate())); 1033c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 103479d0bf7c99ebe30751b199f72fa06fe34a5ded48palfia@homejinni.com __ Subu(sp, sp, 6 * kPointerSize); 10354a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org __ sw(scratch3(), MemOperand(sp, 5 * kPointerSize)); 1036c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org __ LoadRoot(scratch3(), Heap::kUndefinedValueRootIndex); 10374a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org __ sw(scratch3(), MemOperand(sp, 4 * kPointerSize)); 103879d0bf7c99ebe30751b199f72fa06fe34a5ded48palfia@homejinni.com __ sw(scratch3(), MemOperand(sp, 3 * kPointerSize)); 1039c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org __ li(scratch4(), 104032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Operand(ExternalReference::isolate_address(isolate()))); 10414a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org __ sw(scratch4(), MemOperand(sp, 2 * kPointerSize)); 10424a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org __ sw(reg, MemOperand(sp, 1 * kPointerSize)); 10434a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ sw(name(), MemOperand(sp, 0 * kPointerSize)); 1044fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org __ Addu(scratch2(), sp, 1 * kPointerSize); 1045ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com 10464a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ mov(a2, scratch2()); // Saved in case scratch2 == a1. 104757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org // Abi for CallApiGetter. 104857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org Register getter_address_reg = a2; 1049c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 1050662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org Address getter_address = v8::ToCData<Address>(callback->getter()); 1051c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org ApiFunction fun(getter_address); 1052662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL; 1053fe578677d80b14b35f6dca0c193719331b81a81edanno@chromium.org ExternalReference ref = ExternalReference(&fun, type, isolate()); 1054e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org __ li(getter_address_reg, Operand(ref)); 105557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org 1056f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CallApiGetterStub stub(isolate()); 105757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org __ TailCallStub(&stub); 10585c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 10595c838251403b0be9a882540f1922577abba4c872ager@chromium.org 10605c838251403b0be9a882540f1922577abba4c872ager@chromium.org 10612efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgvoid LoadStubCompiler::GenerateLoadInterceptor( 10624a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Register holder_reg, 1063b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org Handle<Object> object, 10644a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Handle<JSObject> interceptor_holder, 10654a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org LookupResult* lookup, 10669faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org Handle<Name> name) { 1067c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(interceptor_holder->HasNamedInterceptor()); 1068c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); 1069c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1070c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // So far the most popular follow ups for interceptor loads are FIELD 1071c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // and CALLBACKS, so inline only them, other cases may be added 1072c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // later. 1073c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org bool compile_followup_inline = false; 107405ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org if (lookup->IsFound() && lookup->IsCacheable()) { 1075de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org if (lookup->IsField()) { 1076c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org compile_followup_inline = true; 1077c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } else if (lookup->type() == CALLBACKS && 1078c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org lookup->GetCallbackObject()->IsExecutableAccessorInfo()) { 1079c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org ExecutableAccessorInfo* callback = 1080c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org ExecutableAccessorInfo::cast(lookup->GetCallbackObject()); 10817028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org compile_followup_inline = callback->getter() != NULL && 10827028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org callback->IsCompatibleReceiver(*object); 1083c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 1084c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 1085c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1086c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (compile_followup_inline) { 1087c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Compile the interceptor call, followed by inline code to load the 1088c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // property from further up the prototype chain if the call fails. 1089c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check that the maps haven't changed. 10904a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org ASSERT(holder_reg.is(receiver()) || holder_reg.is(scratch1())); 1091c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1092212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org // Preserve the receiver register explicitly whenever it is different from 1093212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org // the holder and it is needed should the interceptor return without any 1094212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org // result. The CALLBACKS case needs the receiver to be passed into C++ code, 1095212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org // the FIELD case might cause a miss during the prototype check. 1096212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org bool must_perfrom_prototype_check = *interceptor_holder != lookup->holder(); 10974a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org bool must_preserve_receiver_reg = !receiver().is(holder_reg) && 1098212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org (lookup->type() == CALLBACKS || must_perfrom_prototype_check); 1099212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org 1100c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Save necessary data before invoking an interceptor. 1101c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Requires a frame to make GC aware of pushed pointers. 1102c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com { 1103c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com FrameScope frame_scope(masm(), StackFrame::INTERNAL); 1104212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org if (must_preserve_receiver_reg) { 11054a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ Push(receiver(), holder_reg, this->name()); 1106c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 11074a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ Push(holder_reg, this->name()); 1108c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 1109c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Invoke an interceptor. Note: map checks from receiver to 1110c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // interceptor's holder has been compiled before (see a caller 1111c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // of this method). 111237be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org CompileCallLoadPropertyWithInterceptor( 111337be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org masm(), receiver(), holder_reg, this->name(), interceptor_holder, 111437be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org IC::kLoadPropertyWithInterceptorOnly); 111537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org 1116c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Check if interceptor provided a value for property. If it's 1117c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // the case, return immediately. 1118c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com Label interceptor_failed; 11194a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ LoadRoot(scratch1(), Heap::kNoInterceptorResultSentinelRootIndex); 11204a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ Branch(&interceptor_failed, eq, v0, Operand(scratch1())); 1121c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com frame_scope.GenerateLeaveFrame(); 1122c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ Ret(); 1123c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1124c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ bind(&interceptor_failed); 11254a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ pop(this->name()); 1126c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com __ pop(holder_reg); 1127212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org if (must_preserve_receiver_reg) { 11284a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ pop(receiver()); 1129c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 1130c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com // Leave the internal frame. 1131c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 11324a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org GenerateLoadPostInterceptor(holder_reg, interceptor_holder, name, lookup); 1133c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } else { // !compile_followup_inline 1134c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Call the runtime system to load the interceptor. 1135c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check that the maps haven't changed. 11364a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org PushInterceptorArguments(masm(), receiver(), holder_reg, 11374a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org this->name(), interceptor_holder); 1138c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1139c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ExternalReference ref = ExternalReference( 11408ddb15e9094939a28890ee8bbc7f7fa246ecea49machenbach@chromium.org IC_Utility(IC::kLoadPropertyWithInterceptor), isolate()); 11414a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org __ TailCallExternalReference(ref, StubCache::kInterceptorArgsLength, 1); 1142c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 11435c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 11445c838251403b0be9a882540f1922577abba4c872ager@chromium.org 11455c838251403b0be9a882540f1922577abba4c872ager@chromium.org 11466e28b5694dd5a29d2f37d56d5a005e7cfdd952d1erik.corry@gmail.comHandle<Code> StoreStubCompiler::CompileStoreCallback( 11474c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org Handle<JSObject> object, 1148355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org Handle<JSObject> holder, 1149bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org Handle<Name> name, 1150c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org Handle<ExecutableAccessorInfo> callback) { 115143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org Register holder_reg = HandlerFrontend( 115243c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org IC::CurrentTypeOf(object, isolate()), receiver(), holder, name); 1153c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1154c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Stub never generated for non-global objects that require access 1155c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // checks. 1156355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); 1157c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 11586f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org __ Push(receiver(), holder_reg); // Receiver. 11594c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org __ li(at, Operand(callback)); // Callback info. 1160bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org __ push(at); 1161bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org __ li(at, Operand(name)); 1162bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org __ Push(at, value()); 1163c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1164c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Do tail-call to the runtime system. 1165c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ExternalReference store_callback_property = 116632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); 116743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ TailCallExternalReference(store_callback_property, 5, 1); 1168c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1169c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Return the generated code. 11709af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org return GetCode(kind(), Code::FAST, name); 11717516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 11727516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 11737516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 117446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org#undef __ 117546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org#define __ ACCESS_MASM(masm) 117646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 117746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 117846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.orgvoid StoreStubCompiler::GenerateStoreViaSetter( 117946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org MacroAssembler* masm, 118025530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org Handle<HeapType> type, 1181bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org Register receiver, 1182619781ad24991bca2894d2f677ac960da366b11esvenpanne@chromium.org Handle<JSFunction> setter) { 11837028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // ----------- S t a t e ------------- 11847028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // -- ra : return address 11857028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // ----------------------------------- 11867028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org { 118746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org FrameScope scope(masm, StackFrame::INTERNAL); 11887028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 11897028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // Save value register, so we can restore it later. 1190bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org __ push(value()); 11917028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 119246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org if (!setter.is_null()) { 119346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // Call the JavaScript setter with receiver and value on the stack. 119425530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) { 119525530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org // Swap in the global receiver. 119625530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org __ lw(receiver, 119725530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org FieldMemOperand( 119825530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org receiver, JSGlobalObject::kGlobalReceiverOffset)); 119925530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org } 1200bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org __ Push(receiver, value()); 120146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org ParameterCount actual(1); 120232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org ParameterCount expected(setter); 120332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org __ InvokeFunction(setter, expected, actual, 1204e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org CALL_FUNCTION, NullCallWrapper()); 120546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org } else { 120646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // If we generate a global code snippet for deoptimization only, remember 120746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org // the place to continue after deoptimization. 120846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset()); 120946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org } 12107028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 12117028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // We have to return the passed value, not the return value of the setter. 12127028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org __ pop(v0); 12137028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org 12147028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // Restore context register. 12157028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 12167028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org } 12177028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org __ Ret(); 121846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org} 121946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 122046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 122146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org#undef __ 122246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org#define __ ACCESS_MASM(masm()) 122346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 122446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org 12256e28b5694dd5a29d2f37d56d5a005e7cfdd952d1erik.corry@gmail.comHandle<Code> StoreStubCompiler::CompileStoreInterceptor( 12264c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org Handle<JSObject> object, 12279faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org Handle<Name> name) { 12284c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org __ Push(receiver(), this->name(), value()); 1229c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1230c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Do tail-call to the runtime system. 1231c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org ExternalReference store_ic_property = 123232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate()); 1233cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org __ TailCallExternalReference(store_ic_property, 3, 1); 1234c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1235c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Return the generated code. 12369af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org return GetCode(kind(), Code::FAST, name); 12377516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 12387516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 12397516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 12406d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.orgHandle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<HeapType> type, 1241f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Handle<JSObject> last, 1242f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Handle<Name> name) { 1243f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org NonexistentHandlerFrontend(type, last, name); 124494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org 1245c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Return undefined if maps of the full prototype chain is still the same. 1246c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ LoadRoot(v0, Heap::kUndefinedValueRootIndex); 1247c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Ret(); 1248c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1249c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Return the generated code. 12509af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org return GetCode(kind(), Code::FAST, name); 12517516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 12527516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 12537516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 125494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.orgRegister* LoadStubCompiler::registers() { 125594b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org // receiver, name, scratch1, scratch2, scratch3, scratch4. 125694b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org static Register registers[] = { a0, a2, a3, a1, t0, t1 }; 125794b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org return registers; 125894b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org} 1259c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1260c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 126194b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.orgRegister* KeyedLoadStubCompiler::registers() { 126294b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org // receiver, name, scratch1, scratch2, scratch3, scratch4. 126394b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org static Register registers[] = { a1, a0, a2, a3, t0, t1 }; 126494b0d6fcb08a2f01ba52c6edb712068f482366f1danno@chromium.org return registers; 12655c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 12665c838251403b0be9a882540f1922577abba4c872ager@chromium.org 12675c838251403b0be9a882540f1922577abba4c872ager@chromium.org 1268bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.orgRegister StoreStubCompiler::value() { 1269bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org return a0; 1270bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org} 1271bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org 1272bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org 12732bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.orgRegister* StoreStubCompiler::registers() { 1274bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org // receiver, name, scratch1, scratch2, scratch3. 1275bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org static Register registers[] = { a1, a2, a3, t0, t1 }; 12762bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org return registers; 12772bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org} 12782bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org 12792bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org 12802bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.orgRegister* KeyedStoreStubCompiler::registers() { 1281bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org // receiver, name, scratch1, scratch2, scratch3. 1282bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org static Register registers[] = { a2, a1, a3, t0, t1 }; 12832bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org return registers; 12842bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org} 12852bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org 12862bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org 1287de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org#undef __ 1288de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org#define __ ACCESS_MASM(masm) 1289de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org 1290de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org 1291de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.orgvoid LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm, 129225530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org Handle<HeapType> type, 12932efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Register receiver, 1294de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org Handle<JSFunction> getter) { 1295de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org // ----------- S t a t e ------------- 1296de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org // -- a0 : receiver 1297de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org // -- a2 : name 1298de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org // -- ra : return address 1299de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org // ----------------------------------- 1300de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org { 1301de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org FrameScope scope(masm, StackFrame::INTERNAL); 1302de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org 1303de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org if (!getter.is_null()) { 1304de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org // Call the JavaScript getter with the receiver on the stack. 130525530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) { 130625530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org // Swap in the global receiver. 130725530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org __ lw(receiver, 130825530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org FieldMemOperand( 130925530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org receiver, JSGlobalObject::kGlobalReceiverOffset)); 131025530ce9cb50f9e8386663ca40fd3f6e023ec9f6bmeurer@chromium.org } 13112efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org __ push(receiver); 1312de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org ParameterCount actual(0); 131332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org ParameterCount expected(getter); 131432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org __ InvokeFunction(getter, expected, actual, 1315e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org CALL_FUNCTION, NullCallWrapper()); 1316de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org } else { 1317de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org // If we generate a global code snippet for deoptimization only, remember 1318de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org // the place to continue after deoptimization. 1319de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset()); 1320de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org } 1321de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org 1322de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org // Restore context register. 1323de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 1324de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org } 1325de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org __ Ret(); 1326de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org} 1327de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org 1328de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org 1329de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org#undef __ 1330de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org#define __ ACCESS_MASM(masm()) 1331de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org 1332de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org 13336e28b5694dd5a29d2f37d56d5a005e7cfdd952d1erik.corry@gmail.comHandle<Code> LoadStubCompiler::CompileLoadGlobal( 13346d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org Handle<HeapType> type, 13354a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Handle<GlobalObject> global, 1336b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Handle<PropertyCell> cell, 13379faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org Handle<Name> name, 13386e28b5694dd5a29d2f37d56d5a005e7cfdd952d1erik.corry@gmail.com bool is_dont_delete) { 1339b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org Label miss; 1340c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1341f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org HandlerFrontendHeader(type, receiver(), global, name, &miss); 1342c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1343c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Get the value from the cell. 13446e28b5694dd5a29d2f37d56d5a005e7cfdd952d1erik.corry@gmail.com __ li(a3, Operand(cell)); 1345f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org __ lw(t0, FieldMemOperand(a3, Cell::kValueOffset)); 1346c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1347c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Check for deleted property if property can actually be deleted. 1348c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org if (!is_dont_delete) { 1349c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 1350c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ Branch(&miss, eq, t0, Operand(at)); 1351c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 1352c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 135332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org Counters* counters = isolate()->counters(); 1354c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ IncrementCounter(counters->named_load_global_stub(), 1, a1, a3); 13558a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org __ Ret(USE_DELAY_SLOT); 13564a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org __ mov(v0, t0); 1357c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1358a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org HandlerFrontendFooter(name, &miss); 1359a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org 1360c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Return the generated code. 1361e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org return GetCode(kind(), Code::NORMAL, name); 13625c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 13637516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 13647516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 1365bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.orgHandle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC( 1366af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org TypeHandleList* types, 13679faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org CodeHandleList* handlers, 13689faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org Handle<Name> name, 13699faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org Code::StubType type, 13709faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org IcCheckType check) { 137140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org Label miss; 13729faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org 137343c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org if (check == PROPERTY && 137443c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org (kind() == Code::KEYED_LOAD_IC || kind() == Code::KEYED_STORE_IC)) { 137543c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org __ Branch(&miss, ne, this->name(), Operand(name)); 13769faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org } 13779faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org 1378b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org Label number_case; 13793a9c5d9b20b1897a1acd41dbad9e724c504a4db9machenbach@chromium.org Register match = scratch1(); 1380af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org Label* smi_target = IncludesNumberType(types) ? &number_case : &miss; 13813a9c5d9b20b1897a1acd41dbad9e724c504a4db9machenbach@chromium.org __ JumpIfSmi(receiver(), smi_target, match); // Reg match is 0 if Smi. 1382b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org 13833a9c5d9b20b1897a1acd41dbad9e724c504a4db9machenbach@chromium.org Register map_reg = scratch2(); 1384c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1385af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org int receiver_count = types->length(); 1386f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org int number_of_handled_maps = 0; 13879faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org __ lw(map_reg, FieldMemOperand(receiver(), HeapObject::kMapOffset)); 138840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org for (int current = 0; current < receiver_count; ++current) { 13896d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org Handle<HeapType> type = types->at(current); 1390af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org Handle<Map> map = IC::TypeToMap(*type, isolate()); 1391f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org if (!map->is_deprecated()) { 1392f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org number_of_handled_maps++; 13933a9c5d9b20b1897a1acd41dbad9e724c504a4db9machenbach@chromium.org // Check map and tail call if there's a match. 13943a9c5d9b20b1897a1acd41dbad9e724c504a4db9machenbach@chromium.org // Separate compare from branch, to provide path for above JumpIfSmi(). 13953a9c5d9b20b1897a1acd41dbad9e724c504a4db9machenbach@chromium.org __ Subu(match, map_reg, Operand(map)); 13966d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org if (type->Is(HeapType::Number())) { 1397b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org ASSERT(!number_case.is_unused()); 1398b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org __ bind(&number_case); 1399b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org } 1400f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org __ Jump(handlers->at(current), RelocInfo::CODE_TARGET, 14013a9c5d9b20b1897a1acd41dbad9e724c504a4db9machenbach@chromium.org eq, match, Operand(zero_reg)); 1402f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } 140340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org } 1404f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org ASSERT(number_of_handled_maps != 0); 1405c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1406c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&miss); 14072bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org TailCallBuiltin(masm(), MissBuiltin(kind())); 1408c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1409c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Return the generated code. 14109faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org InlineCacheState state = 1411f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org number_of_handled_maps > 1 ? POLYMORPHIC : MONOMORPHIC; 14129faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org return GetICCode(kind(), type, name, state); 14137516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} 14147516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 14157516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org 14162904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.orgvoid StoreStubCompiler::GenerateStoreArrayLength() { 14172904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org // Prepare tail call to StoreIC_ArrayLength. 14182904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org __ Push(receiver(), value()); 14192904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org 14202904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org ExternalReference ref = 14212904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org ExternalReference(IC_Utility(IC::kStoreIC_ArrayLength), 14222904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org masm()->isolate()); 14232904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org __ TailCallExternalReference(ref, 2, 1); 14242904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org} 14252904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org 14262904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org 14276e28b5694dd5a29d2f37d56d5a005e7cfdd952d1erik.corry@gmail.comHandle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic( 14286e28b5694dd5a29d2f37d56d5a005e7cfdd952d1erik.corry@gmail.com MapHandleList* receiver_maps, 14296e28b5694dd5a29d2f37d56d5a005e7cfdd952d1erik.corry@gmail.com CodeHandleList* handler_stubs, 14306e28b5694dd5a29d2f37d56d5a005e7cfdd952d1erik.corry@gmail.com MapHandleList* transitioned_maps) { 143140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org Label miss; 14324c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org __ JumpIfSmi(receiver(), &miss); 143340cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 143440cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org int receiver_count = receiver_maps->length(); 14354c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org __ lw(scratch1(), FieldMemOperand(receiver(), HeapObject::kMapOffset)); 1436b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org for (int i = 0; i < receiver_count; ++i) { 14376e28b5694dd5a29d2f37d56d5a005e7cfdd952d1erik.corry@gmail.com if (transitioned_maps->at(i).is_null()) { 14386e28b5694dd5a29d2f37d56d5a005e7cfdd952d1erik.corry@gmail.com __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET, eq, 14394c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org scratch1(), Operand(receiver_maps->at(i))); 1440b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org } else { 1441b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org Label next_map; 14424c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org __ Branch(&next_map, ne, scratch1(), Operand(receiver_maps->at(i))); 14434c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org __ li(transition_map(), Operand(transitioned_maps->at(i))); 14446e28b5694dd5a29d2f37d56d5a005e7cfdd952d1erik.corry@gmail.com __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET); 1445b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org __ bind(&next_map); 1446b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org } 1447c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org } 1448c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1449c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org __ bind(&miss); 14502bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org TailCallBuiltin(masm(), MissBuiltin(kind())); 1451c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org 1452c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org // Return the generated code. 14532bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org return GetICCode( 14542bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC); 14555c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 14565c838251403b0be9a882540f1922577abba4c872ager@chromium.org 14575c838251403b0be9a882540f1922577abba4c872ager@chromium.org 145840cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org#undef __ 145940cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org#define __ ACCESS_MASM(masm) 146040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 146140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org 14626db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.orgvoid KeyedLoadStubCompiler::GenerateLoadDictionaryElement( 14636db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org MacroAssembler* masm) { 14646db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // ---------- S t a t e -------------- 14656db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // -- ra : return address 14666db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // -- a0 : key 14676db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // -- a1 : receiver 14686db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // ----------------------------------- 1469af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org Label slow, miss; 14706db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 14716db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register key = a0; 14726db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org Register receiver = a1; 14736db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 1474af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org __ JumpIfNotSmi(key, &miss); 14756db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org __ lw(t0, FieldMemOperand(receiver, JSObject::kElementsOffset)); 14766db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org __ sra(a2, a0, kSmiTagSize); 14776db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org __ LoadFromNumberDictionary(&slow, t0, a0, v0, a2, a3, t1); 14786db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org __ Ret(); 14796db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 14806db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Slow case, key and receiver still in a0 and a1. 14816db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org __ bind(&slow); 14826db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org __ IncrementCounter( 14836db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org masm->isolate()->counters()->keyed_load_external_array_slow(), 14846db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 1, a2, a3); 14856db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Entry registers are intact. 14866db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // ---------- S t a t e -------------- 14876db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // -- ra : return address 14886db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // -- a0 : key 14896db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // -- a1 : receiver 14906db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // ----------------------------------- 14912bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow); 14926db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 14936db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // Miss case, call the runtime. 1494af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org __ bind(&miss); 14956db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 14966db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // ---------- S t a t e -------------- 14976db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // -- ra : return address 14986db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // -- a0 : key 14996db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // -- a1 : receiver 15006db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org // ----------------------------------- 1501af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 15026db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org} 15036db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 15046db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org 15055c838251403b0be9a882540f1922577abba4c872ager@chromium.org#undef __ 15065c838251403b0be9a882540f1922577abba4c872ager@chromium.org 15075c838251403b0be9a882540f1922577abba4c872ager@chromium.org} } // namespace v8::internal 15085c838251403b0be9a882540f1922577abba4c872ager@chromium.org 15099dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com#endif // V8_TARGET_ARCH_MIPS 1510