Chromium Code Reviews| 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/ic/accessor-assembler.h" | 5 #include "src/ic/accessor-assembler.h" |
| 6 | 6 |
| 7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
| 8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
| 9 #include "src/ic/handler-configuration.h" | 9 #include "src/ic/handler-configuration.h" |
| 10 #include "src/ic/stub-cache.h" | 10 #include "src/ic/stub-cache.h" |
| (...skipping 1385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1396 } | 1396 } |
| 1397 | 1397 |
| 1398 void AccessorAssembler::KeyedLoadICGeneric(const LoadICParameters* p) { | 1398 void AccessorAssembler::KeyedLoadICGeneric(const LoadICParameters* p) { |
| 1399 Variable var_index(this, MachineType::PointerRepresentation()); | 1399 Variable var_index(this, MachineType::PointerRepresentation()); |
| 1400 Variable var_unique(this, MachineRepresentation::kTagged); | 1400 Variable var_unique(this, MachineRepresentation::kTagged); |
| 1401 var_unique.Bind(p->name); // Dummy initialization. | 1401 var_unique.Bind(p->name); // Dummy initialization. |
| 1402 Variable var_details(this, MachineRepresentation::kWord32); | 1402 Variable var_details(this, MachineRepresentation::kWord32); |
| 1403 Variable var_value(this, MachineRepresentation::kTagged); | 1403 Variable var_value(this, MachineRepresentation::kTagged); |
| 1404 Label if_index(this), if_unique_name(this), if_element_hole(this), | 1404 Label if_index(this), if_unique_name(this), if_element_hole(this), |
| 1405 if_oob(this), slow(this), stub_cache_miss(this), | 1405 if_oob(this), slow(this), stub_cache_miss(this), |
| 1406 if_property_dictionary(this), if_found_on_receiver(this); | 1406 if_property_dictionary(this), if_found_on_receiver(this), |
| 1407 lookup_prototype_chain(this); | |
| 1407 | 1408 |
| 1408 Node* receiver = p->receiver; | 1409 Node* receiver = p->receiver; |
| 1409 GotoIf(TaggedIsSmi(receiver), &slow); | 1410 GotoIf(TaggedIsSmi(receiver), &slow); |
| 1410 Node* receiver_map = LoadMap(receiver); | 1411 Node* receiver_map = LoadMap(receiver); |
| 1411 Node* instance_type = LoadMapInstanceType(receiver_map); | 1412 Node* instance_type = LoadMapInstanceType(receiver_map); |
| 1412 // Receivers requiring non-standard element accesses (interceptors, access | 1413 // Receivers requiring non-standard element accesses (interceptors, access |
| 1413 // checks, strings and string wrappers, proxies) are handled in the runtime. | 1414 // checks, strings and string wrappers, proxies) are handled in the runtime. |
| 1414 GotoIf(Int32LessThanOrEqual(instance_type, | 1415 GotoIf(Int32LessThanOrEqual(instance_type, |
| 1415 Int32Constant(LAST_CUSTOM_ELEMENTS_RECEIVER)), | 1416 Int32Constant(LAST_CUSTOM_ELEMENTS_RECEIVER)), |
| 1416 &slow); | 1417 &slow); |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1521 Bind(&if_property_dictionary); | 1522 Bind(&if_property_dictionary); |
| 1522 { | 1523 { |
| 1523 Comment("dictionary property load"); | 1524 Comment("dictionary property load"); |
| 1524 // We checked for LAST_CUSTOM_ELEMENTS_RECEIVER before, which rules out | 1525 // We checked for LAST_CUSTOM_ELEMENTS_RECEIVER before, which rules out |
| 1525 // seeing global objects here (which would need special handling). | 1526 // seeing global objects here (which would need special handling). |
| 1526 | 1527 |
| 1527 Node* key = var_unique.value(); | 1528 Node* key = var_unique.value(); |
| 1528 Variable var_name_index(this, MachineType::PointerRepresentation()); | 1529 Variable var_name_index(this, MachineType::PointerRepresentation()); |
| 1529 Label dictionary_found(this, &var_name_index); | 1530 Label dictionary_found(this, &var_name_index); |
| 1530 NameDictionaryLookup<NameDictionary>(properties, key, &dictionary_found, | 1531 NameDictionaryLookup<NameDictionary>(properties, key, &dictionary_found, |
| 1531 &var_name_index, &slow); | 1532 &var_name_index, |
| 1533 &lookup_prototype_chain); | |
| 1532 Bind(&dictionary_found); | 1534 Bind(&dictionary_found); |
| 1533 { | 1535 { |
| 1534 LoadPropertyFromNameDictionary(properties, var_name_index.value(), | 1536 LoadPropertyFromNameDictionary(properties, var_name_index.value(), |
| 1535 &var_details, &var_value); | 1537 &var_details, &var_value); |
| 1536 Goto(&if_found_on_receiver); | 1538 Goto(&if_found_on_receiver); |
| 1537 } | 1539 } |
| 1538 } | 1540 } |
| 1539 | 1541 |
| 1540 Bind(&if_found_on_receiver); | 1542 Bind(&if_found_on_receiver); |
| 1541 { | 1543 { |
| 1542 Node* value = CallGetterIfAccessor(var_value.value(), var_details.value(), | 1544 Node* value = CallGetterIfAccessor(var_value.value(), var_details.value(), |
| 1543 p->context, receiver, &slow); | 1545 p->context, receiver, &slow); |
| 1544 IncrementCounter(isolate()->counters()->ic_keyed_load_generic_symbol(), 1); | 1546 IncrementCounter(isolate()->counters()->ic_keyed_load_generic_symbol(), 1); |
| 1545 Return(value); | 1547 Return(value); |
| 1546 } | 1548 } |
| 1547 | 1549 |
| 1550 Bind(&lookup_prototype_chain); | |
| 1551 { | |
| 1552 Variable var_holder_map(this, MachineRepresentation::kTagged); | |
| 1553 Variable var_holder_instance_type(this, MachineRepresentation::kWord32); | |
| 1554 Label return_undefined(this); | |
| 1555 Variable* merged_variables[] = {&var_holder_map, &var_holder_instance_type}; | |
| 1556 Label loop(this, arraysize(merged_variables), merged_variables); | |
| 1557 | |
| 1558 var_holder_map.Bind(receiver_map); | |
| 1559 var_holder_instance_type.Bind(instance_type); | |
| 1560 Goto(&loop); | |
| 1561 Bind(&loop); | |
| 1562 { | |
| 1563 // Bailout if it can be an integer indexed exotic case. | |
| 1564 GotoIf(Word32Equal(var_holder_instance_type.value(), | |
|
Igor Sheludko
2017/01/27 08:58:08
I guess we can move this check to next_proto block
Jakob Kummerow
2017/01/28 01:41:29
No, we need it in the first iteration. "Integer in
| |
| 1565 Int32Constant(JS_TYPED_ARRAY_TYPE)), | |
| 1566 &slow); | |
| 1567 Node* proto = LoadMapPrototype(var_holder_map.value()); | |
| 1568 GotoIf(WordEqual(proto, NullConstant()), &return_undefined); | |
| 1569 Node* proto_map = LoadMap(proto); | |
| 1570 Node* proto_instance_type = LoadMapInstanceType(proto_map); | |
| 1571 var_holder_map.Bind(proto_map); | |
| 1572 var_holder_instance_type.Bind(proto_instance_type); | |
| 1573 Label next_proto(this), return_value(this, &var_value), goto_slow(this); | |
| 1574 TryGetOwnProperty(p->context, receiver, proto, proto_map, | |
| 1575 proto_instance_type, var_unique.value(), &return_value, | |
| 1576 &var_value, &next_proto, &goto_slow); | |
| 1577 | |
| 1578 Bind(&next_proto); | |
|
Jakob Kummerow
2017/01/25 16:40:06
This trampoline and the next are needed to appease
Igor Sheludko
2017/01/27 08:58:08
Maybe add this as a comment to the code.
Jakob Kummerow
2017/01/28 01:41:29
Done.
| |
| 1579 Goto(&loop); | |
| 1580 | |
| 1581 Bind(&goto_slow); | |
| 1582 Goto(&slow); | |
| 1583 | |
| 1584 Bind(&return_value); | |
| 1585 Return(var_value.value()); | |
| 1586 } | |
| 1587 | |
| 1588 Bind(&return_undefined); | |
| 1589 Return(UndefinedConstant()); | |
| 1590 } | |
| 1591 | |
| 1548 Bind(&slow); | 1592 Bind(&slow); |
| 1549 { | 1593 { |
| 1550 Comment("KeyedLoadGeneric_slow"); | 1594 Comment("KeyedLoadGeneric_slow"); |
| 1551 IncrementCounter(isolate()->counters()->ic_keyed_load_generic_slow(), 1); | 1595 IncrementCounter(isolate()->counters()->ic_keyed_load_generic_slow(), 1); |
| 1552 // TODO(jkummerow): Should we use the GetProperty TF stub instead? | 1596 // TODO(jkummerow): Should we use the GetProperty TF stub instead? |
| 1553 TailCallRuntime(Runtime::kKeyedGetProperty, p->context, p->receiver, | 1597 TailCallRuntime(Runtime::kKeyedGetProperty, p->context, p->receiver, |
| 1554 p->name); | 1598 p->name); |
| 1555 } | 1599 } |
| 1556 } | 1600 } |
| 1557 | 1601 |
| (...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1883 Node* slot = Parameter(Descriptor::kSlot); | 1927 Node* slot = Parameter(Descriptor::kSlot); |
| 1884 Node* context = Parameter(Descriptor::kContext); | 1928 Node* context = Parameter(Descriptor::kContext); |
| 1885 Node* vector = LoadTypeFeedbackVectorForStub(); | 1929 Node* vector = LoadTypeFeedbackVectorForStub(); |
| 1886 | 1930 |
| 1887 StoreICParameters p(context, receiver, name, value, slot, vector); | 1931 StoreICParameters p(context, receiver, name, value, slot, vector); |
| 1888 KeyedStoreIC(&p, language_mode); | 1932 KeyedStoreIC(&p, language_mode); |
| 1889 } | 1933 } |
| 1890 | 1934 |
| 1891 } // namespace internal | 1935 } // namespace internal |
| 1892 } // namespace v8 | 1936 } // namespace v8 |
| OLD | NEW |