| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 | 29 |
| 30 #include "accessors.h" | 30 #include "accessors.h" |
| 31 #include "api.h" | 31 #include "api.h" |
| 32 #include "arguments.h" | 32 #include "arguments.h" |
| 33 #include "codegen.h" | 33 #include "codegen.h" |
| 34 #include "execution.h" | 34 #include "execution.h" |
| 35 #include "ic-inl.h" | 35 #include "ic-inl.h" |
| 36 #include "runtime.h" | 36 #include "runtime.h" |
| 37 #include "stub-cache.h" | 37 #include "stub-cache.h" |
| 38 | 38 |
| 39 #if DEBUG |
| 40 #define DEBUG_LOADIC 0 |
| 41 #endif |
| 42 |
| 39 namespace v8 { | 43 namespace v8 { |
| 40 namespace internal { | 44 namespace internal { |
| 41 | 45 |
| 42 #ifdef DEBUG | 46 #ifdef DEBUG |
| 43 char IC::TransitionMarkFromState(IC::State state) { | 47 char IC::TransitionMarkFromState(IC::State state) { |
| 44 switch (state) { | 48 switch (state) { |
| 45 case UNINITIALIZED: return '0'; | 49 case UNINITIALIZED: return '0'; |
| 46 case PREMONOMORPHIC: return 'P'; | 50 case PREMONOMORPHIC: return 'P'; |
| 47 case MONOMORPHIC: return '1'; | 51 case MONOMORPHIC: return '1'; |
| 48 case MONOMORPHIC_PROTOTYPE_FAILURE: return '^'; | 52 case MONOMORPHIC_PROTOTYPE_FAILURE: return '^'; |
| (...skipping 844 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 893 } | 897 } |
| 894 | 898 |
| 895 // Check if the name is trivially convertible to an index and get | 899 // Check if the name is trivially convertible to an index and get |
| 896 // the element if so. | 900 // the element if so. |
| 897 uint32_t index; | 901 uint32_t index; |
| 898 if (name->AsArrayIndex(&index)) return object->GetElement(index); | 902 if (name->AsArrayIndex(&index)) return object->GetElement(index); |
| 899 | 903 |
| 900 // Named lookup in the object. | 904 // Named lookup in the object. |
| 901 LookupResult lookup(isolate()); | 905 LookupResult lookup(isolate()); |
| 902 LookupForRead(object, name, &lookup); | 906 LookupForRead(object, name, &lookup); |
| 907 #if DEBUG_LOADIC |
| 908 PrintF("==============================2 LoadIC::Load "); |
| 909 name->Print(); |
| 910 PrintF(", "); |
| 911 lookup.Print(stdout); |
| 912 PrintF("\n"); |
| 913 #endif |
| 903 | 914 |
| 904 // If we did not find a property, check if we need to throw an exception. | 915 // If we did not find a property, check if we need to throw an exception. |
| 905 if (!lookup.IsProperty()) { | 916 if (!lookup.IsProperty()) { |
| 906 if (IsContextual(object)) { | 917 if (IsContextual(object)) { |
| 907 return ReferenceError("not_defined", name); | 918 return ReferenceError("not_defined", name); |
| 908 } | 919 } |
| 909 LOG(isolate(), SuspectReadEvent(*name, *object)); | 920 LOG(isolate(), SuspectReadEvent(*name, *object)); |
| 910 } | 921 } |
| 911 | 922 |
| 912 // Update inline cache and stub cache. | 923 // Update inline cache and stub cache. |
| (...skipping 18 matching lines...) Expand all Loading... |
| 931 | 942 |
| 932 // Get the property. | 943 // Get the property. |
| 933 return object->GetProperty(*object, &lookup, *name, &attr); | 944 return object->GetProperty(*object, &lookup, *name, &attr); |
| 934 } | 945 } |
| 935 | 946 |
| 936 | 947 |
| 937 void LoadIC::UpdateCaches(LookupResult* lookup, | 948 void LoadIC::UpdateCaches(LookupResult* lookup, |
| 938 State state, | 949 State state, |
| 939 Handle<Object> object, | 950 Handle<Object> object, |
| 940 Handle<String> name) { | 951 Handle<String> name) { |
| 952 #if DEBUG_LOADIC |
| 953 PrintF("==============================3 LoadIC::UpdateCaches "); |
| 954 name->Print(); |
| 955 PrintF(", state=%s\n", Code::ICState2String(state)); |
| 956 #endif |
| 941 // Bail out if the result is not cacheable. | 957 // Bail out if the result is not cacheable. |
| 942 if (!lookup->IsCacheable()) return; | 958 if (!lookup->IsCacheable()) return; |
| 943 | 959 |
| 944 // Loading properties from values is not common, so don't try to | 960 // Loading properties from values is not common, so don't try to |
| 945 // deal with non-JS objects here. | 961 // deal with non-JS objects here. |
| 946 if (!object->IsJSObject()) return; | 962 if (!object->IsJSObject()) return; |
| 947 Handle<JSObject> receiver = Handle<JSObject>::cast(object); | 963 Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
| 948 | 964 |
| 949 if (HasNormalObjectsInPrototypeChain(isolate(), lookup, *object)) return; | 965 if (HasNormalObjectsInPrototypeChain(isolate(), lookup, *object)) return; |
| 950 | 966 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 981 } else { | 997 } else { |
| 982 // There is only one shared stub for loading normalized | 998 // There is only one shared stub for loading normalized |
| 983 // properties. It does not traverse the prototype chain, so the | 999 // properties. It does not traverse the prototype chain, so the |
| 984 // property must be found in the receiver for the stub to be | 1000 // property must be found in the receiver for the stub to be |
| 985 // applicable. | 1001 // applicable. |
| 986 if (!holder.is_identical_to(receiver)) return; | 1002 if (!holder.is_identical_to(receiver)) return; |
| 987 code = isolate()->stub_cache()->ComputeLoadNormal(); | 1003 code = isolate()->stub_cache()->ComputeLoadNormal(); |
| 988 } | 1004 } |
| 989 break; | 1005 break; |
| 990 case CALLBACKS: { | 1006 case CALLBACKS: { |
| 991 Handle<Object> callback_object(lookup->GetCallbackObject()); | 1007 #if DEBUG_LOADIC |
| 992 if (!callback_object->IsAccessorInfo()) return; | 1008 PrintF("==============================4 LoadIC::UpdateCaches "); |
| 993 Handle<AccessorInfo> callback = | 1009 name->Print(); |
| 994 Handle<AccessorInfo>::cast(callback_object); | 1010 PrintF(", CALLBACKS case, target="); |
| 995 if (v8::ToCData<Address>(callback->getter()) == 0) return; | 1011 target()->Print(); |
| 996 code = isolate()->stub_cache()->ComputeLoadCallback( | 1012 PrintF("\n"); |
| 997 name, receiver, holder, callback); | 1013 #endif |
| 1014 Handle<Object> callback(lookup->GetCallbackObject()); |
| 1015 if (callback->IsAccessorInfo()) { |
| 1016 Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(callback); |
| 1017 if (v8::ToCData<Address>(info->getter()) == 0) return; |
| 1018 code = isolate()->stub_cache()->ComputeLoadCallback( |
| 1019 name, receiver, holder, info); |
| 1020 } else if (callback->IsAccessorPair()) { |
| 1021 Handle<Object> getter(Handle<AccessorPair>::cast(callback)->getter()); |
| 1022 if (!getter->IsJSFunction()) return; |
| 1023 if (holder->IsGlobalObject()) return; |
| 1024 if (!receiver->HasFastProperties()) return; |
| 1025 code = isolate()->stub_cache()->ComputeLoadViaGetter( |
| 1026 name, receiver, holder, Handle<JSFunction>::cast(getter)); |
| 1027 // TODO(svenpanne) Remove me when all platforms work. |
| 1028 if (code.is_null()) return; |
| 1029 #if DEBUG_LOADIC |
| 1030 PrintF("==============================5 LoadIC::UpdateCaches "); |
| 1031 name->Print(); |
| 1032 PrintF(", code="); |
| 1033 code->Print(); |
| 1034 PrintF("\n"); |
| 1035 #endif |
| 1036 } else { |
| 1037 ASSERT(callback->IsForeign()); |
| 1038 // No IC support for old-style native accessors. |
| 1039 return; |
| 1040 } |
| 998 break; | 1041 break; |
| 999 } | 1042 } |
| 1000 case INTERCEPTOR: | 1043 case INTERCEPTOR: |
| 1001 ASSERT(HasInterceptorGetter(*holder)); | 1044 ASSERT(HasInterceptorGetter(*holder)); |
| 1002 code = isolate()->stub_cache()->ComputeLoadInterceptor( | 1045 code = isolate()->stub_cache()->ComputeLoadInterceptor( |
| 1003 name, receiver, holder); | 1046 name, receiver, holder); |
| 1004 break; | 1047 break; |
| 1005 default: | 1048 default: |
| 1006 return; | 1049 return; |
| 1007 } | 1050 } |
| (...skipping 1012 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2020 if (raw_function->is_compiled()) return raw_function; | 2063 if (raw_function->is_compiled()) return raw_function; |
| 2021 | 2064 |
| 2022 Handle<JSFunction> function(raw_function); | 2065 Handle<JSFunction> function(raw_function); |
| 2023 JSFunction::CompileLazy(function, CLEAR_EXCEPTION); | 2066 JSFunction::CompileLazy(function, CLEAR_EXCEPTION); |
| 2024 return *function; | 2067 return *function; |
| 2025 } | 2068 } |
| 2026 | 2069 |
| 2027 | 2070 |
| 2028 // Used from ic-<arch>.cc. | 2071 // Used from ic-<arch>.cc. |
| 2029 RUNTIME_FUNCTION(MaybeObject*, LoadIC_Miss) { | 2072 RUNTIME_FUNCTION(MaybeObject*, LoadIC_Miss) { |
| 2073 #if DEBUG_LOADIC |
| 2074 PrintF("==============================1 LoadIC_Miss "); |
| 2075 args.at<String>(1)->Print(); |
| 2076 PrintF("\n"); |
| 2077 #endif |
| 2030 HandleScope scope(isolate); | 2078 HandleScope scope(isolate); |
| 2031 ASSERT(args.length() == 2); | 2079 ASSERT(args.length() == 2); |
| 2032 LoadIC ic(isolate); | 2080 LoadIC ic(isolate); |
| 2033 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); | 2081 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); |
| 2034 return ic.Load(state, args.at<Object>(0), args.at<String>(1)); | 2082 return ic.Load(state, args.at<Object>(0), args.at<String>(1)); |
| 2035 } | 2083 } |
| 2036 | 2084 |
| 2037 | 2085 |
| 2038 // Used from ic-<arch>.cc | 2086 // Used from ic-<arch>.cc |
| 2039 RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_Miss) { | 2087 RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_Miss) { |
| (...skipping 599 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2639 #undef ADDR | 2687 #undef ADDR |
| 2640 }; | 2688 }; |
| 2641 | 2689 |
| 2642 | 2690 |
| 2643 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 2691 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
| 2644 return IC_utilities[id]; | 2692 return IC_utilities[id]; |
| 2645 } | 2693 } |
| 2646 | 2694 |
| 2647 | 2695 |
| 2648 } } // namespace v8::internal | 2696 } } // namespace v8::internal |
| OLD | NEW |