Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(490)

Side by Side Diff: src/ic/ic.cc

Issue 1531583005: [IC] Fix "compatible receiver" checks hidden behind interceptors (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698