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