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 979 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
990 } | 990 } |
991 | 991 |
992 Handle<Code> ic = isolate()->stub_cache()->ComputePolymorphicIC( | 992 Handle<Code> ic = isolate()->stub_cache()->ComputePolymorphicIC( |
993 &types, &handlers, number_of_valid_types, name, extra_ic_state()); | 993 &types, &handlers, number_of_valid_types, name, extra_ic_state()); |
994 set_target(*ic); | 994 set_target(*ic); |
995 return true; | 995 return true; |
996 } | 996 } |
997 | 997 |
998 | 998 |
999 Handle<Type> IC::CurrentTypeOf(Handle<Object> object, Isolate* isolate) { | 999 Handle<Type> IC::CurrentTypeOf(Handle<Object> object, Isolate* isolate) { |
1000 Type* type = object->IsJSGlobalObject() | 1000 return object->IsJSGlobalObject() |
1001 ? Type::Constant(Handle<JSGlobalObject>::cast(object)) | 1001 ? Type::Constant(Handle<JSGlobalObject>::cast(object), isolate) |
1002 : Type::OfCurrently(object); | 1002 : Type::OfCurrently(object, isolate); |
1003 return handle(type, isolate); | |
1004 } | 1003 } |
1005 | 1004 |
1006 | 1005 |
1007 Handle<Map> IC::TypeToMap(Type* type, Isolate* isolate) { | 1006 Handle<Map> IC::TypeToMap(Type* type, Isolate* isolate) { |
1008 if (type->Is(Type::Number())) return isolate->factory()->heap_number_map(); | 1007 if (type->Is(Type::Number())) return isolate->factory()->heap_number_map(); |
1009 if (type->Is(Type::Boolean())) return isolate->factory()->oddball_map(); | 1008 if (type->Is(Type::Boolean())) return isolate->factory()->oddball_map(); |
1010 if (type->IsConstant()) { | 1009 if (type->IsConstant()) { |
1011 return handle(Handle<JSGlobalObject>::cast(type->AsConstant())->map()); | 1010 return handle(Handle<JSGlobalObject>::cast(type->AsConstant())->map()); |
1012 } | 1011 } |
1013 ASSERT(type->IsClass()); | 1012 ASSERT(type->IsClass()); |
1014 return type->AsClass(); | 1013 return type->AsClass(); |
1015 } | 1014 } |
1016 | 1015 |
1017 | 1016 |
1018 Type* IC::MapToType(Handle<Map> map) { | 1017 Handle<Type> IC::MapToType(Handle<Map> map) { |
1019 if (map->instance_type() == HEAP_NUMBER_TYPE) return Type::Number(); | 1018 Isolate* isolate = map->GetIsolate(); |
| 1019 if (map->instance_type() == HEAP_NUMBER_TYPE) return Type::Number(isolate); |
1020 // The only oddballs that can be recorded in ICs are booleans. | 1020 // The only oddballs that can be recorded in ICs are booleans. |
1021 if (map->instance_type() == ODDBALL_TYPE) return Type::Boolean(); | 1021 if (map->instance_type() == ODDBALL_TYPE) return Type::Boolean(isolate); |
1022 return Type::Class(map); | 1022 return Type::Class(map, isolate); |
1023 } | 1023 } |
1024 | 1024 |
1025 | 1025 |
1026 void IC::UpdateMonomorphicIC(Handle<Type> type, | 1026 void IC::UpdateMonomorphicIC(Handle<Type> type, |
1027 Handle<Code> handler, | 1027 Handle<Code> handler, |
1028 Handle<String> name) { | 1028 Handle<String> name) { |
1029 if (!handler->is_handler()) return set_target(*handler); | 1029 if (!handler->is_handler()) return set_target(*handler); |
1030 Handle<Code> ic = isolate()->stub_cache()->ComputeMonomorphicIC( | 1030 Handle<Code> ic = isolate()->stub_cache()->ComputeMonomorphicIC( |
1031 name, type, handler, extra_ic_state()); | 1031 name, type, handler, extra_ic_state()); |
1032 set_target(*ic); | 1032 set_target(*ic); |
1033 } | 1033 } |
1034 | 1034 |
1035 | 1035 |
1036 void IC::CopyICToMegamorphicCache(Handle<String> name) { | 1036 void IC::CopyICToMegamorphicCache(Handle<String> name) { |
1037 TypeHandleList types; | 1037 TypeHandleList types; |
1038 CodeHandleList handlers; | 1038 CodeHandleList handlers; |
1039 target()->FindAllTypes(&types); | 1039 target()->FindAllTypes(&types); |
1040 if (!target()->FindHandlers(&handlers, types.length())) return; | 1040 if (!target()->FindHandlers(&handlers, types.length())) return; |
1041 for (int i = 0; i < types.length(); i++) { | 1041 for (int i = 0; i < types.length(); i++) { |
1042 UpdateMegamorphicCache(*types.at(i), *name, *handlers.at(i)); | 1042 UpdateMegamorphicCache(*types.at(i), *name, *handlers.at(i)); |
1043 } | 1043 } |
1044 } | 1044 } |
1045 | 1045 |
1046 | 1046 |
1047 bool IC::IsTransitionOfMonomorphicTarget(Type* type) { | 1047 bool IC::IsTransitionOfMonomorphicTarget(Handle<Type> type) { |
1048 if (!type->IsClass()) return false; | 1048 if (!type->IsClass()) return false; |
1049 Map* receiver_map = *type->AsClass(); | 1049 Map* receiver_map = *type->AsClass(); |
1050 Map* current_map = target()->FindFirstMap(); | 1050 Map* current_map = target()->FindFirstMap(); |
1051 ElementsKind receiver_elements_kind = receiver_map->elements_kind(); | 1051 ElementsKind receiver_elements_kind = receiver_map->elements_kind(); |
1052 bool more_general_transition = | 1052 bool more_general_transition = |
1053 IsMoreGeneralElementsKindTransition( | 1053 IsMoreGeneralElementsKindTransition( |
1054 current_map->elements_kind(), receiver_elements_kind); | 1054 current_map->elements_kind(), receiver_elements_kind); |
1055 Map* transitioned_map = more_general_transition | 1055 Map* transitioned_map = more_general_transition |
1056 ? current_map->LookupElementsTransitionMap(receiver_elements_kind) | 1056 ? current_map->LookupElementsTransitionMap(receiver_elements_kind) |
1057 : NULL; | 1057 : NULL; |
(...skipping 11 matching lines...) Expand all Loading... |
1069 case MONOMORPHIC_PROTOTYPE_FAILURE: | 1069 case MONOMORPHIC_PROTOTYPE_FAILURE: |
1070 UpdateMonomorphicIC(type, code, name); | 1070 UpdateMonomorphicIC(type, code, name); |
1071 break; | 1071 break; |
1072 case MONOMORPHIC: { | 1072 case MONOMORPHIC: { |
1073 // For now, call stubs are allowed to rewrite to the same stub. This | 1073 // For now, call stubs are allowed to rewrite to the same stub. This |
1074 // happens e.g., when the field does not contain a function. | 1074 // happens e.g., when the field does not contain a function. |
1075 ASSERT(target()->is_call_stub() || | 1075 ASSERT(target()->is_call_stub() || |
1076 target()->is_keyed_call_stub() || | 1076 target()->is_keyed_call_stub() || |
1077 !target().is_identical_to(code)); | 1077 !target().is_identical_to(code)); |
1078 Code* old_handler = target()->FindFirstHandler(); | 1078 Code* old_handler = target()->FindFirstHandler(); |
1079 if (old_handler == *code && IsTransitionOfMonomorphicTarget(*type)) { | 1079 if (old_handler == *code && IsTransitionOfMonomorphicTarget(type)) { |
1080 UpdateMonomorphicIC(type, code, name); | 1080 UpdateMonomorphicIC(type, code, name); |
1081 break; | 1081 break; |
1082 } | 1082 } |
1083 // Fall through. | 1083 // Fall through. |
1084 } | 1084 } |
1085 case POLYMORPHIC: | 1085 case POLYMORPHIC: |
1086 if (!target()->is_keyed_stub()) { | 1086 if (!target()->is_keyed_stub()) { |
1087 if (UpdatePolymorphicIC(type, name, code)) break; | 1087 if (UpdatePolymorphicIC(type, name, code)) break; |
1088 CopyICToMegamorphicCache(name); | 1088 CopyICToMegamorphicCache(name); |
1089 } | 1089 } |
(...skipping 1523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2613 GENERATE(Token::MOD, SMI, 2048, SMI, NO_OVERWRITE); | 2613 GENERATE(Token::MOD, SMI, 2048, SMI, NO_OVERWRITE); |
2614 #undef GENERATE | 2614 #undef GENERATE |
2615 } | 2615 } |
2616 | 2616 |
2617 | 2617 |
2618 Handle<Type> BinaryOpIC::State::GetResultType(Isolate* isolate) const { | 2618 Handle<Type> BinaryOpIC::State::GetResultType(Isolate* isolate) const { |
2619 Kind result_kind = result_kind_; | 2619 Kind result_kind = result_kind_; |
2620 if (HasSideEffects()) { | 2620 if (HasSideEffects()) { |
2621 result_kind = NONE; | 2621 result_kind = NONE; |
2622 } else if (result_kind == GENERIC && op_ == Token::ADD) { | 2622 } else if (result_kind == GENERIC && op_ == Token::ADD) { |
2623 return handle(Type::Union(handle(Type::Number(), isolate), | 2623 return Type::Union(Type::Number(isolate), Type::String(isolate), isolate); |
2624 handle(Type::String(), isolate)), isolate); | |
2625 } else if (result_kind == NUMBER && op_ == Token::SHR) { | 2624 } else if (result_kind == NUMBER && op_ == Token::SHR) { |
2626 return handle(Type::Unsigned32(), isolate); | 2625 return Type::Unsigned32(isolate); |
2627 } | 2626 } |
2628 ASSERT_NE(GENERIC, result_kind); | 2627 ASSERT_NE(GENERIC, result_kind); |
2629 return KindToType(result_kind, isolate); | 2628 return KindToType(result_kind, isolate); |
2630 } | 2629 } |
2631 | 2630 |
2632 | 2631 |
2633 void BinaryOpIC::State::Print(StringStream* stream) const { | 2632 void BinaryOpIC::State::Print(StringStream* stream) const { |
2634 stream->Add("(%s", Token::Name(op_)); | 2633 stream->Add("(%s", Token::Name(op_)); |
2635 if (mode_ == OVERWRITE_LEFT) stream->Add("_ReuseLeft"); | 2634 if (mode_ == OVERWRITE_LEFT) stream->Add("_ReuseLeft"); |
2636 else if (mode_ == OVERWRITE_RIGHT) stream->Add("_ReuseRight"); | 2635 else if (mode_ == OVERWRITE_RIGHT) stream->Add("_ReuseRight"); |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2751 case STRING: return "String"; | 2750 case STRING: return "String"; |
2752 case GENERIC: return "Generic"; | 2751 case GENERIC: return "Generic"; |
2753 } | 2752 } |
2754 UNREACHABLE(); | 2753 UNREACHABLE(); |
2755 return NULL; | 2754 return NULL; |
2756 } | 2755 } |
2757 | 2756 |
2758 | 2757 |
2759 // static | 2758 // static |
2760 Handle<Type> BinaryOpIC::State::KindToType(Kind kind, Isolate* isolate) { | 2759 Handle<Type> BinaryOpIC::State::KindToType(Kind kind, Isolate* isolate) { |
2761 Type* type = NULL; | |
2762 switch (kind) { | 2760 switch (kind) { |
2763 case NONE: type = Type::None(); break; | 2761 case NONE: return Type::None(isolate); |
2764 case SMI: type = Type::Smi(); break; | 2762 case SMI: return Type::Smi(isolate); |
2765 case INT32: type = Type::Signed32(); break; | 2763 case INT32: return Type::Signed32(isolate); |
2766 case NUMBER: type = Type::Number(); break; | 2764 case NUMBER: return Type::Number(isolate); |
2767 case STRING: type = Type::String(); break; | 2765 case STRING: return Type::String(isolate); |
2768 case GENERIC: type = Type::Any(); break; | 2766 case GENERIC: return Type::Any(isolate); |
2769 } | 2767 } |
2770 return handle(type, isolate); | 2768 UNREACHABLE(); |
| 2769 return Handle<Type>(); |
2771 } | 2770 } |
2772 | 2771 |
2773 | 2772 |
2774 MaybeObject* BinaryOpIC::Transition(Handle<AllocationSite> allocation_site, | 2773 MaybeObject* BinaryOpIC::Transition(Handle<AllocationSite> allocation_site, |
2775 Handle<Object> left, | 2774 Handle<Object> left, |
2776 Handle<Object> right) { | 2775 Handle<Object> right) { |
2777 State state(target()->extended_extra_ic_state()); | 2776 State state(target()->extended_extra_ic_state()); |
2778 | 2777 |
2779 // Compute the actual result using the builtin for the binary operation. | 2778 // Compute the actual result using the builtin for the binary operation. |
2780 Object* builtin = isolate()->js_builtins_object()->javascript_builtin( | 2779 Object* builtin = isolate()->js_builtins_object()->javascript_builtin( |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2895 UNREACHABLE(); | 2894 UNREACHABLE(); |
2896 return NULL; | 2895 return NULL; |
2897 } | 2896 } |
2898 | 2897 |
2899 | 2898 |
2900 Handle<Type> CompareIC::StateToType( | 2899 Handle<Type> CompareIC::StateToType( |
2901 Isolate* isolate, | 2900 Isolate* isolate, |
2902 CompareIC::State state, | 2901 CompareIC::State state, |
2903 Handle<Map> map) { | 2902 Handle<Map> map) { |
2904 switch (state) { | 2903 switch (state) { |
2905 case CompareIC::UNINITIALIZED: | 2904 case CompareIC::UNINITIALIZED: return Type::None(isolate); |
2906 return handle(Type::None(), isolate); | 2905 case CompareIC::SMI: return Type::Smi(isolate); |
2907 case CompareIC::SMI: | 2906 case CompareIC::NUMBER: return Type::Number(isolate); |
2908 return handle(Type::Smi(), isolate); | 2907 case CompareIC::STRING: return Type::String(isolate); |
2909 case CompareIC::NUMBER: | |
2910 return handle(Type::Number(), isolate); | |
2911 case CompareIC::STRING: | |
2912 return handle(Type::String(), isolate); | |
2913 case CompareIC::INTERNALIZED_STRING: | 2908 case CompareIC::INTERNALIZED_STRING: |
2914 return handle(Type::InternalizedString(), isolate); | 2909 return Type::InternalizedString(isolate); |
2915 case CompareIC::UNIQUE_NAME: | 2910 case CompareIC::UNIQUE_NAME: return Type::UniqueName(isolate); |
2916 return handle(Type::UniqueName(), isolate); | 2911 case CompareIC::OBJECT: return Type::Receiver(isolate); |
2917 case CompareIC::OBJECT: | |
2918 return handle(Type::Receiver(), isolate); | |
2919 case CompareIC::KNOWN_OBJECT: | 2912 case CompareIC::KNOWN_OBJECT: |
2920 return handle( | 2913 return map.is_null() |
2921 map.is_null() ? Type::Receiver() : Type::Class(map), isolate); | 2914 ? Type::Receiver(isolate) : Type::Class(map, isolate); |
2922 case CompareIC::GENERIC: | 2915 case CompareIC::GENERIC: return Type::Any(isolate); |
2923 return handle(Type::Any(), isolate); | |
2924 } | 2916 } |
2925 UNREACHABLE(); | 2917 UNREACHABLE(); |
2926 return Handle<Type>(); | 2918 return Handle<Type>(); |
2927 } | 2919 } |
2928 | 2920 |
2929 | 2921 |
2930 void CompareIC::StubInfoToType(int stub_minor_key, | 2922 void CompareIC::StubInfoToType(int stub_minor_key, |
2931 Handle<Type>* left_type, | 2923 Handle<Type>* left_type, |
2932 Handle<Type>* right_type, | 2924 Handle<Type>* right_type, |
2933 Handle<Type>* overall_type, | 2925 Handle<Type>* overall_type, |
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3229 #undef ADDR | 3221 #undef ADDR |
3230 }; | 3222 }; |
3231 | 3223 |
3232 | 3224 |
3233 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 3225 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
3234 return IC_utilities[id]; | 3226 return IC_utilities[id]; |
3235 } | 3227 } |
3236 | 3228 |
3237 | 3229 |
3238 } } // namespace v8::internal | 3230 } } // namespace v8::internal |
OLD | NEW |