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