Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(236)

Side by Side Diff: src/ic/ic.cc

Issue 2438553003: [ic] Support data handlers that represent simple field stores. (Closed)
Patch Set: One more fix for GC stress issues Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/ic/handler-configuration-inl.h ('k') | src/lookup.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/ic/handler-configuration-inl.h ('k') | src/lookup.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698