| 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 3883 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3894 } | 3894 } |
| 3895 | 3895 |
| 3896 | 3896 |
| 3897 HInstruction* HGraphBuilder::BuildMonomorphicElementAccess(HValue* object, | 3897 HInstruction* HGraphBuilder::BuildMonomorphicElementAccess(HValue* object, |
| 3898 HValue* key, | 3898 HValue* key, |
| 3899 HValue* val, | 3899 HValue* val, |
| 3900 Expression* expr, | 3900 Expression* expr, |
| 3901 bool is_store) { | 3901 bool is_store) { |
| 3902 ASSERT(expr->IsMonomorphic()); | 3902 ASSERT(expr->IsMonomorphic()); |
| 3903 Handle<Map> map = expr->GetMonomorphicReceiverType(); | 3903 Handle<Map> map = expr->GetMonomorphicReceiverType(); |
| 3904 if (!map->has_fast_elements() && !map->has_external_array_elements()) { | 3904 if (!map->has_fast_elements() && |
| 3905 !map->has_fast_double_elements() && |
| 3906 !map->has_external_array_elements()) { |
| 3905 return is_store ? BuildStoreKeyedGeneric(object, key, val) | 3907 return is_store ? BuildStoreKeyedGeneric(object, key, val) |
| 3906 : BuildLoadKeyedGeneric(object, key); | 3908 : BuildLoadKeyedGeneric(object, key); |
| 3907 } | 3909 } |
| 3908 AddInstruction(new(zone()) HCheckNonSmi(object)); | 3910 AddInstruction(new(zone()) HCheckNonSmi(object)); |
| 3909 AddInstruction(new(zone()) HCheckMap(object, map)); | 3911 AddInstruction(new(zone()) HCheckMap(object, map)); |
| 3910 HInstruction* elements = new(zone()) HLoadElements(object); | 3912 HInstruction* elements = new(zone()) HLoadElements(object); |
| 3911 HInstruction* length = NULL; | 3913 HInstruction* length = NULL; |
| 3912 HInstruction* checked_key = NULL; | 3914 HInstruction* checked_key = NULL; |
| 3913 if (map->has_external_array_elements()) { | 3915 if (map->has_external_array_elements()) { |
| 3914 AddInstruction(elements); | 3916 AddInstruction(elements); |
| 3915 length = AddInstruction(new(zone()) HExternalArrayLength(elements)); | 3917 length = AddInstruction(new(zone()) HExternalArrayLength(elements)); |
| 3916 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); | 3918 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); |
| 3917 HLoadExternalArrayPointer* external_elements = | 3919 HLoadExternalArrayPointer* external_elements = |
| 3918 new(zone()) HLoadExternalArrayPointer(elements); | 3920 new(zone()) HLoadExternalArrayPointer(elements); |
| 3919 AddInstruction(external_elements); | 3921 AddInstruction(external_elements); |
| 3920 return BuildExternalArrayElementAccess(external_elements, checked_key, | 3922 return BuildExternalArrayElementAccess(external_elements, checked_key, |
| 3921 val, map->elements_kind(), is_store); | 3923 val, map->elements_kind(), is_store); |
| 3922 } | 3924 } |
| 3923 ASSERT(map->has_fast_elements()); | 3925 bool fast_double_elements = map->has_fast_double_elements(); |
| 3926 ASSERT(map->has_fast_elements() || fast_double_elements); |
| 3924 if (map->instance_type() == JS_ARRAY_TYPE) { | 3927 if (map->instance_type() == JS_ARRAY_TYPE) { |
| 3925 length = AddInstruction(new(zone()) HJSArrayLength(object)); | 3928 length = AddInstruction(new(zone()) HJSArrayLength(object)); |
| 3926 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); | 3929 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); |
| 3927 AddInstruction(elements); | 3930 AddInstruction(elements); |
| 3928 if (is_store) { | 3931 if (is_store && !fast_double_elements) { |
| 3929 AddInstruction(new(zone()) HCheckMap( | 3932 AddInstruction(new(zone()) HCheckMap( |
| 3930 elements, isolate()->factory()->fixed_array_map())); | 3933 elements, isolate()->factory()->fixed_array_map())); |
| 3931 } | 3934 } |
| 3932 } else { | 3935 } else { |
| 3933 AddInstruction(elements); | 3936 AddInstruction(elements); |
| 3934 if (is_store) { | 3937 if (is_store && !fast_double_elements) { |
| 3935 AddInstruction(new(zone()) HCheckMap( | 3938 AddInstruction(new(zone()) HCheckMap( |
| 3936 elements, isolate()->factory()->fixed_array_map())); | 3939 elements, isolate()->factory()->fixed_array_map())); |
| 3937 } | 3940 } |
| 3938 length = AddInstruction(new(zone()) HFixedArrayLength(elements)); | 3941 length = AddInstruction(new(zone()) HFixedArrayLength(elements)); |
| 3939 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); | 3942 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); |
| 3940 } | 3943 } |
| 3941 if (is_store) { | 3944 if (is_store) { |
| 3942 return new(zone()) HStoreKeyedFastElement(elements, checked_key, val); | 3945 if (fast_double_elements) { |
| 3946 return new(zone()) HStoreKeyedFastDoubleElement(elements, |
| 3947 checked_key, |
| 3948 val); |
| 3949 } else { |
| 3950 return new(zone()) HStoreKeyedFastElement(elements, checked_key, val); |
| 3951 } |
| 3943 } else { | 3952 } else { |
| 3944 return new(zone()) HLoadKeyedFastElement(elements, checked_key); | 3953 if (fast_double_elements) { |
| 3954 return new(zone()) HLoadKeyedFastDoubleElement(elements, checked_key); |
| 3955 } else { |
| 3956 return new(zone()) HLoadKeyedFastElement(elements, checked_key); |
| 3957 } |
| 3945 } | 3958 } |
| 3946 } | 3959 } |
| 3947 | 3960 |
| 3948 | 3961 |
| 3949 HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object, | 3962 HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object, |
| 3950 HValue* key, | 3963 HValue* key, |
| 3951 HValue* val, | 3964 HValue* val, |
| 3952 Expression* prop, | 3965 Expression* prop, |
| 3953 int ast_id, | 3966 int ast_id, |
| 3954 int position, | 3967 int position, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 3967 } | 3980 } |
| 3968 | 3981 |
| 3969 for (int i = 0; i < maps->length(); ++i) { | 3982 for (int i = 0; i < maps->length(); ++i) { |
| 3970 ASSERT(maps->at(i)->IsMap()); | 3983 ASSERT(maps->at(i)->IsMap()); |
| 3971 type_todo[maps->at(i)->elements_kind()] = true; | 3984 type_todo[maps->at(i)->elements_kind()] = true; |
| 3972 if (maps->at(i)->elements_kind() | 3985 if (maps->at(i)->elements_kind() |
| 3973 >= JSObject::FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND) { | 3986 >= JSObject::FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND) { |
| 3974 todo_external_array = true; | 3987 todo_external_array = true; |
| 3975 } | 3988 } |
| 3976 } | 3989 } |
| 3977 // Support for FAST_DOUBLE_ELEMENTS isn't implemented yet, so we deopt. | |
| 3978 type_todo[JSObject::FAST_DOUBLE_ELEMENTS] = false; | |
| 3979 | 3990 |
| 3980 HBasicBlock* join = graph()->CreateBasicBlock(); | 3991 HBasicBlock* join = graph()->CreateBasicBlock(); |
| 3981 | 3992 |
| 3982 HInstruction* elements_kind_instr = | 3993 HInstruction* elements_kind_instr = |
| 3983 AddInstruction(new(zone()) HElementsKind(object)); | 3994 AddInstruction(new(zone()) HElementsKind(object)); |
| 3984 HInstruction* elements = NULL; | 3995 HInstruction* elements = NULL; |
| 3985 HLoadExternalArrayPointer* external_elements = NULL; | 3996 HLoadExternalArrayPointer* external_elements = NULL; |
| 3986 HInstruction* checked_key = NULL; | 3997 HInstruction* checked_key = NULL; |
| 3987 | 3998 |
| 3988 // FAST_ELEMENTS is assumed to be the first case. | 3999 // FAST_ELEMENTS is assumed to be the first case. |
| (...skipping 28 matching lines...) Expand all Loading... |
| 4017 HCompareConstantEqAndBranch* compare = | 4028 HCompareConstantEqAndBranch* compare = |
| 4018 new(zone()) HCompareConstantEqAndBranch(elements_kind_instr, | 4029 new(zone()) HCompareConstantEqAndBranch(elements_kind_instr, |
| 4019 elements_kind, | 4030 elements_kind, |
| 4020 Token::EQ_STRICT); | 4031 Token::EQ_STRICT); |
| 4021 compare->SetSuccessorAt(0, if_true); | 4032 compare->SetSuccessorAt(0, if_true); |
| 4022 compare->SetSuccessorAt(1, if_false); | 4033 compare->SetSuccessorAt(1, if_false); |
| 4023 current_block()->Finish(compare); | 4034 current_block()->Finish(compare); |
| 4024 | 4035 |
| 4025 set_current_block(if_true); | 4036 set_current_block(if_true); |
| 4026 HInstruction* access; | 4037 HInstruction* access; |
| 4027 if (elements_kind == JSObject::FAST_ELEMENTS) { | 4038 if (elements_kind == JSObject::FAST_ELEMENTS || |
| 4039 elements_kind == JSObject::FAST_DOUBLE_ELEMENTS) { |
| 4028 HBasicBlock* if_jsarray = graph()->CreateBasicBlock(); | 4040 HBasicBlock* if_jsarray = graph()->CreateBasicBlock(); |
| 4029 HBasicBlock* if_fastobject = graph()->CreateBasicBlock(); | 4041 HBasicBlock* if_fastobject = graph()->CreateBasicBlock(); |
| 4030 HHasInstanceTypeAndBranch* typecheck = | 4042 HHasInstanceTypeAndBranch* typecheck = |
| 4031 new(zone()) HHasInstanceTypeAndBranch(object, JS_ARRAY_TYPE); | 4043 new(zone()) HHasInstanceTypeAndBranch(object, JS_ARRAY_TYPE); |
| 4032 typecheck->SetSuccessorAt(0, if_jsarray); | 4044 typecheck->SetSuccessorAt(0, if_jsarray); |
| 4033 typecheck->SetSuccessorAt(1, if_fastobject); | 4045 typecheck->SetSuccessorAt(1, if_fastobject); |
| 4034 current_block()->Finish(typecheck); | 4046 current_block()->Finish(typecheck); |
| 4035 | 4047 |
| 4036 set_current_block(if_jsarray); | 4048 set_current_block(if_jsarray); |
| 4037 HInstruction* length = new(zone()) HJSArrayLength(object); | 4049 HInstruction* length = new(zone()) HJSArrayLength(object); |
| 4038 AddInstruction(length); | 4050 AddInstruction(length); |
| 4039 length->ClearFlag(HValue::kUseGVN); | 4051 length->ClearFlag(HValue::kUseGVN); |
| 4040 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); | 4052 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); |
| 4041 elements = AddInstruction(new(zone()) HLoadElements(object)); | 4053 elements = AddInstruction(new(zone()) HLoadElements(object)); |
| 4042 elements->ClearFlag(HValue::kUseGVN); | 4054 elements->ClearFlag(HValue::kUseGVN); |
| 4055 bool fast_double_elements = |
| 4056 elements_kind == JSObject::FAST_DOUBLE_ELEMENTS; |
| 4043 if (is_store) { | 4057 if (is_store) { |
| 4044 AddInstruction(new(zone()) HCheckMap( | 4058 if (fast_double_elements) { |
| 4045 elements, isolate()->factory()->fixed_array_map())); | 4059 access = AddInstruction( |
| 4046 access = AddInstruction( | 4060 new(zone()) HStoreKeyedFastDoubleElement(elements, |
| 4047 new(zone()) HStoreKeyedFastElement(elements, checked_key, val)); | 4061 checked_key, |
| 4062 val)); |
| 4063 } else { |
| 4064 AddInstruction(new(zone()) HCheckMap( |
| 4065 elements, isolate()->factory()->fixed_array_map())); |
| 4066 access = AddInstruction( |
| 4067 new(zone()) HStoreKeyedFastElement(elements, checked_key, val)); |
| 4068 } |
| 4048 } else { | 4069 } else { |
| 4049 access = AddInstruction( | 4070 if (fast_double_elements) { |
| 4050 new(zone()) HLoadKeyedFastElement(elements, checked_key)); | 4071 access = AddInstruction( |
| 4072 new(zone()) HLoadKeyedFastDoubleElement(elements, checked_key)); |
| 4073 } else { |
| 4074 access = AddInstruction( |
| 4075 new(zone()) HLoadKeyedFastElement(elements, checked_key)); |
| 4076 } |
| 4051 Push(access); | 4077 Push(access); |
| 4052 } | 4078 } |
| 4053 *has_side_effects |= access->HasSideEffects(); | 4079 *has_side_effects |= access->HasSideEffects(); |
| 4054 if (position != -1) { | 4080 if (position != -1) { |
| 4055 access->set_position(position); | 4081 access->set_position(position); |
| 4056 } | 4082 } |
| 4057 if_jsarray->Goto(join); | 4083 if_jsarray->Goto(join); |
| 4058 | 4084 |
| 4059 set_current_block(if_fastobject); | 4085 set_current_block(if_fastobject); |
| 4060 elements = AddInstruction(new(zone()) HLoadElements(object)); | 4086 elements = AddInstruction(new(zone()) HLoadElements(object)); |
| 4061 elements->ClearFlag(HValue::kUseGVN); | 4087 elements->ClearFlag(HValue::kUseGVN); |
| 4062 if (is_store) { | 4088 if (is_store && !fast_double_elements) { |
| 4063 AddInstruction(new(zone()) HCheckMap( | 4089 AddInstruction(new(zone()) HCheckMap( |
| 4064 elements, isolate()->factory()->fixed_array_map())); | 4090 elements, isolate()->factory()->fixed_array_map())); |
| 4065 } | 4091 } |
| 4066 length = AddInstruction(new(zone()) HFixedArrayLength(elements)); | 4092 length = AddInstruction(new(zone()) HFixedArrayLength(elements)); |
| 4067 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); | 4093 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); |
| 4068 if (is_store) { | 4094 if (is_store) { |
| 4069 access = AddInstruction( | 4095 if (fast_double_elements) { |
| 4070 new(zone()) HStoreKeyedFastElement(elements, checked_key, val)); | 4096 access = AddInstruction( |
| 4097 new(zone()) HStoreKeyedFastDoubleElement(elements, |
| 4098 checked_key, |
| 4099 val)); |
| 4100 } else { |
| 4101 access = AddInstruction( |
| 4102 new(zone()) HStoreKeyedFastElement(elements, checked_key, val)); |
| 4103 } |
| 4071 } else { | 4104 } else { |
| 4072 access = AddInstruction( | 4105 if (fast_double_elements) { |
| 4073 new(zone()) HLoadKeyedFastElement(elements, checked_key)); | 4106 access = AddInstruction( |
| 4107 new(zone()) HLoadKeyedFastDoubleElement(elements, checked_key)); |
| 4108 } else { |
| 4109 access = AddInstruction( |
| 4110 new(zone()) HLoadKeyedFastElement(elements, checked_key)); |
| 4111 } |
| 4074 } | 4112 } |
| 4075 } else if (elements_kind == JSObject::DICTIONARY_ELEMENTS) { | 4113 } else if (elements_kind == JSObject::DICTIONARY_ELEMENTS) { |
| 4076 if (is_store) { | 4114 if (is_store) { |
| 4077 access = AddInstruction(BuildStoreKeyedGeneric(object, key, val)); | 4115 access = AddInstruction(BuildStoreKeyedGeneric(object, key, val)); |
| 4078 } else { | 4116 } else { |
| 4079 access = AddInstruction(BuildLoadKeyedGeneric(object, key)); | 4117 access = AddInstruction(BuildLoadKeyedGeneric(object, key)); |
| 4080 } | 4118 } |
| 4081 } else { // External array elements. | 4119 } else { // External array elements. |
| 4082 access = AddInstruction(BuildExternalArrayElementAccess( | 4120 access = AddInstruction(BuildExternalArrayElementAccess( |
| 4083 external_elements, checked_key, val, elements_kind, is_store)); | 4121 external_elements, checked_key, val, elements_kind, is_store)); |
| (...skipping 2622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6706 } | 6744 } |
| 6707 } | 6745 } |
| 6708 | 6746 |
| 6709 #ifdef DEBUG | 6747 #ifdef DEBUG |
| 6710 if (graph_ != NULL) graph_->Verify(); | 6748 if (graph_ != NULL) graph_->Verify(); |
| 6711 if (allocator_ != NULL) allocator_->Verify(); | 6749 if (allocator_ != NULL) allocator_->Verify(); |
| 6712 #endif | 6750 #endif |
| 6713 } | 6751 } |
| 6714 | 6752 |
| 6715 } } // namespace v8::internal | 6753 } } // namespace v8::internal |
| OLD | NEW |