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 |