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

Side by Side Diff: src/hydrogen.cc

Issue 10802038: Add dependency to HLoadKeyed* instructions to prevent invalid hoisting (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix bugs 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
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 4351 matching lines...) Expand 10 before | Expand all | Expand 10 after
4362 current_block()->Finish(compare_index); 4362 current_block()->Finish(compare_index);
4363 4363
4364 set_current_block(loop_successor); 4364 set_current_block(loop_successor);
4365 Drop(5); 4365 Drop(5);
4366 4366
4367 set_current_block(loop_body); 4367 set_current_block(loop_body);
4368 4368
4369 HValue* key = AddInstruction( 4369 HValue* key = AddInstruction(
4370 new(zone()) HLoadKeyedFastElement( 4370 new(zone()) HLoadKeyedFastElement(
4371 environment()->ExpressionStackAt(2), // Enum cache. 4371 environment()->ExpressionStackAt(2), // Enum cache.
4372 environment()->ExpressionStackAt(0))); // Iteration index. 4372 environment()->ExpressionStackAt(0), // Iteration index.
4373 environment()->ExpressionStackAt(0)));
4373 4374
4374 // Check if the expected map still matches that of the enumerable. 4375 // Check if the expected map still matches that of the enumerable.
4375 // If not just deoptimize. 4376 // If not just deoptimize.
4376 AddInstruction(new(zone()) HCheckMapValue( 4377 AddInstruction(new(zone()) HCheckMapValue(
4377 environment()->ExpressionStackAt(4), 4378 environment()->ExpressionStackAt(4),
4378 environment()->ExpressionStackAt(3))); 4379 environment()->ExpressionStackAt(3)));
4379 4380
4380 Bind(each_var, key); 4381 Bind(each_var, key);
4381 4382
4382 BreakAndContinueInfo break_info(stmt, 5); 4383 BreakAndContinueInfo break_info(stmt, 5);
(...skipping 1319 matching lines...) Expand 10 before | Expand all | Expand 10 after
5702 HValue* key) { 5703 HValue* key) {
5703 HValue* context = environment()->LookupContext(); 5704 HValue* context = environment()->LookupContext();
5704 return new(zone()) HLoadKeyedGeneric(context, object, key); 5705 return new(zone()) HLoadKeyedGeneric(context, object, key);
5705 } 5706 }
5706 5707
5707 5708
5708 HInstruction* HGraphBuilder::BuildExternalArrayElementAccess( 5709 HInstruction* HGraphBuilder::BuildExternalArrayElementAccess(
5709 HValue* external_elements, 5710 HValue* external_elements,
5710 HValue* checked_key, 5711 HValue* checked_key,
5711 HValue* val, 5712 HValue* val,
5713 HValue* dependency,
5712 ElementsKind elements_kind, 5714 ElementsKind elements_kind,
5713 bool is_store) { 5715 bool is_store) {
5714 if (is_store) { 5716 if (is_store) {
5715 ASSERT(val != NULL); 5717 ASSERT(val != NULL);
5716 switch (elements_kind) { 5718 switch (elements_kind) {
5717 case EXTERNAL_PIXEL_ELEMENTS: { 5719 case EXTERNAL_PIXEL_ELEMENTS: {
5718 val = AddInstruction(new(zone()) HClampToUint8(val)); 5720 val = AddInstruction(new(zone()) HClampToUint8(val));
5719 break; 5721 break;
5720 } 5722 }
5721 case EXTERNAL_BYTE_ELEMENTS: 5723 case EXTERNAL_BYTE_ELEMENTS:
(...skipping 23 matching lines...) Expand all
5745 case DICTIONARY_ELEMENTS: 5747 case DICTIONARY_ELEMENTS:
5746 case NON_STRICT_ARGUMENTS_ELEMENTS: 5748 case NON_STRICT_ARGUMENTS_ELEMENTS:
5747 UNREACHABLE(); 5749 UNREACHABLE();
5748 break; 5750 break;
5749 } 5751 }
5750 return new(zone()) HStoreKeyedSpecializedArrayElement( 5752 return new(zone()) HStoreKeyedSpecializedArrayElement(
5751 external_elements, checked_key, val, elements_kind); 5753 external_elements, checked_key, val, elements_kind);
5752 } else { 5754 } else {
5753 ASSERT(val == NULL); 5755 ASSERT(val == NULL);
5754 return new(zone()) HLoadKeyedSpecializedArrayElement( 5756 return new(zone()) HLoadKeyedSpecializedArrayElement(
5755 external_elements, checked_key, elements_kind); 5757 external_elements, checked_key, dependency, elements_kind);
5756 } 5758 }
5757 } 5759 }
5758 5760
5759 5761
5760 HInstruction* HGraphBuilder::BuildFastElementAccess(HValue* elements, 5762 HInstruction* HGraphBuilder::BuildFastElementAccess(HValue* elements,
5761 HValue* checked_key, 5763 HValue* checked_key,
5762 HValue* val, 5764 HValue* val,
5765 HValue* load_dependency,
5763 ElementsKind elements_kind, 5766 ElementsKind elements_kind,
5764 bool is_store) { 5767 bool is_store) {
5765 if (is_store) { 5768 if (is_store) {
5766 ASSERT(val != NULL); 5769 ASSERT(val != NULL);
5767 switch (elements_kind) { 5770 switch (elements_kind) {
5768 case FAST_DOUBLE_ELEMENTS: 5771 case FAST_DOUBLE_ELEMENTS:
5769 case FAST_HOLEY_DOUBLE_ELEMENTS: 5772 case FAST_HOLEY_DOUBLE_ELEMENTS:
5770 return new(zone()) HStoreKeyedFastDoubleElement( 5773 return new(zone()) HStoreKeyedFastDoubleElement(
5771 elements, checked_key, val); 5774 elements, checked_key, val);
5772 case FAST_SMI_ELEMENTS: 5775 case FAST_SMI_ELEMENTS:
5773 case FAST_HOLEY_SMI_ELEMENTS: 5776 case FAST_HOLEY_SMI_ELEMENTS:
5774 // Smi-only arrays need a smi check. 5777 // Smi-only arrays need a smi check.
5775 AddInstruction(new(zone()) HCheckSmi(val)); 5778 AddInstruction(new(zone()) HCheckSmi(val));
5776 // Fall through. 5779 // Fall through.
5777 case FAST_ELEMENTS: 5780 case FAST_ELEMENTS:
5778 case FAST_HOLEY_ELEMENTS: 5781 case FAST_HOLEY_ELEMENTS:
5779 return new(zone()) HStoreKeyedFastElement( 5782 return new(zone()) HStoreKeyedFastElement(
5780 elements, checked_key, val, elements_kind); 5783 elements, checked_key, val, elements_kind);
5781 default: 5784 default:
5782 UNREACHABLE(); 5785 UNREACHABLE();
5783 return NULL; 5786 return NULL;
5784 } 5787 }
5785 } 5788 }
5786 // It's an element load (!is_store). 5789 // It's an element load (!is_store).
5787 HoleCheckMode mode = IsFastPackedElementsKind(elements_kind) ? 5790 HoleCheckMode mode = IsFastPackedElementsKind(elements_kind) ?
5788 OMIT_HOLE_CHECK : 5791 OMIT_HOLE_CHECK :
5789 PERFORM_HOLE_CHECK; 5792 PERFORM_HOLE_CHECK;
5790 if (IsFastDoubleElementsKind(elements_kind)) { 5793 if (IsFastDoubleElementsKind(elements_kind)) {
5791 return new(zone()) HLoadKeyedFastDoubleElement(elements, checked_key, mode); 5794 return new(zone()) HLoadKeyedFastDoubleElement(elements, checked_key,
5795 load_dependency, mode);
5792 } else { // Smi or Object elements. 5796 } else { // Smi or Object elements.
5793 return new(zone()) HLoadKeyedFastElement(elements, checked_key, 5797 return new(zone()) HLoadKeyedFastElement(elements, checked_key,
5794 elements_kind); 5798 load_dependency, elements_kind);
5795 } 5799 }
5796 } 5800 }
5797 5801
5798 5802
5799 HInstruction* HGraphBuilder::BuildMonomorphicElementAccess(HValue* object, 5803 HInstruction* HGraphBuilder::BuildMonomorphicElementAccess(HValue* object,
5800 HValue* key, 5804 HValue* key,
5801 HValue* val, 5805 HValue* val,
5802 HValue* dependency, 5806 HValue* dependency,
5803 Handle<Map> map, 5807 Handle<Map> map,
5804 bool is_store) { 5808 bool is_store) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
5840 AddInstruction(check_cow_map); 5844 AddInstruction(check_cow_map);
5841 } 5845 }
5842 HInstruction* length = NULL; 5846 HInstruction* length = NULL;
5843 HInstruction* checked_key = NULL; 5847 HInstruction* checked_key = NULL;
5844 if (map->has_external_array_elements()) { 5848 if (map->has_external_array_elements()) {
5845 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); 5849 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements));
5846 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); 5850 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length));
5847 HLoadExternalArrayPointer* external_elements = 5851 HLoadExternalArrayPointer* external_elements =
5848 new(zone()) HLoadExternalArrayPointer(elements); 5852 new(zone()) HLoadExternalArrayPointer(elements);
5849 AddInstruction(external_elements); 5853 AddInstruction(external_elements);
5850 return BuildExternalArrayElementAccess(external_elements, checked_key, 5854 return BuildExternalArrayElementAccess(
5851 val, map->elements_kind(), is_store); 5855 external_elements, checked_key, val, mapcheck,
5856 map->elements_kind(), is_store);
5852 } 5857 }
5853 ASSERT(fast_smi_only_elements || 5858 ASSERT(fast_smi_only_elements ||
5854 fast_elements || 5859 fast_elements ||
5855 map->has_fast_double_elements()); 5860 map->has_fast_double_elements());
5856 if (map->instance_type() == JS_ARRAY_TYPE) { 5861 if (map->instance_type() == JS_ARRAY_TYPE) {
5857 length = AddInstruction(new(zone()) HJSArrayLength(object, mapcheck, 5862 length = AddInstruction(new(zone()) HJSArrayLength(object, mapcheck,
5858 HType::Smi())); 5863 HType::Smi()));
5859 } else { 5864 } else {
5860 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); 5865 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements));
5861 } 5866 }
5862 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); 5867 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length));
5863 return BuildFastElementAccess(elements, checked_key, val, 5868 return BuildFastElementAccess(elements, checked_key, val, mapcheck,
5864 map->elements_kind(), is_store); 5869 map->elements_kind(), is_store);
5865 } 5870 }
5866 5871
5867 5872
5868 HInstruction* HGraphBuilder::TryBuildConsolidatedElementLoad( 5873 HInstruction* HGraphBuilder::TryBuildConsolidatedElementLoad(
5869 HValue* object, 5874 HValue* object,
5870 HValue* key, 5875 HValue* key,
5871 HValue* val, 5876 HValue* val,
5872 SmallMapList* maps) { 5877 SmallMapList* maps) {
5873 // For polymorphic loads of similar elements kinds (i.e. all tagged or all 5878 // For polymorphic loads of similar elements kinds (i.e. all tagged or all
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
6073 typecheck->SetSuccessorAt(0, if_jsarray); 6078 typecheck->SetSuccessorAt(0, if_jsarray);
6074 typecheck->SetSuccessorAt(1, if_fastobject); 6079 typecheck->SetSuccessorAt(1, if_fastobject);
6075 current_block()->Finish(typecheck); 6080 current_block()->Finish(typecheck);
6076 6081
6077 set_current_block(if_jsarray); 6082 set_current_block(if_jsarray);
6078 HInstruction* length; 6083 HInstruction* length;
6079 length = AddInstruction(new(zone()) HJSArrayLength(object, typecheck, 6084 length = AddInstruction(new(zone()) HJSArrayLength(object, typecheck,
6080 HType::Smi())); 6085 HType::Smi()));
6081 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); 6086 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length));
6082 access = AddInstruction(BuildFastElementAccess( 6087 access = AddInstruction(BuildFastElementAccess(
6083 elements, checked_key, val, elements_kind, is_store)); 6088 elements, checked_key, val, elements_kind_branch,
6089 elements_kind, is_store));
6084 if (!is_store) { 6090 if (!is_store) {
6085 Push(access); 6091 Push(access);
6086 } 6092 }
6087 6093
6088 *has_side_effects |= access->HasObservableSideEffects(); 6094 *has_side_effects |= access->HasObservableSideEffects();
6089 if (position != -1) { 6095 if (position != -1) {
6090 access->set_position(position); 6096 access->set_position(position);
6091 } 6097 }
6092 if_jsarray->Goto(join); 6098 if_jsarray->Goto(join);
6093 6099
6094 set_current_block(if_fastobject); 6100 set_current_block(if_fastobject);
6095 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); 6101 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements));
6096 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); 6102 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length));
6097 access = AddInstruction(BuildFastElementAccess( 6103 access = AddInstruction(BuildFastElementAccess(
6098 elements, checked_key, val, elements_kind, is_store)); 6104 elements, checked_key, val, elements_kind_branch,
6105 elements_kind, is_store));
6099 } else if (elements_kind == DICTIONARY_ELEMENTS) { 6106 } else if (elements_kind == DICTIONARY_ELEMENTS) {
6100 if (is_store) { 6107 if (is_store) {
6101 access = AddInstruction(BuildStoreKeyedGeneric(object, key, val)); 6108 access = AddInstruction(BuildStoreKeyedGeneric(object, key, val));
6102 } else { 6109 } else {
6103 access = AddInstruction(BuildLoadKeyedGeneric(object, key)); 6110 access = AddInstruction(BuildLoadKeyedGeneric(object, key));
6104 } 6111 }
6105 } else { // External array elements. 6112 } else { // External array elements.
6106 access = AddInstruction(BuildExternalArrayElementAccess( 6113 access = AddInstruction(BuildExternalArrayElementAccess(
6107 external_elements, checked_key, val, elements_kind, is_store)); 6114 external_elements, checked_key, val, elements_kind_branch,
6115 elements_kind, is_store));
6108 } 6116 }
6109 *has_side_effects |= access->HasObservableSideEffects(); 6117 *has_side_effects |= access->HasObservableSideEffects();
6110 if (position != RelocInfo::kNoPosition) access->set_position(position); 6118 if (position != RelocInfo::kNoPosition) access->set_position(position);
6111 if (!is_store) { 6119 if (!is_store) {
6112 Push(access); 6120 Push(access);
6113 } 6121 }
6114 current_block()->Goto(join); 6122 current_block()->Goto(join);
6115 set_current_block(if_false); 6123 set_current_block(if_false);
6116 } 6124 }
6117 } 6125 }
(...skipping 3455 matching lines...) Expand 10 before | Expand all | Expand 10 after
9573 } 9581 }
9574 } 9582 }
9575 9583
9576 #ifdef DEBUG 9584 #ifdef DEBUG
9577 if (graph_ != NULL) graph_->Verify(false); // No full verify. 9585 if (graph_ != NULL) graph_->Verify(false); // No full verify.
9578 if (allocator_ != NULL) allocator_->Verify(); 9586 if (allocator_ != NULL) allocator_->Verify();
9579 #endif 9587 #endif
9580 } 9588 }
9581 9589
9582 } } // namespace v8::internal 9590 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698