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 |