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 |