| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/double.h" | 7 #include "src/double.h" |
| 8 #include "src/factory.h" | 8 #include "src/factory.h" |
| 9 #include "src/hydrogen-infer-representation.h" | 9 #include "src/hydrogen-infer-representation.h" |
| 10 #include "src/property-details-inl.h" | 10 #include "src/property-details-inl.h" |
| (...skipping 23 matching lines...) Expand all Loading... |
| 34 | 34 |
| 35 #define DEFINE_COMPILE(type) \ | 35 #define DEFINE_COMPILE(type) \ |
| 36 LInstruction* H##type::CompileToLithium(LChunkBuilder* builder) { \ | 36 LInstruction* H##type::CompileToLithium(LChunkBuilder* builder) { \ |
| 37 return builder->Do##type(this); \ | 37 return builder->Do##type(this); \ |
| 38 } | 38 } |
| 39 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DEFINE_COMPILE) | 39 HYDROGEN_CONCRETE_INSTRUCTION_LIST(DEFINE_COMPILE) |
| 40 #undef DEFINE_COMPILE | 40 #undef DEFINE_COMPILE |
| 41 | 41 |
| 42 | 42 |
| 43 Isolate* HValue::isolate() const { | 43 Isolate* HValue::isolate() const { |
| 44 ASSERT(block() != NULL); | 44 DCHECK(block() != NULL); |
| 45 return block()->isolate(); | 45 return block()->isolate(); |
| 46 } | 46 } |
| 47 | 47 |
| 48 | 48 |
| 49 void HValue::AssumeRepresentation(Representation r) { | 49 void HValue::AssumeRepresentation(Representation r) { |
| 50 if (CheckFlag(kFlexibleRepresentation)) { | 50 if (CheckFlag(kFlexibleRepresentation)) { |
| 51 ChangeRepresentation(r); | 51 ChangeRepresentation(r); |
| 52 // The representation of the value is dictated by type feedback and | 52 // The representation of the value is dictated by type feedback and |
| 53 // will not be changed later. | 53 // will not be changed later. |
| 54 ClearFlag(kFlexibleRepresentation); | 54 ClearFlag(kFlexibleRepresentation); |
| 55 } | 55 } |
| 56 } | 56 } |
| 57 | 57 |
| 58 | 58 |
| 59 void HValue::InferRepresentation(HInferRepresentationPhase* h_infer) { | 59 void HValue::InferRepresentation(HInferRepresentationPhase* h_infer) { |
| 60 ASSERT(CheckFlag(kFlexibleRepresentation)); | 60 DCHECK(CheckFlag(kFlexibleRepresentation)); |
| 61 Representation new_rep = RepresentationFromInputs(); | 61 Representation new_rep = RepresentationFromInputs(); |
| 62 UpdateRepresentation(new_rep, h_infer, "inputs"); | 62 UpdateRepresentation(new_rep, h_infer, "inputs"); |
| 63 new_rep = RepresentationFromUses(); | 63 new_rep = RepresentationFromUses(); |
| 64 UpdateRepresentation(new_rep, h_infer, "uses"); | 64 UpdateRepresentation(new_rep, h_infer, "uses"); |
| 65 if (representation().IsSmi() && HasNonSmiUse()) { | 65 if (representation().IsSmi() && HasNonSmiUse()) { |
| 66 UpdateRepresentation( | 66 UpdateRepresentation( |
| 67 Representation::Integer32(), h_infer, "use requirements"); | 67 Representation::Integer32(), h_infer, "use requirements"); |
| 68 } | 68 } |
| 69 } | 69 } |
| 70 | 70 |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 285 if (lower_ > upper_) { | 285 if (lower_ > upper_) { |
| 286 int32_t tmp = lower_; | 286 int32_t tmp = lower_; |
| 287 lower_ = upper_; | 287 lower_ = upper_; |
| 288 upper_ = tmp; | 288 upper_ = tmp; |
| 289 } | 289 } |
| 290 } | 290 } |
| 291 | 291 |
| 292 | 292 |
| 293 #ifdef DEBUG | 293 #ifdef DEBUG |
| 294 void Range::Verify() const { | 294 void Range::Verify() const { |
| 295 ASSERT(lower_ <= upper_); | 295 DCHECK(lower_ <= upper_); |
| 296 } | 296 } |
| 297 #endif | 297 #endif |
| 298 | 298 |
| 299 | 299 |
| 300 bool Range::MulAndCheckOverflow(const Representation& r, Range* other) { | 300 bool Range::MulAndCheckOverflow(const Representation& r, Range* other) { |
| 301 bool may_overflow = false; | 301 bool may_overflow = false; |
| 302 int v1 = MulWithoutOverflow(r, lower_, other->lower(), &may_overflow); | 302 int v1 = MulWithoutOverflow(r, lower_, other->lower(), &may_overflow); |
| 303 int v2 = MulWithoutOverflow(r, lower_, other->upper(), &may_overflow); | 303 int v2 = MulWithoutOverflow(r, lower_, other->upper(), &may_overflow); |
| 304 int v3 = MulWithoutOverflow(r, upper_, other->lower(), &may_overflow); | 304 int v3 = MulWithoutOverflow(r, upper_, other->lower(), &may_overflow); |
| 305 int v4 = MulWithoutOverflow(r, upper_, other->upper(), &may_overflow); | 305 int v4 = MulWithoutOverflow(r, upper_, other->upper(), &may_overflow); |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 414 bool HValue::Equals(HValue* other) { | 414 bool HValue::Equals(HValue* other) { |
| 415 if (other->opcode() != opcode()) return false; | 415 if (other->opcode() != opcode()) return false; |
| 416 if (!other->representation().Equals(representation())) return false; | 416 if (!other->representation().Equals(representation())) return false; |
| 417 if (!other->type_.Equals(type_)) return false; | 417 if (!other->type_.Equals(type_)) return false; |
| 418 if (other->flags() != flags()) return false; | 418 if (other->flags() != flags()) return false; |
| 419 if (OperandCount() != other->OperandCount()) return false; | 419 if (OperandCount() != other->OperandCount()) return false; |
| 420 for (int i = 0; i < OperandCount(); ++i) { | 420 for (int i = 0; i < OperandCount(); ++i) { |
| 421 if (OperandAt(i)->id() != other->OperandAt(i)->id()) return false; | 421 if (OperandAt(i)->id() != other->OperandAt(i)->id()) return false; |
| 422 } | 422 } |
| 423 bool result = DataEquals(other); | 423 bool result = DataEquals(other); |
| 424 ASSERT(!result || Hashcode() == other->Hashcode()); | 424 DCHECK(!result || Hashcode() == other->Hashcode()); |
| 425 return result; | 425 return result; |
| 426 } | 426 } |
| 427 | 427 |
| 428 | 428 |
| 429 intptr_t HValue::Hashcode() { | 429 intptr_t HValue::Hashcode() { |
| 430 intptr_t result = opcode(); | 430 intptr_t result = opcode(); |
| 431 int count = OperandCount(); | 431 int count = OperandCount(); |
| 432 for (int i = 0; i < count; ++i) { | 432 for (int i = 0; i < count; ++i) { |
| 433 result = result * 19 + OperandAt(i)->id() + (result >> 7); | 433 result = result * 19 + OperandAt(i)->id() + (result >> 7); |
| 434 } | 434 } |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 486 if (other != NULL) ReplaceAllUsesWith(other); | 486 if (other != NULL) ReplaceAllUsesWith(other); |
| 487 Kill(); | 487 Kill(); |
| 488 DeleteFromGraph(); | 488 DeleteFromGraph(); |
| 489 } | 489 } |
| 490 | 490 |
| 491 | 491 |
| 492 void HValue::ReplaceAllUsesWith(HValue* other) { | 492 void HValue::ReplaceAllUsesWith(HValue* other) { |
| 493 while (use_list_ != NULL) { | 493 while (use_list_ != NULL) { |
| 494 HUseListNode* list_node = use_list_; | 494 HUseListNode* list_node = use_list_; |
| 495 HValue* value = list_node->value(); | 495 HValue* value = list_node->value(); |
| 496 ASSERT(!value->block()->IsStartBlock()); | 496 DCHECK(!value->block()->IsStartBlock()); |
| 497 value->InternalSetOperandAt(list_node->index(), other); | 497 value->InternalSetOperandAt(list_node->index(), other); |
| 498 use_list_ = list_node->tail(); | 498 use_list_ = list_node->tail(); |
| 499 list_node->set_tail(other->use_list_); | 499 list_node->set_tail(other->use_list_); |
| 500 other->use_list_ = list_node; | 500 other->use_list_ = list_node; |
| 501 } | 501 } |
| 502 } | 502 } |
| 503 | 503 |
| 504 | 504 |
| 505 void HValue::Kill() { | 505 void HValue::Kill() { |
| 506 // Instead of going through the entire use list of each operand, we only | 506 // Instead of going through the entire use list of each operand, we only |
| 507 // check the first item in each use list and rely on the tail() method to | 507 // check the first item in each use list and rely on the tail() method to |
| 508 // skip dead items, removing them lazily next time we traverse the list. | 508 // skip dead items, removing them lazily next time we traverse the list. |
| 509 SetFlag(kIsDead); | 509 SetFlag(kIsDead); |
| 510 for (int i = 0; i < OperandCount(); ++i) { | 510 for (int i = 0; i < OperandCount(); ++i) { |
| 511 HValue* operand = OperandAt(i); | 511 HValue* operand = OperandAt(i); |
| 512 if (operand == NULL) continue; | 512 if (operand == NULL) continue; |
| 513 HUseListNode* first = operand->use_list_; | 513 HUseListNode* first = operand->use_list_; |
| 514 if (first != NULL && first->value()->CheckFlag(kIsDead)) { | 514 if (first != NULL && first->value()->CheckFlag(kIsDead)) { |
| 515 operand->use_list_ = first->tail(); | 515 operand->use_list_ = first->tail(); |
| 516 } | 516 } |
| 517 } | 517 } |
| 518 } | 518 } |
| 519 | 519 |
| 520 | 520 |
| 521 void HValue::SetBlock(HBasicBlock* block) { | 521 void HValue::SetBlock(HBasicBlock* block) { |
| 522 ASSERT(block_ == NULL || block == NULL); | 522 DCHECK(block_ == NULL || block == NULL); |
| 523 block_ = block; | 523 block_ = block; |
| 524 if (id_ == kNoNumber && block != NULL) { | 524 if (id_ == kNoNumber && block != NULL) { |
| 525 id_ = block->graph()->GetNextValueID(this); | 525 id_ = block->graph()->GetNextValueID(this); |
| 526 } | 526 } |
| 527 } | 527 } |
| 528 | 528 |
| 529 | 529 |
| 530 OStream& operator<<(OStream& os, const HValue& v) { return v.PrintTo(os); } | 530 OStream& operator<<(OStream& os, const HValue& v) { return v.PrintTo(os); } |
| 531 | 531 |
| 532 | 532 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 590 removed->set_tail(new_value->use_list_); | 590 removed->set_tail(new_value->use_list_); |
| 591 new_value->use_list_ = removed; | 591 new_value->use_list_ = removed; |
| 592 } | 592 } |
| 593 } | 593 } |
| 594 } | 594 } |
| 595 | 595 |
| 596 | 596 |
| 597 void HValue::AddNewRange(Range* r, Zone* zone) { | 597 void HValue::AddNewRange(Range* r, Zone* zone) { |
| 598 if (!HasRange()) ComputeInitialRange(zone); | 598 if (!HasRange()) ComputeInitialRange(zone); |
| 599 if (!HasRange()) range_ = new(zone) Range(); | 599 if (!HasRange()) range_ = new(zone) Range(); |
| 600 ASSERT(HasRange()); | 600 DCHECK(HasRange()); |
| 601 r->StackUpon(range_); | 601 r->StackUpon(range_); |
| 602 range_ = r; | 602 range_ = r; |
| 603 } | 603 } |
| 604 | 604 |
| 605 | 605 |
| 606 void HValue::RemoveLastAddedRange() { | 606 void HValue::RemoveLastAddedRange() { |
| 607 ASSERT(HasRange()); | 607 DCHECK(HasRange()); |
| 608 ASSERT(range_->next() != NULL); | 608 DCHECK(range_->next() != NULL); |
| 609 range_ = range_->next(); | 609 range_ = range_->next(); |
| 610 } | 610 } |
| 611 | 611 |
| 612 | 612 |
| 613 void HValue::ComputeInitialRange(Zone* zone) { | 613 void HValue::ComputeInitialRange(Zone* zone) { |
| 614 ASSERT(!HasRange()); | 614 DCHECK(!HasRange()); |
| 615 range_ = InferRange(zone); | 615 range_ = InferRange(zone); |
| 616 ASSERT(HasRange()); | 616 DCHECK(HasRange()); |
| 617 } | 617 } |
| 618 | 618 |
| 619 | 619 |
| 620 OStream& operator<<(OStream& os, const HSourcePosition& p) { | 620 OStream& operator<<(OStream& os, const HSourcePosition& p) { |
| 621 if (p.IsUnknown()) { | 621 if (p.IsUnknown()) { |
| 622 return os << "<?>"; | 622 return os << "<?>"; |
| 623 } else if (FLAG_hydrogen_track_positions) { | 623 } else if (FLAG_hydrogen_track_positions) { |
| 624 return os << "<" << p.inlining_id() << ":" << p.position() << ">"; | 624 return os << "<" << p.inlining_id() << ":" << p.position() << ">"; |
| 625 } else { | 625 } else { |
| 626 return os << "<0:" << p.raw() << ">"; | 626 return os << "<0:" << p.raw() << ">"; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 640 OStream& HInstruction::PrintDataTo(OStream& os) const { // NOLINT | 640 OStream& HInstruction::PrintDataTo(OStream& os) const { // NOLINT |
| 641 for (int i = 0; i < OperandCount(); ++i) { | 641 for (int i = 0; i < OperandCount(); ++i) { |
| 642 if (i > 0) os << " "; | 642 if (i > 0) os << " "; |
| 643 os << NameOf(OperandAt(i)); | 643 os << NameOf(OperandAt(i)); |
| 644 } | 644 } |
| 645 return os; | 645 return os; |
| 646 } | 646 } |
| 647 | 647 |
| 648 | 648 |
| 649 void HInstruction::Unlink() { | 649 void HInstruction::Unlink() { |
| 650 ASSERT(IsLinked()); | 650 DCHECK(IsLinked()); |
| 651 ASSERT(!IsControlInstruction()); // Must never move control instructions. | 651 DCHECK(!IsControlInstruction()); // Must never move control instructions. |
| 652 ASSERT(!IsBlockEntry()); // Doesn't make sense to delete these. | 652 DCHECK(!IsBlockEntry()); // Doesn't make sense to delete these. |
| 653 ASSERT(previous_ != NULL); | 653 DCHECK(previous_ != NULL); |
| 654 previous_->next_ = next_; | 654 previous_->next_ = next_; |
| 655 if (next_ == NULL) { | 655 if (next_ == NULL) { |
| 656 ASSERT(block()->last() == this); | 656 DCHECK(block()->last() == this); |
| 657 block()->set_last(previous_); | 657 block()->set_last(previous_); |
| 658 } else { | 658 } else { |
| 659 next_->previous_ = previous_; | 659 next_->previous_ = previous_; |
| 660 } | 660 } |
| 661 clear_block(); | 661 clear_block(); |
| 662 } | 662 } |
| 663 | 663 |
| 664 | 664 |
| 665 void HInstruction::InsertBefore(HInstruction* next) { | 665 void HInstruction::InsertBefore(HInstruction* next) { |
| 666 ASSERT(!IsLinked()); | 666 DCHECK(!IsLinked()); |
| 667 ASSERT(!next->IsBlockEntry()); | 667 DCHECK(!next->IsBlockEntry()); |
| 668 ASSERT(!IsControlInstruction()); | 668 DCHECK(!IsControlInstruction()); |
| 669 ASSERT(!next->block()->IsStartBlock()); | 669 DCHECK(!next->block()->IsStartBlock()); |
| 670 ASSERT(next->previous_ != NULL); | 670 DCHECK(next->previous_ != NULL); |
| 671 HInstruction* prev = next->previous(); | 671 HInstruction* prev = next->previous(); |
| 672 prev->next_ = this; | 672 prev->next_ = this; |
| 673 next->previous_ = this; | 673 next->previous_ = this; |
| 674 next_ = next; | 674 next_ = next; |
| 675 previous_ = prev; | 675 previous_ = prev; |
| 676 SetBlock(next->block()); | 676 SetBlock(next->block()); |
| 677 if (!has_position() && next->has_position()) { | 677 if (!has_position() && next->has_position()) { |
| 678 set_position(next->position()); | 678 set_position(next->position()); |
| 679 } | 679 } |
| 680 } | 680 } |
| 681 | 681 |
| 682 | 682 |
| 683 void HInstruction::InsertAfter(HInstruction* previous) { | 683 void HInstruction::InsertAfter(HInstruction* previous) { |
| 684 ASSERT(!IsLinked()); | 684 DCHECK(!IsLinked()); |
| 685 ASSERT(!previous->IsControlInstruction()); | 685 DCHECK(!previous->IsControlInstruction()); |
| 686 ASSERT(!IsControlInstruction() || previous->next_ == NULL); | 686 DCHECK(!IsControlInstruction() || previous->next_ == NULL); |
| 687 HBasicBlock* block = previous->block(); | 687 HBasicBlock* block = previous->block(); |
| 688 // Never insert anything except constants into the start block after finishing | 688 // Never insert anything except constants into the start block after finishing |
| 689 // it. | 689 // it. |
| 690 if (block->IsStartBlock() && block->IsFinished() && !IsConstant()) { | 690 if (block->IsStartBlock() && block->IsFinished() && !IsConstant()) { |
| 691 ASSERT(block->end()->SecondSuccessor() == NULL); | 691 DCHECK(block->end()->SecondSuccessor() == NULL); |
| 692 InsertAfter(block->end()->FirstSuccessor()->first()); | 692 InsertAfter(block->end()->FirstSuccessor()->first()); |
| 693 return; | 693 return; |
| 694 } | 694 } |
| 695 | 695 |
| 696 // If we're inserting after an instruction with side-effects that is | 696 // If we're inserting after an instruction with side-effects that is |
| 697 // followed by a simulate instruction, we need to insert after the | 697 // followed by a simulate instruction, we need to insert after the |
| 698 // simulate instruction instead. | 698 // simulate instruction instead. |
| 699 HInstruction* next = previous->next_; | 699 HInstruction* next = previous->next_; |
| 700 if (previous->HasObservableSideEffects() && next != NULL) { | 700 if (previous->HasObservableSideEffects() && next != NULL) { |
| 701 ASSERT(next->IsSimulate()); | 701 DCHECK(next->IsSimulate()); |
| 702 previous = next; | 702 previous = next; |
| 703 next = previous->next_; | 703 next = previous->next_; |
| 704 } | 704 } |
| 705 | 705 |
| 706 previous_ = previous; | 706 previous_ = previous; |
| 707 next_ = next; | 707 next_ = next; |
| 708 SetBlock(block); | 708 SetBlock(block); |
| 709 previous->next_ = this; | 709 previous->next_ = this; |
| 710 if (next != NULL) next->previous_ = this; | 710 if (next != NULL) next->previous_ = this; |
| 711 if (block->last() == previous) { | 711 if (block->last() == previous) { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 741 if (other_operand == NULL) continue; | 741 if (other_operand == NULL) continue; |
| 742 HBasicBlock* other_block = other_operand->block(); | 742 HBasicBlock* other_block = other_operand->block(); |
| 743 if (cur_block == other_block) { | 743 if (cur_block == other_block) { |
| 744 if (!other_operand->IsPhi()) { | 744 if (!other_operand->IsPhi()) { |
| 745 HInstruction* cur = this->previous(); | 745 HInstruction* cur = this->previous(); |
| 746 while (cur != NULL) { | 746 while (cur != NULL) { |
| 747 if (cur == other_operand) break; | 747 if (cur == other_operand) break; |
| 748 cur = cur->previous(); | 748 cur = cur->previous(); |
| 749 } | 749 } |
| 750 // Must reach other operand in the same block! | 750 // Must reach other operand in the same block! |
| 751 ASSERT(cur == other_operand); | 751 DCHECK(cur == other_operand); |
| 752 } | 752 } |
| 753 } else { | 753 } else { |
| 754 // If the following assert fires, you may have forgotten an | 754 // If the following assert fires, you may have forgotten an |
| 755 // AddInstruction. | 755 // AddInstruction. |
| 756 ASSERT(other_block->Dominates(cur_block)); | 756 DCHECK(other_block->Dominates(cur_block)); |
| 757 } | 757 } |
| 758 } | 758 } |
| 759 | 759 |
| 760 // Verify that instructions that may have side-effects are followed | 760 // Verify that instructions that may have side-effects are followed |
| 761 // by a simulate instruction. | 761 // by a simulate instruction. |
| 762 if (HasObservableSideEffects() && !IsOsrEntry()) { | 762 if (HasObservableSideEffects() && !IsOsrEntry()) { |
| 763 ASSERT(next()->IsSimulate()); | 763 DCHECK(next()->IsSimulate()); |
| 764 } | 764 } |
| 765 | 765 |
| 766 // Verify that instructions that can be eliminated by GVN have overridden | 766 // Verify that instructions that can be eliminated by GVN have overridden |
| 767 // HValue::DataEquals. The default implementation is UNREACHABLE. We | 767 // HValue::DataEquals. The default implementation is UNREACHABLE. We |
| 768 // don't actually care whether DataEquals returns true or false here. | 768 // don't actually care whether DataEquals returns true or false here. |
| 769 if (CheckFlag(kUseGVN)) DataEquals(this); | 769 if (CheckFlag(kUseGVN)) DataEquals(this); |
| 770 | 770 |
| 771 // Verify that all uses are in the graph. | 771 // Verify that all uses are in the graph. |
| 772 for (HUseIterator use = uses(); !use.Done(); use.Advance()) { | 772 for (HUseIterator use = uses(); !use.Done(); use.Advance()) { |
| 773 if (use.value()->IsInstruction()) { | 773 if (use.value()->IsInstruction()) { |
| 774 ASSERT(HInstruction::cast(use.value())->IsLinked()); | 774 DCHECK(HInstruction::cast(use.value())->IsLinked()); |
| 775 } | 775 } |
| 776 } | 776 } |
| 777 } | 777 } |
| 778 #endif | 778 #endif |
| 779 | 779 |
| 780 | 780 |
| 781 bool HInstruction::CanDeoptimize() { | 781 bool HInstruction::CanDeoptimize() { |
| 782 // TODO(titzer): make this a virtual method? | 782 // TODO(titzer): make this a virtual method? |
| 783 switch (opcode()) { | 783 switch (opcode()) { |
| 784 case HValue::kAbnormalExit: | 784 case HValue::kAbnormalExit: |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 962 << argument_count(); | 962 << argument_count(); |
| 963 } | 963 } |
| 964 | 964 |
| 965 | 965 |
| 966 void HBoundsCheck::ApplyIndexChange() { | 966 void HBoundsCheck::ApplyIndexChange() { |
| 967 if (skip_check()) return; | 967 if (skip_check()) return; |
| 968 | 968 |
| 969 DecompositionResult decomposition; | 969 DecompositionResult decomposition; |
| 970 bool index_is_decomposable = index()->TryDecompose(&decomposition); | 970 bool index_is_decomposable = index()->TryDecompose(&decomposition); |
| 971 if (index_is_decomposable) { | 971 if (index_is_decomposable) { |
| 972 ASSERT(decomposition.base() == base()); | 972 DCHECK(decomposition.base() == base()); |
| 973 if (decomposition.offset() == offset() && | 973 if (decomposition.offset() == offset() && |
| 974 decomposition.scale() == scale()) return; | 974 decomposition.scale() == scale()) return; |
| 975 } else { | 975 } else { |
| 976 return; | 976 return; |
| 977 } | 977 } |
| 978 | 978 |
| 979 ReplaceAllUsesWith(index()); | 979 ReplaceAllUsesWith(index()); |
| 980 | 980 |
| 981 HValue* current_index = decomposition.base(); | 981 HValue* current_index = decomposition.base(); |
| 982 int actual_offset = decomposition.offset() + offset(); | 982 int actual_offset = decomposition.offset() + offset(); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1023 os << "index"; | 1023 os << "index"; |
| 1024 } | 1024 } |
| 1025 os << " + " << offset() << ") >> " << scale() << ")"; | 1025 os << " + " << offset() << ") >> " << scale() << ")"; |
| 1026 } | 1026 } |
| 1027 if (skip_check()) os << " [DISABLED]"; | 1027 if (skip_check()) os << " [DISABLED]"; |
| 1028 return os; | 1028 return os; |
| 1029 } | 1029 } |
| 1030 | 1030 |
| 1031 | 1031 |
| 1032 void HBoundsCheck::InferRepresentation(HInferRepresentationPhase* h_infer) { | 1032 void HBoundsCheck::InferRepresentation(HInferRepresentationPhase* h_infer) { |
| 1033 ASSERT(CheckFlag(kFlexibleRepresentation)); | 1033 DCHECK(CheckFlag(kFlexibleRepresentation)); |
| 1034 HValue* actual_index = index()->ActualValue(); | 1034 HValue* actual_index = index()->ActualValue(); |
| 1035 HValue* actual_length = length()->ActualValue(); | 1035 HValue* actual_length = length()->ActualValue(); |
| 1036 Representation index_rep = actual_index->representation(); | 1036 Representation index_rep = actual_index->representation(); |
| 1037 Representation length_rep = actual_length->representation(); | 1037 Representation length_rep = actual_length->representation(); |
| 1038 if (index_rep.IsTagged() && actual_index->type().IsSmi()) { | 1038 if (index_rep.IsTagged() && actual_index->type().IsSmi()) { |
| 1039 index_rep = Representation::Smi(); | 1039 index_rep = Representation::Smi(); |
| 1040 } | 1040 } |
| 1041 if (length_rep.IsTagged() && actual_length->type().IsSmi()) { | 1041 if (length_rep.IsTagged() && actual_length->type().IsSmi()) { |
| 1042 length_rep = Representation::Smi(); | 1042 length_rep = Representation::Smi(); |
| 1043 } | 1043 } |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1164 if (expected_input_types_.Contains(ToBooleanStub::SMI)) { | 1164 if (expected_input_types_.Contains(ToBooleanStub::SMI)) { |
| 1165 return Representation::Smi(); | 1165 return Representation::Smi(); |
| 1166 } | 1166 } |
| 1167 return Representation::None(); | 1167 return Representation::None(); |
| 1168 } | 1168 } |
| 1169 | 1169 |
| 1170 | 1170 |
| 1171 bool HBranch::KnownSuccessorBlock(HBasicBlock** block) { | 1171 bool HBranch::KnownSuccessorBlock(HBasicBlock** block) { |
| 1172 HValue* value = this->value(); | 1172 HValue* value = this->value(); |
| 1173 if (value->EmitAtUses()) { | 1173 if (value->EmitAtUses()) { |
| 1174 ASSERT(value->IsConstant()); | 1174 DCHECK(value->IsConstant()); |
| 1175 ASSERT(!value->representation().IsDouble()); | 1175 DCHECK(!value->representation().IsDouble()); |
| 1176 *block = HConstant::cast(value)->BooleanValue() | 1176 *block = HConstant::cast(value)->BooleanValue() |
| 1177 ? FirstSuccessor() | 1177 ? FirstSuccessor() |
| 1178 : SecondSuccessor(); | 1178 : SecondSuccessor(); |
| 1179 return true; | 1179 return true; |
| 1180 } | 1180 } |
| 1181 *block = NULL; | 1181 *block = NULL; |
| 1182 return false; | 1182 return false; |
| 1183 } | 1183 } |
| 1184 | 1184 |
| 1185 | 1185 |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1299 switch (constant->GetInstanceType()) { | 1299 switch (constant->GetInstanceType()) { |
| 1300 case ODDBALL_TYPE: { | 1300 case ODDBALL_TYPE: { |
| 1301 Unique<Object> unique = constant->GetUnique(); | 1301 Unique<Object> unique = constant->GetUnique(); |
| 1302 if (unique.IsKnownGlobal(heap->true_value()) || | 1302 if (unique.IsKnownGlobal(heap->true_value()) || |
| 1303 unique.IsKnownGlobal(heap->false_value())) { | 1303 unique.IsKnownGlobal(heap->false_value())) { |
| 1304 return heap->boolean_string(); | 1304 return heap->boolean_string(); |
| 1305 } | 1305 } |
| 1306 if (unique.IsKnownGlobal(heap->null_value())) { | 1306 if (unique.IsKnownGlobal(heap->null_value())) { |
| 1307 return heap->object_string(); | 1307 return heap->object_string(); |
| 1308 } | 1308 } |
| 1309 ASSERT(unique.IsKnownGlobal(heap->undefined_value())); | 1309 DCHECK(unique.IsKnownGlobal(heap->undefined_value())); |
| 1310 return heap->undefined_string(); | 1310 return heap->undefined_string(); |
| 1311 } | 1311 } |
| 1312 case SYMBOL_TYPE: | 1312 case SYMBOL_TYPE: |
| 1313 return heap->symbol_string(); | 1313 return heap->symbol_string(); |
| 1314 case JS_FUNCTION_TYPE: | 1314 case JS_FUNCTION_TYPE: |
| 1315 case JS_FUNCTION_PROXY_TYPE: | 1315 case JS_FUNCTION_PROXY_TYPE: |
| 1316 return heap->function_string(); | 1316 return heap->function_string(); |
| 1317 default: | 1317 default: |
| 1318 return heap->object_string(); | 1318 return heap->object_string(); |
| 1319 } | 1319 } |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1605 if (HConstant::cast(value())->HasInternalizedStringValue()) { | 1605 if (HConstant::cast(value())->HasInternalizedStringValue()) { |
| 1606 return value(); | 1606 return value(); |
| 1607 } | 1607 } |
| 1608 } | 1608 } |
| 1609 return this; | 1609 return this; |
| 1610 } | 1610 } |
| 1611 | 1611 |
| 1612 | 1612 |
| 1613 void HCheckInstanceType::GetCheckInterval(InstanceType* first, | 1613 void HCheckInstanceType::GetCheckInterval(InstanceType* first, |
| 1614 InstanceType* last) { | 1614 InstanceType* last) { |
| 1615 ASSERT(is_interval_check()); | 1615 DCHECK(is_interval_check()); |
| 1616 switch (check_) { | 1616 switch (check_) { |
| 1617 case IS_SPEC_OBJECT: | 1617 case IS_SPEC_OBJECT: |
| 1618 *first = FIRST_SPEC_OBJECT_TYPE; | 1618 *first = FIRST_SPEC_OBJECT_TYPE; |
| 1619 *last = LAST_SPEC_OBJECT_TYPE; | 1619 *last = LAST_SPEC_OBJECT_TYPE; |
| 1620 return; | 1620 return; |
| 1621 case IS_JS_ARRAY: | 1621 case IS_JS_ARRAY: |
| 1622 *first = *last = JS_ARRAY_TYPE; | 1622 *first = *last = JS_ARRAY_TYPE; |
| 1623 return; | 1623 return; |
| 1624 default: | 1624 default: |
| 1625 UNREACHABLE(); | 1625 UNREACHABLE(); |
| 1626 } | 1626 } |
| 1627 } | 1627 } |
| 1628 | 1628 |
| 1629 | 1629 |
| 1630 void HCheckInstanceType::GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag) { | 1630 void HCheckInstanceType::GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag) { |
| 1631 ASSERT(!is_interval_check()); | 1631 DCHECK(!is_interval_check()); |
| 1632 switch (check_) { | 1632 switch (check_) { |
| 1633 case IS_STRING: | 1633 case IS_STRING: |
| 1634 *mask = kIsNotStringMask; | 1634 *mask = kIsNotStringMask; |
| 1635 *tag = kStringTag; | 1635 *tag = kStringTag; |
| 1636 return; | 1636 return; |
| 1637 case IS_INTERNALIZED_STRING: | 1637 case IS_INTERNALIZED_STRING: |
| 1638 *mask = kIsNotStringMask | kIsNotInternalizedMask; | 1638 *mask = kIsNotStringMask | kIsNotInternalizedMask; |
| 1639 *tag = kInternalizedTag; | 1639 *tag = kInternalizedTag; |
| 1640 return; | 1640 return; |
| 1641 default: | 1641 default: |
| (...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2048 } | 2048 } |
| 2049 } | 2049 } |
| 2050 | 2050 |
| 2051 result->base = base; | 2051 result->base = base; |
| 2052 } | 2052 } |
| 2053 } | 2053 } |
| 2054 | 2054 |
| 2055 | 2055 |
| 2056 void InductionVariableData::AddCheck(HBoundsCheck* check, | 2056 void InductionVariableData::AddCheck(HBoundsCheck* check, |
| 2057 int32_t upper_limit) { | 2057 int32_t upper_limit) { |
| 2058 ASSERT(limit_validity() != NULL); | 2058 DCHECK(limit_validity() != NULL); |
| 2059 if (limit_validity() != check->block() && | 2059 if (limit_validity() != check->block() && |
| 2060 !limit_validity()->Dominates(check->block())) return; | 2060 !limit_validity()->Dominates(check->block())) return; |
| 2061 if (!phi()->block()->current_loop()->IsNestedInThisLoop( | 2061 if (!phi()->block()->current_loop()->IsNestedInThisLoop( |
| 2062 check->block()->current_loop())) return; | 2062 check->block()->current_loop())) return; |
| 2063 | 2063 |
| 2064 ChecksRelatedToLength* length_checks = checks(); | 2064 ChecksRelatedToLength* length_checks = checks(); |
| 2065 while (length_checks != NULL) { | 2065 while (length_checks != NULL) { |
| 2066 if (length_checks->length() == check->length()) break; | 2066 if (length_checks->length() == check->length()) break; |
| 2067 length_checks = length_checks->next(); | 2067 length_checks = length_checks->next(); |
| 2068 } | 2068 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 2086 } | 2086 } |
| 2087 } | 2087 } |
| 2088 } | 2088 } |
| 2089 | 2089 |
| 2090 | 2090 |
| 2091 void InductionVariableData::ChecksRelatedToLength::UseNewIndexInCurrentBlock( | 2091 void InductionVariableData::ChecksRelatedToLength::UseNewIndexInCurrentBlock( |
| 2092 Token::Value token, | 2092 Token::Value token, |
| 2093 int32_t mask, | 2093 int32_t mask, |
| 2094 HValue* index_base, | 2094 HValue* index_base, |
| 2095 HValue* context) { | 2095 HValue* context) { |
| 2096 ASSERT(first_check_in_block() != NULL); | 2096 DCHECK(first_check_in_block() != NULL); |
| 2097 HValue* previous_index = first_check_in_block()->index(); | 2097 HValue* previous_index = first_check_in_block()->index(); |
| 2098 ASSERT(context != NULL); | 2098 DCHECK(context != NULL); |
| 2099 | 2099 |
| 2100 Zone* zone = index_base->block()->graph()->zone(); | 2100 Zone* zone = index_base->block()->graph()->zone(); |
| 2101 set_added_constant(HConstant::New(zone, context, mask)); | 2101 set_added_constant(HConstant::New(zone, context, mask)); |
| 2102 if (added_index() != NULL) { | 2102 if (added_index() != NULL) { |
| 2103 added_constant()->InsertBefore(added_index()); | 2103 added_constant()->InsertBefore(added_index()); |
| 2104 } else { | 2104 } else { |
| 2105 added_constant()->InsertBefore(first_check_in_block()); | 2105 added_constant()->InsertBefore(first_check_in_block()); |
| 2106 } | 2106 } |
| 2107 | 2107 |
| 2108 if (added_index() == NULL) { | 2108 if (added_index() == NULL) { |
| 2109 first_check_in_block()->ReplaceAllUsesWith(first_check_in_block()->index()); | 2109 first_check_in_block()->ReplaceAllUsesWith(first_check_in_block()->index()); |
| 2110 HInstruction* new_index = HBitwise::New(zone, context, token, index_base, | 2110 HInstruction* new_index = HBitwise::New(zone, context, token, index_base, |
| 2111 added_constant()); | 2111 added_constant()); |
| 2112 ASSERT(new_index->IsBitwise()); | 2112 DCHECK(new_index->IsBitwise()); |
| 2113 new_index->ClearAllSideEffects(); | 2113 new_index->ClearAllSideEffects(); |
| 2114 new_index->AssumeRepresentation(Representation::Integer32()); | 2114 new_index->AssumeRepresentation(Representation::Integer32()); |
| 2115 set_added_index(HBitwise::cast(new_index)); | 2115 set_added_index(HBitwise::cast(new_index)); |
| 2116 added_index()->InsertBefore(first_check_in_block()); | 2116 added_index()->InsertBefore(first_check_in_block()); |
| 2117 } | 2117 } |
| 2118 ASSERT(added_index()->op() == token); | 2118 DCHECK(added_index()->op() == token); |
| 2119 | 2119 |
| 2120 added_index()->SetOperandAt(1, index_base); | 2120 added_index()->SetOperandAt(1, index_base); |
| 2121 added_index()->SetOperandAt(2, added_constant()); | 2121 added_index()->SetOperandAt(2, added_constant()); |
| 2122 first_check_in_block()->SetOperandAt(0, added_index()); | 2122 first_check_in_block()->SetOperandAt(0, added_index()); |
| 2123 if (previous_index->HasNoUses()) { | 2123 if (previous_index->HasNoUses()) { |
| 2124 previous_index->DeleteAndReplaceWith(NULL); | 2124 previous_index->DeleteAndReplaceWith(NULL); |
| 2125 } | 2125 } |
| 2126 } | 2126 } |
| 2127 | 2127 |
| 2128 void InductionVariableData::ChecksRelatedToLength::AddCheck( | 2128 void InductionVariableData::ChecksRelatedToLength::AddCheck( |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2218 | 2218 |
| 2219 | 2219 |
| 2220 /* | 2220 /* |
| 2221 * Swaps the information in "update" with the one contained in "this". | 2221 * Swaps the information in "update" with the one contained in "this". |
| 2222 * The swapping is important because this method is used while doing a | 2222 * The swapping is important because this method is used while doing a |
| 2223 * dominator tree traversal, and "update" will retain the old data that | 2223 * dominator tree traversal, and "update" will retain the old data that |
| 2224 * will be restored while backtracking. | 2224 * will be restored while backtracking. |
| 2225 */ | 2225 */ |
| 2226 void InductionVariableData::UpdateAdditionalLimit( | 2226 void InductionVariableData::UpdateAdditionalLimit( |
| 2227 InductionVariableLimitUpdate* update) { | 2227 InductionVariableLimitUpdate* update) { |
| 2228 ASSERT(update->updated_variable == this); | 2228 DCHECK(update->updated_variable == this); |
| 2229 if (update->limit_is_upper) { | 2229 if (update->limit_is_upper) { |
| 2230 swap(&additional_upper_limit_, &update->limit); | 2230 swap(&additional_upper_limit_, &update->limit); |
| 2231 swap(&additional_upper_limit_is_included_, &update->limit_is_included); | 2231 swap(&additional_upper_limit_is_included_, &update->limit_is_included); |
| 2232 } else { | 2232 } else { |
| 2233 swap(&additional_lower_limit_, &update->limit); | 2233 swap(&additional_lower_limit_, &update->limit); |
| 2234 swap(&additional_lower_limit_is_included_, &update->limit_is_included); | 2234 swap(&additional_lower_limit_is_included_, &update->limit_is_included); |
| 2235 } | 2235 } |
| 2236 } | 2236 } |
| 2237 | 2237 |
| 2238 | 2238 |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2349 | 2349 |
| 2350 Token::Value token = branch->token(); | 2350 Token::Value token = branch->token(); |
| 2351 if (!Token::IsArithmeticCompareOp(token)) return; | 2351 if (!Token::IsArithmeticCompareOp(token)) return; |
| 2352 | 2352 |
| 2353 HBasicBlock* other_target; | 2353 HBasicBlock* other_target; |
| 2354 if (block == branch->SuccessorAt(0)) { | 2354 if (block == branch->SuccessorAt(0)) { |
| 2355 other_target = branch->SuccessorAt(1); | 2355 other_target = branch->SuccessorAt(1); |
| 2356 } else { | 2356 } else { |
| 2357 other_target = branch->SuccessorAt(0); | 2357 other_target = branch->SuccessorAt(0); |
| 2358 token = Token::NegateCompareOp(token); | 2358 token = Token::NegateCompareOp(token); |
| 2359 ASSERT(block == branch->SuccessorAt(1)); | 2359 DCHECK(block == branch->SuccessorAt(1)); |
| 2360 } | 2360 } |
| 2361 | 2361 |
| 2362 InductionVariableData* data; | 2362 InductionVariableData* data; |
| 2363 | 2363 |
| 2364 data = GetInductionVariableData(branch->left()); | 2364 data = GetInductionVariableData(branch->left()); |
| 2365 HValue* limit = branch->right(); | 2365 HValue* limit = branch->right(); |
| 2366 if (data == NULL) { | 2366 if (data == NULL) { |
| 2367 data = GetInductionVariableData(branch->right()); | 2367 data = GetInductionVariableData(branch->right()); |
| 2368 token = Token::ReverseCompareOp(token); | 2368 token = Token::ReverseCompareOp(token); |
| 2369 limit = branch->left(); | 2369 limit = branch->left(); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2414 | 2414 |
| 2415 | 2415 |
| 2416 Range* HMathMinMax::InferRange(Zone* zone) { | 2416 Range* HMathMinMax::InferRange(Zone* zone) { |
| 2417 if (representation().IsSmiOrInteger32()) { | 2417 if (representation().IsSmiOrInteger32()) { |
| 2418 Range* a = left()->range(); | 2418 Range* a = left()->range(); |
| 2419 Range* b = right()->range(); | 2419 Range* b = right()->range(); |
| 2420 Range* res = a->Copy(zone); | 2420 Range* res = a->Copy(zone); |
| 2421 if (operation_ == kMathMax) { | 2421 if (operation_ == kMathMax) { |
| 2422 res->CombinedMax(b); | 2422 res->CombinedMax(b); |
| 2423 } else { | 2423 } else { |
| 2424 ASSERT(operation_ == kMathMin); | 2424 DCHECK(operation_ == kMathMin); |
| 2425 res->CombinedMin(b); | 2425 res->CombinedMin(b); |
| 2426 } | 2426 } |
| 2427 return res; | 2427 return res; |
| 2428 } else { | 2428 } else { |
| 2429 return HValue::InferRange(zone); | 2429 return HValue::InferRange(zone); |
| 2430 } | 2430 } |
| 2431 } | 2431 } |
| 2432 | 2432 |
| 2433 | 2433 |
| 2434 void HPushArguments::AddInput(HValue* value) { | 2434 void HPushArguments::AddInput(HValue* value) { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2474 int count = OperandCount(); | 2474 int count = OperandCount(); |
| 2475 int position = 0; | 2475 int position = 0; |
| 2476 while (position < count && candidate == NULL) { | 2476 while (position < count && candidate == NULL) { |
| 2477 HValue* current = OperandAt(position++); | 2477 HValue* current = OperandAt(position++); |
| 2478 if (current != this) candidate = current; | 2478 if (current != this) candidate = current; |
| 2479 } | 2479 } |
| 2480 while (position < count) { | 2480 while (position < count) { |
| 2481 HValue* current = OperandAt(position++); | 2481 HValue* current = OperandAt(position++); |
| 2482 if (current != this && current != candidate) return NULL; | 2482 if (current != this && current != candidate) return NULL; |
| 2483 } | 2483 } |
| 2484 ASSERT(candidate != this); | 2484 DCHECK(candidate != this); |
| 2485 return candidate; | 2485 return candidate; |
| 2486 } | 2486 } |
| 2487 | 2487 |
| 2488 | 2488 |
| 2489 void HPhi::DeleteFromGraph() { | 2489 void HPhi::DeleteFromGraph() { |
| 2490 ASSERT(block() != NULL); | 2490 DCHECK(block() != NULL); |
| 2491 block()->RemovePhi(this); | 2491 block()->RemovePhi(this); |
| 2492 ASSERT(block() == NULL); | 2492 DCHECK(block() == NULL); |
| 2493 } | 2493 } |
| 2494 | 2494 |
| 2495 | 2495 |
| 2496 void HPhi::InitRealUses(int phi_id) { | 2496 void HPhi::InitRealUses(int phi_id) { |
| 2497 // Initialize real uses. | 2497 // Initialize real uses. |
| 2498 phi_id_ = phi_id; | 2498 phi_id_ = phi_id; |
| 2499 // Compute a conservative approximation of truncating uses before inferring | 2499 // Compute a conservative approximation of truncating uses before inferring |
| 2500 // representations. The proper, exact computation will be done later, when | 2500 // representations. The proper, exact computation will be done later, when |
| 2501 // inserting representation changes. | 2501 // inserting representation changes. |
| 2502 SetFlag(kTruncatingToSmi); | 2502 SetFlag(kTruncatingToSmi); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2583 os << NameOf(values_[i]); | 2583 os << NameOf(values_[i]); |
| 2584 if (i > 0) os << ","; | 2584 if (i > 0) os << ","; |
| 2585 } | 2585 } |
| 2586 } | 2586 } |
| 2587 return os; | 2587 return os; |
| 2588 } | 2588 } |
| 2589 | 2589 |
| 2590 | 2590 |
| 2591 void HSimulate::ReplayEnvironment(HEnvironment* env) { | 2591 void HSimulate::ReplayEnvironment(HEnvironment* env) { |
| 2592 if (done_with_replay_) return; | 2592 if (done_with_replay_) return; |
| 2593 ASSERT(env != NULL); | 2593 DCHECK(env != NULL); |
| 2594 env->set_ast_id(ast_id()); | 2594 env->set_ast_id(ast_id()); |
| 2595 env->Drop(pop_count()); | 2595 env->Drop(pop_count()); |
| 2596 for (int i = values()->length() - 1; i >= 0; --i) { | 2596 for (int i = values()->length() - 1; i >= 0; --i) { |
| 2597 HValue* value = values()->at(i); | 2597 HValue* value = values()->at(i); |
| 2598 if (HasAssignedIndexAt(i)) { | 2598 if (HasAssignedIndexAt(i)) { |
| 2599 env->Bind(GetAssignedIndexAt(i), value); | 2599 env->Bind(GetAssignedIndexAt(i), value); |
| 2600 } else { | 2600 } else { |
| 2601 env->Push(value); | 2601 env->Push(value); |
| 2602 } | 2602 } |
| 2603 } | 2603 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2616 ReplayEnvironmentNested(HCapturedObject::cast(value)->values(), other); | 2616 ReplayEnvironmentNested(HCapturedObject::cast(value)->values(), other); |
| 2617 } | 2617 } |
| 2618 } | 2618 } |
| 2619 } | 2619 } |
| 2620 } | 2620 } |
| 2621 | 2621 |
| 2622 | 2622 |
| 2623 // Replay captured objects by replacing all captured objects with the | 2623 // Replay captured objects by replacing all captured objects with the |
| 2624 // same capture id in the current and all outer environments. | 2624 // same capture id in the current and all outer environments. |
| 2625 void HCapturedObject::ReplayEnvironment(HEnvironment* env) { | 2625 void HCapturedObject::ReplayEnvironment(HEnvironment* env) { |
| 2626 ASSERT(env != NULL); | 2626 DCHECK(env != NULL); |
| 2627 while (env != NULL) { | 2627 while (env != NULL) { |
| 2628 ReplayEnvironmentNested(env->values(), this); | 2628 ReplayEnvironmentNested(env->values(), this); |
| 2629 env = env->outer(); | 2629 env = env->outer(); |
| 2630 } | 2630 } |
| 2631 } | 2631 } |
| 2632 | 2632 |
| 2633 | 2633 |
| 2634 OStream& HCapturedObject::PrintDataTo(OStream& os) const { // NOLINT | 2634 OStream& HCapturedObject::PrintDataTo(OStream& os) const { // NOLINT |
| 2635 os << "#" << capture_id() << " "; | 2635 os << "#" << capture_id() << " "; |
| 2636 return HDematerializedObject::PrintDataTo(os); | 2636 return HDematerializedObject::PrintDataTo(os); |
| 2637 } | 2637 } |
| 2638 | 2638 |
| 2639 | 2639 |
| 2640 void HEnterInlined::RegisterReturnTarget(HBasicBlock* return_target, | 2640 void HEnterInlined::RegisterReturnTarget(HBasicBlock* return_target, |
| 2641 Zone* zone) { | 2641 Zone* zone) { |
| 2642 ASSERT(return_target->IsInlineReturnTarget()); | 2642 DCHECK(return_target->IsInlineReturnTarget()); |
| 2643 return_targets_.Add(return_target, zone); | 2643 return_targets_.Add(return_target, zone); |
| 2644 } | 2644 } |
| 2645 | 2645 |
| 2646 | 2646 |
| 2647 OStream& HEnterInlined::PrintDataTo(OStream& os) const { // NOLINT | 2647 OStream& HEnterInlined::PrintDataTo(OStream& os) const { // NOLINT |
| 2648 return os << function()->debug_name()->ToCString().get() | 2648 return os << function()->debug_name()->ToCString().get() |
| 2649 << ", id=" << function()->id().ToInt(); | 2649 << ", id=" << function()->id().ToInt(); |
| 2650 } | 2650 } |
| 2651 | 2651 |
| 2652 | 2652 |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2708 object_map_(object_map), | 2708 object_map_(object_map), |
| 2709 has_stable_map_value_(has_stable_map_value), | 2709 has_stable_map_value_(has_stable_map_value), |
| 2710 has_smi_value_(false), | 2710 has_smi_value_(false), |
| 2711 has_int32_value_(false), | 2711 has_int32_value_(false), |
| 2712 has_double_value_(false), | 2712 has_double_value_(false), |
| 2713 has_external_reference_value_(false), | 2713 has_external_reference_value_(false), |
| 2714 is_not_in_new_space_(is_not_in_new_space), | 2714 is_not_in_new_space_(is_not_in_new_space), |
| 2715 boolean_value_(boolean_value), | 2715 boolean_value_(boolean_value), |
| 2716 is_undetectable_(is_undetectable), | 2716 is_undetectable_(is_undetectable), |
| 2717 instance_type_(instance_type) { | 2717 instance_type_(instance_type) { |
| 2718 ASSERT(!object.handle().is_null()); | 2718 DCHECK(!object.handle().is_null()); |
| 2719 ASSERT(!type.IsTaggedNumber() || type.IsNone()); | 2719 DCHECK(!type.IsTaggedNumber() || type.IsNone()); |
| 2720 Initialize(r); | 2720 Initialize(r); |
| 2721 } | 2721 } |
| 2722 | 2722 |
| 2723 | 2723 |
| 2724 HConstant::HConstant(int32_t integer_value, | 2724 HConstant::HConstant(int32_t integer_value, |
| 2725 Representation r, | 2725 Representation r, |
| 2726 bool is_not_in_new_space, | 2726 bool is_not_in_new_space, |
| 2727 Unique<Object> object) | 2727 Unique<Object> object) |
| 2728 : object_(object), | 2728 : object_(object), |
| 2729 object_map_(Handle<Map>::null()), | 2729 object_map_(Handle<Map>::null()), |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2825 if (has_double_value_) { | 2825 if (has_double_value_) { |
| 2826 if (IsSpecialDouble()) { | 2826 if (IsSpecialDouble()) { |
| 2827 return true; | 2827 return true; |
| 2828 } | 2828 } |
| 2829 return false; | 2829 return false; |
| 2830 } | 2830 } |
| 2831 if (has_external_reference_value_) { | 2831 if (has_external_reference_value_) { |
| 2832 return false; | 2832 return false; |
| 2833 } | 2833 } |
| 2834 | 2834 |
| 2835 ASSERT(!object_.handle().is_null()); | 2835 DCHECK(!object_.handle().is_null()); |
| 2836 Heap* heap = isolate()->heap(); | 2836 Heap* heap = isolate()->heap(); |
| 2837 ASSERT(!object_.IsKnownGlobal(heap->minus_zero_value())); | 2837 DCHECK(!object_.IsKnownGlobal(heap->minus_zero_value())); |
| 2838 ASSERT(!object_.IsKnownGlobal(heap->nan_value())); | 2838 DCHECK(!object_.IsKnownGlobal(heap->nan_value())); |
| 2839 return | 2839 return |
| 2840 #define IMMORTAL_IMMOVABLE_ROOT(name) \ | 2840 #define IMMORTAL_IMMOVABLE_ROOT(name) \ |
| 2841 object_.IsKnownGlobal(heap->name()) || | 2841 object_.IsKnownGlobal(heap->name()) || |
| 2842 IMMORTAL_IMMOVABLE_ROOT_LIST(IMMORTAL_IMMOVABLE_ROOT) | 2842 IMMORTAL_IMMOVABLE_ROOT_LIST(IMMORTAL_IMMOVABLE_ROOT) |
| 2843 #undef IMMORTAL_IMMOVABLE_ROOT | 2843 #undef IMMORTAL_IMMOVABLE_ROOT |
| 2844 #define INTERNALIZED_STRING(name, value) \ | 2844 #define INTERNALIZED_STRING(name, value) \ |
| 2845 object_.IsKnownGlobal(heap->name()) || | 2845 object_.IsKnownGlobal(heap->name()) || |
| 2846 INTERNALIZED_STRING_LIST(INTERNALIZED_STRING) | 2846 INTERNALIZED_STRING_LIST(INTERNALIZED_STRING) |
| 2847 #undef INTERNALIZED_STRING | 2847 #undef INTERNALIZED_STRING |
| 2848 #define STRING_TYPE(NAME, size, name, Name) \ | 2848 #define STRING_TYPE(NAME, size, name, Name) \ |
| 2849 object_.IsKnownGlobal(heap->name##_map()) || | 2849 object_.IsKnownGlobal(heap->name##_map()) || |
| 2850 STRING_TYPE_LIST(STRING_TYPE) | 2850 STRING_TYPE_LIST(STRING_TYPE) |
| 2851 #undef STRING_TYPE | 2851 #undef STRING_TYPE |
| 2852 false; | 2852 false; |
| 2853 } | 2853 } |
| 2854 | 2854 |
| 2855 | 2855 |
| 2856 bool HConstant::EmitAtUses() { | 2856 bool HConstant::EmitAtUses() { |
| 2857 ASSERT(IsLinked()); | 2857 DCHECK(IsLinked()); |
| 2858 if (block()->graph()->has_osr() && | 2858 if (block()->graph()->has_osr() && |
| 2859 block()->graph()->IsStandardConstant(this)) { | 2859 block()->graph()->IsStandardConstant(this)) { |
| 2860 // TODO(titzer): this seems like a hack that should be fixed by custom OSR. | 2860 // TODO(titzer): this seems like a hack that should be fixed by custom OSR. |
| 2861 return true; | 2861 return true; |
| 2862 } | 2862 } |
| 2863 if (HasNoUses()) return true; | 2863 if (HasNoUses()) return true; |
| 2864 if (IsCell()) return false; | 2864 if (IsCell()) return false; |
| 2865 if (representation().IsDouble()) return false; | 2865 if (representation().IsDouble()) return false; |
| 2866 if (representation().IsExternal()) return false; | 2866 if (representation().IsExternal()) return false; |
| 2867 return true; | 2867 return true; |
| 2868 } | 2868 } |
| 2869 | 2869 |
| 2870 | 2870 |
| 2871 HConstant* HConstant::CopyToRepresentation(Representation r, Zone* zone) const { | 2871 HConstant* HConstant::CopyToRepresentation(Representation r, Zone* zone) const { |
| 2872 if (r.IsSmi() && !has_smi_value_) return NULL; | 2872 if (r.IsSmi() && !has_smi_value_) return NULL; |
| 2873 if (r.IsInteger32() && !has_int32_value_) return NULL; | 2873 if (r.IsInteger32() && !has_int32_value_) return NULL; |
| 2874 if (r.IsDouble() && !has_double_value_) return NULL; | 2874 if (r.IsDouble() && !has_double_value_) return NULL; |
| 2875 if (r.IsExternal() && !has_external_reference_value_) return NULL; | 2875 if (r.IsExternal() && !has_external_reference_value_) return NULL; |
| 2876 if (has_int32_value_) { | 2876 if (has_int32_value_) { |
| 2877 return new(zone) HConstant(int32_value_, r, is_not_in_new_space_, object_); | 2877 return new(zone) HConstant(int32_value_, r, is_not_in_new_space_, object_); |
| 2878 } | 2878 } |
| 2879 if (has_double_value_) { | 2879 if (has_double_value_) { |
| 2880 return new(zone) HConstant(double_value_, r, is_not_in_new_space_, object_); | 2880 return new(zone) HConstant(double_value_, r, is_not_in_new_space_, object_); |
| 2881 } | 2881 } |
| 2882 if (has_external_reference_value_) { | 2882 if (has_external_reference_value_) { |
| 2883 return new(zone) HConstant(external_reference_value_); | 2883 return new(zone) HConstant(external_reference_value_); |
| 2884 } | 2884 } |
| 2885 ASSERT(!object_.handle().is_null()); | 2885 DCHECK(!object_.handle().is_null()); |
| 2886 return new(zone) HConstant(object_, | 2886 return new(zone) HConstant(object_, |
| 2887 object_map_, | 2887 object_map_, |
| 2888 has_stable_map_value_, | 2888 has_stable_map_value_, |
| 2889 r, | 2889 r, |
| 2890 type_, | 2890 type_, |
| 2891 is_not_in_new_space_, | 2891 is_not_in_new_space_, |
| 2892 boolean_value_, | 2892 boolean_value_, |
| 2893 is_undetectable_, | 2893 is_undetectable_, |
| 2894 instance_type_); | 2894 instance_type_); |
| 2895 } | 2895 } |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2948 | 2948 |
| 2949 OStream& HBinaryOperation::PrintDataTo(OStream& os) const { // NOLINT | 2949 OStream& HBinaryOperation::PrintDataTo(OStream& os) const { // NOLINT |
| 2950 os << NameOf(left()) << " " << NameOf(right()); | 2950 os << NameOf(left()) << " " << NameOf(right()); |
| 2951 if (CheckFlag(kCanOverflow)) os << " !"; | 2951 if (CheckFlag(kCanOverflow)) os << " !"; |
| 2952 if (CheckFlag(kBailoutOnMinusZero)) os << " -0?"; | 2952 if (CheckFlag(kBailoutOnMinusZero)) os << " -0?"; |
| 2953 return os; | 2953 return os; |
| 2954 } | 2954 } |
| 2955 | 2955 |
| 2956 | 2956 |
| 2957 void HBinaryOperation::InferRepresentation(HInferRepresentationPhase* h_infer) { | 2957 void HBinaryOperation::InferRepresentation(HInferRepresentationPhase* h_infer) { |
| 2958 ASSERT(CheckFlag(kFlexibleRepresentation)); | 2958 DCHECK(CheckFlag(kFlexibleRepresentation)); |
| 2959 Representation new_rep = RepresentationFromInputs(); | 2959 Representation new_rep = RepresentationFromInputs(); |
| 2960 UpdateRepresentation(new_rep, h_infer, "inputs"); | 2960 UpdateRepresentation(new_rep, h_infer, "inputs"); |
| 2961 | 2961 |
| 2962 if (representation().IsSmi() && HasNonSmiUse()) { | 2962 if (representation().IsSmi() && HasNonSmiUse()) { |
| 2963 UpdateRepresentation( | 2963 UpdateRepresentation( |
| 2964 Representation::Integer32(), h_infer, "use requirements"); | 2964 Representation::Integer32(), h_infer, "use requirements"); |
| 2965 } | 2965 } |
| 2966 | 2966 |
| 2967 if (observed_output_representation_.IsNone()) { | 2967 if (observed_output_representation_.IsNone()) { |
| 2968 new_rep = RepresentationFromUses(); | 2968 new_rep = RepresentationFromUses(); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3015 | 3015 |
| 3016 | 3016 |
| 3017 void HBinaryOperation::AssumeRepresentation(Representation r) { | 3017 void HBinaryOperation::AssumeRepresentation(Representation r) { |
| 3018 set_observed_input_representation(1, r); | 3018 set_observed_input_representation(1, r); |
| 3019 set_observed_input_representation(2, r); | 3019 set_observed_input_representation(2, r); |
| 3020 HValue::AssumeRepresentation(r); | 3020 HValue::AssumeRepresentation(r); |
| 3021 } | 3021 } |
| 3022 | 3022 |
| 3023 | 3023 |
| 3024 void HMathMinMax::InferRepresentation(HInferRepresentationPhase* h_infer) { | 3024 void HMathMinMax::InferRepresentation(HInferRepresentationPhase* h_infer) { |
| 3025 ASSERT(CheckFlag(kFlexibleRepresentation)); | 3025 DCHECK(CheckFlag(kFlexibleRepresentation)); |
| 3026 Representation new_rep = RepresentationFromInputs(); | 3026 Representation new_rep = RepresentationFromInputs(); |
| 3027 UpdateRepresentation(new_rep, h_infer, "inputs"); | 3027 UpdateRepresentation(new_rep, h_infer, "inputs"); |
| 3028 // Do not care about uses. | 3028 // Do not care about uses. |
| 3029 } | 3029 } |
| 3030 | 3030 |
| 3031 | 3031 |
| 3032 Range* HBitwise::InferRange(Zone* zone) { | 3032 Range* HBitwise::InferRange(Zone* zone) { |
| 3033 if (op() == Token::BIT_XOR) { | 3033 if (op() == Token::BIT_XOR) { |
| 3034 if (left()->HasRange() && right()->HasRange()) { | 3034 if (left()->HasRange() && right()->HasRange()) { |
| 3035 // The maximum value has the high bit, and all bits below, set: | 3035 // The maximum value has the high bit, and all bits below, set: |
| (...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3399 OStream& HLoadNamedGeneric::PrintDataTo(OStream& os) const { // NOLINT | 3399 OStream& HLoadNamedGeneric::PrintDataTo(OStream& os) const { // NOLINT |
| 3400 Handle<String> n = Handle<String>::cast(name()); | 3400 Handle<String> n = Handle<String>::cast(name()); |
| 3401 return os << NameOf(object()) << "." << n->ToCString().get(); | 3401 return os << NameOf(object()) << "." << n->ToCString().get(); |
| 3402 } | 3402 } |
| 3403 | 3403 |
| 3404 | 3404 |
| 3405 OStream& HLoadKeyed::PrintDataTo(OStream& os) const { // NOLINT | 3405 OStream& HLoadKeyed::PrintDataTo(OStream& os) const { // NOLINT |
| 3406 if (!is_external()) { | 3406 if (!is_external()) { |
| 3407 os << NameOf(elements()); | 3407 os << NameOf(elements()); |
| 3408 } else { | 3408 } else { |
| 3409 ASSERT(elements_kind() >= FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND && | 3409 DCHECK(elements_kind() >= FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND && |
| 3410 elements_kind() <= LAST_EXTERNAL_ARRAY_ELEMENTS_KIND); | 3410 elements_kind() <= LAST_EXTERNAL_ARRAY_ELEMENTS_KIND); |
| 3411 os << NameOf(elements()) << "." << ElementsKindToString(elements_kind()); | 3411 os << NameOf(elements()) << "." << ElementsKindToString(elements_kind()); |
| 3412 } | 3412 } |
| 3413 | 3413 |
| 3414 os << "[" << NameOf(key()); | 3414 os << "[" << NameOf(key()); |
| 3415 if (IsDehoisted()) os << " + " << base_offset(); | 3415 if (IsDehoisted()) os << " + " << base_offset(); |
| 3416 os << "]"; | 3416 os << "]"; |
| 3417 | 3417 |
| 3418 if (HasDependency()) os << " " << NameOf(dependency()); | 3418 if (HasDependency()) os << " " << NameOf(dependency()); |
| 3419 if (RequiresHoleCheck()) os << " check_hole"; | 3419 if (RequiresHoleCheck()) os << " check_hole"; |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3544 if (NeedsWriteBarrier()) os << " (write-barrier)"; | 3544 if (NeedsWriteBarrier()) os << " (write-barrier)"; |
| 3545 if (has_transition()) os << " (transition map " << *transition_map() << ")"; | 3545 if (has_transition()) os << " (transition map " << *transition_map() << ")"; |
| 3546 return os; | 3546 return os; |
| 3547 } | 3547 } |
| 3548 | 3548 |
| 3549 | 3549 |
| 3550 OStream& HStoreKeyed::PrintDataTo(OStream& os) const { // NOLINT | 3550 OStream& HStoreKeyed::PrintDataTo(OStream& os) const { // NOLINT |
| 3551 if (!is_external()) { | 3551 if (!is_external()) { |
| 3552 os << NameOf(elements()); | 3552 os << NameOf(elements()); |
| 3553 } else { | 3553 } else { |
| 3554 ASSERT(elements_kind() >= FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND && | 3554 DCHECK(elements_kind() >= FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND && |
| 3555 elements_kind() <= LAST_EXTERNAL_ARRAY_ELEMENTS_KIND); | 3555 elements_kind() <= LAST_EXTERNAL_ARRAY_ELEMENTS_KIND); |
| 3556 os << NameOf(elements()) << "." << ElementsKindToString(elements_kind()); | 3556 os << NameOf(elements()) << "." << ElementsKindToString(elements_kind()); |
| 3557 } | 3557 } |
| 3558 | 3558 |
| 3559 os << "[" << NameOf(key()); | 3559 os << "[" << NameOf(key()); |
| 3560 if (IsDehoisted()) os << " + " << base_offset(); | 3560 if (IsDehoisted()) os << " + " << base_offset(); |
| 3561 return os << "] = " << NameOf(value()); | 3561 return os << "] = " << NameOf(value()); |
| 3562 } | 3562 } |
| 3563 | 3563 |
| 3564 | 3564 |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3667 Representation input_rep = value()->representation(); | 3667 Representation input_rep = value()->representation(); |
| 3668 if (!input_rep.IsTagged()) { | 3668 if (!input_rep.IsTagged()) { |
| 3669 rep = rep.generalize(input_rep); | 3669 rep = rep.generalize(input_rep); |
| 3670 } | 3670 } |
| 3671 return rep; | 3671 return rep; |
| 3672 } | 3672 } |
| 3673 | 3673 |
| 3674 | 3674 |
| 3675 bool HAllocate::HandleSideEffectDominator(GVNFlag side_effect, | 3675 bool HAllocate::HandleSideEffectDominator(GVNFlag side_effect, |
| 3676 HValue* dominator) { | 3676 HValue* dominator) { |
| 3677 ASSERT(side_effect == kNewSpacePromotion); | 3677 DCHECK(side_effect == kNewSpacePromotion); |
| 3678 Zone* zone = block()->zone(); | 3678 Zone* zone = block()->zone(); |
| 3679 if (!FLAG_use_allocation_folding) return false; | 3679 if (!FLAG_use_allocation_folding) return false; |
| 3680 | 3680 |
| 3681 // Try to fold allocations together with their dominating allocations. | 3681 // Try to fold allocations together with their dominating allocations. |
| 3682 if (!dominator->IsAllocate()) { | 3682 if (!dominator->IsAllocate()) { |
| 3683 if (FLAG_trace_allocation_folding) { | 3683 if (FLAG_trace_allocation_folding) { |
| 3684 PrintF("#%d (%s) cannot fold into #%d (%s)\n", | 3684 PrintF("#%d (%s) cannot fold into #%d (%s)\n", |
| 3685 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); | 3685 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); |
| 3686 } | 3686 } |
| 3687 return false; | 3687 return false; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3720 PrintF("#%d (%s) cannot fold into #%d (%s), " | 3720 PrintF("#%d (%s) cannot fold into #%d (%s), " |
| 3721 "can't estimate total allocation size\n", | 3721 "can't estimate total allocation size\n", |
| 3722 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); | 3722 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); |
| 3723 } | 3723 } |
| 3724 return false; | 3724 return false; |
| 3725 } | 3725 } |
| 3726 | 3726 |
| 3727 if (!current_size->IsInteger32Constant()) { | 3727 if (!current_size->IsInteger32Constant()) { |
| 3728 // If it's not constant then it is a size_in_bytes calculation graph | 3728 // If it's not constant then it is a size_in_bytes calculation graph |
| 3729 // like this: (const_header_size + const_element_size * size). | 3729 // like this: (const_header_size + const_element_size * size). |
| 3730 ASSERT(current_size->IsInstruction()); | 3730 DCHECK(current_size->IsInstruction()); |
| 3731 | 3731 |
| 3732 HInstruction* current_instr = HInstruction::cast(current_size); | 3732 HInstruction* current_instr = HInstruction::cast(current_size); |
| 3733 if (!current_instr->Dominates(dominator_allocate)) { | 3733 if (!current_instr->Dominates(dominator_allocate)) { |
| 3734 if (FLAG_trace_allocation_folding) { | 3734 if (FLAG_trace_allocation_folding) { |
| 3735 PrintF("#%d (%s) cannot fold into #%d (%s), dynamic size " | 3735 PrintF("#%d (%s) cannot fold into #%d (%s), dynamic size " |
| 3736 "value does not dominate target allocation\n", | 3736 "value does not dominate target allocation\n", |
| 3737 id(), Mnemonic(), dominator_allocate->id(), | 3737 id(), Mnemonic(), dominator_allocate->id(), |
| 3738 dominator_allocate->Mnemonic()); | 3738 dominator_allocate->Mnemonic()); |
| 3739 } | 3739 } |
| 3740 return false; | 3740 return false; |
| 3741 } | 3741 } |
| 3742 } | 3742 } |
| 3743 | 3743 |
| 3744 ASSERT((IsNewSpaceAllocation() && | 3744 DCHECK((IsNewSpaceAllocation() && |
| 3745 dominator_allocate->IsNewSpaceAllocation()) || | 3745 dominator_allocate->IsNewSpaceAllocation()) || |
| 3746 (IsOldDataSpaceAllocation() && | 3746 (IsOldDataSpaceAllocation() && |
| 3747 dominator_allocate->IsOldDataSpaceAllocation()) || | 3747 dominator_allocate->IsOldDataSpaceAllocation()) || |
| 3748 (IsOldPointerSpaceAllocation() && | 3748 (IsOldPointerSpaceAllocation() && |
| 3749 dominator_allocate->IsOldPointerSpaceAllocation())); | 3749 dominator_allocate->IsOldPointerSpaceAllocation())); |
| 3750 | 3750 |
| 3751 // First update the size of the dominator allocate instruction. | 3751 // First update the size of the dominator allocate instruction. |
| 3752 dominator_size = dominator_allocate->size(); | 3752 dominator_size = dominator_allocate->size(); |
| 3753 int32_t original_object_size = | 3753 int32_t original_object_size = |
| 3754 HConstant::cast(dominator_size)->GetInteger32Constant(); | 3754 HConstant::cast(dominator_size)->GetInteger32Constant(); |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3882 // allocation as soon as we have store elimination. | 3882 // allocation as soon as we have store elimination. |
| 3883 if (block()->block_id() != dominator_dominator->block()->block_id()) { | 3883 if (block()->block_id() != dominator_dominator->block()->block_id()) { |
| 3884 if (FLAG_trace_allocation_folding) { | 3884 if (FLAG_trace_allocation_folding) { |
| 3885 PrintF("#%d (%s) cannot fold into #%d (%s), different basic blocks\n", | 3885 PrintF("#%d (%s) cannot fold into #%d (%s), different basic blocks\n", |
| 3886 id(), Mnemonic(), dominator_dominator->id(), | 3886 id(), Mnemonic(), dominator_dominator->id(), |
| 3887 dominator_dominator->Mnemonic()); | 3887 dominator_dominator->Mnemonic()); |
| 3888 } | 3888 } |
| 3889 return NULL; | 3889 return NULL; |
| 3890 } | 3890 } |
| 3891 | 3891 |
| 3892 ASSERT((IsOldDataSpaceAllocation() && | 3892 DCHECK((IsOldDataSpaceAllocation() && |
| 3893 dominator_dominator->IsOldDataSpaceAllocation()) || | 3893 dominator_dominator->IsOldDataSpaceAllocation()) || |
| 3894 (IsOldPointerSpaceAllocation() && | 3894 (IsOldPointerSpaceAllocation() && |
| 3895 dominator_dominator->IsOldPointerSpaceAllocation())); | 3895 dominator_dominator->IsOldPointerSpaceAllocation())); |
| 3896 | 3896 |
| 3897 int32_t current_size = HConstant::cast(size())->GetInteger32Constant(); | 3897 int32_t current_size = HConstant::cast(size())->GetInteger32Constant(); |
| 3898 HStoreNamedField* dominator_free_space_size = | 3898 HStoreNamedField* dominator_free_space_size = |
| 3899 dominator->filler_free_space_size_; | 3899 dominator->filler_free_space_size_; |
| 3900 if (dominator_free_space_size != NULL) { | 3900 if (dominator_free_space_size != NULL) { |
| 3901 // We already hoisted one old space allocation, i.e., we already installed | 3901 // We already hoisted one old space allocation, i.e., we already installed |
| 3902 // a filler map. Hence, we just have to update the free space size. | 3902 // a filler map. Hence, we just have to update the free space size. |
| 3903 dominator->UpdateFreeSpaceFiller(current_size); | 3903 dominator->UpdateFreeSpaceFiller(current_size); |
| 3904 } else { | 3904 } else { |
| 3905 // This is the first old space allocation that gets hoisted. We have to | 3905 // This is the first old space allocation that gets hoisted. We have to |
| 3906 // install a filler map since the follwing allocation may cause a GC. | 3906 // install a filler map since the follwing allocation may cause a GC. |
| 3907 dominator->CreateFreeSpaceFiller(current_size); | 3907 dominator->CreateFreeSpaceFiller(current_size); |
| 3908 } | 3908 } |
| 3909 | 3909 |
| 3910 // We can hoist the old space allocation over the actual dominator. | 3910 // We can hoist the old space allocation over the actual dominator. |
| 3911 return dominator_dominator; | 3911 return dominator_dominator; |
| 3912 } | 3912 } |
| 3913 return dominator; | 3913 return dominator; |
| 3914 } | 3914 } |
| 3915 | 3915 |
| 3916 | 3916 |
| 3917 void HAllocate::UpdateFreeSpaceFiller(int32_t free_space_size) { | 3917 void HAllocate::UpdateFreeSpaceFiller(int32_t free_space_size) { |
| 3918 ASSERT(filler_free_space_size_ != NULL); | 3918 DCHECK(filler_free_space_size_ != NULL); |
| 3919 Zone* zone = block()->zone(); | 3919 Zone* zone = block()->zone(); |
| 3920 // We must explicitly force Smi representation here because on x64 we | 3920 // We must explicitly force Smi representation here because on x64 we |
| 3921 // would otherwise automatically choose int32, but the actual store | 3921 // would otherwise automatically choose int32, but the actual store |
| 3922 // requires a Smi-tagged value. | 3922 // requires a Smi-tagged value. |
| 3923 HConstant* new_free_space_size = HConstant::CreateAndInsertBefore( | 3923 HConstant* new_free_space_size = HConstant::CreateAndInsertBefore( |
| 3924 zone, | 3924 zone, |
| 3925 context(), | 3925 context(), |
| 3926 filler_free_space_size_->value()->GetInteger32Constant() + | 3926 filler_free_space_size_->value()->GetInteger32Constant() + |
| 3927 free_space_size, | 3927 free_space_size, |
| 3928 Representation::Smi(), | 3928 Representation::Smi(), |
| 3929 filler_free_space_size_); | 3929 filler_free_space_size_); |
| 3930 filler_free_space_size_->UpdateValue(new_free_space_size); | 3930 filler_free_space_size_->UpdateValue(new_free_space_size); |
| 3931 } | 3931 } |
| 3932 | 3932 |
| 3933 | 3933 |
| 3934 void HAllocate::CreateFreeSpaceFiller(int32_t free_space_size) { | 3934 void HAllocate::CreateFreeSpaceFiller(int32_t free_space_size) { |
| 3935 ASSERT(filler_free_space_size_ == NULL); | 3935 DCHECK(filler_free_space_size_ == NULL); |
| 3936 Zone* zone = block()->zone(); | 3936 Zone* zone = block()->zone(); |
| 3937 HInstruction* free_space_instr = | 3937 HInstruction* free_space_instr = |
| 3938 HInnerAllocatedObject::New(zone, context(), dominating_allocate_, | 3938 HInnerAllocatedObject::New(zone, context(), dominating_allocate_, |
| 3939 dominating_allocate_->size(), type()); | 3939 dominating_allocate_->size(), type()); |
| 3940 free_space_instr->InsertBefore(this); | 3940 free_space_instr->InsertBefore(this); |
| 3941 HConstant* filler_map = HConstant::CreateAndInsertAfter( | 3941 HConstant* filler_map = HConstant::CreateAndInsertAfter( |
| 3942 zone, Unique<Map>::CreateImmovable( | 3942 zone, Unique<Map>::CreateImmovable( |
| 3943 isolate()->factory()->free_space_map()), true, free_space_instr); | 3943 isolate()->factory()->free_space_map()), true, free_space_instr); |
| 3944 HInstruction* store_map = HStoreNamedField::New(zone, context(), | 3944 HInstruction* store_map = HStoreNamedField::New(zone, context(), |
| 3945 free_space_instr, HObjectAccess::ForMap(), filler_map); | 3945 free_space_instr, HObjectAccess::ForMap(), filler_map); |
| (...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4403 HValue* context, | 4403 HValue* context, |
| 4404 String::Encoding encoding, | 4404 String::Encoding encoding, |
| 4405 HValue* string, | 4405 HValue* string, |
| 4406 HValue* index) { | 4406 HValue* index) { |
| 4407 if (FLAG_fold_constants && string->IsConstant() && index->IsConstant()) { | 4407 if (FLAG_fold_constants && string->IsConstant() && index->IsConstant()) { |
| 4408 HConstant* c_string = HConstant::cast(string); | 4408 HConstant* c_string = HConstant::cast(string); |
| 4409 HConstant* c_index = HConstant::cast(index); | 4409 HConstant* c_index = HConstant::cast(index); |
| 4410 if (c_string->HasStringValue() && c_index->HasInteger32Value()) { | 4410 if (c_string->HasStringValue() && c_index->HasInteger32Value()) { |
| 4411 Handle<String> s = c_string->StringValue(); | 4411 Handle<String> s = c_string->StringValue(); |
| 4412 int32_t i = c_index->Integer32Value(); | 4412 int32_t i = c_index->Integer32Value(); |
| 4413 ASSERT_LE(0, i); | 4413 DCHECK_LE(0, i); |
| 4414 ASSERT_LT(i, s->length()); | 4414 DCHECK_LT(i, s->length()); |
| 4415 return H_CONSTANT_INT(s->Get(i)); | 4415 return H_CONSTANT_INT(s->Get(i)); |
| 4416 } | 4416 } |
| 4417 } | 4417 } |
| 4418 return new(zone) HSeqStringGetChar(encoding, string, index); | 4418 return new(zone) HSeqStringGetChar(encoding, string, index); |
| 4419 } | 4419 } |
| 4420 | 4420 |
| 4421 | 4421 |
| 4422 #undef H_CONSTANT_INT | 4422 #undef H_CONSTANT_INT |
| 4423 #undef H_CONSTANT_DOUBLE | 4423 #undef H_CONSTANT_DOUBLE |
| 4424 | 4424 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4459 HValue* use = it.value(); | 4459 HValue* use = it.value(); |
| 4460 if (use->IsBinaryOperation()) { | 4460 if (use->IsBinaryOperation()) { |
| 4461 HBinaryOperation::cast(use)->set_observed_input_representation( | 4461 HBinaryOperation::cast(use)->set_observed_input_representation( |
| 4462 it.index(), Representation::Smi()); | 4462 it.index(), Representation::Smi()); |
| 4463 } | 4463 } |
| 4464 } | 4464 } |
| 4465 } | 4465 } |
| 4466 | 4466 |
| 4467 | 4467 |
| 4468 void HPhi::InferRepresentation(HInferRepresentationPhase* h_infer) { | 4468 void HPhi::InferRepresentation(HInferRepresentationPhase* h_infer) { |
| 4469 ASSERT(CheckFlag(kFlexibleRepresentation)); | 4469 DCHECK(CheckFlag(kFlexibleRepresentation)); |
| 4470 Representation new_rep = RepresentationFromInputs(); | 4470 Representation new_rep = RepresentationFromInputs(); |
| 4471 UpdateRepresentation(new_rep, h_infer, "inputs"); | 4471 UpdateRepresentation(new_rep, h_infer, "inputs"); |
| 4472 new_rep = RepresentationFromUses(); | 4472 new_rep = RepresentationFromUses(); |
| 4473 UpdateRepresentation(new_rep, h_infer, "uses"); | 4473 UpdateRepresentation(new_rep, h_infer, "uses"); |
| 4474 new_rep = RepresentationFromUseRequirements(); | 4474 new_rep = RepresentationFromUseRequirements(); |
| 4475 UpdateRepresentation(new_rep, h_infer, "use requirements"); | 4475 UpdateRepresentation(new_rep, h_infer, "use requirements"); |
| 4476 } | 4476 } |
| 4477 | 4477 |
| 4478 | 4478 |
| 4479 Representation HPhi::RepresentationFromInputs() { | 4479 Representation HPhi::RepresentationFromInputs() { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4523 } | 4523 } |
| 4524 } | 4524 } |
| 4525 return false; | 4525 return false; |
| 4526 } | 4526 } |
| 4527 | 4527 |
| 4528 | 4528 |
| 4529 // Node-specific verification code is only included in debug mode. | 4529 // Node-specific verification code is only included in debug mode. |
| 4530 #ifdef DEBUG | 4530 #ifdef DEBUG |
| 4531 | 4531 |
| 4532 void HPhi::Verify() { | 4532 void HPhi::Verify() { |
| 4533 ASSERT(OperandCount() == block()->predecessors()->length()); | 4533 DCHECK(OperandCount() == block()->predecessors()->length()); |
| 4534 for (int i = 0; i < OperandCount(); ++i) { | 4534 for (int i = 0; i < OperandCount(); ++i) { |
| 4535 HValue* value = OperandAt(i); | 4535 HValue* value = OperandAt(i); |
| 4536 HBasicBlock* defining_block = value->block(); | 4536 HBasicBlock* defining_block = value->block(); |
| 4537 HBasicBlock* predecessor_block = block()->predecessors()->at(i); | 4537 HBasicBlock* predecessor_block = block()->predecessors()->at(i); |
| 4538 ASSERT(defining_block == predecessor_block || | 4538 DCHECK(defining_block == predecessor_block || |
| 4539 defining_block->Dominates(predecessor_block)); | 4539 defining_block->Dominates(predecessor_block)); |
| 4540 } | 4540 } |
| 4541 } | 4541 } |
| 4542 | 4542 |
| 4543 | 4543 |
| 4544 void HSimulate::Verify() { | 4544 void HSimulate::Verify() { |
| 4545 HInstruction::Verify(); | 4545 HInstruction::Verify(); |
| 4546 ASSERT(HasAstId() || next()->IsEnterInlined()); | 4546 DCHECK(HasAstId() || next()->IsEnterInlined()); |
| 4547 } | 4547 } |
| 4548 | 4548 |
| 4549 | 4549 |
| 4550 void HCheckHeapObject::Verify() { | 4550 void HCheckHeapObject::Verify() { |
| 4551 HInstruction::Verify(); | 4551 HInstruction::Verify(); |
| 4552 ASSERT(HasNoUses()); | 4552 DCHECK(HasNoUses()); |
| 4553 } | 4553 } |
| 4554 | 4554 |
| 4555 | 4555 |
| 4556 void HCheckValue::Verify() { | 4556 void HCheckValue::Verify() { |
| 4557 HInstruction::Verify(); | 4557 HInstruction::Verify(); |
| 4558 ASSERT(HasNoUses()); | 4558 DCHECK(HasNoUses()); |
| 4559 } | 4559 } |
| 4560 | 4560 |
| 4561 #endif | 4561 #endif |
| 4562 | 4562 |
| 4563 | 4563 |
| 4564 HObjectAccess HObjectAccess::ForFixedArrayHeader(int offset) { | 4564 HObjectAccess HObjectAccess::ForFixedArrayHeader(int offset) { |
| 4565 ASSERT(offset >= 0); | 4565 DCHECK(offset >= 0); |
| 4566 ASSERT(offset < FixedArray::kHeaderSize); | 4566 DCHECK(offset < FixedArray::kHeaderSize); |
| 4567 if (offset == FixedArray::kLengthOffset) return ForFixedArrayLength(); | 4567 if (offset == FixedArray::kLengthOffset) return ForFixedArrayLength(); |
| 4568 return HObjectAccess(kInobject, offset); | 4568 return HObjectAccess(kInobject, offset); |
| 4569 } | 4569 } |
| 4570 | 4570 |
| 4571 | 4571 |
| 4572 HObjectAccess HObjectAccess::ForMapAndOffset(Handle<Map> map, int offset, | 4572 HObjectAccess HObjectAccess::ForMapAndOffset(Handle<Map> map, int offset, |
| 4573 Representation representation) { | 4573 Representation representation) { |
| 4574 ASSERT(offset >= 0); | 4574 DCHECK(offset >= 0); |
| 4575 Portion portion = kInobject; | 4575 Portion portion = kInobject; |
| 4576 | 4576 |
| 4577 if (offset == JSObject::kElementsOffset) { | 4577 if (offset == JSObject::kElementsOffset) { |
| 4578 portion = kElementsPointer; | 4578 portion = kElementsPointer; |
| 4579 } else if (offset == JSObject::kMapOffset) { | 4579 } else if (offset == JSObject::kMapOffset) { |
| 4580 portion = kMaps; | 4580 portion = kMaps; |
| 4581 } | 4581 } |
| 4582 bool existing_inobject_property = true; | 4582 bool existing_inobject_property = true; |
| 4583 if (!map.is_null()) { | 4583 if (!map.is_null()) { |
| 4584 existing_inobject_property = (offset < | 4584 existing_inobject_property = (offset < |
| (...skipping 19 matching lines...) Expand all Loading... |
| 4604 case AllocationSite::kWeakNextOffset: | 4604 case AllocationSite::kWeakNextOffset: |
| 4605 return HObjectAccess(kInobject, offset, Representation::Tagged()); | 4605 return HObjectAccess(kInobject, offset, Representation::Tagged()); |
| 4606 default: | 4606 default: |
| 4607 UNREACHABLE(); | 4607 UNREACHABLE(); |
| 4608 } | 4608 } |
| 4609 return HObjectAccess(kInobject, offset); | 4609 return HObjectAccess(kInobject, offset); |
| 4610 } | 4610 } |
| 4611 | 4611 |
| 4612 | 4612 |
| 4613 HObjectAccess HObjectAccess::ForContextSlot(int index) { | 4613 HObjectAccess HObjectAccess::ForContextSlot(int index) { |
| 4614 ASSERT(index >= 0); | 4614 DCHECK(index >= 0); |
| 4615 Portion portion = kInobject; | 4615 Portion portion = kInobject; |
| 4616 int offset = Context::kHeaderSize + index * kPointerSize; | 4616 int offset = Context::kHeaderSize + index * kPointerSize; |
| 4617 ASSERT_EQ(offset, Context::SlotOffset(index) + kHeapObjectTag); | 4617 DCHECK_EQ(offset, Context::SlotOffset(index) + kHeapObjectTag); |
| 4618 return HObjectAccess(portion, offset, Representation::Tagged()); | 4618 return HObjectAccess(portion, offset, Representation::Tagged()); |
| 4619 } | 4619 } |
| 4620 | 4620 |
| 4621 | 4621 |
| 4622 HObjectAccess HObjectAccess::ForJSArrayOffset(int offset) { | 4622 HObjectAccess HObjectAccess::ForJSArrayOffset(int offset) { |
| 4623 ASSERT(offset >= 0); | 4623 DCHECK(offset >= 0); |
| 4624 Portion portion = kInobject; | 4624 Portion portion = kInobject; |
| 4625 | 4625 |
| 4626 if (offset == JSObject::kElementsOffset) { | 4626 if (offset == JSObject::kElementsOffset) { |
| 4627 portion = kElementsPointer; | 4627 portion = kElementsPointer; |
| 4628 } else if (offset == JSArray::kLengthOffset) { | 4628 } else if (offset == JSArray::kLengthOffset) { |
| 4629 portion = kArrayLengths; | 4629 portion = kArrayLengths; |
| 4630 } else if (offset == JSObject::kMapOffset) { | 4630 } else if (offset == JSObject::kMapOffset) { |
| 4631 portion = kMaps; | 4631 portion = kMaps; |
| 4632 } | 4632 } |
| 4633 return HObjectAccess(portion, offset); | 4633 return HObjectAccess(portion, offset); |
| 4634 } | 4634 } |
| 4635 | 4635 |
| 4636 | 4636 |
| 4637 HObjectAccess HObjectAccess::ForBackingStoreOffset(int offset, | 4637 HObjectAccess HObjectAccess::ForBackingStoreOffset(int offset, |
| 4638 Representation representation) { | 4638 Representation representation) { |
| 4639 ASSERT(offset >= 0); | 4639 DCHECK(offset >= 0); |
| 4640 return HObjectAccess(kBackingStore, offset, representation, | 4640 return HObjectAccess(kBackingStore, offset, representation, |
| 4641 Handle<String>::null(), false, false); | 4641 Handle<String>::null(), false, false); |
| 4642 } | 4642 } |
| 4643 | 4643 |
| 4644 | 4644 |
| 4645 HObjectAccess HObjectAccess::ForField(Handle<Map> map, | 4645 HObjectAccess HObjectAccess::ForField(Handle<Map> map, |
| 4646 LookupResult* lookup, | 4646 LookupResult* lookup, |
| 4647 Handle<String> name) { | 4647 Handle<String> name) { |
| 4648 ASSERT(lookup->IsField() || lookup->IsTransitionToField()); | 4648 DCHECK(lookup->IsField() || lookup->IsTransitionToField()); |
| 4649 int index; | 4649 int index; |
| 4650 Representation representation; | 4650 Representation representation; |
| 4651 if (lookup->IsField()) { | 4651 if (lookup->IsField()) { |
| 4652 index = lookup->GetLocalFieldIndexFromMap(*map); | 4652 index = lookup->GetLocalFieldIndexFromMap(*map); |
| 4653 representation = lookup->representation(); | 4653 representation = lookup->representation(); |
| 4654 } else { | 4654 } else { |
| 4655 Map* transition = lookup->GetTransitionTarget(); | 4655 Map* transition = lookup->GetTransitionTarget(); |
| 4656 int descriptor = transition->LastAdded(); | 4656 int descriptor = transition->LastAdded(); |
| 4657 index = transition->instance_descriptors()->GetFieldIndex(descriptor) - | 4657 index = transition->instance_descriptors()->GetFieldIndex(descriptor) - |
| 4658 map->inobject_properties(); | 4658 map->inobject_properties(); |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4783 break; | 4783 break; |
| 4784 case HObjectAccess::kExternalMemory: | 4784 case HObjectAccess::kExternalMemory: |
| 4785 os << "[external-memory]"; | 4785 os << "[external-memory]"; |
| 4786 break; | 4786 break; |
| 4787 } | 4787 } |
| 4788 | 4788 |
| 4789 return os << "@" << access.offset(); | 4789 return os << "@" << access.offset(); |
| 4790 } | 4790 } |
| 4791 | 4791 |
| 4792 } } // namespace v8::internal | 4792 } } // namespace v8::internal |
| OLD | NEW |