| 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/v8.h" | 5 #include "src/v8.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/codegen.h" | 10 #include "src/codegen.h" |
| (...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 331 Handle<Object> object, | 331 Handle<Object> object, |
| 332 Handle<Object> key) { | 332 Handle<Object> key) { |
| 333 HandleScope scope(isolate()); | 333 HandleScope scope(isolate()); |
| 334 Handle<Object> args[2] = { key, object }; | 334 Handle<Object> args[2] = { key, object }; |
| 335 Handle<Object> error = isolate()->factory()->NewTypeError( | 335 Handle<Object> error = isolate()->factory()->NewTypeError( |
| 336 type, HandleVector(args, 2)); | 336 type, HandleVector(args, 2)); |
| 337 return isolate()->Throw<Object>(error); | 337 return isolate()->Throw<Object>(error); |
| 338 } | 338 } |
| 339 | 339 |
| 340 | 340 |
| 341 MaybeHandle<Object> IC::ReferenceError(const char* type, Handle<String> name) { | 341 MaybeHandle<Object> IC::ReferenceError(const char* type, Handle<Name> name) { |
| 342 HandleScope scope(isolate()); | 342 HandleScope scope(isolate()); |
| 343 Handle<Object> error = isolate()->factory()->NewReferenceError( | 343 Handle<Object> error = isolate()->factory()->NewReferenceError( |
| 344 type, HandleVector(&name, 1)); | 344 type, HandleVector(&name, 1)); |
| 345 return isolate()->Throw<Object>(error); | 345 return isolate()->Throw<Object>(error); |
| 346 } | 346 } |
| 347 | 347 |
| 348 | 348 |
| 349 static void ComputeTypeInfoCountDelta(IC::State old_state, IC::State new_state, | 349 static void ComputeTypeInfoCountDelta(IC::State old_state, IC::State new_state, |
| 350 int* polymorphic_delta, | 350 int* polymorphic_delta, |
| 351 int* generic_delta) { | 351 int* generic_delta) { |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 583 | 583 |
| 584 static bool MigrateDeprecated(Handle<Object> object) { | 584 static bool MigrateDeprecated(Handle<Object> object) { |
| 585 if (!object->IsJSObject()) return false; | 585 if (!object->IsJSObject()) return false; |
| 586 Handle<JSObject> receiver = Handle<JSObject>::cast(object); | 586 Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
| 587 if (!receiver->map()->is_deprecated()) return false; | 587 if (!receiver->map()->is_deprecated()) return false; |
| 588 JSObject::MigrateInstance(Handle<JSObject>::cast(object)); | 588 JSObject::MigrateInstance(Handle<JSObject>::cast(object)); |
| 589 return true; | 589 return true; |
| 590 } | 590 } |
| 591 | 591 |
| 592 | 592 |
| 593 MaybeHandle<Object> LoadIC::Load(Handle<Object> object, Handle<String> name) { | 593 MaybeHandle<Object> LoadIC::Load(Handle<Object> object, Handle<Name> name) { |
| 594 // If the object is undefined or null it's illegal to try to get any | 594 // If the object is undefined or null it's illegal to try to get any |
| 595 // of its properties; throw a TypeError in that case. | 595 // of its properties; throw a TypeError in that case. |
| 596 if (object->IsUndefined() || object->IsNull()) { | 596 if (object->IsUndefined() || object->IsNull()) { |
| 597 return TypeError("non_object_property_load", object, name); | 597 return TypeError("non_object_property_load", object, name); |
| 598 } | 598 } |
| 599 | 599 |
| 600 // Check if the name is trivially convertible to an index and get | 600 // Check if the name is trivially convertible to an index and get |
| 601 // the element or char if so. | 601 // the element or char if so. |
| 602 uint32_t index; | 602 uint32_t index; |
| 603 if (kind() == Code::KEYED_LOAD_IC && name->AsArrayIndex(&index)) { | 603 if (kind() == Code::KEYED_LOAD_IC && name->AsArrayIndex(&index)) { |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 653 if (!receiver_maps->at(current).is_null() && | 653 if (!receiver_maps->at(current).is_null() && |
| 654 receiver_maps->at(current).is_identical_to(new_receiver_map)) { | 654 receiver_maps->at(current).is_identical_to(new_receiver_map)) { |
| 655 return false; | 655 return false; |
| 656 } | 656 } |
| 657 } | 657 } |
| 658 receiver_maps->Add(new_receiver_map); | 658 receiver_maps->Add(new_receiver_map); |
| 659 return true; | 659 return true; |
| 660 } | 660 } |
| 661 | 661 |
| 662 | 662 |
| 663 bool IC::UpdatePolymorphicIC(Handle<String> name, Handle<Code> code) { | 663 bool IC::UpdatePolymorphicIC(Handle<Name> name, Handle<Code> code) { |
| 664 if (!code->is_handler()) return false; | 664 if (!code->is_handler()) return false; |
| 665 if (target()->is_keyed_stub() && state() != PROTOTYPE_FAILURE) return false; | 665 if (target()->is_keyed_stub() && state() != PROTOTYPE_FAILURE) return false; |
| 666 Handle<HeapType> type = receiver_type(); | 666 Handle<HeapType> type = receiver_type(); |
| 667 TypeHandleList types; | 667 TypeHandleList types; |
| 668 CodeHandleList handlers; | 668 CodeHandleList handlers; |
| 669 | 669 |
| 670 TargetTypes(&types); | 670 TargetTypes(&types); |
| 671 int number_of_types = types.length(); | 671 int number_of_types = types.length(); |
| 672 int deprecated_types = 0; | 672 int deprecated_types = 0; |
| 673 int handler_to_overwrite = -1; | 673 int handler_to_overwrite = -1; |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 759 | 759 |
| 760 | 760 |
| 761 template | 761 template |
| 762 Type* IC::MapToType<Type>(Handle<Map> map, Zone* zone); | 762 Type* IC::MapToType<Type>(Handle<Map> map, Zone* zone); |
| 763 | 763 |
| 764 | 764 |
| 765 template | 765 template |
| 766 Handle<HeapType> IC::MapToType<HeapType>(Handle<Map> map, Isolate* region); | 766 Handle<HeapType> IC::MapToType<HeapType>(Handle<Map> map, Isolate* region); |
| 767 | 767 |
| 768 | 768 |
| 769 void IC::UpdateMonomorphicIC(Handle<Code> handler, Handle<String> name) { | 769 void IC::UpdateMonomorphicIC(Handle<Code> handler, Handle<Name> name) { |
| 770 DCHECK(handler->is_handler()); | 770 DCHECK(handler->is_handler()); |
| 771 Handle<Code> ic = PropertyICCompiler::ComputeMonomorphic( | 771 Handle<Code> ic = PropertyICCompiler::ComputeMonomorphic( |
| 772 kind(), name, receiver_type(), handler, extra_ic_state()); | 772 kind(), name, receiver_type(), handler, extra_ic_state()); |
| 773 set_target(*ic); | 773 set_target(*ic); |
| 774 } | 774 } |
| 775 | 775 |
| 776 | 776 |
| 777 void IC::CopyICToMegamorphicCache(Handle<String> name) { | 777 void IC::CopyICToMegamorphicCache(Handle<Name> name) { |
| 778 TypeHandleList types; | 778 TypeHandleList types; |
| 779 CodeHandleList handlers; | 779 CodeHandleList handlers; |
| 780 TargetTypes(&types); | 780 TargetTypes(&types); |
| 781 if (!target()->FindHandlers(&handlers, types.length())) return; | 781 if (!target()->FindHandlers(&handlers, types.length())) return; |
| 782 for (int i = 0; i < types.length(); i++) { | 782 for (int i = 0; i < types.length(); i++) { |
| 783 UpdateMegamorphicCache(*types.at(i), *name, *handlers.at(i)); | 783 UpdateMegamorphicCache(*types.at(i), *name, *handlers.at(i)); |
| 784 } | 784 } |
| 785 } | 785 } |
| 786 | 786 |
| 787 | 787 |
| 788 bool IC::IsTransitionOfMonomorphicTarget(Map* source_map, Map* target_map) { | 788 bool IC::IsTransitionOfMonomorphicTarget(Map* source_map, Map* target_map) { |
| 789 if (source_map == NULL) return true; | 789 if (source_map == NULL) return true; |
| 790 if (target_map == NULL) return false; | 790 if (target_map == NULL) return false; |
| 791 ElementsKind target_elements_kind = target_map->elements_kind(); | 791 ElementsKind target_elements_kind = target_map->elements_kind(); |
| 792 bool more_general_transition = | 792 bool more_general_transition = |
| 793 IsMoreGeneralElementsKindTransition( | 793 IsMoreGeneralElementsKindTransition( |
| 794 source_map->elements_kind(), target_elements_kind); | 794 source_map->elements_kind(), target_elements_kind); |
| 795 Map* transitioned_map = more_general_transition | 795 Map* transitioned_map = more_general_transition |
| 796 ? source_map->LookupElementsTransitionMap(target_elements_kind) | 796 ? source_map->LookupElementsTransitionMap(target_elements_kind) |
| 797 : NULL; | 797 : NULL; |
| 798 | 798 |
| 799 return transitioned_map == target_map; | 799 return transitioned_map == target_map; |
| 800 } | 800 } |
| 801 | 801 |
| 802 | 802 |
| 803 void IC::PatchCache(Handle<String> name, Handle<Code> code) { | 803 void IC::PatchCache(Handle<Name> name, Handle<Code> code) { |
| 804 switch (state()) { | 804 switch (state()) { |
| 805 case UNINITIALIZED: | 805 case UNINITIALIZED: |
| 806 case PREMONOMORPHIC: | 806 case PREMONOMORPHIC: |
| 807 UpdateMonomorphicIC(code, name); | 807 UpdateMonomorphicIC(code, name); |
| 808 break; | 808 break; |
| 809 case PROTOTYPE_FAILURE: | 809 case PROTOTYPE_FAILURE: |
| 810 case MONOMORPHIC: | 810 case MONOMORPHIC: |
| 811 case POLYMORPHIC: | 811 case POLYMORPHIC: |
| 812 if (!target()->is_keyed_stub() || state() == PROTOTYPE_FAILURE) { | 812 if (!target()->is_keyed_stub() || state() == PROTOTYPE_FAILURE) { |
| 813 if (UpdatePolymorphicIC(name, code)) break; | 813 if (UpdatePolymorphicIC(name, code)) break; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 866 } | 866 } |
| 867 | 867 |
| 868 | 868 |
| 869 Handle<Code> LoadIC::SimpleFieldLoad(FieldIndex index) { | 869 Handle<Code> LoadIC::SimpleFieldLoad(FieldIndex index) { |
| 870 LoadFieldStub stub(isolate(), index); | 870 LoadFieldStub stub(isolate(), index); |
| 871 return stub.GetCode(); | 871 return stub.GetCode(); |
| 872 } | 872 } |
| 873 | 873 |
| 874 | 874 |
| 875 void LoadIC::UpdateCaches(LookupIterator* lookup, Handle<Object> object, | 875 void LoadIC::UpdateCaches(LookupIterator* lookup, Handle<Object> object, |
| 876 Handle<String> name) { | 876 Handle<Name> name) { |
| 877 if (state() == UNINITIALIZED) { | 877 if (state() == UNINITIALIZED) { |
| 878 // This is the first time we execute this inline cache. | 878 // This is the first time we execute this inline cache. |
| 879 // Set the target to the pre monomorphic stub to delay | 879 // Set the target to the pre monomorphic stub to delay |
| 880 // setting the monomorphic state. | 880 // setting the monomorphic state. |
| 881 set_target(*pre_monomorphic_stub()); | 881 set_target(*pre_monomorphic_stub()); |
| 882 TRACE_IC("LoadIC", name); | 882 TRACE_IC("LoadIC", name); |
| 883 return; | 883 return; |
| 884 } | 884 } |
| 885 | 885 |
| 886 Handle<Code> code; | 886 Handle<Code> code; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 906 | 906 |
| 907 | 907 |
| 908 void IC::UpdateMegamorphicCache(HeapType* type, Name* name, Code* code) { | 908 void IC::UpdateMegamorphicCache(HeapType* type, Name* name, Code* code) { |
| 909 if (kind() == Code::KEYED_LOAD_IC || kind() == Code::KEYED_STORE_IC) return; | 909 if (kind() == Code::KEYED_LOAD_IC || kind() == Code::KEYED_STORE_IC) return; |
| 910 Map* map = *TypeToMap(type, isolate()); | 910 Map* map = *TypeToMap(type, isolate()); |
| 911 isolate()->stub_cache()->Set(name, map, code); | 911 isolate()->stub_cache()->Set(name, map, code); |
| 912 } | 912 } |
| 913 | 913 |
| 914 | 914 |
| 915 Handle<Code> IC::ComputeHandler(LookupIterator* lookup, Handle<Object> object, | 915 Handle<Code> IC::ComputeHandler(LookupIterator* lookup, Handle<Object> object, |
| 916 Handle<String> name, Handle<Object> value) { | 916 Handle<Name> name, Handle<Object> value) { |
| 917 bool receiver_is_holder = | 917 bool receiver_is_holder = |
| 918 object.is_identical_to(lookup->GetHolder<JSObject>()); | 918 object.is_identical_to(lookup->GetHolder<JSObject>()); |
| 919 CacheHolderFlag flag; | 919 CacheHolderFlag flag; |
| 920 Handle<Map> stub_holder_map = IC::GetHandlerCacheHolder( | 920 Handle<Map> stub_holder_map = IC::GetHandlerCacheHolder( |
| 921 *receiver_type(), receiver_is_holder, isolate(), &flag); | 921 *receiver_type(), receiver_is_holder, isolate(), &flag); |
| 922 | 922 |
| 923 Handle<Code> code = PropertyHandlerCompiler::Find( | 923 Handle<Code> code = PropertyHandlerCompiler::Find( |
| 924 name, stub_holder_map, kind(), flag, | 924 name, stub_holder_map, kind(), flag, |
| 925 lookup->holder_map()->is_dictionary_map() ? Code::NORMAL : Code::FAST); | 925 lookup->holder_map()->is_dictionary_map() ? Code::NORMAL : Code::FAST); |
| 926 // Use the cached value if it exists, and if it is different from the | 926 // Use the cached value if it exists, and if it is different from the |
| (...skipping 23 matching lines...) Expand all Loading... |
| 950 | 950 |
| 951 if (code->type() != Code::NORMAL) { | 951 if (code->type() != Code::NORMAL) { |
| 952 Map::UpdateCodeCache(stub_holder_map, name, code); | 952 Map::UpdateCodeCache(stub_holder_map, name, code); |
| 953 } | 953 } |
| 954 | 954 |
| 955 return code; | 955 return code; |
| 956 } | 956 } |
| 957 | 957 |
| 958 | 958 |
| 959 Handle<Code> IC::ComputeStoreHandler(LookupResult* lookup, | 959 Handle<Code> IC::ComputeStoreHandler(LookupResult* lookup, |
| 960 Handle<Object> object, Handle<String> name, | 960 Handle<Object> object, Handle<Name> name, |
| 961 Handle<Object> value) { | 961 Handle<Object> value) { |
| 962 bool receiver_is_holder = lookup->ReceiverIsHolder(object); | 962 bool receiver_is_holder = lookup->ReceiverIsHolder(object); |
| 963 CacheHolderFlag flag; | 963 CacheHolderFlag flag; |
| 964 Handle<Map> stub_holder_map = IC::GetHandlerCacheHolder( | 964 Handle<Map> stub_holder_map = IC::GetHandlerCacheHolder( |
| 965 *receiver_type(), receiver_is_holder, isolate(), &flag); | 965 *receiver_type(), receiver_is_holder, isolate(), &flag); |
| 966 | 966 |
| 967 Handle<Code> code = PropertyHandlerCompiler::Find( | 967 Handle<Code> code = PropertyHandlerCompiler::Find( |
| 968 name, stub_holder_map, handler_kind(), flag, | 968 name, stub_holder_map, handler_kind(), flag, |
| 969 lookup->holder()->HasFastProperties() ? Code::FAST : Code::NORMAL); | 969 lookup->holder()->HasFastProperties() ? Code::FAST : Code::NORMAL); |
| 970 // Use the cached value if it exists, and if it is different from the | 970 // Use the cached value if it exists, and if it is different from the |
| (...skipping 23 matching lines...) Expand all Loading... |
| 994 | 994 |
| 995 if (code->type() != Code::NORMAL) { | 995 if (code->type() != Code::NORMAL) { |
| 996 Map::UpdateCodeCache(stub_holder_map, name, code); | 996 Map::UpdateCodeCache(stub_holder_map, name, code); |
| 997 } | 997 } |
| 998 | 998 |
| 999 return code; | 999 return code; |
| 1000 } | 1000 } |
| 1001 | 1001 |
| 1002 | 1002 |
| 1003 Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup, | 1003 Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup, |
| 1004 Handle<Object> object, Handle<String> name, | 1004 Handle<Object> object, Handle<Name> name, |
| 1005 Handle<Object> unused, | 1005 Handle<Object> unused, |
| 1006 CacheHolderFlag cache_holder) { | 1006 CacheHolderFlag cache_holder) { |
| 1007 if (object->IsString() && | 1007 if (object->IsString() && |
| 1008 String::Equals(isolate()->factory()->length_string(), name)) { | 1008 Name::Equals(isolate()->factory()->length_string(), name)) { |
| 1009 FieldIndex index = FieldIndex::ForInObjectOffset(String::kLengthOffset); | 1009 FieldIndex index = FieldIndex::ForInObjectOffset(String::kLengthOffset); |
| 1010 return SimpleFieldLoad(index); | 1010 return SimpleFieldLoad(index); |
| 1011 } | 1011 } |
| 1012 | 1012 |
| 1013 if (object->IsStringWrapper() && | 1013 if (object->IsStringWrapper() && |
| 1014 String::Equals(isolate()->factory()->length_string(), name)) { | 1014 Name::Equals(isolate()->factory()->length_string(), name)) { |
| 1015 StringLengthStub string_length_stub(isolate()); | 1015 StringLengthStub string_length_stub(isolate()); |
| 1016 return string_length_stub.GetCode(); | 1016 return string_length_stub.GetCode(); |
| 1017 } | 1017 } |
| 1018 | 1018 |
| 1019 // Use specialized code for getting prototype of functions. | 1019 // Use specialized code for getting prototype of functions. |
| 1020 if (object->IsJSFunction() && | 1020 if (object->IsJSFunction() && |
| 1021 String::Equals(isolate()->factory()->prototype_string(), name) && | 1021 Name::Equals(isolate()->factory()->prototype_string(), name) && |
| 1022 Handle<JSFunction>::cast(object)->should_have_prototype() && | 1022 Handle<JSFunction>::cast(object)->should_have_prototype() && |
| 1023 !Handle<JSFunction>::cast(object)->map()->has_non_instance_prototype()) { | 1023 !Handle<JSFunction>::cast(object)->map()->has_non_instance_prototype()) { |
| 1024 Handle<Code> stub; | 1024 Handle<Code> stub; |
| 1025 FunctionPrototypeStub function_prototype_stub(isolate()); | 1025 FunctionPrototypeStub function_prototype_stub(isolate()); |
| 1026 return function_prototype_stub.GetCode(); | 1026 return function_prototype_stub.GetCode(); |
| 1027 } | 1027 } |
| 1028 | 1028 |
| 1029 Handle<HeapType> type = receiver_type(); | 1029 Handle<HeapType> type = receiver_type(); |
| 1030 Handle<JSObject> holder = lookup->GetHolder<JSObject>(); | 1030 Handle<JSObject> holder = lookup->GetHolder<JSObject>(); |
| 1031 bool receiver_is_holder = object.is_identical_to(holder); | 1031 bool receiver_is_holder = object.is_identical_to(holder); |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1230 return result; | 1230 return result; |
| 1231 } | 1231 } |
| 1232 | 1232 |
| 1233 Handle<Object> load_handle; | 1233 Handle<Object> load_handle; |
| 1234 Handle<Code> stub = generic_stub(); | 1234 Handle<Code> stub = generic_stub(); |
| 1235 | 1235 |
| 1236 // Check for non-string values that can be converted into an | 1236 // Check for non-string values that can be converted into an |
| 1237 // internalized string directly or is representable as a smi. | 1237 // internalized string directly or is representable as a smi. |
| 1238 key = TryConvertKey(key, isolate()); | 1238 key = TryConvertKey(key, isolate()); |
| 1239 | 1239 |
| 1240 if (key->IsInternalizedString()) { | 1240 if (key->IsInternalizedString() || key->IsSymbol()) { |
| 1241 ASSIGN_RETURN_ON_EXCEPTION( | 1241 ASSIGN_RETURN_ON_EXCEPTION( |
| 1242 isolate(), | 1242 isolate(), |
| 1243 load_handle, | 1243 load_handle, |
| 1244 LoadIC::Load(object, Handle<String>::cast(key)), | 1244 LoadIC::Load(object, Handle<Name>::cast(key)), |
| 1245 Object); | 1245 Object); |
| 1246 } else if (FLAG_use_ic && !object->IsAccessCheckNeeded()) { | 1246 } else if (FLAG_use_ic && !object->IsAccessCheckNeeded()) { |
| 1247 if (object->IsString() && key->IsNumber()) { | 1247 if (object->IsString() && key->IsNumber()) { |
| 1248 if (state() == UNINITIALIZED) stub = string_stub(); | 1248 if (state() == UNINITIALIZED) stub = string_stub(); |
| 1249 } else if (object->IsJSObject()) { | 1249 } else if (object->IsJSObject()) { |
| 1250 Handle<JSObject> receiver = Handle<JSObject>::cast(object); | 1250 Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
| 1251 if (receiver->elements()->map() == | 1251 if (receiver->elements()->map() == |
| 1252 isolate()->heap()->sloppy_arguments_elements_map()) { | 1252 isolate()->heap()->sloppy_arguments_elements_map()) { |
| 1253 stub = sloppy_arguments_stub(); | 1253 stub = sloppy_arguments_stub(); |
| 1254 } else if (receiver->HasIndexedInterceptor()) { | 1254 } else if (receiver->HasIndexedInterceptor()) { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1273 Handle<Object> result; | 1273 Handle<Object> result; |
| 1274 ASSIGN_RETURN_ON_EXCEPTION( | 1274 ASSIGN_RETURN_ON_EXCEPTION( |
| 1275 isolate(), | 1275 isolate(), |
| 1276 result, | 1276 result, |
| 1277 Runtime::GetObjectProperty(isolate(), object, key), | 1277 Runtime::GetObjectProperty(isolate(), object, key), |
| 1278 Object); | 1278 Object); |
| 1279 return result; | 1279 return result; |
| 1280 } | 1280 } |
| 1281 | 1281 |
| 1282 | 1282 |
| 1283 static bool LookupForWrite(Handle<Object> object, Handle<String> name, | 1283 static bool LookupForWrite(Handle<Object> object, Handle<Name> name, |
| 1284 Handle<Object> value, LookupResult* lookup, IC* ic) { | 1284 Handle<Object> value, LookupResult* lookup, IC* ic) { |
| 1285 // Disable ICs for non-JSObjects for now. | 1285 // Disable ICs for non-JSObjects for now. |
| 1286 if (!object->IsJSObject()) return false; | 1286 if (!object->IsJSObject()) return false; |
| 1287 Handle<JSObject> receiver = Handle<JSObject>::cast(object); | 1287 Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
| 1288 | 1288 |
| 1289 Handle<JSObject> holder = receiver; | 1289 Handle<JSObject> holder = receiver; |
| 1290 receiver->Lookup(name, lookup); | 1290 receiver->Lookup(name, lookup); |
| 1291 if (lookup->IsFound()) { | 1291 if (lookup->IsFound()) { |
| 1292 if (lookup->IsInterceptor() && !HasInterceptorSetter(lookup->holder())) { | 1292 if (lookup->IsInterceptor() && !HasInterceptorSetter(lookup->holder())) { |
| 1293 receiver->LookupOwnRealNamedProperty(name, lookup); | 1293 receiver->LookupOwnRealNamedProperty(name, lookup); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1341 if (!ic->IsNameCompatibleWithPrototypeFailure(name)) return false; | 1341 if (!ic->IsNameCompatibleWithPrototypeFailure(name)) return false; |
| 1342 ic->MarkPrototypeFailure(name); | 1342 ic->MarkPrototypeFailure(name); |
| 1343 return true; | 1343 return true; |
| 1344 } | 1344 } |
| 1345 | 1345 |
| 1346 return true; | 1346 return true; |
| 1347 } | 1347 } |
| 1348 | 1348 |
| 1349 | 1349 |
| 1350 MaybeHandle<Object> StoreIC::Store(Handle<Object> object, | 1350 MaybeHandle<Object> StoreIC::Store(Handle<Object> object, |
| 1351 Handle<String> name, | 1351 Handle<Name> name, |
| 1352 Handle<Object> value, | 1352 Handle<Object> value, |
| 1353 JSReceiver::StoreFromKeyed store_mode) { | 1353 JSReceiver::StoreFromKeyed store_mode) { |
| 1354 // TODO(verwaest): Let SetProperty do the migration, since storing a property | 1354 // TODO(verwaest): Let SetProperty do the migration, since storing a property |
| 1355 // might deprecate the current map again, if value does not fit. | 1355 // might deprecate the current map again, if value does not fit. |
| 1356 if (MigrateDeprecated(object) || object->IsJSProxy()) { | 1356 if (MigrateDeprecated(object) || object->IsJSProxy()) { |
| 1357 Handle<Object> result; | 1357 Handle<Object> result; |
| 1358 ASSIGN_RETURN_ON_EXCEPTION( | 1358 ASSIGN_RETURN_ON_EXCEPTION( |
| 1359 isolate(), result, | 1359 isolate(), result, |
| 1360 Object::SetProperty(object, name, value, strict_mode()), Object); | 1360 Object::SetProperty(object, name, value, strict_mode()), Object); |
| 1361 return result; | 1361 return result; |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1466 | 1466 |
| 1467 Handle<Code> StoreIC::pre_monomorphic_stub(Isolate* isolate, | 1467 Handle<Code> StoreIC::pre_monomorphic_stub(Isolate* isolate, |
| 1468 StrictMode strict_mode) { | 1468 StrictMode strict_mode) { |
| 1469 ExtraICState state = ComputeExtraICState(strict_mode); | 1469 ExtraICState state = ComputeExtraICState(strict_mode); |
| 1470 return PropertyICCompiler::ComputeStore(isolate, PREMONOMORPHIC, state); | 1470 return PropertyICCompiler::ComputeStore(isolate, PREMONOMORPHIC, state); |
| 1471 } | 1471 } |
| 1472 | 1472 |
| 1473 | 1473 |
| 1474 void StoreIC::UpdateCaches(LookupResult* lookup, | 1474 void StoreIC::UpdateCaches(LookupResult* lookup, |
| 1475 Handle<JSObject> receiver, | 1475 Handle<JSObject> receiver, |
| 1476 Handle<String> name, | 1476 Handle<Name> name, |
| 1477 Handle<Object> value) { | 1477 Handle<Object> value) { |
| 1478 DCHECK(lookup->IsFound()); | 1478 DCHECK(lookup->IsFound()); |
| 1479 | 1479 |
| 1480 // These are not cacheable, so we never see such LookupResults here. | 1480 // These are not cacheable, so we never see such LookupResults here. |
| 1481 DCHECK(!lookup->IsHandler()); | 1481 DCHECK(!lookup->IsHandler()); |
| 1482 | 1482 |
| 1483 Handle<Code> code = ComputeStoreHandler(lookup, receiver, name, value); | 1483 Handle<Code> code = ComputeStoreHandler(lookup, receiver, name, value); |
| 1484 | 1484 |
| 1485 PatchCache(name, code); | 1485 PatchCache(name, code); |
| 1486 TRACE_IC("StoreIC", name); | 1486 TRACE_IC("StoreIC", name); |
| 1487 } | 1487 } |
| 1488 | 1488 |
| 1489 | 1489 |
| 1490 Handle<Code> StoreIC::CompileStoreHandler(LookupResult* lookup, | 1490 Handle<Code> StoreIC::CompileStoreHandler(LookupResult* lookup, |
| 1491 Handle<Object> object, | 1491 Handle<Object> object, |
| 1492 Handle<String> name, | 1492 Handle<Name> name, |
| 1493 Handle<Object> value, | 1493 Handle<Object> value, |
| 1494 CacheHolderFlag cache_holder) { | 1494 CacheHolderFlag cache_holder) { |
| 1495 if (object->IsAccessCheckNeeded()) return slow_stub(); | 1495 if (object->IsAccessCheckNeeded()) return slow_stub(); |
| 1496 DCHECK(cache_holder == kCacheOnReceiver || lookup->type() == CALLBACKS || | 1496 DCHECK(cache_holder == kCacheOnReceiver || lookup->type() == CALLBACKS || |
| 1497 (object->IsJSGlobalProxy() && lookup->holder()->IsJSGlobalObject())); | 1497 (object->IsJSGlobalProxy() && lookup->holder()->IsJSGlobalObject())); |
| 1498 // This is currently guaranteed by checks in StoreIC::Store. | 1498 // This is currently guaranteed by checks in StoreIC::Store. |
| 1499 Handle<JSObject> receiver = Handle<JSObject>::cast(object); | 1499 Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
| 1500 | 1500 |
| 1501 Handle<JSObject> holder(lookup->holder()); | 1501 Handle<JSObject> holder(lookup->holder()); |
| 1502 | 1502 |
| (...skipping 1667 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3170 #undef ADDR | 3170 #undef ADDR |
| 3171 }; | 3171 }; |
| 3172 | 3172 |
| 3173 | 3173 |
| 3174 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 3174 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
| 3175 return IC_utilities[id]; | 3175 return IC_utilities[id]; |
| 3176 } | 3176 } |
| 3177 | 3177 |
| 3178 | 3178 |
| 3179 } } // namespace v8::internal | 3179 } } // namespace v8::internal |
| OLD | NEW |