Chromium Code Reviews| 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 954 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 965 return KeyedLoadIC::ChooseMegamorphicStub(isolate(), extra_ic_state()); | 965 return KeyedLoadIC::ChooseMegamorphicStub(isolate(), extra_ic_state()); |
| 966 } | 966 } |
| 967 | 967 |
| 968 | 968 |
| 969 Handle<Code> LoadIC::SimpleFieldLoad(FieldIndex index) { | 969 Handle<Code> LoadIC::SimpleFieldLoad(FieldIndex index) { |
| 970 LoadFieldStub stub(isolate(), index); | 970 LoadFieldStub stub(isolate(), index); |
| 971 return stub.GetCode(); | 971 return stub.GetCode(); |
| 972 } | 972 } |
| 973 | 973 |
| 974 | 974 |
| 975 bool IsCompatibleReceiver(LookupIterator* lookup, Handle<Map> receiver_map) { | |
|
Jakob Kummerow
2015/12/17 11:36:31
This is factored out from below.
| |
| 976 DCHECK(lookup->state() == LookupIterator::ACCESSOR); | |
| 977 Isolate* isolate = lookup->isolate(); | |
| 978 Handle<Object> accessors = lookup->GetAccessors(); | |
| 979 if (accessors->IsExecutableAccessorInfo()) { | |
| 980 Handle<ExecutableAccessorInfo> info = | |
| 981 Handle<ExecutableAccessorInfo>::cast(accessors); | |
| 982 if (info->getter() != NULL && | |
| 983 !ExecutableAccessorInfo::IsCompatibleReceiverMap(isolate, info, | |
| 984 receiver_map)) { | |
| 985 return false; | |
| 986 } | |
| 987 } else if (accessors->IsAccessorPair()) { | |
| 988 Handle<Object> getter(Handle<AccessorPair>::cast(accessors)->getter(), | |
| 989 isolate); | |
| 990 Handle<JSObject> holder = lookup->GetHolder<JSObject>(); | |
| 991 Handle<Object> receiver = lookup->GetReceiver(); | |
| 992 if (getter->IsJSFunction() && holder->HasFastProperties()) { | |
| 993 Handle<JSFunction> function = Handle<JSFunction>::cast(getter); | |
| 994 if (receiver->IsJSObject() || function->shared()->IsBuiltin() || | |
| 995 !is_sloppy(function->shared()->language_mode())) { | |
| 996 CallOptimization call_optimization(function); | |
| 997 if (call_optimization.is_simple_api_call() && | |
| 998 !call_optimization.IsCompatibleReceiverMap(receiver_map, holder)) { | |
| 999 return false; | |
| 1000 } | |
| 1001 } | |
| 1002 } | |
| 1003 } | |
| 1004 return true; | |
| 1005 } | |
| 1006 | |
| 1007 | |
| 975 void LoadIC::UpdateCaches(LookupIterator* lookup) { | 1008 void LoadIC::UpdateCaches(LookupIterator* lookup) { |
| 976 if (state() == UNINITIALIZED) { | 1009 if (state() == UNINITIALIZED) { |
| 977 // This is the first time we execute this inline cache. Set the target to | 1010 // This is the first time we execute this inline cache. Set the target to |
| 978 // the pre monomorphic stub to delay setting the monomorphic state. | 1011 // the pre monomorphic stub to delay setting the monomorphic state. |
| 979 ConfigureVectorState(PREMONOMORPHIC); | 1012 ConfigureVectorState(PREMONOMORPHIC); |
| 980 TRACE_IC("LoadIC", lookup->name()); | 1013 TRACE_IC("LoadIC", lookup->name()); |
| 981 return; | 1014 return; |
| 982 } | 1015 } |
| 983 | 1016 |
| 984 Handle<Code> code; | 1017 Handle<Code> code; |
| 985 if (lookup->state() == LookupIterator::JSPROXY || | 1018 if (lookup->state() == LookupIterator::JSPROXY || |
| 986 lookup->state() == LookupIterator::ACCESS_CHECK) { | 1019 lookup->state() == LookupIterator::ACCESS_CHECK) { |
| 987 code = slow_stub(); | 1020 code = slow_stub(); |
| 988 } else if (!lookup->IsFound()) { | 1021 } else if (!lookup->IsFound()) { |
| 989 if (kind() == Code::LOAD_IC && !is_strong(language_mode())) { | 1022 if (kind() == Code::LOAD_IC && !is_strong(language_mode())) { |
| 990 code = NamedLoadHandlerCompiler::ComputeLoadNonexistent(lookup->name(), | 1023 code = NamedLoadHandlerCompiler::ComputeLoadNonexistent(lookup->name(), |
| 991 receiver_map()); | 1024 receiver_map()); |
| 992 // TODO(jkummerow/verwaest): Introduce a builtin that handles this case. | 1025 // TODO(jkummerow/verwaest): Introduce a builtin that handles this case. |
| 993 if (code.is_null()) code = slow_stub(); | 1026 if (code.is_null()) code = slow_stub(); |
| 994 } else { | 1027 } else { |
| 995 code = slow_stub(); | 1028 code = slow_stub(); |
| 996 } | 1029 } |
| 997 } else { | 1030 } else { |
| 998 if (lookup->state() == LookupIterator::ACCESSOR) { | 1031 if (lookup->state() == LookupIterator::ACCESSOR) { |
| 999 Handle<Object> accessors = lookup->GetAccessors(); | 1032 if (!IsCompatibleReceiver(lookup, receiver_map())) { |
| 1000 Handle<Map> map = receiver_map(); | 1033 TRACE_GENERIC_IC(isolate(), "LoadIC", "incompatible receiver type"); |
| 1001 if (accessors->IsExecutableAccessorInfo()) { | 1034 code = slow_stub(); |
| 1002 Handle<ExecutableAccessorInfo> info = | 1035 } |
| 1003 Handle<ExecutableAccessorInfo>::cast(accessors); | 1036 } else if (lookup->state() == LookupIterator::INTERCEPTOR) { |
| 1004 if ((v8::ToCData<Address>(info->getter()) != 0) && | 1037 // Perform a lookup behind the interceptor. Copy the LookupIterator since |
| 1005 !ExecutableAccessorInfo::IsCompatibleReceiverMap(isolate(), info, | 1038 // the original iterator will be used to fetch the value. |
| 1006 map)) { | 1039 LookupIterator it = *lookup; |
| 1007 TRACE_GENERIC_IC(isolate(), "LoadIC", "incompatible receiver type"); | 1040 it.Next(); |
| 1008 code = slow_stub(); | 1041 LookupForRead(&it); |
| 1009 } | 1042 if (it.state() == LookupIterator::ACCESSOR && |
| 1010 } else if (accessors->IsAccessorPair()) { | 1043 !IsCompatibleReceiver(&it, receiver_map())) { |
| 1011 Handle<Object> getter(Handle<AccessorPair>::cast(accessors)->getter(), | 1044 TRACE_GENERIC_IC(isolate(), "LoadIC", "incompatible receiver type"); |
| 1012 isolate()); | 1045 code = slow_stub(); |
| 1013 Handle<JSObject> holder = lookup->GetHolder<JSObject>(); | |
| 1014 Handle<Object> receiver = lookup->GetReceiver(); | |
| 1015 if (getter->IsJSFunction() && holder->HasFastProperties()) { | |
| 1016 Handle<JSFunction> function = Handle<JSFunction>::cast(getter); | |
| 1017 if (receiver->IsJSObject() || function->shared()->IsBuiltin() || | |
| 1018 !is_sloppy(function->shared()->language_mode())) { | |
| 1019 CallOptimization call_optimization(function); | |
| 1020 if (call_optimization.is_simple_api_call() && | |
| 1021 !call_optimization.IsCompatibleReceiver(receiver, holder)) { | |
| 1022 TRACE_GENERIC_IC(isolate(), "LoadIC", | |
| 1023 "incompatible receiver type"); | |
| 1024 code = slow_stub(); | |
| 1025 } | |
| 1026 } | |
| 1027 } | |
| 1028 } | 1046 } |
| 1029 } | 1047 } |
| 1030 if (code.is_null()) code = ComputeHandler(lookup); | 1048 if (code.is_null()) code = ComputeHandler(lookup); |
| 1031 } | 1049 } |
| 1032 | 1050 |
| 1033 PatchCache(lookup->name(), code); | 1051 PatchCache(lookup->name(), code); |
| 1034 TRACE_IC("LoadIC", lookup->name()); | 1052 TRACE_IC("LoadIC", lookup->name()); |
| 1035 } | 1053 } |
| 1036 | 1054 |
| 1037 | 1055 |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1147 &object_offset)) { | 1165 &object_offset)) { |
| 1148 FieldIndex index = FieldIndex::ForInObjectOffset(object_offset, *map); | 1166 FieldIndex index = FieldIndex::ForInObjectOffset(object_offset, *map); |
| 1149 ArrayBufferViewLoadFieldStub stub(isolate(), index); | 1167 ArrayBufferViewLoadFieldStub stub(isolate(), index); |
| 1150 return stub.GetCode(); | 1168 return stub.GetCode(); |
| 1151 } | 1169 } |
| 1152 | 1170 |
| 1153 Handle<Object> accessors = lookup->GetAccessors(); | 1171 Handle<Object> accessors = lookup->GetAccessors(); |
| 1154 if (accessors->IsExecutableAccessorInfo()) { | 1172 if (accessors->IsExecutableAccessorInfo()) { |
| 1155 Handle<ExecutableAccessorInfo> info = | 1173 Handle<ExecutableAccessorInfo> info = |
| 1156 Handle<ExecutableAccessorInfo>::cast(accessors); | 1174 Handle<ExecutableAccessorInfo>::cast(accessors); |
| 1157 if (v8::ToCData<Address>(info->getter()) == 0) break; | 1175 if (v8::ToCData<Address>(info->getter()) == 0) break; |
|
jochen (gone - plz use gerrit)
2015/12/17 11:43:46
also use IsCompatibleReceiver() here?
| |
| 1158 if (!ExecutableAccessorInfo::IsCompatibleReceiverMap(isolate(), info, | 1176 if (!ExecutableAccessorInfo::IsCompatibleReceiverMap(isolate(), info, |
| 1159 map)) { | 1177 map)) { |
| 1160 // This case should be already handled in LoadIC::UpdateCaches. | 1178 // This case should be already handled in LoadIC::UpdateCaches. |
| 1161 UNREACHABLE(); | 1179 UNREACHABLE(); |
| 1162 break; | 1180 break; |
| 1163 } | 1181 } |
| 1164 if (!holder->HasFastProperties()) break; | 1182 if (!holder->HasFastProperties()) break; |
| 1165 NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder); | 1183 NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder); |
| 1166 return compiler.CompileLoadCallback(lookup->name(), info); | 1184 return compiler.CompileLoadCallback(lookup->name(), info); |
| 1167 } | 1185 } |
| (...skipping 1789 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2957 KeyedLoadICNexus nexus(vector, vector_slot); | 2975 KeyedLoadICNexus nexus(vector, vector_slot); |
| 2958 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); | 2976 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); |
| 2959 ic.UpdateState(receiver, key); | 2977 ic.UpdateState(receiver, key); |
| 2960 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); | 2978 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); |
| 2961 } | 2979 } |
| 2962 | 2980 |
| 2963 return *result; | 2981 return *result; |
| 2964 } | 2982 } |
| 2965 } // namespace internal | 2983 } // namespace internal |
| 2966 } // namespace v8 | 2984 } // namespace v8 |
| OLD | NEW |