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/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/api.h" | 8 #include "src/api.h" |
9 #include "src/arguments.h" | 9 #include "src/arguments.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 820 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
831 ExtraICState extra_state) { | 831 ExtraICState extra_state) { |
832 return isolate->stub_cache()->ComputeLoad(PREMONOMORPHIC, extra_state); | 832 return isolate->stub_cache()->ComputeLoad(PREMONOMORPHIC, extra_state); |
833 } | 833 } |
834 | 834 |
835 | 835 |
836 Handle<Code> LoadIC::megamorphic_stub() { | 836 Handle<Code> LoadIC::megamorphic_stub() { |
837 return isolate()->stub_cache()->ComputeLoad(MEGAMORPHIC, extra_ic_state()); | 837 return isolate()->stub_cache()->ComputeLoad(MEGAMORPHIC, extra_ic_state()); |
838 } | 838 } |
839 | 839 |
840 | 840 |
841 Handle<Code> LoadIC::SimpleFieldLoad(FieldIndex index) { | 841 Handle<Code> LoadIC::SimpleFieldLoad(int offset, |
| 842 bool inobject, |
| 843 Representation representation) { |
842 if (kind() == Code::LOAD_IC) { | 844 if (kind() == Code::LOAD_IC) { |
843 LoadFieldStub stub(isolate(), index); | 845 LoadFieldStub stub(isolate(), inobject, offset, representation); |
844 return stub.GetCode(); | 846 return stub.GetCode(); |
845 } else { | 847 } else { |
846 KeyedLoadFieldStub stub(isolate(), index); | 848 KeyedLoadFieldStub stub(isolate(), inobject, offset, representation); |
847 return stub.GetCode(); | 849 return stub.GetCode(); |
848 } | 850 } |
849 } | 851 } |
850 | 852 |
851 | 853 |
852 void LoadIC::UpdateCaches(LookupResult* lookup, | 854 void LoadIC::UpdateCaches(LookupResult* lookup, |
853 Handle<Object> object, | 855 Handle<Object> object, |
854 Handle<String> name) { | 856 Handle<String> name) { |
855 if (state() == UNINITIALIZED) { | 857 if (state() == UNINITIALIZED) { |
856 // This is the first time we execute this inline cache. | 858 // This is the first time we execute this inline cache. |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
915 } | 917 } |
916 | 918 |
917 | 919 |
918 Handle<Code> LoadIC::CompileHandler(LookupResult* lookup, | 920 Handle<Code> LoadIC::CompileHandler(LookupResult* lookup, |
919 Handle<Object> object, | 921 Handle<Object> object, |
920 Handle<String> name, | 922 Handle<String> name, |
921 Handle<Object> unused, | 923 Handle<Object> unused, |
922 InlineCacheHolderFlag cache_holder) { | 924 InlineCacheHolderFlag cache_holder) { |
923 if (object->IsString() && | 925 if (object->IsString() && |
924 String::Equals(isolate()->factory()->length_string(), name)) { | 926 String::Equals(isolate()->factory()->length_string(), name)) { |
925 FieldIndex index = FieldIndex::ForInObjectOffset(String::kLengthOffset); | 927 int length_index = String::kLengthOffset / kPointerSize; |
926 return SimpleFieldLoad(index); | 928 return SimpleFieldLoad(length_index); |
927 } | 929 } |
928 | 930 |
929 if (object->IsStringWrapper() && | 931 if (object->IsStringWrapper() && |
930 String::Equals(isolate()->factory()->length_string(), name)) { | 932 String::Equals(isolate()->factory()->length_string(), name)) { |
931 if (kind() == Code::LOAD_IC) { | 933 if (kind() == Code::LOAD_IC) { |
932 StringLengthStub string_length_stub(isolate()); | 934 StringLengthStub string_length_stub(isolate()); |
933 return string_length_stub.GetCode(); | 935 return string_length_stub.GetCode(); |
934 } else { | 936 } else { |
935 KeyedStringLengthStub string_length_stub(isolate()); | 937 KeyedStringLengthStub string_length_stub(isolate()); |
936 return string_length_stub.GetCode(); | 938 return string_length_stub.GetCode(); |
937 } | 939 } |
938 } | 940 } |
939 | 941 |
940 Handle<HeapType> type = CurrentTypeOf(object, isolate()); | 942 Handle<HeapType> type = CurrentTypeOf(object, isolate()); |
941 Handle<JSObject> holder(lookup->holder()); | 943 Handle<JSObject> holder(lookup->holder()); |
942 LoadStubCompiler compiler(isolate(), kNoExtraICState, cache_holder, kind()); | 944 LoadStubCompiler compiler(isolate(), kNoExtraICState, cache_holder, kind()); |
943 | 945 |
944 switch (lookup->type()) { | 946 switch (lookup->type()) { |
945 case FIELD: { | 947 case FIELD: { |
946 FieldIndex field = lookup->GetFieldIndex(); | 948 PropertyIndex field = lookup->GetFieldIndex(); |
947 if (object.is_identical_to(holder)) { | 949 if (object.is_identical_to(holder)) { |
948 return SimpleFieldLoad(field); | 950 return SimpleFieldLoad(field.translate(holder), |
| 951 field.is_inobject(holder), |
| 952 lookup->representation()); |
949 } | 953 } |
950 return compiler.CompileLoadField( | 954 return compiler.CompileLoadField( |
951 type, holder, name, field, lookup->representation()); | 955 type, holder, name, field, lookup->representation()); |
952 } | 956 } |
953 case CONSTANT: { | 957 case CONSTANT: { |
954 Handle<Object> constant(lookup->GetConstant(), isolate()); | 958 Handle<Object> constant(lookup->GetConstant(), isolate()); |
955 // TODO(2803): Don't compute a stub for cons strings because they cannot | 959 // TODO(2803): Don't compute a stub for cons strings because they cannot |
956 // be embedded into code. | 960 // be embedded into code. |
957 if (constant->IsConsString()) break; | 961 if (constant->IsConsString()) break; |
958 return compiler.CompileLoadConstant(type, holder, name, constant); | 962 return compiler.CompileLoadConstant(type, holder, name, constant); |
(...skipping 15 matching lines...) Expand all Loading... |
974 // There is only one shared stub for loading normalized | 978 // There is only one shared stub for loading normalized |
975 // properties. It does not traverse the prototype chain, so the | 979 // properties. It does not traverse the prototype chain, so the |
976 // property must be found in the object for the stub to be | 980 // property must be found in the object for the stub to be |
977 // applicable. | 981 // applicable. |
978 if (!object.is_identical_to(holder)) break; | 982 if (!object.is_identical_to(holder)) break; |
979 return isolate()->builtins()->LoadIC_Normal(); | 983 return isolate()->builtins()->LoadIC_Normal(); |
980 case CALLBACKS: { | 984 case CALLBACKS: { |
981 // Use simple field loads for some well-known callback properties. | 985 // Use simple field loads for some well-known callback properties. |
982 if (object->IsJSObject()) { | 986 if (object->IsJSObject()) { |
983 Handle<JSObject> receiver = Handle<JSObject>::cast(object); | 987 Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
984 Handle<Map> map(receiver->map()); | |
985 Handle<HeapType> type = IC::MapToType<HeapType>( | 988 Handle<HeapType> type = IC::MapToType<HeapType>( |
986 handle(receiver->map()), isolate()); | 989 handle(receiver->map()), isolate()); |
987 int object_offset; | 990 int object_offset; |
988 if (Accessors::IsJSObjectFieldAccessor<HeapType>( | 991 if (Accessors::IsJSObjectFieldAccessor<HeapType>( |
989 type, name, &object_offset)) { | 992 type, name, &object_offset)) { |
990 FieldIndex index = FieldIndex::ForInObjectOffset( | 993 return SimpleFieldLoad(object_offset / kPointerSize); |
991 object_offset, receiver->map()); | |
992 return SimpleFieldLoad(index); | |
993 } | 994 } |
994 } | 995 } |
995 | 996 |
996 Handle<Object> callback(lookup->GetCallbackObject(), isolate()); | 997 Handle<Object> callback(lookup->GetCallbackObject(), isolate()); |
997 if (callback->IsExecutableAccessorInfo()) { | 998 if (callback->IsExecutableAccessorInfo()) { |
998 Handle<ExecutableAccessorInfo> info = | 999 Handle<ExecutableAccessorInfo> info = |
999 Handle<ExecutableAccessorInfo>::cast(callback); | 1000 Handle<ExecutableAccessorInfo>::cast(callback); |
1000 if (v8::ToCData<Address>(info->getter()) == 0) break; | 1001 if (v8::ToCData<Address>(info->getter()) == 0) break; |
1001 if (!info->IsCompatibleReceiver(*object)) break; | 1002 if (!info->IsCompatibleReceiver(*object)) break; |
1002 return compiler.CompileLoadCallback(type, holder, name, info); | 1003 return compiler.CompileLoadCallback(type, holder, name, info); |
(...skipping 2046 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3049 #undef ADDR | 3050 #undef ADDR |
3050 }; | 3051 }; |
3051 | 3052 |
3052 | 3053 |
3053 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 3054 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
3054 return IC_utilities[id]; | 3055 return IC_utilities[id]; |
3055 } | 3056 } |
3056 | 3057 |
3057 | 3058 |
3058 } } // namespace v8::internal | 3059 } } // namespace v8::internal |
OLD | NEW |