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 3319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 if (FLAG_smi_only_arrays) { | 3339 if (FLAG_smi_only_arrays) { |
3340 HInstruction* elements_kind = | |
3341 AddInstruction(new(zone()) HElementsKind(literal)); | |
3342 HBasicBlock* store_fast = graph()->CreateBasicBlock(); | |
danno
2011/09/23 09:05:24
Wow, cool, you went for bonus points here (I don't
Jakob Kummerow
2011/09/26 11:30:32
Done.
| |
3343 // Two empty blocks to satisfy edge split form. | |
3344 HBasicBlock* store_fast_edgesplit1 = graph()->CreateBasicBlock(); | |
3345 HBasicBlock* store_fast_edgesplit2 = graph()->CreateBasicBlock(); | |
3346 HBasicBlock* store_generic = graph()->CreateBasicBlock(); | |
3347 HBasicBlock* check_smi_only_elements = graph()->CreateBasicBlock(); | |
3348 HBasicBlock* join = graph()->CreateBasicBlock(); | |
3349 | |
3350 HIsSmiAndBranch* smicheck = new(zone()) HIsSmiAndBranch(value); | |
3351 smicheck->SetSuccessorAt(0, store_fast_edgesplit1); | |
3352 smicheck->SetSuccessorAt(1, check_smi_only_elements); | |
3353 current_block()->Finish(smicheck); | |
3354 store_fast_edgesplit1->Finish(new(zone()) HGoto(store_fast)); | |
3355 | |
3356 set_current_block(check_smi_only_elements); | |
3357 HCompareConstantEqAndBranch* smi_elements_check = | |
3358 new(zone()) HCompareConstantEqAndBranch(elements_kind, | |
3359 FAST_SMI_ONLY_ELEMENTS, | |
3360 Token::EQ_STRICT); | |
3361 smi_elements_check->SetSuccessorAt(0, store_generic); | |
3362 smi_elements_check->SetSuccessorAt(1, store_fast_edgesplit2); | |
3363 current_block()->Finish(smi_elements_check); | |
3364 store_fast_edgesplit2->Finish(new(zone()) HGoto(store_fast)); | |
3365 | |
3366 set_current_block(store_fast); | |
3367 AddInstruction(new(zone()) HStoreKeyedFastElement(elements, key, value)); | |
3368 store_fast->Goto(join); | |
3369 | |
3370 set_current_block(store_generic); | |
3340 AddInstruction(BuildStoreKeyedGeneric(literal, key, value)); | 3371 AddInstruction(BuildStoreKeyedGeneric(literal, key, value)); |
3372 store_generic->Goto(join); | |
3373 | |
3374 join->SetJoinId(expr->id()); | |
3375 set_current_block(join); | |
3341 } else { | 3376 } else { |
3342 AddInstruction(new(zone()) HStoreKeyedFastElement(elements, key, value)); | 3377 AddInstruction(new(zone()) HStoreKeyedFastElement(elements, key, value)); |
3343 } | 3378 } |
3344 | 3379 |
3345 AddSimulate(expr->GetIdForElement(i)); | 3380 AddSimulate(expr->GetIdForElement(i)); |
3346 } | 3381 } |
3347 return ast_context()->ReturnValue(Pop()); | 3382 return ast_context()->ReturnValue(Pop()); |
3348 } | 3383 } |
3349 | 3384 |
3350 | 3385 |
(...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3962 } | 3997 } |
3963 return new(zone()) HStoreKeyedSpecializedArrayElement( | 3998 return new(zone()) HStoreKeyedSpecializedArrayElement( |
3964 external_elements, checked_key, val, elements_kind); | 3999 external_elements, checked_key, val, elements_kind); |
3965 } else { | 4000 } else { |
3966 return new(zone()) HLoadKeyedSpecializedArrayElement( | 4001 return new(zone()) HLoadKeyedSpecializedArrayElement( |
3967 external_elements, checked_key, elements_kind); | 4002 external_elements, checked_key, elements_kind); |
3968 } | 4003 } |
3969 } | 4004 } |
3970 | 4005 |
3971 | 4006 |
4007 HInstruction* HGraphBuilder::BuildFastElementAccess(HValue* elements, | |
danno
2011/09/23 09:05:24
I find it a little asymmetric that BuildFirstEleme
danno
2011/09/23 09:07:52
"not last last one" should read "the returned inst
Jakob Kummerow
2011/09/26 11:30:32
It's currently consistent with a bunch of other me
| |
4008 HValue* checked_key, | |
4009 HValue* val, | |
4010 ElementsKind elements_kind, | |
4011 bool is_store) { | |
4012 if (is_store) { | |
4013 ASSERT(val != NULL); | |
4014 if (elements_kind == FAST_DOUBLE_ELEMENTS) { | |
4015 return new(zone()) HStoreKeyedFastDoubleElement( | |
4016 elements, checked_key, val); | |
4017 } else if (elements_kind == FAST_SMI_ONLY_ELEMENTS) { | |
4018 AddInstruction(new(zone()) HCheckSmi(val)); | |
4019 return new(zone()) HStoreKeyedFastElement( | |
4020 elements, checked_key, val, HStoreKeyedFastElement::VALUE_IS_SMI); | |
4021 } else { | |
4022 return new(zone()) HStoreKeyedFastElement(elements, checked_key, val); | |
4023 } | |
4024 } else { | |
4025 if (elements_kind == FAST_DOUBLE_ELEMENTS) { | |
4026 return new(zone()) HLoadKeyedFastDoubleElement(elements, checked_key); | |
4027 } else { | |
4028 return new(zone()) HLoadKeyedFastElement(elements, checked_key); | |
danno
2011/09/23 09:05:24
If you're refactoring anyway, perhaps you might wa
Jakob Kummerow
2011/09/26 11:30:32
Done. Removed the unnecessary outer "else" and add
| |
4029 } | |
4030 } | |
4031 } | |
4032 | |
4033 | |
3972 HInstruction* HGraphBuilder::BuildMonomorphicElementAccess(HValue* object, | 4034 HInstruction* HGraphBuilder::BuildMonomorphicElementAccess(HValue* object, |
3973 HValue* key, | 4035 HValue* key, |
3974 HValue* val, | 4036 HValue* val, |
3975 Expression* expr, | 4037 Expression* expr, |
3976 bool is_store) { | 4038 bool is_store) { |
3977 ASSERT(expr->IsMonomorphic()); | 4039 ASSERT(expr->IsMonomorphic()); |
3978 Handle<Map> map = expr->GetMonomorphicReceiverType(); | 4040 Handle<Map> map = expr->GetMonomorphicReceiverType(); |
3979 AddInstruction(new(zone()) HCheckNonSmi(object)); | 4041 AddInstruction(new(zone()) HCheckNonSmi(object)); |
3980 HInstruction* mapcheck = AddInstruction(new(zone()) HCheckMap(object, map)); | 4042 HInstruction* mapcheck = AddInstruction(new(zone()) HCheckMap(object, map)); |
3981 if (!map->has_fast_elements() && | 4043 bool fast_smi_only_elements = map->has_fast_smi_only_elements(); |
3982 !map->has_fast_double_elements() && | 4044 bool fast_elements = map->has_fast_elements(); |
4045 bool fast_double_elements = map->has_fast_double_elements(); | |
4046 if (!fast_smi_only_elements && | |
4047 !fast_elements && | |
4048 !fast_double_elements && | |
3983 !map->has_external_array_elements()) { | 4049 !map->has_external_array_elements()) { |
3984 return is_store ? BuildStoreKeyedGeneric(object, key, val) | 4050 return is_store ? BuildStoreKeyedGeneric(object, key, val) |
3985 : BuildLoadKeyedGeneric(object, key); | 4051 : BuildLoadKeyedGeneric(object, key); |
3986 } | 4052 } |
3987 HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object)); | 4053 HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object)); |
3988 bool fast_double_elements = map->has_fast_double_elements(); | 4054 if (is_store && (fast_elements || fast_smi_only_elements)) { |
3989 if (is_store && map->has_fast_elements()) { | |
3990 AddInstruction(new(zone()) HCheckMap( | 4055 AddInstruction(new(zone()) HCheckMap( |
3991 elements, isolate()->factory()->fixed_array_map())); | 4056 elements, isolate()->factory()->fixed_array_map())); |
3992 } | 4057 } |
3993 HInstruction* length = NULL; | 4058 HInstruction* length = NULL; |
3994 HInstruction* checked_key = NULL; | 4059 HInstruction* checked_key = NULL; |
3995 if (map->has_external_array_elements()) { | 4060 if (map->has_external_array_elements()) { |
3996 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); | 4061 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); |
3997 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); | 4062 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); |
3998 HLoadExternalArrayPointer* external_elements = | 4063 HLoadExternalArrayPointer* external_elements = |
3999 new(zone()) HLoadExternalArrayPointer(elements); | 4064 new(zone()) HLoadExternalArrayPointer(elements); |
4000 AddInstruction(external_elements); | 4065 AddInstruction(external_elements); |
4001 return BuildExternalArrayElementAccess(external_elements, checked_key, | 4066 return BuildExternalArrayElementAccess(external_elements, checked_key, |
4002 val, map->elements_kind(), is_store); | 4067 val, map->elements_kind(), is_store); |
4003 } | 4068 } |
4004 ASSERT(map->has_fast_elements() || fast_double_elements); | 4069 ASSERT(fast_smi_only_elements || fast_elements || fast_double_elements); |
danno
2011/09/23 09:05:24
Perhaps add predicates to the map that test for mu
Jakob Kummerow
2011/09/26 11:30:32
I'd prefer not to do that, for two reasons:
(1) Th
| |
4005 if (map->instance_type() == JS_ARRAY_TYPE) { | 4070 if (map->instance_type() == JS_ARRAY_TYPE) { |
4006 length = AddInstruction(new(zone()) HJSArrayLength(object, mapcheck)); | 4071 length = AddInstruction(new(zone()) HJSArrayLength(object, mapcheck)); |
4007 } else { | 4072 } else { |
4008 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); | 4073 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); |
4009 } | 4074 } |
4010 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); | 4075 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); |
4011 if (is_store) { | 4076 return BuildFastElementAccess(elements, checked_key, val, |
4012 if (fast_double_elements) { | 4077 map->elements_kind(), is_store); |
4013 return new(zone()) HStoreKeyedFastDoubleElement(elements, | |
4014 checked_key, | |
4015 val); | |
4016 } else { | |
4017 return new(zone()) HStoreKeyedFastElement(elements, checked_key, val); | |
4018 } | |
4019 } else { | |
4020 if (fast_double_elements) { | |
4021 return new(zone()) HLoadKeyedFastDoubleElement(elements, checked_key); | |
4022 } else { | |
4023 return new(zone()) HLoadKeyedFastElement(elements, checked_key); | |
4024 } | |
4025 } | |
4026 } | 4078 } |
4027 | 4079 |
4028 | 4080 |
4029 HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object, | 4081 HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object, |
4030 HValue* key, | 4082 HValue* key, |
4031 HValue* val, | 4083 HValue* val, |
4032 Expression* prop, | 4084 Expression* prop, |
4033 int ast_id, | 4085 int ast_id, |
4034 int position, | 4086 int position, |
4035 bool is_store, | 4087 bool is_store, |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4068 // FAST_DOUBLE_ELEMENTS and DICTIONARY_ELEMENTS are handled before external | 4120 // FAST_DOUBLE_ELEMENTS and DICTIONARY_ELEMENTS are handled before external |
4069 // arrays. | 4121 // arrays. |
4070 STATIC_ASSERT(FAST_SMI_ONLY_ELEMENTS < FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); | 4122 STATIC_ASSERT(FAST_SMI_ONLY_ELEMENTS < FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); |
4071 STATIC_ASSERT(FAST_ELEMENTS < FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); | 4123 STATIC_ASSERT(FAST_ELEMENTS < FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); |
4072 STATIC_ASSERT(FAST_DOUBLE_ELEMENTS < FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); | 4124 STATIC_ASSERT(FAST_DOUBLE_ELEMENTS < FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); |
4073 STATIC_ASSERT(DICTIONARY_ELEMENTS < FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); | 4125 STATIC_ASSERT(DICTIONARY_ELEMENTS < FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); |
4074 | 4126 |
4075 for (ElementsKind elements_kind = FIRST_ELEMENTS_KIND; | 4127 for (ElementsKind elements_kind = FIRST_ELEMENTS_KIND; |
4076 elements_kind <= LAST_ELEMENTS_KIND; | 4128 elements_kind <= LAST_ELEMENTS_KIND; |
4077 elements_kind = ElementsKind(elements_kind + 1)) { | 4129 elements_kind = ElementsKind(elements_kind + 1)) { |
4078 // After having handled FAST_ELEMENTS, FAST_SMI_ELEMENTS, | 4130 // After having handled FAST_ELEMENTS, FAST_SMI_ONLY_ELEMENTS, |
4079 // FAST_DOUBLE_ELEMENTS and DICTIONARY_ELEMENTS, we need to add some code | 4131 // FAST_DOUBLE_ELEMENTS and DICTIONARY_ELEMENTS, we need to add some code |
4080 // that's executed for all external array cases. | 4132 // that's executed for all external array cases. |
4081 STATIC_ASSERT(LAST_EXTERNAL_ARRAY_ELEMENTS_KIND == | 4133 STATIC_ASSERT(LAST_EXTERNAL_ARRAY_ELEMENTS_KIND == |
4082 LAST_ELEMENTS_KIND); | 4134 LAST_ELEMENTS_KIND); |
4083 if (elements_kind == FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND | 4135 if (elements_kind == FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND |
4084 && todo_external_array) { | 4136 && todo_external_array) { |
4085 HInstruction* length = | 4137 HInstruction* length = |
4086 AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); | 4138 AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); |
4087 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); | 4139 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); |
4088 external_elements = new(zone()) HLoadExternalArrayPointer(elements); | 4140 external_elements = new(zone()) HLoadExternalArrayPointer(elements); |
4089 AddInstruction(external_elements); | 4141 AddInstruction(external_elements); |
4090 } | 4142 } |
4091 if (type_todo[elements_kind]) { | 4143 if (type_todo[elements_kind]) { |
4092 HBasicBlock* if_true = graph()->CreateBasicBlock(); | 4144 HBasicBlock* if_true = graph()->CreateBasicBlock(); |
4093 HBasicBlock* if_false = graph()->CreateBasicBlock(); | 4145 HBasicBlock* if_false = graph()->CreateBasicBlock(); |
4094 elements_kind_branch = new(zone()) HCompareConstantEqAndBranch( | 4146 elements_kind_branch = new(zone()) HCompareConstantEqAndBranch( |
4095 elements_kind_instr, elements_kind, Token::EQ_STRICT); | 4147 elements_kind_instr, elements_kind, Token::EQ_STRICT); |
4096 elements_kind_branch->SetSuccessorAt(0, if_true); | 4148 elements_kind_branch->SetSuccessorAt(0, if_true); |
4097 elements_kind_branch->SetSuccessorAt(1, if_false); | 4149 elements_kind_branch->SetSuccessorAt(1, if_false); |
4098 current_block()->Finish(elements_kind_branch); | 4150 current_block()->Finish(elements_kind_branch); |
4099 | 4151 |
4100 set_current_block(if_true); | 4152 set_current_block(if_true); |
4101 HInstruction* access; | 4153 HInstruction* access; |
4102 if (elements_kind == FAST_SMI_ONLY_ELEMENTS || | 4154 if (elements_kind == FAST_SMI_ONLY_ELEMENTS || |
4103 elements_kind == FAST_ELEMENTS || | 4155 elements_kind == FAST_ELEMENTS || |
4104 elements_kind == FAST_DOUBLE_ELEMENTS) { | 4156 elements_kind == FAST_DOUBLE_ELEMENTS) { |
4105 bool fast_double_elements = | 4157 if (is_store && elements_kind == FAST_SMI_ONLY_ELEMENTS) { |
4106 elements_kind == FAST_DOUBLE_ELEMENTS; | 4158 // When the |object| has FAST_SMI_ONLY_ELEMENTS, chances are we'll |
danno
2011/09/23 09:05:24
stype nit: passive voice instead of "we"?
Jakob Kummerow
2011/09/26 11:30:32
Done -- both comment and the code it referred to a
| |
4107 if (is_store && !fast_double_elements) { | 4159 // only ever see more Smis being stored in it, so it's fine to |
4160 // just deopt if that assumption is ever wrong. | |
4161 AddInstruction(new(zone()) HCheckSmi(val)); | |
4162 } | |
4163 if (is_store && elements_kind != FAST_DOUBLE_ELEMENTS) { | |
4108 AddInstruction(new(zone()) HCheckMap( | 4164 AddInstruction(new(zone()) HCheckMap( |
4109 elements, isolate()->factory()->fixed_array_map(), | 4165 elements, isolate()->factory()->fixed_array_map(), |
4110 elements_kind_branch)); | 4166 elements_kind_branch)); |
4111 } | 4167 } |
4168 // TODO(jkummerow): We could get around the need for these two blocks | |
danno
2011/09/23 09:05:24
stype nit: passive voice instead of "we"?
Jakob Kummerow
2011/09/26 11:30:32
Done.
| |
4169 // in one of two ways: | |
4170 // (1) Introduce ElementsKinds for JSArrays that are distinct from | |
4171 // those for fast objects. | |
4172 // (2) Put the common instructions into a third "join" block. This | |
4173 // requires additional AST IDs that we can deopt to from inside | |
4174 // that join block. They must be added to the Property class (when | |
4175 // it's a keyed property) and registered in the full codegen. | |
4112 HBasicBlock* if_jsarray = graph()->CreateBasicBlock(); | 4176 HBasicBlock* if_jsarray = graph()->CreateBasicBlock(); |
4113 HBasicBlock* if_fastobject = graph()->CreateBasicBlock(); | 4177 HBasicBlock* if_fastobject = graph()->CreateBasicBlock(); |
4114 HHasInstanceTypeAndBranch* typecheck = | 4178 HHasInstanceTypeAndBranch* typecheck = |
4115 new(zone()) HHasInstanceTypeAndBranch(object, JS_ARRAY_TYPE); | 4179 new(zone()) HHasInstanceTypeAndBranch(object, JS_ARRAY_TYPE); |
4116 typecheck->SetSuccessorAt(0, if_jsarray); | 4180 typecheck->SetSuccessorAt(0, if_jsarray); |
4117 typecheck->SetSuccessorAt(1, if_fastobject); | 4181 typecheck->SetSuccessorAt(1, if_fastobject); |
4118 current_block()->Finish(typecheck); | 4182 current_block()->Finish(typecheck); |
4119 | 4183 |
4120 set_current_block(if_jsarray); | 4184 set_current_block(if_jsarray); |
4121 HInstruction* length; | 4185 HInstruction* length; |
4122 if (is_store && elements_kind == FAST_SMI_ONLY_ELEMENTS) { | 4186 length = AddInstruction(new(zone()) HJSArrayLength(object, typecheck)); |
4123 // For now, fall back to the generic stub for | 4187 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); |
4124 // FAST_SMI_ONLY_ELEMENTS | 4188 access = AddInstruction(BuildFastElementAccess( |
4125 access = AddInstruction(BuildStoreKeyedGeneric(object, key, val)); | 4189 elements, checked_key, val, elements_kind, is_store)); |
4126 } else { | 4190 if (!is_store) { |
4127 length = new(zone()) HJSArrayLength(object, typecheck); | 4191 Push(access); |
4128 AddInstruction(length); | |
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 } | |
4142 } else { | |
4143 if (fast_double_elements) { | |
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); | |
4152 } | |
4153 } | 4192 } |
4154 | 4193 |
4155 *has_side_effects |= access->HasSideEffects(); | 4194 *has_side_effects |= access->HasSideEffects(); |
4156 if (position != -1) { | 4195 if (position != -1) { |
4157 access->set_position(position); | 4196 access->set_position(position); |
4158 } | 4197 } |
4159 if_jsarray->Goto(join); | 4198 if_jsarray->Goto(join); |
4160 | 4199 |
4161 set_current_block(if_fastobject); | 4200 set_current_block(if_fastobject); |
4162 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); | 4201 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); |
4163 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); | 4202 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length)); |
4164 if (is_store) { | 4203 access = AddInstruction(BuildFastElementAccess( |
4165 if (fast_double_elements) { | 4204 elements, checked_key, val, elements_kind, is_store)); |
4166 access = AddInstruction( | |
4167 new(zone()) HStoreKeyedFastDoubleElement(elements, | |
4168 checked_key, | |
4169 val)); | |
4170 } else { | |
4171 access = AddInstruction( | |
4172 new(zone()) HStoreKeyedFastElement(elements, checked_key, val)); | |
4173 } | |
4174 } else { | |
4175 if (fast_double_elements) { | |
4176 access = AddInstruction( | |
4177 new(zone()) HLoadKeyedFastDoubleElement(elements, checked_key)); | |
4178 } else { | |
4179 access = AddInstruction( | |
4180 new(zone()) HLoadKeyedFastElement(elements, checked_key)); | |
4181 } | |
4182 } | |
4183 } else if (elements_kind == DICTIONARY_ELEMENTS) { | 4205 } else if (elements_kind == DICTIONARY_ELEMENTS) { |
4184 if (is_store) { | 4206 if (is_store) { |
4185 access = AddInstruction(BuildStoreKeyedGeneric(object, key, val)); | 4207 access = AddInstruction(BuildStoreKeyedGeneric(object, key, val)); |
4186 } else { | 4208 } else { |
4187 access = AddInstruction(BuildLoadKeyedGeneric(object, key)); | 4209 access = AddInstruction(BuildLoadKeyedGeneric(object, key)); |
4188 } | 4210 } |
4189 } else { // External array elements. | 4211 } else { // External array elements. |
4190 access = AddInstruction(BuildExternalArrayElementAccess( | 4212 access = AddInstruction(BuildExternalArrayElementAccess( |
4191 external_elements, checked_key, val, elements_kind, is_store)); | 4213 external_elements, checked_key, val, elements_kind, is_store)); |
4192 } | 4214 } |
(...skipping 2666 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6859 } | 6881 } |
6860 } | 6882 } |
6861 | 6883 |
6862 #ifdef DEBUG | 6884 #ifdef DEBUG |
6863 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 6885 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
6864 if (allocator_ != NULL) allocator_->Verify(); | 6886 if (allocator_ != NULL) allocator_->Verify(); |
6865 #endif | 6887 #endif |
6866 } | 6888 } |
6867 | 6889 |
6868 } } // namespace v8::internal | 6890 } } // namespace v8::internal |
OLD | NEW |