| 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 3318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3329 | 3329 |
| 3330 // Load the elements array before the first store. | 3330 // Load the elements array before the first store. |
| 3331 if (elements == NULL) { | 3331 if (elements == NULL) { |
| 3332 elements = new(zone()) HLoadElements(literal); | 3332 elements = new(zone()) HLoadElements(literal); |
| 3333 AddInstruction(elements); | 3333 AddInstruction(elements); |
| 3334 } | 3334 } |
| 3335 | 3335 |
| 3336 HValue* key = AddInstruction( | 3336 HValue* key = AddInstruction( |
| 3337 new(zone()) HConstant(Handle<Object>(Smi::FromInt(i)), | 3337 new(zone()) HConstant(Handle<Object>(Smi::FromInt(i)), |
| 3338 Representation::Integer32())); | 3338 Representation::Integer32())); |
| 3339 AddInstruction(new(zone()) HStoreKeyedFastElement(elements, key, value)); | 3339 if (FLAG_smi_only_arrays) { |
| 3340 AddInstruction(BuildStoreKeyedGeneric(literal, key, value)); |
| 3341 } else { |
| 3342 AddInstruction(new(zone()) HStoreKeyedFastElement(elements, key, value)); |
| 3343 } |
| 3344 |
| 3340 AddSimulate(expr->GetIdForElement(i)); | 3345 AddSimulate(expr->GetIdForElement(i)); |
| 3341 } | 3346 } |
| 3342 return ast_context()->ReturnValue(Pop()); | 3347 return ast_context()->ReturnValue(Pop()); |
| 3343 } | 3348 } |
| 3344 | 3349 |
| 3345 | 3350 |
| 3346 // Sets the lookup result and returns true if the store can be inlined. | 3351 // Sets the lookup result and returns true if the store can be inlined. |
| 3347 static bool ComputeStoredField(Handle<Map> type, | 3352 static bool ComputeStoredField(Handle<Map> type, |
| 3348 Handle<String> name, | 3353 Handle<String> name, |
| 3349 LookupResult* lookup) { | 3354 LookupResult* lookup) { |
| (...skipping 590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3940 case EXTERNAL_INT_ELEMENTS: | 3945 case EXTERNAL_INT_ELEMENTS: |
| 3941 case EXTERNAL_UNSIGNED_INT_ELEMENTS: { | 3946 case EXTERNAL_UNSIGNED_INT_ELEMENTS: { |
| 3942 HToInt32* floor_val = new(zone()) HToInt32(val); | 3947 HToInt32* floor_val = new(zone()) HToInt32(val); |
| 3943 AddInstruction(floor_val); | 3948 AddInstruction(floor_val); |
| 3944 val = floor_val; | 3949 val = floor_val; |
| 3945 break; | 3950 break; |
| 3946 } | 3951 } |
| 3947 case EXTERNAL_FLOAT_ELEMENTS: | 3952 case EXTERNAL_FLOAT_ELEMENTS: |
| 3948 case EXTERNAL_DOUBLE_ELEMENTS: | 3953 case EXTERNAL_DOUBLE_ELEMENTS: |
| 3949 break; | 3954 break; |
| 3955 case FAST_SMI_ONLY_ELEMENTS: |
| 3950 case FAST_ELEMENTS: | 3956 case FAST_ELEMENTS: |
| 3951 case FAST_DOUBLE_ELEMENTS: | 3957 case FAST_DOUBLE_ELEMENTS: |
| 3952 case DICTIONARY_ELEMENTS: | 3958 case DICTIONARY_ELEMENTS: |
| 3953 case NON_STRICT_ARGUMENTS_ELEMENTS: | 3959 case NON_STRICT_ARGUMENTS_ELEMENTS: |
| 3954 UNREACHABLE(); | 3960 UNREACHABLE(); |
| 3955 break; | 3961 break; |
| 3956 } | 3962 } |
| 3957 return new(zone()) HStoreKeyedSpecializedArrayElement( | 3963 return new(zone()) HStoreKeyedSpecializedArrayElement( |
| 3958 external_elements, checked_key, val, elements_kind); | 3964 external_elements, checked_key, val, elements_kind); |
| 3959 } else { | 3965 } else { |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4051 | 4057 |
| 4052 HBasicBlock* join = graph()->CreateBasicBlock(); | 4058 HBasicBlock* join = graph()->CreateBasicBlock(); |
| 4053 | 4059 |
| 4054 HInstruction* elements_kind_instr = | 4060 HInstruction* elements_kind_instr = |
| 4055 AddInstruction(new(zone()) HElementsKind(object)); | 4061 AddInstruction(new(zone()) HElementsKind(object)); |
| 4056 HCompareConstantEqAndBranch* elements_kind_branch = NULL; | 4062 HCompareConstantEqAndBranch* elements_kind_branch = NULL; |
| 4057 HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object)); | 4063 HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object)); |
| 4058 HLoadExternalArrayPointer* external_elements = NULL; | 4064 HLoadExternalArrayPointer* external_elements = NULL; |
| 4059 HInstruction* checked_key = NULL; | 4065 HInstruction* checked_key = NULL; |
| 4060 | 4066 |
| 4061 // FAST_ELEMENTS is assumed to be the first case. | 4067 // Generated code assumes that FAST_SMI_ONLY_ELEMENTS, FAST_ELEMENTS, |
| 4062 STATIC_ASSERT(FAST_ELEMENTS == 0); | 4068 // FAST_DOUBLE_ELEMENTS and DICTIONARY_ELEMENTS are handled before external |
| 4069 // arrays. |
| 4070 STATIC_ASSERT(FAST_SMI_ONLY_ELEMENTS < FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); |
| 4071 STATIC_ASSERT(FAST_ELEMENTS < FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); |
| 4072 STATIC_ASSERT(FAST_DOUBLE_ELEMENTS < FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); |
| 4073 STATIC_ASSERT(DICTIONARY_ELEMENTS < FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); |
| 4063 | 4074 |
| 4064 for (ElementsKind elements_kind = FAST_ELEMENTS; | 4075 for (ElementsKind elements_kind = FIRST_ELEMENTS_KIND; |
| 4065 elements_kind <= LAST_ELEMENTS_KIND; | 4076 elements_kind <= LAST_ELEMENTS_KIND; |
| 4066 elements_kind = ElementsKind(elements_kind + 1)) { | 4077 elements_kind = ElementsKind(elements_kind + 1)) { |
| 4067 // After having handled FAST_ELEMENTS and DICTIONARY_ELEMENTS, we | 4078 // After having handled FAST_ELEMENTS, FAST_SMI_ELEMENTS, |
| 4068 // need to add some code that's executed for all external array cases. | 4079 // FAST_DOUBLE_ELEMENTS and DICTIONARY_ELEMENTS, we need to add some code |
| 4080 // that's executed for all external array cases. |
| 4069 STATIC_ASSERT(LAST_EXTERNAL_ARRAY_ELEMENTS_KIND == | 4081 STATIC_ASSERT(LAST_EXTERNAL_ARRAY_ELEMENTS_KIND == |
| 4070 LAST_ELEMENTS_KIND); | 4082 LAST_ELEMENTS_KIND); |
| 4071 if (elements_kind == FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND | 4083 if (elements_kind == FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND |
| 4072 && todo_external_array) { | 4084 && todo_external_array) { |
| 4073 HInstruction* length = | 4085 HInstruction* length = |
| 4074 AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); | 4086 AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); |
| 4075 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); | 4087 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); |
| 4076 external_elements = new(zone()) HLoadExternalArrayPointer(elements); | 4088 external_elements = new(zone()) HLoadExternalArrayPointer(elements); |
| 4077 AddInstruction(external_elements); | 4089 AddInstruction(external_elements); |
| 4078 } | 4090 } |
| 4079 if (type_todo[elements_kind]) { | 4091 if (type_todo[elements_kind]) { |
| 4080 HBasicBlock* if_true = graph()->CreateBasicBlock(); | 4092 HBasicBlock* if_true = graph()->CreateBasicBlock(); |
| 4081 HBasicBlock* if_false = graph()->CreateBasicBlock(); | 4093 HBasicBlock* if_false = graph()->CreateBasicBlock(); |
| 4082 elements_kind_branch = new(zone()) HCompareConstantEqAndBranch( | 4094 elements_kind_branch = new(zone()) HCompareConstantEqAndBranch( |
| 4083 elements_kind_instr, elements_kind, Token::EQ_STRICT); | 4095 elements_kind_instr, elements_kind, Token::EQ_STRICT); |
| 4084 elements_kind_branch->SetSuccessorAt(0, if_true); | 4096 elements_kind_branch->SetSuccessorAt(0, if_true); |
| 4085 elements_kind_branch->SetSuccessorAt(1, if_false); | 4097 elements_kind_branch->SetSuccessorAt(1, if_false); |
| 4086 current_block()->Finish(elements_kind_branch); | 4098 current_block()->Finish(elements_kind_branch); |
| 4087 | 4099 |
| 4088 set_current_block(if_true); | 4100 set_current_block(if_true); |
| 4089 HInstruction* access; | 4101 HInstruction* access; |
| 4090 if (elements_kind == FAST_ELEMENTS || | 4102 if (elements_kind == FAST_SMI_ONLY_ELEMENTS || |
| 4103 elements_kind == FAST_ELEMENTS || |
| 4091 elements_kind == FAST_DOUBLE_ELEMENTS) { | 4104 elements_kind == FAST_DOUBLE_ELEMENTS) { |
| 4092 bool fast_double_elements = | 4105 bool fast_double_elements = |
| 4093 elements_kind == FAST_DOUBLE_ELEMENTS; | 4106 elements_kind == FAST_DOUBLE_ELEMENTS; |
| 4094 if (is_store && elements_kind == FAST_ELEMENTS) { | 4107 if (is_store && !fast_double_elements) { |
| 4095 AddInstruction(new(zone()) HCheckMap( | 4108 AddInstruction(new(zone()) HCheckMap( |
| 4096 elements, isolate()->factory()->fixed_array_map(), | 4109 elements, isolate()->factory()->fixed_array_map(), |
| 4097 elements_kind_branch)); | 4110 elements_kind_branch)); |
| 4098 } | 4111 } |
| 4099 HBasicBlock* if_jsarray = graph()->CreateBasicBlock(); | 4112 HBasicBlock* if_jsarray = graph()->CreateBasicBlock(); |
| 4100 HBasicBlock* if_fastobject = graph()->CreateBasicBlock(); | 4113 HBasicBlock* if_fastobject = graph()->CreateBasicBlock(); |
| 4101 HHasInstanceTypeAndBranch* typecheck = | 4114 HHasInstanceTypeAndBranch* typecheck = |
| 4102 new(zone()) HHasInstanceTypeAndBranch(object, JS_ARRAY_TYPE); | 4115 new(zone()) HHasInstanceTypeAndBranch(object, JS_ARRAY_TYPE); |
| 4103 typecheck->SetSuccessorAt(0, if_jsarray); | 4116 typecheck->SetSuccessorAt(0, if_jsarray); |
| 4104 typecheck->SetSuccessorAt(1, if_fastobject); | 4117 typecheck->SetSuccessorAt(1, if_fastobject); |
| 4105 current_block()->Finish(typecheck); | 4118 current_block()->Finish(typecheck); |
| 4106 | 4119 |
| 4107 set_current_block(if_jsarray); | 4120 set_current_block(if_jsarray); |
| 4108 HInstruction* length = new(zone()) HJSArrayLength(object, typecheck); | 4121 HInstruction* length; |
| 4109 AddInstruction(length); | 4122 if (is_store && elements_kind == FAST_SMI_ONLY_ELEMENTS) { |
| 4110 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); | 4123 // For now, fall back to the generic stub for |
| 4111 if (is_store) { | 4124 // FAST_SMI_ONLY_ELEMENTS |
| 4112 if (fast_double_elements) { | 4125 access = AddInstruction(BuildStoreKeyedGeneric(object, key, val)); |
| 4113 access = AddInstruction( | 4126 } else { |
| 4114 new(zone()) HStoreKeyedFastDoubleElement(elements, | 4127 length = new(zone()) HJSArrayLength(object, typecheck); |
| 4115 checked_key, | 4128 AddInstruction(length); |
| 4116 val)); | 4129 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); |
| 4130 if (is_store) { |
| 4131 if (fast_double_elements) { |
| 4132 access = AddInstruction( |
| 4133 new(zone()) HStoreKeyedFastDoubleElement(elements, |
| 4134 checked_key, |
| 4135 val)); |
| 4136 } else { |
| 4137 access = AddInstruction( |
| 4138 new(zone()) HStoreKeyedFastElement(elements, |
| 4139 checked_key, |
| 4140 val)); |
| 4141 } |
| 4117 } else { | 4142 } else { |
| 4118 access = AddInstruction( | 4143 if (fast_double_elements) { |
| 4119 new(zone()) HStoreKeyedFastElement(elements, checked_key, val)); | 4144 access = AddInstruction( |
| 4145 new(zone()) HLoadKeyedFastDoubleElement(elements, |
| 4146 checked_key)); |
| 4147 } else { |
| 4148 access = AddInstruction( |
| 4149 new(zone()) HLoadKeyedFastElement(elements, checked_key)); |
| 4150 } |
| 4151 Push(access); |
| 4120 } | 4152 } |
| 4121 } else { | |
| 4122 if (fast_double_elements) { | |
| 4123 access = AddInstruction( | |
| 4124 new(zone()) HLoadKeyedFastDoubleElement(elements, checked_key)); | |
| 4125 } else { | |
| 4126 access = AddInstruction( | |
| 4127 new(zone()) HLoadKeyedFastElement(elements, checked_key)); | |
| 4128 } | |
| 4129 Push(access); | |
| 4130 } | 4153 } |
| 4154 |
| 4131 *has_side_effects |= access->HasSideEffects(); | 4155 *has_side_effects |= access->HasSideEffects(); |
| 4132 if (position != -1) { | 4156 if (position != -1) { |
| 4133 access->set_position(position); | 4157 access->set_position(position); |
| 4134 } | 4158 } |
| 4135 if_jsarray->Goto(join); | 4159 if_jsarray->Goto(join); |
| 4136 | 4160 |
| 4137 set_current_block(if_fastobject); | 4161 set_current_block(if_fastobject); |
| 4138 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); | 4162 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); |
| 4139 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); | 4163 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); |
| 4140 if (is_store) { | 4164 if (is_store) { |
| (...skipping 2694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6835 } | 6859 } |
| 6836 } | 6860 } |
| 6837 | 6861 |
| 6838 #ifdef DEBUG | 6862 #ifdef DEBUG |
| 6839 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 6863 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
| 6840 if (allocator_ != NULL) allocator_->Verify(); | 6864 if (allocator_ != NULL) allocator_->Verify(); |
| 6841 #endif | 6865 #endif |
| 6842 } | 6866 } |
| 6843 | 6867 |
| 6844 } } // namespace v8::internal | 6868 } } // namespace v8::internal |
| OLD | NEW |