| 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 785 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 796 | 796 |
| 797 Register PropertyHandlerCompiler::Frontend(Register object_reg, | 797 Register PropertyHandlerCompiler::Frontend(Register object_reg, |
| 798 Handle<Name> name) { | 798 Handle<Name> name) { |
| 799 Label miss; | 799 Label miss; |
| 800 Register reg = FrontendHeader(object_reg, name, &miss); | 800 Register reg = FrontendHeader(object_reg, name, &miss); |
| 801 FrontendFooter(name, &miss); | 801 FrontendFooter(name, &miss); |
| 802 return reg; | 802 return reg; |
| 803 } | 803 } |
| 804 | 804 |
| 805 | 805 |
| 806 void NamedLoadHandlerCompiler::NonexistentFrontend(Handle<Name> name) { | 806 void PropertyHandlerCompiler::NonexistentFrontendHeader(Handle<Name> name, |
| 807 Label miss; | 807 Label* miss, |
| 808 | 808 Register scratch1, |
| 809 Register scratch2) { |
| 809 Register holder_reg; | 810 Register holder_reg; |
| 810 Handle<Map> last_map; | 811 Handle<Map> last_map; |
| 811 if (holder().is_null()) { | 812 if (holder().is_null()) { |
| 812 holder_reg = receiver(); | 813 holder_reg = receiver(); |
| 813 last_map = IC::TypeToMap(*type(), isolate()); | 814 last_map = IC::TypeToMap(*type(), isolate()); |
| 814 // If |type| has null as its prototype, |holder()| is | 815 // If |type| has null as its prototype, |holder()| is |
| 815 // Handle<JSObject>::null(). | 816 // Handle<JSObject>::null(). |
| 816 ASSERT(last_map->prototype() == isolate()->heap()->null_value()); | 817 ASSERT(last_map->prototype() == isolate()->heap()->null_value()); |
| 817 } else { | 818 } else { |
| 818 holder_reg = FrontendHeader(receiver(), name, &miss); | 819 holder_reg = FrontendHeader(receiver(), name, miss); |
| 819 last_map = handle(holder()->map()); | 820 last_map = handle(holder()->map()); |
| 820 } | 821 } |
| 821 | 822 |
| 822 if (last_map->is_dictionary_map() && !last_map->IsJSGlobalObjectMap()) { | 823 if (last_map->is_dictionary_map()) { |
| 823 if (!name->IsUniqueName()) { | 824 if (last_map->IsJSGlobalObjectMap()) { |
| 824 ASSERT(name->IsString()); | 825 Handle<JSGlobalObject> global = |
| 825 name = factory()->InternalizeString(Handle<String>::cast(name)); | 826 holder().is_null() |
| 827 ? Handle<JSGlobalObject>::cast(type()->AsConstant()->Value()) |
| 828 : Handle<JSGlobalObject>::cast(holder()); |
| 829 GenerateCheckPropertyCell(masm(), global, name, scratch1, miss); |
| 830 } else { |
| 831 if (!name->IsUniqueName()) { |
| 832 ASSERT(name->IsString()); |
| 833 name = factory()->InternalizeString(Handle<String>::cast(name)); |
| 834 } |
| 835 ASSERT(holder().is_null() || |
| 836 holder()->property_dictionary()->FindEntry(name) == |
| 837 NameDictionary::kNotFound); |
| 838 GenerateDictionaryNegativeLookup(masm(), miss, holder_reg, name, scratch1, |
| 839 scratch2); |
| 826 } | 840 } |
| 827 ASSERT(holder().is_null() || | |
| 828 holder()->property_dictionary()->FindEntry(name) == | |
| 829 NameDictionary::kNotFound); | |
| 830 GenerateDictionaryNegativeLookup(masm(), &miss, holder_reg, name, | |
| 831 scratch2(), scratch3()); | |
| 832 } | 841 } |
| 833 | |
| 834 // If the last object in the prototype chain is a global object, | |
| 835 // check that the global property cell is empty. | |
| 836 if (last_map->IsJSGlobalObjectMap()) { | |
| 837 Handle<JSGlobalObject> global = | |
| 838 holder().is_null() | |
| 839 ? Handle<JSGlobalObject>::cast(type()->AsConstant()->Value()) | |
| 840 : Handle<JSGlobalObject>::cast(holder()); | |
| 841 GenerateCheckPropertyCell(masm(), global, name, scratch2(), &miss); | |
| 842 } | |
| 843 | |
| 844 FrontendFooter(name, &miss); | |
| 845 } | 842 } |
| 846 | 843 |
| 847 | 844 |
| 848 Handle<Code> NamedLoadHandlerCompiler::CompileLoadField( | 845 Handle<Code> NamedLoadHandlerCompiler::CompileLoadField( |
| 849 Handle<Name> name, FieldIndex field, Representation representation) { | 846 Handle<Name> name, FieldIndex field, Representation representation) { |
| 850 Register reg = Frontend(receiver(), name); | 847 Register reg = Frontend(receiver(), name); |
| 851 GenerateLoadField(reg, field, representation); | 848 GenerateLoadField(reg, field, representation); |
| 852 return GetCode(kind(), Code::FAST, name); | 849 return GetCode(kind(), Code::FAST, name); |
| 853 } | 850 } |
| 854 | 851 |
| 855 | 852 |
| 856 Handle<Code> NamedLoadHandlerCompiler::CompileLoadConstant( | 853 Handle<Code> NamedLoadHandlerCompiler::CompileLoadConstant( |
| 857 Handle<Name> name, Handle<Object> value) { | 854 Handle<Name> name, Handle<Object> value) { |
| 858 Frontend(receiver(), name); | 855 Frontend(receiver(), name); |
| 859 GenerateLoadConstant(value); | 856 GenerateLoadConstant(value); |
| 860 return GetCode(kind(), Code::FAST, name); | 857 return GetCode(kind(), Code::FAST, name); |
| 861 } | 858 } |
| 862 | 859 |
| 863 | 860 |
| 861 Handle<Code> NamedLoadHandlerCompiler::CompileLoadNonexistent( |
| 862 Handle<Name> name) { |
| 863 Label miss; |
| 864 NonexistentFrontendHeader(name, &miss, scratch2(), scratch3()); |
| 865 GenerateLoadConstant(isolate()->factory()->undefined_value()); |
| 866 FrontendFooter(name, &miss); |
| 867 return GetCode(kind(), Code::FAST, name); |
| 868 } |
| 869 |
| 870 |
| 864 Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback( | 871 Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback( |
| 865 Handle<Name> name, Handle<ExecutableAccessorInfo> callback) { | 872 Handle<Name> name, Handle<ExecutableAccessorInfo> callback) { |
| 866 Register reg = CallbackFrontend(receiver(), name, callback); | 873 Register reg = CallbackFrontend(receiver(), name, callback); |
| 867 GenerateLoadCallback(reg, callback); | 874 GenerateLoadCallback(reg, callback); |
| 868 return GetCode(kind(), Code::FAST, name); | 875 return GetCode(kind(), Code::FAST, name); |
| 869 } | 876 } |
| 870 | 877 |
| 871 | 878 |
| 872 Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback( | 879 Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback( |
| 873 Handle<Name> name, const CallOptimization& call_optimization) { | 880 Handle<Name> name, const CallOptimization& call_optimization) { |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 963 bool is_nonexistent = holder()->map() == transition->GetBackPointer(); | 970 bool is_nonexistent = holder()->map() == transition->GetBackPointer(); |
| 964 if (is_nonexistent) { | 971 if (is_nonexistent) { |
| 965 // Find the top object. | 972 // Find the top object. |
| 966 Handle<JSObject> last; | 973 Handle<JSObject> last; |
| 967 PrototypeIterator iter(isolate(), holder()); | 974 PrototypeIterator iter(isolate(), holder()); |
| 968 while (!iter.IsAtEnd()) { | 975 while (!iter.IsAtEnd()) { |
| 969 last = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); | 976 last = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)); |
| 970 iter.Advance(); | 977 iter.Advance(); |
| 971 } | 978 } |
| 972 if (!last.is_null()) set_holder(last); | 979 if (!last.is_null()) set_holder(last); |
| 973 } | 980 NonexistentFrontendHeader(name, &miss, scratch1(), scratch2()); |
| 974 | 981 } else { |
| 975 Register holder_reg = FrontendHeader(receiver(), name, &miss); | 982 FrontendHeader(receiver(), name, &miss); |
| 976 | 983 ASSERT(holder()->HasFastProperties()); |
| 977 // If no property was found, and the holder (the last object in the | |
| 978 // prototype chain) is in slow mode, we need to do a negative lookup on the | |
| 979 // holder. | |
| 980 if (is_nonexistent) { | |
| 981 GenerateNegativeHolderLookup(holder_reg, name, &miss); | |
| 982 } | 984 } |
| 983 | 985 |
| 984 GenerateStoreTransition(transition, name, receiver(), this->name(), value(), | 986 GenerateStoreTransition(transition, name, receiver(), this->name(), value(), |
| 985 scratch1(), scratch2(), scratch3(), &miss, &slow); | 987 scratch1(), scratch2(), scratch3(), &miss, &slow); |
| 986 | 988 |
| 987 // Handle store cache miss. | |
| 988 GenerateRestoreName(&miss, name); | 989 GenerateRestoreName(&miss, name); |
| 989 TailCallBuiltin(masm(), MissBuiltin(kind())); | 990 TailCallBuiltin(masm(), MissBuiltin(kind())); |
| 990 | 991 |
| 991 GenerateRestoreName(&slow, name); | 992 GenerateRestoreName(&slow, name); |
| 992 TailCallBuiltin(masm(), SlowBuiltin(kind())); | 993 TailCallBuiltin(masm(), SlowBuiltin(kind())); |
| 993 return GetCode(kind(), Code::FAST, name); | 994 return GetCode(kind(), Code::FAST, name); |
| 994 } | 995 } |
| 995 | 996 |
| 996 | 997 |
| 997 Handle<Code> NamedStoreHandlerCompiler::CompileStoreField(LookupResult* lookup, | 998 Handle<Code> NamedStoreHandlerCompiler::CompileStoreField(LookupResult* lookup, |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1293 Handle<FunctionTemplateInfo>( | 1294 Handle<FunctionTemplateInfo>( |
| 1294 FunctionTemplateInfo::cast(signature->receiver())); | 1295 FunctionTemplateInfo::cast(signature->receiver())); |
| 1295 } | 1296 } |
| 1296 } | 1297 } |
| 1297 | 1298 |
| 1298 is_simple_api_call_ = true; | 1299 is_simple_api_call_ = true; |
| 1299 } | 1300 } |
| 1300 | 1301 |
| 1301 | 1302 |
| 1302 } } // namespace v8::internal | 1303 } } // namespace v8::internal |
| OLD | NEW |