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 <iostream> | 7 #include <iostream> |
8 | 8 |
9 #include "src/accessors.h" | 9 #include "src/accessors.h" |
10 #include "src/api-arguments-inl.h" | 10 #include "src/api-arguments-inl.h" |
(...skipping 850 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
861 if (receiver_map->IsJSGlobalObjectMap()) { | 861 if (receiver_map->IsJSGlobalObjectMap()) { |
862 return -1; | 862 return -1; |
863 } | 863 } |
864 // We don't encode the requirement to check access rights because we already | 864 // We don't encode the requirement to check access rights because we already |
865 // passed the access check for current native context and the access | 865 // passed the access check for current native context and the access |
866 // can't be revoked. | 866 // can't be revoked. |
867 | 867 |
868 HandleScope scope(isolate); | 868 HandleScope scope(isolate); |
869 int checks_count = 0; | 869 int checks_count = 0; |
870 | 870 |
| 871 if (receiver_map->IsPrimitiveMap() || receiver_map->IsJSGlobalProxyMap()) { |
| 872 // The validity cell check for primitive and global proxy receivers does |
| 873 // not guarantee that certain native context ever had access to other |
| 874 // native context. However, a handler created for one native context could |
| 875 // be used in other native context through the megamorphic stub cache. |
| 876 // So we record the original native context to which this handler |
| 877 // corresponds. |
| 878 if (fill_array) { |
| 879 Handle<Context> native_context = isolate->native_context(); |
| 880 array->set(LoadHandler::kFirstPrototypeIndex + checks_count, |
| 881 native_context->self_weak_cell()); |
| 882 } |
| 883 checks_count++; |
| 884 } |
| 885 |
871 // Create/count entries for each global or dictionary prototype appeared in | 886 // Create/count entries for each global or dictionary prototype appeared in |
872 // the prototype chain contains from receiver till holder. | 887 // the prototype chain contains from receiver till holder. |
873 for (PrototypeIterator iter(receiver_map); !iter.IsAtEnd(); iter.Advance()) { | 888 for (PrototypeIterator iter(receiver_map); !iter.IsAtEnd(); iter.Advance()) { |
874 Handle<JSObject> current = PrototypeIterator::GetCurrent<JSObject>(iter); | 889 Handle<JSObject> current = PrototypeIterator::GetCurrent<JSObject>(iter); |
875 if (holder.is_identical_to(current)) break; | 890 if (holder.is_identical_to(current)) break; |
876 Handle<Map> current_map(current->map(), isolate); | 891 Handle<Map> current_map(current->map(), isolate); |
877 | 892 |
878 if (current_map->IsJSGlobalObjectMap()) { | 893 if (current_map->IsJSGlobalObjectMap()) { |
879 if (fill_array) { | 894 if (fill_array) { |
880 Handle<JSGlobalObject> global = Handle<JSGlobalObject>::cast(current); | 895 Handle<JSGlobalObject> global = Handle<JSGlobalObject>::cast(current); |
(...skipping 29 matching lines...) Expand all Loading... |
910 return InitPrototypeChecks<false>(isolate(), receiver_map, holder, | 925 return InitPrototypeChecks<false>(isolate(), receiver_map, holder, |
911 Handle<FixedArray>(), Handle<Name>()); | 926 Handle<FixedArray>(), Handle<Name>()); |
912 } | 927 } |
913 | 928 |
914 Handle<Object> LoadIC::LoadFromPrototype(Handle<Map> receiver_map, | 929 Handle<Object> LoadIC::LoadFromPrototype(Handle<Map> receiver_map, |
915 Handle<JSObject> holder, | 930 Handle<JSObject> holder, |
916 Handle<Name> name, | 931 Handle<Name> name, |
917 Handle<Object> smi_handler) { | 932 Handle<Object> smi_handler) { |
918 int checks_count = GetPrototypeCheckCount(receiver_map, holder); | 933 int checks_count = GetPrototypeCheckCount(receiver_map, holder); |
919 DCHECK_LE(0, checks_count); | 934 DCHECK_LE(0, checks_count); |
| 935 DCHECK(!receiver_map->IsJSGlobalObjectMap()); |
920 | 936 |
921 if (receiver_map->IsJSGlobalObjectMap()) { | 937 if (receiver_map->IsPrimitiveMap() || receiver_map->IsJSGlobalProxyMap()) { |
922 UNREACHABLE(); | 938 DCHECK(!receiver_map->is_dictionary_map()); |
| 939 DCHECK_LE(1, checks_count); // For native context. |
| 940 smi_handler = |
| 941 LoadHandler::EnableAccessCheckOnReceiver(isolate(), smi_handler); |
923 } else if (receiver_map->is_dictionary_map()) { | 942 } else if (receiver_map->is_dictionary_map()) { |
924 smi_handler = | 943 smi_handler = |
925 LoadHandler::EnableNegativeLookupOnReceiver(isolate(), smi_handler); | 944 LoadHandler::EnableNegativeLookupOnReceiver(isolate(), smi_handler); |
926 } | 945 } |
927 | 946 |
928 Handle<Cell> validity_cell = | 947 Handle<Cell> validity_cell = |
929 Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate()); | 948 Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate()); |
930 DCHECK(!validity_cell.is_null()); | 949 DCHECK(!validity_cell.is_null()); |
931 | 950 |
932 Handle<WeakCell> holder_cell = | 951 Handle<WeakCell> holder_cell = |
(...skipping 16 matching lines...) Expand all Loading... |
949 Handle<Object> LoadIC::LoadNonExistent(Handle<Map> receiver_map, | 968 Handle<Object> LoadIC::LoadNonExistent(Handle<Map> receiver_map, |
950 Handle<Name> name) { | 969 Handle<Name> name) { |
951 Handle<JSObject> holder; // null handle | 970 Handle<JSObject> holder; // null handle |
952 int checks_count = GetPrototypeCheckCount(receiver_map, holder); | 971 int checks_count = GetPrototypeCheckCount(receiver_map, holder); |
953 DCHECK_LE(0, checks_count); | 972 DCHECK_LE(0, checks_count); |
954 DCHECK(!receiver_map->IsJSGlobalObjectMap()); | 973 DCHECK(!receiver_map->IsJSGlobalObjectMap()); |
955 | 974 |
956 Handle<Object> smi_handler = LoadHandler::LoadNonExistent( | 975 Handle<Object> smi_handler = LoadHandler::LoadNonExistent( |
957 isolate(), receiver_map->is_dictionary_map()); | 976 isolate(), receiver_map->is_dictionary_map()); |
958 | 977 |
| 978 if (receiver_map->IsPrimitiveMap() || receiver_map->IsJSGlobalProxyMap()) { |
| 979 DCHECK(!receiver_map->is_dictionary_map()); |
| 980 DCHECK_LE(1, checks_count); // For native context. |
| 981 smi_handler = |
| 982 LoadHandler::EnableAccessCheckOnReceiver(isolate(), smi_handler); |
| 983 } |
| 984 |
959 Handle<Object> validity_cell = | 985 Handle<Object> validity_cell = |
960 Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate()); | 986 Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate()); |
961 if (validity_cell.is_null()) { | 987 if (validity_cell.is_null()) { |
962 // This must be a case when receiver's prototype is null. | 988 // This must be a case when receiver's prototype is null. |
963 DCHECK_EQ(*isolate()->factory()->null_value(), | 989 DCHECK_EQ(*isolate()->factory()->null_value(), |
964 receiver_map->GetPrototypeChainRootMap(isolate())->prototype()); | 990 receiver_map->GetPrototypeChainRootMap(isolate())->prototype()); |
965 DCHECK_EQ(0, checks_count); | 991 DCHECK_EQ(0, checks_count); |
966 validity_cell = handle(Smi::FromInt(0), isolate()); | 992 validity_cell = handle(Smi::FromInt(0), isolate()); |
967 } | 993 } |
968 | 994 |
(...skipping 2203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3172 DCHECK_EQ(LookupIterator::INTERCEPTOR, it.state()); | 3198 DCHECK_EQ(LookupIterator::INTERCEPTOR, it.state()); |
3173 it.Next(); | 3199 it.Next(); |
3174 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, | 3200 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, |
3175 Object::GetProperty(&it)); | 3201 Object::GetProperty(&it)); |
3176 } | 3202 } |
3177 | 3203 |
3178 return *result; | 3204 return *result; |
3179 } | 3205 } |
3180 } // namespace internal | 3206 } // namespace internal |
3181 } // namespace v8 | 3207 } // namespace v8 |
OLD | NEW |