| 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 |