| 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 <iostream> | 7 #include <iostream> |
| 8 | 8 |
| 9 #include "src/accessors.h" | 9 #include "src/accessors.h" |
| 10 #include "src/api-arguments-inl.h" | 10 #include "src/api-arguments-inl.h" |
| (...skipping 1118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1129 return isolate()->store_stub_cache(); | 1129 return isolate()->store_stub_cache(); |
| 1130 | 1130 |
| 1131 default: | 1131 default: |
| 1132 break; | 1132 break; |
| 1133 } | 1133 } |
| 1134 UNREACHABLE(); | 1134 UNREACHABLE(); |
| 1135 return nullptr; | 1135 return nullptr; |
| 1136 } | 1136 } |
| 1137 | 1137 |
| 1138 void IC::UpdateMegamorphicCache(Map* map, Name* name, Object* handler) { | 1138 void IC::UpdateMegamorphicCache(Map* map, Name* name, Object* handler) { |
| 1139 if (FLAG_store_ic_smi_handlers && handler->IsSmi() && | |
| 1140 (kind() == Code::STORE_IC || kind() == Code::KEYED_STORE_IC)) { | |
| 1141 // TODO(ishell, jkummerow): Implement data handlers support in | |
| 1142 // KeyedStoreIC_Megamorphic. | |
| 1143 Handle<Map> map_handle(map, isolate()); | |
| 1144 Handle<Name> name_handle(name, isolate()); | |
| 1145 int config = Smi::cast(handler)->value(); | |
| 1146 int value_index = StoreHandler::DescriptorValueIndexBits::decode(config); | |
| 1147 int descriptor = (value_index - DescriptorArray::kDescriptorValue - | |
| 1148 DescriptorArray::kFirstIndex) / | |
| 1149 DescriptorArray::kDescriptorSize; | |
| 1150 if (map->instance_descriptors()->length()) { | |
| 1151 PropertyDetails details = | |
| 1152 map->instance_descriptors()->GetDetails(descriptor); | |
| 1153 DCHECK_EQ(DATA, details.type()); | |
| 1154 DCHECK_EQ(name, map->instance_descriptors()->GetKey(descriptor)); | |
| 1155 Representation representation = details.representation(); | |
| 1156 FieldIndex index = FieldIndex::ForDescriptor(map, descriptor); | |
| 1157 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreFieldStub); | |
| 1158 StoreFieldStub stub(isolate(), index, representation); | |
| 1159 handler = *stub.GetCode(); | |
| 1160 } else { | |
| 1161 // It must be a prototype map that some prototype used to have. This map | |
| 1162 // check will never succeed so write a dummy smi to the cache. | |
| 1163 DCHECK(!map->is_dictionary_map()); | |
| 1164 DCHECK(map->is_prototype_map()); | |
| 1165 handler = Smi::FromInt(1); | |
| 1166 } | |
| 1167 stub_cache()->Set(*name_handle, *map_handle, handler); | |
| 1168 return; | |
| 1169 } | |
| 1170 stub_cache()->Set(name, map, handler); | 1139 stub_cache()->Set(name, map, handler); |
| 1171 } | 1140 } |
| 1172 | 1141 |
| 1173 void IC::TraceHandlerCacheHitStats(LookupIterator* lookup) { | 1142 void IC::TraceHandlerCacheHitStats(LookupIterator* lookup) { |
| 1174 if (!FLAG_runtime_call_stats) return; | 1143 if (!FLAG_runtime_call_stats) return; |
| 1175 | 1144 |
| 1176 if (kind() == Code::LOAD_IC || kind() == Code::LOAD_GLOBAL_IC || | 1145 if (kind() == Code::LOAD_IC || kind() == Code::LOAD_GLOBAL_IC || |
| 1177 kind() == Code::KEYED_LOAD_IC) { | 1146 kind() == Code::KEYED_LOAD_IC) { |
| 1178 switch (lookup->state()) { | 1147 switch (lookup->state()) { |
| 1179 case LookupIterator::ACCESS_CHECK: | 1148 case LookupIterator::ACCESS_CHECK: |
| (...skipping 820 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2000 if (holder->IsJSGlobalObject()) { | 1969 if (holder->IsJSGlobalObject()) { |
| 2001 break; // Custom-compiled handler. | 1970 break; // Custom-compiled handler. |
| 2002 } | 1971 } |
| 2003 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreNormal); | 1972 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreNormal); |
| 2004 DCHECK(holder.is_identical_to(receiver)); | 1973 DCHECK(holder.is_identical_to(receiver)); |
| 2005 return isolate()->builtins()->StoreIC_Normal(); | 1974 return isolate()->builtins()->StoreIC_Normal(); |
| 2006 } | 1975 } |
| 2007 | 1976 |
| 2008 // -------------- Fields -------------- | 1977 // -------------- Fields -------------- |
| 2009 if (lookup->property_details().type() == DATA) { | 1978 if (lookup->property_details().type() == DATA) { |
| 2010 bool use_stub = true; | 1979 if (FLAG_tf_store_ic_stub) { |
| 2011 if (lookup->representation().IsHeapObject()) { | 1980 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreFieldDH); |
| 2012 // Only use a generic stub if no types need to be tracked. | 1981 int descriptor = lookup->GetFieldDescriptorIndex(); |
| 2013 Handle<FieldType> field_type = lookup->GetFieldType(); | 1982 FieldIndex index = lookup->GetFieldIndex(); |
| 2014 use_stub = !field_type->IsClass(); | 1983 return StoreHandler::StoreField(isolate(), descriptor, index, |
| 2015 } | 1984 lookup->representation()); |
| 2016 if (use_stub) { | 1985 } else { |
| 2017 if (FLAG_store_ic_smi_handlers) { | 1986 bool use_stub = true; |
| 2018 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreFieldDH); | 1987 if (lookup->representation().IsHeapObject()) { |
| 2019 int descriptor = lookup->GetFieldDescriptorIndex(); | 1988 // Only use a generic stub if no types need to be tracked. |
| 2020 FieldIndex index = lookup->GetFieldIndex(); | 1989 Handle<FieldType> field_type = lookup->GetFieldType(); |
| 2021 return StoreHandler::StoreField(isolate(), descriptor, index, | 1990 use_stub = !field_type->IsClass(); |
| 2022 lookup->representation()); | 1991 } |
| 2023 } else { | 1992 if (use_stub) { |
| 2024 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreFieldStub); | 1993 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreFieldStub); |
| 2025 StoreFieldStub stub(isolate(), lookup->GetFieldIndex(), | 1994 StoreFieldStub stub(isolate(), lookup->GetFieldIndex(), |
| 2026 lookup->representation()); | 1995 lookup->representation()); |
| 2027 return stub.GetCode(); | 1996 return stub.GetCode(); |
| 2028 } | 1997 } |
| 2029 } | 1998 } |
| 2030 break; // Custom-compiled handler. | 1999 break; // Custom-compiled handler. |
| 2031 } | 2000 } |
| 2032 | 2001 |
| 2033 // -------------- Constant properties -------------- | 2002 // -------------- Constant properties -------------- |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2133 auto updated_type = | 2102 auto updated_type = |
| 2134 PropertyCell::UpdatedType(cell, value, lookup->property_details()); | 2103 PropertyCell::UpdatedType(cell, value, lookup->property_details()); |
| 2135 auto code = PropertyCellStoreHandler( | 2104 auto code = PropertyCellStoreHandler( |
| 2136 isolate(), receiver, Handle<JSGlobalObject>::cast(holder), | 2105 isolate(), receiver, Handle<JSGlobalObject>::cast(holder), |
| 2137 lookup->name(), cell, updated_type); | 2106 lookup->name(), cell, updated_type); |
| 2138 return code; | 2107 return code; |
| 2139 } | 2108 } |
| 2140 | 2109 |
| 2141 // -------------- Fields -------------- | 2110 // -------------- Fields -------------- |
| 2142 if (lookup->property_details().type() == DATA) { | 2111 if (lookup->property_details().type() == DATA) { |
| 2112 DCHECK(!FLAG_tf_store_ic_stub); |
| 2143 #ifdef DEBUG | 2113 #ifdef DEBUG |
| 2144 bool use_stub = true; | 2114 bool use_stub = true; |
| 2145 if (lookup->representation().IsHeapObject()) { | 2115 if (lookup->representation().IsHeapObject()) { |
| 2146 // Only use a generic stub if no types need to be tracked. | 2116 // Only use a generic stub if no types need to be tracked. |
| 2147 Handle<FieldType> field_type = lookup->GetFieldType(); | 2117 Handle<FieldType> field_type = lookup->GetFieldType(); |
| 2148 use_stub = !field_type->IsClass(); | 2118 use_stub = !field_type->IsClass(); |
| 2149 } | 2119 } |
| 2150 DCHECK(!use_stub); | 2120 DCHECK(!use_stub); |
| 2151 #endif | 2121 #endif |
| 2152 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreField); | 2122 TRACE_HANDLER_STATS(isolate(), StoreIC_StoreField); |
| (...skipping 1051 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3204 DCHECK_EQ(LookupIterator::INTERCEPTOR, it.state()); | 3174 DCHECK_EQ(LookupIterator::INTERCEPTOR, it.state()); |
| 3205 it.Next(); | 3175 it.Next(); |
| 3206 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, | 3176 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, |
| 3207 Object::GetProperty(&it)); | 3177 Object::GetProperty(&it)); |
| 3208 } | 3178 } |
| 3209 | 3179 |
| 3210 return *result; | 3180 return *result; |
| 3211 } | 3181 } |
| 3212 } // namespace internal | 3182 } // namespace internal |
| 3213 } // namespace v8 | 3183 } // namespace v8 |
| OLD | NEW |