| 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 996 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1007 return KeyedLoadIC::ChooseMegamorphicStub(isolate(), extra_ic_state()); | 1007 return KeyedLoadIC::ChooseMegamorphicStub(isolate(), extra_ic_state()); |
| 1008 } | 1008 } |
| 1009 | 1009 |
| 1010 | 1010 |
| 1011 Handle<Code> LoadIC::SimpleFieldLoad(FieldIndex index) { | 1011 Handle<Code> LoadIC::SimpleFieldLoad(FieldIndex index) { |
| 1012 LoadFieldStub stub(isolate(), index); | 1012 LoadFieldStub stub(isolate(), index); |
| 1013 return stub.GetCode(); | 1013 return stub.GetCode(); |
| 1014 } | 1014 } |
| 1015 | 1015 |
| 1016 | 1016 |
| 1017 bool IsCompatibleReceiver(LookupIterator* lookup, Handle<Map> receiver_map) { |
| 1018 DCHECK(lookup->state() == LookupIterator::ACCESSOR); |
| 1019 Isolate* isolate = lookup->isolate(); |
| 1020 Handle<Object> accessors = lookup->GetAccessors(); |
| 1021 if (accessors->IsExecutableAccessorInfo()) { |
| 1022 Handle<ExecutableAccessorInfo> info = |
| 1023 Handle<ExecutableAccessorInfo>::cast(accessors); |
| 1024 if (info->getter() != NULL && |
| 1025 !ExecutableAccessorInfo::IsCompatibleReceiverMap(isolate, info, |
| 1026 receiver_map)) { |
| 1027 return false; |
| 1028 } |
| 1029 } else if (accessors->IsAccessorPair()) { |
| 1030 Handle<Object> getter(Handle<AccessorPair>::cast(accessors)->getter(), |
| 1031 isolate); |
| 1032 Handle<JSObject> holder = lookup->GetHolder<JSObject>(); |
| 1033 Handle<Object> receiver = lookup->GetReceiver(); |
| 1034 if (getter->IsJSFunction() && holder->HasFastProperties()) { |
| 1035 Handle<JSFunction> function = Handle<JSFunction>::cast(getter); |
| 1036 if (receiver->IsJSObject() || function->shared()->IsBuiltin() || |
| 1037 !is_sloppy(function->shared()->language_mode())) { |
| 1038 CallOptimization call_optimization(function); |
| 1039 if (call_optimization.is_simple_api_call() && |
| 1040 !call_optimization.IsCompatibleReceiverMap(receiver_map, holder)) { |
| 1041 return false; |
| 1042 } |
| 1043 } |
| 1044 } |
| 1045 } |
| 1046 return true; |
| 1047 } |
| 1048 |
| 1049 |
| 1017 void LoadIC::UpdateCaches(LookupIterator* lookup) { | 1050 void LoadIC::UpdateCaches(LookupIterator* lookup) { |
| 1018 if (state() == UNINITIALIZED) { | 1051 if (state() == UNINITIALIZED) { |
| 1019 // This is the first time we execute this inline cache. Set the target to | 1052 // This is the first time we execute this inline cache. Set the target to |
| 1020 // the pre monomorphic stub to delay setting the monomorphic state. | 1053 // the pre monomorphic stub to delay setting the monomorphic state. |
| 1021 ConfigureVectorState(PREMONOMORPHIC); | 1054 ConfigureVectorState(PREMONOMORPHIC); |
| 1022 TRACE_IC("LoadIC", lookup->name()); | 1055 TRACE_IC("LoadIC", lookup->name()); |
| 1023 return; | 1056 return; |
| 1024 } | 1057 } |
| 1025 | 1058 |
| 1026 Handle<Code> code; | 1059 Handle<Code> code; |
| 1027 if (lookup->state() == LookupIterator::JSPROXY || | 1060 if (lookup->state() == LookupIterator::JSPROXY || |
| 1028 lookup->state() == LookupIterator::ACCESS_CHECK) { | 1061 lookup->state() == LookupIterator::ACCESS_CHECK) { |
| 1029 code = slow_stub(); | 1062 code = slow_stub(); |
| 1030 } else if (!lookup->IsFound()) { | 1063 } else if (!lookup->IsFound()) { |
| 1031 if (kind() == Code::LOAD_IC && !is_strong(language_mode())) { | 1064 if (kind() == Code::LOAD_IC && !is_strong(language_mode())) { |
| 1032 code = NamedLoadHandlerCompiler::ComputeLoadNonexistent(lookup->name(), | 1065 code = NamedLoadHandlerCompiler::ComputeLoadNonexistent(lookup->name(), |
| 1033 receiver_map()); | 1066 receiver_map()); |
| 1034 // TODO(jkummerow/verwaest): Introduce a builtin that handles this case. | 1067 // TODO(jkummerow/verwaest): Introduce a builtin that handles this case. |
| 1035 if (code.is_null()) code = slow_stub(); | 1068 if (code.is_null()) code = slow_stub(); |
| 1036 } else { | 1069 } else { |
| 1037 code = slow_stub(); | 1070 code = slow_stub(); |
| 1038 } | 1071 } |
| 1039 } else { | 1072 } else { |
| 1040 if (lookup->state() == LookupIterator::ACCESSOR) { | 1073 if (lookup->state() == LookupIterator::ACCESSOR) { |
| 1041 Handle<Object> accessors = lookup->GetAccessors(); | 1074 if (!IsCompatibleReceiver(lookup, receiver_map())) { |
| 1042 Handle<Map> map = receiver_map(); | 1075 TRACE_GENERIC_IC(isolate(), "LoadIC", "incompatible receiver type"); |
| 1043 if (accessors->IsExecutableAccessorInfo()) { | 1076 code = slow_stub(); |
| 1044 Handle<ExecutableAccessorInfo> info = | 1077 } |
| 1045 Handle<ExecutableAccessorInfo>::cast(accessors); | 1078 } else if (lookup->state() == LookupIterator::INTERCEPTOR) { |
| 1046 if ((v8::ToCData<Address>(info->getter()) != 0) && | 1079 // Perform a lookup behind the interceptor. Copy the LookupIterator since |
| 1047 !ExecutableAccessorInfo::IsCompatibleReceiverMap(isolate(), info, | 1080 // the original iterator will be used to fetch the value. |
| 1048 map)) { | 1081 LookupIterator it = *lookup; |
| 1049 TRACE_GENERIC_IC(isolate(), "LoadIC", "incompatible receiver type"); | 1082 it.Next(); |
| 1050 code = slow_stub(); | 1083 LookupForRead(&it); |
| 1051 } | 1084 if (it.state() == LookupIterator::ACCESSOR && |
| 1052 } else if (accessors->IsAccessorPair()) { | 1085 !IsCompatibleReceiver(&it, receiver_map())) { |
| 1053 Handle<Object> getter(Handle<AccessorPair>::cast(accessors)->getter(), | 1086 TRACE_GENERIC_IC(isolate(), "LoadIC", "incompatible receiver type"); |
| 1054 isolate()); | 1087 code = slow_stub(); |
| 1055 Handle<JSObject> holder = lookup->GetHolder<JSObject>(); | |
| 1056 Handle<Object> receiver = lookup->GetReceiver(); | |
| 1057 if (getter->IsJSFunction() && holder->HasFastProperties()) { | |
| 1058 Handle<JSFunction> function = Handle<JSFunction>::cast(getter); | |
| 1059 if (receiver->IsJSObject() || function->shared()->IsBuiltin() || | |
| 1060 !is_sloppy(function->shared()->language_mode())) { | |
| 1061 CallOptimization call_optimization(function); | |
| 1062 if (call_optimization.is_simple_api_call() && | |
| 1063 !call_optimization.IsCompatibleReceiver(receiver, holder)) { | |
| 1064 TRACE_GENERIC_IC(isolate(), "LoadIC", | |
| 1065 "incompatible receiver type"); | |
| 1066 code = slow_stub(); | |
| 1067 } | |
| 1068 } | |
| 1069 } | |
| 1070 } | 1088 } |
| 1071 } | 1089 } |
| 1072 if (code.is_null()) code = ComputeHandler(lookup); | 1090 if (code.is_null()) code = ComputeHandler(lookup); |
| 1073 } | 1091 } |
| 1074 | 1092 |
| 1075 PatchCache(lookup->name(), code); | 1093 PatchCache(lookup->name(), code); |
| 1076 TRACE_IC("LoadIC", lookup->name()); | 1094 TRACE_IC("LoadIC", lookup->name()); |
| 1077 } | 1095 } |
| 1078 | 1096 |
| 1079 | 1097 |
| (...skipping 2059 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3139 KeyedLoadICNexus nexus(vector, vector_slot); | 3157 KeyedLoadICNexus nexus(vector, vector_slot); |
| 3140 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); | 3158 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); |
| 3141 ic.UpdateState(receiver, key); | 3159 ic.UpdateState(receiver, key); |
| 3142 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); | 3160 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); |
| 3143 } | 3161 } |
| 3144 | 3162 |
| 3145 return *result; | 3163 return *result; |
| 3146 } | 3164 } |
| 3147 } // namespace internal | 3165 } // namespace internal |
| 3148 } // namespace v8 | 3166 } // namespace v8 |
| OLD | NEW |