| 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 |