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

Side by Side Diff: src/hydrogen.cc

Issue 16870013: Version 3.19.18.3. (Closed) Base URL: https://v8.googlecode.com/svn/trunk
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') | src/version.cc » ('j') | 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 6363 matching lines...) Expand 10 before | Expand all | Expand 10 after
6374 instr = new(zone()) HLoadNamedFieldPolymorphic( 6374 instr = new(zone()) HLoadNamedFieldPolymorphic(
6375 context, object, types, name, zone()); 6375 context, object, types, name, zone());
6376 } 6376 }
6377 6377
6378 instr->set_position(expr->position()); 6378 instr->set_position(expr->position());
6379 return ast_context()->ReturnInstruction(instr, expr->id()); 6379 return ast_context()->ReturnInstruction(instr, expr->id());
6380 } 6380 }
6381 6381
6382 6382
6383 bool HOptimizedGraphBuilder::TryStorePolymorphicAsMonomorphic( 6383 bool HOptimizedGraphBuilder::TryStorePolymorphicAsMonomorphic(
6384 Assignment* expr, 6384 int position,
6385 BailoutId assignment_id,
6385 HValue* object, 6386 HValue* object,
6386 HValue* value, 6387 HValue* value,
6387 SmallMapList* types, 6388 SmallMapList* types,
6388 Handle<String> name) { 6389 Handle<String> name) {
6389 // Use monomorphic store if property lookup results in the same field index 6390 // Use monomorphic store if property lookup results in the same field index
6390 // for all maps. Requires special map check on the set of all handled maps. 6391 // for all maps. Requires special map check on the set of all handled maps.
6391 if (types->length() > kMaxStorePolymorphism) return false; 6392 if (types->length() > kMaxStorePolymorphism) return false;
6392 6393
6393 // TODO(verwaest): Merge the checking logic with the code in 6394 // TODO(verwaest): Merge the checking logic with the code in
6394 // TryLoadPolymorphicAsMonomorphic. 6395 // TryLoadPolymorphicAsMonomorphic.
(...skipping 30 matching lines...) Expand all
6425 6426
6426 // Everything matched; can use monomorphic store. 6427 // Everything matched; can use monomorphic store.
6427 BuildCheckNonSmi(object); 6428 BuildCheckNonSmi(object);
6428 AddInstruction(HCheckMaps::New(object, types, zone())); 6429 AddInstruction(HCheckMaps::New(object, types, zone()));
6429 HInstruction* store; 6430 HInstruction* store;
6430 CHECK_ALIVE_OR_RETURN( 6431 CHECK_ALIVE_OR_RETURN(
6431 store = BuildStoreNamedField( 6432 store = BuildStoreNamedField(
6432 object, name, value, types->at(count - 1), &lookup), 6433 object, name, value, types->at(count - 1), &lookup),
6433 true); 6434 true);
6434 Push(value); 6435 Push(value);
6435 store->set_position(expr->position()); 6436 store->set_position(position);
6436 AddInstruction(store); 6437 AddInstruction(store);
6437 AddSimulate(expr->AssignmentId()); 6438 AddSimulate(assignment_id);
6438 ast_context()->ReturnValue(Pop()); 6439 ast_context()->ReturnValue(Pop());
6439 return true; 6440 return true;
6440 } 6441 }
6441 6442
6442 6443
6443 void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField( 6444 void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField(
6444 Assignment* expr, 6445 BailoutId id,
6446 int position,
6447 BailoutId assignment_id,
6445 HValue* object, 6448 HValue* object,
6446 HValue* value, 6449 HValue* value,
6447 SmallMapList* types, 6450 SmallMapList* types,
6448 Handle<String> name) { 6451 Handle<String> name) {
6449 if (TryStorePolymorphicAsMonomorphic(expr, object, value, types, name)) { 6452 if (TryStorePolymorphicAsMonomorphic(
6453 position, assignment_id, object, value, types, name)) {
6450 return; 6454 return;
6451 } 6455 }
6452 6456
6453 // TODO(ager): We should recognize when the prototype chains for different 6457 // TODO(ager): We should recognize when the prototype chains for different
6454 // maps are identical. In that case we can avoid repeatedly generating the 6458 // maps are identical. In that case we can avoid repeatedly generating the
6455 // same prototype map checks. 6459 // same prototype map checks.
6456 int count = 0; 6460 int count = 0;
6457 HBasicBlock* join = NULL; 6461 HBasicBlock* join = NULL;
6458 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) { 6462 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) {
6459 Handle<Map> map = types->at(i); 6463 Handle<Map> map = types->at(i);
6460 LookupResult lookup(isolate()); 6464 LookupResult lookup(isolate());
6461 if (ComputeLoadStoreField(map, name, &lookup, true)) { 6465 if (ComputeLoadStoreField(map, name, &lookup, true)) {
6462 if (count == 0) { 6466 if (count == 0) {
6463 BuildCheckNonSmi(object); 6467 BuildCheckNonSmi(object);
6464 join = graph()->CreateBasicBlock(); 6468 join = graph()->CreateBasicBlock();
6465 } 6469 }
6466 ++count; 6470 ++count;
6467 HBasicBlock* if_true = graph()->CreateBasicBlock(); 6471 HBasicBlock* if_true = graph()->CreateBasicBlock();
6468 HBasicBlock* if_false = graph()->CreateBasicBlock(); 6472 HBasicBlock* if_false = graph()->CreateBasicBlock();
6469 HCompareMap* compare = 6473 HCompareMap* compare =
6470 new(zone()) HCompareMap(object, map, if_true, if_false); 6474 new(zone()) HCompareMap(object, map, if_true, if_false);
6471 current_block()->Finish(compare); 6475 current_block()->Finish(compare);
6472 6476
6473 set_current_block(if_true); 6477 set_current_block(if_true);
6474 HInstruction* instr; 6478 HInstruction* instr;
6475 CHECK_ALIVE( 6479 CHECK_ALIVE(
6476 instr = BuildStoreNamedField(object, name, value, map, &lookup)); 6480 instr = BuildStoreNamedField(object, name, value, map, &lookup));
6477 instr->set_position(expr->position()); 6481 instr->set_position(position);
6478 // Goto will add the HSimulate for the store. 6482 // Goto will add the HSimulate for the store.
6479 AddInstruction(instr); 6483 AddInstruction(instr);
6480 if (!ast_context()->IsEffect()) Push(value); 6484 if (!ast_context()->IsEffect()) Push(value);
6481 current_block()->Goto(join); 6485 current_block()->Goto(join);
6482 6486
6483 set_current_block(if_false); 6487 set_current_block(if_false);
6484 } 6488 }
6485 } 6489 }
6486 6490
6487 // Finish up. Unconditionally deoptimize if we've handled all the maps we 6491 // Finish up. Unconditionally deoptimize if we've handled all the maps we
6488 // know about and do not want to handle ones we've never seen. Otherwise 6492 // know about and do not want to handle ones we've never seen. Otherwise
6489 // use a generic IC. 6493 // use a generic IC.
6490 if (count == types->length() && FLAG_deoptimize_uncommon_cases) { 6494 if (count == types->length() && FLAG_deoptimize_uncommon_cases) {
6491 current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses); 6495 current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses);
6492 } else { 6496 } else {
6493 HInstruction* instr = BuildStoreNamedGeneric(object, name, value); 6497 HInstruction* instr = BuildStoreNamedGeneric(object, name, value);
6494 instr->set_position(expr->position()); 6498 instr->set_position(position);
6495 AddInstruction(instr); 6499 AddInstruction(instr);
6496 6500
6497 if (join != NULL) { 6501 if (join != NULL) {
6498 if (!ast_context()->IsEffect()) Push(value); 6502 if (!ast_context()->IsEffect()) Push(value);
6499 current_block()->Goto(join); 6503 current_block()->Goto(join);
6500 } else { 6504 } else {
6501 // The HSimulate for the store should not see the stored value in 6505 // The HSimulate for the store should not see the stored value in
6502 // effect contexts (it is not materialized at expr->id() in the 6506 // effect contexts (it is not materialized at expr->id() in the
6503 // unoptimized code). 6507 // unoptimized code).
6504 if (instr->HasObservableSideEffects()) { 6508 if (instr->HasObservableSideEffects()) {
6505 if (ast_context()->IsEffect()) { 6509 if (ast_context()->IsEffect()) {
6506 AddSimulate(expr->id(), REMOVABLE_SIMULATE); 6510 AddSimulate(id, REMOVABLE_SIMULATE);
6507 } else { 6511 } else {
6508 Push(value); 6512 Push(value);
6509 AddSimulate(expr->id(), REMOVABLE_SIMULATE); 6513 AddSimulate(id, REMOVABLE_SIMULATE);
6510 Drop(1); 6514 Drop(1);
6511 } 6515 }
6512 } 6516 }
6513 return ast_context()->ReturnValue(value); 6517 return ast_context()->ReturnValue(value);
6514 } 6518 }
6515 } 6519 }
6516 6520
6517 ASSERT(join != NULL); 6521 ASSERT(join != NULL);
6518 join->SetJoinId(expr->id()); 6522 join->SetJoinId(id);
6519 set_current_block(join); 6523 set_current_block(join);
6520 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); 6524 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop());
6521 } 6525 }
6522 6526
6523 6527
6524 void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) { 6528 void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) {
6525 Property* prop = expr->target()->AsProperty(); 6529 Property* prop = expr->target()->AsProperty();
6526 ASSERT(prop != NULL); 6530 ASSERT(prop != NULL);
6527 CHECK_ALIVE(VisitForValue(prop->obj())); 6531 CHECK_ALIVE(VisitForValue(prop->obj()));
6528 6532
6529 if (prop->key()->IsPropertyName()) { 6533 if (prop->key()->IsPropertyName()) {
6530 // Named store. 6534 // Named store.
6531 CHECK_ALIVE(VisitForValue(expr->value())); 6535 CHECK_ALIVE(VisitForValue(expr->value()));
6532 HValue* value = environment()->ExpressionStackAt(0); 6536 HValue* value = environment()->ExpressionStackAt(0);
6533 HValue* object = environment()->ExpressionStackAt(1); 6537 HValue* object = environment()->ExpressionStackAt(1);
6534 6538
6535 Literal* key = prop->key()->AsLiteral(); 6539 return BuildStoreNamed(expr, expr->id(), expr->position(),
6536 Handle<String> name = Handle<String>::cast(key->handle()); 6540 expr->AssignmentId(), prop, object, value);
6537 ASSERT(!name.is_null());
6538
6539 HInstruction* instr = NULL;
6540 SmallMapList* types = expr->GetReceiverTypes();
6541 bool monomorphic = expr->IsMonomorphic();
6542 Handle<Map> map;
6543 if (monomorphic) {
6544 map = types->first();
6545 if (map->is_dictionary_map()) monomorphic = false;
6546 }
6547 if (monomorphic) {
6548 Handle<JSFunction> setter;
6549 Handle<JSObject> holder;
6550 if (LookupSetter(map, name, &setter, &holder)) {
6551 AddCheckConstantFunction(holder, object, map);
6552 if (FLAG_inline_accessors && TryInlineSetter(setter, expr, value)) {
6553 return;
6554 }
6555 Drop(2);
6556 AddInstruction(new(zone()) HPushArgument(object));
6557 AddInstruction(new(zone()) HPushArgument(value));
6558 instr = new(zone()) HCallConstantFunction(setter, 2);
6559 } else {
6560 Drop(2);
6561 CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object,
6562 name,
6563 value,
6564 map));
6565 }
6566
6567 } else if (types != NULL && types->length() > 1) {
6568 Drop(2);
6569 return HandlePolymorphicStoreNamedField(expr, object, value, types, name);
6570 } else {
6571 Drop(2);
6572 instr = BuildStoreNamedGeneric(object, name, value);
6573 }
6574
6575 Push(value);
6576 instr->set_position(expr->position());
6577 AddInstruction(instr);
6578 if (instr->HasObservableSideEffects()) {
6579 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE);
6580 }
6581 return ast_context()->ReturnValue(Pop());
6582
6583 } else { 6541 } else {
6584 // Keyed store. 6542 // Keyed store.
6585 CHECK_ALIVE(VisitForValue(prop->key())); 6543 CHECK_ALIVE(VisitForValue(prop->key()));
6586 CHECK_ALIVE(VisitForValue(expr->value())); 6544 CHECK_ALIVE(VisitForValue(expr->value()));
6587 HValue* value = environment()->ExpressionStackAt(0); 6545 HValue* value = environment()->ExpressionStackAt(0);
6588 HValue* key = environment()->ExpressionStackAt(1); 6546 HValue* key = environment()->ExpressionStackAt(1);
6589 HValue* object = environment()->ExpressionStackAt(2); 6547 HValue* object = environment()->ExpressionStackAt(2);
6590 bool has_side_effects = false; 6548 bool has_side_effects = false;
6591 HandleKeyedElementAccess(object, key, value, expr, expr->AssignmentId(), 6549 HandleKeyedElementAccess(object, key, value, expr, expr->AssignmentId(),
6592 expr->position(), 6550 expr->position(),
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
6631 value, 6589 value,
6632 function_strict_mode_flag()); 6590 function_strict_mode_flag());
6633 instr->set_position(position); 6591 instr->set_position(position);
6634 AddInstruction(instr); 6592 AddInstruction(instr);
6635 ASSERT(instr->HasObservableSideEffects()); 6593 ASSERT(instr->HasObservableSideEffects());
6636 AddSimulate(ast_id, REMOVABLE_SIMULATE); 6594 AddSimulate(ast_id, REMOVABLE_SIMULATE);
6637 } 6595 }
6638 } 6596 }
6639 6597
6640 6598
6599 void HOptimizedGraphBuilder::BuildStoreNamed(Expression* expr,
6600 BailoutId id,
6601 int position,
6602 BailoutId assignment_id,
6603 Property* prop,
6604 HValue* object,
6605 HValue* value) {
6606 Literal* key = prop->key()->AsLiteral();
6607 Handle<String> name = Handle<String>::cast(key->handle());
6608 ASSERT(!name.is_null());
6609
6610 HInstruction* instr = NULL;
6611 SmallMapList* types = expr->GetReceiverTypes();
6612 bool monomorphic = expr->IsMonomorphic();
6613 Handle<Map> map;
6614 if (monomorphic) {
6615 map = types->first();
6616 if (map->is_dictionary_map()) monomorphic = false;
6617 }
6618 if (monomorphic) {
6619 Handle<JSFunction> setter;
6620 Handle<JSObject> holder;
6621 if (LookupSetter(map, name, &setter, &holder)) {
6622 AddCheckConstantFunction(holder, object, map);
6623 if (FLAG_inline_accessors &&
6624 TryInlineSetter(setter, id, assignment_id, value)) {
6625 return;
6626 }
6627 Drop(2);
6628 AddInstruction(new(zone()) HPushArgument(object));
6629 AddInstruction(new(zone()) HPushArgument(value));
6630 instr = new(zone()) HCallConstantFunction(setter, 2);
6631 } else {
6632 Drop(2);
6633 CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object,
6634 name,
6635 value,
6636 map));
6637 }
6638
6639 } else if (types != NULL && types->length() > 1) {
6640 Drop(2);
6641 return HandlePolymorphicStoreNamedField(
6642 id, position, assignment_id, object, value, types, name);
6643 } else {
6644 Drop(2);
6645 instr = BuildStoreNamedGeneric(object, name, value);
6646 }
6647
6648 Push(value);
6649 instr->set_position(position);
6650 AddInstruction(instr);
6651 if (instr->HasObservableSideEffects()) {
6652 AddSimulate(assignment_id, REMOVABLE_SIMULATE);
6653 }
6654 return ast_context()->ReturnValue(Pop());
6655 }
6656
6657
6641 void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) { 6658 void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) {
6642 Expression* target = expr->target(); 6659 Expression* target = expr->target();
6643 VariableProxy* proxy = target->AsVariableProxy(); 6660 VariableProxy* proxy = target->AsVariableProxy();
6644 Property* prop = target->AsProperty(); 6661 Property* prop = target->AsProperty();
6645 ASSERT(proxy == NULL || prop == NULL); 6662 ASSERT(proxy == NULL || prop == NULL);
6646 6663
6647 // We have a second position recorded in the FullCodeGenerator to have 6664 // We have a second position recorded in the FullCodeGenerator to have
6648 // type feedback for the binary operation. 6665 // type feedback for the binary operation.
6649 BinaryOperation* operation = expr->binary_operation(); 6666 BinaryOperation* operation = expr->binary_operation();
6650 6667
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
6757 CHECK_ALIVE(VisitForValue(expr->value())); 6774 CHECK_ALIVE(VisitForValue(expr->value()));
6758 HValue* right = Pop(); 6775 HValue* right = Pop();
6759 HValue* left = Pop(); 6776 HValue* left = Pop();
6760 6777
6761 HInstruction* instr = BuildBinaryOperation(operation, left, right); 6778 HInstruction* instr = BuildBinaryOperation(operation, left, right);
6762 PushAndAdd(instr); 6779 PushAndAdd(instr);
6763 if (instr->HasObservableSideEffects()) { 6780 if (instr->HasObservableSideEffects()) {
6764 AddSimulate(operation->id(), REMOVABLE_SIMULATE); 6781 AddSimulate(operation->id(), REMOVABLE_SIMULATE);
6765 } 6782 }
6766 6783
6767 HInstruction* store; 6784 return BuildStoreNamed(prop, expr->id(), expr->position(),
6768 if (!monomorphic || map->is_observed()) { 6785 expr->AssignmentId(), prop, object, instr);
6769 // If we don't know the monomorphic type, do a generic store.
6770 CHECK_ALIVE(store = BuildStoreNamedGeneric(object, name, instr));
6771 } else {
6772 Handle<JSFunction> setter;
6773 Handle<JSObject> holder;
6774 if (LookupSetter(map, name, &setter, &holder)) {
6775 store = BuildCallSetter(object, instr, map, setter, holder);
6776 } else {
6777 CHECK_ALIVE(store = BuildStoreNamedMonomorphic(object,
6778 name,
6779 instr,
6780 map));
6781 }
6782 }
6783 AddInstruction(store);
6784 // Drop the simulated receiver and value. Return the value.
6785 Drop(2);
6786 Push(instr);
6787 if (store->HasObservableSideEffects()) {
6788 AddSimulate(expr->AssignmentId(), REMOVABLE_SIMULATE);
6789 }
6790 return ast_context()->ReturnValue(Pop());
6791
6792 } else { 6786 } else {
6793 // Keyed property. 6787 // Keyed property.
6794 CHECK_ALIVE(VisitForValue(prop->obj())); 6788 CHECK_ALIVE(VisitForValue(prop->obj()));
6795 CHECK_ALIVE(VisitForValue(prop->key())); 6789 CHECK_ALIVE(VisitForValue(prop->key()));
6796 HValue* obj = environment()->ExpressionStackAt(1); 6790 HValue* obj = environment()->ExpressionStackAt(1);
6797 HValue* key = environment()->ExpressionStackAt(0); 6791 HValue* key = environment()->ExpressionStackAt(0);
6798 6792
6799 bool has_side_effects = false; 6793 bool has_side_effects = false;
6800 HValue* load = HandleKeyedElementAccess( 6794 HValue* load = HandleKeyedElementAccess(
6801 obj, key, NULL, prop, prop->LoadId(), RelocInfo::kNoPosition, 6795 obj, key, NULL, prop, prop->LoadId(), RelocInfo::kNoPosition,
(...skipping 1442 matching lines...) Expand 10 before | Expand all | Expand 10 after
8244 getter, 8238 getter,
8245 0, 8239 0,
8246 NULL, 8240 NULL,
8247 prop->id(), 8241 prop->id(),
8248 prop->LoadId(), 8242 prop->LoadId(),
8249 GETTER_CALL_RETURN); 8243 GETTER_CALL_RETURN);
8250 } 8244 }
8251 8245
8252 8246
8253 bool HOptimizedGraphBuilder::TryInlineSetter(Handle<JSFunction> setter, 8247 bool HOptimizedGraphBuilder::TryInlineSetter(Handle<JSFunction> setter,
8254 Assignment* assignment, 8248 BailoutId id,
8249 BailoutId assignment_id,
8255 HValue* implicit_return_value) { 8250 HValue* implicit_return_value) {
8256 return TryInline(CALL_AS_METHOD, 8251 return TryInline(CALL_AS_METHOD,
8257 setter, 8252 setter,
8258 1, 8253 1,
8259 implicit_return_value, 8254 implicit_return_value,
8260 assignment->id(), 8255 id, assignment_id,
8261 assignment->AssignmentId(),
8262 SETTER_CALL_RETURN); 8256 SETTER_CALL_RETURN);
8263 } 8257 }
8264 8258
8265 8259
8266 bool HOptimizedGraphBuilder::TryInlineApply(Handle<JSFunction> function, 8260 bool HOptimizedGraphBuilder::TryInlineApply(Handle<JSFunction> function,
8267 Call* expr, 8261 Call* expr,
8268 int arguments_count) { 8262 int arguments_count) {
8269 return TryInline(CALL_AS_METHOD, 8263 return TryInline(CALL_AS_METHOD,
8270 function, 8264 function,
8271 arguments_count, 8265 arguments_count,
(...skipping 3391 matching lines...) Expand 10 before | Expand all | Expand 10 after
11663 } 11657 }
11664 } 11658 }
11665 11659
11666 #ifdef DEBUG 11660 #ifdef DEBUG
11667 if (graph_ != NULL) graph_->Verify(false); // No full verify. 11661 if (graph_ != NULL) graph_->Verify(false); // No full verify.
11668 if (allocator_ != NULL) allocator_->Verify(); 11662 if (allocator_ != NULL) allocator_->Verify();
11669 #endif 11663 #endif
11670 } 11664 }
11671 11665
11672 } } // namespace v8::internal 11666 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/version.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698