| 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.h" |     8 #include "src/api.h" | 
|     9 #include "src/api-arguments.h" |     9 #include "src/api-arguments.h" | 
|    10 #include "src/arguments.h" |    10 #include "src/arguments.h" | 
| (...skipping 918 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   929   TRACE_IC("LoadIC", lookup->name()); |   929   TRACE_IC("LoadIC", lookup->name()); | 
|   930 } |   930 } | 
|   931  |   931  | 
|   932  |   932  | 
|   933 void IC::UpdateMegamorphicCache(Map* map, Name* name, Code* code) { |   933 void IC::UpdateMegamorphicCache(Map* map, Name* name, Code* code) { | 
|   934   isolate()->stub_cache()->Set(name, map, code); |   934   isolate()->stub_cache()->Set(name, map, code); | 
|   935 } |   935 } | 
|   936  |   936  | 
|   937  |   937  | 
|   938 Handle<Code> IC::ComputeHandler(LookupIterator* lookup, Handle<Object> value) { |   938 Handle<Code> IC::ComputeHandler(LookupIterator* lookup, Handle<Object> value) { | 
 |   939   // Try to find a globally shared handler stub. | 
 |   940   Handle<Code> code = GetMapIndependentHandler(lookup); | 
 |   941   if (!code.is_null()) return code; | 
 |   942  | 
 |   943   // Otherwise check the map's handler cache for a map-specific handler, and | 
 |   944   // compile one if the cache comes up empty. | 
|   939   bool receiver_is_holder = |   945   bool receiver_is_holder = | 
|   940       lookup->GetReceiver().is_identical_to(lookup->GetHolder<JSObject>()); |   946       lookup->GetReceiver().is_identical_to(lookup->GetHolder<JSObject>()); | 
|   941   CacheHolderFlag flag; |   947   CacheHolderFlag flag; | 
|   942   Handle<Map> stub_holder_map = IC::GetHandlerCacheHolder( |   948   Handle<Map> stub_holder_map; | 
|   943       receiver_map(), receiver_is_holder, isolate(), &flag); |   949   if (kind() == Code::LOAD_IC || kind() == Code::KEYED_LOAD_IC) { | 
 |   950     stub_holder_map = IC::GetHandlerCacheHolder( | 
 |   951         receiver_map(), receiver_is_holder, isolate(), &flag); | 
 |   952   } else { | 
 |   953     DCHECK(kind() == Code::STORE_IC || kind() == Code::KEYED_STORE_IC); | 
 |   954     // Store handlers cannot be cached on prototypes. | 
 |   955     flag = kCacheOnReceiver; | 
 |   956     stub_holder_map = receiver_map(); | 
 |   957   } | 
|   944  |   958  | 
|   945   Handle<Code> code = PropertyHandlerCompiler::Find( |   959   code = PropertyHandlerCompiler::Find(lookup->name(), stub_holder_map, kind(), | 
|   946       lookup->name(), stub_holder_map, kind(), flag); |   960                                        flag); | 
|   947   // Use the cached value if it exists, and if it is different from the |   961   // Use the cached value if it exists, and if it is different from the | 
|   948   // handler that just missed. |   962   // handler that just missed. | 
|   949   if (!code.is_null()) { |   963   if (!code.is_null()) { | 
|   950     Handle<Code> handler; |   964     Handle<Code> handler; | 
|   951     if (maybe_handler_.ToHandle(&handler)) { |   965     if (maybe_handler_.ToHandle(&handler)) { | 
|   952       if (!handler.is_identical_to(code)) { |   966       if (!handler.is_identical_to(code)) { | 
|   953         TRACE_HANDLER_STATS(isolate(), IC_HandlerCacheHit); |   967         TRACE_HANDLER_STATS(isolate(), IC_HandlerCacheHit); | 
|   954         return code; |   968         return code; | 
|   955       } |   969       } | 
|   956     } else { |   970     } else { | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
|   967         } |   981         } | 
|   968       } else { |   982       } else { | 
|   969         TRACE_HANDLER_STATS(isolate(), IC_HandlerCacheHit); |   983         TRACE_HANDLER_STATS(isolate(), IC_HandlerCacheHit); | 
|   970         return code; |   984         return code; | 
|   971       } |   985       } | 
|   972     } |   986     } | 
|   973   } |   987   } | 
|   974  |   988  | 
|   975   code = CompileHandler(lookup, value, flag); |   989   code = CompileHandler(lookup, value, flag); | 
|   976   DCHECK(code->is_handler()); |   990   DCHECK(code->is_handler()); | 
|   977  |   991   DCHECK(Code::ExtractCacheHolderFromFlags(code->flags()) == flag); | 
|   978   // TODO(mvstanton): we'd only like to cache code on the map when it's custom |   992   Map::UpdateCodeCache(stub_holder_map, lookup->name(), code); | 
|   979   // code compiled for this map, otherwise it's already cached in the global |  | 
|   980   // code cache. We are also guarding against installing code with flags that |  | 
|   981   // don't match the desired CacheHolderFlag computed above, which would lead to |  | 
|   982   // invalid lookups later. |  | 
|   983   bool is_normal = receiver_is_holder && |  | 
|   984                    !lookup->GetHolder<JSReceiver>()->HasFastProperties(); |  | 
|   985   if (!is_normal && Code::ExtractCacheHolderFromFlags(code->flags()) == flag) { |  | 
|   986     Map::UpdateCodeCache(stub_holder_map, lookup->name(), code); |  | 
|   987   } |  | 
|   988  |   993  | 
|   989   return code; |   994   return code; | 
|   990 } |   995 } | 
|   991  |   996  | 
|   992  |   997 Handle<Code> LoadIC::GetMapIndependentHandler(LookupIterator* lookup) { | 
|   993 Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup, |  | 
|   994                                     Handle<Object> unused, |  | 
|   995                                     CacheHolderFlag cache_holder) { |  | 
|   996   Handle<Object> receiver = lookup->GetReceiver(); |   998   Handle<Object> receiver = lookup->GetReceiver(); | 
|   997   if (receiver->IsString() && |   999   if (receiver->IsString() && | 
|   998       Name::Equals(isolate()->factory()->length_string(), lookup->name())) { |  1000       Name::Equals(isolate()->factory()->length_string(), lookup->name())) { | 
|   999     FieldIndex index = FieldIndex::ForInObjectOffset(String::kLengthOffset); |  1001     FieldIndex index = FieldIndex::ForInObjectOffset(String::kLengthOffset); | 
|  1000     return SimpleFieldLoad(index); |  1002     return SimpleFieldLoad(index); | 
|  1001   } |  1003   } | 
|  1002  |  1004  | 
|  1003   if (receiver->IsStringWrapper() && |  1005   if (receiver->IsStringWrapper() && | 
|  1004       Name::Equals(isolate()->factory()->length_string(), lookup->name())) { |  1006       Name::Equals(isolate()->factory()->length_string(), lookup->name())) { | 
|  1005     TRACE_HANDLER_STATS(isolate(), LoadIC_StringLengthStub); |  1007     TRACE_HANDLER_STATS(isolate(), LoadIC_StringLengthStub); | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
|  1017     Handle<Code> stub; |  1019     Handle<Code> stub; | 
|  1018     TRACE_HANDLER_STATS(isolate(), LoadIC_FunctionPrototypeStub); |  1020     TRACE_HANDLER_STATS(isolate(), LoadIC_FunctionPrototypeStub); | 
|  1019     FunctionPrototypeStub function_prototype_stub(isolate()); |  1021     FunctionPrototypeStub function_prototype_stub(isolate()); | 
|  1020     return function_prototype_stub.GetCode(); |  1022     return function_prototype_stub.GetCode(); | 
|  1021   } |  1023   } | 
|  1022  |  1024  | 
|  1023   Handle<Map> map = receiver_map(); |  1025   Handle<Map> map = receiver_map(); | 
|  1024   Handle<JSObject> holder = lookup->GetHolder<JSObject>(); |  1026   Handle<JSObject> holder = lookup->GetHolder<JSObject>(); | 
|  1025   bool receiver_is_holder = receiver.is_identical_to(holder); |  1027   bool receiver_is_holder = receiver.is_identical_to(holder); | 
|  1026   switch (lookup->state()) { |  1028   switch (lookup->state()) { | 
|  1027     case LookupIterator::INTERCEPTOR: { |  1029     case LookupIterator::INTERCEPTOR: | 
|  1028       DCHECK(!holder->GetNamedInterceptor()->getter()->IsUndefined()); |  1030       break;  // Custom-compiled handler. | 
|  1029       TRACE_HANDLER_STATS(isolate(), LoadIC_LoadInterceptor); |  | 
|  1030       NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder); |  | 
|  1031       // Perform a lookup behind the interceptor. Copy the LookupIterator since |  | 
|  1032       // the original iterator will be used to fetch the value. |  | 
|  1033       LookupIterator it = *lookup; |  | 
|  1034       it.Next(); |  | 
|  1035       LookupForRead(&it); |  | 
|  1036       return compiler.CompileLoadInterceptor(&it); |  | 
|  1037     } |  | 
|  1038  |  1031  | 
|  1039     case LookupIterator::ACCESSOR: { |  1032     case LookupIterator::ACCESSOR: { | 
|  1040       // Use simple field loads for some well-known callback properties. |  1033       // Use simple field loads for some well-known callback properties. | 
|  1041       // The method will only return true for absolute truths based on the |  1034       // The method will only return true for absolute truths based on the | 
|  1042       // receiver maps. |  1035       // receiver maps. | 
|  1043       int object_offset; |  1036       int object_offset; | 
|  1044       if (Accessors::IsJSObjectFieldAccessor(map, lookup->name(), |  1037       if (Accessors::IsJSObjectFieldAccessor(map, lookup->name(), | 
|  1045                                              &object_offset)) { |  1038                                              &object_offset)) { | 
|  1046         FieldIndex index = FieldIndex::ForInObjectOffset(object_offset, *map); |  1039         FieldIndex index = FieldIndex::ForInObjectOffset(object_offset, *map); | 
|  1047         return SimpleFieldLoad(index); |  1040         return SimpleFieldLoad(index); | 
|  1048       } |  1041       } | 
|  1049       if (Accessors::IsJSArrayBufferViewFieldAccessor(map, lookup->name(), |  1042       if (Accessors::IsJSArrayBufferViewFieldAccessor(map, lookup->name(), | 
|  1050                                                       &object_offset)) { |  1043                                                       &object_offset)) { | 
|  1051         TRACE_HANDLER_STATS(isolate(), LoadIC_ArrayBufferViewLoadFieldStub); |  1044         TRACE_HANDLER_STATS(isolate(), LoadIC_ArrayBufferViewLoadFieldStub); | 
|  1052         FieldIndex index = FieldIndex::ForInObjectOffset(object_offset, *map); |  1045         FieldIndex index = FieldIndex::ForInObjectOffset(object_offset, *map); | 
|  1053         ArrayBufferViewLoadFieldStub stub(isolate(), index); |  1046         ArrayBufferViewLoadFieldStub stub(isolate(), index); | 
|  1054         return stub.GetCode(); |  1047         return stub.GetCode(); | 
|  1055       } |  1048       } | 
|  1056  |  1049  | 
|  1057       if (IsCompatibleReceiver(lookup, map)) { |  1050       if (IsCompatibleReceiver(lookup, map)) { | 
|  1058         Handle<Object> accessors = lookup->GetAccessors(); |  1051         Handle<Object> accessors = lookup->GetAccessors(); | 
|  1059         if (accessors->IsAccessorPair()) { |  1052         if (accessors->IsAccessorPair()) { | 
|  1060           if (!holder->HasFastProperties()) break; |  1053           if (!holder->HasFastProperties()) { | 
 |  1054             TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub); | 
 |  1055             return slow_stub(); | 
 |  1056           } | 
|  1061           // When debugging we need to go the slow path to flood the accessor. |  1057           // When debugging we need to go the slow path to flood the accessor. | 
|  1062           if (GetSharedFunctionInfo()->HasDebugInfo()) break; |  1058           if (GetSharedFunctionInfo()->HasDebugInfo()) { | 
|  1063           Handle<Object> getter(Handle<AccessorPair>::cast(accessors)->getter(), |  1059             TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub); | 
|  1064                                 isolate()); |  1060             return slow_stub(); | 
|  1065           CallOptimization call_optimization(getter); |  | 
|  1066           NamedLoadHandlerCompiler compiler(isolate(), map, holder, |  | 
|  1067                                             cache_holder); |  | 
|  1068           if (call_optimization.is_simple_api_call()) { |  | 
|  1069             TRACE_HANDLER_STATS(isolate(), LoadIC_LoadCallback); |  | 
|  1070             int index = lookup->GetAccessorIndex(); |  | 
|  1071             return compiler.CompileLoadCallback(lookup->name(), |  | 
|  1072                                                 call_optimization, index); |  | 
|  1073           } |  1061           } | 
|  1074           TRACE_HANDLER_STATS(isolate(), LoadIC_LoadViaGetter); |  1062           break;  // Custom-compiled handler. | 
|  1075           int expected_arguments = Handle<JSFunction>::cast(getter) |  | 
|  1076                                        ->shared() |  | 
|  1077                                        ->internal_formal_parameter_count(); |  | 
|  1078           return compiler.CompileLoadViaGetter( |  | 
|  1079               lookup->name(), lookup->GetAccessorIndex(), expected_arguments); |  | 
|  1080         } else if (accessors->IsAccessorInfo()) { |  1063         } else if (accessors->IsAccessorInfo()) { | 
|  1081           Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(accessors); |  1064           Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(accessors); | 
|  1082           if (v8::ToCData<Address>(info->getter()) == nullptr) break; |  1065           if (v8::ToCData<Address>(info->getter()) == nullptr) { | 
|  1083           if (!AccessorInfo::IsCompatibleReceiverMap(isolate(), info, map)) { |  1066             TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub); | 
|  1084             // This case should be already handled in LoadIC::UpdateCaches. |  1067             return slow_stub(); | 
|  1085             UNREACHABLE(); |  | 
|  1086             break; |  | 
|  1087           } |  1068           } | 
|  1088           if (!holder->HasFastProperties()) break; |  1069           // Ruled out by IsCompatibleReceiver() above. | 
 |  1070           DCHECK(AccessorInfo::IsCompatibleReceiverMap(isolate(), info, map)); | 
 |  1071           if (!holder->HasFastProperties()) return slow_stub(); | 
|  1089           if (receiver_is_holder) { |  1072           if (receiver_is_holder) { | 
|  1090             TRACE_HANDLER_STATS(isolate(), LoadIC_LoadApiGetterStub); |  1073             TRACE_HANDLER_STATS(isolate(), LoadIC_LoadApiGetterStub); | 
|  1091             int index = lookup->GetAccessorIndex(); |  1074             int index = lookup->GetAccessorIndex(); | 
|  1092             LoadApiGetterStub stub(isolate(), true, index); |  1075             LoadApiGetterStub stub(isolate(), true, index); | 
|  1093             return stub.GetCode(); |  1076             return stub.GetCode(); | 
|  1094           } |  1077           } | 
|  1095           if (info->is_sloppy() && !receiver->IsJSReceiver()) break; |  1078           if (info->is_sloppy() && !receiver->IsJSReceiver()) { | 
|  1096           TRACE_HANDLER_STATS(isolate(), LoadIC_LoadCallback); |  1079             TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub); | 
|  1097           NamedLoadHandlerCompiler compiler(isolate(), map, holder, |  1080             return slow_stub(); | 
|  1098                                             cache_holder); |  1081           } | 
|  1099           return compiler.CompileLoadCallback(lookup->name(), info); |  1082           break;  // Custom-compiled handler. | 
|  1100         } |  1083         } | 
|  1101       } |  1084       } | 
|  1102       break; |  1085       TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub); | 
 |  1086       return slow_stub(); | 
|  1103     } |  1087     } | 
|  1104  |  1088  | 
|  1105     case LookupIterator::DATA: { |  1089     case LookupIterator::DATA: { | 
|  1106       if (lookup->is_dictionary_holder()) { |  1090       if (lookup->is_dictionary_holder()) { | 
|  1107         if (kind() != Code::LOAD_IC) break; |  1091         if (kind() != Code::LOAD_IC) { | 
 |  1092           TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub); | 
 |  1093           return slow_stub(); | 
 |  1094         } | 
|  1108         if (holder->IsJSGlobalObject()) { |  1095         if (holder->IsJSGlobalObject()) { | 
|  1109           TRACE_HANDLER_STATS(isolate(), LoadIC_LoadGlobal); |  1096           break;  // Custom-compiled handler. | 
|  1110           NamedLoadHandlerCompiler compiler(isolate(), map, holder, |  | 
|  1111                                             cache_holder); |  | 
|  1112           Handle<PropertyCell> cell = lookup->GetPropertyCell(); |  | 
|  1113           Handle<Code> code = compiler.CompileLoadGlobal( |  | 
|  1114               cell, lookup->name(), lookup->IsConfigurable()); |  | 
|  1115           // TODO(verwaest): Move caching of these NORMAL stubs outside as well. |  | 
|  1116           CacheHolderFlag flag; |  | 
|  1117           Handle<Map> stub_holder_map = |  | 
|  1118               GetHandlerCacheHolder(map, receiver_is_holder, isolate(), &flag); |  | 
|  1119           Map::UpdateCodeCache(stub_holder_map, lookup->name(), code); |  | 
|  1120           return code; |  | 
|  1121         } |  1097         } | 
|  1122         // There is only one shared stub for loading normalized |  1098         // There is only one shared stub for loading normalized | 
|  1123         // properties. It does not traverse the prototype chain, so the |  1099         // properties. It does not traverse the prototype chain, so the | 
|  1124         // property must be found in the object for the stub to be |  1100         // property must be found in the object for the stub to be | 
|  1125         // applicable. |  1101         // applicable. | 
|  1126         if (!receiver_is_holder) break; |  1102         if (!receiver_is_holder) { | 
 |  1103           TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub); | 
 |  1104           return slow_stub(); | 
 |  1105         } | 
|  1127         TRACE_HANDLER_STATS(isolate(), LoadIC_LoadNormal); |  1106         TRACE_HANDLER_STATS(isolate(), LoadIC_LoadNormal); | 
|  1128         return isolate()->builtins()->LoadIC_Normal(); |  1107         return isolate()->builtins()->LoadIC_Normal(); | 
|  1129       } |  1108       } | 
|  1130  |  1109  | 
|  1131       // -------------- Fields -------------- |  1110       // -------------- Fields -------------- | 
|  1132       if (lookup->property_details().type() == DATA) { |  1111       if (lookup->property_details().type() == DATA) { | 
|  1133         FieldIndex field = lookup->GetFieldIndex(); |  1112         FieldIndex field = lookup->GetFieldIndex(); | 
|  1134         if (receiver_is_holder) { |  1113         if (receiver_is_holder) { | 
|  1135           return SimpleFieldLoad(field); |  1114           return SimpleFieldLoad(field); | 
|  1136         } |  1115         } | 
|  1137         TRACE_HANDLER_STATS(isolate(), LoadIC_LoadField); |  1116         break;  // Custom-compiled handler. | 
|  1138         NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder); |  | 
|  1139         return compiler.CompileLoadField(lookup->name(), field); |  | 
|  1140       } |  1117       } | 
|  1141  |  1118  | 
|  1142       // -------------- Constant properties -------------- |  1119       // -------------- Constant properties -------------- | 
|  1143       DCHECK(lookup->property_details().type() == DATA_CONSTANT); |  1120       DCHECK(lookup->property_details().type() == DATA_CONSTANT); | 
|  1144       if (receiver_is_holder) { |  1121       if (receiver_is_holder) { | 
|  1145         TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstantStub); |  1122         TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstantStub); | 
|  1146         LoadConstantStub stub(isolate(), lookup->GetConstantIndex()); |  1123         LoadConstantStub stub(isolate(), lookup->GetConstantIndex()); | 
|  1147         return stub.GetCode(); |  1124         return stub.GetCode(); | 
|  1148       } |  1125       } | 
 |  1126       break;  // Custom-compiled handler. | 
 |  1127     } | 
 |  1128  | 
 |  1129     case LookupIterator::INTEGER_INDEXED_EXOTIC: | 
 |  1130       TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub); | 
 |  1131       return slow_stub(); | 
 |  1132     case LookupIterator::ACCESS_CHECK: | 
 |  1133     case LookupIterator::JSPROXY: | 
 |  1134     case LookupIterator::NOT_FOUND: | 
 |  1135     case LookupIterator::TRANSITION: | 
 |  1136       UNREACHABLE(); | 
 |  1137   } | 
 |  1138  | 
 |  1139   return Handle<Code>::null(); | 
 |  1140 } | 
 |  1141  | 
 |  1142 Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup, | 
 |  1143                                     Handle<Object> unused, | 
 |  1144                                     CacheHolderFlag cache_holder) { | 
 |  1145   Handle<JSObject> holder = lookup->GetHolder<JSObject>(); | 
 |  1146 #ifdef DEBUG | 
 |  1147   // Only used by DCHECKs below. | 
 |  1148   Handle<Object> receiver = lookup->GetReceiver(); | 
 |  1149   bool receiver_is_holder = receiver.is_identical_to(holder); | 
 |  1150 #endif | 
 |  1151   // Non-map-specific handler stubs have already been selected. | 
 |  1152   DCHECK(!receiver->IsString() || | 
 |  1153          !Name::Equals(isolate()->factory()->length_string(), lookup->name())); | 
 |  1154   DCHECK(!receiver->IsStringWrapper() || | 
 |  1155          !Name::Equals(isolate()->factory()->length_string(), lookup->name())); | 
 |  1156  | 
 |  1157   DCHECK(!( | 
 |  1158       receiver->IsJSFunction() && | 
 |  1159       Name::Equals(isolate()->factory()->prototype_string(), lookup->name()) && | 
 |  1160       receiver->IsConstructor() && | 
 |  1161       !Handle<JSFunction>::cast(receiver) | 
 |  1162            ->map() | 
 |  1163            ->has_non_instance_prototype())); | 
 |  1164  | 
 |  1165   Handle<Map> map = receiver_map(); | 
 |  1166   switch (lookup->state()) { | 
 |  1167     case LookupIterator::INTERCEPTOR: { | 
 |  1168       DCHECK(!holder->GetNamedInterceptor()->getter()->IsUndefined()); | 
 |  1169       TRACE_HANDLER_STATS(isolate(), LoadIC_LoadInterceptor); | 
 |  1170       NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder); | 
 |  1171       // Perform a lookup behind the interceptor. Copy the LookupIterator since | 
 |  1172       // the original iterator will be used to fetch the value. | 
 |  1173       LookupIterator it = *lookup; | 
 |  1174       it.Next(); | 
 |  1175       LookupForRead(&it); | 
 |  1176       return compiler.CompileLoadInterceptor(&it); | 
 |  1177     } | 
 |  1178  | 
 |  1179     case LookupIterator::ACCESSOR: { | 
 |  1180 #ifdef DEBUG | 
 |  1181       int object_offset; | 
 |  1182       DCHECK(!Accessors::IsJSObjectFieldAccessor(map, lookup->name(), | 
 |  1183                                                  &object_offset)); | 
 |  1184       DCHECK(!Accessors::IsJSArrayBufferViewFieldAccessor(map, lookup->name(), | 
 |  1185                                                           &object_offset)); | 
 |  1186 #endif | 
 |  1187  | 
 |  1188       DCHECK(IsCompatibleReceiver(lookup, map)); | 
 |  1189       Handle<Object> accessors = lookup->GetAccessors(); | 
 |  1190       if (accessors->IsAccessorPair()) { | 
 |  1191         DCHECK(holder->HasFastProperties()); | 
 |  1192         DCHECK(!GetSharedFunctionInfo()->HasDebugInfo()); | 
 |  1193         Handle<Object> getter(Handle<AccessorPair>::cast(accessors)->getter(), | 
 |  1194                               isolate()); | 
 |  1195         CallOptimization call_optimization(getter); | 
 |  1196         NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder); | 
 |  1197         if (call_optimization.is_simple_api_call()) { | 
 |  1198           TRACE_HANDLER_STATS(isolate(), LoadIC_LoadCallback); | 
 |  1199           int index = lookup->GetAccessorIndex(); | 
 |  1200           return compiler.CompileLoadCallback(lookup->name(), call_optimization, | 
 |  1201                                               index); | 
 |  1202         } | 
 |  1203         TRACE_HANDLER_STATS(isolate(), LoadIC_LoadViaGetter); | 
 |  1204         int expected_arguments = Handle<JSFunction>::cast(getter) | 
 |  1205                                      ->shared() | 
 |  1206                                      ->internal_formal_parameter_count(); | 
 |  1207         return compiler.CompileLoadViaGetter( | 
 |  1208             lookup->name(), lookup->GetAccessorIndex(), expected_arguments); | 
 |  1209       } else { | 
 |  1210         DCHECK(accessors->IsAccessorInfo()); | 
 |  1211         Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(accessors); | 
 |  1212         DCHECK(v8::ToCData<Address>(info->getter()) != nullptr); | 
 |  1213         DCHECK(AccessorInfo::IsCompatibleReceiverMap(isolate(), info, map)); | 
 |  1214         DCHECK(holder->HasFastProperties()); | 
 |  1215         DCHECK(!receiver_is_holder); | 
 |  1216         DCHECK(!info->is_sloppy() || receiver->IsJSReceiver()); | 
 |  1217         TRACE_HANDLER_STATS(isolate(), LoadIC_LoadCallback); | 
 |  1218         NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder); | 
 |  1219         return compiler.CompileLoadCallback(lookup->name(), info); | 
 |  1220       } | 
 |  1221       UNREACHABLE(); | 
 |  1222     } | 
 |  1223  | 
 |  1224     case LookupIterator::DATA: { | 
 |  1225       if (lookup->is_dictionary_holder()) { | 
 |  1226         DCHECK(kind() == Code::LOAD_IC); | 
 |  1227         DCHECK(holder->IsJSGlobalObject()); | 
 |  1228         TRACE_HANDLER_STATS(isolate(), LoadIC_LoadGlobal); | 
 |  1229         NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder); | 
 |  1230         Handle<PropertyCell> cell = lookup->GetPropertyCell(); | 
 |  1231         Handle<Code> code = compiler.CompileLoadGlobal( | 
 |  1232             cell, lookup->name(), lookup->IsConfigurable()); | 
 |  1233         return code; | 
 |  1234       } | 
 |  1235  | 
 |  1236       // -------------- Fields -------------- | 
 |  1237       if (lookup->property_details().type() == DATA) { | 
 |  1238         FieldIndex field = lookup->GetFieldIndex(); | 
 |  1239         DCHECK(!receiver_is_holder); | 
 |  1240         TRACE_HANDLER_STATS(isolate(), LoadIC_LoadField); | 
 |  1241         NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder); | 
 |  1242         return compiler.CompileLoadField(lookup->name(), field); | 
 |  1243       } | 
 |  1244  | 
 |  1245       // -------------- Constant properties -------------- | 
 |  1246       DCHECK(lookup->property_details().type() == DATA_CONSTANT); | 
 |  1247       DCHECK(!receiver_is_holder); | 
|  1149       TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstant); |  1248       TRACE_HANDLER_STATS(isolate(), LoadIC_LoadConstant); | 
|  1150       NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder); |  1249       NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder); | 
|  1151       return compiler.CompileLoadConstant(lookup->name(), |  1250       return compiler.CompileLoadConstant(lookup->name(), | 
|  1152                                           lookup->GetConstantIndex()); |  1251                                           lookup->GetConstantIndex()); | 
|  1153     } |  1252     } | 
|  1154  |  1253  | 
|  1155     case LookupIterator::INTEGER_INDEXED_EXOTIC: |  1254     case LookupIterator::INTEGER_INDEXED_EXOTIC: | 
|  1156       break; |  | 
|  1157     case LookupIterator::ACCESS_CHECK: |  1255     case LookupIterator::ACCESS_CHECK: | 
|  1158     case LookupIterator::JSPROXY: |  1256     case LookupIterator::JSPROXY: | 
|  1159     case LookupIterator::NOT_FOUND: |  1257     case LookupIterator::NOT_FOUND: | 
|  1160     case LookupIterator::TRANSITION: |  1258     case LookupIterator::TRANSITION: | 
|  1161       UNREACHABLE(); |  1259       UNREACHABLE(); | 
|  1162   } |  1260   } | 
|  1163  |  1261   UNREACHABLE(); | 
|  1164   TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub); |  | 
|  1165   return slow_stub(); |  1262   return slow_stub(); | 
|  1166 } |  1263 } | 
|  1167  |  1264  | 
|  1168  |  1265  | 
|  1169 static Handle<Object> TryConvertKey(Handle<Object> key, Isolate* isolate) { |  1266 static Handle<Object> TryConvertKey(Handle<Object> key, Isolate* isolate) { | 
|  1170   // This helper implements a few common fast cases for converting |  1267   // This helper implements a few common fast cases for converting | 
|  1171   // non-smi keys of keyed loads/stores to a smi or a string. |  1268   // non-smi keys of keyed loads/stores to a smi or a string. | 
|  1172   if (key->IsHeapNumber()) { |  1269   if (key->IsHeapNumber()) { | 
|  1173     double value = Handle<HeapNumber>::cast(key)->value(); |  1270     double value = Handle<HeapNumber>::cast(key)->value(); | 
|  1174     if (std::isnan(value)) { |  1271     if (std::isnan(value)) { | 
| (...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1506     constant_type = Just(cell->GetConstantType()); |  1603     constant_type = Just(cell->GetConstantType()); | 
|  1507   } |  1604   } | 
|  1508   StoreGlobalStub stub(isolate, type, constant_type, |  1605   StoreGlobalStub stub(isolate, type, constant_type, | 
|  1509                        receiver->IsJSGlobalProxy()); |  1606                        receiver->IsJSGlobalProxy()); | 
|  1510   auto code = stub.GetCodeCopyFromTemplate(holder, cell); |  1607   auto code = stub.GetCodeCopyFromTemplate(holder, cell); | 
|  1511   // TODO(verwaest): Move caching of these NORMAL stubs outside as well. |  1608   // TODO(verwaest): Move caching of these NORMAL stubs outside as well. | 
|  1512   HeapObject::UpdateMapCodeCache(receiver, name, code); |  1609   HeapObject::UpdateMapCodeCache(receiver, name, code); | 
|  1513   return code; |  1610   return code; | 
|  1514 } |  1611 } | 
|  1515  |  1612  | 
|  1516  |  1613 Handle<Code> StoreIC::GetMapIndependentHandler(LookupIterator* lookup) { | 
|  1517 Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup, |  | 
|  1518                                      Handle<Object> value, |  | 
|  1519                                      CacheHolderFlag cache_holder) { |  | 
|  1520   DCHECK_NE(LookupIterator::JSPROXY, lookup->state()); |  1614   DCHECK_NE(LookupIterator::JSPROXY, lookup->state()); | 
|  1521  |  1615  | 
|  1522   // This is currently guaranteed by checks in StoreIC::Store. |  1616   // This is currently guaranteed by checks in StoreIC::Store. | 
|  1523   Handle<JSObject> receiver = Handle<JSObject>::cast(lookup->GetReceiver()); |  1617   Handle<JSObject> receiver = Handle<JSObject>::cast(lookup->GetReceiver()); | 
|  1524   Handle<JSObject> holder = lookup->GetHolder<JSObject>(); |  1618   Handle<JSObject> holder = lookup->GetHolder<JSObject>(); | 
|  1525   DCHECK(!receiver->IsAccessCheckNeeded() || lookup->name()->IsPrivate()); |  1619   DCHECK(!receiver->IsAccessCheckNeeded() || lookup->name()->IsPrivate()); | 
|  1526  |  1620  | 
|  1527   switch (lookup->state()) { |  1621   switch (lookup->state()) { | 
|  1528     case LookupIterator::TRANSITION: { |  1622     case LookupIterator::TRANSITION: { | 
|  1529       auto store_target = lookup->GetStoreTarget(); |  1623       auto store_target = lookup->GetStoreTarget(); | 
|  1530       if (store_target->IsJSGlobalObject()) { |  1624       if (store_target->IsJSGlobalObject()) { | 
|  1531         // TODO(dcarney): this currently just deopts. Use the transition cell. |  1625         break;  // Custom-compiled handler. | 
|  1532         TRACE_HANDLER_STATS(isolate(), StoreIC_StoreGlobalTransition); |  | 
|  1533         auto cell = isolate()->factory()->NewPropertyCell(); |  | 
|  1534         cell->set_value(*value); |  | 
|  1535         auto code = PropertyCellStoreHandler( |  | 
|  1536             isolate(), store_target, Handle<JSGlobalObject>::cast(store_target), |  | 
|  1537             lookup->name(), cell, PropertyCellType::kConstant); |  | 
|  1538         cell->set_value(isolate()->heap()->the_hole_value()); |  | 
|  1539         return code; |  | 
|  1540       } |  1626       } | 
|  1541       Handle<Map> transition = lookup->transition_map(); |  | 
|  1542       // Currently not handled by CompileStoreTransition. |  1627       // Currently not handled by CompileStoreTransition. | 
|  1543       if (!holder->HasFastProperties()) { |  1628       if (!holder->HasFastProperties()) { | 
|  1544         TRACE_GENERIC_IC(isolate(), "StoreIC", "transition from slow"); |  1629         TRACE_GENERIC_IC(isolate(), "StoreIC", "transition from slow"); | 
|  1545         break; |  1630         TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub); | 
 |  1631         return slow_stub(); | 
|  1546       } |  1632       } | 
|  1547  |  1633  | 
|  1548       DCHECK(lookup->IsCacheableTransition()); |  1634       DCHECK(lookup->IsCacheableTransition()); | 
|  1549       TRACE_HANDLER_STATS(isolate(), StoreIC_StoreTransition); |  1635       break;  // Custom-compiled handler. | 
|  1550       NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder); |  | 
|  1551       return compiler.CompileStoreTransition(transition, lookup->name()); |  | 
|  1552     } |  1636     } | 
|  1553  |  1637  | 
|  1554     case LookupIterator::INTERCEPTOR: { |  1638     case LookupIterator::INTERCEPTOR: { | 
|  1555       DCHECK(!holder->GetNamedInterceptor()->setter()->IsUndefined()); |  1639       DCHECK(!holder->GetNamedInterceptor()->setter()->IsUndefined()); | 
|  1556       TRACE_HANDLER_STATS(isolate(), StoreIC_StoreInterceptorStub); |  1640       TRACE_HANDLER_STATS(isolate(), StoreIC_StoreInterceptorStub); | 
|  1557       StoreInterceptorStub stub(isolate()); |  1641       StoreInterceptorStub stub(isolate()); | 
|  1558       return stub.GetCode(); |  1642       return stub.GetCode(); | 
|  1559     } |  1643     } | 
|  1560  |  1644  | 
|  1561     case LookupIterator::ACCESSOR: { |  1645     case LookupIterator::ACCESSOR: { | 
|  1562       if (!holder->HasFastProperties()) { |  1646       if (!holder->HasFastProperties()) { | 
|  1563         TRACE_GENERIC_IC(isolate(), "StoreIC", "accessor on slow map"); |  1647         TRACE_GENERIC_IC(isolate(), "StoreIC", "accessor on slow map"); | 
|  1564         break; |  1648         TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub); | 
 |  1649         return slow_stub(); | 
|  1565       } |  1650       } | 
|  1566       Handle<Object> accessors = lookup->GetAccessors(); |  1651       Handle<Object> accessors = lookup->GetAccessors(); | 
|  1567       if (accessors->IsAccessorInfo()) { |  1652       if (accessors->IsAccessorInfo()) { | 
|  1568         Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(accessors); |  1653         Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(accessors); | 
|  1569         if (v8::ToCData<Address>(info->setter()) == 0) { |  1654         if (v8::ToCData<Address>(info->setter()) == nullptr) { | 
|  1570           TRACE_GENERIC_IC(isolate(), "StoreIC", "setter == 0"); |  1655           TRACE_GENERIC_IC(isolate(), "StoreIC", "setter == nullptr"); | 
|  1571           break; |  1656           TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub); | 
 |  1657           return slow_stub(); | 
|  1572         } |  1658         } | 
|  1573         if (AccessorInfo::cast(*accessors)->is_special_data_property() && |  1659         if (AccessorInfo::cast(*accessors)->is_special_data_property() && | 
|  1574             !lookup->HolderIsReceiverOrHiddenPrototype()) { |  1660             !lookup->HolderIsReceiverOrHiddenPrototype()) { | 
|  1575           TRACE_GENERIC_IC(isolate(), "StoreIC", |  1661           TRACE_GENERIC_IC(isolate(), "StoreIC", | 
|  1576                            "special data property in prototype chain"); |  1662                            "special data property in prototype chain"); | 
|  1577           break; |  1663           TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub); | 
 |  1664           return slow_stub(); | 
|  1578         } |  1665         } | 
|  1579         if (!AccessorInfo::IsCompatibleReceiverMap(isolate(), info, |  1666         if (!AccessorInfo::IsCompatibleReceiverMap(isolate(), info, | 
|  1580                                                    receiver_map())) { |  1667                                                    receiver_map())) { | 
|  1581           TRACE_GENERIC_IC(isolate(), "StoreIC", "incompatible receiver type"); |  1668           TRACE_GENERIC_IC(isolate(), "StoreIC", "incompatible receiver type"); | 
|  1582           break; |  1669           TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub); | 
 |  1670           return slow_stub(); | 
|  1583         } |  1671         } | 
|  1584         if (info->is_sloppy() && !receiver->IsJSReceiver()) break; |  1672         if (info->is_sloppy() && !receiver->IsJSReceiver()) { | 
|  1585         TRACE_HANDLER_STATS(isolate(), StoreIC_StoreCallback); |  1673           TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub); | 
|  1586         NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder); |  1674           return slow_stub(); | 
|  1587         return compiler.CompileStoreCallback(receiver, lookup->name(), info, |  1675         } | 
|  1588                                              language_mode()); |  1676         break;  // Custom-compiled handler. | 
|  1589       } else if (accessors->IsAccessorPair()) { |  1677       } else if (accessors->IsAccessorPair()) { | 
|  1590         Handle<Object> setter(Handle<AccessorPair>::cast(accessors)->setter(), |  1678         Handle<Object> setter(Handle<AccessorPair>::cast(accessors)->setter(), | 
|  1591                               isolate()); |  1679                               isolate()); | 
|  1592         if (!setter->IsJSFunction() && !setter->IsFunctionTemplateInfo()) { |  1680         if (!setter->IsJSFunction() && !setter->IsFunctionTemplateInfo()) { | 
|  1593           TRACE_GENERIC_IC(isolate(), "StoreIC", "setter not a function"); |  1681           TRACE_GENERIC_IC(isolate(), "StoreIC", "setter not a function"); | 
|  1594           break; |  1682           TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub); | 
 |  1683           return slow_stub(); | 
|  1595         } |  1684         } | 
|  1596         CallOptimization call_optimization(setter); |  1685         CallOptimization call_optimization(setter); | 
|  1597         NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder); |  | 
|  1598         if (call_optimization.is_simple_api_call()) { |  1686         if (call_optimization.is_simple_api_call()) { | 
|  1599           if (call_optimization.IsCompatibleReceiver(receiver, holder)) { |  1687           if (call_optimization.IsCompatibleReceiver(receiver, holder)) { | 
|  1600             TRACE_HANDLER_STATS(isolate(), StoreIC_StoreCallback); |  1688             break;  // Custom-compiled handler. | 
|  1601             return compiler.CompileStoreCallback(receiver, lookup->name(), |  | 
|  1602                                                  call_optimization, |  | 
|  1603                                                  lookup->GetAccessorIndex()); |  | 
|  1604           } |  1689           } | 
|  1605           TRACE_GENERIC_IC(isolate(), "StoreIC", "incompatible receiver"); |  1690           TRACE_GENERIC_IC(isolate(), "StoreIC", "incompatible receiver"); | 
|  1606           break; |  1691           TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub); | 
 |  1692           return slow_stub(); | 
|  1607         } |  1693         } | 
|  1608         TRACE_HANDLER_STATS(isolate(), StoreIC_StoreViaSetter); |  1694         break;  // Custom-compiled handler. | 
|  1609         int expected_arguments = JSFunction::cast(*setter) |  | 
|  1610                                      ->shared() |  | 
|  1611                                      ->internal_formal_parameter_count(); |  | 
|  1612         return compiler.CompileStoreViaSetter(receiver, lookup->name(), |  | 
|  1613                                               lookup->GetAccessorIndex(), |  | 
|  1614                                               expected_arguments); |  | 
|  1615       } |  1695       } | 
|  1616       break; |  1696       TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub); | 
 |  1697       return slow_stub(); | 
|  1617     } |  1698     } | 
|  1618  |  1699  | 
|  1619     case LookupIterator::DATA: { |  1700     case LookupIterator::DATA: { | 
|  1620       if (lookup->is_dictionary_holder()) { |  1701       if (lookup->is_dictionary_holder()) { | 
|  1621         if (holder->IsJSGlobalObject()) { |  1702         if (holder->IsJSGlobalObject()) { | 
|  1622           TRACE_HANDLER_STATS(isolate(), StoreIC_StoreGlobal); |  1703           break;  // Custom-compiled handler. | 
|  1623           DCHECK(holder.is_identical_to(receiver) || |  | 
|  1624                  receiver->map()->prototype() == *holder); |  | 
|  1625           auto cell = lookup->GetPropertyCell(); |  | 
|  1626           auto updated_type = PropertyCell::UpdatedType( |  | 
|  1627               cell, value, lookup->property_details()); |  | 
|  1628           auto code = PropertyCellStoreHandler( |  | 
|  1629               isolate(), receiver, Handle<JSGlobalObject>::cast(holder), |  | 
|  1630               lookup->name(), cell, updated_type); |  | 
|  1631           return code; |  | 
|  1632         } |  1704         } | 
|  1633         TRACE_HANDLER_STATS(isolate(), StoreIC_StoreNormal); |  1705         TRACE_HANDLER_STATS(isolate(), StoreIC_StoreNormal); | 
|  1634         DCHECK(holder.is_identical_to(receiver)); |  1706         DCHECK(holder.is_identical_to(receiver)); | 
|  1635         return isolate()->builtins()->StoreIC_Normal(); |  1707         return isolate()->builtins()->StoreIC_Normal(); | 
|  1636       } |  1708       } | 
|  1637  |  1709  | 
|  1638       // -------------- Fields -------------- |  1710       // -------------- Fields -------------- | 
|  1639       if (lookup->property_details().type() == DATA) { |  1711       if (lookup->property_details().type() == DATA) { | 
|  1640         bool use_stub = true; |  1712         bool use_stub = true; | 
|  1641         if (lookup->representation().IsHeapObject()) { |  1713         if (lookup->representation().IsHeapObject()) { | 
|  1642           // Only use a generic stub if no types need to be tracked. |  1714           // Only use a generic stub if no types need to be tracked. | 
|  1643           Handle<FieldType> field_type = lookup->GetFieldType(); |  1715           Handle<FieldType> field_type = lookup->GetFieldType(); | 
|  1644           use_stub = !field_type->IsClass(); |  1716           use_stub = !field_type->IsClass(); | 
|  1645         } |  1717         } | 
|  1646         if (use_stub) { |  1718         if (use_stub) { | 
|  1647           TRACE_HANDLER_STATS(isolate(), StoreIC_StoreFieldStub); |  1719           TRACE_HANDLER_STATS(isolate(), StoreIC_StoreFieldStub); | 
|  1648           StoreFieldStub stub(isolate(), lookup->GetFieldIndex(), |  1720           StoreFieldStub stub(isolate(), lookup->GetFieldIndex(), | 
|  1649                               lookup->representation()); |  1721                               lookup->representation()); | 
|  1650           return stub.GetCode(); |  1722           return stub.GetCode(); | 
|  1651         } |  1723         } | 
 |  1724         break;  // Custom-compiled handler. | 
 |  1725       } | 
 |  1726  | 
 |  1727       // -------------- Constant properties -------------- | 
 |  1728       DCHECK(lookup->property_details().type() == DATA_CONSTANT); | 
 |  1729       TRACE_GENERIC_IC(isolate(), "StoreIC", "constant property"); | 
 |  1730       TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub); | 
 |  1731       return slow_stub(); | 
 |  1732     } | 
 |  1733  | 
 |  1734     case LookupIterator::INTEGER_INDEXED_EXOTIC: | 
 |  1735     case LookupIterator::ACCESS_CHECK: | 
 |  1736     case LookupIterator::JSPROXY: | 
 |  1737     case LookupIterator::NOT_FOUND: | 
 |  1738       UNREACHABLE(); | 
 |  1739   } | 
 |  1740   return Handle<Code>::null(); | 
 |  1741 } | 
 |  1742  | 
 |  1743 Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup, | 
 |  1744                                      Handle<Object> value, | 
 |  1745                                      CacheHolderFlag cache_holder) { | 
 |  1746   DCHECK_NE(LookupIterator::JSPROXY, lookup->state()); | 
 |  1747  | 
 |  1748   // This is currently guaranteed by checks in StoreIC::Store. | 
 |  1749   Handle<JSObject> receiver = Handle<JSObject>::cast(lookup->GetReceiver()); | 
 |  1750   Handle<JSObject> holder = lookup->GetHolder<JSObject>(); | 
 |  1751   DCHECK(!receiver->IsAccessCheckNeeded() || lookup->name()->IsPrivate()); | 
 |  1752  | 
 |  1753   switch (lookup->state()) { | 
 |  1754     case LookupIterator::TRANSITION: { | 
 |  1755       auto store_target = lookup->GetStoreTarget(); | 
 |  1756       if (store_target->IsJSGlobalObject()) { | 
 |  1757         // TODO(dcarney): this currently just deopts. Use the transition cell. | 
 |  1758         TRACE_HANDLER_STATS(isolate(), StoreIC_StoreGlobalTransition); | 
 |  1759         auto cell = isolate()->factory()->NewPropertyCell(); | 
 |  1760         cell->set_value(*value); | 
 |  1761         auto code = PropertyCellStoreHandler( | 
 |  1762             isolate(), store_target, Handle<JSGlobalObject>::cast(store_target), | 
 |  1763             lookup->name(), cell, PropertyCellType::kConstant); | 
 |  1764         cell->set_value(isolate()->heap()->the_hole_value()); | 
 |  1765         return code; | 
 |  1766       } | 
 |  1767       Handle<Map> transition = lookup->transition_map(); | 
 |  1768       // Currently not handled by CompileStoreTransition. | 
 |  1769       DCHECK(holder->HasFastProperties()); | 
 |  1770  | 
 |  1771       DCHECK(lookup->IsCacheableTransition()); | 
 |  1772       TRACE_HANDLER_STATS(isolate(), StoreIC_StoreTransition); | 
 |  1773       NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder); | 
 |  1774       return compiler.CompileStoreTransition(transition, lookup->name()); | 
 |  1775     } | 
 |  1776  | 
 |  1777     case LookupIterator::INTERCEPTOR: | 
 |  1778       UNREACHABLE(); | 
 |  1779  | 
 |  1780     case LookupIterator::ACCESSOR: { | 
 |  1781       DCHECK(holder->HasFastProperties()); | 
 |  1782       Handle<Object> accessors = lookup->GetAccessors(); | 
 |  1783       if (accessors->IsAccessorInfo()) { | 
 |  1784         Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(accessors); | 
 |  1785         DCHECK(v8::ToCData<Address>(info->setter()) != 0); | 
 |  1786         DCHECK(!AccessorInfo::cast(*accessors)->is_special_data_property() || | 
 |  1787                lookup->HolderIsReceiverOrHiddenPrototype()); | 
 |  1788         DCHECK(AccessorInfo::IsCompatibleReceiverMap(isolate(), info, | 
 |  1789                                                      receiver_map())); | 
 |  1790         DCHECK(!info->is_sloppy() || receiver->IsJSReceiver()); | 
 |  1791         TRACE_HANDLER_STATS(isolate(), StoreIC_StoreCallback); | 
 |  1792         NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder); | 
 |  1793         return compiler.CompileStoreCallback(receiver, lookup->name(), info, | 
 |  1794                                              language_mode()); | 
 |  1795       } else { | 
 |  1796         DCHECK(accessors->IsAccessorPair()); | 
 |  1797         Handle<Object> setter(Handle<AccessorPair>::cast(accessors)->setter(), | 
 |  1798                               isolate()); | 
 |  1799         DCHECK(setter->IsJSFunction() || setter->IsFunctionTemplateInfo()); | 
 |  1800         CallOptimization call_optimization(setter); | 
 |  1801         NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder); | 
 |  1802         if (call_optimization.is_simple_api_call()) { | 
 |  1803           DCHECK(call_optimization.IsCompatibleReceiver(receiver, holder)); | 
 |  1804           TRACE_HANDLER_STATS(isolate(), StoreIC_StoreCallback); | 
 |  1805           return compiler.CompileStoreCallback(receiver, lookup->name(), | 
 |  1806                                                call_optimization, | 
 |  1807                                                lookup->GetAccessorIndex()); | 
 |  1808         } | 
 |  1809         TRACE_HANDLER_STATS(isolate(), StoreIC_StoreViaSetter); | 
 |  1810         int expected_arguments = JSFunction::cast(*setter) | 
 |  1811                                      ->shared() | 
 |  1812                                      ->internal_formal_parameter_count(); | 
 |  1813         return compiler.CompileStoreViaSetter(receiver, lookup->name(), | 
 |  1814                                               lookup->GetAccessorIndex(), | 
 |  1815                                               expected_arguments); | 
 |  1816       } | 
 |  1817     } | 
 |  1818  | 
 |  1819     case LookupIterator::DATA: { | 
 |  1820       if (lookup->is_dictionary_holder()) { | 
 |  1821         DCHECK(holder->IsJSGlobalObject()); | 
 |  1822         TRACE_HANDLER_STATS(isolate(), StoreIC_StoreGlobal); | 
 |  1823         DCHECK(holder.is_identical_to(receiver) || | 
 |  1824                receiver->map()->prototype() == *holder); | 
 |  1825         auto cell = lookup->GetPropertyCell(); | 
 |  1826         auto updated_type = | 
 |  1827             PropertyCell::UpdatedType(cell, value, lookup->property_details()); | 
 |  1828         auto code = PropertyCellStoreHandler( | 
 |  1829             isolate(), receiver, Handle<JSGlobalObject>::cast(holder), | 
 |  1830             lookup->name(), cell, updated_type); | 
 |  1831         return code; | 
 |  1832       } | 
 |  1833  | 
 |  1834       // -------------- Fields -------------- | 
 |  1835       if (lookup->property_details().type() == DATA) { | 
 |  1836 #ifdef DEBUG | 
 |  1837         bool use_stub = true; | 
 |  1838         if (lookup->representation().IsHeapObject()) { | 
 |  1839           // Only use a generic stub if no types need to be tracked. | 
 |  1840           Handle<FieldType> field_type = lookup->GetFieldType(); | 
 |  1841           use_stub = !field_type->IsClass(); | 
 |  1842         } | 
 |  1843         DCHECK(!use_stub); | 
 |  1844 #endif | 
|  1652         TRACE_HANDLER_STATS(isolate(), StoreIC_StoreField); |  1845         TRACE_HANDLER_STATS(isolate(), StoreIC_StoreField); | 
|  1653         NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder); |  1846         NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder); | 
|  1654         return compiler.CompileStoreField(lookup); |  1847         return compiler.CompileStoreField(lookup); | 
|  1655       } |  1848       } | 
|  1656  |  1849  | 
|  1657       // -------------- Constant properties -------------- |  1850       // -------------- Constant properties -------------- | 
|  1658       DCHECK(lookup->property_details().type() == DATA_CONSTANT); |  1851       DCHECK(lookup->property_details().type() == DATA_CONSTANT); | 
|  1659       TRACE_GENERIC_IC(isolate(), "StoreIC", "constant property"); |  1852       UNREACHABLE(); | 
|  1660       break; |  | 
|  1661     } |  1853     } | 
|  1662  |  1854  | 
|  1663     case LookupIterator::INTEGER_INDEXED_EXOTIC: |  1855     case LookupIterator::INTEGER_INDEXED_EXOTIC: | 
|  1664     case LookupIterator::ACCESS_CHECK: |  1856     case LookupIterator::ACCESS_CHECK: | 
|  1665     case LookupIterator::JSPROXY: |  1857     case LookupIterator::JSPROXY: | 
|  1666     case LookupIterator::NOT_FOUND: |  1858     case LookupIterator::NOT_FOUND: | 
|  1667       UNREACHABLE(); |  1859       UNREACHABLE(); | 
|  1668   } |  1860   } | 
|  1669   TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub); |  1861   UNREACHABLE(); | 
|  1670   return slow_stub(); |  1862   return slow_stub(); | 
|  1671 } |  1863 } | 
|  1672  |  1864  | 
|  1673 void KeyedStoreIC::UpdateStoreElement(Handle<Map> receiver_map, |  1865 void KeyedStoreIC::UpdateStoreElement(Handle<Map> receiver_map, | 
|  1674                                       KeyedAccessStoreMode store_mode) { |  1866                                       KeyedAccessStoreMode store_mode) { | 
|  1675   MapHandleList target_receiver_maps; |  1867   MapHandleList target_receiver_maps; | 
|  1676   TargetMaps(&target_receiver_maps); |  1868   TargetMaps(&target_receiver_maps); | 
|  1677   if (target_receiver_maps.length() == 0) { |  1869   if (target_receiver_maps.length() == 0) { | 
|  1678     Handle<Map> monomorphic_map = |  1870     Handle<Map> monomorphic_map = | 
|  1679         ComputeTransitionedMap(receiver_map, store_mode); |  1871         ComputeTransitionedMap(receiver_map, store_mode); | 
| (...skipping 1114 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2794     KeyedLoadICNexus nexus(vector, vector_slot); |  2986     KeyedLoadICNexus nexus(vector, vector_slot); | 
|  2795     KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); |  2987     KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); | 
|  2796     ic.UpdateState(receiver, key); |  2988     ic.UpdateState(receiver, key); | 
|  2797     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); |  2989     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); | 
|  2798   } |  2990   } | 
|  2799  |  2991  | 
|  2800   return *result; |  2992   return *result; | 
|  2801 } |  2993 } | 
|  2802 }  // namespace internal |  2994 }  // namespace internal | 
|  2803 }  // namespace v8 |  2995 }  // namespace v8 | 
| OLD | NEW |