| 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 |