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 990 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1001 } | 1001 } |
1002 | 1002 |
1003 Handle<Code> ic = isolate()->stub_cache()->ComputePolymorphicIC( | 1003 Handle<Code> ic = isolate()->stub_cache()->ComputePolymorphicIC( |
1004 &types, &handlers, number_of_valid_types, name, extra_ic_state()); | 1004 &types, &handlers, number_of_valid_types, name, extra_ic_state()); |
1005 set_target(*ic); | 1005 set_target(*ic); |
1006 return true; | 1006 return true; |
1007 } | 1007 } |
1008 | 1008 |
1009 | 1009 |
1010 Handle<Type> IC::CurrentTypeOf(Handle<Object> object, Isolate* isolate) { | 1010 Handle<Type> IC::CurrentTypeOf(Handle<Object> object, Isolate* isolate) { |
1011 Type* type = object->IsJSGlobalObject() | 1011 return object->IsJSGlobalObject() |
1012 ? Type::Constant(Handle<JSGlobalObject>::cast(object)) | 1012 ? Type::Constant(Handle<JSGlobalObject>::cast(object), isolate) |
titzer
2013/12/17 09:13:07
Side question: It's weird the type of the global o
rossberg
2013/12/17 09:33:13
The global object is handled rather specially in t
| |
1013 : Type::OfCurrently(object); | 1013 : Type::OfCurrently(object, isolate); |
1014 return handle(type, isolate); | |
1015 } | 1014 } |
1016 | 1015 |
1017 | 1016 |
1018 Handle<Map> IC::TypeToMap(Type* type, Isolate* isolate) { | 1017 Handle<Map> IC::TypeToMap(Type* type, Isolate* isolate) { |
1019 if (type->Is(Type::Number())) return isolate->factory()->heap_number_map(); | 1018 if (type->Is(Type::Number())) return isolate->factory()->heap_number_map(); |
1020 if (type->Is(Type::Boolean())) return isolate->factory()->oddball_map(); | 1019 if (type->Is(Type::Boolean())) return isolate->factory()->oddball_map(); |
1021 if (type->IsConstant()) { | 1020 if (type->IsConstant()) { |
1022 return handle(Handle<JSGlobalObject>::cast(type->AsConstant())->map()); | 1021 return handle(Handle<JSGlobalObject>::cast(type->AsConstant())->map()); |
1023 } | 1022 } |
1024 ASSERT(type->IsClass()); | 1023 ASSERT(type->IsClass()); |
1025 return type->AsClass(); | 1024 return type->AsClass(); |
1026 } | 1025 } |
1027 | 1026 |
1028 | 1027 |
1029 Type* IC::MapToType(Handle<Map> map) { | 1028 Handle<Type> IC::MapToType(Handle<Map> map) { |
1030 if (map->instance_type() == HEAP_NUMBER_TYPE) return Type::Number(); | 1029 Isolate* isolate = map->GetIsolate(); |
1030 if (map->instance_type() == HEAP_NUMBER_TYPE) return Type::Number(isolate); | |
1031 // The only oddballs that can be recorded in ICs are booleans. | 1031 // The only oddballs that can be recorded in ICs are booleans. |
1032 if (map->instance_type() == ODDBALL_TYPE) return Type::Boolean(); | 1032 if (map->instance_type() == ODDBALL_TYPE) return Type::Boolean(isolate); |
1033 return Type::Class(map); | 1033 return Type::Class(map, isolate); |
1034 } | 1034 } |
1035 | 1035 |
1036 | 1036 |
1037 void IC::UpdateMonomorphicIC(Handle<Type> type, | 1037 void IC::UpdateMonomorphicIC(Handle<Type> type, |
1038 Handle<Code> handler, | 1038 Handle<Code> handler, |
1039 Handle<String> name) { | 1039 Handle<String> name) { |
1040 if (!handler->is_handler()) return set_target(*handler); | 1040 if (!handler->is_handler()) return set_target(*handler); |
1041 Handle<Code> ic = isolate()->stub_cache()->ComputeMonomorphicIC( | 1041 Handle<Code> ic = isolate()->stub_cache()->ComputeMonomorphicIC( |
1042 name, type, handler, extra_ic_state()); | 1042 name, type, handler, extra_ic_state()); |
1043 set_target(*ic); | 1043 set_target(*ic); |
1044 } | 1044 } |
1045 | 1045 |
1046 | 1046 |
1047 void IC::CopyICToMegamorphicCache(Handle<String> name) { | 1047 void IC::CopyICToMegamorphicCache(Handle<String> name) { |
1048 TypeHandleList types; | 1048 TypeHandleList types; |
1049 CodeHandleList handlers; | 1049 CodeHandleList handlers; |
1050 target()->FindAllTypes(&types); | 1050 target()->FindAllTypes(&types); |
1051 if (!target()->FindHandlers(&handlers, types.length())) return; | 1051 if (!target()->FindHandlers(&handlers, types.length())) return; |
1052 for (int i = 0; i < types.length(); i++) { | 1052 for (int i = 0; i < types.length(); i++) { |
1053 UpdateMegamorphicCache(*types.at(i), *name, *handlers.at(i)); | 1053 UpdateMegamorphicCache(*types.at(i), *name, *handlers.at(i)); |
1054 } | 1054 } |
1055 } | 1055 } |
1056 | 1056 |
1057 | 1057 |
1058 bool IC::IsTransitionOfMonomorphicTarget(Type* type) { | 1058 bool IC::IsTransitionOfMonomorphicTarget(Handle<Type> type) { |
1059 if (!type->IsClass()) return false; | 1059 if (!type->IsClass()) return false; |
1060 Map* receiver_map = *type->AsClass(); | 1060 Map* receiver_map = *type->AsClass(); |
1061 Map* current_map = target()->FindFirstMap(); | 1061 Map* current_map = target()->FindFirstMap(); |
1062 ElementsKind receiver_elements_kind = receiver_map->elements_kind(); | 1062 ElementsKind receiver_elements_kind = receiver_map->elements_kind(); |
1063 bool more_general_transition = | 1063 bool more_general_transition = |
1064 IsMoreGeneralElementsKindTransition( | 1064 IsMoreGeneralElementsKindTransition( |
1065 current_map->elements_kind(), receiver_elements_kind); | 1065 current_map->elements_kind(), receiver_elements_kind); |
1066 Map* transitioned_map = more_general_transition | 1066 Map* transitioned_map = more_general_transition |
1067 ? current_map->LookupElementsTransitionMap(receiver_elements_kind) | 1067 ? current_map->LookupElementsTransitionMap(receiver_elements_kind) |
1068 : NULL; | 1068 : NULL; |
(...skipping 11 matching lines...) Expand all Loading... | |
1080 case MONOMORPHIC_PROTOTYPE_FAILURE: | 1080 case MONOMORPHIC_PROTOTYPE_FAILURE: |
1081 UpdateMonomorphicIC(type, code, name); | 1081 UpdateMonomorphicIC(type, code, name); |
1082 break; | 1082 break; |
1083 case MONOMORPHIC: { | 1083 case MONOMORPHIC: { |
1084 // For now, call stubs are allowed to rewrite to the same stub. This | 1084 // For now, call stubs are allowed to rewrite to the same stub. This |
1085 // happens e.g., when the field does not contain a function. | 1085 // happens e.g., when the field does not contain a function. |
1086 ASSERT(target()->is_call_stub() || | 1086 ASSERT(target()->is_call_stub() || |
1087 target()->is_keyed_call_stub() || | 1087 target()->is_keyed_call_stub() || |
1088 !target().is_identical_to(code)); | 1088 !target().is_identical_to(code)); |
1089 Code* old_handler = target()->FindFirstHandler(); | 1089 Code* old_handler = target()->FindFirstHandler(); |
1090 if (old_handler == *code && IsTransitionOfMonomorphicTarget(*type)) { | 1090 if (old_handler == *code && IsTransitionOfMonomorphicTarget(type)) { |
1091 UpdateMonomorphicIC(type, code, name); | 1091 UpdateMonomorphicIC(type, code, name); |
1092 break; | 1092 break; |
1093 } | 1093 } |
1094 // Fall through. | 1094 // Fall through. |
1095 } | 1095 } |
1096 case POLYMORPHIC: | 1096 case POLYMORPHIC: |
1097 if (!target()->is_keyed_stub()) { | 1097 if (!target()->is_keyed_stub()) { |
1098 if (UpdatePolymorphicIC(type, name, code)) break; | 1098 if (UpdatePolymorphicIC(type, name, code)) break; |
1099 CopyICToMegamorphicCache(name); | 1099 CopyICToMegamorphicCache(name); |
1100 } | 1100 } |
(...skipping 1474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2575 GENERATE(Token::MOD, SMI, 2048, SMI, NO_OVERWRITE); | 2575 GENERATE(Token::MOD, SMI, 2048, SMI, NO_OVERWRITE); |
2576 #undef GENERATE | 2576 #undef GENERATE |
2577 } | 2577 } |
2578 | 2578 |
2579 | 2579 |
2580 Handle<Type> BinaryOpIC::State::GetResultType(Isolate* isolate) const { | 2580 Handle<Type> BinaryOpIC::State::GetResultType(Isolate* isolate) const { |
2581 Kind result_kind = result_kind_; | 2581 Kind result_kind = result_kind_; |
2582 if (HasSideEffects()) { | 2582 if (HasSideEffects()) { |
2583 result_kind = NONE; | 2583 result_kind = NONE; |
2584 } else if (result_kind == GENERIC && op_ == Token::ADD) { | 2584 } else if (result_kind == GENERIC && op_ == Token::ADD) { |
2585 return handle(Type::Union(handle(Type::Number(), isolate), | 2585 return Type::Union(Type::Number(isolate), Type::String(isolate), isolate); |
2586 handle(Type::String(), isolate)), isolate); | |
2587 } else if (result_kind == NUMBER && op_ == Token::SHR) { | 2586 } else if (result_kind == NUMBER && op_ == Token::SHR) { |
2588 return handle(Type::Unsigned32(), isolate); | 2587 return Type::Unsigned32(isolate); |
2589 } | 2588 } |
2590 ASSERT_NE(GENERIC, result_kind); | 2589 ASSERT_NE(GENERIC, result_kind); |
2591 return KindToType(result_kind, isolate); | 2590 return KindToType(result_kind, isolate); |
2592 } | 2591 } |
2593 | 2592 |
2594 | 2593 |
2595 void BinaryOpIC::State::Print(StringStream* stream) const { | 2594 void BinaryOpIC::State::Print(StringStream* stream) const { |
2596 stream->Add("(%s", Token::Name(op_)); | 2595 stream->Add("(%s", Token::Name(op_)); |
2597 if (mode_ == OVERWRITE_LEFT) stream->Add("_ReuseLeft"); | 2596 if (mode_ == OVERWRITE_LEFT) stream->Add("_ReuseLeft"); |
2598 else if (mode_ == OVERWRITE_RIGHT) stream->Add("_ReuseRight"); | 2597 else if (mode_ == OVERWRITE_RIGHT) stream->Add("_ReuseRight"); |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2700 case STRING: return "String"; | 2699 case STRING: return "String"; |
2701 case GENERIC: return "Generic"; | 2700 case GENERIC: return "Generic"; |
2702 } | 2701 } |
2703 UNREACHABLE(); | 2702 UNREACHABLE(); |
2704 return NULL; | 2703 return NULL; |
2705 } | 2704 } |
2706 | 2705 |
2707 | 2706 |
2708 // static | 2707 // static |
2709 Handle<Type> BinaryOpIC::State::KindToType(Kind kind, Isolate* isolate) { | 2708 Handle<Type> BinaryOpIC::State::KindToType(Kind kind, Isolate* isolate) { |
2710 Type* type = NULL; | |
2711 switch (kind) { | 2709 switch (kind) { |
2712 case NONE: type = Type::None(); break; | 2710 case NONE: return Type::None(isolate); |
2713 case SMI: type = Type::Smi(); break; | 2711 case SMI: return Type::Smi(isolate); |
2714 case INT32: type = Type::Signed32(); break; | 2712 case INT32: return Type::Signed32(isolate); |
2715 case NUMBER: type = Type::Number(); break; | 2713 case NUMBER: return Type::Number(isolate); |
2716 case STRING: type = Type::String(); break; | 2714 case STRING: return Type::String(isolate); |
2717 case GENERIC: type = Type::Any(); break; | 2715 case GENERIC: return Type::Any(isolate); |
2718 } | 2716 } |
2719 return handle(type, isolate); | 2717 UNREACHABLE(); |
2718 return Handle<Type>(); | |
2720 } | 2719 } |
2721 | 2720 |
2722 | 2721 |
2723 MaybeObject* BinaryOpIC::Transition(Handle<Object> left, Handle<Object> right) { | 2722 MaybeObject* BinaryOpIC::Transition(Handle<Object> left, Handle<Object> right) { |
2724 State state(target()->extended_extra_ic_state()); | 2723 State state(target()->extended_extra_ic_state()); |
2725 | 2724 |
2726 // Compute the actual result using the builtin for the binary operation. | 2725 // Compute the actual result using the builtin for the binary operation. |
2727 Object* builtin = isolate()->js_builtins_object()->javascript_builtin( | 2726 Object* builtin = isolate()->js_builtins_object()->javascript_builtin( |
2728 TokenToJSBuiltin(state.op())); | 2727 TokenToJSBuiltin(state.op())); |
2729 Handle<JSFunction> function = handle(JSFunction::cast(builtin), isolate()); | 2728 Handle<JSFunction> function = handle(JSFunction::cast(builtin), isolate()); |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2804 UNREACHABLE(); | 2803 UNREACHABLE(); |
2805 return NULL; | 2804 return NULL; |
2806 } | 2805 } |
2807 | 2806 |
2808 | 2807 |
2809 Handle<Type> CompareIC::StateToType( | 2808 Handle<Type> CompareIC::StateToType( |
2810 Isolate* isolate, | 2809 Isolate* isolate, |
2811 CompareIC::State state, | 2810 CompareIC::State state, |
2812 Handle<Map> map) { | 2811 Handle<Map> map) { |
2813 switch (state) { | 2812 switch (state) { |
2814 case CompareIC::UNINITIALIZED: | 2813 case CompareIC::UNINITIALIZED: return Type::None(isolate); |
2815 return handle(Type::None(), isolate); | 2814 case CompareIC::SMI: return Type::Smi(isolate); |
2816 case CompareIC::SMI: | 2815 case CompareIC::NUMBER: return Type::Number(isolate); |
2817 return handle(Type::Smi(), isolate); | 2816 case CompareIC::STRING: return Type::String(isolate); |
2818 case CompareIC::NUMBER: | |
2819 return handle(Type::Number(), isolate); | |
2820 case CompareIC::STRING: | |
2821 return handle(Type::String(), isolate); | |
2822 case CompareIC::INTERNALIZED_STRING: | 2817 case CompareIC::INTERNALIZED_STRING: |
2823 return handle(Type::InternalizedString(), isolate); | 2818 return Type::InternalizedString(isolate); |
2824 case CompareIC::UNIQUE_NAME: | 2819 case CompareIC::UNIQUE_NAME: return Type::UniqueName(isolate); |
2825 return handle(Type::UniqueName(), isolate); | 2820 case CompareIC::OBJECT: return Type::Receiver(isolate); |
2826 case CompareIC::OBJECT: | |
2827 return handle(Type::Receiver(), isolate); | |
2828 case CompareIC::KNOWN_OBJECT: | 2821 case CompareIC::KNOWN_OBJECT: |
2829 return handle( | 2822 return map.is_null() |
2830 map.is_null() ? Type::Receiver() : Type::Class(map), isolate); | 2823 ? Type::Receiver(isolate) : Type::Class(map, isolate); |
2831 case CompareIC::GENERIC: | 2824 case CompareIC::GENERIC: return Type::Any(isolate); |
2832 return handle(Type::Any(), isolate); | |
2833 } | 2825 } |
2834 UNREACHABLE(); | 2826 UNREACHABLE(); |
2835 return Handle<Type>(); | 2827 return Handle<Type>(); |
2836 } | 2828 } |
2837 | 2829 |
2838 | 2830 |
2839 void CompareIC::StubInfoToType(int stub_minor_key, | 2831 void CompareIC::StubInfoToType(int stub_minor_key, |
2840 Handle<Type>* left_type, | 2832 Handle<Type>* left_type, |
2841 Handle<Type>* right_type, | 2833 Handle<Type>* right_type, |
2842 Handle<Type>* overall_type, | 2834 Handle<Type>* overall_type, |
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3138 #undef ADDR | 3130 #undef ADDR |
3139 }; | 3131 }; |
3140 | 3132 |
3141 | 3133 |
3142 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 3134 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
3143 return IC_utilities[id]; | 3135 return IC_utilities[id]; |
3144 } | 3136 } |
3145 | 3137 |
3146 | 3138 |
3147 } } // namespace v8::internal | 3139 } } // namespace v8::internal |
OLD | NEW |