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/ic/ic.h" | 5 #include "src/ic/ic.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/api-arguments-inl.h" | 8 #include "src/api-arguments-inl.h" |
9 #include "src/api.h" | 9 #include "src/api.h" |
10 #include "src/arguments.h" | 10 #include "src/arguments.h" |
(...skipping 549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
560 LoadICNexus* nexus = casted_nexus<LoadICNexus>(); | 560 LoadICNexus* nexus = casted_nexus<LoadICNexus>(); |
561 nexus->ConfigureMonomorphic(map, handler); | 561 nexus->ConfigureMonomorphic(map, handler); |
562 } else if (kind() == Code::LOAD_GLOBAL_IC) { | 562 } else if (kind() == Code::LOAD_GLOBAL_IC) { |
563 LoadGlobalICNexus* nexus = casted_nexus<LoadGlobalICNexus>(); | 563 LoadGlobalICNexus* nexus = casted_nexus<LoadGlobalICNexus>(); |
564 nexus->ConfigureHandlerMode(Handle<Code>::cast(handler)); | 564 nexus->ConfigureHandlerMode(Handle<Code>::cast(handler)); |
565 } else if (kind() == Code::KEYED_LOAD_IC) { | 565 } else if (kind() == Code::KEYED_LOAD_IC) { |
566 KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>(); | 566 KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>(); |
567 nexus->ConfigureMonomorphic(name, map, handler); | 567 nexus->ConfigureMonomorphic(name, map, handler); |
568 } else if (kind() == Code::STORE_IC) { | 568 } else if (kind() == Code::STORE_IC) { |
569 StoreICNexus* nexus = casted_nexus<StoreICNexus>(); | 569 StoreICNexus* nexus = casted_nexus<StoreICNexus>(); |
570 nexus->ConfigureMonomorphic(map, Handle<Code>::cast(handler)); | 570 nexus->ConfigureMonomorphic(map, handler); |
571 } else { | 571 } else { |
572 DCHECK(kind() == Code::KEYED_STORE_IC); | 572 DCHECK(kind() == Code::KEYED_STORE_IC); |
573 KeyedStoreICNexus* nexus = casted_nexus<KeyedStoreICNexus>(); | 573 KeyedStoreICNexus* nexus = casted_nexus<KeyedStoreICNexus>(); |
574 nexus->ConfigureMonomorphic(name, map, Handle<Code>::cast(handler)); | 574 nexus->ConfigureMonomorphic(name, map, handler); |
575 } | 575 } |
576 | 576 |
577 vector_set_ = true; | 577 vector_set_ = true; |
578 OnTypeFeedbackChanged(isolate(), get_host()); | 578 OnTypeFeedbackChanged(isolate(), get_host()); |
579 } | 579 } |
580 | 580 |
581 void IC::ConfigureVectorState(Handle<Name> name, MapHandleList* maps, | 581 void IC::ConfigureVectorState(Handle<Name> name, MapHandleList* maps, |
582 List<Handle<Object>>* handlers) { | 582 List<Handle<Object>>* handlers) { |
583 DCHECK(UseVector()); | 583 DCHECK(UseVector()); |
584 if (kind() == Code::LOAD_IC) { | 584 if (kind() == Code::LOAD_IC) { |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
783 MapHandleList map_list; | 783 MapHandleList map_list; |
784 map_list.Add(handle(target_map)); | 784 map_list.Add(handle(target_map)); |
785 transitioned_map = source_map->FindElementsKindTransitionedMap(&map_list); | 785 transitioned_map = source_map->FindElementsKindTransitionedMap(&map_list); |
786 } | 786 } |
787 return transitioned_map == target_map; | 787 return transitioned_map == target_map; |
788 } | 788 } |
789 | 789 |
790 void IC::PatchCache(Handle<Name> name, Handle<Object> handler) { | 790 void IC::PatchCache(Handle<Name> name, Handle<Object> handler) { |
791 DCHECK(IsHandler(*handler)); | 791 DCHECK(IsHandler(*handler)); |
792 // Currently only LoadIC and KeyedLoadIC support non-code handlers. | 792 // Currently only LoadIC and KeyedLoadIC support non-code handlers. |
793 DCHECK_IMPLIES(!handler->IsCode(), | 793 DCHECK_IMPLIES(!handler->IsCode(), kind() == Code::LOAD_IC || |
794 kind() == Code::LOAD_IC || kind() == Code::KEYED_LOAD_IC); | 794 kind() == Code::KEYED_LOAD_IC || |
795 kind() == Code::STORE_IC || | |
796 kind() == Code::KEYED_STORE_IC); | |
795 switch (state()) { | 797 switch (state()) { |
796 case UNINITIALIZED: | 798 case UNINITIALIZED: |
797 case PREMONOMORPHIC: | 799 case PREMONOMORPHIC: |
798 UpdateMonomorphicIC(handler, name); | 800 UpdateMonomorphicIC(handler, name); |
799 break; | 801 break; |
800 case RECOMPUTE_HANDLER: | 802 case RECOMPUTE_HANDLER: |
801 case MONOMORPHIC: | 803 case MONOMORPHIC: |
802 if (kind() == Code::LOAD_GLOBAL_IC) { | 804 if (kind() == Code::LOAD_GLOBAL_IC) { |
803 UpdateMonomorphicIC(handler, name); | 805 UpdateMonomorphicIC(handler, name); |
804 break; | 806 break; |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1003 return isolate()->store_stub_cache(); | 1005 return isolate()->store_stub_cache(); |
1004 | 1006 |
1005 default: | 1007 default: |
1006 break; | 1008 break; |
1007 } | 1009 } |
1008 UNREACHABLE(); | 1010 UNREACHABLE(); |
1009 return nullptr; | 1011 return nullptr; |
1010 } | 1012 } |
1011 | 1013 |
1012 void IC::UpdateMegamorphicCache(Map* map, Name* name, Object* handler) { | 1014 void IC::UpdateMegamorphicCache(Map* map, Name* name, Object* handler) { |
1015 if (FLAG_store_ic_smi_handlers && handler->IsSmi() && | |
1016 (kind() == Code::STORE_IC || kind() == Code::KEYED_STORE_IC)) { | |
1017 // TODO(ishell, jkummerow): Implement data handlers support in | |
1018 // KeyedStoreIC_Megamorphic. | |
1019 Handle<Map> map_handle(map, isolate()); | |
1020 Handle<Name> name_handle(name, isolate()); | |
1021 int config = Smi::cast(handler)->value(); | |
1022 int value_index = StoreHandler::DescriptorValueIndexBits::decode(config); | |
1023 int descriptor = (value_index - DescriptorArray::kDescriptorValue - | |
1024 DescriptorArray::kFirstIndex) / | |
1025 DescriptorArray::kDescriptorSize; | |
1026 if (map->instance_descriptors()->length()) { | |
1027 PropertyDetails details = | |
1028 map->instance_descriptors()->GetDetails(descriptor); | |
1029 DCHECK_EQ(DATA, details.type()); | |
1030 DCHECK_EQ(name, map->instance_descriptors()->GetKey(descriptor)); | |
1031 Representation representation = details.representation(); | |
1032 FieldIndex index = FieldIndex::ForDescriptor(map, descriptor); | |
1033 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreFieldStub); | |
1034 StoreFieldStub stub(isolate(), index, representation); | |
1035 handler = *stub.GetCode(); | |
1036 } else { | |
1037 // It must be a prototype map that some prototype used to have. This map | |
1038 // check will never succeed so write a dummy smi to the cache. | |
1039 DCHECK(!map->is_dictionary_map()); | |
1040 DCHECK(map->is_prototype_map()); | |
1041 handler = Smi::FromInt(1); | |
Jakob Kummerow
2016/10/24 09:56:19
Come to think of it: why is this line not "return;
Igor Sheludko
2016/12/05 07:30:07
Actually, we should have not even got here with su
| |
1042 } | |
1043 stub_cache()->Set(*name_handle, *map_handle, handler); | |
1044 return; | |
1045 } | |
1013 stub_cache()->Set(name, map, handler); | 1046 stub_cache()->Set(name, map, handler); |
1014 } | 1047 } |
1015 | 1048 |
1016 Handle<Object> IC::ComputeHandler(LookupIterator* lookup, | 1049 Handle<Object> IC::ComputeHandler(LookupIterator* lookup, |
1017 Handle<Object> value) { | 1050 Handle<Object> value) { |
1018 // Try to find a globally shared handler stub. | 1051 // Try to find a globally shared handler stub. |
1019 Handle<Object> handler = GetMapIndependentHandler(lookup); | 1052 Handle<Object> handler = GetMapIndependentHandler(lookup); |
1020 if (!handler.is_null()) { | 1053 if (!handler.is_null()) { |
1021 DCHECK(IC::IsHandler(*handler)); | 1054 DCHECK(IC::IsHandler(*handler)); |
1022 return handler; | 1055 return handler; |
(...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1634 // the pre monomorphic stub to delay setting the monomorphic state. | 1667 // the pre monomorphic stub to delay setting the monomorphic state. |
1635 ConfigureVectorState(PREMONOMORPHIC, Handle<Object>()); | 1668 ConfigureVectorState(PREMONOMORPHIC, Handle<Object>()); |
1636 TRACE_IC("StoreIC", lookup->name()); | 1669 TRACE_IC("StoreIC", lookup->name()); |
1637 return; | 1670 return; |
1638 } | 1671 } |
1639 | 1672 |
1640 bool use_ic = LookupForWrite(lookup, value, store_mode); | 1673 bool use_ic = LookupForWrite(lookup, value, store_mode); |
1641 if (!use_ic) { | 1674 if (!use_ic) { |
1642 TRACE_GENERIC_IC(isolate(), "StoreIC", "LookupForWrite said 'false'"); | 1675 TRACE_GENERIC_IC(isolate(), "StoreIC", "LookupForWrite said 'false'"); |
1643 } | 1676 } |
1644 Handle<Code> code = | 1677 Handle<Object> handler = use_ic ? ComputeHandler(lookup, value) |
1645 use_ic ? Handle<Code>::cast(ComputeHandler(lookup, value)) : slow_stub(); | 1678 : Handle<Object>::cast(slow_stub()); |
1646 | 1679 |
1647 PatchCache(lookup->name(), code); | 1680 PatchCache(lookup->name(), handler); |
1648 TRACE_IC("StoreIC", lookup->name()); | 1681 TRACE_IC("StoreIC", lookup->name()); |
1649 } | 1682 } |
1650 | 1683 |
1651 | 1684 |
1652 static Handle<Code> PropertyCellStoreHandler( | 1685 static Handle<Code> PropertyCellStoreHandler( |
1653 Isolate* isolate, Handle<JSObject> receiver, Handle<JSGlobalObject> holder, | 1686 Isolate* isolate, Handle<JSObject> receiver, Handle<JSGlobalObject> holder, |
1654 Handle<Name> name, Handle<PropertyCell> cell, PropertyCellType type) { | 1687 Handle<Name> name, Handle<PropertyCell> cell, PropertyCellType type) { |
1655 auto constant_type = Nothing<PropertyCellConstantType>(); | 1688 auto constant_type = Nothing<PropertyCellConstantType>(); |
1656 if (type == PropertyCellType::kConstantType) { | 1689 if (type == PropertyCellType::kConstantType) { |
1657 constant_type = Just(cell->GetConstantType()); | 1690 constant_type = Just(cell->GetConstantType()); |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1763 | 1796 |
1764 // -------------- Fields -------------- | 1797 // -------------- Fields -------------- |
1765 if (lookup->property_details().type() == DATA) { | 1798 if (lookup->property_details().type() == DATA) { |
1766 bool use_stub = true; | 1799 bool use_stub = true; |
1767 if (lookup->representation().IsHeapObject()) { | 1800 if (lookup->representation().IsHeapObject()) { |
1768 // Only use a generic stub if no types need to be tracked. | 1801 // Only use a generic stub if no types need to be tracked. |
1769 Handle<FieldType> field_type = lookup->GetFieldType(); | 1802 Handle<FieldType> field_type = lookup->GetFieldType(); |
1770 use_stub = !field_type->IsClass(); | 1803 use_stub = !field_type->IsClass(); |
1771 } | 1804 } |
1772 if (use_stub) { | 1805 if (use_stub) { |
1773 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreFieldStub); | 1806 if (FLAG_store_ic_smi_handlers) { |
1774 StoreFieldStub stub(isolate(), lookup->GetFieldIndex(), | 1807 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreFieldDH); |
1775 lookup->representation()); | 1808 int descriptor = lookup->GetFieldDescriptorIndex(); |
1776 return stub.GetCode(); | 1809 FieldIndex index = lookup->GetFieldIndex(); |
1810 return StoreHandler::StoreField(isolate(), descriptor, index, | |
1811 lookup->representation()); | |
1812 } else { | |
1813 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreFieldStub); | |
1814 StoreFieldStub stub(isolate(), lookup->GetFieldIndex(), | |
1815 lookup->representation()); | |
1816 return stub.GetCode(); | |
1817 } | |
1777 } | 1818 } |
1778 break; // Custom-compiled handler. | 1819 break; // Custom-compiled handler. |
1779 } | 1820 } |
1780 | 1821 |
1781 // -------------- Constant properties -------------- | 1822 // -------------- Constant properties -------------- |
1782 DCHECK(lookup->property_details().type() == DATA_CONSTANT); | 1823 DCHECK(lookup->property_details().type() == DATA_CONSTANT); |
1783 TRACE_GENERIC_IC(isolate(), "StoreIC", "constant property"); | 1824 TRACE_GENERIC_IC(isolate(), "StoreIC", "constant property"); |
1784 TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub); | 1825 TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub); |
1785 return slow_stub(); | 1826 return slow_stub(); |
1786 } | 1827 } |
(...skipping 1178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2965 DCHECK_EQ(LookupIterator::INTERCEPTOR, it.state()); | 3006 DCHECK_EQ(LookupIterator::INTERCEPTOR, it.state()); |
2966 it.Next(); | 3007 it.Next(); |
2967 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, | 3008 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, |
2968 Object::GetProperty(&it)); | 3009 Object::GetProperty(&it)); |
2969 } | 3010 } |
2970 | 3011 |
2971 return *result; | 3012 return *result; |
2972 } | 3013 } |
2973 } // namespace internal | 3014 } // namespace internal |
2974 } // namespace v8 | 3015 } // namespace v8 |
OLD | NEW |