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 |