Chromium Code Reviews| 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 |