OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 4756 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4767 Drop(1); // array literal index | 4767 Drop(1); // array literal index |
4768 return ast_context()->ReturnValue(Pop()); | 4768 return ast_context()->ReturnValue(Pop()); |
4769 } | 4769 } |
4770 | 4770 |
4771 | 4771 |
4772 // Sets the lookup result and returns true if the load/store can be inlined. | 4772 // Sets the lookup result and returns true if the load/store can be inlined. |
4773 static bool ComputeLoadStoreField(Handle<Map> type, | 4773 static bool ComputeLoadStoreField(Handle<Map> type, |
4774 Handle<String> name, | 4774 Handle<String> name, |
4775 LookupResult* lookup, | 4775 LookupResult* lookup, |
4776 bool is_store) { | 4776 bool is_store) { |
| 4777 ASSERT(!is_store || !type->is_observed()); |
4777 if (type->has_named_interceptor()) { | 4778 if (type->has_named_interceptor()) { |
4778 lookup->InterceptorResult(NULL); | 4779 lookup->InterceptorResult(NULL); |
4779 return false; | 4780 return false; |
4780 } | 4781 } |
4781 // If we directly find a field, the access can be inlined. | 4782 // If we directly find a field, the access can be inlined. |
4782 type->LookupDescriptor(NULL, *name, lookup); | 4783 type->LookupDescriptor(NULL, *name, lookup); |
4783 if (lookup->IsField()) return true; | 4784 if (lookup->IsField()) return true; |
4784 | 4785 |
4785 // For a load, we are out of luck if there is no such field. | 4786 // For a load, we are out of luck if there is no such field. |
4786 if (!is_store) return false; | 4787 if (!is_store) return false; |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5037 | 5038 |
5038 instr->set_position(expr->position()); | 5039 instr->set_position(expr->position()); |
5039 return ast_context()->ReturnInstruction(instr, expr->id()); | 5040 return ast_context()->ReturnInstruction(instr, expr->id()); |
5040 } | 5041 } |
5041 | 5042 |
5042 | 5043 |
5043 bool HOptimizedGraphBuilder::TryStorePolymorphicAsMonomorphic( | 5044 bool HOptimizedGraphBuilder::TryStorePolymorphicAsMonomorphic( |
5044 int position, | 5045 int position, |
5045 BailoutId assignment_id, | 5046 BailoutId assignment_id, |
5046 HValue* object, | 5047 HValue* object, |
5047 HValue* value, | 5048 HValue* store_value, |
| 5049 HValue* result_value, |
5048 SmallMapList* types, | 5050 SmallMapList* types, |
5049 Handle<String> name) { | 5051 Handle<String> name) { |
5050 // Use monomorphic store if property lookup results in the same field index | 5052 // Use monomorphic store if property lookup results in the same field index |
5051 // for all maps. Requires special map check on the set of all handled maps. | 5053 // for all maps. Requires special map check on the set of all handled maps. |
5052 if (types->length() > kMaxStorePolymorphism) return false; | 5054 if (types->length() > kMaxStorePolymorphism) return false; |
5053 | 5055 |
5054 // TODO(verwaest): Merge the checking logic with the code in | 5056 // TODO(verwaest): Merge the checking logic with the code in |
5055 // TryLoadPolymorphicAsMonomorphic. | 5057 // TryLoadPolymorphicAsMonomorphic. |
5056 LookupResult lookup(isolate()); | 5058 LookupResult lookup(isolate()); |
5057 int count; | 5059 int count; |
5058 Representation representation = Representation::None(); | 5060 Representation representation = Representation::None(); |
5059 HObjectAccess access = HObjectAccess::ForMap(); // initial value unused. | 5061 HObjectAccess access = HObjectAccess::ForMap(); // initial value unused. |
5060 for (count = 0; count < types->length(); ++count) { | 5062 for (count = 0; count < types->length(); ++count) { |
5061 Handle<Map> map = types->at(count); | 5063 Handle<Map> map = types->at(count); |
5062 // Pass false to ignore transitions. | 5064 // Pass false to ignore transitions. |
5063 if (!ComputeLoadStoreField(map, name, &lookup, false)) break; | 5065 if (!ComputeLoadStoreField(map, name, &lookup, false)) break; |
| 5066 ASSERT(!map->is_observed()); |
5064 | 5067 |
5065 HObjectAccess new_access = HObjectAccess::ForField(map, &lookup, name); | 5068 HObjectAccess new_access = HObjectAccess::ForField(map, &lookup, name); |
5066 Representation new_representation = | 5069 Representation new_representation = |
5067 ComputeLoadStoreRepresentation(map, &lookup); | 5070 ComputeLoadStoreRepresentation(map, &lookup); |
5068 | 5071 |
5069 if (count == 0) { | 5072 if (count == 0) { |
5070 // First time through the loop; set access and representation. | 5073 // First time through the loop; set access and representation. |
5071 access = new_access; | 5074 access = new_access; |
5072 representation = new_representation; | 5075 representation = new_representation; |
5073 } else if (!representation.IsCompatibleForStore(new_representation)) { | 5076 } else if (!representation.IsCompatibleForStore(new_representation)) { |
5074 // Representations did not match. | 5077 // Representations did not match. |
5075 break; | 5078 break; |
5076 } else if (access.offset() != new_access.offset()) { | 5079 } else if (access.offset() != new_access.offset()) { |
5077 // Offsets did not match. | 5080 // Offsets did not match. |
5078 break; | 5081 break; |
5079 } else if (access.IsInobject() != new_access.IsInobject()) { | 5082 } else if (access.IsInobject() != new_access.IsInobject()) { |
5080 // In-objectness did not match. | 5083 // In-objectness did not match. |
5081 break; | 5084 break; |
5082 } | 5085 } |
5083 } | 5086 } |
5084 | 5087 |
5085 if (count != types->length()) return false; | 5088 if (count != types->length()) return false; |
5086 | 5089 |
5087 // Everything matched; can use monomorphic store. | 5090 // Everything matched; can use monomorphic store. |
5088 BuildCheckHeapObject(object); | 5091 BuildCheckHeapObject(object); |
5089 AddInstruction(HCheckMaps::New(object, types, zone())); | 5092 AddInstruction(HCheckMaps::New(object, types, zone())); |
5090 HInstruction* store; | 5093 HInstruction* store; |
5091 CHECK_ALIVE_OR_RETURN( | 5094 CHECK_ALIVE_OR_RETURN( |
5092 store = BuildStoreNamedField( | 5095 store = BuildStoreNamedField( |
5093 object, name, value, types->at(count - 1), &lookup), | 5096 object, name, store_value, types->at(count - 1), &lookup), |
5094 true); | 5097 true); |
5095 Push(value); | 5098 if (result_value != NULL) Push(result_value); |
| 5099 Push(store_value); |
5096 store->set_position(position); | 5100 store->set_position(position); |
5097 AddInstruction(store); | 5101 AddInstruction(store); |
5098 AddSimulate(assignment_id); | 5102 AddSimulate(assignment_id); |
| 5103 if (result_value != NULL) Drop(1); |
5099 ast_context()->ReturnValue(Pop()); | 5104 ast_context()->ReturnValue(Pop()); |
5100 return true; | 5105 return true; |
5101 } | 5106 } |
5102 | 5107 |
5103 | 5108 |
5104 void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField( | 5109 void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField( |
5105 BailoutId id, | 5110 BailoutId id, |
5106 int position, | 5111 int position, |
5107 BailoutId assignment_id, | 5112 BailoutId assignment_id, |
5108 HValue* object, | 5113 HValue* object, |
5109 HValue* value, | 5114 HValue* store_value, |
| 5115 HValue* result_value, |
5110 SmallMapList* types, | 5116 SmallMapList* types, |
5111 Handle<String> name) { | 5117 Handle<String> name) { |
5112 if (TryStorePolymorphicAsMonomorphic( | 5118 if (TryStorePolymorphicAsMonomorphic( |
5113 position, assignment_id, object, value, types, name)) { | 5119 position, assignment_id, object, |
| 5120 store_value, result_value, types, name)) { |
5114 return; | 5121 return; |
5115 } | 5122 } |
5116 | 5123 |
5117 // TODO(ager): We should recognize when the prototype chains for different | 5124 // TODO(ager): We should recognize when the prototype chains for different |
5118 // maps are identical. In that case we can avoid repeatedly generating the | 5125 // maps are identical. In that case we can avoid repeatedly generating the |
5119 // same prototype map checks. | 5126 // same prototype map checks. |
5120 int count = 0; | 5127 int count = 0; |
5121 HBasicBlock* join = NULL; | 5128 HBasicBlock* join = NULL; |
5122 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) { | 5129 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) { |
5123 Handle<Map> map = types->at(i); | 5130 Handle<Map> map = types->at(i); |
5124 LookupResult lookup(isolate()); | 5131 LookupResult lookup(isolate()); |
5125 if (ComputeLoadStoreField(map, name, &lookup, true)) { | 5132 if (ComputeLoadStoreField(map, name, &lookup, true)) { |
5126 if (count == 0) { | 5133 if (count == 0) { |
5127 BuildCheckHeapObject(object); | 5134 BuildCheckHeapObject(object); |
5128 join = graph()->CreateBasicBlock(); | 5135 join = graph()->CreateBasicBlock(); |
5129 } | 5136 } |
5130 ++count; | 5137 ++count; |
5131 HBasicBlock* if_true = graph()->CreateBasicBlock(); | 5138 HBasicBlock* if_true = graph()->CreateBasicBlock(); |
5132 HBasicBlock* if_false = graph()->CreateBasicBlock(); | 5139 HBasicBlock* if_false = graph()->CreateBasicBlock(); |
5133 HCompareMap* compare = | 5140 HCompareMap* compare = |
5134 new(zone()) HCompareMap(object, map, if_true, if_false); | 5141 new(zone()) HCompareMap(object, map, if_true, if_false); |
5135 current_block()->Finish(compare); | 5142 current_block()->Finish(compare); |
5136 | 5143 |
5137 set_current_block(if_true); | 5144 set_current_block(if_true); |
5138 HInstruction* instr; | 5145 HInstruction* instr; |
5139 CHECK_ALIVE( | 5146 CHECK_ALIVE(instr = BuildStoreNamedField( |
5140 instr = BuildStoreNamedField(object, name, value, map, &lookup)); | 5147 object, name, store_value, map, &lookup)); |
5141 instr->set_position(position); | 5148 instr->set_position(position); |
5142 // Goto will add the HSimulate for the store. | 5149 // Goto will add the HSimulate for the store. |
5143 AddInstruction(instr); | 5150 AddInstruction(instr); |
5144 if (!ast_context()->IsEffect()) Push(value); | 5151 if (!ast_context()->IsEffect()) { |
| 5152 if (result_value != NULL) Push(result_value); |
| 5153 Push(store_value); |
| 5154 } |
5145 current_block()->Goto(join); | 5155 current_block()->Goto(join); |
5146 | 5156 |
5147 set_current_block(if_false); | 5157 set_current_block(if_false); |
5148 } | 5158 } |
5149 } | 5159 } |
5150 | 5160 |
5151 // Finish up. Unconditionally deoptimize if we've handled all the maps we | 5161 // Finish up. Unconditionally deoptimize if we've handled all the maps we |
5152 // know about and do not want to handle ones we've never seen. Otherwise | 5162 // know about and do not want to handle ones we've never seen. Otherwise |
5153 // use a generic IC. | 5163 // use a generic IC. |
5154 if (count == types->length() && FLAG_deoptimize_uncommon_cases) { | 5164 if (count == types->length() && FLAG_deoptimize_uncommon_cases) { |
5155 current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses); | 5165 current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses); |
5156 } else { | 5166 } else { |
5157 HInstruction* instr = BuildStoreNamedGeneric(object, name, value); | 5167 HInstruction* instr = BuildStoreNamedGeneric(object, name, store_value); |
5158 instr->set_position(position); | 5168 instr->set_position(position); |
5159 AddInstruction(instr); | 5169 AddInstruction(instr); |
5160 | 5170 |
5161 if (join != NULL) { | 5171 if (join != NULL) { |
5162 if (!ast_context()->IsEffect()) Push(value); | 5172 if (!ast_context()->IsEffect()) { |
| 5173 if (result_value != NULL) Push(result_value); |
| 5174 Push(store_value); |
| 5175 } |
5163 current_block()->Goto(join); | 5176 current_block()->Goto(join); |
5164 } else { | 5177 } else { |
5165 // The HSimulate for the store should not see the stored value in | 5178 // The HSimulate for the store should not see the stored value in |
5166 // effect contexts (it is not materialized at expr->id() in the | 5179 // effect contexts (it is not materialized at expr->id() in the |
5167 // unoptimized code). | 5180 // unoptimized code). |
5168 if (instr->HasObservableSideEffects()) { | 5181 if (instr->HasObservableSideEffects()) { |
5169 if (ast_context()->IsEffect()) { | 5182 if (ast_context()->IsEffect()) { |
5170 AddSimulate(id, REMOVABLE_SIMULATE); | 5183 AddSimulate(id, REMOVABLE_SIMULATE); |
5171 } else { | 5184 } else { |
5172 Push(value); | 5185 if (result_value != NULL) Push(result_value); |
| 5186 Push(store_value); |
5173 AddSimulate(id, REMOVABLE_SIMULATE); | 5187 AddSimulate(id, REMOVABLE_SIMULATE); |
5174 Drop(1); | 5188 Drop(result_value != NULL ? 2 : 1); |
5175 } | 5189 } |
5176 } | 5190 } |
5177 return ast_context()->ReturnValue(value); | 5191 return ast_context()->ReturnValue( |
| 5192 result_value != NULL ? result_value : store_value); |
5178 } | 5193 } |
5179 } | 5194 } |
5180 | 5195 |
5181 ASSERT(join != NULL); | 5196 ASSERT(join != NULL); |
5182 join->SetJoinId(id); | 5197 join->SetJoinId(id); |
5183 set_current_block(join); | 5198 set_current_block(join); |
5184 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); | 5199 if (!ast_context()->IsEffect()) { |
| 5200 if (result_value != NULL) Drop(1); |
| 5201 ast_context()->ReturnValue(Pop()); |
| 5202 } |
5185 } | 5203 } |
5186 | 5204 |
5187 | 5205 |
5188 void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) { | 5206 void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) { |
5189 Property* prop = expr->target()->AsProperty(); | 5207 Property* prop = expr->target()->AsProperty(); |
5190 ASSERT(prop != NULL); | 5208 ASSERT(prop != NULL); |
5191 CHECK_ALIVE(VisitForValue(prop->obj())); | 5209 CHECK_ALIVE(VisitForValue(prop->obj())); |
5192 | 5210 |
5193 if (prop->key()->IsPropertyName()) { | 5211 if (prop->key()->IsPropertyName()) { |
5194 // Named store. | 5212 // Named store. |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5263 } | 5281 } |
5264 } | 5282 } |
5265 | 5283 |
5266 | 5284 |
5267 void HOptimizedGraphBuilder::BuildStoreNamed(Expression* expr, | 5285 void HOptimizedGraphBuilder::BuildStoreNamed(Expression* expr, |
5268 BailoutId id, | 5286 BailoutId id, |
5269 int position, | 5287 int position, |
5270 BailoutId assignment_id, | 5288 BailoutId assignment_id, |
5271 Property* prop, | 5289 Property* prop, |
5272 HValue* object, | 5290 HValue* object, |
5273 HValue* value) { | 5291 HValue* store_value, |
| 5292 HValue* result_value) { |
5274 Literal* key = prop->key()->AsLiteral(); | 5293 Literal* key = prop->key()->AsLiteral(); |
5275 Handle<String> name = Handle<String>::cast(key->value()); | 5294 Handle<String> name = Handle<String>::cast(key->value()); |
5276 ASSERT(!name.is_null()); | 5295 ASSERT(!name.is_null()); |
5277 | 5296 |
5278 HInstruction* instr = NULL; | 5297 HInstruction* instr = NULL; |
5279 SmallMapList* types = expr->GetReceiverTypes(); | 5298 SmallMapList* types = expr->GetReceiverTypes(); |
5280 bool monomorphic = expr->IsMonomorphic(); | 5299 bool monomorphic = expr->IsMonomorphic(); |
5281 Handle<Map> map; | 5300 Handle<Map> map; |
5282 if (monomorphic) { | 5301 if (monomorphic) { |
5283 map = types->first(); | 5302 map = types->first(); |
5284 if (map->is_dictionary_map()) monomorphic = false; | 5303 if (map->is_dictionary_map()) monomorphic = false; |
5285 } | 5304 } |
5286 if (monomorphic) { | 5305 if (monomorphic) { |
5287 Handle<JSFunction> setter; | 5306 Handle<JSFunction> setter; |
5288 Handle<JSObject> holder; | 5307 Handle<JSObject> holder; |
5289 if (LookupSetter(map, name, &setter, &holder)) { | 5308 if (LookupSetter(map, name, &setter, &holder)) { |
5290 AddCheckConstantFunction(holder, object, map); | 5309 AddCheckConstantFunction(holder, object, map); |
5291 if (FLAG_inline_accessors && | 5310 // Don't try to inline if the result_value is different from the |
5292 TryInlineSetter(setter, id, assignment_id, value)) { | 5311 // store_value. That case isn't handled yet by the inlining. |
| 5312 if (result_value == NULL && |
| 5313 FLAG_inline_accessors && |
| 5314 TryInlineSetter(setter, id, assignment_id, store_value)) { |
5293 return; | 5315 return; |
5294 } | 5316 } |
5295 Drop(2); | 5317 Drop(2); |
5296 Add<HPushArgument>(object); | 5318 Add<HPushArgument>(object); |
5297 Add<HPushArgument>(value); | 5319 Add<HPushArgument>(store_value); |
5298 instr = new(zone()) HCallConstantFunction(setter, 2); | 5320 instr = new(zone()) HCallConstantFunction(setter, 2); |
5299 } else { | 5321 } else { |
5300 Drop(2); | 5322 Drop(2); |
5301 CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object, | 5323 CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object, |
5302 name, | 5324 name, |
5303 value, | 5325 store_value, |
5304 map)); | 5326 map)); |
5305 } | 5327 } |
5306 | |
5307 } else if (types != NULL && types->length() > 1) { | 5328 } else if (types != NULL && types->length() > 1) { |
5308 Drop(2); | 5329 Drop(2); |
5309 return HandlePolymorphicStoreNamedField( | 5330 return HandlePolymorphicStoreNamedField( |
5310 id, position, assignment_id, object, value, types, name); | 5331 id, position, assignment_id, object, |
| 5332 store_value, result_value, types, name); |
5311 } else { | 5333 } else { |
5312 Drop(2); | 5334 Drop(2); |
5313 instr = BuildStoreNamedGeneric(object, name, value); | 5335 instr = BuildStoreNamedGeneric(object, name, store_value); |
5314 } | 5336 } |
5315 | 5337 |
5316 Push(value); | 5338 if (result_value != NULL) Push(result_value); |
| 5339 Push(store_value); |
5317 instr->set_position(position); | 5340 instr->set_position(position); |
5318 AddInstruction(instr); | 5341 AddInstruction(instr); |
5319 if (instr->HasObservableSideEffects()) { | 5342 if (instr->HasObservableSideEffects()) { |
5320 AddSimulate(assignment_id, REMOVABLE_SIMULATE); | 5343 AddSimulate(assignment_id, REMOVABLE_SIMULATE); |
5321 } | 5344 } |
| 5345 if (result_value != NULL) Drop(1); |
5322 return ast_context()->ReturnValue(Pop()); | 5346 return ast_context()->ReturnValue(Pop()); |
5323 } | 5347 } |
5324 | 5348 |
5325 | 5349 |
5326 void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) { | 5350 void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) { |
5327 Expression* target = expr->target(); | 5351 Expression* target = expr->target(); |
5328 VariableProxy* proxy = target->AsVariableProxy(); | 5352 VariableProxy* proxy = target->AsVariableProxy(); |
5329 Property* prop = target->AsProperty(); | 5353 Property* prop = target->AsProperty(); |
5330 ASSERT(proxy == NULL || prop == NULL); | 5354 ASSERT(proxy == NULL || prop == NULL); |
5331 | 5355 |
(...skipping 2544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7876 } else if (types != NULL && types->length() > 1) { | 7900 } else if (types != NULL && types->length() > 1) { |
7877 load = TryLoadPolymorphicAsMonomorphic(prop, object, types, name); | 7901 load = TryLoadPolymorphicAsMonomorphic(prop, object, types, name); |
7878 } | 7902 } |
7879 if (load == NULL) load = BuildLoadNamedGeneric(object, name, prop); | 7903 if (load == NULL) load = BuildLoadNamedGeneric(object, name, prop); |
7880 PushAndAdd(load); | 7904 PushAndAdd(load); |
7881 if (load->HasObservableSideEffects()) { | 7905 if (load->HasObservableSideEffects()) { |
7882 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); | 7906 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); |
7883 } | 7907 } |
7884 | 7908 |
7885 after = BuildIncrement(returns_original_input, expr); | 7909 after = BuildIncrement(returns_original_input, expr); |
7886 input = Pop(); | |
7887 | 7910 |
7888 HInstruction* store; | 7911 HValue* result = returns_original_input ? Pop() : NULL; |
7889 if (!monomorphic || map->is_observed()) { | |
7890 // If we don't know the monomorphic type, do a generic store. | |
7891 CHECK_ALIVE(store = BuildStoreNamedGeneric(object, name, after)); | |
7892 } else { | |
7893 Handle<JSFunction> setter; | |
7894 Handle<JSObject> holder; | |
7895 if (LookupSetter(map, name, &setter, &holder)) { | |
7896 store = BuildCallSetter(object, after, map, setter, holder); | |
7897 } else { | |
7898 CHECK_ALIVE(store = BuildStoreNamedMonomorphic(object, | |
7899 name, | |
7900 after, | |
7901 map)); | |
7902 } | |
7903 } | |
7904 AddInstruction(store); | |
7905 | 7912 |
7906 // Overwrite the receiver in the bailout environment with the result | 7913 return BuildStoreNamed(prop, expr->id(), expr->position(), |
7907 // of the operation, and the placeholder with the original value if | 7914 expr->AssignmentId(), prop, object, after, result); |
7908 // necessary. | |
7909 environment()->SetExpressionStackAt(0, after); | |
7910 if (returns_original_input) environment()->SetExpressionStackAt(1, input); | |
7911 if (store->HasObservableSideEffects()) { | |
7912 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE); | |
7913 } | |
7914 | |
7915 } else { | 7915 } else { |
7916 // Keyed property. | 7916 // Keyed property. |
7917 if (returns_original_input) Push(graph()->GetConstantUndefined()); | 7917 if (returns_original_input) Push(graph()->GetConstantUndefined()); |
7918 | 7918 |
7919 CHECK_ALIVE(VisitForValue(prop->obj())); | 7919 CHECK_ALIVE(VisitForValue(prop->obj())); |
7920 CHECK_ALIVE(VisitForValue(prop->key())); | 7920 CHECK_ALIVE(VisitForValue(prop->key())); |
7921 HValue* obj = environment()->ExpressionStackAt(1); | 7921 HValue* obj = environment()->ExpressionStackAt(1); |
7922 HValue* key = environment()->ExpressionStackAt(0); | 7922 HValue* key = environment()->ExpressionStackAt(0); |
7923 | 7923 |
7924 bool has_side_effects = false; | 7924 bool has_side_effects = false; |
(...skipping 2251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10176 if (ShouldProduceTraceOutput()) { | 10176 if (ShouldProduceTraceOutput()) { |
10177 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 10177 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
10178 } | 10178 } |
10179 | 10179 |
10180 #ifdef DEBUG | 10180 #ifdef DEBUG |
10181 graph_->Verify(false); // No full verify. | 10181 graph_->Verify(false); // No full verify. |
10182 #endif | 10182 #endif |
10183 } | 10183 } |
10184 | 10184 |
10185 } } // namespace v8::internal | 10185 } } // namespace v8::internal |
OLD | NEW |