Chromium Code Reviews| 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 |