Chromium Code Reviews| 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 |