| OLD | NEW | 
|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #if V8_TARGET_ARCH_MIPS | 5 #if V8_TARGET_ARCH_MIPS | 
| 6 | 6 | 
| 7 #include "src/codegen.h" | 7 #include "src/codegen.h" | 
| 8 #include "src/ic/ic.h" | 8 #include "src/ic/ic.h" | 
| 9 #include "src/ic/stub-cache.h" | 9 #include "src/ic/stub-cache.h" | 
| 10 #include "src/interface-descriptors.h" | 10 #include "src/interface-descriptors.h" | 
| 11 | 11 | 
| 12 namespace v8 { | 12 namespace v8 { | 
| 13 namespace internal { | 13 namespace internal { | 
| 14 | 14 | 
| 15 #define __ ACCESS_MASM(masm) | 15 #define __ ACCESS_MASM(masm) | 
| 16 | 16 | 
| 17 static void ProbeTable(StubCache* stub_cache, MacroAssembler* masm, | 17 static void ProbeTable(StubCache* stub_cache, MacroAssembler* masm, | 
| 18                        Code::Flags flags, StubCache::Table table, | 18                        Code::Flags flags, StubCache::Table table, | 
| 19                        Register receiver, Register name, | 19                        Register receiver, Register name, | 
| 20                        // Number of the cache entry, not scaled. | 20                        // The offset is scaled by 4, based on | 
|  | 21                        // kCacheIndexShift, which is two bits | 
| 21                        Register offset, Register scratch, Register scratch2, | 22                        Register offset, Register scratch, Register scratch2, | 
| 22                        Register offset_scratch) { | 23                        Register offset_scratch) { | 
| 23   ExternalReference key_offset(stub_cache->key_reference(table)); | 24   ExternalReference key_offset(stub_cache->key_reference(table)); | 
| 24   ExternalReference value_offset(stub_cache->value_reference(table)); | 25   ExternalReference value_offset(stub_cache->value_reference(table)); | 
| 25   ExternalReference map_offset(stub_cache->map_reference(table)); | 26   ExternalReference map_offset(stub_cache->map_reference(table)); | 
| 26 | 27 | 
| 27   uint32_t key_off_addr = reinterpret_cast<uint32_t>(key_offset.address()); | 28   uint32_t key_off_addr = reinterpret_cast<uint32_t>(key_offset.address()); | 
| 28   uint32_t value_off_addr = reinterpret_cast<uint32_t>(value_offset.address()); | 29   uint32_t value_off_addr = reinterpret_cast<uint32_t>(value_offset.address()); | 
| 29   uint32_t map_off_addr = reinterpret_cast<uint32_t>(map_offset.address()); | 30   uint32_t map_off_addr = reinterpret_cast<uint32_t>(map_offset.address()); | 
| 30 | 31 | 
| 31   // Check the relative positions of the address fields. | 32   // Check the relative positions of the address fields. | 
| 32   DCHECK(value_off_addr > key_off_addr); | 33   DCHECK(value_off_addr > key_off_addr); | 
| 33   DCHECK((value_off_addr - key_off_addr) % 4 == 0); | 34   DCHECK((value_off_addr - key_off_addr) % 4 == 0); | 
| 34   DCHECK((value_off_addr - key_off_addr) < (256 * 4)); | 35   DCHECK((value_off_addr - key_off_addr) < (256 * 4)); | 
| 35   DCHECK(map_off_addr > key_off_addr); | 36   DCHECK(map_off_addr > key_off_addr); | 
| 36   DCHECK((map_off_addr - key_off_addr) % 4 == 0); | 37   DCHECK((map_off_addr - key_off_addr) % 4 == 0); | 
| 37   DCHECK((map_off_addr - key_off_addr) < (256 * 4)); | 38   DCHECK((map_off_addr - key_off_addr) < (256 * 4)); | 
| 38 | 39 | 
| 39   Label miss; | 40   Label miss; | 
| 40   Register base_addr = scratch; | 41   Register base_addr = scratch; | 
| 41   scratch = no_reg; | 42   scratch = no_reg; | 
| 42 | 43 | 
| 43   // Multiply by 3 because there are 3 fields per entry (name, code, map). | 44   // Multiply by 3 because there are 3 fields per entry (name, code, map). | 
| 44   __ Lsa(offset_scratch, offset, offset, 1); | 45   __ Lsa(offset_scratch, offset, offset, 1); | 
| 45 | 46 | 
| 46   // Calculate the base address of the entry. | 47   // Calculate the base address of the entry. | 
| 47   __ li(base_addr, Operand(key_offset)); | 48   __ li(base_addr, Operand(key_offset)); | 
| 48   __ Lsa(base_addr, base_addr, offset_scratch, kPointerSizeLog2); | 49   __ Addu(base_addr, base_addr, offset_scratch); | 
| 49 | 50 | 
| 50   // Check that the key in the entry matches the name. | 51   // Check that the key in the entry matches the name. | 
| 51   __ lw(at, MemOperand(base_addr, 0)); | 52   __ lw(at, MemOperand(base_addr, 0)); | 
| 52   __ Branch(&miss, ne, name, Operand(at)); | 53   __ Branch(&miss, ne, name, Operand(at)); | 
| 53 | 54 | 
| 54   // Check the map matches. | 55   // Check the map matches. | 
| 55   __ lw(at, MemOperand(base_addr, map_off_addr - key_off_addr)); | 56   __ lw(at, MemOperand(base_addr, map_off_addr - key_off_addr)); | 
| 56   __ lw(scratch2, FieldMemOperand(receiver, HeapObject::kMapOffset)); | 57   __ lw(scratch2, FieldMemOperand(receiver, HeapObject::kMapOffset)); | 
| 57   __ Branch(&miss, ne, at, Operand(scratch2)); | 58   __ Branch(&miss, ne, at, Operand(scratch2)); | 
| 58 | 59 | 
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 127   __ IncrementCounter(counters->megamorphic_stub_cache_probes(), 1, extra2, | 128   __ IncrementCounter(counters->megamorphic_stub_cache_probes(), 1, extra2, | 
| 128                       extra3); | 129                       extra3); | 
| 129 | 130 | 
| 130   // Check that the receiver isn't a smi. | 131   // Check that the receiver isn't a smi. | 
| 131   __ JumpIfSmi(receiver, &miss); | 132   __ JumpIfSmi(receiver, &miss); | 
| 132 | 133 | 
| 133   // Get the map of the receiver and compute the hash. | 134   // Get the map of the receiver and compute the hash. | 
| 134   __ lw(scratch, FieldMemOperand(name, Name::kHashFieldOffset)); | 135   __ lw(scratch, FieldMemOperand(name, Name::kHashFieldOffset)); | 
| 135   __ lw(at, FieldMemOperand(receiver, HeapObject::kMapOffset)); | 136   __ lw(at, FieldMemOperand(receiver, HeapObject::kMapOffset)); | 
| 136   __ Addu(scratch, scratch, at); | 137   __ Addu(scratch, scratch, at); | 
| 137   uint32_t mask = kPrimaryTableSize - 1; | 138   __ Xor(scratch, scratch, Operand(flags)); | 
| 138   // We shift out the last two bits because they are not part of the hash and | 139   __ And(scratch, scratch, | 
| 139   // they are always 01 for maps. | 140          Operand((kPrimaryTableSize - 1) << kCacheIndexShift)); | 
| 140   __ srl(scratch, scratch, kCacheIndexShift); |  | 
| 141   __ Xor(scratch, scratch, Operand((flags >> kCacheIndexShift) & mask)); |  | 
| 142   __ And(scratch, scratch, Operand(mask)); |  | 
| 143 | 141 | 
| 144   // Probe the primary table. | 142   // Probe the primary table. | 
| 145   ProbeTable(this, masm, flags, kPrimary, receiver, name, scratch, extra, | 143   ProbeTable(this, masm, flags, kPrimary, receiver, name, scratch, extra, | 
| 146              extra2, extra3); | 144              extra2, extra3); | 
| 147 | 145 | 
| 148   // Primary miss: Compute hash for secondary probe. | 146   // Primary miss: Compute hash for secondary probe. | 
| 149   __ srl(at, name, kCacheIndexShift); | 147   __ Subu(scratch, scratch, name); | 
| 150   __ Subu(scratch, scratch, at); | 148   __ Addu(scratch, scratch, Operand(flags)); | 
| 151   uint32_t mask2 = kSecondaryTableSize - 1; | 149   __ And(scratch, scratch, | 
| 152   __ Addu(scratch, scratch, Operand((flags >> kCacheIndexShift) & mask2)); | 150          Operand((kSecondaryTableSize - 1) << kCacheIndexShift)); | 
| 153   __ And(scratch, scratch, Operand(mask2)); |  | 
| 154 | 151 | 
| 155   // Probe the secondary table. | 152   // Probe the secondary table. | 
| 156   ProbeTable(this, masm, flags, kSecondary, receiver, name, scratch, extra, | 153   ProbeTable(this, masm, flags, kSecondary, receiver, name, scratch, extra, | 
| 157              extra2, extra3); | 154              extra2, extra3); | 
| 158 | 155 | 
| 159   // Cache miss: Fall-through and let caller handle the miss by | 156   // Cache miss: Fall-through and let caller handle the miss by | 
| 160   // entering the runtime system. | 157   // entering the runtime system. | 
| 161   __ bind(&miss); | 158   __ bind(&miss); | 
| 162   __ IncrementCounter(counters->megamorphic_stub_cache_misses(), 1, extra2, | 159   __ IncrementCounter(counters->megamorphic_stub_cache_misses(), 1, extra2, | 
| 163                       extra3); | 160                       extra3); | 
| 164 } | 161 } | 
| 165 | 162 | 
| 166 | 163 | 
| 167 #undef __ | 164 #undef __ | 
| 168 }  // namespace internal | 165 }  // namespace internal | 
| 169 }  // namespace v8 | 166 }  // namespace v8 | 
| 170 | 167 | 
| 171 #endif  // V8_TARGET_ARCH_MIPS | 168 #endif  // V8_TARGET_ARCH_MIPS | 
| OLD | NEW | 
|---|