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 942 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
953 if (!receiver_maps->at(current).is_null() && | 953 if (!receiver_maps->at(current).is_null() && |
954 receiver_maps->at(current).is_identical_to(new_receiver_map)) { | 954 receiver_maps->at(current).is_identical_to(new_receiver_map)) { |
955 return false; | 955 return false; |
956 } | 956 } |
957 } | 957 } |
958 receiver_maps->Add(new_receiver_map); | 958 receiver_maps->Add(new_receiver_map); |
959 return true; | 959 return true; |
960 } | 960 } |
961 | 961 |
962 | 962 |
963 bool IC::UpdatePolymorphicIC(Handle<Type> type, | 963 bool IC::UpdatePolymorphicIC(Handle<HeapType> type, |
964 Handle<String> name, | 964 Handle<String> name, |
965 Handle<Code> code) { | 965 Handle<Code> code) { |
966 if (!code->is_handler()) return false; | 966 if (!code->is_handler()) return false; |
967 TypeHandleList types; | 967 TypeHandleList types; |
968 CodeHandleList handlers; | 968 CodeHandleList handlers; |
969 | 969 |
970 int number_of_valid_types; | 970 int number_of_valid_types; |
971 int handler_to_overwrite = -1; | 971 int handler_to_overwrite = -1; |
972 | 972 |
973 target()->FindAllTypes(&types); | 973 target()->FindAllTypes(&types); |
974 int number_of_types = types.length(); | 974 int number_of_types = types.length(); |
975 number_of_valid_types = number_of_types; | 975 number_of_valid_types = number_of_types; |
976 | 976 |
977 for (int i = 0; i < number_of_types; i++) { | 977 for (int i = 0; i < number_of_types; i++) { |
978 Handle<Type> current_type = types.at(i); | 978 Handle<HeapType> current_type = types.at(i); |
979 // Filter out deprecated maps to ensure their instances get migrated. | 979 // Filter out deprecated maps to ensure their instances get migrated. |
980 if (current_type->IsClass() && current_type->AsClass()->is_deprecated()) { | 980 if (current_type->IsClass() && current_type->AsClass()->is_deprecated()) { |
981 number_of_valid_types--; | 981 number_of_valid_types--; |
982 // If the receiver type is already in the polymorphic IC, this indicates | 982 // If the receiver type is already in the polymorphic IC, this indicates |
983 // there was a prototoype chain failure. In that case, just overwrite the | 983 // there was a prototoype chain failure. In that case, just overwrite the |
984 // handler. | 984 // handler. |
985 } else if (type->IsCurrently(current_type)) { | 985 } else if (type->IsCurrently(current_type)) { |
986 ASSERT(handler_to_overwrite == -1); | 986 ASSERT(handler_to_overwrite == -1); |
987 number_of_valid_types--; | 987 number_of_valid_types--; |
988 handler_to_overwrite = i; | 988 handler_to_overwrite = i; |
(...skipping 12 matching lines...) Expand all Loading... |
1001 handlers.Add(code); | 1001 handlers.Add(code); |
1002 } | 1002 } |
1003 | 1003 |
1004 Handle<Code> ic = isolate()->stub_cache()->ComputePolymorphicIC( | 1004 Handle<Code> ic = isolate()->stub_cache()->ComputePolymorphicIC( |
1005 &types, &handlers, number_of_valid_types, name, extra_ic_state()); | 1005 &types, &handlers, number_of_valid_types, name, extra_ic_state()); |
1006 set_target(*ic); | 1006 set_target(*ic); |
1007 return true; | 1007 return true; |
1008 } | 1008 } |
1009 | 1009 |
1010 | 1010 |
1011 Handle<Type> IC::CurrentTypeOf(Handle<Object> object, Isolate* isolate) { | 1011 Handle<HeapType> IC::CurrentTypeOf(Handle<Object> object, Isolate* isolate) { |
1012 return object->IsJSGlobalObject() | 1012 return object->IsJSGlobalObject() |
1013 ? Type::Constant(Handle<JSGlobalObject>::cast(object), isolate) | 1013 ? HeapType::Constant(Handle<JSGlobalObject>::cast(object), isolate) |
1014 : Type::OfCurrently(object, isolate); | 1014 : HeapType::OfCurrently(object, isolate); |
1015 } | 1015 } |
1016 | 1016 |
1017 | 1017 |
1018 Handle<Map> IC::TypeToMap(Type* type, Isolate* isolate) { | 1018 Handle<Map> IC::TypeToMap(HeapType* type, Isolate* isolate) { |
1019 if (type->Is(Type::Number())) return isolate->factory()->heap_number_map(); | 1019 if (type->Is(HeapType::Number())) |
1020 if (type->Is(Type::Boolean())) return isolate->factory()->oddball_map(); | 1020 return isolate->factory()->heap_number_map(); |
| 1021 if (type->Is(HeapType::Boolean())) return isolate->factory()->oddball_map(); |
1021 if (type->IsConstant()) { | 1022 if (type->IsConstant()) { |
1022 return handle(Handle<JSGlobalObject>::cast(type->AsConstant())->map()); | 1023 return handle(Handle<JSGlobalObject>::cast(type->AsConstant())->map()); |
1023 } | 1024 } |
1024 ASSERT(type->IsClass()); | 1025 ASSERT(type->IsClass()); |
1025 return type->AsClass(); | 1026 return type->AsClass(); |
1026 } | 1027 } |
1027 | 1028 |
1028 | 1029 |
1029 Handle<Type> IC::MapToType(Handle<Map> map) { | 1030 Handle<HeapType> IC::MapToType(Handle<Map> map) { |
1030 Isolate* isolate = map->GetIsolate(); | 1031 Isolate* isolate = map->GetIsolate(); |
1031 if (map->instance_type() == HEAP_NUMBER_TYPE) return Type::Number(isolate); | 1032 if (map->instance_type() == HEAP_NUMBER_TYPE) { |
1032 // The only oddballs that can be recorded in ICs are booleans. | 1033 return HeapType::Number(isolate); |
1033 if (map->instance_type() == ODDBALL_TYPE) return Type::Boolean(isolate); | 1034 } else if (map->instance_type() == ODDBALL_TYPE) { |
1034 return Type::Class(map, isolate); | 1035 // The only oddballs that can be recorded in ICs are booleans. |
| 1036 return HeapType::Boolean(isolate); |
| 1037 } else { |
| 1038 return HeapType::Class(map, isolate); |
| 1039 } |
1035 } | 1040 } |
1036 | 1041 |
1037 | 1042 |
1038 void IC::UpdateMonomorphicIC(Handle<Type> type, | 1043 void IC::UpdateMonomorphicIC(Handle<HeapType> type, |
1039 Handle<Code> handler, | 1044 Handle<Code> handler, |
1040 Handle<String> name) { | 1045 Handle<String> name) { |
1041 if (!handler->is_handler()) return set_target(*handler); | 1046 if (!handler->is_handler()) return set_target(*handler); |
1042 Handle<Code> ic = isolate()->stub_cache()->ComputeMonomorphicIC( | 1047 Handle<Code> ic = isolate()->stub_cache()->ComputeMonomorphicIC( |
1043 name, type, handler, extra_ic_state()); | 1048 name, type, handler, extra_ic_state()); |
1044 set_target(*ic); | 1049 set_target(*ic); |
1045 } | 1050 } |
1046 | 1051 |
1047 | 1052 |
1048 void IC::CopyICToMegamorphicCache(Handle<String> name) { | 1053 void IC::CopyICToMegamorphicCache(Handle<String> name) { |
1049 TypeHandleList types; | 1054 TypeHandleList types; |
1050 CodeHandleList handlers; | 1055 CodeHandleList handlers; |
1051 target()->FindAllTypes(&types); | 1056 target()->FindAllTypes(&types); |
1052 if (!target()->FindHandlers(&handlers, types.length())) return; | 1057 if (!target()->FindHandlers(&handlers, types.length())) return; |
1053 for (int i = 0; i < types.length(); i++) { | 1058 for (int i = 0; i < types.length(); i++) { |
1054 UpdateMegamorphicCache(*types.at(i), *name, *handlers.at(i)); | 1059 UpdateMegamorphicCache(*types.at(i), *name, *handlers.at(i)); |
1055 } | 1060 } |
1056 } | 1061 } |
1057 | 1062 |
1058 | 1063 |
1059 bool IC::IsTransitionOfMonomorphicTarget(Handle<Type> type) { | 1064 bool IC::IsTransitionOfMonomorphicTarget(Handle<HeapType> type) { |
1060 if (!type->IsClass()) return false; | 1065 if (!type->IsClass()) return false; |
1061 Map* receiver_map = *type->AsClass(); | 1066 Map* receiver_map = *type->AsClass(); |
1062 Map* current_map = target()->FindFirstMap(); | 1067 Map* current_map = target()->FindFirstMap(); |
1063 ElementsKind receiver_elements_kind = receiver_map->elements_kind(); | 1068 ElementsKind receiver_elements_kind = receiver_map->elements_kind(); |
1064 bool more_general_transition = | 1069 bool more_general_transition = |
1065 IsMoreGeneralElementsKindTransition( | 1070 IsMoreGeneralElementsKindTransition( |
1066 current_map->elements_kind(), receiver_elements_kind); | 1071 current_map->elements_kind(), receiver_elements_kind); |
1067 Map* transitioned_map = more_general_transition | 1072 Map* transitioned_map = more_general_transition |
1068 ? current_map->LookupElementsTransitionMap(receiver_elements_kind) | 1073 ? current_map->LookupElementsTransitionMap(receiver_elements_kind) |
1069 : NULL; | 1074 : NULL; |
1070 | 1075 |
1071 return transitioned_map == receiver_map; | 1076 return transitioned_map == receiver_map; |
1072 } | 1077 } |
1073 | 1078 |
1074 | 1079 |
1075 void IC::PatchCache(Handle<Type> type, | 1080 void IC::PatchCache(Handle<HeapType> type, |
1076 Handle<String> name, | 1081 Handle<String> name, |
1077 Handle<Code> code) { | 1082 Handle<Code> code) { |
1078 switch (state()) { | 1083 switch (state()) { |
1079 case UNINITIALIZED: | 1084 case UNINITIALIZED: |
1080 case PREMONOMORPHIC: | 1085 case PREMONOMORPHIC: |
1081 case MONOMORPHIC_PROTOTYPE_FAILURE: | 1086 case MONOMORPHIC_PROTOTYPE_FAILURE: |
1082 UpdateMonomorphicIC(type, code, name); | 1087 UpdateMonomorphicIC(type, code, name); |
1083 break; | 1088 break; |
1084 case MONOMORPHIC: { | 1089 case MONOMORPHIC: { |
1085 // For now, call stubs are allowed to rewrite to the same stub. This | 1090 // For now, call stubs are allowed to rewrite to the same stub. This |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1131 Handle<String> name) { | 1136 Handle<String> name) { |
1132 if (state() == UNINITIALIZED) { | 1137 if (state() == UNINITIALIZED) { |
1133 // This is the first time we execute this inline cache. | 1138 // This is the first time we execute this inline cache. |
1134 // Set the target to the pre monomorphic stub to delay | 1139 // Set the target to the pre monomorphic stub to delay |
1135 // setting the monomorphic state. | 1140 // setting the monomorphic state. |
1136 set_target(*pre_monomorphic_stub()); | 1141 set_target(*pre_monomorphic_stub()); |
1137 TRACE_IC("LoadIC", name); | 1142 TRACE_IC("LoadIC", name); |
1138 return; | 1143 return; |
1139 } | 1144 } |
1140 | 1145 |
1141 Handle<Type> type = CurrentTypeOf(object, isolate()); | 1146 Handle<HeapType> type = CurrentTypeOf(object, isolate()); |
1142 Handle<Code> code; | 1147 Handle<Code> code; |
1143 if (!lookup->IsCacheable()) { | 1148 if (!lookup->IsCacheable()) { |
1144 // Bail out if the result is not cacheable. | 1149 // Bail out if the result is not cacheable. |
1145 code = slow_stub(); | 1150 code = slow_stub(); |
1146 } else if (!lookup->IsProperty()) { | 1151 } else if (!lookup->IsProperty()) { |
1147 if (kind() == Code::LOAD_IC) { | 1152 if (kind() == Code::LOAD_IC) { |
1148 code = isolate()->stub_cache()->ComputeLoadNonexistent(name, type); | 1153 code = isolate()->stub_cache()->ComputeLoadNonexistent(name, type); |
1149 } else { | 1154 } else { |
1150 code = slow_stub(); | 1155 code = slow_stub(); |
1151 } | 1156 } |
1152 } else { | 1157 } else { |
1153 code = ComputeHandler(lookup, object, name); | 1158 code = ComputeHandler(lookup, object, name); |
1154 } | 1159 } |
1155 | 1160 |
1156 PatchCache(type, name, code); | 1161 PatchCache(type, name, code); |
1157 TRACE_IC("LoadIC", name); | 1162 TRACE_IC("LoadIC", name); |
1158 } | 1163 } |
1159 | 1164 |
1160 | 1165 |
1161 void IC::UpdateMegamorphicCache(Type* type, Name* name, Code* code) { | 1166 void IC::UpdateMegamorphicCache(HeapType* type, Name* name, Code* code) { |
1162 // Cache code holding map should be consistent with | 1167 // Cache code holding map should be consistent with |
1163 // GenerateMonomorphicCacheProbe. | 1168 // GenerateMonomorphicCacheProbe. |
1164 Map* map = *TypeToMap(type, isolate()); | 1169 Map* map = *TypeToMap(type, isolate()); |
1165 isolate()->stub_cache()->Set(name, map, code); | 1170 isolate()->stub_cache()->Set(name, map, code); |
1166 } | 1171 } |
1167 | 1172 |
1168 | 1173 |
1169 Handle<Code> IC::ComputeHandler(LookupResult* lookup, | 1174 Handle<Code> IC::ComputeHandler(LookupResult* lookup, |
1170 Handle<Object> object, | 1175 Handle<Object> object, |
1171 Handle<String> name, | 1176 Handle<String> name, |
(...skipping 20 matching lines...) Expand all Loading... |
1192 Handle<Code> LoadIC::CompileHandler(LookupResult* lookup, | 1197 Handle<Code> LoadIC::CompileHandler(LookupResult* lookup, |
1193 Handle<Object> object, | 1198 Handle<Object> object, |
1194 Handle<String> name, | 1199 Handle<String> name, |
1195 Handle<Object> unused, | 1200 Handle<Object> unused, |
1196 InlineCacheHolderFlag cache_holder) { | 1201 InlineCacheHolderFlag cache_holder) { |
1197 if (object->IsString() && name->Equals(isolate()->heap()->length_string())) { | 1202 if (object->IsString() && name->Equals(isolate()->heap()->length_string())) { |
1198 int length_index = String::kLengthOffset / kPointerSize; | 1203 int length_index = String::kLengthOffset / kPointerSize; |
1199 return SimpleFieldLoad(length_index); | 1204 return SimpleFieldLoad(length_index); |
1200 } | 1205 } |
1201 | 1206 |
1202 Handle<Type> type = CurrentTypeOf(object, isolate()); | 1207 Handle<HeapType> type = CurrentTypeOf(object, isolate()); |
1203 Handle<JSObject> holder(lookup->holder()); | 1208 Handle<JSObject> holder(lookup->holder()); |
1204 LoadStubCompiler compiler(isolate(), kNoExtraICState, cache_holder, kind()); | 1209 LoadStubCompiler compiler(isolate(), kNoExtraICState, cache_holder, kind()); |
1205 | 1210 |
1206 switch (lookup->type()) { | 1211 switch (lookup->type()) { |
1207 case FIELD: { | 1212 case FIELD: { |
1208 PropertyIndex field = lookup->GetFieldIndex(); | 1213 PropertyIndex field = lookup->GetFieldIndex(); |
1209 if (object.is_identical_to(holder)) { | 1214 if (object.is_identical_to(holder)) { |
1210 return SimpleFieldLoad(field.translate(holder), | 1215 return SimpleFieldLoad(field.translate(holder), |
1211 field.is_inobject(holder), | 1216 field.is_inobject(holder), |
1212 lookup->representation()); | 1217 lookup->representation()); |
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1638 receiver, lookup, transition, name); | 1643 receiver, lookup, transition, name); |
1639 } | 1644 } |
1640 case NORMAL: | 1645 case NORMAL: |
1641 if (kind() == Code::KEYED_STORE_IC) break; | 1646 if (kind() == Code::KEYED_STORE_IC) break; |
1642 if (receiver->IsGlobalObject()) { | 1647 if (receiver->IsGlobalObject()) { |
1643 // The stub generated for the global object picks the value directly | 1648 // The stub generated for the global object picks the value directly |
1644 // from the property cell. So the property must be directly on the | 1649 // from the property cell. So the property must be directly on the |
1645 // global object. | 1650 // global object. |
1646 Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver); | 1651 Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver); |
1647 Handle<PropertyCell> cell(global->GetPropertyCell(lookup), isolate()); | 1652 Handle<PropertyCell> cell(global->GetPropertyCell(lookup), isolate()); |
1648 Handle<Type> union_type = PropertyCell::UpdatedType(cell, value); | 1653 Handle<HeapType> union_type = PropertyCell::UpdatedType(cell, value); |
1649 StoreGlobalStub stub(union_type->IsConstant()); | 1654 StoreGlobalStub stub(union_type->IsConstant()); |
1650 | 1655 |
1651 Handle<Code> code = stub.GetCodeCopyFromTemplate( | 1656 Handle<Code> code = stub.GetCodeCopyFromTemplate( |
1652 isolate(), receiver->map(), *cell); | 1657 isolate(), receiver->map(), *cell); |
1653 // TODO(verwaest): Move caching of these NORMAL stubs outside as well. | 1658 // TODO(verwaest): Move caching of these NORMAL stubs outside as well. |
1654 HeapObject::UpdateMapCodeCache(receiver, name, code); | 1659 HeapObject::UpdateMapCodeCache(receiver, name, code); |
1655 return code; | 1660 return code; |
1656 } | 1661 } |
1657 ASSERT(holder.is_identical_to(receiver)); | 1662 ASSERT(holder.is_identical_to(receiver)); |
1658 return isolate()->builtins()->StoreIC_Normal(); | 1663 return isolate()->builtins()->StoreIC_Normal(); |
(...skipping 912 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2571 GENERATE(Token::MOD, SMI, 4, SMI, NO_OVERWRITE); | 2576 GENERATE(Token::MOD, SMI, 4, SMI, NO_OVERWRITE); |
2572 GENERATE(Token::MOD, SMI, 4, SMI, OVERWRITE_LEFT); | 2577 GENERATE(Token::MOD, SMI, 4, SMI, OVERWRITE_LEFT); |
2573 GENERATE(Token::MOD, SMI, 8, SMI, NO_OVERWRITE); | 2578 GENERATE(Token::MOD, SMI, 8, SMI, NO_OVERWRITE); |
2574 GENERATE(Token::MOD, SMI, 16, SMI, OVERWRITE_LEFT); | 2579 GENERATE(Token::MOD, SMI, 16, SMI, OVERWRITE_LEFT); |
2575 GENERATE(Token::MOD, SMI, 32, SMI, NO_OVERWRITE); | 2580 GENERATE(Token::MOD, SMI, 32, SMI, NO_OVERWRITE); |
2576 GENERATE(Token::MOD, SMI, 2048, SMI, NO_OVERWRITE); | 2581 GENERATE(Token::MOD, SMI, 2048, SMI, NO_OVERWRITE); |
2577 #undef GENERATE | 2582 #undef GENERATE |
2578 } | 2583 } |
2579 | 2584 |
2580 | 2585 |
2581 Handle<Type> BinaryOpIC::State::GetResultType(Isolate* isolate) const { | 2586 Type* BinaryOpIC::State::GetResultType(Zone* zone) const { |
2582 Kind result_kind = result_kind_; | 2587 Kind result_kind = result_kind_; |
2583 if (HasSideEffects()) { | 2588 if (HasSideEffects()) { |
2584 result_kind = NONE; | 2589 result_kind = NONE; |
2585 } else if (result_kind == GENERIC && op_ == Token::ADD) { | 2590 } else if (result_kind == GENERIC && op_ == Token::ADD) { |
2586 return Type::Union(Type::Number(isolate), Type::String(isolate), isolate); | 2591 return Type::Union(Type::Number(zone), Type::String(zone), zone); |
2587 } else if (result_kind == NUMBER && op_ == Token::SHR) { | 2592 } else if (result_kind == NUMBER && op_ == Token::SHR) { |
2588 return Type::Unsigned32(isolate); | 2593 return Type::Unsigned32(zone); |
2589 } | 2594 } |
2590 ASSERT_NE(GENERIC, result_kind); | 2595 ASSERT_NE(GENERIC, result_kind); |
2591 return KindToType(result_kind, isolate); | 2596 return KindToType(result_kind, zone); |
2592 } | 2597 } |
2593 | 2598 |
2594 | 2599 |
2595 void BinaryOpIC::State::Print(StringStream* stream) const { | 2600 void BinaryOpIC::State::Print(StringStream* stream) const { |
2596 stream->Add("(%s", Token::Name(op_)); | 2601 stream->Add("(%s", Token::Name(op_)); |
2597 if (mode_ == OVERWRITE_LEFT) stream->Add("_ReuseLeft"); | 2602 if (mode_ == OVERWRITE_LEFT) stream->Add("_ReuseLeft"); |
2598 else if (mode_ == OVERWRITE_RIGHT) stream->Add("_ReuseRight"); | 2603 else if (mode_ == OVERWRITE_RIGHT) stream->Add("_ReuseRight"); |
2599 stream->Add(":%s*", KindToString(left_kind_)); | 2604 stream->Add(":%s*", KindToString(left_kind_)); |
2600 if (fixed_right_arg_.has_value) { | 2605 if (fixed_right_arg_.has_value) { |
2601 stream->Add("%d", fixed_right_arg_.value); | 2606 stream->Add("%d", fixed_right_arg_.value); |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2699 case NUMBER: return "Number"; | 2704 case NUMBER: return "Number"; |
2700 case STRING: return "String"; | 2705 case STRING: return "String"; |
2701 case GENERIC: return "Generic"; | 2706 case GENERIC: return "Generic"; |
2702 } | 2707 } |
2703 UNREACHABLE(); | 2708 UNREACHABLE(); |
2704 return NULL; | 2709 return NULL; |
2705 } | 2710 } |
2706 | 2711 |
2707 | 2712 |
2708 // static | 2713 // static |
2709 Handle<Type> BinaryOpIC::State::KindToType(Kind kind, Isolate* isolate) { | 2714 Type* BinaryOpIC::State::KindToType(Kind kind, Zone* zone) { |
2710 switch (kind) { | 2715 switch (kind) { |
2711 case NONE: return Type::None(isolate); | 2716 case NONE: return Type::None(zone); |
2712 case SMI: return Type::Smi(isolate); | 2717 case SMI: return Type::Smi(zone); |
2713 case INT32: return Type::Signed32(isolate); | 2718 case INT32: return Type::Signed32(zone); |
2714 case NUMBER: return Type::Number(isolate); | 2719 case NUMBER: return Type::Number(zone); |
2715 case STRING: return Type::String(isolate); | 2720 case STRING: return Type::String(zone); |
2716 case GENERIC: return Type::Any(isolate); | 2721 case GENERIC: return Type::Any(zone); |
2717 } | 2722 } |
2718 UNREACHABLE(); | 2723 UNREACHABLE(); |
2719 return Handle<Type>(); | 2724 return NULL; |
2720 } | 2725 } |
2721 | 2726 |
2722 | 2727 |
2723 MaybeObject* BinaryOpIC::Transition(Handle<Object> left, Handle<Object> right) { | 2728 MaybeObject* BinaryOpIC::Transition(Handle<Object> left, Handle<Object> right) { |
2724 State state(target()->extended_extra_ic_state()); | 2729 State state(target()->extended_extra_ic_state()); |
2725 | 2730 |
2726 // Compute the actual result using the builtin for the binary operation. | 2731 // Compute the actual result using the builtin for the binary operation. |
2727 Object* builtin = isolate()->js_builtins_object()->javascript_builtin( | 2732 Object* builtin = isolate()->js_builtins_object()->javascript_builtin( |
2728 TokenToJSBuiltin(state.op())); | 2733 TokenToJSBuiltin(state.op())); |
2729 Handle<JSFunction> function = handle(JSFunction::cast(builtin), isolate()); | 2734 Handle<JSFunction> function = handle(JSFunction::cast(builtin), isolate()); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2799 case UNIQUE_NAME: return "UNIQUE_NAME"; | 2804 case UNIQUE_NAME: return "UNIQUE_NAME"; |
2800 case OBJECT: return "OBJECT"; | 2805 case OBJECT: return "OBJECT"; |
2801 case KNOWN_OBJECT: return "KNOWN_OBJECT"; | 2806 case KNOWN_OBJECT: return "KNOWN_OBJECT"; |
2802 case GENERIC: return "GENERIC"; | 2807 case GENERIC: return "GENERIC"; |
2803 } | 2808 } |
2804 UNREACHABLE(); | 2809 UNREACHABLE(); |
2805 return NULL; | 2810 return NULL; |
2806 } | 2811 } |
2807 | 2812 |
2808 | 2813 |
2809 Handle<Type> CompareIC::StateToType( | 2814 Type* CompareIC::StateToType( |
2810 Isolate* isolate, | 2815 Zone* zone, |
2811 CompareIC::State state, | 2816 CompareIC::State state, |
2812 Handle<Map> map) { | 2817 Handle<Map> map) { |
2813 switch (state) { | 2818 switch (state) { |
2814 case CompareIC::UNINITIALIZED: return Type::None(isolate); | 2819 case CompareIC::UNINITIALIZED: return Type::None(zone); |
2815 case CompareIC::SMI: return Type::Smi(isolate); | 2820 case CompareIC::SMI: return Type::Smi(zone); |
2816 case CompareIC::NUMBER: return Type::Number(isolate); | 2821 case CompareIC::NUMBER: return Type::Number(zone); |
2817 case CompareIC::STRING: return Type::String(isolate); | 2822 case CompareIC::STRING: return Type::String(zone); |
2818 case CompareIC::INTERNALIZED_STRING: | 2823 case CompareIC::INTERNALIZED_STRING: return Type::InternalizedString(zone); |
2819 return Type::InternalizedString(isolate); | 2824 case CompareIC::UNIQUE_NAME: return Type::UniqueName(zone); |
2820 case CompareIC::UNIQUE_NAME: return Type::UniqueName(isolate); | 2825 case CompareIC::OBJECT: return Type::Receiver(zone); |
2821 case CompareIC::OBJECT: return Type::Receiver(isolate); | |
2822 case CompareIC::KNOWN_OBJECT: | 2826 case CompareIC::KNOWN_OBJECT: |
2823 return map.is_null() | 2827 return map.is_null() ? Type::Receiver(zone) : Type::Class(map, zone); |
2824 ? Type::Receiver(isolate) : Type::Class(map, isolate); | 2828 case CompareIC::GENERIC: return Type::Any(zone); |
2825 case CompareIC::GENERIC: return Type::Any(isolate); | |
2826 } | 2829 } |
2827 UNREACHABLE(); | 2830 UNREACHABLE(); |
2828 return Handle<Type>(); | 2831 return NULL; |
2829 } | 2832 } |
2830 | 2833 |
2831 | 2834 |
2832 void CompareIC::StubInfoToType(int stub_minor_key, | 2835 void CompareIC::StubInfoToType(int stub_minor_key, |
2833 Handle<Type>* left_type, | 2836 Type** left_type, |
2834 Handle<Type>* right_type, | 2837 Type** right_type, |
2835 Handle<Type>* overall_type, | 2838 Type** overall_type, |
2836 Handle<Map> map, | 2839 Handle<Map> map, |
2837 Isolate* isolate) { | 2840 Zone* zone) { |
2838 State left_state, right_state, handler_state; | 2841 State left_state, right_state, handler_state; |
2839 ICCompareStub::DecodeMinorKey(stub_minor_key, &left_state, &right_state, | 2842 ICCompareStub::DecodeMinorKey(stub_minor_key, &left_state, &right_state, |
2840 &handler_state, NULL); | 2843 &handler_state, NULL); |
2841 *left_type = StateToType(isolate, left_state); | 2844 *left_type = StateToType(zone, left_state); |
2842 *right_type = StateToType(isolate, right_state); | 2845 *right_type = StateToType(zone, right_state); |
2843 *overall_type = StateToType(isolate, handler_state, map); | 2846 *overall_type = StateToType(zone, handler_state, map); |
2844 } | 2847 } |
2845 | 2848 |
2846 | 2849 |
2847 CompareIC::State CompareIC::NewInputState(State old_state, | 2850 CompareIC::State CompareIC::NewInputState(State old_state, |
2848 Handle<Object> value) { | 2851 Handle<Object> value) { |
2849 switch (old_state) { | 2852 switch (old_state) { |
2850 case UNINITIALIZED: | 2853 case UNINITIALIZED: |
2851 if (value->IsSmi()) return SMI; | 2854 if (value->IsSmi()) return SMI; |
2852 if (value->IsHeapNumber()) return NUMBER; | 2855 if (value->IsHeapNumber()) return NUMBER; |
2853 if (value->IsInternalizedString()) return INTERNALIZED_STRING; | 2856 if (value->IsInternalizedString()) return INTERNALIZED_STRING; |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3131 #undef ADDR | 3134 #undef ADDR |
3132 }; | 3135 }; |
3133 | 3136 |
3134 | 3137 |
3135 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 3138 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
3136 return IC_utilities[id]; | 3139 return IC_utilities[id]; |
3137 } | 3140 } |
3138 | 3141 |
3139 | 3142 |
3140 } } // namespace v8::internal | 3143 } } // namespace v8::internal |
OLD | NEW |