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

Side by Side Diff: src/hydrogen.cc

Issue 7003054: Fix bug with GVN on array loads. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: fixed performance regression Created 9 years, 6 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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 2244 matching lines...) Expand 10 before | Expand all | Expand 10 after
2255 HStackCheckEliminator sce(graph()); 2255 HStackCheckEliminator sce(graph());
2256 sce.Process(); 2256 sce.Process();
2257 2257
2258 // Perform common subexpression elimination and loop-invariant code motion. 2258 // Perform common subexpression elimination and loop-invariant code motion.
2259 if (FLAG_use_gvn) { 2259 if (FLAG_use_gvn) {
2260 HPhase phase("Global value numbering", graph()); 2260 HPhase phase("Global value numbering", graph());
2261 HGlobalValueNumberer gvn(graph(), info()); 2261 HGlobalValueNumberer gvn(graph(), info());
2262 gvn.Analyze(); 2262 gvn.Analyze();
2263 } 2263 }
2264 2264
2265 // Replace the results of check instructions with the original value, if the
2266 // result is used. This is safe now, since we don't do code motion after this
2267 // point. It enables better register allocation since the value produced by
2268 // check instructions is really a copy of the original value.
2269 graph()->ReplaceCheckedValues();
2270
2265 return graph(); 2271 return graph();
2266 } 2272 }
2267 2273
2268 2274
2275 void HGraph::ReplaceCheckedValues() {
2276 HPhase phase("Replace checked values", this);
2277 for (int i = 0; i < blocks()->length(); ++i) {
2278 HInstruction* instr = blocks()->at(i)->first();
2279 while (instr != NULL) {
2280 if (instr->IsBoundsCheck()) {
2281 // Replace all uses of the checked value with the original input.
2282 instr->ReplaceAllUsesWith(HBoundsCheck::cast(instr)->index());
2283 }
2284 instr = instr->next();
2285 }
2286 }
2287 }
2288
2289
2269 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) { 2290 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) {
2270 ASSERT(current_block() != NULL); 2291 ASSERT(current_block() != NULL);
2271 current_block()->AddInstruction(instr); 2292 current_block()->AddInstruction(instr);
2272 return instr; 2293 return instr;
2273 } 2294 }
2274 2295
2275 2296
2276 void HGraphBuilder::AddSimulate(int id) { 2297 void HGraphBuilder::AddSimulate(int id) {
2277 ASSERT(current_block() != NULL); 2298 ASSERT(current_block() != NULL);
2278 current_block()->AddSimulate(id); 2299 current_block()->AddSimulate(id);
(...skipping 1428 matching lines...) Expand 10 before | Expand all | Expand 10 after
3707 HValue* key, 3728 HValue* key,
3708 Property* expr) { 3729 Property* expr) {
3709 ASSERT(!expr->key()->IsPropertyName() && expr->IsMonomorphic()); 3730 ASSERT(!expr->key()->IsPropertyName() && expr->IsMonomorphic());
3710 AddInstruction(new(zone()) HCheckNonSmi(object)); 3731 AddInstruction(new(zone()) HCheckNonSmi(object));
3711 Handle<Map> map = expr->GetMonomorphicReceiverType(); 3732 Handle<Map> map = expr->GetMonomorphicReceiverType();
3712 ASSERT(map->has_fast_elements()); 3733 ASSERT(map->has_fast_elements());
3713 AddInstruction(new(zone()) HCheckMap(object, map)); 3734 AddInstruction(new(zone()) HCheckMap(object, map));
3714 bool is_array = (map->instance_type() == JS_ARRAY_TYPE); 3735 bool is_array = (map->instance_type() == JS_ARRAY_TYPE);
3715 HLoadElements* elements = new(zone()) HLoadElements(object); 3736 HLoadElements* elements = new(zone()) HLoadElements(object);
3716 HInstruction* length = NULL; 3737 HInstruction* length = NULL;
3738 HInstruction* checked_key = NULL;
3717 if (is_array) { 3739 if (is_array) {
3718 length = AddInstruction(new(zone()) HJSArrayLength(object)); 3740 length = AddInstruction(new(zone()) HJSArrayLength(object));
3719 AddInstruction(new(zone()) HBoundsCheck(key, length)); 3741 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length));
3720 AddInstruction(elements); 3742 AddInstruction(elements);
3721 } else { 3743 } else {
3722 AddInstruction(elements); 3744 AddInstruction(elements);
3723 length = AddInstruction(new(zone()) HFixedArrayLength(elements)); 3745 length = AddInstruction(new(zone()) HFixedArrayLength(elements));
3724 AddInstruction(new(zone()) HBoundsCheck(key, length)); 3746 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length));
3725 } 3747 }
3726 return new(zone()) HLoadKeyedFastElement(elements, key); 3748 return new(zone()) HLoadKeyedFastElement(elements, checked_key);
3727 } 3749 }
3728 3750
3729 3751
3730 HInstruction* HGraphBuilder::BuildLoadKeyedSpecializedArrayElement( 3752 HInstruction* HGraphBuilder::BuildLoadKeyedSpecializedArrayElement(
3731 HValue* object, 3753 HValue* object,
3732 HValue* key, 3754 HValue* key,
3733 Property* expr) { 3755 Property* expr) {
3734 ASSERT(!expr->key()->IsPropertyName() && expr->IsMonomorphic()); 3756 ASSERT(!expr->key()->IsPropertyName() && expr->IsMonomorphic());
3735 AddInstruction(new(zone()) HCheckNonSmi(object)); 3757 AddInstruction(new(zone()) HCheckNonSmi(object));
3736 Handle<Map> map = expr->GetMonomorphicReceiverType(); 3758 Handle<Map> map = expr->GetMonomorphicReceiverType();
3737 ASSERT(!map->has_fast_elements()); 3759 ASSERT(!map->has_fast_elements());
3738 ASSERT(map->has_external_array_elements()); 3760 ASSERT(map->has_external_array_elements());
3739 AddInstruction(new(zone()) HCheckMap(object, map)); 3761 AddInstruction(new(zone()) HCheckMap(object, map));
3740 HLoadElements* elements = new(zone()) HLoadElements(object); 3762 HLoadElements* elements = new(zone()) HLoadElements(object);
3741 AddInstruction(elements); 3763 AddInstruction(elements);
3742 HInstruction* length = new(zone()) HExternalArrayLength(elements); 3764 HInstruction* length = new(zone()) HExternalArrayLength(elements);
3743 AddInstruction(length); 3765 AddInstruction(length);
3744 AddInstruction(new(zone()) HBoundsCheck(key, length)); 3766 HInstruction* checked_key =
3767 AddInstruction(new(zone()) HBoundsCheck(key, length));
3745 HLoadExternalArrayPointer* external_elements = 3768 HLoadExternalArrayPointer* external_elements =
3746 new(zone()) HLoadExternalArrayPointer(elements); 3769 new(zone()) HLoadExternalArrayPointer(elements);
3747 AddInstruction(external_elements); 3770 AddInstruction(external_elements);
3748 HLoadKeyedSpecializedArrayElement* pixel_array_value = 3771 HLoadKeyedSpecializedArrayElement* pixel_array_value =
3749 new(zone()) HLoadKeyedSpecializedArrayElement( 3772 new(zone()) HLoadKeyedSpecializedArrayElement(
3750 external_elements, key, expr->external_array_type()); 3773 external_elements, checked_key, expr->external_array_type());
3751 return pixel_array_value; 3774 return pixel_array_value;
3752 } 3775 }
3753 3776
3754 3777
3755 HInstruction* HGraphBuilder::BuildLoadKeyed(HValue* obj, 3778 HInstruction* HGraphBuilder::BuildLoadKeyed(HValue* obj,
3756 HValue* key, 3779 HValue* key,
3757 Property* prop) { 3780 Property* prop) {
3758 if (prop->IsMonomorphic()) { 3781 if (prop->IsMonomorphic()) {
3759 Handle<Map> receiver_type(prop->GetMonomorphicReceiverType()); 3782 Handle<Map> receiver_type(prop->GetMonomorphicReceiverType());
3760 // An object has either fast elements or pixel array elements, but never 3783 // An object has either fast elements or pixel array elements, but never
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
3795 HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object)); 3818 HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object));
3796 AddInstruction(new(zone()) HCheckMap( 3819 AddInstruction(new(zone()) HCheckMap(
3797 elements, isolate()->factory()->fixed_array_map())); 3820 elements, isolate()->factory()->fixed_array_map()));
3798 bool is_array = (map->instance_type() == JS_ARRAY_TYPE); 3821 bool is_array = (map->instance_type() == JS_ARRAY_TYPE);
3799 HInstruction* length = NULL; 3822 HInstruction* length = NULL;
3800 if (is_array) { 3823 if (is_array) {
3801 length = AddInstruction(new(zone()) HJSArrayLength(object)); 3824 length = AddInstruction(new(zone()) HJSArrayLength(object));
3802 } else { 3825 } else {
3803 length = AddInstruction(new(zone()) HFixedArrayLength(elements)); 3826 length = AddInstruction(new(zone()) HFixedArrayLength(elements));
3804 } 3827 }
3805 AddInstruction(new(zone()) HBoundsCheck(key, length)); 3828 HInstruction* checked_key =
3806 return new(zone()) HStoreKeyedFastElement(elements, key, val); 3829 AddInstruction(new(zone()) HBoundsCheck(key, length));
3830 return new(zone()) HStoreKeyedFastElement(elements, checked_key, val);
3807 } 3831 }
3808 3832
3809 3833
3810 HInstruction* HGraphBuilder::BuildStoreKeyedSpecializedArrayElement( 3834 HInstruction* HGraphBuilder::BuildStoreKeyedSpecializedArrayElement(
3811 HValue* object, 3835 HValue* object,
3812 HValue* key, 3836 HValue* key,
3813 HValue* val, 3837 HValue* val,
3814 Expression* expr) { 3838 Expression* expr) {
3815 ASSERT(expr->IsMonomorphic()); 3839 ASSERT(expr->IsMonomorphic());
3816 AddInstruction(new(zone()) HCheckNonSmi(object)); 3840 AddInstruction(new(zone()) HCheckNonSmi(object));
3817 Handle<Map> map = expr->GetMonomorphicReceiverType(); 3841 Handle<Map> map = expr->GetMonomorphicReceiverType();
3818 ASSERT(!map->has_fast_elements()); 3842 ASSERT(!map->has_fast_elements());
3819 ASSERT(map->has_external_array_elements()); 3843 ASSERT(map->has_external_array_elements());
3820 AddInstruction(new(zone()) HCheckMap(object, map)); 3844 AddInstruction(new(zone()) HCheckMap(object, map));
3821 HLoadElements* elements = new(zone()) HLoadElements(object); 3845 HLoadElements* elements = new(zone()) HLoadElements(object);
3822 AddInstruction(elements); 3846 AddInstruction(elements);
3823 HInstruction* length = AddInstruction( 3847 HInstruction* length = AddInstruction(
3824 new(zone()) HExternalArrayLength(elements)); 3848 new(zone()) HExternalArrayLength(elements));
3825 AddInstruction(new(zone()) HBoundsCheck(key, length)); 3849 HInstruction* checked_key =
3850 AddInstruction(new(zone()) HBoundsCheck(key, length));
3826 HLoadExternalArrayPointer* external_elements = 3851 HLoadExternalArrayPointer* external_elements =
3827 new(zone()) HLoadExternalArrayPointer(elements); 3852 new(zone()) HLoadExternalArrayPointer(elements);
3828 AddInstruction(external_elements); 3853 AddInstruction(external_elements);
3829 ExternalArrayType array_type = expr->external_array_type(); 3854 ExternalArrayType array_type = expr->external_array_type();
3830 switch (array_type) { 3855 switch (array_type) {
3831 case kExternalPixelArray: { 3856 case kExternalPixelArray: {
3832 HClampToUint8* clamp = new(zone()) HClampToUint8(val); 3857 HClampToUint8* clamp = new(zone()) HClampToUint8(val);
3833 AddInstruction(clamp); 3858 AddInstruction(clamp);
3834 val = clamp; 3859 val = clamp;
3835 break; 3860 break;
3836 } 3861 }
3837 case kExternalByteArray: 3862 case kExternalByteArray:
3838 case kExternalUnsignedByteArray: 3863 case kExternalUnsignedByteArray:
3839 case kExternalShortArray: 3864 case kExternalShortArray:
3840 case kExternalUnsignedShortArray: 3865 case kExternalUnsignedShortArray:
3841 case kExternalIntArray: 3866 case kExternalIntArray:
3842 case kExternalUnsignedIntArray: { 3867 case kExternalUnsignedIntArray: {
3843 HToInt32* floor_val = new(zone()) HToInt32(val); 3868 HToInt32* floor_val = new(zone()) HToInt32(val);
3844 AddInstruction(floor_val); 3869 AddInstruction(floor_val);
3845 val = floor_val; 3870 val = floor_val;
3846 break; 3871 break;
3847 } 3872 }
3848 case kExternalFloatArray: 3873 case kExternalFloatArray:
3849 case kExternalDoubleArray: 3874 case kExternalDoubleArray:
3850 break; 3875 break;
3851 } 3876 }
3852 return new(zone()) HStoreKeyedSpecializedArrayElement( 3877 return new(zone()) HStoreKeyedSpecializedArrayElement(
3853 external_elements, 3878 external_elements,
3854 key, 3879 checked_key,
3855 val, 3880 val,
3856 expr->external_array_type()); 3881 expr->external_array_type());
3857 } 3882 }
3858 3883
3859 3884
3860 HInstruction* HGraphBuilder::BuildStoreKeyed(HValue* object, 3885 HInstruction* HGraphBuilder::BuildStoreKeyed(HValue* object,
3861 HValue* key, 3886 HValue* key,
3862 HValue* value, 3887 HValue* value,
3863 Expression* expr) { 3888 Expression* expr) {
3864 if (expr->IsMonomorphic()) { 3889 if (expr->IsMonomorphic()) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
3902 result = new(zone()) HArgumentsLength(elements); 3927 result = new(zone()) HArgumentsLength(elements);
3903 } else { 3928 } else {
3904 Push(graph()->GetArgumentsObject()); 3929 Push(graph()->GetArgumentsObject());
3905 VisitForValue(expr->key()); 3930 VisitForValue(expr->key());
3906 if (HasStackOverflow() || current_block() == NULL) return true; 3931 if (HasStackOverflow() || current_block() == NULL) return true;
3907 HValue* key = Pop(); 3932 HValue* key = Pop();
3908 Drop(1); // Arguments object. 3933 Drop(1); // Arguments object.
3909 HInstruction* elements = AddInstruction(new(zone()) HArgumentsElements); 3934 HInstruction* elements = AddInstruction(new(zone()) HArgumentsElements);
3910 HInstruction* length = AddInstruction( 3935 HInstruction* length = AddInstruction(
3911 new(zone()) HArgumentsLength(elements)); 3936 new(zone()) HArgumentsLength(elements));
3912 AddInstruction(new(zone()) HBoundsCheck(key, length)); 3937 HInstruction* checked_key =
3913 result = new(zone()) HAccessArgumentsAt(elements, length, key); 3938 AddInstruction(new(zone()) HBoundsCheck(key, length));
3939 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key);
3914 } 3940 }
3915 ast_context()->ReturnInstruction(result, expr->id()); 3941 ast_context()->ReturnInstruction(result, expr->id());
3916 return true; 3942 return true;
3917 } 3943 }
3918 3944
3919 3945
3920 void HGraphBuilder::VisitProperty(Property* expr) { 3946 void HGraphBuilder::VisitProperty(Property* expr) {
3921 ASSERT(!HasStackOverflow()); 3947 ASSERT(!HasStackOverflow());
3922 ASSERT(current_block() != NULL); 3948 ASSERT(current_block() != NULL);
3923 ASSERT(current_block()->HasPredecessor()); 3949 ASSERT(current_block()->HasPredecessor());
(...skipping 1092 matching lines...) Expand 10 before | Expand all | Expand 10 after
5016 return new(zone()) HCompareSymbolEq(left, right, op); 5042 return new(zone()) HCompareSymbolEq(left, right, op);
5017 } 5043 }
5018 5044
5019 5045
5020 HStringCharCodeAt* HGraphBuilder::BuildStringCharCodeAt(HValue* string, 5046 HStringCharCodeAt* HGraphBuilder::BuildStringCharCodeAt(HValue* string,
5021 HValue* index) { 5047 HValue* index) {
5022 AddInstruction(new(zone()) HCheckNonSmi(string)); 5048 AddInstruction(new(zone()) HCheckNonSmi(string));
5023 AddInstruction(HCheckInstanceType::NewIsString(string)); 5049 AddInstruction(HCheckInstanceType::NewIsString(string));
5024 HStringLength* length = new(zone()) HStringLength(string); 5050 HStringLength* length = new(zone()) HStringLength(string);
5025 AddInstruction(length); 5051 AddInstruction(length);
5026 AddInstruction(new(zone()) HBoundsCheck(index, length)); 5052 HInstruction* checked_index =
5027 return new(zone()) HStringCharCodeAt(string, index); 5053 AddInstruction(new(zone()) HBoundsCheck(index, length));
5054 return new(zone()) HStringCharCodeAt(string, checked_index);
5028 } 5055 }
5029 5056
5030 5057
5031 HInstruction* HGraphBuilder::BuildBinaryOperation(BinaryOperation* expr, 5058 HInstruction* HGraphBuilder::BuildBinaryOperation(BinaryOperation* expr,
5032 HValue* left, 5059 HValue* left,
5033 HValue* right) { 5060 HValue* right) {
5034 TypeInfo info = oracle()->BinaryType(expr); 5061 TypeInfo info = oracle()->BinaryType(expr);
5035 if (info.IsUninitialized()) { 5062 if (info.IsUninitialized()) {
5036 AddInstruction(new(zone()) HSoftDeoptimize); 5063 AddInstruction(new(zone()) HSoftDeoptimize);
5037 info = TypeInfo::Unknown(); 5064 info = TypeInfo::Unknown();
(...skipping 1301 matching lines...) Expand 10 before | Expand all | Expand 10 after
6339 } 6366 }
6340 } 6367 }
6341 6368
6342 #ifdef DEBUG 6369 #ifdef DEBUG
6343 if (graph_ != NULL) graph_->Verify(); 6370 if (graph_ != NULL) graph_->Verify();
6344 if (allocator_ != NULL) allocator_->Verify(); 6371 if (allocator_ != NULL) allocator_->Verify();
6345 #endif 6372 #endif
6346 } 6373 }
6347 6374
6348 } } // namespace v8::internal 6375 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | src/hydrogen-instructions.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698