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, handler); | 570 nexus->ConfigureMonomorphic(map, Handle<Code>::cast(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, handler); | 574 nexus->ConfigureMonomorphic(name, map, Handle<Code>::cast(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(), kind() == Code::LOAD_IC || | 793 DCHECK_IMPLIES(!handler->IsCode(), |
794 kind() == Code::KEYED_LOAD_IC || | 794 kind() == Code::LOAD_IC || kind() == Code::KEYED_LOAD_IC); |
795 kind() == Code::STORE_IC || | |
796 kind() == Code::KEYED_STORE_IC); | |
797 switch (state()) { | 795 switch (state()) { |
798 case UNINITIALIZED: | 796 case UNINITIALIZED: |
799 case PREMONOMORPHIC: | 797 case PREMONOMORPHIC: |
800 UpdateMonomorphicIC(handler, name); | 798 UpdateMonomorphicIC(handler, name); |
801 break; | 799 break; |
802 case RECOMPUTE_HANDLER: | 800 case RECOMPUTE_HANDLER: |
803 case MONOMORPHIC: | 801 case MONOMORPHIC: |
804 if (kind() == Code::LOAD_GLOBAL_IC) { | 802 if (kind() == Code::LOAD_GLOBAL_IC) { |
805 UpdateMonomorphicIC(handler, name); | 803 UpdateMonomorphicIC(handler, name); |
806 break; | 804 break; |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1005 return isolate()->store_stub_cache(); | 1003 return isolate()->store_stub_cache(); |
1006 | 1004 |
1007 default: | 1005 default: |
1008 break; | 1006 break; |
1009 } | 1007 } |
1010 UNREACHABLE(); | 1008 UNREACHABLE(); |
1011 return nullptr; | 1009 return nullptr; |
1012 } | 1010 } |
1013 | 1011 |
1014 void IC::UpdateMegamorphicCache(Map* map, Name* name, Object* handler) { | 1012 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 | |
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 Code* handler = *stub.GetCode(); | |
1036 stub_cache()->Set(*name_handle, *map_handle, handler); | |
1037 return; | |
1038 } | |
1039 stub_cache()->Set(name, map, handler); | 1013 stub_cache()->Set(name, map, handler); |
1040 } | 1014 } |
1041 | 1015 |
1042 Handle<Object> IC::ComputeHandler(LookupIterator* lookup, | 1016 Handle<Object> IC::ComputeHandler(LookupIterator* lookup, |
1043 Handle<Object> value) { | 1017 Handle<Object> value) { |
1044 // Try to find a globally shared handler stub. | 1018 // Try to find a globally shared handler stub. |
1045 Handle<Object> handler = GetMapIndependentHandler(lookup); | 1019 Handle<Object> handler = GetMapIndependentHandler(lookup); |
1046 if (!handler.is_null()) { | 1020 if (!handler.is_null()) { |
1047 DCHECK(IC::IsHandler(*handler)); | 1021 DCHECK(IC::IsHandler(*handler)); |
1048 return handler; | 1022 return handler; |
(...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1660 // the pre monomorphic stub to delay setting the monomorphic state. | 1634 // the pre monomorphic stub to delay setting the monomorphic state. |
1661 ConfigureVectorState(PREMONOMORPHIC, Handle<Object>()); | 1635 ConfigureVectorState(PREMONOMORPHIC, Handle<Object>()); |
1662 TRACE_IC("StoreIC", lookup->name()); | 1636 TRACE_IC("StoreIC", lookup->name()); |
1663 return; | 1637 return; |
1664 } | 1638 } |
1665 | 1639 |
1666 bool use_ic = LookupForWrite(lookup, value, store_mode); | 1640 bool use_ic = LookupForWrite(lookup, value, store_mode); |
1667 if (!use_ic) { | 1641 if (!use_ic) { |
1668 TRACE_GENERIC_IC(isolate(), "StoreIC", "LookupForWrite said 'false'"); | 1642 TRACE_GENERIC_IC(isolate(), "StoreIC", "LookupForWrite said 'false'"); |
1669 } | 1643 } |
1670 Handle<Object> handler = use_ic ? ComputeHandler(lookup, value) | 1644 Handle<Code> code = |
1671 : Handle<Object>::cast(slow_stub()); | 1645 use_ic ? Handle<Code>::cast(ComputeHandler(lookup, value)) : slow_stub(); |
1672 | 1646 |
1673 PatchCache(lookup->name(), handler); | 1647 PatchCache(lookup->name(), code); |
1674 TRACE_IC("StoreIC", lookup->name()); | 1648 TRACE_IC("StoreIC", lookup->name()); |
1675 } | 1649 } |
1676 | 1650 |
1677 | 1651 |
1678 static Handle<Code> PropertyCellStoreHandler( | 1652 static Handle<Code> PropertyCellStoreHandler( |
1679 Isolate* isolate, Handle<JSObject> receiver, Handle<JSGlobalObject> holder, | 1653 Isolate* isolate, Handle<JSObject> receiver, Handle<JSGlobalObject> holder, |
1680 Handle<Name> name, Handle<PropertyCell> cell, PropertyCellType type) { | 1654 Handle<Name> name, Handle<PropertyCell> cell, PropertyCellType type) { |
1681 auto constant_type = Nothing<PropertyCellConstantType>(); | 1655 auto constant_type = Nothing<PropertyCellConstantType>(); |
1682 if (type == PropertyCellType::kConstantType) { | 1656 if (type == PropertyCellType::kConstantType) { |
1683 constant_type = Just(cell->GetConstantType()); | 1657 constant_type = Just(cell->GetConstantType()); |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1782 if (holder->IsJSGlobalObject()) { | 1756 if (holder->IsJSGlobalObject()) { |
1783 break; // Custom-compiled handler. | 1757 break; // Custom-compiled handler. |
1784 } | 1758 } |
1785 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreNormal); | 1759 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreNormal); |
1786 DCHECK(holder.is_identical_to(receiver)); | 1760 DCHECK(holder.is_identical_to(receiver)); |
1787 return isolate()->builtins()->StoreIC_Normal(); | 1761 return isolate()->builtins()->StoreIC_Normal(); |
1788 } | 1762 } |
1789 | 1763 |
1790 // -------------- Fields -------------- | 1764 // -------------- Fields -------------- |
1791 if (lookup->property_details().type() == DATA) { | 1765 if (lookup->property_details().type() == DATA) { |
1792 if (FLAG_store_ic_smi_handlers) { | 1766 bool use_stub = true; |
1793 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreFieldDH); | 1767 if (lookup->representation().IsHeapObject()) { |
1794 int descriptor = lookup->GetFieldDescriptorIndex(); | 1768 // Only use a generic stub if no types need to be tracked. |
1795 FieldIndex index = lookup->GetFieldIndex(); | 1769 Handle<FieldType> field_type = lookup->GetFieldType(); |
1796 return StoreHandler::StoreField(isolate(), descriptor, index, | 1770 use_stub = !field_type->IsClass(); |
1797 lookup->representation()); | 1771 } |
1798 } else { | 1772 if (use_stub) { |
1799 bool use_stub = true; | 1773 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreFieldStub); |
1800 if (lookup->representation().IsHeapObject()) { | 1774 StoreFieldStub stub(isolate(), lookup->GetFieldIndex(), |
1801 // Only use a generic stub if no types need to be tracked. | 1775 lookup->representation()); |
1802 Handle<FieldType> field_type = lookup->GetFieldType(); | 1776 return stub.GetCode(); |
1803 use_stub = !field_type->IsClass(); | |
1804 } | |
1805 if (use_stub) { | |
1806 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreFieldStub); | |
1807 StoreFieldStub stub(isolate(), lookup->GetFieldIndex(), | |
1808 lookup->representation()); | |
1809 return stub.GetCode(); | |
1810 } | |
1811 } | 1777 } |
1812 break; // Custom-compiled handler. | 1778 break; // Custom-compiled handler. |
1813 } | 1779 } |
1814 | 1780 |
1815 // -------------- Constant properties -------------- | 1781 // -------------- Constant properties -------------- |
1816 DCHECK(lookup->property_details().type() == DATA_CONSTANT); | 1782 DCHECK(lookup->property_details().type() == DATA_CONSTANT); |
1817 TRACE_GENERIC_IC(isolate(), "StoreIC", "constant property"); | 1783 TRACE_GENERIC_IC(isolate(), "StoreIC", "constant property"); |
1818 TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub); | 1784 TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub); |
1819 return slow_stub(); | 1785 return slow_stub(); |
1820 } | 1786 } |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1918 isolate(), receiver, Handle<JSGlobalObject>::cast(holder), | 1884 isolate(), receiver, Handle<JSGlobalObject>::cast(holder), |
1919 lookup->name(), cell, updated_type); | 1885 lookup->name(), cell, updated_type); |
1920 return code; | 1886 return code; |
1921 } | 1887 } |
1922 | 1888 |
1923 // -------------- Fields -------------- | 1889 // -------------- Fields -------------- |
1924 if (lookup->property_details().type() == DATA) { | 1890 if (lookup->property_details().type() == DATA) { |
1925 #ifdef DEBUG | 1891 #ifdef DEBUG |
1926 bool use_stub = true; | 1892 bool use_stub = true; |
1927 if (lookup->representation().IsHeapObject()) { | 1893 if (lookup->representation().IsHeapObject()) { |
1928 DCHECK(!FLAG_store_ic_smi_handlers); | |
1929 // Only use a generic stub if no types need to be tracked. | 1894 // Only use a generic stub if no types need to be tracked. |
1930 Handle<FieldType> field_type = lookup->GetFieldType(); | 1895 Handle<FieldType> field_type = lookup->GetFieldType(); |
1931 use_stub = !field_type->IsClass(); | 1896 use_stub = !field_type->IsClass(); |
1932 } | 1897 } |
1933 DCHECK(!use_stub); | 1898 DCHECK(!use_stub); |
1934 #endif | 1899 #endif |
1935 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreField); | 1900 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreField); |
1936 NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder); | 1901 NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder); |
1937 return compiler.CompileStoreField(lookup); | 1902 return compiler.CompileStoreField(lookup); |
1938 } | 1903 } |
(...skipping 1061 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3000 DCHECK_EQ(LookupIterator::INTERCEPTOR, it.state()); | 2965 DCHECK_EQ(LookupIterator::INTERCEPTOR, it.state()); |
3001 it.Next(); | 2966 it.Next(); |
3002 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, | 2967 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, |
3003 Object::GetProperty(&it)); | 2968 Object::GetProperty(&it)); |
3004 } | 2969 } |
3005 | 2970 |
3006 return *result; | 2971 return *result; |
3007 } | 2972 } |
3008 } // namespace internal | 2973 } // namespace internal |
3009 } // namespace v8 | 2974 } // namespace v8 |
OLD | NEW |