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 |