| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/crankshaft/hydrogen.h" | 5 #include "src/crankshaft/hydrogen.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include <sstream> | 8 #include <sstream> |
| 9 | 9 |
| 10 #include "src/allocation-site-scopes.h" | 10 #include "src/allocation-site-scopes.h" |
| (...skipping 6896 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6907 if (access_type == LOAD) { | 6907 if (access_type == LOAD) { |
| 6908 HInstruction* consolidated_load = | 6908 HInstruction* consolidated_load = |
| 6909 TryBuildConsolidatedElementLoad(object, key, val, maps); | 6909 TryBuildConsolidatedElementLoad(object, key, val, maps); |
| 6910 if (consolidated_load != NULL) { | 6910 if (consolidated_load != NULL) { |
| 6911 *has_side_effects |= consolidated_load->HasObservableSideEffects(); | 6911 *has_side_effects |= consolidated_load->HasObservableSideEffects(); |
| 6912 return consolidated_load; | 6912 return consolidated_load; |
| 6913 } | 6913 } |
| 6914 } | 6914 } |
| 6915 | 6915 |
| 6916 // Elements_kind transition support. | 6916 // Elements_kind transition support. |
| 6917 MapHandleList transition_target(maps->length()); | 6917 MapHandles transition_target; |
| 6918 transition_target.reserve(maps->length()); |
| 6918 // Collect possible transition targets. | 6919 // Collect possible transition targets. |
| 6919 MapHandleList possible_transitioned_maps(maps->length()); | 6920 MapHandles possible_transitioned_maps; |
| 6921 possible_transitioned_maps.reserve(maps->length()); |
| 6920 for (int i = 0; i < maps->length(); ++i) { | 6922 for (int i = 0; i < maps->length(); ++i) { |
| 6921 Handle<Map> map = maps->at(i); | 6923 Handle<Map> map = maps->at(i); |
| 6922 // Loads from strings or loads with a mix of string and non-string maps | 6924 // Loads from strings or loads with a mix of string and non-string maps |
| 6923 // shouldn't be handled polymorphically. | 6925 // shouldn't be handled polymorphically. |
| 6924 DCHECK(access_type != LOAD || !map->IsStringMap()); | 6926 DCHECK(access_type != LOAD || !map->IsStringMap()); |
| 6925 ElementsKind elements_kind = map->elements_kind(); | 6927 ElementsKind elements_kind = map->elements_kind(); |
| 6926 if (CanInlineElementAccess(map) && IsFastElementsKind(elements_kind) && | 6928 if (CanInlineElementAccess(map) && IsFastElementsKind(elements_kind) && |
| 6927 elements_kind != GetInitialFastElementsKind()) { | 6929 elements_kind != GetInitialFastElementsKind()) { |
| 6928 possible_transitioned_maps.Add(map); | 6930 possible_transitioned_maps.push_back(map); |
| 6929 } | 6931 } |
| 6930 if (IsSloppyArgumentsElementsKind(elements_kind)) { | 6932 if (IsSloppyArgumentsElementsKind(elements_kind)) { |
| 6931 HInstruction* result = | 6933 HInstruction* result = |
| 6932 BuildKeyedGeneric(access_type, expr, slot, object, key, val); | 6934 BuildKeyedGeneric(access_type, expr, slot, object, key, val); |
| 6933 *has_side_effects = result->HasObservableSideEffects(); | 6935 *has_side_effects = result->HasObservableSideEffects(); |
| 6934 return AddInstruction(result); | 6936 return AddInstruction(result); |
| 6935 } | 6937 } |
| 6936 } | 6938 } |
| 6937 // Get transition target for each map (NULL == no transition). | 6939 // Get transition target for each map (NULL == no transition). |
| 6938 for (int i = 0; i < maps->length(); ++i) { | 6940 for (int i = 0; i < maps->length(); ++i) { |
| 6939 Handle<Map> map = maps->at(i); | 6941 Handle<Map> map = maps->at(i); |
| 6940 Map* transitioned_map = | 6942 Map* transitioned_map = |
| 6941 map->FindElementsKindTransitionedMap(&possible_transitioned_maps); | 6943 map->FindElementsKindTransitionedMap(possible_transitioned_maps); |
| 6942 if (transitioned_map != nullptr) { | 6944 if (transitioned_map != nullptr) { |
| 6943 DCHECK(!map->is_stable()); | 6945 DCHECK(!map->is_stable()); |
| 6944 transition_target.Add(handle(transitioned_map)); | 6946 transition_target.push_back(handle(transitioned_map)); |
| 6945 } else { | 6947 } else { |
| 6946 transition_target.Add(Handle<Map>()); | 6948 transition_target.push_back(Handle<Map>()); |
| 6947 } | 6949 } |
| 6948 } | 6950 } |
| 6949 | 6951 |
| 6950 MapHandleList untransitionable_maps(maps->length()); | 6952 MapHandles untransitionable_maps; |
| 6953 untransitionable_maps.reserve(maps->length()); |
| 6951 HTransitionElementsKind* transition = NULL; | 6954 HTransitionElementsKind* transition = NULL; |
| 6952 for (int i = 0; i < maps->length(); ++i) { | 6955 for (int i = 0; i < maps->length(); ++i) { |
| 6953 Handle<Map> map = maps->at(i); | 6956 Handle<Map> map = maps->at(i); |
| 6954 DCHECK(map->IsMap()); | 6957 DCHECK(map->IsMap()); |
| 6955 if (!transition_target.at(i).is_null()) { | 6958 if (!transition_target.at(i).is_null()) { |
| 6956 DCHECK(Map::IsValidElementsTransition( | 6959 DCHECK(Map::IsValidElementsTransition( |
| 6957 map->elements_kind(), | 6960 map->elements_kind(), |
| 6958 transition_target.at(i)->elements_kind())); | 6961 transition_target.at(i)->elements_kind())); |
| 6959 transition = Add<HTransitionElementsKind>(object, map, | 6962 transition = Add<HTransitionElementsKind>(object, map, |
| 6960 transition_target.at(i)); | 6963 transition_target.at(i)); |
| 6961 } else { | 6964 } else { |
| 6962 untransitionable_maps.Add(map); | 6965 untransitionable_maps.push_back(map); |
| 6963 } | 6966 } |
| 6964 } | 6967 } |
| 6965 | 6968 |
| 6966 // If only one map is left after transitioning, handle this case | 6969 // If only one map is left after transitioning, handle this case |
| 6967 // monomorphically. | 6970 // monomorphically. |
| 6968 DCHECK(untransitionable_maps.length() >= 1); | 6971 DCHECK(untransitionable_maps.size() >= 1); |
| 6969 if (untransitionable_maps.length() == 1) { | 6972 if (untransitionable_maps.size() == 1) { |
| 6970 Handle<Map> untransitionable_map = untransitionable_maps[0]; | 6973 Handle<Map> untransitionable_map = untransitionable_maps[0]; |
| 6971 HInstruction* instr = NULL; | 6974 HInstruction* instr = NULL; |
| 6972 if (!CanInlineElementAccess(untransitionable_map)) { | 6975 if (!CanInlineElementAccess(untransitionable_map)) { |
| 6973 instr = AddInstruction( | 6976 instr = AddInstruction( |
| 6974 BuildKeyedGeneric(access_type, expr, slot, object, key, val)); | 6977 BuildKeyedGeneric(access_type, expr, slot, object, key, val)); |
| 6975 } else { | 6978 } else { |
| 6976 instr = BuildMonomorphicElementAccess( | 6979 instr = BuildMonomorphicElementAccess( |
| 6977 object, key, val, transition, untransitionable_map, access_type, | 6980 object, key, val, transition, untransitionable_map, access_type, |
| 6978 store_mode); | 6981 store_mode); |
| 6979 } | 6982 } |
| 6980 *has_side_effects |= instr->HasObservableSideEffects(); | 6983 *has_side_effects |= instr->HasObservableSideEffects(); |
| 6981 return access_type == STORE ? val : instr; | 6984 return access_type == STORE ? val : instr; |
| 6982 } | 6985 } |
| 6983 | 6986 |
| 6984 HBasicBlock* join = graph()->CreateBasicBlock(); | 6987 HBasicBlock* join = graph()->CreateBasicBlock(); |
| 6985 | 6988 |
| 6986 for (int i = 0; i < untransitionable_maps.length(); ++i) { | 6989 for (Handle<Map> map : untransitionable_maps) { |
| 6987 Handle<Map> map = untransitionable_maps[i]; | |
| 6988 ElementsKind elements_kind = map->elements_kind(); | 6990 ElementsKind elements_kind = map->elements_kind(); |
| 6989 HBasicBlock* this_map = graph()->CreateBasicBlock(); | 6991 HBasicBlock* this_map = graph()->CreateBasicBlock(); |
| 6990 HBasicBlock* other_map = graph()->CreateBasicBlock(); | 6992 HBasicBlock* other_map = graph()->CreateBasicBlock(); |
| 6991 HCompareMap* mapcompare = | 6993 HCompareMap* mapcompare = |
| 6992 New<HCompareMap>(object, map, this_map, other_map); | 6994 New<HCompareMap>(object, map, this_map, other_map); |
| 6993 FinishCurrentBlock(mapcompare); | 6995 FinishCurrentBlock(mapcompare); |
| 6994 | 6996 |
| 6995 set_current_block(this_map); | 6997 set_current_block(this_map); |
| 6996 HInstruction* access = NULL; | 6998 HInstruction* access = NULL; |
| 6997 if (!CanInlineElementAccess(map)) { | 6999 if (!CanInlineElementAccess(map)) { |
| (...skipping 5523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12521 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 12523 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 12522 } | 12524 } |
| 12523 | 12525 |
| 12524 #ifdef DEBUG | 12526 #ifdef DEBUG |
| 12525 graph_->Verify(false); // No full verify. | 12527 graph_->Verify(false); // No full verify. |
| 12526 #endif | 12528 #endif |
| 12527 } | 12529 } |
| 12528 | 12530 |
| 12529 } // namespace internal | 12531 } // namespace internal |
| 12530 } // namespace v8 | 12532 } // namespace v8 |
| OLD | NEW |