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/api.h" | 7 #include "src/api.h" |
8 #include "src/arguments.h" | 8 #include "src/arguments.h" |
9 #include "src/ast.h" | 9 #include "src/ast.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
191 if (current_map->prototype()->IsNull()) break; | 191 if (current_map->prototype()->IsNull()) break; |
192 last = handle(JSObject::cast(current_map->prototype())); | 192 last = handle(JSObject::cast(current_map->prototype())); |
193 current_map = handle(last->map()); | 193 current_map = handle(last->map()); |
194 } | 194 } |
195 // Compile the stub that is either shared for all names or | 195 // Compile the stub that is either shared for all names or |
196 // name specific if there are global objects involved. | 196 // name specific if there are global objects involved. |
197 Handle<Code> handler = PropertyHandlerCompiler::Find( | 197 Handle<Code> handler = PropertyHandlerCompiler::Find( |
198 cache_name, stub_holder_map, Code::LOAD_IC, flag, Code::FAST); | 198 cache_name, stub_holder_map, Code::LOAD_IC, flag, Code::FAST); |
199 if (!handler.is_null()) return handler; | 199 if (!handler.is_null()) return handler; |
200 | 200 |
201 NamedLoadHandlerCompiler compiler(isolate, flag); | 201 NamedLoadHandlerCompiler compiler(isolate, type, flag); |
202 handler = compiler.CompileLoadNonexistent(type, last, cache_name); | 202 handler = compiler.CompileLoadNonexistent(last, cache_name); |
203 Map::UpdateCodeCache(stub_holder_map, cache_name, handler); | 203 Map::UpdateCodeCache(stub_holder_map, cache_name, handler); |
204 return handler; | 204 return handler; |
205 } | 205 } |
206 | 206 |
207 | 207 |
208 Handle<Code> PropertyICCompiler::ComputeKeyedLoadMonomorphic( | 208 Handle<Code> PropertyICCompiler::ComputeKeyedLoadMonomorphic( |
209 Handle<Map> receiver_map) { | 209 Handle<Map> receiver_map) { |
210 Isolate* isolate = receiver_map->GetIsolate(); | 210 Isolate* isolate = receiver_map->GetIsolate(); |
211 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC); | 211 Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC); |
212 Handle<Name> name = isolate->factory()->KeyedLoadMonomorphic_string(); | 212 Handle<Name> name = isolate->factory()->KeyedLoadMonomorphic_string(); |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
492 | 492 |
493 | 493 |
494 RUNTIME_FUNCTION(StoreCallbackProperty) { | 494 RUNTIME_FUNCTION(StoreCallbackProperty) { |
495 JSObject* receiver = JSObject::cast(args[0]); | 495 JSObject* receiver = JSObject::cast(args[0]); |
496 JSObject* holder = JSObject::cast(args[1]); | 496 JSObject* holder = JSObject::cast(args[1]); |
497 ExecutableAccessorInfo* callback = ExecutableAccessorInfo::cast(args[2]); | 497 ExecutableAccessorInfo* callback = ExecutableAccessorInfo::cast(args[2]); |
498 Address setter_address = v8::ToCData<Address>(callback->setter()); | 498 Address setter_address = v8::ToCData<Address>(callback->setter()); |
499 v8::AccessorSetterCallback fun = | 499 v8::AccessorSetterCallback fun = |
500 FUNCTION_CAST<v8::AccessorSetterCallback>(setter_address); | 500 FUNCTION_CAST<v8::AccessorSetterCallback>(setter_address); |
501 ASSERT(fun != NULL); | 501 ASSERT(fun != NULL); |
502 ASSERT(callback->IsCompatibleReceiver(receiver)); | |
503 Handle<Name> name = args.at<Name>(3); | 502 Handle<Name> name = args.at<Name>(3); |
504 Handle<Object> value = args.at<Object>(4); | 503 Handle<Object> value = args.at<Object>(4); |
505 HandleScope scope(isolate); | 504 HandleScope scope(isolate); |
| 505 ASSERT(!callback->HasExpectedReceiverType() || |
| 506 callback->IsCompatibleReceiver(receiver->map())); |
506 | 507 |
507 // TODO(rossberg): Support symbols in the API. | 508 // TODO(rossberg): Support symbols in the API. |
508 if (name->IsSymbol()) return *value; | 509 if (name->IsSymbol()) return *value; |
509 Handle<String> str = Handle<String>::cast(name); | 510 Handle<String> str = Handle<String>::cast(name); |
510 | 511 |
511 LOG(isolate, ApiNamedPropertyAccess("store", receiver, *name)); | 512 LOG(isolate, ApiNamedPropertyAccess("store", receiver, *name)); |
512 PropertyCallbackArguments | 513 PropertyCallbackArguments |
513 custom_args(isolate, callback->data(), receiver, holder); | 514 custom_args(isolate, callback->data(), receiver, holder); |
514 custom_args.Call(fun, v8::Utils::ToLocal(str), v8::Utils::ToLocal(value)); | 515 custom_args.Call(fun, v8::Utils::ToLocal(str), v8::Utils::ToLocal(value)); |
515 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); | 516 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
734 Handle<Name> name) { | 735 Handle<Name> name) { |
735 return (FLAG_print_code_stubs && !name.is_null() && name->IsString()) | 736 return (FLAG_print_code_stubs && !name.is_null() && name->IsString()) |
736 ? GetCodeWithFlags(flags, Handle<String>::cast(name)->ToCString().get()) | 737 ? GetCodeWithFlags(flags, Handle<String>::cast(name)->ToCString().get()) |
737 : GetCodeWithFlags(flags, NULL); | 738 : GetCodeWithFlags(flags, NULL); |
738 } | 739 } |
739 | 740 |
740 | 741 |
741 #define __ ACCESS_MASM(masm()) | 742 #define __ ACCESS_MASM(masm()) |
742 | 743 |
743 | 744 |
744 Register NamedLoadHandlerCompiler::FrontendHeader(Handle<HeapType> type, | 745 Register NamedLoadHandlerCompiler::FrontendHeader(Register object_reg, |
745 Register object_reg, | |
746 Handle<JSObject> holder, | 746 Handle<JSObject> holder, |
747 Handle<Name> name, | 747 Handle<Name> name, |
748 Label* miss) { | 748 Label* miss) { |
749 PrototypeCheckType check_type = CHECK_ALL_MAPS; | 749 PrototypeCheckType check_type = CHECK_ALL_MAPS; |
750 int function_index = -1; | 750 int function_index = -1; |
751 if (type->Is(HeapType::String())) { | 751 if (type()->Is(HeapType::String())) { |
752 function_index = Context::STRING_FUNCTION_INDEX; | 752 function_index = Context::STRING_FUNCTION_INDEX; |
753 } else if (type->Is(HeapType::Symbol())) { | 753 } else if (type()->Is(HeapType::Symbol())) { |
754 function_index = Context::SYMBOL_FUNCTION_INDEX; | 754 function_index = Context::SYMBOL_FUNCTION_INDEX; |
755 } else if (type->Is(HeapType::Number())) { | 755 } else if (type()->Is(HeapType::Number())) { |
756 function_index = Context::NUMBER_FUNCTION_INDEX; | 756 function_index = Context::NUMBER_FUNCTION_INDEX; |
757 } else if (type->Is(HeapType::Boolean())) { | 757 } else if (type()->Is(HeapType::Boolean())) { |
758 function_index = Context::BOOLEAN_FUNCTION_INDEX; | 758 function_index = Context::BOOLEAN_FUNCTION_INDEX; |
759 } else { | 759 } else { |
760 check_type = SKIP_RECEIVER; | 760 check_type = SKIP_RECEIVER; |
761 } | 761 } |
762 | 762 |
763 if (check_type == CHECK_ALL_MAPS) { | 763 if (check_type == CHECK_ALL_MAPS) { |
764 GenerateDirectLoadGlobalFunctionPrototype( | 764 GenerateDirectLoadGlobalFunctionPrototype( |
765 masm(), function_index, scratch1(), miss); | 765 masm(), function_index, scratch1(), miss); |
766 Object* function = isolate()->native_context()->get(function_index); | 766 Object* function = isolate()->native_context()->get(function_index); |
767 Object* prototype = JSFunction::cast(function)->instance_prototype(); | 767 Object* prototype = JSFunction::cast(function)->instance_prototype(); |
768 type = IC::CurrentTypeOf(handle(prototype, isolate()), isolate()); | 768 set_type_for_object(handle(prototype, isolate())); |
769 object_reg = scratch1(); | 769 object_reg = scratch1(); |
770 } | 770 } |
771 | 771 |
772 // Check that the maps starting from the prototype haven't changed. | 772 // Check that the maps starting from the prototype haven't changed. |
773 return CheckPrototypes( | 773 return CheckPrototypes(object_reg, holder, scratch1(), scratch2(), scratch3(), |
774 type, object_reg, holder, scratch1(), scratch2(), scratch3(), | 774 name, miss, check_type); |
775 name, miss, check_type); | |
776 } | 775 } |
777 | 776 |
778 | 777 |
779 // Frontend for store uses the name register. It has to be restored before a | 778 // Frontend for store uses the name register. It has to be restored before a |
780 // miss. | 779 // miss. |
781 Register NamedStoreHandlerCompiler::FrontendHeader(Handle<HeapType> type, | 780 Register NamedStoreHandlerCompiler::FrontendHeader(Register object_reg, |
782 Register object_reg, | |
783 Handle<JSObject> holder, | 781 Handle<JSObject> holder, |
784 Handle<Name> name, | 782 Handle<Name> name, |
785 Label* miss) { | 783 Label* miss) { |
786 return CheckPrototypes(type, object_reg, holder, this->name(), | 784 return CheckPrototypes(object_reg, holder, this->name(), scratch1(), |
787 scratch1(), scratch2(), name, miss, SKIP_RECEIVER); | 785 scratch2(), name, miss, SKIP_RECEIVER); |
788 } | 786 } |
789 | 787 |
790 | 788 |
791 bool PropertyICCompiler::IncludesNumberType(TypeHandleList* types) { | 789 bool PropertyICCompiler::IncludesNumberType(TypeHandleList* types) { |
792 for (int i = 0; i < types->length(); ++i) { | 790 for (int i = 0; i < types->length(); ++i) { |
793 if (types->at(i)->Is(HeapType::Number())) return true; | 791 if (types->at(i)->Is(HeapType::Number())) return true; |
794 } | 792 } |
795 return false; | 793 return false; |
796 } | 794 } |
797 | 795 |
798 | 796 |
799 Register PropertyHandlerCompiler::Frontend(Handle<HeapType> type, | 797 Register PropertyHandlerCompiler::Frontend(Register object_reg, |
800 Register object_reg, | |
801 Handle<JSObject> holder, | 798 Handle<JSObject> holder, |
802 Handle<Name> name) { | 799 Handle<Name> name) { |
803 Label miss; | 800 Label miss; |
804 Register reg = FrontendHeader(type, object_reg, holder, name, &miss); | 801 Register reg = FrontendHeader(object_reg, holder, name, &miss); |
805 FrontendFooter(name, &miss); | 802 FrontendFooter(name, &miss); |
806 return reg; | 803 return reg; |
807 } | 804 } |
808 | 805 |
809 | 806 |
810 void NamedLoadHandlerCompiler::NonexistentFrontend(Handle<HeapType> type, | 807 void NamedLoadHandlerCompiler::NonexistentFrontend(Handle<JSObject> last, |
811 Handle<JSObject> last, | |
812 Handle<Name> name) { | 808 Handle<Name> name) { |
813 Label miss; | 809 Label miss; |
814 | 810 |
815 Register holder; | 811 Register holder; |
816 Handle<Map> last_map; | 812 Handle<Map> last_map; |
817 if (last.is_null()) { | 813 if (last.is_null()) { |
818 holder = receiver(); | 814 holder = receiver(); |
819 last_map = IC::TypeToMap(*type, isolate()); | 815 last_map = IC::TypeToMap(*type(), isolate()); |
820 // If |type| has null as its prototype, |last| is Handle<JSObject>::null(). | 816 // If |type| has null as its prototype, |last| is Handle<JSObject>::null(). |
821 ASSERT(last_map->prototype() == isolate()->heap()->null_value()); | 817 ASSERT(last_map->prototype() == isolate()->heap()->null_value()); |
822 } else { | 818 } else { |
823 holder = FrontendHeader(type, receiver(), last, name, &miss); | 819 holder = FrontendHeader(receiver(), last, name, &miss); |
824 last_map = handle(last->map()); | 820 last_map = handle(last->map()); |
825 } | 821 } |
826 | 822 |
827 if (last_map->is_dictionary_map() && | 823 if (last_map->is_dictionary_map() && |
828 !last_map->IsJSGlobalObjectMap() && | 824 !last_map->IsJSGlobalObjectMap() && |
829 !last_map->IsJSGlobalProxyMap()) { | 825 !last_map->IsJSGlobalProxyMap()) { |
830 if (!name->IsUniqueName()) { | 826 if (!name->IsUniqueName()) { |
831 ASSERT(name->IsString()); | 827 ASSERT(name->IsString()); |
832 name = factory()->InternalizeString(Handle<String>::cast(name)); | 828 name = factory()->InternalizeString(Handle<String>::cast(name)); |
833 } | 829 } |
834 ASSERT(last.is_null() || | 830 ASSERT(last.is_null() || |
835 last->property_dictionary()->FindEntry(name) == | 831 last->property_dictionary()->FindEntry(name) == |
836 NameDictionary::kNotFound); | 832 NameDictionary::kNotFound); |
837 GenerateDictionaryNegativeLookup(masm(), &miss, holder, name, | 833 GenerateDictionaryNegativeLookup(masm(), &miss, holder, name, |
838 scratch2(), scratch3()); | 834 scratch2(), scratch3()); |
839 } | 835 } |
840 | 836 |
841 // If the last object in the prototype chain is a global object, | 837 // If the last object in the prototype chain is a global object, |
842 // check that the global property cell is empty. | 838 // check that the global property cell is empty. |
843 if (last_map->IsJSGlobalObjectMap()) { | 839 if (last_map->IsJSGlobalObjectMap()) { |
844 Handle<JSGlobalObject> global = last.is_null() | 840 Handle<JSGlobalObject> global = |
845 ? Handle<JSGlobalObject>::cast(type->AsConstant()->Value()) | 841 last.is_null() |
846 : Handle<JSGlobalObject>::cast(last); | 842 ? Handle<JSGlobalObject>::cast(type()->AsConstant()->Value()) |
| 843 : Handle<JSGlobalObject>::cast(last); |
847 GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss); | 844 GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss); |
848 } | 845 } |
849 | 846 |
850 FrontendFooter(name, &miss); | 847 FrontendFooter(name, &miss); |
851 } | 848 } |
852 | 849 |
853 | 850 |
854 Handle<Code> NamedLoadHandlerCompiler::CompileLoadField( | 851 Handle<Code> NamedLoadHandlerCompiler::CompileLoadField( |
855 Handle<HeapType> type, Handle<JSObject> holder, Handle<Name> name, | 852 Handle<JSObject> holder, Handle<Name> name, FieldIndex field, |
856 FieldIndex field, Representation representation) { | 853 Representation representation) { |
857 Register reg = Frontend(type, receiver(), holder, name); | 854 Register reg = Frontend(receiver(), holder, name); |
858 GenerateLoadField(reg, holder, field, representation); | 855 GenerateLoadField(reg, holder, field, representation); |
859 return GetCode(kind(), Code::FAST, name); | 856 return GetCode(kind(), Code::FAST, name); |
860 } | 857 } |
861 | 858 |
862 | 859 |
863 Handle<Code> NamedLoadHandlerCompiler::CompileLoadConstant( | 860 Handle<Code> NamedLoadHandlerCompiler::CompileLoadConstant( |
864 Handle<HeapType> type, Handle<JSObject> holder, Handle<Name> name, | 861 Handle<JSObject> holder, Handle<Name> name, Handle<Object> value) { |
865 Handle<Object> value) { | 862 Frontend(receiver(), holder, name); |
866 Frontend(type, receiver(), holder, name); | |
867 GenerateLoadConstant(value); | 863 GenerateLoadConstant(value); |
868 return GetCode(kind(), Code::FAST, name); | 864 return GetCode(kind(), Code::FAST, name); |
869 } | 865 } |
870 | 866 |
871 | 867 |
872 Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback( | 868 Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback( |
873 Handle<HeapType> type, Handle<JSObject> holder, Handle<Name> name, | 869 Handle<JSObject> holder, Handle<Name> name, |
874 Handle<ExecutableAccessorInfo> callback) { | 870 Handle<ExecutableAccessorInfo> callback) { |
875 Register reg = CallbackFrontend(type, receiver(), holder, name, callback); | 871 Register reg = CallbackFrontend(receiver(), holder, name, callback); |
876 GenerateLoadCallback(reg, callback); | 872 GenerateLoadCallback(reg, callback); |
877 return GetCode(kind(), Code::FAST, name); | 873 return GetCode(kind(), Code::FAST, name); |
878 } | 874 } |
879 | 875 |
880 | 876 |
881 Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback( | 877 Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback( |
882 Handle<HeapType> type, Handle<JSObject> holder, Handle<Name> name, | 878 Handle<JSObject> holder, Handle<Name> name, |
883 const CallOptimization& call_optimization) { | 879 const CallOptimization& call_optimization) { |
884 ASSERT(call_optimization.is_simple_api_call()); | 880 ASSERT(call_optimization.is_simple_api_call()); |
885 Handle<JSFunction> callback = call_optimization.constant_function(); | 881 Handle<JSFunction> callback = call_optimization.constant_function(); |
886 CallbackFrontend(type, receiver(), holder, name, callback); | 882 CallbackFrontend(receiver(), holder, name, callback); |
887 Handle<Map>receiver_map = IC::TypeToMap(*type, isolate()); | 883 Handle<Map> receiver_map = IC::TypeToMap(*type(), isolate()); |
888 GenerateFastApiCall( | 884 GenerateFastApiCall( |
889 masm(), call_optimization, receiver_map, | 885 masm(), call_optimization, receiver_map, |
890 receiver(), scratch1(), false, 0, NULL); | 886 receiver(), scratch1(), false, 0, NULL); |
891 return GetCode(kind(), Code::FAST, name); | 887 return GetCode(kind(), Code::FAST, name); |
892 } | 888 } |
893 | 889 |
894 | 890 |
895 Handle<Code> NamedLoadHandlerCompiler::CompileLoadInterceptor( | 891 Handle<Code> NamedLoadHandlerCompiler::CompileLoadInterceptor( |
896 Handle<HeapType> type, Handle<JSObject> holder, Handle<Name> name) { | 892 Handle<JSObject> holder, Handle<Name> name) { |
897 // Perform a lookup after the interceptor. | 893 // Perform a lookup after the interceptor. |
898 LookupResult lookup(isolate()); | 894 LookupResult lookup(isolate()); |
899 holder->LookupOwnRealNamedProperty(name, &lookup); | 895 holder->LookupOwnRealNamedProperty(name, &lookup); |
900 if (!lookup.IsFound()) { | 896 if (!lookup.IsFound()) { |
901 PrototypeIterator iter(holder->GetIsolate(), holder); | 897 PrototypeIterator iter(holder->GetIsolate(), holder); |
902 if (!iter.IsAtEnd()) { | 898 if (!iter.IsAtEnd()) { |
903 PrototypeIterator::GetCurrent(iter)->Lookup(name, &lookup); | 899 PrototypeIterator::GetCurrent(iter)->Lookup(name, &lookup); |
904 } | 900 } |
905 } | 901 } |
906 | 902 |
907 Register reg = Frontend(type, receiver(), holder, name); | 903 Register reg = Frontend(receiver(), holder, name); |
908 // TODO(368): Compile in the whole chain: all the interceptors in | 904 // TODO(368): Compile in the whole chain: all the interceptors in |
909 // prototypes and ultimate answer. | 905 // prototypes and ultimate answer. |
910 GenerateLoadInterceptor(reg, type, holder, &lookup, name); | 906 GenerateLoadInterceptor(reg, holder, &lookup, name); |
911 return GetCode(kind(), Code::FAST, name); | 907 return GetCode(kind(), Code::FAST, name); |
912 } | 908 } |
913 | 909 |
914 | 910 |
915 void NamedLoadHandlerCompiler::GenerateLoadPostInterceptor( | 911 void NamedLoadHandlerCompiler::GenerateLoadPostInterceptor( |
916 Register interceptor_reg, Handle<JSObject> interceptor_holder, | 912 Register interceptor_reg, Handle<JSObject> interceptor_holder, |
917 Handle<Name> name, LookupResult* lookup) { | 913 Handle<Name> name, LookupResult* lookup) { |
918 Handle<JSObject> holder(lookup->holder()); | 914 Handle<JSObject> holder(lookup->holder()); |
919 if (lookup->IsField()) { | 915 if (lookup->IsField()) { |
920 FieldIndex field = lookup->GetFieldIndex(); | 916 FieldIndex field = lookup->GetFieldIndex(); |
921 if (interceptor_holder.is_identical_to(holder)) { | 917 if (interceptor_holder.is_identical_to(holder)) { |
922 GenerateLoadField( | 918 GenerateLoadField( |
923 interceptor_reg, holder, field, lookup->representation()); | 919 interceptor_reg, holder, field, lookup->representation()); |
924 } else { | 920 } else { |
925 // We found FIELD property in prototype chain of interceptor's holder. | 921 // We found FIELD property in prototype chain of interceptor's holder. |
926 // Retrieve a field from field's holder. | 922 // Retrieve a field from field's holder. |
927 Register reg = Frontend(IC::CurrentTypeOf(interceptor_holder, isolate()), | 923 set_type_for_object(interceptor_holder); |
928 interceptor_reg, holder, name); | 924 Register reg = Frontend(interceptor_reg, holder, name); |
929 GenerateLoadField( | 925 GenerateLoadField( |
930 reg, holder, field, lookup->representation()); | 926 reg, holder, field, lookup->representation()); |
931 } | 927 } |
932 } else { | 928 } else { |
933 // We found CALLBACKS property in prototype chain of interceptor's | 929 // We found CALLBACKS property in prototype chain of interceptor's |
934 // holder. | 930 // holder. |
935 ASSERT(lookup->type() == CALLBACKS); | 931 ASSERT(lookup->type() == CALLBACKS); |
936 Handle<ExecutableAccessorInfo> callback( | 932 Handle<ExecutableAccessorInfo> callback( |
937 ExecutableAccessorInfo::cast(lookup->GetCallbackObject())); | 933 ExecutableAccessorInfo::cast(lookup->GetCallbackObject())); |
938 ASSERT(callback->getter() != NULL); | 934 ASSERT(callback->getter() != NULL); |
939 | 935 |
940 Register reg = | 936 set_type_for_object(interceptor_holder); |
941 CallbackFrontend(IC::CurrentTypeOf(interceptor_holder, isolate()), | 937 Register reg = CallbackFrontend(interceptor_reg, holder, name, callback); |
942 interceptor_reg, holder, name, callback); | |
943 GenerateLoadCallback(reg, callback); | 938 GenerateLoadCallback(reg, callback); |
944 } | 939 } |
945 } | 940 } |
946 | 941 |
947 | 942 |
948 Handle<Code> PropertyICCompiler::CompileMonomorphic(Handle<HeapType> type, | 943 Handle<Code> PropertyICCompiler::CompileMonomorphic(Handle<HeapType> type, |
949 Handle<Code> handler, | 944 Handle<Code> handler, |
950 Handle<Name> name, | 945 Handle<Name> name, |
951 IcCheckType check) { | 946 IcCheckType check) { |
952 TypeHandleList types(1); | 947 TypeHandleList types(1); |
953 CodeHandleList handlers(1); | 948 CodeHandleList handlers(1); |
954 types.Add(type); | 949 types.Add(type); |
955 handlers.Add(handler); | 950 handlers.Add(handler); |
956 Code::StubType stub_type = handler->type(); | 951 Code::StubType stub_type = handler->type(); |
957 return CompilePolymorphic(&types, &handlers, name, stub_type, check); | 952 return CompilePolymorphic(&types, &handlers, name, stub_type, check); |
958 } | 953 } |
959 | 954 |
960 | 955 |
961 Handle<Code> NamedLoadHandlerCompiler::CompileLoadViaGetter( | 956 Handle<Code> NamedLoadHandlerCompiler::CompileLoadViaGetter( |
962 Handle<HeapType> type, Handle<JSObject> holder, Handle<Name> name, | 957 Handle<JSObject> holder, Handle<Name> name, Handle<JSFunction> getter) { |
963 Handle<JSFunction> getter) { | 958 Frontend(receiver(), holder, name); |
964 Frontend(type, receiver(), holder, name); | 959 GenerateLoadViaGetter(masm(), type(), receiver(), getter); |
965 GenerateLoadViaGetter(masm(), type, receiver(), getter); | |
966 return GetCode(kind(), Code::FAST, name); | 960 return GetCode(kind(), Code::FAST, name); |
967 } | 961 } |
968 | 962 |
969 | 963 |
970 Handle<Code> NamedStoreHandlerCompiler::CompileStoreTransition( | 964 Handle<Code> NamedStoreHandlerCompiler::CompileStoreTransition( |
971 Handle<JSObject> object, LookupResult* lookup, Handle<Map> transition, | 965 Handle<JSObject> object, LookupResult* lookup, Handle<Map> transition, |
972 Handle<Name> name) { | 966 Handle<Name> name) { |
973 Label miss, slow; | 967 Label miss, slow; |
974 | 968 |
975 // Ensure no transitions to deprecated maps are followed. | 969 // Ensure no transitions to deprecated maps are followed. |
976 __ CheckMapDeprecated(transition, scratch1(), &miss); | 970 __ CheckMapDeprecated(transition, scratch1(), &miss); |
977 | 971 |
978 // Check that we are allowed to write this. | 972 // Check that we are allowed to write this. |
979 PrototypeIterator iter(object->GetIsolate(), object); | 973 PrototypeIterator iter(object->GetIsolate(), object); |
980 if (!iter.IsAtEnd()) { | 974 if (!iter.IsAtEnd()) { |
981 Handle<JSObject> holder; | 975 Handle<JSObject> holder; |
982 // holder == object indicates that no property was found. | 976 // holder == object indicates that no property was found. |
983 if (lookup->holder() != *object) { | 977 if (lookup->holder() != *object) { |
984 holder = Handle<JSObject>(lookup->holder()); | 978 holder = Handle<JSObject>(lookup->holder()); |
985 } else { | 979 } else { |
986 // Find the top object. | 980 // Find the top object. |
987 do { | 981 do { |
988 holder = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); | 982 holder = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); |
989 iter.Advance(); | 983 iter.Advance(); |
990 } while (!iter.IsAtEnd()); | 984 } while (!iter.IsAtEnd()); |
991 } | 985 } |
992 | 986 |
993 Register holder_reg = FrontendHeader(IC::CurrentTypeOf(object, isolate()), | 987 Register holder_reg = FrontendHeader(receiver(), holder, name, &miss); |
994 receiver(), holder, name, &miss); | |
995 | 988 |
996 // If no property was found, and the holder (the last object in the | 989 // If no property was found, and the holder (the last object in the |
997 // prototype chain) is in slow mode, we need to do a negative lookup on the | 990 // prototype chain) is in slow mode, we need to do a negative lookup on the |
998 // holder. | 991 // holder. |
999 if (lookup->holder() == *object) { | 992 if (lookup->holder() == *object) { |
1000 GenerateNegativeHolderLookup(masm(), holder, holder_reg, name, &miss); | 993 GenerateNegativeHolderLookup(masm(), holder, holder_reg, name, &miss); |
1001 } | 994 } |
1002 } | 995 } |
1003 | 996 |
1004 GenerateStoreTransition(masm(), | 997 GenerateStoreTransition(masm(), |
(...skipping 13 matching lines...) Expand all Loading... |
1018 GenerateRestoreName(masm(), &slow, name); | 1011 GenerateRestoreName(masm(), &slow, name); |
1019 TailCallBuiltin(masm(), SlowBuiltin(kind())); | 1012 TailCallBuiltin(masm(), SlowBuiltin(kind())); |
1020 return GetCode(kind(), Code::FAST, name); | 1013 return GetCode(kind(), Code::FAST, name); |
1021 } | 1014 } |
1022 | 1015 |
1023 | 1016 |
1024 Handle<Code> NamedStoreHandlerCompiler::CompileStoreField( | 1017 Handle<Code> NamedStoreHandlerCompiler::CompileStoreField( |
1025 Handle<JSObject> object, LookupResult* lookup, Handle<Name> name) { | 1018 Handle<JSObject> object, LookupResult* lookup, Handle<Name> name) { |
1026 Label miss; | 1019 Label miss; |
1027 | 1020 |
1028 FrontendHeader(IC::CurrentTypeOf(object, isolate()), receiver(), object, name, | 1021 FrontendHeader(receiver(), object, name, &miss); |
1029 &miss); | |
1030 | 1022 |
1031 // Generate store field code. | 1023 // Generate store field code. |
1032 GenerateStoreField(masm(), | 1024 GenerateStoreField(masm(), |
1033 object, | 1025 object, |
1034 lookup, | 1026 lookup, |
1035 receiver(), this->name(), value(), scratch1(), scratch2(), | 1027 receiver(), this->name(), value(), scratch1(), scratch2(), |
1036 &miss); | 1028 &miss); |
1037 | 1029 |
1038 // Handle store cache miss. | 1030 // Handle store cache miss. |
1039 __ bind(&miss); | 1031 __ bind(&miss); |
(...skipping 19 matching lines...) Expand all Loading... |
1059 // Handle miss case. | 1051 // Handle miss case. |
1060 __ bind(&miss); | 1052 __ bind(&miss); |
1061 TailCallBuiltin(masm(), MissBuiltin(kind())); | 1053 TailCallBuiltin(masm(), MissBuiltin(kind())); |
1062 return GetCode(kind(), Code::FAST, name); | 1054 return GetCode(kind(), Code::FAST, name); |
1063 } | 1055 } |
1064 | 1056 |
1065 | 1057 |
1066 Handle<Code> NamedStoreHandlerCompiler::CompileStoreViaSetter( | 1058 Handle<Code> NamedStoreHandlerCompiler::CompileStoreViaSetter( |
1067 Handle<JSObject> object, Handle<JSObject> holder, Handle<Name> name, | 1059 Handle<JSObject> object, Handle<JSObject> holder, Handle<Name> name, |
1068 Handle<JSFunction> setter) { | 1060 Handle<JSFunction> setter) { |
1069 Handle<HeapType> type = IC::CurrentTypeOf(object, isolate()); | 1061 Frontend(receiver(), holder, name); |
1070 Frontend(type, receiver(), holder, name); | 1062 GenerateStoreViaSetter(masm(), type(), receiver(), setter); |
1071 GenerateStoreViaSetter(masm(), type, receiver(), setter); | |
1072 | 1063 |
1073 return GetCode(kind(), Code::FAST, name); | 1064 return GetCode(kind(), Code::FAST, name); |
1074 } | 1065 } |
1075 | 1066 |
1076 | 1067 |
1077 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( | 1068 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( |
1078 Handle<JSObject> object, Handle<JSObject> holder, Handle<Name> name, | 1069 Handle<JSObject> object, Handle<JSObject> holder, Handle<Name> name, |
1079 const CallOptimization& call_optimization) { | 1070 const CallOptimization& call_optimization) { |
1080 Frontend(IC::CurrentTypeOf(object, isolate()), receiver(), holder, name); | 1071 Frontend(receiver(), holder, name); |
1081 Register values[] = { value() }; | 1072 Register values[] = { value() }; |
1082 GenerateFastApiCall( | 1073 GenerateFastApiCall( |
1083 masm(), call_optimization, handle(object->map()), | 1074 masm(), call_optimization, handle(object->map()), |
1084 receiver(), scratch1(), true, 1, values); | 1075 receiver(), scratch1(), true, 1, values); |
1085 return GetCode(kind(), Code::FAST, name); | 1076 return GetCode(kind(), Code::FAST, name); |
1086 } | 1077 } |
1087 | 1078 |
1088 | 1079 |
1089 Handle<Code> PropertyICCompiler::CompileKeyedStoreMonomorphic( | 1080 Handle<Code> PropertyICCompiler::CompileKeyedStoreMonomorphic( |
1090 Handle<Map> receiver_map, KeyedAccessStoreMode store_mode) { | 1081 Handle<Map> receiver_map, KeyedAccessStoreMode store_mode) { |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1350 Handle<FunctionTemplateInfo>( | 1341 Handle<FunctionTemplateInfo>( |
1351 FunctionTemplateInfo::cast(signature->receiver())); | 1342 FunctionTemplateInfo::cast(signature->receiver())); |
1352 } | 1343 } |
1353 } | 1344 } |
1354 | 1345 |
1355 is_simple_api_call_ = true; | 1346 is_simple_api_call_ = true; |
1356 } | 1347 } |
1357 | 1348 |
1358 | 1349 |
1359 } } // namespace v8::internal | 1350 } } // namespace v8::internal |
OLD | NEW |