Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(294)

Side by Side Diff: src/hydrogen.cc

Issue 18537006: Revert "Unify the Count Operation assignment with other assignments." (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 5026 matching lines...) Expand 10 before | Expand all | Expand 10 after
5037 5037
5038 instr->set_position(expr->position()); 5038 instr->set_position(expr->position());
5039 return ast_context()->ReturnInstruction(instr, expr->id()); 5039 return ast_context()->ReturnInstruction(instr, expr->id());
5040 } 5040 }
5041 5041
5042 5042
5043 bool HOptimizedGraphBuilder::TryStorePolymorphicAsMonomorphic( 5043 bool HOptimizedGraphBuilder::TryStorePolymorphicAsMonomorphic(
5044 int position, 5044 int position,
5045 BailoutId assignment_id, 5045 BailoutId assignment_id,
5046 HValue* object, 5046 HValue* object,
5047 HValue* store_value, 5047 HValue* value,
5048 HValue* result_value,
5049 SmallMapList* types, 5048 SmallMapList* types,
5050 Handle<String> name) { 5049 Handle<String> name) {
5051 // Use monomorphic store if property lookup results in the same field index 5050 // Use monomorphic store if property lookup results in the same field index
5052 // for all maps. Requires special map check on the set of all handled maps. 5051 // for all maps. Requires special map check on the set of all handled maps.
5053 if (types->length() > kMaxStorePolymorphism) return false; 5052 if (types->length() > kMaxStorePolymorphism) return false;
5054 5053
5055 // TODO(verwaest): Merge the checking logic with the code in 5054 // TODO(verwaest): Merge the checking logic with the code in
5056 // TryLoadPolymorphicAsMonomorphic. 5055 // TryLoadPolymorphicAsMonomorphic.
5057 LookupResult lookup(isolate()); 5056 LookupResult lookup(isolate());
5058 int count; 5057 int count;
(...skipping 25 matching lines...) Expand all
5084 } 5083 }
5085 5084
5086 if (count != types->length()) return false; 5085 if (count != types->length()) return false;
5087 5086
5088 // Everything matched; can use monomorphic store. 5087 // Everything matched; can use monomorphic store.
5089 BuildCheckHeapObject(object); 5088 BuildCheckHeapObject(object);
5090 AddInstruction(HCheckMaps::New(object, types, zone())); 5089 AddInstruction(HCheckMaps::New(object, types, zone()));
5091 HInstruction* store; 5090 HInstruction* store;
5092 CHECK_ALIVE_OR_RETURN( 5091 CHECK_ALIVE_OR_RETURN(
5093 store = BuildStoreNamedField( 5092 store = BuildStoreNamedField(
5094 object, name, store_value, types->at(count - 1), &lookup), 5093 object, name, value, types->at(count - 1), &lookup),
5095 true); 5094 true);
5096 if (result_value != NULL) Push(result_value); 5095 Push(value);
5097 Push(store_value);
5098 store->set_position(position); 5096 store->set_position(position);
5099 AddInstruction(store); 5097 AddInstruction(store);
5100 AddSimulate(assignment_id); 5098 AddSimulate(assignment_id);
5101 if (result_value != NULL) Drop(1);
5102 ast_context()->ReturnValue(Pop()); 5099 ast_context()->ReturnValue(Pop());
5103 return true; 5100 return true;
5104 } 5101 }
5105 5102
5106 5103
5107 void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField( 5104 void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField(
5108 BailoutId id, 5105 BailoutId id,
5109 int position, 5106 int position,
5110 BailoutId assignment_id, 5107 BailoutId assignment_id,
5111 HValue* object, 5108 HValue* object,
5112 HValue* store_value, 5109 HValue* value,
5113 HValue* result_value,
5114 SmallMapList* types, 5110 SmallMapList* types,
5115 Handle<String> name) { 5111 Handle<String> name) {
5116 if (TryStorePolymorphicAsMonomorphic( 5112 if (TryStorePolymorphicAsMonomorphic(
5117 position, assignment_id, object, 5113 position, assignment_id, object, value, types, name)) {
5118 store_value, result_value, types, name)) {
5119 return; 5114 return;
5120 } 5115 }
5121 5116
5122 // TODO(ager): We should recognize when the prototype chains for different 5117 // TODO(ager): We should recognize when the prototype chains for different
5123 // maps are identical. In that case we can avoid repeatedly generating the 5118 // maps are identical. In that case we can avoid repeatedly generating the
5124 // same prototype map checks. 5119 // same prototype map checks.
5125 int count = 0; 5120 int count = 0;
5126 HBasicBlock* join = NULL; 5121 HBasicBlock* join = NULL;
5127 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) { 5122 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) {
5128 Handle<Map> map = types->at(i); 5123 Handle<Map> map = types->at(i);
5129 LookupResult lookup(isolate()); 5124 LookupResult lookup(isolate());
5130 if (ComputeLoadStoreField(map, name, &lookup, true)) { 5125 if (ComputeLoadStoreField(map, name, &lookup, true)) {
5131 if (count == 0) { 5126 if (count == 0) {
5132 BuildCheckHeapObject(object); 5127 BuildCheckHeapObject(object);
5133 join = graph()->CreateBasicBlock(); 5128 join = graph()->CreateBasicBlock();
5134 } 5129 }
5135 ++count; 5130 ++count;
5136 HBasicBlock* if_true = graph()->CreateBasicBlock(); 5131 HBasicBlock* if_true = graph()->CreateBasicBlock();
5137 HBasicBlock* if_false = graph()->CreateBasicBlock(); 5132 HBasicBlock* if_false = graph()->CreateBasicBlock();
5138 HCompareMap* compare = 5133 HCompareMap* compare =
5139 new(zone()) HCompareMap(object, map, if_true, if_false); 5134 new(zone()) HCompareMap(object, map, if_true, if_false);
5140 current_block()->Finish(compare); 5135 current_block()->Finish(compare);
5141 5136
5142 set_current_block(if_true); 5137 set_current_block(if_true);
5143 HInstruction* instr; 5138 HInstruction* instr;
5144 CHECK_ALIVE(instr = BuildStoreNamedField( 5139 CHECK_ALIVE(
5145 object, name, store_value, map, &lookup)); 5140 instr = BuildStoreNamedField(object, name, value, map, &lookup));
5146 instr->set_position(position); 5141 instr->set_position(position);
5147 // Goto will add the HSimulate for the store. 5142 // Goto will add the HSimulate for the store.
5148 AddInstruction(instr); 5143 AddInstruction(instr);
5149 if (!ast_context()->IsEffect()) { 5144 if (!ast_context()->IsEffect()) Push(value);
5150 if (result_value != NULL) Push(result_value);
5151 Push(store_value);
5152 }
5153 current_block()->Goto(join); 5145 current_block()->Goto(join);
5154 5146
5155 set_current_block(if_false); 5147 set_current_block(if_false);
5156 } 5148 }
5157 } 5149 }
5158 5150
5159 // Finish up. Unconditionally deoptimize if we've handled all the maps we 5151 // Finish up. Unconditionally deoptimize if we've handled all the maps we
5160 // know about and do not want to handle ones we've never seen. Otherwise 5152 // know about and do not want to handle ones we've never seen. Otherwise
5161 // use a generic IC. 5153 // use a generic IC.
5162 if (count == types->length() && FLAG_deoptimize_uncommon_cases) { 5154 if (count == types->length() && FLAG_deoptimize_uncommon_cases) {
5163 current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses); 5155 current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses);
5164 } else { 5156 } else {
5165 HInstruction* instr = BuildStoreNamedGeneric(object, name, store_value); 5157 HInstruction* instr = BuildStoreNamedGeneric(object, name, value);
5166 instr->set_position(position); 5158 instr->set_position(position);
5167 AddInstruction(instr); 5159 AddInstruction(instr);
5168 5160
5169 if (join != NULL) { 5161 if (join != NULL) {
5170 if (!ast_context()->IsEffect()) { 5162 if (!ast_context()->IsEffect()) Push(value);
5171 if (result_value != NULL) Push(result_value);
5172 Push(store_value);
5173 }
5174 current_block()->Goto(join); 5163 current_block()->Goto(join);
5175 } else { 5164 } else {
5176 // The HSimulate for the store should not see the stored value in 5165 // The HSimulate for the store should not see the stored value in
5177 // effect contexts (it is not materialized at expr->id() in the 5166 // effect contexts (it is not materialized at expr->id() in the
5178 // unoptimized code). 5167 // unoptimized code).
5179 if (instr->HasObservableSideEffects()) { 5168 if (instr->HasObservableSideEffects()) {
5180 if (ast_context()->IsEffect()) { 5169 if (ast_context()->IsEffect()) {
5181 AddSimulate(id, REMOVABLE_SIMULATE); 5170 AddSimulate(id, REMOVABLE_SIMULATE);
5182 } else { 5171 } else {
5183 if (result_value != NULL) Push(result_value); 5172 Push(value);
5184 Push(store_value);
5185 AddSimulate(id, REMOVABLE_SIMULATE); 5173 AddSimulate(id, REMOVABLE_SIMULATE);
5186 Drop(result_value != NULL ? 2 : 1); 5174 Drop(1);
5187 } 5175 }
5188 } 5176 }
5189 return ast_context()->ReturnValue( 5177 return ast_context()->ReturnValue(value);
5190 result_value != NULL ? result_value : store_value);
5191 } 5178 }
5192 } 5179 }
5193 5180
5194 ASSERT(join != NULL); 5181 ASSERT(join != NULL);
5195 join->SetJoinId(id); 5182 join->SetJoinId(id);
5196 set_current_block(join); 5183 set_current_block(join);
5197 if (!ast_context()->IsEffect()) { 5184 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop());
5198 if (result_value != NULL) Drop(1);
5199 ast_context()->ReturnValue(Pop());
5200 }
5201 } 5185 }
5202 5186
5203 5187
5204 void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) { 5188 void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) {
5205 Property* prop = expr->target()->AsProperty(); 5189 Property* prop = expr->target()->AsProperty();
5206 ASSERT(prop != NULL); 5190 ASSERT(prop != NULL);
5207 CHECK_ALIVE(VisitForValue(prop->obj())); 5191 CHECK_ALIVE(VisitForValue(prop->obj()));
5208 5192
5209 if (prop->key()->IsPropertyName()) { 5193 if (prop->key()->IsPropertyName()) {
5210 // Named store. 5194 // Named store.
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
5279 } 5263 }
5280 } 5264 }
5281 5265
5282 5266
5283 void HOptimizedGraphBuilder::BuildStoreNamed(Expression* expr, 5267 void HOptimizedGraphBuilder::BuildStoreNamed(Expression* expr,
5284 BailoutId id, 5268 BailoutId id,
5285 int position, 5269 int position,
5286 BailoutId assignment_id, 5270 BailoutId assignment_id,
5287 Property* prop, 5271 Property* prop,
5288 HValue* object, 5272 HValue* object,
5289 HValue* store_value, 5273 HValue* value) {
5290 HValue* result_value) {
5291 Literal* key = prop->key()->AsLiteral(); 5274 Literal* key = prop->key()->AsLiteral();
5292 Handle<String> name = Handle<String>::cast(key->value()); 5275 Handle<String> name = Handle<String>::cast(key->value());
5293 ASSERT(!name.is_null()); 5276 ASSERT(!name.is_null());
5294 5277
5295 HInstruction* instr = NULL; 5278 HInstruction* instr = NULL;
5296 SmallMapList* types = expr->GetReceiverTypes(); 5279 SmallMapList* types = expr->GetReceiverTypes();
5297 bool monomorphic = expr->IsMonomorphic(); 5280 bool monomorphic = expr->IsMonomorphic();
5298 Handle<Map> map; 5281 Handle<Map> map;
5299 if (monomorphic) { 5282 if (monomorphic) {
5300 map = types->first(); 5283 map = types->first();
5301 if (map->is_dictionary_map()) monomorphic = false; 5284 if (map->is_dictionary_map()) monomorphic = false;
5302 } 5285 }
5303 if (monomorphic) { 5286 if (monomorphic) {
5304 Handle<JSFunction> setter; 5287 Handle<JSFunction> setter;
5305 Handle<JSObject> holder; 5288 Handle<JSObject> holder;
5306 if (LookupSetter(map, name, &setter, &holder)) { 5289 if (LookupSetter(map, name, &setter, &holder)) {
5307 AddCheckConstantFunction(holder, object, map); 5290 AddCheckConstantFunction(holder, object, map);
5308 // Don't try to inline if the result_value is different from the 5291 if (FLAG_inline_accessors &&
5309 // store_value. That case isn't handled yet by the inlining. 5292 TryInlineSetter(setter, id, assignment_id, value)) {
5310 if (result_value == NULL &&
5311 FLAG_inline_accessors &&
5312 TryInlineSetter(setter, id, assignment_id, store_value)) {
5313 return; 5293 return;
5314 } 5294 }
5315 Drop(2); 5295 Drop(2);
5316 Add<HPushArgument>(object); 5296 Add<HPushArgument>(object);
5317 Add<HPushArgument>(store_value); 5297 Add<HPushArgument>(value);
5318 instr = new(zone()) HCallConstantFunction(setter, 2); 5298 instr = new(zone()) HCallConstantFunction(setter, 2);
5319 } else { 5299 } else {
5320 Drop(2); 5300 Drop(2);
5321 CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object, 5301 CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object,
5322 name, 5302 name,
5323 store_value, 5303 value,
5324 map)); 5304 map));
5325 } 5305 }
5306
5326 } else if (types != NULL && types->length() > 1) { 5307 } else if (types != NULL && types->length() > 1) {
5327 Drop(2); 5308 Drop(2);
5328 return HandlePolymorphicStoreNamedField( 5309 return HandlePolymorphicStoreNamedField(
5329 id, position, assignment_id, object, 5310 id, position, assignment_id, object, value, types, name);
5330 store_value, result_value, types, name);
5331 } else { 5311 } else {
5332 Drop(2); 5312 Drop(2);
5333 instr = BuildStoreNamedGeneric(object, name, store_value); 5313 instr = BuildStoreNamedGeneric(object, name, value);
5334 } 5314 }
5335 5315
5336 if (result_value != NULL) Push(result_value); 5316 Push(value);
5337 Push(store_value);
5338 instr->set_position(position); 5317 instr->set_position(position);
5339 AddInstruction(instr); 5318 AddInstruction(instr);
5340 if (instr->HasObservableSideEffects()) { 5319 if (instr->HasObservableSideEffects()) {
5341 AddSimulate(assignment_id, REMOVABLE_SIMULATE); 5320 AddSimulate(assignment_id, REMOVABLE_SIMULATE);
5342 } 5321 }
5343 if (result_value != NULL) Drop(1);
5344 return ast_context()->ReturnValue(Pop()); 5322 return ast_context()->ReturnValue(Pop());
5345 } 5323 }
5346 5324
5347 5325
5348 void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) { 5326 void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) {
5349 Expression* target = expr->target(); 5327 Expression* target = expr->target();
5350 VariableProxy* proxy = target->AsVariableProxy(); 5328 VariableProxy* proxy = target->AsVariableProxy();
5351 Property* prop = target->AsProperty(); 5329 Property* prop = target->AsProperty();
5352 ASSERT(proxy == NULL || prop == NULL); 5330 ASSERT(proxy == NULL || prop == NULL);
5353 5331
(...skipping 2544 matching lines...) Expand 10 before | Expand all | Expand 10 after
7898 } else if (types != NULL && types->length() > 1) { 7876 } else if (types != NULL && types->length() > 1) {
7899 load = TryLoadPolymorphicAsMonomorphic(prop, object, types, name); 7877 load = TryLoadPolymorphicAsMonomorphic(prop, object, types, name);
7900 } 7878 }
7901 if (load == NULL) load = BuildLoadNamedGeneric(object, name, prop); 7879 if (load == NULL) load = BuildLoadNamedGeneric(object, name, prop);
7902 PushAndAdd(load); 7880 PushAndAdd(load);
7903 if (load->HasObservableSideEffects()) { 7881 if (load->HasObservableSideEffects()) {
7904 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); 7882 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE);
7905 } 7883 }
7906 7884
7907 after = BuildIncrement(returns_original_input, expr); 7885 after = BuildIncrement(returns_original_input, expr);
7886 input = Pop();
7908 7887
7909 HValue* result = returns_original_input ? Pop() : NULL; 7888 HInstruction* store;
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);
7910 7905
7911 return BuildStoreNamed(prop, expr->id(), expr->position(), 7906 // Overwrite the receiver in the bailout environment with the result
7912 expr->AssignmentId(), prop, object, after, result); 7907 // of the operation, and the placeholder with the original value if
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
7913 } else { 7915 } else {
7914 // Keyed property. 7916 // Keyed property.
7915 if (returns_original_input) Push(graph()->GetConstantUndefined()); 7917 if (returns_original_input) Push(graph()->GetConstantUndefined());
7916 7918
7917 CHECK_ALIVE(VisitForValue(prop->obj())); 7919 CHECK_ALIVE(VisitForValue(prop->obj()));
7918 CHECK_ALIVE(VisitForValue(prop->key())); 7920 CHECK_ALIVE(VisitForValue(prop->key()));
7919 HValue* obj = environment()->ExpressionStackAt(1); 7921 HValue* obj = environment()->ExpressionStackAt(1);
7920 HValue* key = environment()->ExpressionStackAt(0); 7922 HValue* key = environment()->ExpressionStackAt(0);
7921 7923
7922 bool has_side_effects = false; 7924 bool has_side_effects = false;
(...skipping 2251 matching lines...) Expand 10 before | Expand all | Expand 10 after
10174 if (ShouldProduceTraceOutput()) { 10176 if (ShouldProduceTraceOutput()) {
10175 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 10177 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
10176 } 10178 }
10177 10179
10178 #ifdef DEBUG 10180 #ifdef DEBUG
10179 graph_->Verify(false); // No full verify. 10181 graph_->Verify(false); // No full verify.
10180 #endif 10182 #endif
10181 } 10183 }
10182 10184
10183 } } // namespace v8::internal 10185 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698