| OLD | NEW |
| 1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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/code-stub-assembler.h" | 5 #include "src/code-stub-assembler.h" |
| 6 #include "src/code-factory.h" | 6 #include "src/code-factory.h" |
| 7 #include "src/frames-inl.h" | 7 #include "src/frames-inl.h" |
| 8 #include "src/frames.h" | 8 #include "src/frames.h" |
| 9 #include "src/ic/stub-cache.h" | 9 #include "src/ic/stub-cache.h" |
| 10 | 10 |
| (...skipping 1426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1437 Bind(&if_done); | 1437 Bind(&if_done); |
| 1438 return var_result.value(); | 1438 return var_result.value(); |
| 1439 } | 1439 } |
| 1440 | 1440 |
| 1441 Node* CodeStubAssembler::BitFieldDecode(Node* word32, uint32_t shift, | 1441 Node* CodeStubAssembler::BitFieldDecode(Node* word32, uint32_t shift, |
| 1442 uint32_t mask) { | 1442 uint32_t mask) { |
| 1443 return Word32Shr(Word32And(word32, Int32Constant(mask)), | 1443 return Word32Shr(Word32And(word32, Int32Constant(mask)), |
| 1444 Int32Constant(shift)); | 1444 Int32Constant(shift)); |
| 1445 } | 1445 } |
| 1446 | 1446 |
| 1447 void CodeStubAssembler::SetCounter(StatsCounter* counter, int value) { |
| 1448 if (FLAG_native_code_counters && counter->Enabled()) { |
| 1449 Node* counter_address = ExternalConstant(ExternalReference(counter)); |
| 1450 StoreNoWriteBarrier(MachineRepresentation::kWord32, counter_address, |
| 1451 Int32Constant(value)); |
| 1452 } |
| 1453 } |
| 1454 |
| 1455 void CodeStubAssembler::IncrementCounter(StatsCounter* counter, int delta) { |
| 1456 DCHECK(delta > 0); |
| 1457 if (FLAG_native_code_counters && counter->Enabled()) { |
| 1458 Node* counter_address = ExternalConstant(ExternalReference(counter)); |
| 1459 Node* value = Load(MachineType::Int32(), counter_address); |
| 1460 value = Int32Add(value, Int32Constant(delta)); |
| 1461 StoreNoWriteBarrier(MachineRepresentation::kWord32, counter_address, value); |
| 1462 } |
| 1463 } |
| 1464 |
| 1465 void CodeStubAssembler::DecrementCounter(StatsCounter* counter, int delta) { |
| 1466 DCHECK(delta > 0); |
| 1467 if (FLAG_native_code_counters && counter->Enabled()) { |
| 1468 Node* counter_address = ExternalConstant(ExternalReference(counter)); |
| 1469 Node* value = Load(MachineType::Int32(), counter_address); |
| 1470 value = Int32Sub(value, Int32Constant(delta)); |
| 1471 StoreNoWriteBarrier(MachineRepresentation::kWord32, counter_address, value); |
| 1472 } |
| 1473 } |
| 1474 |
| 1447 void CodeStubAssembler::TryToName(Node* key, Label* if_keyisindex, | 1475 void CodeStubAssembler::TryToName(Node* key, Label* if_keyisindex, |
| 1448 Variable* var_index, Label* if_keyisunique, | 1476 Variable* var_index, Label* if_keyisunique, |
| 1449 Label* if_bailout) { | 1477 Label* if_bailout) { |
| 1450 DCHECK_EQ(MachineRepresentation::kWord32, var_index->rep()); | 1478 DCHECK_EQ(MachineRepresentation::kWord32, var_index->rep()); |
| 1451 | 1479 |
| 1452 Label if_keyissmi(this), if_keyisnotsmi(this); | 1480 Label if_keyissmi(this), if_keyisnotsmi(this); |
| 1453 Branch(WordIsSmi(key), &if_keyissmi, &if_keyisnotsmi); | 1481 Branch(WordIsSmi(key), &if_keyissmi, &if_keyisnotsmi); |
| 1454 Bind(&if_keyissmi); | 1482 Bind(&if_keyissmi); |
| 1455 { | 1483 { |
| 1456 // Negative smi keys are named properties. Handle in the runtime. | 1484 // Negative smi keys are named properties. Handle in the runtime. |
| (...skipping 693 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2150 | 2178 |
| 2151 void CodeStubAssembler::TryProbeStubCacheTable( | 2179 void CodeStubAssembler::TryProbeStubCacheTable( |
| 2152 StubCache* stub_cache, StubCacheTable table_id, | 2180 StubCache* stub_cache, StubCacheTable table_id, |
| 2153 compiler::Node* entry_offset, compiler::Node* name, Code::Flags flags, | 2181 compiler::Node* entry_offset, compiler::Node* name, Code::Flags flags, |
| 2154 compiler::Node* map, Label* if_handler, Variable* var_handler, | 2182 compiler::Node* map, Label* if_handler, Variable* var_handler, |
| 2155 Label* if_miss) { | 2183 Label* if_miss) { |
| 2156 StubCache::Table table = static_cast<StubCache::Table>(table_id); | 2184 StubCache::Table table = static_cast<StubCache::Table>(table_id); |
| 2157 #ifdef DEBUG | 2185 #ifdef DEBUG |
| 2158 if (FLAG_test_secondary_stub_cache && table == StubCache::kPrimary) { | 2186 if (FLAG_test_secondary_stub_cache && table == StubCache::kPrimary) { |
| 2159 Goto(if_miss); | 2187 Goto(if_miss); |
| 2188 return; |
| 2160 } else if (FLAG_test_primary_stub_cache && table == StubCache::kSecondary) { | 2189 } else if (FLAG_test_primary_stub_cache && table == StubCache::kSecondary) { |
| 2161 Goto(if_miss); | 2190 Goto(if_miss); |
| 2191 return; |
| 2162 } | 2192 } |
| 2163 #endif | 2193 #endif |
| 2164 // The {table_offset} holds the entry offset times four (due to masking | 2194 // The {table_offset} holds the entry offset times four (due to masking |
| 2165 // and shifting optimizations). | 2195 // and shifting optimizations). |
| 2166 const int kMultiplier = sizeof(StubCache::Entry) >> Name::kHashShift; | 2196 const int kMultiplier = sizeof(StubCache::Entry) >> Name::kHashShift; |
| 2167 entry_offset = Int32Mul(entry_offset, Int32Constant(kMultiplier)); | 2197 entry_offset = Int32Mul(entry_offset, Int32Constant(kMultiplier)); |
| 2168 | 2198 |
| 2169 // Check that the key in the entry matches the name. | 2199 // Check that the key in the entry matches the name. |
| 2170 Node* key_base = | 2200 Node* key_base = |
| 2171 ExternalConstant(ExternalReference(stub_cache->key_reference(table))); | 2201 ExternalConstant(ExternalReference(stub_cache->key_reference(table))); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2195 | 2225 |
| 2196 // We found the handler. | 2226 // We found the handler. |
| 2197 var_handler->Bind(code); | 2227 var_handler->Bind(code); |
| 2198 Goto(if_handler); | 2228 Goto(if_handler); |
| 2199 } | 2229 } |
| 2200 | 2230 |
| 2201 void CodeStubAssembler::TryProbeStubCache( | 2231 void CodeStubAssembler::TryProbeStubCache( |
| 2202 StubCache* stub_cache, Code::Flags flags, compiler::Node* receiver, | 2232 StubCache* stub_cache, Code::Flags flags, compiler::Node* receiver, |
| 2203 compiler::Node* name, Label* if_handler, Variable* var_handler, | 2233 compiler::Node* name, Label* if_handler, Variable* var_handler, |
| 2204 Label* if_miss) { | 2234 Label* if_miss) { |
| 2205 Label try_secondary(this); | 2235 Label try_secondary(this), miss(this); |
| 2236 |
| 2237 Counters* counters = isolate()->counters(); |
| 2238 IncrementCounter(counters->megamorphic_stub_cache_probes(), 1); |
| 2206 | 2239 |
| 2207 // Check that the {receiver} isn't a smi. | 2240 // Check that the {receiver} isn't a smi. |
| 2208 GotoIf(WordIsSmi(receiver), if_miss); | 2241 GotoIf(WordIsSmi(receiver), &miss); |
| 2209 | 2242 |
| 2210 Node* receiver_map = LoadMap(receiver); | 2243 Node* receiver_map = LoadMap(receiver); |
| 2211 | 2244 |
| 2212 // Probe the primary table. | 2245 // Probe the primary table. |
| 2213 Node* primary_offset = StubCachePrimaryOffset(name, flags, receiver_map); | 2246 Node* primary_offset = StubCachePrimaryOffset(name, flags, receiver_map); |
| 2214 TryProbeStubCacheTable(stub_cache, kPrimary, primary_offset, name, flags, | 2247 TryProbeStubCacheTable(stub_cache, kPrimary, primary_offset, name, flags, |
| 2215 receiver_map, if_handler, var_handler, &try_secondary); | 2248 receiver_map, if_handler, var_handler, &try_secondary); |
| 2216 | 2249 |
| 2217 Bind(&try_secondary); | 2250 Bind(&try_secondary); |
| 2218 { | 2251 { |
| 2219 // Probe the secondary table. | 2252 // Probe the secondary table. |
| 2220 Node* secondary_offset = | 2253 Node* secondary_offset = |
| 2221 StubCacheSecondaryOffset(name, flags, primary_offset); | 2254 StubCacheSecondaryOffset(name, flags, primary_offset); |
| 2222 TryProbeStubCacheTable(stub_cache, kSecondary, secondary_offset, name, | 2255 TryProbeStubCacheTable(stub_cache, kSecondary, secondary_offset, name, |
| 2223 flags, receiver_map, if_handler, var_handler, | 2256 flags, receiver_map, if_handler, var_handler, &miss); |
| 2224 if_miss); | 2257 } |
| 2258 |
| 2259 Bind(&miss); |
| 2260 { |
| 2261 IncrementCounter(counters->megamorphic_stub_cache_misses(), 1); |
| 2262 Goto(if_miss); |
| 2225 } | 2263 } |
| 2226 } | 2264 } |
| 2227 | 2265 |
| 2228 void CodeStubAssembler::LoadIC(const LoadICParameters* p, Label* if_miss) { | 2266 void CodeStubAssembler::LoadIC(const LoadICParameters* p, Label* if_miss) { |
| 2229 Variable var_handler(this, MachineRepresentation::kTagged); | 2267 Variable var_handler(this, MachineRepresentation::kTagged); |
| 2230 // TODO(ishell): defer blocks when it works. | 2268 // TODO(ishell): defer blocks when it works. |
| 2231 Label if_handler(this, &var_handler), try_polymorphic(this), | 2269 Label if_handler(this, &var_handler), try_polymorphic(this), |
| 2232 try_megamorphic(this /*, Label::kDeferred*/); | 2270 try_megamorphic(this /*, Label::kDeferred*/); |
| 2233 | 2271 |
| 2234 Node* receiver_map = LoadReceiverMap(p->receiver); | 2272 Node* receiver_map = LoadReceiverMap(p->receiver); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 2263 Code::Flags code_flags = | 2301 Code::Flags code_flags = |
| 2264 Code::RemoveHolderFromFlags(Code::ComputeHandlerFlags(Code::LOAD_IC)); | 2302 Code::RemoveHolderFromFlags(Code::ComputeHandlerFlags(Code::LOAD_IC)); |
| 2265 | 2303 |
| 2266 TryProbeStubCache(isolate()->stub_cache(), code_flags, p->receiver, p->name, | 2304 TryProbeStubCache(isolate()->stub_cache(), code_flags, p->receiver, p->name, |
| 2267 &if_handler, &var_handler, if_miss); | 2305 &if_handler, &var_handler, if_miss); |
| 2268 } | 2306 } |
| 2269 } | 2307 } |
| 2270 | 2308 |
| 2271 } // namespace internal | 2309 } // namespace internal |
| 2272 } // namespace v8 | 2310 } // namespace v8 |
| OLD | NEW |