| 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 #include "src/v8.h" |    5 #include "src/v8.h" | 
|    6  |    6  | 
|    7 #if V8_TARGET_ARCH_X87 |    7 #if V8_TARGET_ARCH_X87 | 
|    8  |    8  | 
|    9 #include "src/codegen.h" |    9 #include "src/codegen.h" | 
 |   10 #include "src/ic/ic.h" | 
|   10 #include "src/ic/stub-cache.h" |   11 #include "src/ic/stub-cache.h" | 
 |   12 #include "src/interface-descriptors.h" | 
|   11  |   13  | 
|   12 namespace v8 { |   14 namespace v8 { | 
|   13 namespace internal { |   15 namespace internal { | 
|   14  |   16  | 
|   15 #define __ ACCESS_MASM(masm) |   17 #define __ ACCESS_MASM(masm) | 
|   16  |   18  | 
|   17  |   19  | 
|   18 static void ProbeTable(Isolate* isolate, MacroAssembler* masm, |   20 static void ProbeTable(Isolate* isolate, MacroAssembler* masm, | 
|   19                        Code::Flags flags, bool leave_frame, |   21                        Code::Kind ic_kind, Code::Flags flags, bool leave_frame, | 
|   20                        StubCache::Table table, Register name, Register receiver, |   22                        StubCache::Table table, Register name, Register receiver, | 
|   21                        // Number of the cache entry pointer-size scaled. |   23                        // Number of the cache entry pointer-size scaled. | 
|   22                        Register offset, Register extra) { |   24                        Register offset, Register extra) { | 
|   23   ExternalReference key_offset(isolate->stub_cache()->key_reference(table)); |   25   ExternalReference key_offset(isolate->stub_cache()->key_reference(table)); | 
|   24   ExternalReference value_offset(isolate->stub_cache()->value_reference(table)); |   26   ExternalReference value_offset(isolate->stub_cache()->value_reference(table)); | 
|   25   ExternalReference map_offset(isolate->stub_cache()->map_reference(table)); |   27   ExternalReference map_offset(isolate->stub_cache()->map_reference(table)); | 
|   26  |   28  | 
|   27   Label miss; |   29   Label miss; | 
|   28  |   30  | 
|   29   // Multiply by 3 because there are 3 fields per entry (name, code, map). |   31   // Multiply by 3 because there are 3 fields per entry (name, code, map). | 
| (...skipping 19 matching lines...) Expand all  Loading... | 
|   49     __ j(not_equal, &miss); |   51     __ j(not_equal, &miss); | 
|   50  |   52  | 
|   51 #ifdef DEBUG |   53 #ifdef DEBUG | 
|   52     if (FLAG_test_secondary_stub_cache && table == StubCache::kPrimary) { |   54     if (FLAG_test_secondary_stub_cache && table == StubCache::kPrimary) { | 
|   53       __ jmp(&miss); |   55       __ jmp(&miss); | 
|   54     } else if (FLAG_test_primary_stub_cache && table == StubCache::kSecondary) { |   56     } else if (FLAG_test_primary_stub_cache && table == StubCache::kSecondary) { | 
|   55       __ jmp(&miss); |   57       __ jmp(&miss); | 
|   56     } |   58     } | 
|   57 #endif |   59 #endif | 
|   58  |   60  | 
 |   61     if (IC::ICUseVector(ic_kind)) { | 
 |   62       // The vector and slot were pushed onto the stack before starting the | 
 |   63       // probe, and need to be dropped before calling the handler. | 
 |   64       __ pop(VectorLoadICDescriptor::VectorRegister()); | 
 |   65       __ pop(VectorLoadICDescriptor::SlotRegister()); | 
 |   66     } | 
 |   67  | 
|   59     if (leave_frame) __ leave(); |   68     if (leave_frame) __ leave(); | 
|   60  |   69  | 
|   61     // Jump to the first instruction in the code stub. |   70     // Jump to the first instruction in the code stub. | 
|   62     __ add(extra, Immediate(Code::kHeaderSize - kHeapObjectTag)); |   71     __ add(extra, Immediate(Code::kHeaderSize - kHeapObjectTag)); | 
|   63     __ jmp(extra); |   72     __ jmp(extra); | 
|   64  |   73  | 
|   65     __ bind(&miss); |   74     __ bind(&miss); | 
|   66   } else { |   75   } else { | 
|   67     // Save the offset on the stack. |   76     // Save the offset on the stack. | 
|   68     __ push(offset); |   77     __ push(offset); | 
| (...skipping 24 matching lines...) Expand all  Loading... | 
|   93       __ jmp(&miss); |  102       __ jmp(&miss); | 
|   94     } else if (FLAG_test_primary_stub_cache && table == StubCache::kSecondary) { |  103     } else if (FLAG_test_primary_stub_cache && table == StubCache::kSecondary) { | 
|   95       __ jmp(&miss); |  104       __ jmp(&miss); | 
|   96     } |  105     } | 
|   97 #endif |  106 #endif | 
|   98  |  107  | 
|   99     // Restore offset and re-load code entry from cache. |  108     // Restore offset and re-load code entry from cache. | 
|  100     __ pop(offset); |  109     __ pop(offset); | 
|  101     __ mov(offset, Operand::StaticArray(offset, times_1, value_offset)); |  110     __ mov(offset, Operand::StaticArray(offset, times_1, value_offset)); | 
|  102  |  111  | 
 |  112     if (IC::ICUseVector(ic_kind)) { | 
 |  113       // The vector and slot were pushed onto the stack before starting the | 
 |  114       // probe, and need to be dropped before calling the handler. | 
 |  115       Register vector = VectorLoadICDescriptor::VectorRegister(); | 
 |  116       Register slot = VectorLoadICDescriptor::SlotRegister(); | 
 |  117       DCHECK(!offset.is(vector) && !offset.is(slot)); | 
 |  118  | 
 |  119       __ pop(vector); | 
 |  120       __ pop(slot); | 
 |  121     } | 
 |  122  | 
 |  123  | 
|  103     if (leave_frame) __ leave(); |  124     if (leave_frame) __ leave(); | 
|  104  |  125  | 
|  105     // Jump to the first instruction in the code stub. |  126     // Jump to the first instruction in the code stub. | 
|  106     __ add(offset, Immediate(Code::kHeaderSize - kHeapObjectTag)); |  127     __ add(offset, Immediate(Code::kHeaderSize - kHeapObjectTag)); | 
|  107     __ jmp(offset); |  128     __ jmp(offset); | 
|  108  |  129  | 
|  109     // Pop at miss. |  130     // Pop at miss. | 
|  110     __ bind(&miss); |  131     __ bind(&miss); | 
|  111     __ pop(offset); |  132     __ pop(offset); | 
|  112   } |  133   } | 
|  113 } |  134 } | 
|  114  |  135  | 
|  115  |  136  | 
|  116 void StubCache::GenerateProbe(MacroAssembler* masm, Code::Flags flags, |  137 void StubCache::GenerateProbe(MacroAssembler* masm, Code::Kind ic_kind, | 
|  117                               bool leave_frame, Register receiver, |  138                               Code::Flags flags, bool leave_frame, | 
|  118                               Register name, Register scratch, Register extra, |  139                               Register receiver, Register name, | 
|  119                               Register extra2, Register extra3) { |  140                               Register scratch, Register extra, Register extra2, | 
 |  141                               Register extra3) { | 
|  120   Label miss; |  142   Label miss; | 
|  121  |  143  | 
|  122   // Assert that code is valid.  The multiplying code relies on the entry size |  144   // Assert that code is valid.  The multiplying code relies on the entry size | 
|  123   // being 12. |  145   // being 12. | 
|  124   DCHECK(sizeof(Entry) == 12); |  146   DCHECK(sizeof(Entry) == 12); | 
|  125  |  147  | 
|  126   // Assert the flags do not name a specific type. |  148   // Assert the flags do not name a specific type. | 
|  127   DCHECK(Code::ExtractTypeFromFlags(flags) == 0); |  149   DCHECK(Code::ExtractTypeFromFlags(flags) == 0); | 
|  128  |  150  | 
|  129   // Assert that there are no register conflicts. |  151   // Assert that there are no register conflicts. | 
| (...skipping 22 matching lines...) Expand all  Loading... | 
|  152   __ add(offset, FieldOperand(receiver, HeapObject::kMapOffset)); |  174   __ add(offset, FieldOperand(receiver, HeapObject::kMapOffset)); | 
|  153   __ xor_(offset, flags); |  175   __ xor_(offset, flags); | 
|  154   // We mask out the last two bits because they are not part of the hash and |  176   // We mask out the last two bits because they are not part of the hash and | 
|  155   // they are always 01 for maps.  Also in the two 'and' instructions below. |  177   // they are always 01 for maps.  Also in the two 'and' instructions below. | 
|  156   __ and_(offset, (kPrimaryTableSize - 1) << kCacheIndexShift); |  178   __ and_(offset, (kPrimaryTableSize - 1) << kCacheIndexShift); | 
|  157   // ProbeTable expects the offset to be pointer scaled, which it is, because |  179   // ProbeTable expects the offset to be pointer scaled, which it is, because | 
|  158   // the heap object tag size is 2 and the pointer size log 2 is also 2. |  180   // the heap object tag size is 2 and the pointer size log 2 is also 2. | 
|  159   DCHECK(kCacheIndexShift == kPointerSizeLog2); |  181   DCHECK(kCacheIndexShift == kPointerSizeLog2); | 
|  160  |  182  | 
|  161   // Probe the primary table. |  183   // Probe the primary table. | 
|  162   ProbeTable(isolate(), masm, flags, leave_frame, kPrimary, name, receiver, |  184   ProbeTable(isolate(), masm, ic_kind, flags, leave_frame, kPrimary, name, | 
|  163              offset, extra); |  185              receiver, offset, extra); | 
|  164  |  186  | 
|  165   // Primary miss: Compute hash for secondary probe. |  187   // Primary miss: Compute hash for secondary probe. | 
|  166   __ mov(offset, FieldOperand(name, Name::kHashFieldOffset)); |  188   __ mov(offset, FieldOperand(name, Name::kHashFieldOffset)); | 
|  167   __ add(offset, FieldOperand(receiver, HeapObject::kMapOffset)); |  189   __ add(offset, FieldOperand(receiver, HeapObject::kMapOffset)); | 
|  168   __ xor_(offset, flags); |  190   __ xor_(offset, flags); | 
|  169   __ and_(offset, (kPrimaryTableSize - 1) << kCacheIndexShift); |  191   __ and_(offset, (kPrimaryTableSize - 1) << kCacheIndexShift); | 
|  170   __ sub(offset, name); |  192   __ sub(offset, name); | 
|  171   __ add(offset, Immediate(flags)); |  193   __ add(offset, Immediate(flags)); | 
|  172   __ and_(offset, (kSecondaryTableSize - 1) << kCacheIndexShift); |  194   __ and_(offset, (kSecondaryTableSize - 1) << kCacheIndexShift); | 
|  173  |  195  | 
|  174   // Probe the secondary table. |  196   // Probe the secondary table. | 
|  175   ProbeTable(isolate(), masm, flags, leave_frame, kSecondary, name, receiver, |  197   ProbeTable(isolate(), masm, ic_kind, flags, leave_frame, kSecondary, name, | 
|  176              offset, extra); |  198              receiver, offset, extra); | 
|  177  |  199  | 
|  178   // Cache miss: Fall-through and let caller handle the miss by |  200   // Cache miss: Fall-through and let caller handle the miss by | 
|  179   // entering the runtime system. |  201   // entering the runtime system. | 
|  180   __ bind(&miss); |  202   __ bind(&miss); | 
|  181   __ IncrementCounter(counters->megamorphic_stub_cache_misses(), 1); |  203   __ IncrementCounter(counters->megamorphic_stub_cache_misses(), 1); | 
|  182 } |  204 } | 
|  183  |  205  | 
|  184  |  206  | 
|  185 #undef __ |  207 #undef __ | 
|  186 } |  208 } | 
|  187 }  // namespace v8::internal |  209 }  // namespace v8::internal | 
|  188  |  210  | 
|  189 #endif  // V8_TARGET_ARCH_X87 |  211 #endif  // V8_TARGET_ARCH_X87 | 
| OLD | NEW |