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 |