OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |