| 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 |