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 |