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/arguments.h" | 9 #include "src/arguments.h" |
10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
(...skipping 968 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
979 Handle<Object> accessors = lookup->GetAccessors(); | 979 Handle<Object> accessors = lookup->GetAccessors(); |
980 if (accessors->IsAccessorInfo()) { | 980 if (accessors->IsAccessorInfo()) { |
981 Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(accessors); | 981 Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(accessors); |
982 if (info->getter() != NULL && | 982 if (info->getter() != NULL && |
983 !AccessorInfo::IsCompatibleReceiverMap(isolate, info, receiver_map)) { | 983 !AccessorInfo::IsCompatibleReceiverMap(isolate, info, receiver_map)) { |
984 return false; | 984 return false; |
985 } | 985 } |
986 } else if (accessors->IsAccessorPair()) { | 986 } else if (accessors->IsAccessorPair()) { |
987 Handle<Object> getter(Handle<AccessorPair>::cast(accessors)->getter(), | 987 Handle<Object> getter(Handle<AccessorPair>::cast(accessors)->getter(), |
988 isolate); | 988 isolate); |
989 if (!getter->IsJSFunction() && !getter->IsFunctionTemplateInfo()) | |
990 return false; | |
991 Handle<JSObject> holder = lookup->GetHolder<JSObject>(); | 989 Handle<JSObject> holder = lookup->GetHolder<JSObject>(); |
992 Handle<Object> receiver = lookup->GetReceiver(); | 990 Handle<Object> receiver = lookup->GetReceiver(); |
993 if (holder->HasFastProperties()) { | 991 if (getter->IsJSFunction() && holder->HasFastProperties()) { |
994 if (getter->IsJSFunction()) { | 992 Handle<JSFunction> function = Handle<JSFunction>::cast(getter); |
995 Handle<JSFunction> function = Handle<JSFunction>::cast(getter); | 993 if (receiver->IsJSObject() || function->shared()->IsBuiltin() || |
996 if (!receiver->IsJSObject() && !function->shared()->IsBuiltin() && | 994 !is_sloppy(function->shared()->language_mode())) { |
997 is_sloppy(function->shared()->language_mode())) { | 995 CallOptimization call_optimization(function); |
998 // Calling sloppy non-builtins with a value as the receiver | 996 if (call_optimization.is_simple_api_call() && |
999 // requires boxing. | 997 !call_optimization.IsCompatibleReceiverMap(receiver_map, holder)) { |
1000 return false; | 998 return false; |
1001 } | 999 } |
1002 } | 1000 } |
1003 CallOptimization call_optimization(getter); | |
1004 if (call_optimization.is_simple_api_call() && | |
1005 !call_optimization.IsCompatibleReceiverMap(receiver_map, holder)) { | |
1006 return false; | |
1007 } | |
1008 } | 1001 } |
1009 } | 1002 } |
1010 return true; | 1003 return true; |
1011 } | 1004 } |
1012 | 1005 |
1013 | 1006 |
1014 void LoadIC::UpdateCaches(LookupIterator* lookup) { | 1007 void LoadIC::UpdateCaches(LookupIterator* lookup) { |
1015 if (state() == UNINITIALIZED) { | 1008 if (state() == UNINITIALIZED) { |
1016 // This is the first time we execute this inline cache. Set the target to | 1009 // This is the first time we execute this inline cache. Set the target to |
1017 // the pre monomorphic stub to delay setting the monomorphic state. | 1010 // the pre monomorphic stub to delay setting the monomorphic state. |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1167 FieldIndex index = FieldIndex::ForInObjectOffset(object_offset, *map); | 1160 FieldIndex index = FieldIndex::ForInObjectOffset(object_offset, *map); |
1168 return SimpleFieldLoad(index); | 1161 return SimpleFieldLoad(index); |
1169 } | 1162 } |
1170 if (Accessors::IsJSArrayBufferViewFieldAccessor(map, lookup->name(), | 1163 if (Accessors::IsJSArrayBufferViewFieldAccessor(map, lookup->name(), |
1171 &object_offset)) { | 1164 &object_offset)) { |
1172 FieldIndex index = FieldIndex::ForInObjectOffset(object_offset, *map); | 1165 FieldIndex index = FieldIndex::ForInObjectOffset(object_offset, *map); |
1173 ArrayBufferViewLoadFieldStub stub(isolate(), index); | 1166 ArrayBufferViewLoadFieldStub stub(isolate(), index); |
1174 return stub.GetCode(); | 1167 return stub.GetCode(); |
1175 } | 1168 } |
1176 | 1169 |
1177 if (IsCompatibleReceiver(lookup, map)) { | 1170 Handle<Object> accessors = lookup->GetAccessors(); |
1178 Handle<Object> accessors = lookup->GetAccessors(); | 1171 if (accessors->IsAccessorInfo()) { |
1179 if (accessors->IsAccessorPair()) { | 1172 Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(accessors); |
1180 if (!holder->HasFastProperties()) break; | 1173 if (v8::ToCData<Address>(info->getter()) == 0) break; |
1181 // When debugging we need to go the slow path to flood the accessor. | 1174 if (!AccessorInfo::IsCompatibleReceiverMap(isolate(), info, map)) { |
1182 if (GetSharedFunctionInfo()->HasDebugInfo()) break; | 1175 // This case should be already handled in LoadIC::UpdateCaches. |
1183 Handle<Object> getter(Handle<AccessorPair>::cast(accessors)->getter(), | 1176 UNREACHABLE(); |
1184 isolate()); | 1177 break; |
1185 CallOptimization call_optimization(getter); | 1178 } |
1186 NamedLoadHandlerCompiler compiler(isolate(), map, holder, | 1179 if (!holder->HasFastProperties()) break; |
1187 cache_holder); | 1180 NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder); |
1188 if (call_optimization.is_simple_api_call()) { | 1181 return compiler.CompileLoadCallback(lookup->name(), info); |
| 1182 } |
| 1183 if (accessors->IsAccessorPair()) { |
| 1184 Handle<Object> getter(Handle<AccessorPair>::cast(accessors)->getter(), |
| 1185 isolate()); |
| 1186 if (!getter->IsJSFunction()) break; |
| 1187 if (!holder->HasFastProperties()) break; |
| 1188 // When debugging we need to go the slow path to flood the accessor. |
| 1189 if (GetSharedFunctionInfo()->HasDebugInfo()) break; |
| 1190 Handle<JSFunction> function = Handle<JSFunction>::cast(getter); |
| 1191 if (!receiver->IsJSObject() && !function->shared()->IsBuiltin() && |
| 1192 is_sloppy(function->shared()->language_mode())) { |
| 1193 // Calling sloppy non-builtins with a value as the receiver |
| 1194 // requires boxing. |
| 1195 break; |
| 1196 } |
| 1197 CallOptimization call_optimization(function); |
| 1198 NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder); |
| 1199 if (call_optimization.is_simple_api_call()) { |
| 1200 if (call_optimization.IsCompatibleReceiver(receiver, holder)) { |
1189 return compiler.CompileLoadCallback( | 1201 return compiler.CompileLoadCallback( |
1190 lookup->name(), call_optimization, lookup->GetAccessorIndex()); | 1202 lookup->name(), call_optimization, lookup->GetAccessorIndex()); |
1191 } | 1203 } else { |
1192 int expected_arguments = Handle<JSFunction>::cast(getter) | |
1193 ->shared() | |
1194 ->internal_formal_parameter_count(); | |
1195 return compiler.CompileLoadViaGetter( | |
1196 lookup->name(), lookup->GetAccessorIndex(), expected_arguments); | |
1197 } else if (accessors->IsAccessorInfo()) { | |
1198 Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(accessors); | |
1199 if (v8::ToCData<Address>(info->getter()) == 0) break; | |
1200 if (!AccessorInfo::IsCompatibleReceiverMap(isolate(), info, map)) { | |
1201 // This case should be already handled in LoadIC::UpdateCaches. | 1204 // This case should be already handled in LoadIC::UpdateCaches. |
1202 UNREACHABLE(); | 1205 UNREACHABLE(); |
1203 break; | |
1204 } | 1206 } |
1205 if (!holder->HasFastProperties()) break; | |
1206 NamedLoadHandlerCompiler compiler(isolate(), map, holder, | |
1207 cache_holder); | |
1208 return compiler.CompileLoadCallback(lookup->name(), info); | |
1209 } | 1207 } |
| 1208 int expected_arguments = |
| 1209 function->shared()->internal_formal_parameter_count(); |
| 1210 return compiler.CompileLoadViaGetter( |
| 1211 lookup->name(), lookup->GetAccessorIndex(), expected_arguments); |
1210 } | 1212 } |
1211 break; | 1213 break; |
1212 } | 1214 } |
1213 | 1215 |
1214 case LookupIterator::DATA: { | 1216 case LookupIterator::DATA: { |
1215 if (lookup->is_dictionary_holder()) { | 1217 if (lookup->is_dictionary_holder()) { |
1216 if (kind() != Code::LOAD_IC) break; | 1218 if (kind() != Code::LOAD_IC) break; |
1217 if (holder->IsJSGlobalObject()) { | 1219 if (holder->IsJSGlobalObject()) { |
1218 NamedLoadHandlerCompiler compiler(isolate(), map, holder, | 1220 NamedLoadHandlerCompiler compiler(isolate(), map, holder, |
1219 cache_holder); | 1221 cache_holder); |
(...skipping 1752 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2972 KeyedLoadICNexus nexus(vector, vector_slot); | 2974 KeyedLoadICNexus nexus(vector, vector_slot); |
2973 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); | 2975 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); |
2974 ic.UpdateState(receiver, key); | 2976 ic.UpdateState(receiver, key); |
2975 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); | 2977 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); |
2976 } | 2978 } |
2977 | 2979 |
2978 return *result; | 2980 return *result; |
2979 } | 2981 } |
2980 } // namespace internal | 2982 } // namespace internal |
2981 } // namespace v8 | 2983 } // namespace v8 |
OLD | NEW |