| 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     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); |  | 
| 1042     } |  | 
| 1043     stub_cache()->Set(*name_handle, *map_handle, handler); |  | 
| 1044     return; |  | 
| 1045   } |  | 
| 1046   stub_cache()->Set(name, map, handler); | 1013   stub_cache()->Set(name, map, handler); | 
| 1047 } | 1014 } | 
| 1048 | 1015 | 
| 1049 Handle<Object> IC::ComputeHandler(LookupIterator* lookup, | 1016 Handle<Object> IC::ComputeHandler(LookupIterator* lookup, | 
| 1050                                   Handle<Object> value) { | 1017                                   Handle<Object> value) { | 
| 1051   // Try to find a globally shared handler stub. | 1018   // Try to find a globally shared handler stub. | 
| 1052   Handle<Object> handler = GetMapIndependentHandler(lookup); | 1019   Handle<Object> handler = GetMapIndependentHandler(lookup); | 
| 1053   if (!handler.is_null()) { | 1020   if (!handler.is_null()) { | 
| 1054     DCHECK(IC::IsHandler(*handler)); | 1021     DCHECK(IC::IsHandler(*handler)); | 
| 1055     return handler; | 1022     return handler; | 
| (...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1667     // the pre monomorphic stub to delay setting the monomorphic state. | 1634     // the pre monomorphic stub to delay setting the monomorphic state. | 
| 1668     ConfigureVectorState(PREMONOMORPHIC, Handle<Object>()); | 1635     ConfigureVectorState(PREMONOMORPHIC, Handle<Object>()); | 
| 1669     TRACE_IC("StoreIC", lookup->name()); | 1636     TRACE_IC("StoreIC", lookup->name()); | 
| 1670     return; | 1637     return; | 
| 1671   } | 1638   } | 
| 1672 | 1639 | 
| 1673   bool use_ic = LookupForWrite(lookup, value, store_mode); | 1640   bool use_ic = LookupForWrite(lookup, value, store_mode); | 
| 1674   if (!use_ic) { | 1641   if (!use_ic) { | 
| 1675     TRACE_GENERIC_IC(isolate(), "StoreIC", "LookupForWrite said 'false'"); | 1642     TRACE_GENERIC_IC(isolate(), "StoreIC", "LookupForWrite said 'false'"); | 
| 1676   } | 1643   } | 
| 1677   Handle<Object> handler = use_ic ? ComputeHandler(lookup, value) | 1644   Handle<Code> code = | 
| 1678                                   : Handle<Object>::cast(slow_stub()); | 1645       use_ic ? Handle<Code>::cast(ComputeHandler(lookup, value)) : slow_stub(); | 
| 1679 | 1646 | 
| 1680   PatchCache(lookup->name(), handler); | 1647   PatchCache(lookup->name(), code); | 
| 1681   TRACE_IC("StoreIC", lookup->name()); | 1648   TRACE_IC("StoreIC", lookup->name()); | 
| 1682 } | 1649 } | 
| 1683 | 1650 | 
| 1684 | 1651 | 
| 1685 static Handle<Code> PropertyCellStoreHandler( | 1652 static Handle<Code> PropertyCellStoreHandler( | 
| 1686     Isolate* isolate, Handle<JSObject> receiver, Handle<JSGlobalObject> holder, | 1653     Isolate* isolate, Handle<JSObject> receiver, Handle<JSGlobalObject> holder, | 
| 1687     Handle<Name> name, Handle<PropertyCell> cell, PropertyCellType type) { | 1654     Handle<Name> name, Handle<PropertyCell> cell, PropertyCellType type) { | 
| 1688   auto constant_type = Nothing<PropertyCellConstantType>(); | 1655   auto constant_type = Nothing<PropertyCellConstantType>(); | 
| 1689   if (type == PropertyCellType::kConstantType) { | 1656   if (type == PropertyCellType::kConstantType) { | 
| 1690     constant_type = Just(cell->GetConstantType()); | 1657     constant_type = Just(cell->GetConstantType()); | 
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1789         if (holder->IsJSGlobalObject()) { | 1756         if (holder->IsJSGlobalObject()) { | 
| 1790           break;  // Custom-compiled handler. | 1757           break;  // Custom-compiled handler. | 
| 1791         } | 1758         } | 
| 1792         TRACE_HANDLER_STATS(isolate(), StoreIC_StoreNormal); | 1759         TRACE_HANDLER_STATS(isolate(), StoreIC_StoreNormal); | 
| 1793         DCHECK(holder.is_identical_to(receiver)); | 1760         DCHECK(holder.is_identical_to(receiver)); | 
| 1794         return isolate()->builtins()->StoreIC_Normal(); | 1761         return isolate()->builtins()->StoreIC_Normal(); | 
| 1795       } | 1762       } | 
| 1796 | 1763 | 
| 1797       // -------------- Fields -------------- | 1764       // -------------- Fields -------------- | 
| 1798       if (lookup->property_details().type() == DATA) { | 1765       if (lookup->property_details().type() == DATA) { | 
| 1799         if (FLAG_store_ic_smi_handlers) { | 1766         bool use_stub = true; | 
| 1800           TRACE_HANDLER_STATS(isolate(), StoreIC_StoreFieldDH); | 1767         if (lookup->representation().IsHeapObject()) { | 
| 1801           int descriptor = lookup->GetFieldDescriptorIndex(); | 1768           // Only use a generic stub if no types need to be tracked. | 
| 1802           FieldIndex index = lookup->GetFieldIndex(); | 1769           Handle<FieldType> field_type = lookup->GetFieldType(); | 
| 1803           return StoreHandler::StoreField(isolate(), descriptor, index, | 1770           use_stub = !field_type->IsClass(); | 
| 1804                                           lookup->representation()); | 1771         } | 
| 1805         } else { | 1772         if (use_stub) { | 
| 1806           bool use_stub = true; | 1773           TRACE_HANDLER_STATS(isolate(), StoreIC_StoreFieldStub); | 
| 1807           if (lookup->representation().IsHeapObject()) { | 1774           StoreFieldStub stub(isolate(), lookup->GetFieldIndex(), | 
| 1808             // Only use a generic stub if no types need to be tracked. | 1775                               lookup->representation()); | 
| 1809             Handle<FieldType> field_type = lookup->GetFieldType(); | 1776           return stub.GetCode(); | 
| 1810             use_stub = !field_type->IsClass(); |  | 
| 1811           } |  | 
| 1812           if (use_stub) { |  | 
| 1813             TRACE_HANDLER_STATS(isolate(), StoreIC_StoreFieldStub); |  | 
| 1814             StoreFieldStub stub(isolate(), lookup->GetFieldIndex(), |  | 
| 1815                                 lookup->representation()); |  | 
| 1816             return stub.GetCode(); |  | 
| 1817           } |  | 
| 1818         } | 1777         } | 
| 1819         break;  // Custom-compiled handler. | 1778         break;  // Custom-compiled handler. | 
| 1820       } | 1779       } | 
| 1821 | 1780 | 
| 1822       // -------------- Constant properties -------------- | 1781       // -------------- Constant properties -------------- | 
| 1823       DCHECK(lookup->property_details().type() == DATA_CONSTANT); | 1782       DCHECK(lookup->property_details().type() == DATA_CONSTANT); | 
| 1824       TRACE_GENERIC_IC(isolate(), "StoreIC", "constant property"); | 1783       TRACE_GENERIC_IC(isolate(), "StoreIC", "constant property"); | 
| 1825       TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub); | 1784       TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub); | 
| 1826       return slow_stub(); | 1785       return slow_stub(); | 
| 1827     } | 1786     } | 
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1925             isolate(), receiver, Handle<JSGlobalObject>::cast(holder), | 1884             isolate(), receiver, Handle<JSGlobalObject>::cast(holder), | 
| 1926             lookup->name(), cell, updated_type); | 1885             lookup->name(), cell, updated_type); | 
| 1927         return code; | 1886         return code; | 
| 1928       } | 1887       } | 
| 1929 | 1888 | 
| 1930       // -------------- Fields -------------- | 1889       // -------------- Fields -------------- | 
| 1931       if (lookup->property_details().type() == DATA) { | 1890       if (lookup->property_details().type() == DATA) { | 
| 1932 #ifdef DEBUG | 1891 #ifdef DEBUG | 
| 1933         bool use_stub = true; | 1892         bool use_stub = true; | 
| 1934         if (lookup->representation().IsHeapObject()) { | 1893         if (lookup->representation().IsHeapObject()) { | 
| 1935           DCHECK(!FLAG_store_ic_smi_handlers); |  | 
| 1936           // 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. | 
| 1937           Handle<FieldType> field_type = lookup->GetFieldType(); | 1895           Handle<FieldType> field_type = lookup->GetFieldType(); | 
| 1938           use_stub = !field_type->IsClass(); | 1896           use_stub = !field_type->IsClass(); | 
| 1939         } | 1897         } | 
| 1940         DCHECK(!use_stub); | 1898         DCHECK(!use_stub); | 
| 1941 #endif | 1899 #endif | 
| 1942         TRACE_HANDLER_STATS(isolate(), StoreIC_StoreField); | 1900         TRACE_HANDLER_STATS(isolate(), StoreIC_StoreField); | 
| 1943         NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder); | 1901         NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder); | 
| 1944         return compiler.CompileStoreField(lookup); | 1902         return compiler.CompileStoreField(lookup); | 
| 1945       } | 1903       } | 
| (...skipping 1061 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3007     DCHECK_EQ(LookupIterator::INTERCEPTOR, it.state()); | 2965     DCHECK_EQ(LookupIterator::INTERCEPTOR, it.state()); | 
| 3008     it.Next(); | 2966     it.Next(); | 
| 3009     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, | 2967     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, | 
| 3010                                        Object::GetProperty(&it)); | 2968                                        Object::GetProperty(&it)); | 
| 3011   } | 2969   } | 
| 3012 | 2970 | 
| 3013   return *result; | 2971   return *result; | 
| 3014 } | 2972 } | 
| 3015 }  // namespace internal | 2973 }  // namespace internal | 
| 3016 }  // namespace v8 | 2974 }  // namespace v8 | 
| OLD | NEW | 
|---|