Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(236)

Side by Side Diff: src/hydrogen.cc

Issue 10692043: Consolidate similar KeyedLoads to worst case instead of transitioning elements (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Whitespace and comment tweaks Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 5731 matching lines...) Expand 10 before | Expand all | Expand 10 after
5742 } 5742 }
5743 } 5743 }
5744 5744
5745 5745
5746 HInstruction* HGraphBuilder::BuildMonomorphicElementAccess(HValue* object, 5746 HInstruction* HGraphBuilder::BuildMonomorphicElementAccess(HValue* object,
5747 HValue* key, 5747 HValue* key,
5748 HValue* val, 5748 HValue* val,
5749 HValue* dependency, 5749 HValue* dependency,
5750 Handle<Map> map, 5750 Handle<Map> map,
5751 bool is_store) { 5751 bool is_store) {
5752 HInstruction* mapcheck = 5752 HCheckMaps* mapcheck = new(zone()) HCheckMaps(object, map,
5753 AddInstruction(new(zone()) HCheckMaps(object, map, zone(), dependency)); 5753 zone(), dependency);
5754 AddInstruction(mapcheck);
5755 if (dependency) {
5756 mapcheck->ClearGVNFlag(kDependsOnElementsKind);
5757 }
5758 return BuildUncheckedMonomorphicElementAccess(object, key, val,
5759 mapcheck, map, is_store);
5760 }
5761
5762
5763 HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess(
5764 HValue* object,
5765 HValue* key,
5766 HValue* val,
5767 HCheckMaps* mapcheck,
5768 Handle<Map> map,
5769 bool is_store) {
5754 // No GVNFlag is necessary for ElementsKind if there is an explicit dependency 5770 // No GVNFlag is necessary for ElementsKind if there is an explicit dependency
5755 // on a HElementsTransition instruction. The flag can also be removed if the 5771 // on a HElementsTransition instruction. The flag can also be removed if the
5756 // map to check has FAST_HOLEY_ELEMENTS, since there can be no further 5772 // map to check has FAST_HOLEY_ELEMENTS, since there can be no further
5757 // ElementsKind transitions. Finally, the dependency can be removed for stores 5773 // ElementsKind transitions. Finally, the dependency can be removed for stores
5758 // for FAST_ELEMENTS, since a transition to HOLEY elements won't change the 5774 // for FAST_ELEMENTS, since a transition to HOLEY elements won't change the
5759 // generated store code. 5775 // generated store code.
5760 if (dependency || 5776 if ((map->elements_kind() == FAST_HOLEY_ELEMENTS) ||
5761 (map->elements_kind() == FAST_HOLEY_ELEMENTS) ||
5762 (map->elements_kind() == FAST_ELEMENTS && is_store)) { 5777 (map->elements_kind() == FAST_ELEMENTS && is_store)) {
5763 mapcheck->ClearGVNFlag(kDependsOnElementsKind); 5778 mapcheck->ClearGVNFlag(kDependsOnElementsKind);
5764 } 5779 }
5765 bool fast_smi_only_elements = map->has_fast_smi_elements(); 5780 bool fast_smi_only_elements = map->has_fast_smi_elements();
5766 bool fast_elements = map->has_fast_object_elements(); 5781 bool fast_elements = map->has_fast_object_elements();
5767 HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object)); 5782 HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object));
5768 if (is_store && (fast_elements || fast_smi_only_elements)) { 5783 if (is_store && (fast_elements || fast_smi_only_elements)) {
5769 HCheckMaps* check_cow_map = new(zone()) HCheckMaps( 5784 HCheckMaps* check_cow_map = new(zone()) HCheckMaps(
5770 elements, isolate()->factory()->fixed_array_map(), zone()); 5785 elements, isolate()->factory()->fixed_array_map(), zone());
5771 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); 5786 check_cow_map->ClearGVNFlag(kDependsOnElementsKind);
(...skipping 18 matching lines...) Expand all
5790 HType::Smi())); 5805 HType::Smi()));
5791 } else { 5806 } else {
5792 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); 5807 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements));
5793 } 5808 }
5794 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); 5809 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length));
5795 return BuildFastElementAccess(elements, checked_key, val, 5810 return BuildFastElementAccess(elements, checked_key, val,
5796 map->elements_kind(), is_store); 5811 map->elements_kind(), is_store);
5797 } 5812 }
5798 5813
5799 5814
5815 HInstruction* HGraphBuilder::TryBuildConsolidatedElementLoad(
5816 HValue* object,
5817 HValue* key,
5818 HValue* val,
5819 SmallMapList* maps) {
5820 // For polymorphic loads of similar elements kinds (i.e. all tagged or all
5821 // double), always use the "worst case" code without a transition. This is
5822 // much faster than transitioning the elements to the worst case, trading a
5823 // HTransitionElements for a HCheckMaps, and avoiding mutation of the array.
5824 bool has_double_maps = false;
5825 bool has_smi_or_object_maps = false;
5826 bool has_js_array_access = false;
5827 bool has_non_js_array_access = false;
5828 Handle<Map> most_general_consolidated_map;
5829 for (int i = 0; i < maps->length(); ++i) {
5830 Handle<Map> map = maps->at(i);
5831 // Don't allow mixing of JSArrays with JSObjects.
5832 if (map->instance_type() == JS_ARRAY_TYPE) {
5833 if (has_non_js_array_access) return NULL;
5834 has_js_array_access = true;
5835 } else if (has_js_array_access) {
5836 return NULL;
5837 } else {
5838 has_non_js_array_access = true;
5839 }
5840 // Don't allow mixed, incompatible elements kinds.
5841 if (map->has_fast_double_elements()) {
5842 if (has_smi_or_object_maps) return NULL;
5843 has_double_maps = true;
5844 } else if (map->has_fast_smi_or_object_elements()) {
5845 if (has_double_maps) return NULL;
5846 has_smi_or_object_maps = true;
5847 } else {
5848 return NULL;
5849 }
5850 // Remember the most general elements kind, the code for its load will
5851 // properly handle all of the more specific cases.
5852 if ((i == 0) || IsMoreGeneralElementsKindTransition(
5853 most_general_consolidated_map->elements_kind(),
5854 map->elements_kind())) {
5855 most_general_consolidated_map = map;
5856 }
5857 }
5858 if (!has_double_maps && !has_smi_or_object_maps) return NULL;
5859
5860 HCheckMaps* check_maps =
5861 new(zone()) HCheckMaps(object, maps, zone());
Jakob Kummerow 2012/06/29 18:42:41 nit: fits on one line
danno 2012/07/02 11:07:14 Done.
5862 AddInstruction(check_maps);
5863 HInstruction* instr = BuildUncheckedMonomorphicElementAccess(
5864 object, key, val,
5865 check_maps, most_general_consolidated_map, false);
Jakob Kummerow 2012/06/29 18:42:41 nit: fits on the same line as "object, key, val".
danno 2012/07/02 11:07:14 Done.
5866 return instr;
5867 }
5868
5869
5800 HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object, 5870 HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object,
5801 HValue* key, 5871 HValue* key,
5802 HValue* val, 5872 HValue* val,
5803 Expression* prop, 5873 Expression* prop,
5804 int ast_id, 5874 int ast_id,
5805 int position, 5875 int position,
5806 bool is_store, 5876 bool is_store,
5807 bool* has_side_effects) { 5877 bool* has_side_effects) {
5808 *has_side_effects = false; 5878 *has_side_effects = false;
5809 AddInstruction(new(zone()) HCheckNonSmi(object)); 5879 AddInstruction(new(zone()) HCheckNonSmi(object));
5810 SmallMapList* maps = prop->GetReceiverTypes(); 5880 SmallMapList* maps = prop->GetReceiverTypes();
5811 bool todo_external_array = false; 5881 bool todo_external_array = false;
5812 5882
5883 if (!is_store) {
5884 HInstruction* consolidated_load =
5885 TryBuildConsolidatedElementLoad(object, key, val, maps);
5886 if (consolidated_load != NULL) {
5887 AddInstruction(consolidated_load);
5888 *has_side_effects |= consolidated_load->HasObservableSideEffects();
5889 consolidated_load->set_position(position);
5890 return consolidated_load;
5891 }
5892 }
5893
5813 static const int kNumElementTypes = kElementsKindCount; 5894 static const int kNumElementTypes = kElementsKindCount;
5814 bool type_todo[kNumElementTypes]; 5895 bool type_todo[kNumElementTypes];
5815 for (int i = 0; i < kNumElementTypes; ++i) { 5896 for (int i = 0; i < kNumElementTypes; ++i) {
5816 type_todo[i] = false; 5897 type_todo[i] = false;
5817 } 5898 }
5818 5899
5819 // Elements_kind transition support. 5900 // Elements_kind transition support.
5820 MapHandleList transition_target(maps->length()); 5901 MapHandleList transition_target(maps->length());
5821 // Collect possible transition targets. 5902 // Collect possible transition targets.
5822 MapHandleList possible_transitioned_maps(maps->length()); 5903 MapHandleList possible_transitioned_maps(maps->length());
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
5858 untransitionable_map = map; 5939 untransitionable_map = map;
5859 } 5940 }
5860 } 5941 }
5861 5942
5862 // If only one map is left after transitioning, handle this case 5943 // If only one map is left after transitioning, handle this case
5863 // monomorphically. 5944 // monomorphically.
5864 if (num_untransitionable_maps == 1) { 5945 if (num_untransitionable_maps == 1) {
5865 HInstruction* instr = NULL; 5946 HInstruction* instr = NULL;
5866 if (untransitionable_map->has_slow_elements_kind()) { 5947 if (untransitionable_map->has_slow_elements_kind()) {
5867 instr = AddInstruction(is_store ? BuildStoreKeyedGeneric(object, key, val) 5948 instr = AddInstruction(is_store ? BuildStoreKeyedGeneric(object, key, val)
5868 : BuildLoadKeyedGeneric(object, key)); 5949 : BuildLoadKeyedGeneric(object, key));
Jakob Kummerow 2012/06/29 18:42:41 nit: why this change?
danno 2012/07/02 11:07:14 Done.
5869 } else { 5950 } else {
5870 instr = AddInstruction(BuildMonomorphicElementAccess( 5951 instr = AddInstruction(BuildMonomorphicElementAccess(
5871 object, key, val, transition, untransitionable_map, is_store)); 5952 object, key, val, transition, untransitionable_map, is_store));
5872 } 5953 }
5873 *has_side_effects |= instr->HasObservableSideEffects(); 5954 *has_side_effects |= instr->HasObservableSideEffects();
5874 instr->set_position(position); 5955 instr->set_position(position);
5875 return is_store ? NULL : instr; 5956 return is_store ? NULL : instr;
5876 } 5957 }
5877 5958
5878 AddInstruction(HCheckInstanceType::NewIsSpecObject(object, zone())); 5959 AddInstruction(HCheckInstanceType::NewIsSpecObject(object, zone()));
(...skipping 3561 matching lines...) Expand 10 before | Expand all | Expand 10 after
9440 } 9521 }
9441 } 9522 }
9442 9523
9443 #ifdef DEBUG 9524 #ifdef DEBUG
9444 if (graph_ != NULL) graph_->Verify(false); // No full verify. 9525 if (graph_ != NULL) graph_->Verify(false); // No full verify.
9445 if (allocator_ != NULL) allocator_->Verify(); 9526 if (allocator_ != NULL) allocator_->Verify();
9446 #endif 9527 #endif
9447 } 9528 }
9448 9529
9449 } } // namespace v8::internal 9530 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698