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 1484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1495 void CodeStubAssembler::DecrementCounter(StatsCounter* counter, int delta) { | 1495 void CodeStubAssembler::DecrementCounter(StatsCounter* counter, int delta) { |
1496 DCHECK(delta > 0); | 1496 DCHECK(delta > 0); |
1497 if (FLAG_native_code_counters && counter->Enabled()) { | 1497 if (FLAG_native_code_counters && counter->Enabled()) { |
1498 Node* counter_address = ExternalConstant(ExternalReference(counter)); | 1498 Node* counter_address = ExternalConstant(ExternalReference(counter)); |
1499 Node* value = Load(MachineType::Int32(), counter_address); | 1499 Node* value = Load(MachineType::Int32(), counter_address); |
1500 value = Int32Sub(value, Int32Constant(delta)); | 1500 value = Int32Sub(value, Int32Constant(delta)); |
1501 StoreNoWriteBarrier(MachineRepresentation::kWord32, counter_address, value); | 1501 StoreNoWriteBarrier(MachineRepresentation::kWord32, counter_address, value); |
1502 } | 1502 } |
1503 } | 1503 } |
1504 | 1504 |
| 1505 void CodeStubAssembler::Use(Label* label) { |
| 1506 GotoIf(Word32Equal(Int32Constant(0), Int32Constant(1)), label); |
| 1507 } |
| 1508 |
1505 void CodeStubAssembler::TryToName(Node* key, Label* if_keyisindex, | 1509 void CodeStubAssembler::TryToName(Node* key, Label* if_keyisindex, |
1506 Variable* var_index, Label* if_keyisunique, | 1510 Variable* var_index, Label* if_keyisunique, |
1507 Label* if_bailout) { | 1511 Label* if_bailout) { |
1508 DCHECK_EQ(MachineRepresentation::kWord32, var_index->rep()); | 1512 DCHECK_EQ(MachineRepresentation::kWord32, var_index->rep()); |
1509 Comment("TryToName"); | 1513 Comment("TryToName"); |
1510 | 1514 |
1511 Label if_keyissmi(this), if_keyisnotsmi(this); | 1515 Label if_keyissmi(this), if_keyisnotsmi(this); |
1512 Branch(WordIsSmi(key), &if_keyissmi, &if_keyisnotsmi); | 1516 Branch(WordIsSmi(key), &if_keyissmi, &if_keyisnotsmi); |
1513 Bind(&if_keyissmi); | 1517 Bind(&if_keyissmi); |
1514 { | 1518 { |
(...skipping 653 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2168 Goto(&if_isdictionary); | 2172 Goto(&if_isdictionary); |
2169 } | 2173 } |
2170 } | 2174 } |
2171 | 2175 |
2172 // Instantiate template methods to workaround GCC compilation issue. | 2176 // Instantiate template methods to workaround GCC compilation issue. |
2173 template void CodeStubAssembler::NumberDictionaryLookup<SeededNumberDictionary>( | 2177 template void CodeStubAssembler::NumberDictionaryLookup<SeededNumberDictionary>( |
2174 Node*, Node*, Label*, Variable*, Label*); | 2178 Node*, Node*, Label*, Variable*, Label*); |
2175 template void CodeStubAssembler::NumberDictionaryLookup< | 2179 template void CodeStubAssembler::NumberDictionaryLookup< |
2176 UnseededNumberDictionary>(Node*, Node*, Label*, Variable*, Label*); | 2180 UnseededNumberDictionary>(Node*, Node*, Label*, Variable*, Label*); |
2177 | 2181 |
| 2182 void CodeStubAssembler::TryPrototypeChainLookup( |
| 2183 Node* receiver, Node* key, LookupInHolder& lookup_property_in_holder, |
| 2184 LookupInHolder& lookup_element_in_holder, Label* if_end, |
| 2185 Label* if_bailout) { |
| 2186 // Ensure receiver is JSReceiver, otherwise bailout. |
| 2187 Label if_objectisnotsmi(this); |
| 2188 Branch(WordIsSmi(receiver), if_bailout, &if_objectisnotsmi); |
| 2189 Bind(&if_objectisnotsmi); |
| 2190 |
| 2191 Node* map = LoadMap(receiver); |
| 2192 Node* instance_type = LoadMapInstanceType(map); |
| 2193 { |
| 2194 Label if_objectisreceiver(this); |
| 2195 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE); |
| 2196 Branch(Int32GreaterThanOrEqual(instance_type, |
| 2197 Int32Constant(FIRST_JS_RECEIVER_TYPE)), |
| 2198 &if_objectisreceiver, if_bailout); |
| 2199 Bind(&if_objectisreceiver); |
| 2200 } |
| 2201 |
| 2202 Variable var_index(this, MachineRepresentation::kWord32); |
| 2203 |
| 2204 Label if_keyisindex(this), if_iskeyunique(this); |
| 2205 TryToName(key, &if_keyisindex, &var_index, &if_iskeyunique, if_bailout); |
| 2206 |
| 2207 Bind(&if_iskeyunique); |
| 2208 { |
| 2209 Variable var_holder(this, MachineRepresentation::kTagged); |
| 2210 Variable var_holder_map(this, MachineRepresentation::kTagged); |
| 2211 Variable var_holder_instance_type(this, MachineRepresentation::kWord8); |
| 2212 |
| 2213 Variable* merged_variables[] = {&var_holder, &var_holder_map, |
| 2214 &var_holder_instance_type}; |
| 2215 Label loop(this, arraysize(merged_variables), merged_variables); |
| 2216 var_holder.Bind(receiver); |
| 2217 var_holder_map.Bind(map); |
| 2218 var_holder_instance_type.Bind(instance_type); |
| 2219 Goto(&loop); |
| 2220 Bind(&loop); |
| 2221 { |
| 2222 Node* holder_map = var_holder_map.value(); |
| 2223 Node* holder_instance_type = var_holder_instance_type.value(); |
| 2224 |
| 2225 Label next_proto(this); |
| 2226 lookup_property_in_holder(receiver, var_holder.value(), holder_map, |
| 2227 holder_instance_type, key, &next_proto, |
| 2228 if_bailout); |
| 2229 Bind(&next_proto); |
| 2230 |
| 2231 // Bailout if it can be an integer indexed exotic case. |
| 2232 GotoIf( |
| 2233 Word32Equal(holder_instance_type, Int32Constant(JS_TYPED_ARRAY_TYPE)), |
| 2234 if_bailout); |
| 2235 |
| 2236 Node* proto = LoadMapPrototype(holder_map); |
| 2237 |
| 2238 Label if_not_null(this); |
| 2239 Branch(WordEqual(proto, NullConstant()), if_end, &if_not_null); |
| 2240 Bind(&if_not_null); |
| 2241 |
| 2242 Node* map = LoadMap(proto); |
| 2243 Node* instance_type = LoadMapInstanceType(map); |
| 2244 |
| 2245 var_holder.Bind(proto); |
| 2246 var_holder_map.Bind(map); |
| 2247 var_holder_instance_type.Bind(instance_type); |
| 2248 Goto(&loop); |
| 2249 } |
| 2250 } |
| 2251 Bind(&if_keyisindex); |
| 2252 { |
| 2253 Variable var_holder(this, MachineRepresentation::kTagged); |
| 2254 Variable var_holder_map(this, MachineRepresentation::kTagged); |
| 2255 Variable var_holder_instance_type(this, MachineRepresentation::kWord8); |
| 2256 |
| 2257 Variable* merged_variables[] = {&var_holder, &var_holder_map, |
| 2258 &var_holder_instance_type}; |
| 2259 Label loop(this, arraysize(merged_variables), merged_variables); |
| 2260 var_holder.Bind(receiver); |
| 2261 var_holder_map.Bind(map); |
| 2262 var_holder_instance_type.Bind(instance_type); |
| 2263 Goto(&loop); |
| 2264 Bind(&loop); |
| 2265 { |
| 2266 Label next_proto(this); |
| 2267 lookup_element_in_holder(receiver, var_holder.value(), |
| 2268 var_holder_map.value(), |
| 2269 var_holder_instance_type.value(), |
| 2270 var_index.value(), &next_proto, if_bailout); |
| 2271 Bind(&next_proto); |
| 2272 |
| 2273 Node* proto = LoadMapPrototype(var_holder_map.value()); |
| 2274 |
| 2275 Label if_not_null(this); |
| 2276 Branch(WordEqual(proto, NullConstant()), if_end, &if_not_null); |
| 2277 Bind(&if_not_null); |
| 2278 |
| 2279 Node* map = LoadMap(proto); |
| 2280 Node* instance_type = LoadMapInstanceType(map); |
| 2281 |
| 2282 var_holder.Bind(proto); |
| 2283 var_holder_map.Bind(map); |
| 2284 var_holder_instance_type.Bind(instance_type); |
| 2285 Goto(&loop); |
| 2286 } |
| 2287 } |
| 2288 } |
| 2289 |
2178 Node* CodeStubAssembler::OrdinaryHasInstance(Node* context, Node* callable, | 2290 Node* CodeStubAssembler::OrdinaryHasInstance(Node* context, Node* callable, |
2179 Node* object) { | 2291 Node* object) { |
2180 Variable var_result(this, MachineRepresentation::kTagged); | 2292 Variable var_result(this, MachineRepresentation::kTagged); |
2181 Label return_false(this), return_true(this), | 2293 Label return_false(this), return_true(this), |
2182 return_runtime(this, Label::kDeferred), return_result(this); | 2294 return_runtime(this, Label::kDeferred), return_result(this); |
2183 | 2295 |
2184 // Goto runtime if {object} is a Smi. | 2296 // Goto runtime if {object} is a Smi. |
2185 GotoIf(WordIsSmi(object), &return_runtime); | 2297 GotoIf(WordIsSmi(object), &return_runtime); |
2186 | 2298 |
2187 // Load map of {object}. | 2299 // Load map of {object}. |
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2668 } | 2780 } |
2669 Bind(&miss); | 2781 Bind(&miss); |
2670 { | 2782 { |
2671 TailCallRuntime(Runtime::kLoadGlobalIC_Miss, p->context, p->slot, | 2783 TailCallRuntime(Runtime::kLoadGlobalIC_Miss, p->context, p->slot, |
2672 p->vector); | 2784 p->vector); |
2673 } | 2785 } |
2674 } | 2786 } |
2675 | 2787 |
2676 } // namespace internal | 2788 } // namespace internal |
2677 } // namespace v8 | 2789 } // namespace v8 |
OLD | NEW |