| 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 840 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 851 } | 851 } |
| 852 | 852 |
| 853 namespace { | 853 namespace { |
| 854 | 854 |
| 855 template <bool fill_array = true> | 855 template <bool fill_array = true> |
| 856 int InitPrototypeChecks(Isolate* isolate, Handle<Map> receiver_map, | 856 int InitPrototypeChecks(Isolate* isolate, Handle<Map> receiver_map, |
| 857 Handle<JSObject> holder, Handle<Name> name, | 857 Handle<JSObject> holder, Handle<Name> name, |
| 858 Handle<FixedArray> array, int first_index) { | 858 Handle<FixedArray> array, int first_index) { |
| 859 DCHECK(holder.is_null() || holder->HasFastProperties()); | 859 DCHECK(holder.is_null() || holder->HasFastProperties()); |
| 860 | 860 |
| 861 // The following kinds of receiver maps require custom handler compilation. | |
| 862 if (receiver_map->IsJSGlobalObjectMap()) { | |
| 863 return -1; | |
| 864 } | |
| 865 // We don't encode the requirement to check access rights because we already | 861 // We don't encode the requirement to check access rights because we already |
| 866 // passed the access check for current native context and the access | 862 // passed the access check for current native context and the access |
| 867 // can't be revoked. | 863 // can't be revoked. |
| 868 | 864 |
| 869 HandleScope scope(isolate); | 865 HandleScope scope(isolate); |
| 870 int checks_count = 0; | 866 int checks_count = 0; |
| 871 | 867 |
| 872 if (receiver_map->IsPrimitiveMap() || receiver_map->IsJSGlobalProxyMap()) { | 868 if (receiver_map->IsPrimitiveMap() || receiver_map->IsJSGlobalProxyMap()) { |
| 873 // The validity cell check for primitive and global proxy receivers does | 869 // The validity cell check for primitive and global proxy receivers does |
| 874 // not guarantee that certain native context ever had access to other | 870 // not guarantee that certain native context ever had access to other |
| 875 // native context. However, a handler created for one native context could | 871 // native context. However, a handler created for one native context could |
| 876 // be used in other native context through the megamorphic stub cache. | 872 // be used in other native context through the megamorphic stub cache. |
| 877 // So we record the original native context to which this handler | 873 // So we record the original native context to which this handler |
| 878 // corresponds. | 874 // corresponds. |
| 879 if (fill_array) { | 875 if (fill_array) { |
| 880 Handle<Context> native_context = isolate->native_context(); | 876 Handle<Context> native_context = isolate->native_context(); |
| 881 array->set(LoadHandler::kFirstPrototypeIndex + checks_count, | 877 array->set(LoadHandler::kFirstPrototypeIndex + checks_count, |
| 882 native_context->self_weak_cell()); | 878 native_context->self_weak_cell()); |
| 883 } | 879 } |
| 884 checks_count++; | 880 checks_count++; |
| 881 |
| 882 } else if (receiver_map->IsJSGlobalObjectMap()) { |
| 883 if (fill_array) { |
| 884 Handle<JSGlobalObject> global = isolate->global_object(); |
| 885 Handle<PropertyCell> cell = JSGlobalObject::EnsureEmptyPropertyCell( |
| 886 global, name, PropertyCellType::kInvalidated); |
| 887 DCHECK(cell->value()->IsTheHole(isolate)); |
| 888 Handle<WeakCell> weak_cell = isolate->factory()->NewWeakCell(cell); |
| 889 array->set(LoadHandler::kFirstPrototypeIndex + checks_count, *weak_cell); |
| 890 } |
| 891 checks_count++; |
| 885 } | 892 } |
| 886 | 893 |
| 887 // Create/count entries for each global or dictionary prototype appeared in | 894 // Create/count entries for each global or dictionary prototype appeared in |
| 888 // the prototype chain contains from receiver till holder. | 895 // the prototype chain contains from receiver till holder. |
| 889 PrototypeIterator::WhereToEnd end = name->IsPrivate() | 896 PrototypeIterator::WhereToEnd end = name->IsPrivate() |
| 890 ? PrototypeIterator::END_AT_NON_HIDDEN | 897 ? PrototypeIterator::END_AT_NON_HIDDEN |
| 891 : PrototypeIterator::END_AT_NULL; | 898 : PrototypeIterator::END_AT_NULL; |
| 892 for (PrototypeIterator iter(receiver_map, end); !iter.IsAtEnd(); | 899 for (PrototypeIterator iter(receiver_map, end); !iter.IsAtEnd(); |
| 893 iter.Advance()) { | 900 iter.Advance()) { |
| 894 Handle<JSObject> current = PrototypeIterator::GetCurrent<JSObject>(iter); | 901 Handle<JSObject> current = PrototypeIterator::GetCurrent<JSObject>(iter); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 935 | 942 |
| 936 } // namespace | 943 } // namespace |
| 937 | 944 |
| 938 Handle<Object> LoadIC::LoadFromPrototype(Handle<Map> receiver_map, | 945 Handle<Object> LoadIC::LoadFromPrototype(Handle<Map> receiver_map, |
| 939 Handle<JSObject> holder, | 946 Handle<JSObject> holder, |
| 940 Handle<Name> name, | 947 Handle<Name> name, |
| 941 Handle<Object> smi_handler) { | 948 Handle<Object> smi_handler) { |
| 942 int checks_count = | 949 int checks_count = |
| 943 GetPrototypeCheckCount(isolate(), receiver_map, holder, name); | 950 GetPrototypeCheckCount(isolate(), receiver_map, holder, name); |
| 944 DCHECK_LE(0, checks_count); | 951 DCHECK_LE(0, checks_count); |
| 945 DCHECK(!receiver_map->IsJSGlobalObjectMap()); | |
| 946 | 952 |
| 947 if (receiver_map->IsPrimitiveMap() || receiver_map->IsJSGlobalProxyMap()) { | 953 if (receiver_map->IsPrimitiveMap() || receiver_map->IsJSGlobalProxyMap()) { |
| 948 DCHECK(!receiver_map->is_dictionary_map()); | 954 DCHECK(!receiver_map->is_dictionary_map()); |
| 949 DCHECK_LE(1, checks_count); // For native context. | 955 DCHECK_LE(1, checks_count); // For native context. |
| 950 smi_handler = | 956 smi_handler = |
| 951 LoadHandler::EnableAccessCheckOnReceiver(isolate(), smi_handler); | 957 LoadHandler::EnableAccessCheckOnReceiver(isolate(), smi_handler); |
| 952 } else if (receiver_map->is_dictionary_map()) { | 958 } else if (receiver_map->is_dictionary_map() && |
| 959 !receiver_map->IsJSGlobalObjectMap()) { |
| 953 smi_handler = | 960 smi_handler = |
| 954 LoadHandler::EnableNegativeLookupOnReceiver(isolate(), smi_handler); | 961 LoadHandler::EnableNegativeLookupOnReceiver(isolate(), smi_handler); |
| 955 } | 962 } |
| 956 | 963 |
| 957 Handle<Cell> validity_cell = | 964 Handle<Cell> validity_cell = |
| 958 Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate()); | 965 Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate()); |
| 959 DCHECK(!validity_cell.is_null()); | 966 DCHECK(!validity_cell.is_null()); |
| 960 | 967 |
| 961 Handle<WeakCell> holder_cell = | 968 Handle<WeakCell> holder_cell = |
| 962 Map::GetOrCreatePrototypeWeakCell(holder, isolate()); | 969 Map::GetOrCreatePrototypeWeakCell(holder, isolate()); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 974 LoadHandler::kFirstPrototypeIndex); | 981 LoadHandler::kFirstPrototypeIndex); |
| 975 return handler_array; | 982 return handler_array; |
| 976 } | 983 } |
| 977 | 984 |
| 978 Handle<Object> LoadIC::LoadNonExistent(Handle<Map> receiver_map, | 985 Handle<Object> LoadIC::LoadNonExistent(Handle<Map> receiver_map, |
| 979 Handle<Name> name) { | 986 Handle<Name> name) { |
| 980 Handle<JSObject> holder; // null handle | 987 Handle<JSObject> holder; // null handle |
| 981 int checks_count = | 988 int checks_count = |
| 982 GetPrototypeCheckCount(isolate(), receiver_map, holder, name); | 989 GetPrototypeCheckCount(isolate(), receiver_map, holder, name); |
| 983 DCHECK_LE(0, checks_count); | 990 DCHECK_LE(0, checks_count); |
| 984 DCHECK(!receiver_map->IsJSGlobalObjectMap()); | |
| 985 | 991 |
| 986 Handle<Object> smi_handler = LoadHandler::LoadNonExistent( | 992 bool do_negative_lookup_on_receiver = |
| 987 isolate(), receiver_map->is_dictionary_map()); | 993 receiver_map->is_dictionary_map() && !receiver_map->IsJSGlobalObjectMap(); |
| 994 Handle<Object> smi_handler = |
| 995 LoadHandler::LoadNonExistent(isolate(), do_negative_lookup_on_receiver); |
| 988 | 996 |
| 989 if (receiver_map->IsPrimitiveMap() || receiver_map->IsJSGlobalProxyMap()) { | 997 if (receiver_map->IsPrimitiveMap() || receiver_map->IsJSGlobalProxyMap()) { |
| 990 DCHECK(!receiver_map->is_dictionary_map()); | 998 DCHECK(!receiver_map->is_dictionary_map()); |
| 991 DCHECK_LE(1, checks_count); // For native context. | 999 DCHECK_LE(1, checks_count); // For native context. |
| 992 smi_handler = | 1000 smi_handler = |
| 993 LoadHandler::EnableAccessCheckOnReceiver(isolate(), smi_handler); | 1001 LoadHandler::EnableAccessCheckOnReceiver(isolate(), smi_handler); |
| 994 } | 1002 } |
| 995 | 1003 |
| 996 Handle<Object> validity_cell = | 1004 Handle<Object> validity_cell = |
| 997 Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate()); | 1005 Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate()); |
| (...skipping 2248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3246 DCHECK_EQ(LookupIterator::INTERCEPTOR, it.state()); | 3254 DCHECK_EQ(LookupIterator::INTERCEPTOR, it.state()); |
| 3247 it.Next(); | 3255 it.Next(); |
| 3248 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, | 3256 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, |
| 3249 Object::GetProperty(&it)); | 3257 Object::GetProperty(&it)); |
| 3250 } | 3258 } |
| 3251 | 3259 |
| 3252 return *result; | 3260 return *result; |
| 3253 } | 3261 } |
| 3254 } // namespace internal | 3262 } // namespace internal |
| 3255 } // namespace v8 | 3263 } // namespace v8 |
| OLD | NEW |