| 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/base/bits.h" | 10 #include "src/base/bits.h" |
| (...skipping 647 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 658 nexus->ConfigureMegamorphic(); | 658 nexus->ConfigureMegamorphic(); |
| 659 } else { | 659 } else { |
| 660 UNREACHABLE(); | 660 UNREACHABLE(); |
| 661 } | 661 } |
| 662 } else if (kind() == Code::KEYED_LOAD_IC) { | 662 } else if (kind() == Code::KEYED_LOAD_IC) { |
| 663 KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>(); | 663 KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>(); |
| 664 if (new_state == GENERIC) { | 664 if (new_state == GENERIC) { |
| 665 nexus->ConfigureGeneric(); | 665 nexus->ConfigureGeneric(); |
| 666 } else if (new_state == PREMONOMORPHIC) { | 666 } else if (new_state == PREMONOMORPHIC) { |
| 667 nexus->ConfigurePremonomorphic(); | 667 nexus->ConfigurePremonomorphic(); |
| 668 } else if (new_state == MEGAMORPHIC) { | |
| 669 nexus->ConfigureMegamorphic(); | |
| 670 } else { | 668 } else { |
| 671 UNREACHABLE(); | 669 UNREACHABLE(); |
| 672 } | 670 } |
| 673 } else { | 671 } else { |
| 674 UNREACHABLE(); | 672 UNREACHABLE(); |
| 675 } | 673 } |
| 676 | 674 |
| 677 OnTypeFeedbackChanged(isolate(), get_host(), *vector(), saved_state(), | 675 OnTypeFeedbackChanged(isolate(), get_host(), *vector(), saved_state(), |
| 678 new_state); | 676 new_state); |
| 679 } | 677 } |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 964 case PROTOTYPE_FAILURE: | 962 case PROTOTYPE_FAILURE: |
| 965 case MONOMORPHIC: | 963 case MONOMORPHIC: |
| 966 case POLYMORPHIC: | 964 case POLYMORPHIC: |
| 967 if (!target()->is_keyed_stub() || state() == PROTOTYPE_FAILURE) { | 965 if (!target()->is_keyed_stub() || state() == PROTOTYPE_FAILURE) { |
| 968 if (UpdatePolymorphicIC(name, code)) break; | 966 if (UpdatePolymorphicIC(name, code)) break; |
| 969 // For keyed stubs, we can't know whether old handlers were for the | 967 // For keyed stubs, we can't know whether old handlers were for the |
| 970 // same key. | 968 // same key. |
| 971 CopyICToMegamorphicCache(name); | 969 CopyICToMegamorphicCache(name); |
| 972 } | 970 } |
| 973 if (UseVector()) { | 971 if (UseVector()) { |
| 974 ConfigureVectorState(MEGAMORPHIC); | 972 ConfigureVectorState(kind() == Code::KEYED_LOAD_IC ? GENERIC |
| 973 : MEGAMORPHIC); |
| 975 } else { | 974 } else { |
| 976 set_target(*megamorphic_stub()); | 975 set_target(*megamorphic_stub()); |
| 977 } | 976 } |
| 978 // Fall through. | 977 // Fall through. |
| 979 case MEGAMORPHIC: | 978 case MEGAMORPHIC: |
| 980 UpdateMegamorphicCache(*receiver_type(), *name, *code); | 979 UpdateMegamorphicCache(*receiver_type(), *name, *code); |
| 981 // Indicate that we've handled this case. | 980 // Indicate that we've handled this case. |
| 982 target_set_ = true; | 981 target_set_ = true; |
| 983 break; | 982 break; |
| 984 case DEBUG_STUB: | 983 case DEBUG_STUB: |
| (...skipping 1325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2310 HandleScope scope(isolate); | 2309 HandleScope scope(isolate); |
| 2311 Handle<Object> receiver = args.at<Object>(0); | 2310 Handle<Object> receiver = args.at<Object>(0); |
| 2312 Handle<Name> key = args.at<Name>(1); | 2311 Handle<Name> key = args.at<Name>(1); |
| 2313 Handle<Object> result; | 2312 Handle<Object> result; |
| 2314 | 2313 |
| 2315 if (FLAG_vector_ics) { | 2314 if (FLAG_vector_ics) { |
| 2316 DCHECK(args.length() == 4); | 2315 DCHECK(args.length() == 4); |
| 2317 Handle<Smi> slot = args.at<Smi>(2); | 2316 Handle<Smi> slot = args.at<Smi>(2); |
| 2318 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(3); | 2317 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(3); |
| 2319 FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value()); | 2318 FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value()); |
| 2320 LoadICNexus nexus(vector, vector_slot); | 2319 // A monomorphic or polymorphic KeyedLoadIC with a string key can call the |
| 2321 LoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); | 2320 // LoadIC miss handler if the handler misses. Since the vector Nexus is |
| 2322 ic.UpdateState(receiver, key); | 2321 // set up outside the IC, handle that here. |
| 2323 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); | 2322 if (vector->GetKind(vector_slot) == Code::LOAD_IC) { |
| 2323 LoadICNexus nexus(vector, vector_slot); |
| 2324 LoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); |
| 2325 ic.UpdateState(receiver, key); |
| 2326 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, |
| 2327 ic.Load(receiver, key)); |
| 2328 } else { |
| 2329 DCHECK(vector->GetKind(vector_slot) == Code::KEYED_LOAD_IC); |
| 2330 KeyedLoadICNexus nexus(vector, vector_slot); |
| 2331 KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus); |
| 2332 ic.UpdateState(receiver, key); |
| 2333 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, |
| 2334 ic.Load(receiver, key)); |
| 2335 } |
| 2324 } else { | 2336 } else { |
| 2325 DCHECK(args.length() == 2); | 2337 DCHECK(args.length() == 2); |
| 2326 LoadIC ic(IC::NO_EXTRA_FRAME, isolate); | 2338 LoadIC ic(IC::NO_EXTRA_FRAME, isolate); |
| 2327 ic.UpdateState(receiver, key); | 2339 ic.UpdateState(receiver, key); |
| 2328 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); | 2340 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); |
| 2329 } | 2341 } |
| 2330 return *result; | 2342 return *result; |
| 2331 } | 2343 } |
| 2332 | 2344 |
| 2333 | 2345 |
| (...skipping 621 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2955 HandleScope scope(isolate); | 2967 HandleScope scope(isolate); |
| 2956 Handle<Object> receiver = args.at<Object>(0); | 2968 Handle<Object> receiver = args.at<Object>(0); |
| 2957 Handle<Name> key = args.at<Name>(1); | 2969 Handle<Name> key = args.at<Name>(1); |
| 2958 Handle<Object> result; | 2970 Handle<Object> result; |
| 2959 | 2971 |
| 2960 if (FLAG_vector_ics) { | 2972 if (FLAG_vector_ics) { |
| 2961 DCHECK(args.length() == 4); | 2973 DCHECK(args.length() == 4); |
| 2962 Handle<Smi> slot = args.at<Smi>(2); | 2974 Handle<Smi> slot = args.at<Smi>(2); |
| 2963 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(3); | 2975 Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(3); |
| 2964 FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value()); | 2976 FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value()); |
| 2965 LoadICNexus nexus(vector, vector_slot); | 2977 // A monomorphic or polymorphic KeyedLoadIC with a string key can call the |
| 2966 LoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); | 2978 // LoadIC miss handler if the handler misses. Since the vector Nexus is |
| 2967 ic.UpdateState(receiver, key); | 2979 // set up outside the IC, handle that here. |
| 2968 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); | 2980 if (vector->GetKind(vector_slot) == Code::LOAD_IC) { |
| 2981 LoadICNexus nexus(vector, vector_slot); |
| 2982 LoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); |
| 2983 ic.UpdateState(receiver, key); |
| 2984 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, |
| 2985 ic.Load(receiver, key)); |
| 2986 } else { |
| 2987 DCHECK(vector->GetKind(vector_slot) == Code::KEYED_LOAD_IC); |
| 2988 KeyedLoadICNexus nexus(vector, vector_slot); |
| 2989 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); |
| 2990 ic.UpdateState(receiver, key); |
| 2991 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, |
| 2992 ic.Load(receiver, key)); |
| 2993 } |
| 2969 } else { | 2994 } else { |
| 2970 DCHECK(args.length() == 2); | 2995 DCHECK(args.length() == 2); |
| 2971 LoadIC ic(IC::EXTRA_CALL_FRAME, isolate); | 2996 LoadIC ic(IC::EXTRA_CALL_FRAME, isolate); |
| 2972 ic.UpdateState(receiver, key); | 2997 ic.UpdateState(receiver, key); |
| 2973 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); | 2998 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); |
| 2974 } | 2999 } |
| 2975 | 3000 |
| 2976 return *result; | 3001 return *result; |
| 2977 } | 3002 } |
| 2978 | 3003 |
| 2979 | 3004 |
| 2980 static const Address IC_utilities[] = { | 3005 static const Address IC_utilities[] = { |
| 2981 #define ADDR(name) FUNCTION_ADDR(name), | 3006 #define ADDR(name) FUNCTION_ADDR(name), |
| 2982 IC_UTIL_LIST(ADDR) NULL | 3007 IC_UTIL_LIST(ADDR) NULL |
| 2983 #undef ADDR | 3008 #undef ADDR |
| 2984 }; | 3009 }; |
| 2985 | 3010 |
| 2986 | 3011 |
| 2987 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; } | 3012 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; } |
| 2988 } | 3013 } |
| 2989 } // namespace v8::internal | 3014 } // namespace v8::internal |
| OLD | NEW |