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

Side by Side Diff: src/hydrogen.cc

Issue 17432004: Unify the Count Operation assignment with other assignments. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 6 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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 6347 matching lines...) Expand 10 before | Expand all | Expand 10 after
6358 instr->set_position(expr->position()); 6358 instr->set_position(expr->position());
6359 return ast_context()->ReturnInstruction(instr, expr->id()); 6359 return ast_context()->ReturnInstruction(instr, expr->id());
6360 } 6360 }
6361 6361
6362 6362
6363 bool HOptimizedGraphBuilder::TryStorePolymorphicAsMonomorphic( 6363 bool HOptimizedGraphBuilder::TryStorePolymorphicAsMonomorphic(
6364 int position, 6364 int position,
6365 BailoutId assignment_id, 6365 BailoutId assignment_id,
6366 HValue* object, 6366 HValue* object,
6367 HValue* value, 6367 HValue* value,
6368 HValue* result,
6368 SmallMapList* types, 6369 SmallMapList* types,
6369 Handle<String> name) { 6370 Handle<String> name) {
6370 // Use monomorphic store if property lookup results in the same field index 6371 // Use monomorphic store if property lookup results in the same field index
6371 // for all maps. Requires special map check on the set of all handled maps. 6372 // for all maps. Requires special map check on the set of all handled maps.
6372 if (types->length() > kMaxStorePolymorphism) return false; 6373 if (types->length() > kMaxStorePolymorphism) return false;
6373 6374
6374 // TODO(verwaest): Merge the checking logic with the code in 6375 // TODO(verwaest): Merge the checking logic with the code in
6375 // TryLoadPolymorphicAsMonomorphic. 6376 // TryLoadPolymorphicAsMonomorphic.
6376 LookupResult lookup(isolate()); 6377 LookupResult lookup(isolate());
6377 int count; 6378 int count;
(...skipping 27 matching lines...) Expand all
6405 if (count != types->length()) return false; 6406 if (count != types->length()) return false;
6406 6407
6407 // Everything matched; can use monomorphic store. 6408 // Everything matched; can use monomorphic store.
6408 BuildCheckNonSmi(object); 6409 BuildCheckNonSmi(object);
6409 AddInstruction(HCheckMaps::New(object, types, zone())); 6410 AddInstruction(HCheckMaps::New(object, types, zone()));
6410 HInstruction* store; 6411 HInstruction* store;
6411 CHECK_ALIVE_OR_RETURN( 6412 CHECK_ALIVE_OR_RETURN(
6412 store = BuildStoreNamedField( 6413 store = BuildStoreNamedField(
6413 object, name, value, types->at(count - 1), &lookup), 6414 object, name, value, types->at(count - 1), &lookup),
6414 true); 6415 true);
6416 if (result != value) Push(result);
Sven Panne 2013/06/24 06:58:13 This comparison (and similar ones elsewhere) are q
danno 2013/06/27 08:34:10 +1 to sven's comment. It's really difficult to und
6415 Push(value); 6417 Push(value);
6416 store->set_position(position); 6418 store->set_position(position);
6417 AddInstruction(store); 6419 AddInstruction(store);
6418 AddSimulate(assignment_id); 6420 AddSimulate(assignment_id);
6421 if (result != value) Drop(1);
6419 ast_context()->ReturnValue(Pop()); 6422 ast_context()->ReturnValue(Pop());
6420 return true; 6423 return true;
6421 } 6424 }
6422 6425
6423 6426
6424 void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField( 6427 void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField(
6425 BailoutId id, 6428 BailoutId id,
6426 int position, 6429 int position,
6427 BailoutId assignment_id, 6430 BailoutId assignment_id,
6428 HValue* object, 6431 HValue* object,
6429 HValue* value, 6432 HValue* value,
6433 HValue* result,
6430 SmallMapList* types, 6434 SmallMapList* types,
6431 Handle<String> name) { 6435 Handle<String> name) {
6432 if (TryStorePolymorphicAsMonomorphic( 6436 if (TryStorePolymorphicAsMonomorphic(
6433 position, assignment_id, object, value, types, name)) { 6437 position, assignment_id, object, value, result, types, name)) {
6434 return; 6438 return;
6435 } 6439 }
6436 6440
6437 // TODO(ager): We should recognize when the prototype chains for different 6441 // TODO(ager): We should recognize when the prototype chains for different
6438 // maps are identical. In that case we can avoid repeatedly generating the 6442 // maps are identical. In that case we can avoid repeatedly generating the
6439 // same prototype map checks. 6443 // same prototype map checks.
6440 int count = 0; 6444 int count = 0;
6441 HBasicBlock* join = NULL; 6445 HBasicBlock* join = NULL;
6442 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) { 6446 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) {
6443 Handle<Map> map = types->at(i); 6447 Handle<Map> map = types->at(i);
(...skipping 10 matching lines...) Expand all
6454 new(zone()) HCompareMap(object, map, if_true, if_false); 6458 new(zone()) HCompareMap(object, map, if_true, if_false);
6455 current_block()->Finish(compare); 6459 current_block()->Finish(compare);
6456 6460
6457 set_current_block(if_true); 6461 set_current_block(if_true);
6458 HInstruction* instr; 6462 HInstruction* instr;
6459 CHECK_ALIVE( 6463 CHECK_ALIVE(
6460 instr = BuildStoreNamedField(object, name, value, map, &lookup)); 6464 instr = BuildStoreNamedField(object, name, value, map, &lookup));
6461 instr->set_position(position); 6465 instr->set_position(position);
6462 // Goto will add the HSimulate for the store. 6466 // Goto will add the HSimulate for the store.
6463 AddInstruction(instr); 6467 AddInstruction(instr);
6464 if (!ast_context()->IsEffect()) Push(value); 6468 if (!ast_context()->IsEffect()) {
6469 if (value != result) Push(result);
6470 Push(value);
6471 }
6465 current_block()->Goto(join); 6472 current_block()->Goto(join);
6466 6473
6467 set_current_block(if_false); 6474 set_current_block(if_false);
6468 } 6475 }
6469 } 6476 }
6470 6477
6471 // Finish up. Unconditionally deoptimize if we've handled all the maps we 6478 // Finish up. Unconditionally deoptimize if we've handled all the maps we
6472 // know about and do not want to handle ones we've never seen. Otherwise 6479 // know about and do not want to handle ones we've never seen. Otherwise
6473 // use a generic IC. 6480 // use a generic IC.
6474 if (count == types->length() && FLAG_deoptimize_uncommon_cases) { 6481 if (count == types->length() && FLAG_deoptimize_uncommon_cases) {
6475 current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses); 6482 current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses);
6476 } else { 6483 } else {
6477 HInstruction* instr = BuildStoreNamedGeneric(object, name, value); 6484 HInstruction* instr = BuildStoreNamedGeneric(object, name, value);
6478 instr->set_position(position); 6485 instr->set_position(position);
6479 AddInstruction(instr); 6486 AddInstruction(instr);
6480 6487
6481 if (join != NULL) { 6488 if (join != NULL) {
6482 if (!ast_context()->IsEffect()) Push(value); 6489 if (!ast_context()->IsEffect()) {
6490 if (result != value) Push(result);
6491 Push(value);
6492 }
6483 current_block()->Goto(join); 6493 current_block()->Goto(join);
6484 } else { 6494 } else {
6485 // The HSimulate for the store should not see the stored value in 6495 // The HSimulate for the store should not see the stored value in
6486 // effect contexts (it is not materialized at expr->id() in the 6496 // effect contexts (it is not materialized at expr->id() in the
6487 // unoptimized code). 6497 // unoptimized code).
6488 if (instr->HasObservableSideEffects()) { 6498 if (instr->HasObservableSideEffects()) {
6489 if (ast_context()->IsEffect()) { 6499 if (ast_context()->IsEffect()) {
6490 AddSimulate(id, REMOVABLE_SIMULATE); 6500 AddSimulate(id, REMOVABLE_SIMULATE);
6491 } else { 6501 } else {
6502 if (result != value) Push(result);
6492 Push(value); 6503 Push(value);
6493 AddSimulate(id, REMOVABLE_SIMULATE); 6504 AddSimulate(id, REMOVABLE_SIMULATE);
6494 Drop(1); 6505 Drop(result != value ? 2 : 1);
6495 } 6506 }
6496 } 6507 }
6497 return ast_context()->ReturnValue(value); 6508 return ast_context()->ReturnValue(result);
6498 } 6509 }
6499 } 6510 }
6500 6511
6501 ASSERT(join != NULL); 6512 ASSERT(join != NULL);
6502 join->SetJoinId(id); 6513 join->SetJoinId(id);
6503 set_current_block(join); 6514 set_current_block(join);
6515 if (result != value) Drop(1);
danno 2013/07/09 16:22:04 This is a bug
6504 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); 6516 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop());
6505 } 6517 }
6506 6518
6507 6519
6508 void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) { 6520 void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) {
6509 Property* prop = expr->target()->AsProperty(); 6521 Property* prop = expr->target()->AsProperty();
6510 ASSERT(prop != NULL); 6522 ASSERT(prop != NULL);
6511 CHECK_ALIVE(VisitForValue(prop->obj())); 6523 CHECK_ALIVE(VisitForValue(prop->obj()));
6512 6524
6513 if (prop->key()->IsPropertyName()) { 6525 if (prop->key()->IsPropertyName()) {
6514 // Named store. 6526 // Named store.
6515 CHECK_ALIVE(VisitForValue(expr->value())); 6527 CHECK_ALIVE(VisitForValue(expr->value()));
6516 HValue* value = environment()->ExpressionStackAt(0); 6528 HValue* value = environment()->ExpressionStackAt(0);
6517 HValue* object = environment()->ExpressionStackAt(1); 6529 HValue* object = environment()->ExpressionStackAt(1);
6518 6530
6519 return BuildStoreNamed(expr, expr->id(), expr->position(), 6531 return BuildStoreNamed(expr, expr->id(), expr->position(),
6520 expr->AssignmentId(), prop, object, value); 6532 expr->AssignmentId(), prop, object, value, value);
6521 } else { 6533 } else {
6522 // Keyed store. 6534 // Keyed store.
6523 CHECK_ALIVE(VisitForValue(prop->key())); 6535 CHECK_ALIVE(VisitForValue(prop->key()));
6524 CHECK_ALIVE(VisitForValue(expr->value())); 6536 CHECK_ALIVE(VisitForValue(expr->value()));
6525 HValue* value = environment()->ExpressionStackAt(0); 6537 HValue* value = environment()->ExpressionStackAt(0);
6526 HValue* key = environment()->ExpressionStackAt(1); 6538 HValue* key = environment()->ExpressionStackAt(1);
6527 HValue* object = environment()->ExpressionStackAt(2); 6539 HValue* object = environment()->ExpressionStackAt(2);
6528 bool has_side_effects = false; 6540 bool has_side_effects = false;
6529 HandleKeyedElementAccess(object, key, value, expr, expr->AssignmentId(), 6541 HandleKeyedElementAccess(object, key, value, expr, expr->AssignmentId(),
6530 expr->position(), 6542 expr->position(),
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
6575 } 6587 }
6576 } 6588 }
6577 6589
6578 6590
6579 void HOptimizedGraphBuilder::BuildStoreNamed(Expression* expr, 6591 void HOptimizedGraphBuilder::BuildStoreNamed(Expression* expr,
6580 BailoutId id, 6592 BailoutId id,
6581 int position, 6593 int position,
6582 BailoutId assignment_id, 6594 BailoutId assignment_id,
6583 Property* prop, 6595 Property* prop,
6584 HValue* object, 6596 HValue* object,
6585 HValue* value) { 6597 HValue* value,
6598 HValue* result) {
6586 Literal* key = prop->key()->AsLiteral(); 6599 Literal* key = prop->key()->AsLiteral();
6587 Handle<String> name = Handle<String>::cast(key->handle()); 6600 Handle<String> name = Handle<String>::cast(key->handle());
6588 ASSERT(!name.is_null()); 6601 ASSERT(!name.is_null());
6589 6602
6590 HInstruction* instr = NULL; 6603 HInstruction* instr = NULL;
6591 SmallMapList* types = expr->GetReceiverTypes(); 6604 SmallMapList* types = expr->GetReceiverTypes();
6592 bool monomorphic = expr->IsMonomorphic(); 6605 bool monomorphic = expr->IsMonomorphic();
6593 Handle<Map> map; 6606 Handle<Map> map;
6594 if (monomorphic) { 6607 if (monomorphic) {
6595 map = types->first(); 6608 map = types->first();
6596 if (map->is_dictionary_map()) monomorphic = false; 6609 if (map->is_dictionary_map()) monomorphic = false;
6597 } 6610 }
6598 if (monomorphic) { 6611 if (monomorphic) {
6599 Handle<JSFunction> setter; 6612 Handle<JSFunction> setter;
6600 Handle<JSObject> holder; 6613 Handle<JSObject> holder;
6601 if (LookupSetter(map, name, &setter, &holder)) { 6614 if (LookupSetter(map, name, &setter, &holder)) {
6602 AddCheckConstantFunction(holder, object, map); 6615 AddCheckConstantFunction(holder, object, map);
6603 if (FLAG_inline_accessors && 6616 if (result == value &&
6617 FLAG_inline_accessors &&
6604 TryInlineSetter(setter, id, assignment_id, value)) { 6618 TryInlineSetter(setter, id, assignment_id, value)) {
6605 return; 6619 return;
6606 } 6620 }
6607 Drop(2); 6621 Drop(2);
6608 AddInstruction(new(zone()) HPushArgument(object)); 6622 AddInstruction(new(zone()) HPushArgument(object));
6609 AddInstruction(new(zone()) HPushArgument(value)); 6623 AddInstruction(new(zone()) HPushArgument(value));
6610 instr = new(zone()) HCallConstantFunction(setter, 2); 6624 instr = new(zone()) HCallConstantFunction(setter, 2);
6611 } else { 6625 } else {
6612 Drop(2); 6626 Drop(2);
6613 CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object, 6627 CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object,
6614 name, 6628 name,
6615 value, 6629 value,
6616 map)); 6630 map));
6617 } 6631 }
6618
6619 } else if (types != NULL && types->length() > 1) { 6632 } else if (types != NULL && types->length() > 1) {
6620 Drop(2); 6633 Drop(2);
6621 return HandlePolymorphicStoreNamedField( 6634 return HandlePolymorphicStoreNamedField(
6622 id, position, assignment_id, object, value, types, name); 6635 id, position, assignment_id, object, value, result, types, name);
6623 } else { 6636 } else {
6624 Drop(2); 6637 Drop(2);
6625 instr = BuildStoreNamedGeneric(object, name, value); 6638 instr = BuildStoreNamedGeneric(object, name, value);
6626 } 6639 }
6627 6640
6641 if (value != result) Push(result);
6628 Push(value); 6642 Push(value);
6629 instr->set_position(position); 6643 instr->set_position(position);
6630 AddInstruction(instr); 6644 AddInstruction(instr);
6631 if (instr->HasObservableSideEffects()) { 6645 if (instr->HasObservableSideEffects()) {
6632 AddSimulate(assignment_id, REMOVABLE_SIMULATE); 6646 AddSimulate(assignment_id, REMOVABLE_SIMULATE);
6633 } 6647 }
6648 if (value != result) Drop(1);
6634 return ast_context()->ReturnValue(Pop()); 6649 return ast_context()->ReturnValue(Pop());
6635 } 6650 }
6636 6651
6637 6652
6638 void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) { 6653 void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) {
6639 Expression* target = expr->target(); 6654 Expression* target = expr->target();
6640 VariableProxy* proxy = target->AsVariableProxy(); 6655 VariableProxy* proxy = target->AsVariableProxy();
6641 Property* prop = target->AsProperty(); 6656 Property* prop = target->AsProperty();
6642 ASSERT(proxy == NULL || prop == NULL); 6657 ASSERT(proxy == NULL || prop == NULL);
6643 6658
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
6755 HValue* right = Pop(); 6770 HValue* right = Pop();
6756 HValue* left = Pop(); 6771 HValue* left = Pop();
6757 6772
6758 HInstruction* instr = BuildBinaryOperation(operation, left, right); 6773 HInstruction* instr = BuildBinaryOperation(operation, left, right);
6759 PushAndAdd(instr); 6774 PushAndAdd(instr);
6760 if (instr->HasObservableSideEffects()) { 6775 if (instr->HasObservableSideEffects()) {
6761 AddSimulate(operation->id(), REMOVABLE_SIMULATE); 6776 AddSimulate(operation->id(), REMOVABLE_SIMULATE);
6762 } 6777 }
6763 6778
6764 return BuildStoreNamed(prop, expr->id(), expr->position(), 6779 return BuildStoreNamed(prop, expr->id(), expr->position(),
6765 expr->AssignmentId(), prop, object, instr); 6780 expr->AssignmentId(), prop, object, instr, instr);
6766 } else { 6781 } else {
6767 // Keyed property. 6782 // Keyed property.
6768 CHECK_ALIVE(VisitForValue(prop->obj())); 6783 CHECK_ALIVE(VisitForValue(prop->obj()));
6769 CHECK_ALIVE(VisitForValue(prop->key())); 6784 CHECK_ALIVE(VisitForValue(prop->key()));
6770 HValue* obj = environment()->ExpressionStackAt(1); 6785 HValue* obj = environment()->ExpressionStackAt(1);
6771 HValue* key = environment()->ExpressionStackAt(0); 6786 HValue* key = environment()->ExpressionStackAt(0);
6772 6787
6773 bool has_side_effects = false; 6788 bool has_side_effects = false;
6774 HValue* load = HandleKeyedElementAccess( 6789 HValue* load = HandleKeyedElementAccess(
6775 obj, key, NULL, prop, prop->LoadId(), RelocInfo::kNoPosition, 6790 obj, key, NULL, prop, prop->LoadId(), RelocInfo::kNoPosition,
(...skipping 2471 matching lines...) Expand 10 before | Expand all | Expand 10 after
9247 } else if (types != NULL && types->length() > 1) { 9262 } else if (types != NULL && types->length() > 1) {
9248 load = TryLoadPolymorphicAsMonomorphic(prop, object, types, name); 9263 load = TryLoadPolymorphicAsMonomorphic(prop, object, types, name);
9249 } 9264 }
9250 if (load == NULL) load = BuildLoadNamedGeneric(object, name, prop); 9265 if (load == NULL) load = BuildLoadNamedGeneric(object, name, prop);
9251 PushAndAdd(load); 9266 PushAndAdd(load);
9252 if (load->HasObservableSideEffects()) { 9267 if (load->HasObservableSideEffects()) {
9253 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); 9268 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE);
9254 } 9269 }
9255 9270
9256 after = BuildIncrement(returns_original_input, expr); 9271 after = BuildIncrement(returns_original_input, expr);
9257 input = Pop();
9258 9272
9259 HInstruction* store; 9273 HValue* result = returns_original_input ? Pop() : after;
9260 if (!monomorphic || map->is_observed()) {
9261 // If we don't know the monomorphic type, do a generic store.
9262 CHECK_ALIVE(store = BuildStoreNamedGeneric(object, name, after));
9263 } else {
9264 Handle<JSFunction> setter;
9265 Handle<JSObject> holder;
9266 if (LookupSetter(map, name, &setter, &holder)) {
9267 store = BuildCallSetter(object, after, map, setter, holder);
9268 } else {
9269 CHECK_ALIVE(store = BuildStoreNamedMonomorphic(object,
9270 name,
9271 after,
9272 map));
9273 }
9274 }
9275 AddInstruction(store);
9276 9274
9277 // Overwrite the receiver in the bailout environment with the result 9275 return BuildStoreNamed(prop, expr->id(), expr->position(),
9278 // of the operation, and the placeholder with the original value if 9276 expr->AssignmentId(), prop, object, after, result);
9279 // necessary.
9280 environment()->SetExpressionStackAt(0, after);
9281 if (returns_original_input) environment()->SetExpressionStackAt(1, input);
9282 if (store->HasObservableSideEffects()) {
9283 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE);
9284 }
9285
9286 } else { 9277 } else {
9287 // Keyed property. 9278 // Keyed property.
9288 if (returns_original_input) Push(graph()->GetConstantUndefined()); 9279 if (returns_original_input) Push(graph()->GetConstantUndefined());
9289 9280
9290 CHECK_ALIVE(VisitForValue(prop->obj())); 9281 CHECK_ALIVE(VisitForValue(prop->obj()));
9291 CHECK_ALIVE(VisitForValue(prop->key())); 9282 CHECK_ALIVE(VisitForValue(prop->key()));
9292 HValue* obj = environment()->ExpressionStackAt(1); 9283 HValue* obj = environment()->ExpressionStackAt(1);
9293 HValue* key = environment()->ExpressionStackAt(0); 9284 HValue* key = environment()->ExpressionStackAt(0);
9294 9285
9295 bool has_side_effects = false; 9286 bool has_side_effects = false;
(...skipping 2288 matching lines...) Expand 10 before | Expand all | Expand 10 after
11584 } 11575 }
11585 } 11576 }
11586 11577
11587 #ifdef DEBUG 11578 #ifdef DEBUG
11588 if (graph_ != NULL) graph_->Verify(false); // No full verify. 11579 if (graph_ != NULL) graph_->Verify(false); // No full verify.
11589 if (allocator_ != NULL) allocator_->Verify(); 11580 if (allocator_ != NULL) allocator_->Verify();
11590 #endif 11581 #endif
11591 } 11582 }
11592 11583
11593 } } // namespace v8::internal 11584 } } // 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