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