OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
443 Verify(); | 443 Verify(); |
444 #endif | 444 #endif |
445 return may_overflow; | 445 return may_overflow; |
446 } | 446 } |
447 | 447 |
448 | 448 |
449 const char* HType::ToString() { | 449 const char* HType::ToString() { |
450 // Note: The c1visualizer syntax for locals allows only a sequence of the | 450 // Note: The c1visualizer syntax for locals allows only a sequence of the |
451 // following characters: A-Za-z0-9_-|: | 451 // following characters: A-Za-z0-9_-|: |
452 switch (type_) { | 452 switch (type_) { |
| 453 case kNone: return "none"; |
453 case kTagged: return "tagged"; | 454 case kTagged: return "tagged"; |
454 case kTaggedPrimitive: return "primitive"; | 455 case kTaggedPrimitive: return "primitive"; |
455 case kTaggedNumber: return "number"; | 456 case kTaggedNumber: return "number"; |
456 case kSmi: return "smi"; | 457 case kSmi: return "smi"; |
457 case kHeapNumber: return "heap-number"; | 458 case kHeapNumber: return "heap-number"; |
458 case kString: return "string"; | 459 case kString: return "string"; |
459 case kBoolean: return "boolean"; | 460 case kBoolean: return "boolean"; |
460 case kNonPrimitive: return "non-primitive"; | 461 case kNonPrimitive: return "non-primitive"; |
461 case kJSArray: return "array"; | 462 case kJSArray: return "array"; |
462 case kJSObject: return "object"; | 463 case kJSObject: return "object"; |
463 case kUninitialized: return "uninitialized"; | |
464 } | 464 } |
465 UNREACHABLE(); | 465 UNREACHABLE(); |
466 return "unreachable"; | 466 return "unreachable"; |
467 } | 467 } |
468 | 468 |
469 | 469 |
470 HType HType::TypeFromValue(Handle<Object> value) { | 470 HType HType::TypeFromValue(Handle<Object> value) { |
471 HType result = HType::Tagged(); | 471 HType result = HType::Tagged(); |
472 if (value->IsSmi()) { | 472 if (value->IsSmi()) { |
473 result = HType::Smi(); | 473 result = HType::Smi(); |
(...skipping 612 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1086 } else { | 1086 } else { |
1087 return; | 1087 return; |
1088 } | 1088 } |
1089 | 1089 |
1090 ReplaceAllUsesWith(index()); | 1090 ReplaceAllUsesWith(index()); |
1091 | 1091 |
1092 HValue* current_index = decomposition.base(); | 1092 HValue* current_index = decomposition.base(); |
1093 int actual_offset = decomposition.offset() + offset(); | 1093 int actual_offset = decomposition.offset() + offset(); |
1094 int actual_scale = decomposition.scale() + scale(); | 1094 int actual_scale = decomposition.scale() + scale(); |
1095 | 1095 |
| 1096 Zone* zone = block()->graph()->zone(); |
| 1097 HValue* context = block()->graph()->GetInvalidContext(); |
1096 if (actual_offset != 0) { | 1098 if (actual_offset != 0) { |
1097 HConstant* add_offset = new(block()->graph()->zone()) HConstant( | 1099 HConstant* add_offset = HConstant::New(zone, context, actual_offset); |
1098 actual_offset, index()->representation()); | |
1099 add_offset->InsertBefore(this); | 1100 add_offset->InsertBefore(this); |
1100 HInstruction* add = HAdd::New(block()->graph()->zone(), | 1101 HInstruction* add = HAdd::New(zone, context, |
1101 block()->graph()->GetInvalidContext(), current_index, add_offset); | 1102 current_index, add_offset); |
1102 add->InsertBefore(this); | 1103 add->InsertBefore(this); |
1103 add->AssumeRepresentation(index()->representation()); | 1104 add->AssumeRepresentation(index()->representation()); |
1104 add->ClearFlag(kCanOverflow); | 1105 add->ClearFlag(kCanOverflow); |
1105 current_index = add; | 1106 current_index = add; |
1106 } | 1107 } |
1107 | 1108 |
1108 if (actual_scale != 0) { | 1109 if (actual_scale != 0) { |
1109 HConstant* sar_scale = new(block()->graph()->zone()) HConstant( | 1110 HConstant* sar_scale = HConstant::New(zone, context, actual_scale); |
1110 actual_scale, index()->representation()); | |
1111 sar_scale->InsertBefore(this); | 1111 sar_scale->InsertBefore(this); |
1112 HInstruction* sar = HSar::New(block()->graph()->zone(), | 1112 HInstruction* sar = HSar::New(zone, context, |
1113 block()->graph()->GetInvalidContext(), current_index, sar_scale); | 1113 current_index, sar_scale); |
1114 sar->InsertBefore(this); | 1114 sar->InsertBefore(this); |
1115 sar->AssumeRepresentation(index()->representation()); | 1115 sar->AssumeRepresentation(index()->representation()); |
1116 current_index = sar; | 1116 current_index = sar; |
1117 } | 1117 } |
1118 | 1118 |
1119 SetOperandAt(0, current_index); | 1119 SetOperandAt(0, current_index); |
1120 | 1120 |
1121 base_ = NULL; | 1121 base_ = NULL; |
1122 offset_ = 0; | 1122 offset_ = 0; |
1123 scale_ = 0; | 1123 scale_ = 0; |
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1610 | 1610 |
1611 // Insert the new values in the graph. | 1611 // Insert the new values in the graph. |
1612 if (new_left->IsInstruction() && | 1612 if (new_left->IsInstruction() && |
1613 !HInstruction::cast(new_left)->IsLinked()) { | 1613 !HInstruction::cast(new_left)->IsLinked()) { |
1614 HInstruction::cast(new_left)->InsertBefore(this); | 1614 HInstruction::cast(new_left)->InsertBefore(this); |
1615 } | 1615 } |
1616 if (new_right->IsInstruction() && | 1616 if (new_right->IsInstruction() && |
1617 !HInstruction::cast(new_right)->IsLinked()) { | 1617 !HInstruction::cast(new_right)->IsLinked()) { |
1618 HInstruction::cast(new_right)->InsertBefore(this); | 1618 HInstruction::cast(new_right)->InsertBefore(this); |
1619 } | 1619 } |
1620 HMathFloorOfDiv* instr = new(block()->zone()) | 1620 HMathFloorOfDiv* instr = |
1621 HMathFloorOfDiv(context(), new_left, new_right); | 1621 HMathFloorOfDiv::New(block()->zone(), context(), new_left, new_right); |
1622 // Replace this HMathFloor instruction by the new HMathFloorOfDiv. | 1622 // Replace this HMathFloor instruction by the new HMathFloorOfDiv. |
1623 instr->InsertBefore(this); | 1623 instr->InsertBefore(this); |
1624 ReplaceAllUsesWith(instr); | 1624 ReplaceAllUsesWith(instr); |
1625 Kill(); | 1625 Kill(); |
1626 // We know the division had no other uses than this HMathFloor. Delete it. | 1626 // We know the division had no other uses than this HMathFloor. Delete it. |
1627 // Dead code elimination will deal with |left| and |right| if | 1627 // Dead code elimination will deal with |left| and |right| if |
1628 // appropriate. | 1628 // appropriate. |
1629 hdiv->DeleteAndReplaceWith(NULL); | 1629 hdiv->DeleteAndReplaceWith(NULL); |
1630 | 1630 |
1631 // Return NULL to remove this instruction from the graph. | 1631 // Return NULL to remove this instruction from the graph. |
1632 return NULL; | 1632 return NULL; |
1633 } | 1633 } |
1634 #endif | 1634 #endif |
1635 } | 1635 } |
1636 return this; | 1636 return this; |
1637 } | 1637 } |
1638 | 1638 |
1639 | 1639 |
1640 HValue* HCheckInstanceType::Canonicalize() { | 1640 HValue* HCheckInstanceType::Canonicalize() { |
1641 if (check_ == IS_STRING && | 1641 if (check_ == IS_STRING && value()->type().IsString()) { |
1642 !value()->type().IsUninitialized() && | 1642 return value(); |
1643 value()->type().IsString()) { | |
1644 return NULL; | |
1645 } | 1643 } |
1646 | 1644 |
1647 if (check_ == IS_INTERNALIZED_STRING && value()->IsConstant()) { | 1645 if (check_ == IS_INTERNALIZED_STRING && value()->IsConstant()) { |
1648 if (HConstant::cast(value())->HasInternalizedStringValue()) return NULL; | 1646 if (HConstant::cast(value())->HasInternalizedStringValue()) { |
| 1647 return value(); |
| 1648 } |
1649 } | 1649 } |
1650 return this; | 1650 return this; |
1651 } | 1651 } |
1652 | 1652 |
1653 | 1653 |
1654 void HCheckInstanceType::GetCheckInterval(InstanceType* first, | 1654 void HCheckInstanceType::GetCheckInterval(InstanceType* first, |
1655 InstanceType* last) { | 1655 InstanceType* last) { |
1656 ASSERT(is_interval_check()); | 1656 ASSERT(is_interval_check()); |
1657 switch (check_) { | 1657 switch (check_) { |
1658 case IS_SPEC_OBJECT: | 1658 case IS_SPEC_OBJECT: |
(...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2130 | 2130 |
2131 void InductionVariableData::ChecksRelatedToLength::UseNewIndexInCurrentBlock( | 2131 void InductionVariableData::ChecksRelatedToLength::UseNewIndexInCurrentBlock( |
2132 Token::Value token, | 2132 Token::Value token, |
2133 int32_t mask, | 2133 int32_t mask, |
2134 HValue* index_base, | 2134 HValue* index_base, |
2135 HValue* context) { | 2135 HValue* context) { |
2136 ASSERT(first_check_in_block() != NULL); | 2136 ASSERT(first_check_in_block() != NULL); |
2137 HValue* previous_index = first_check_in_block()->index(); | 2137 HValue* previous_index = first_check_in_block()->index(); |
2138 ASSERT(context != NULL); | 2138 ASSERT(context != NULL); |
2139 | 2139 |
2140 set_added_constant(new(index_base->block()->graph()->zone()) HConstant( | 2140 Zone* zone = index_base->block()->graph()->zone(); |
2141 mask, index_base->representation())); | 2141 set_added_constant(HConstant::New(zone, context, mask)); |
2142 if (added_index() != NULL) { | 2142 if (added_index() != NULL) { |
2143 added_constant()->InsertBefore(added_index()); | 2143 added_constant()->InsertBefore(added_index()); |
2144 } else { | 2144 } else { |
2145 added_constant()->InsertBefore(first_check_in_block()); | 2145 added_constant()->InsertBefore(first_check_in_block()); |
2146 } | 2146 } |
2147 | 2147 |
2148 if (added_index() == NULL) { | 2148 if (added_index() == NULL) { |
2149 first_check_in_block()->ReplaceAllUsesWith(first_check_in_block()->index()); | 2149 first_check_in_block()->ReplaceAllUsesWith(first_check_in_block()->index()); |
2150 HInstruction* new_index = HBitwise::New( | 2150 HInstruction* new_index = HBitwise::New(zone, context, token, index_base, |
2151 index_base->block()->graph()->zone(), | 2151 added_constant()); |
2152 token, context, index_base, added_constant()); | |
2153 ASSERT(new_index->IsBitwise()); | 2152 ASSERT(new_index->IsBitwise()); |
2154 new_index->ClearAllSideEffects(); | 2153 new_index->ClearAllSideEffects(); |
2155 new_index->AssumeRepresentation(Representation::Integer32()); | 2154 new_index->AssumeRepresentation(Representation::Integer32()); |
2156 set_added_index(HBitwise::cast(new_index)); | 2155 set_added_index(HBitwise::cast(new_index)); |
2157 added_index()->InsertBefore(first_check_in_block()); | 2156 added_index()->InsertBefore(first_check_in_block()); |
2158 } | 2157 } |
2159 ASSERT(added_index()->op() == token); | 2158 ASSERT(added_index()->op() == token); |
2160 | 2159 |
2161 added_index()->SetOperandAt(1, index_base); | 2160 added_index()->SetOperandAt(1, index_base); |
2162 added_index()->SetOperandAt(2, added_constant()); | 2161 added_index()->SetOperandAt(2, added_constant()); |
(...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2641 } | 2640 } |
2642 | 2641 |
2643 | 2642 |
2644 static bool IsInteger32(double value) { | 2643 static bool IsInteger32(double value) { |
2645 double roundtrip_value = static_cast<double>(static_cast<int32_t>(value)); | 2644 double roundtrip_value = static_cast<double>(static_cast<int32_t>(value)); |
2646 return BitCast<int64_t>(roundtrip_value) == BitCast<int64_t>(value); | 2645 return BitCast<int64_t>(roundtrip_value) == BitCast<int64_t>(value); |
2647 } | 2646 } |
2648 | 2647 |
2649 | 2648 |
2650 HConstant::HConstant(Handle<Object> handle, Representation r) | 2649 HConstant::HConstant(Handle<Object> handle, Representation r) |
2651 : handle_(handle), | 2650 : HTemplateInstruction<0>(HType::TypeFromValue(handle)), |
| 2651 handle_(handle), |
2652 unique_id_(), | 2652 unique_id_(), |
2653 has_smi_value_(false), | 2653 has_smi_value_(false), |
2654 has_int32_value_(false), | 2654 has_int32_value_(false), |
2655 has_double_value_(false), | 2655 has_double_value_(false), |
| 2656 has_external_reference_value_(false), |
2656 is_internalized_string_(false), | 2657 is_internalized_string_(false), |
2657 is_not_in_new_space_(true), | 2658 is_not_in_new_space_(true), |
2658 is_cell_(false), | 2659 is_cell_(false), |
2659 boolean_value_(handle->BooleanValue()) { | 2660 boolean_value_(handle->BooleanValue()) { |
2660 if (handle_->IsHeapObject()) { | 2661 if (handle_->IsHeapObject()) { |
2661 Heap* heap = Handle<HeapObject>::cast(handle)->GetHeap(); | 2662 Heap* heap = Handle<HeapObject>::cast(handle)->GetHeap(); |
2662 is_not_in_new_space_ = !heap->InNewSpace(*handle); | 2663 is_not_in_new_space_ = !heap->InNewSpace(*handle); |
2663 } | 2664 } |
2664 if (handle_->IsNumber()) { | 2665 if (handle_->IsNumber()) { |
2665 double n = handle_->Number(); | 2666 double n = handle_->Number(); |
2666 has_int32_value_ = IsInteger32(n); | 2667 has_int32_value_ = IsInteger32(n); |
2667 int32_value_ = DoubleToInt32(n); | 2668 int32_value_ = DoubleToInt32(n); |
2668 has_smi_value_ = has_int32_value_ && Smi::IsValid(int32_value_); | 2669 has_smi_value_ = has_int32_value_ && Smi::IsValid(int32_value_); |
2669 double_value_ = n; | 2670 double_value_ = n; |
2670 has_double_value_ = true; | 2671 has_double_value_ = true; |
2671 } else { | 2672 } else { |
2672 type_from_value_ = HType::TypeFromValue(handle_); | |
2673 is_internalized_string_ = handle_->IsInternalizedString(); | 2673 is_internalized_string_ = handle_->IsInternalizedString(); |
2674 } | 2674 } |
2675 | 2675 |
2676 is_cell_ = !handle_.is_null() && | 2676 is_cell_ = !handle_.is_null() && |
2677 (handle_->IsCell() || handle_->IsPropertyCell()); | 2677 (handle_->IsCell() || handle_->IsPropertyCell()); |
2678 Initialize(r); | 2678 Initialize(r); |
2679 } | 2679 } |
2680 | 2680 |
2681 | 2681 |
2682 HConstant::HConstant(Handle<Object> handle, | 2682 HConstant::HConstant(Handle<Object> handle, |
2683 UniqueValueId unique_id, | 2683 UniqueValueId unique_id, |
2684 Representation r, | 2684 Representation r, |
2685 HType type, | 2685 HType type, |
2686 bool is_internalize_string, | 2686 bool is_internalize_string, |
2687 bool is_not_in_new_space, | 2687 bool is_not_in_new_space, |
2688 bool is_cell, | 2688 bool is_cell, |
2689 bool boolean_value) | 2689 bool boolean_value) |
2690 : handle_(handle), | 2690 : HTemplateInstruction<0>(type), |
2691 unique_id_(unique_id), | 2691 handle_(handle), |
2692 has_smi_value_(false), | 2692 unique_id_(unique_id), |
2693 has_int32_value_(false), | 2693 has_smi_value_(false), |
2694 has_double_value_(false), | 2694 has_int32_value_(false), |
2695 is_internalized_string_(is_internalize_string), | 2695 has_double_value_(false), |
2696 is_not_in_new_space_(is_not_in_new_space), | 2696 has_external_reference_value_(false), |
2697 is_cell_(is_cell), | 2697 is_internalized_string_(is_internalize_string), |
2698 boolean_value_(boolean_value), | 2698 is_not_in_new_space_(is_not_in_new_space), |
2699 type_from_value_(type) { | 2699 is_cell_(is_cell), |
| 2700 boolean_value_(boolean_value) { |
2700 ASSERT(!handle.is_null()); | 2701 ASSERT(!handle.is_null()); |
2701 ASSERT(!type.IsUninitialized()); | |
2702 ASSERT(!type.IsTaggedNumber()); | 2702 ASSERT(!type.IsTaggedNumber()); |
2703 Initialize(r); | 2703 Initialize(r); |
2704 } | 2704 } |
2705 | 2705 |
2706 | 2706 |
2707 HConstant::HConstant(int32_t integer_value, | 2707 HConstant::HConstant(int32_t integer_value, |
2708 Representation r, | 2708 Representation r, |
2709 bool is_not_in_new_space, | 2709 bool is_not_in_new_space, |
2710 Handle<Object> optional_handle) | 2710 Handle<Object> optional_handle) |
2711 : handle_(optional_handle), | 2711 : handle_(optional_handle), |
2712 unique_id_(), | 2712 unique_id_(), |
2713 has_int32_value_(true), | 2713 has_smi_value_(Smi::IsValid(integer_value)), |
2714 has_double_value_(true), | 2714 has_int32_value_(true), |
2715 is_internalized_string_(false), | 2715 has_double_value_(true), |
2716 is_not_in_new_space_(is_not_in_new_space), | 2716 has_external_reference_value_(false), |
2717 is_cell_(false), | 2717 is_internalized_string_(false), |
2718 boolean_value_(integer_value != 0), | 2718 is_not_in_new_space_(is_not_in_new_space), |
2719 int32_value_(integer_value), | 2719 is_cell_(false), |
2720 double_value_(FastI2D(integer_value)) { | 2720 boolean_value_(integer_value != 0), |
2721 has_smi_value_ = Smi::IsValid(int32_value_); | 2721 int32_value_(integer_value), |
| 2722 double_value_(FastI2D(integer_value)) { |
| 2723 set_type(has_smi_value_ ? HType::Smi() : HType::TaggedNumber()); |
2722 Initialize(r); | 2724 Initialize(r); |
2723 } | 2725 } |
2724 | 2726 |
2725 | 2727 |
2726 HConstant::HConstant(double double_value, | 2728 HConstant::HConstant(double double_value, |
2727 Representation r, | 2729 Representation r, |
2728 bool is_not_in_new_space, | 2730 bool is_not_in_new_space, |
2729 Handle<Object> optional_handle) | 2731 Handle<Object> optional_handle) |
2730 : handle_(optional_handle), | 2732 : handle_(optional_handle), |
2731 unique_id_(), | 2733 unique_id_(), |
2732 has_int32_value_(IsInteger32(double_value)), | 2734 has_int32_value_(IsInteger32(double_value)), |
2733 has_double_value_(true), | 2735 has_double_value_(true), |
2734 is_internalized_string_(false), | 2736 has_external_reference_value_(false), |
2735 is_not_in_new_space_(is_not_in_new_space), | 2737 is_internalized_string_(false), |
2736 is_cell_(false), | 2738 is_not_in_new_space_(is_not_in_new_space), |
2737 boolean_value_(double_value != 0 && !std::isnan(double_value)), | 2739 is_cell_(false), |
2738 int32_value_(DoubleToInt32(double_value)), | 2740 boolean_value_(double_value != 0 && !std::isnan(double_value)), |
2739 double_value_(double_value) { | 2741 int32_value_(DoubleToInt32(double_value)), |
| 2742 double_value_(double_value) { |
2740 has_smi_value_ = has_int32_value_ && Smi::IsValid(int32_value_); | 2743 has_smi_value_ = has_int32_value_ && Smi::IsValid(int32_value_); |
| 2744 set_type(has_smi_value_ ? HType::Smi() : HType::TaggedNumber()); |
2741 Initialize(r); | 2745 Initialize(r); |
2742 } | 2746 } |
2743 | 2747 |
2744 | 2748 |
| 2749 HConstant::HConstant(ExternalReference reference) |
| 2750 : HTemplateInstruction<0>(HType::None()), |
| 2751 has_smi_value_(false), |
| 2752 has_int32_value_(false), |
| 2753 has_double_value_(false), |
| 2754 has_external_reference_value_(true), |
| 2755 is_internalized_string_(false), |
| 2756 is_not_in_new_space_(true), |
| 2757 is_cell_(false), |
| 2758 boolean_value_(true), |
| 2759 external_reference_value_(reference) { |
| 2760 Initialize(Representation::External()); |
| 2761 } |
| 2762 |
| 2763 |
2745 void HConstant::Initialize(Representation r) { | 2764 void HConstant::Initialize(Representation r) { |
2746 if (r.IsNone()) { | 2765 if (r.IsNone()) { |
2747 if (has_smi_value_ && kSmiValueSize == 31) { | 2766 if (has_smi_value_ && kSmiValueSize == 31) { |
2748 r = Representation::Smi(); | 2767 r = Representation::Smi(); |
2749 } else if (has_int32_value_) { | 2768 } else if (has_int32_value_) { |
2750 r = Representation::Integer32(); | 2769 r = Representation::Integer32(); |
2751 } else if (has_double_value_) { | 2770 } else if (has_double_value_) { |
2752 r = Representation::Double(); | 2771 r = Representation::Double(); |
| 2772 } else if (has_external_reference_value_) { |
| 2773 r = Representation::External(); |
2753 } else { | 2774 } else { |
2754 r = Representation::Tagged(); | 2775 r = Representation::Tagged(); |
2755 } | 2776 } |
2756 } | 2777 } |
2757 set_representation(r); | 2778 set_representation(r); |
2758 SetFlag(kUseGVN); | 2779 SetFlag(kUseGVN); |
2759 } | 2780 } |
2760 | 2781 |
2761 | 2782 |
2762 bool HConstant::EmitAtUses() { | 2783 bool HConstant::EmitAtUses() { |
2763 ASSERT(IsLinked()); | 2784 ASSERT(IsLinked()); |
2764 if (block()->graph()->has_osr()) { | 2785 if (block()->graph()->has_osr()) { |
2765 return block()->graph()->IsStandardConstant(this); | 2786 return block()->graph()->IsStandardConstant(this); |
2766 } | 2787 } |
2767 if (IsCell()) return false; | 2788 if (IsCell()) return false; |
2768 if (representation().IsDouble()) return false; | 2789 if (representation().IsDouble()) return false; |
2769 return true; | 2790 return true; |
2770 } | 2791 } |
2771 | 2792 |
2772 | 2793 |
2773 HConstant* HConstant::CopyToRepresentation(Representation r, Zone* zone) const { | 2794 HConstant* HConstant::CopyToRepresentation(Representation r, Zone* zone) const { |
2774 if (r.IsSmi() && !has_smi_value_) return NULL; | 2795 if (r.IsSmi() && !has_smi_value_) return NULL; |
2775 if (r.IsInteger32() && !has_int32_value_) return NULL; | 2796 if (r.IsInteger32() && !has_int32_value_) return NULL; |
2776 if (r.IsDouble() && !has_double_value_) return NULL; | 2797 if (r.IsDouble() && !has_double_value_) return NULL; |
| 2798 if (r.IsExternal() && !has_external_reference_value_) return NULL; |
2777 if (has_int32_value_) { | 2799 if (has_int32_value_) { |
2778 return new(zone) HConstant(int32_value_, r, is_not_in_new_space_, handle_); | 2800 return new(zone) HConstant(int32_value_, r, is_not_in_new_space_, handle_); |
2779 } | 2801 } |
2780 if (has_double_value_) { | 2802 if (has_double_value_) { |
2781 return new(zone) HConstant(double_value_, r, is_not_in_new_space_, handle_); | 2803 return new(zone) HConstant(double_value_, r, is_not_in_new_space_, handle_); |
2782 } | 2804 } |
| 2805 if (has_external_reference_value_) { |
| 2806 return new(zone) HConstant(external_reference_value_); |
| 2807 } |
2783 ASSERT(!handle_.is_null()); | 2808 ASSERT(!handle_.is_null()); |
2784 return new(zone) HConstant(handle_, | 2809 return new(zone) HConstant(handle_, |
2785 unique_id_, | 2810 unique_id_, |
2786 r, | 2811 r, |
2787 type_from_value_, | 2812 type_, |
2788 is_internalized_string_, | 2813 is_internalized_string_, |
2789 is_not_in_new_space_, | 2814 is_not_in_new_space_, |
2790 is_cell_, | 2815 is_cell_, |
2791 boolean_value_); | 2816 boolean_value_); |
2792 } | 2817 } |
2793 | 2818 |
2794 | 2819 |
2795 Maybe<HConstant*> HConstant::CopyToTruncatedInt32(Zone* zone) { | 2820 Maybe<HConstant*> HConstant::CopyToTruncatedInt32(Zone* zone) { |
2796 HConstant* res = NULL; | 2821 HConstant* res = NULL; |
2797 if (has_int32_value_) { | 2822 if (has_int32_value_) { |
(...skipping 27 matching lines...) Expand all Loading... |
2825 } | 2850 } |
2826 return Maybe<HConstant*>(res != NULL, res); | 2851 return Maybe<HConstant*>(res != NULL, res); |
2827 } | 2852 } |
2828 | 2853 |
2829 | 2854 |
2830 void HConstant::PrintDataTo(StringStream* stream) { | 2855 void HConstant::PrintDataTo(StringStream* stream) { |
2831 if (has_int32_value_) { | 2856 if (has_int32_value_) { |
2832 stream->Add("%d ", int32_value_); | 2857 stream->Add("%d ", int32_value_); |
2833 } else if (has_double_value_) { | 2858 } else if (has_double_value_) { |
2834 stream->Add("%f ", FmtElm(double_value_)); | 2859 stream->Add("%f ", FmtElm(double_value_)); |
| 2860 } else if (has_external_reference_value_) { |
| 2861 stream->Add("%p ", reinterpret_cast<void*>( |
| 2862 external_reference_value_.address())); |
2835 } else { | 2863 } else { |
2836 handle()->ShortPrint(stream); | 2864 handle()->ShortPrint(stream); |
2837 } | 2865 } |
2838 } | 2866 } |
2839 | 2867 |
2840 | 2868 |
2841 void HBinaryOperation::PrintDataTo(StringStream* stream) { | 2869 void HBinaryOperation::PrintDataTo(StringStream* stream) { |
2842 left()->PrintNameTo(stream); | 2870 left()->PrintNameTo(stream); |
2843 stream->Add(" "); | 2871 stream->Add(" "); |
2844 right()->PrintNameTo(stream); | 2872 right()->PrintNameTo(stream); |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3021 ? left()->range()->Copy(zone) | 3049 ? left()->range()->Copy(zone) |
3022 : new(zone) Range(); | 3050 : new(zone) Range(); |
3023 result->Shl(c->Integer32Value()); | 3051 result->Shl(c->Integer32Value()); |
3024 return result; | 3052 return result; |
3025 } | 3053 } |
3026 } | 3054 } |
3027 return HValue::InferRange(zone); | 3055 return HValue::InferRange(zone); |
3028 } | 3056 } |
3029 | 3057 |
3030 | 3058 |
| 3059 Range* HLoadNamedField::InferRange(Zone* zone) { |
| 3060 if (access().IsStringLength()) { |
| 3061 return new(zone) Range(0, String::kMaxLength); |
| 3062 } |
| 3063 return HValue::InferRange(zone); |
| 3064 } |
| 3065 |
| 3066 |
3031 Range* HLoadKeyed::InferRange(Zone* zone) { | 3067 Range* HLoadKeyed::InferRange(Zone* zone) { |
3032 switch (elements_kind()) { | 3068 switch (elements_kind()) { |
3033 case EXTERNAL_PIXEL_ELEMENTS: | 3069 case EXTERNAL_PIXEL_ELEMENTS: |
3034 return new(zone) Range(0, 255); | 3070 return new(zone) Range(0, 255); |
3035 case EXTERNAL_BYTE_ELEMENTS: | 3071 case EXTERNAL_BYTE_ELEMENTS: |
3036 return new(zone) Range(-128, 127); | 3072 return new(zone) Range(-128, 127); |
3037 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 3073 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
3038 return new(zone) Range(0, 255); | 3074 return new(zone) Range(0, 255); |
3039 case EXTERNAL_SHORT_ELEMENTS: | 3075 case EXTERNAL_SHORT_ELEMENTS: |
3040 return new(zone) Range(-32768, 32767); | 3076 return new(zone) Range(-32768, 32767); |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3253 // We don't have an easy way to handle both a call (to the generic stub) and | 3289 // We don't have an easy way to handle both a call (to the generic stub) and |
3254 // a deopt in the same hydrogen instruction, so in this case we don't add | 3290 // a deopt in the same hydrogen instruction, so in this case we don't add |
3255 // the negative lookups which can deopt - just let the generic stub handle | 3291 // the negative lookups which can deopt - just let the generic stub handle |
3256 // them. | 3292 // them. |
3257 SetAllSideEffects(); | 3293 SetAllSideEffects(); |
3258 need_generic_ = true; | 3294 need_generic_ = true; |
3259 } | 3295 } |
3260 } | 3296 } |
3261 | 3297 |
3262 | 3298 |
3263 HCheckMaps* HCheckMaps::New(HValue* value, | 3299 HCheckMaps* HCheckMaps::New(Zone* zone, |
| 3300 HValue* context, |
| 3301 HValue* value, |
3264 Handle<Map> map, | 3302 Handle<Map> map, |
3265 Zone* zone, | |
3266 CompilationInfo* info, | 3303 CompilationInfo* info, |
3267 HValue* typecheck) { | 3304 HValue* typecheck) { |
3268 HCheckMaps* check_map = new(zone) HCheckMaps(value, zone, typecheck); | 3305 HCheckMaps* check_map = new(zone) HCheckMaps(value, zone, typecheck); |
3269 check_map->map_set_.Add(map, zone); | 3306 check_map->map_set_.Add(map, zone); |
3270 if (map->CanOmitMapChecks() && | 3307 if (map->CanOmitMapChecks() && |
3271 value->IsConstant() && | 3308 value->IsConstant() && |
3272 HConstant::cast(value)->InstanceOf(map)) { | 3309 HConstant::cast(value)->InstanceOf(map)) { |
3273 check_map->omit(info); | 3310 check_map->omit(info); |
3274 } | 3311 } |
3275 return check_map; | 3312 return check_map; |
3276 } | 3313 } |
3277 | 3314 |
3278 | 3315 |
3279 HCheckMaps* HCheckMaps::NewWithTransitions(HValue* value, | |
3280 Handle<Map> map, | |
3281 Zone* zone, | |
3282 CompilationInfo* info) { | |
3283 HCheckMaps* check_map = new(zone) HCheckMaps(value, zone, value); | |
3284 check_map->map_set_.Add(map, zone); | |
3285 | |
3286 // Since transitioned elements maps of the initial map don't fail the map | |
3287 // check, the CheckMaps instruction doesn't need to depend on ElementsKinds. | |
3288 check_map->ClearGVNFlag(kDependsOnElementsKind); | |
3289 | |
3290 ElementsKind kind = map->elements_kind(); | |
3291 bool packed = IsFastPackedElementsKind(kind); | |
3292 while (CanTransitionToMoreGeneralFastElementsKind(kind, packed)) { | |
3293 kind = GetNextMoreGeneralFastElementsKind(kind, packed); | |
3294 Map* transitioned_map = | |
3295 map->LookupElementsTransitionMap(kind); | |
3296 if (transitioned_map) { | |
3297 check_map->map_set_.Add(Handle<Map>(transitioned_map), zone); | |
3298 } | |
3299 }; | |
3300 | |
3301 if (map->CanOmitMapChecks() && | |
3302 value->IsConstant() && | |
3303 HConstant::cast(value)->InstanceOf(map)) { | |
3304 check_map->omit(info); | |
3305 } | |
3306 | |
3307 check_map->map_set_.Sort(); | |
3308 return check_map; | |
3309 } | |
3310 | |
3311 | |
3312 void HCheckMaps::FinalizeUniqueValueId() { | 3316 void HCheckMaps::FinalizeUniqueValueId() { |
3313 if (!map_unique_ids_.is_empty()) return; | 3317 if (!map_unique_ids_.is_empty()) return; |
3314 Zone* zone = block()->zone(); | 3318 Zone* zone = block()->zone(); |
3315 map_unique_ids_.Initialize(map_set_.length(), zone); | 3319 map_unique_ids_.Initialize(map_set_.length(), zone); |
3316 for (int i = 0; i < map_set_.length(); i++) { | 3320 for (int i = 0; i < map_set_.length(); i++) { |
3317 map_unique_ids_.Add(UniqueValueId(map_set_.at(i)), zone); | 3321 map_unique_ids_.Add(UniqueValueId(map_set_.at(i)), zone); |
3318 } | 3322 } |
3319 } | 3323 } |
3320 | 3324 |
3321 | 3325 |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3474 if (key()->IsLoadKeyed()) { | 3478 if (key()->IsLoadKeyed()) { |
3475 HLoadKeyed* key_load = HLoadKeyed::cast(key()); | 3479 HLoadKeyed* key_load = HLoadKeyed::cast(key()); |
3476 if (key_load->elements()->IsForInCacheArray()) { | 3480 if (key_load->elements()->IsForInCacheArray()) { |
3477 HForInCacheArray* names_cache = | 3481 HForInCacheArray* names_cache = |
3478 HForInCacheArray::cast(key_load->elements()); | 3482 HForInCacheArray::cast(key_load->elements()); |
3479 | 3483 |
3480 if (names_cache->enumerable() == object()) { | 3484 if (names_cache->enumerable() == object()) { |
3481 HForInCacheArray* index_cache = | 3485 HForInCacheArray* index_cache = |
3482 names_cache->index_cache(); | 3486 names_cache->index_cache(); |
3483 HCheckMapValue* map_check = | 3487 HCheckMapValue* map_check = |
3484 new(block()->zone()) HCheckMapValue(object(), names_cache->map()); | 3488 HCheckMapValue::New(block()->graph()->zone(), |
3485 HInstruction* index = new(block()->zone()) HLoadKeyed( | 3489 block()->graph()->GetInvalidContext(), |
| 3490 object(), |
| 3491 names_cache->map()); |
| 3492 HInstruction* index = HLoadKeyed::New( |
| 3493 block()->graph()->zone(), |
| 3494 block()->graph()->GetInvalidContext(), |
3486 index_cache, | 3495 index_cache, |
3487 key_load->key(), | 3496 key_load->key(), |
3488 key_load->key(), | 3497 key_load->key(), |
3489 key_load->elements_kind()); | 3498 key_load->elements_kind()); |
3490 map_check->InsertBefore(this); | 3499 map_check->InsertBefore(this); |
3491 index->InsertBefore(this); | 3500 index->InsertBefore(this); |
3492 HLoadFieldByIndex* load = new(block()->zone()) HLoadFieldByIndex( | 3501 HLoadFieldByIndex* load = new(block()->zone()) HLoadFieldByIndex( |
3493 object(), index); | 3502 object(), index); |
3494 load->InsertBefore(this); | 3503 load->InsertBefore(this); |
3495 return load; | 3504 return load; |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3604 if (details_.IsReadOnly()) stream->Add(" (read-only)"); | 3613 if (details_.IsReadOnly()) stream->Add(" (read-only)"); |
3605 } | 3614 } |
3606 | 3615 |
3607 | 3616 |
3608 void HStoreGlobalGeneric::PrintDataTo(StringStream* stream) { | 3617 void HStoreGlobalGeneric::PrintDataTo(StringStream* stream) { |
3609 stream->Add("%o = ", *name()); | 3618 stream->Add("%o = ", *name()); |
3610 value()->PrintNameTo(stream); | 3619 value()->PrintNameTo(stream); |
3611 } | 3620 } |
3612 | 3621 |
3613 | 3622 |
3614 void HLinkObjectInList::PrintDataTo(StringStream* stream) { | |
3615 value()->PrintNameTo(stream); | |
3616 stream->Add(" offset %d", store_field_.offset()); | |
3617 } | |
3618 | |
3619 | |
3620 void HLoadContextSlot::PrintDataTo(StringStream* stream) { | 3623 void HLoadContextSlot::PrintDataTo(StringStream* stream) { |
3621 value()->PrintNameTo(stream); | 3624 value()->PrintNameTo(stream); |
3622 stream->Add("[%d]", slot_index()); | 3625 stream->Add("[%d]", slot_index()); |
3623 } | 3626 } |
3624 | 3627 |
3625 | 3628 |
3626 void HStoreContextSlot::PrintDataTo(StringStream* stream) { | 3629 void HStoreContextSlot::PrintDataTo(StringStream* stream) { |
3627 context()->PrintNameTo(stream); | 3630 context()->PrintNameTo(stream); |
3628 stream->Add("[%d] = ", slot_index()); | 3631 stream->Add("[%d] = ", slot_index()); |
3629 value()->PrintNameTo(stream); | 3632 value()->PrintNameTo(stream); |
3630 } | 3633 } |
3631 | 3634 |
3632 | 3635 |
3633 // Implementation of type inference and type conversions. Calculates | 3636 // Implementation of type inference and type conversions. Calculates |
3634 // the inferred type of this instruction based on the input operands. | 3637 // the inferred type of this instruction based on the input operands. |
3635 | 3638 |
3636 HType HValue::CalculateInferredType() { | 3639 HType HValue::CalculateInferredType() { |
3637 return type_; | 3640 return type_; |
3638 } | 3641 } |
3639 | 3642 |
3640 | 3643 |
3641 HType HCheckMaps::CalculateInferredType() { | |
3642 return value()->type(); | |
3643 } | |
3644 | |
3645 | |
3646 HType HCheckFunction::CalculateInferredType() { | |
3647 return value()->type(); | |
3648 } | |
3649 | |
3650 | |
3651 HType HCheckHeapObject::CalculateInferredType() { | |
3652 return HType::NonPrimitive(); | |
3653 } | |
3654 | |
3655 | |
3656 HType HCheckSmi::CalculateInferredType() { | |
3657 return HType::Smi(); | |
3658 } | |
3659 | |
3660 | |
3661 HType HPhi::CalculateInferredType() { | 3644 HType HPhi::CalculateInferredType() { |
3662 HType result = HType::Uninitialized(); | 3645 if (OperandCount() == 0) return HType::Tagged(); |
3663 for (int i = 0; i < OperandCount(); ++i) { | 3646 HType result = OperandAt(0)->type(); |
| 3647 for (int i = 1; i < OperandCount(); ++i) { |
3664 HType current = OperandAt(i)->type(); | 3648 HType current = OperandAt(i)->type(); |
3665 result = result.Combine(current); | 3649 result = result.Combine(current); |
3666 } | 3650 } |
3667 return result; | 3651 return result; |
3668 } | 3652 } |
3669 | 3653 |
3670 | 3654 |
3671 HType HConstant::CalculateInferredType() { | |
3672 if (has_int32_value_) { | |
3673 return Smi::IsValid(int32_value_) ? HType::Smi() : HType::HeapNumber(); | |
3674 } | |
3675 if (has_double_value_) return HType::HeapNumber(); | |
3676 ASSERT(!type_from_value_.IsUninitialized()); | |
3677 return type_from_value_; | |
3678 } | |
3679 | |
3680 | |
3681 HType HCompareGeneric::CalculateInferredType() { | |
3682 return HType::Boolean(); | |
3683 } | |
3684 | |
3685 | |
3686 HType HInstanceOf::CalculateInferredType() { | |
3687 return HType::Boolean(); | |
3688 } | |
3689 | |
3690 | |
3691 HType HInstanceOfKnownGlobal::CalculateInferredType() { | |
3692 return HType::Boolean(); | |
3693 } | |
3694 | |
3695 | |
3696 HType HChange::CalculateInferredType() { | 3655 HType HChange::CalculateInferredType() { |
3697 if (from().IsDouble() && to().IsTagged()) return HType::HeapNumber(); | 3656 if (from().IsDouble() && to().IsTagged()) return HType::HeapNumber(); |
3698 return type(); | 3657 return type(); |
3699 } | 3658 } |
3700 | 3659 |
3701 | 3660 |
3702 HType HBitwiseBinaryOperation::CalculateInferredType() { | |
3703 return HType::TaggedNumber(); | |
3704 } | |
3705 | |
3706 | |
3707 HType HArithmeticBinaryOperation::CalculateInferredType() { | |
3708 return HType::TaggedNumber(); | |
3709 } | |
3710 | |
3711 | |
3712 HType HAdd::CalculateInferredType() { | |
3713 return HType::Tagged(); | |
3714 } | |
3715 | |
3716 | |
3717 HType HBitNot::CalculateInferredType() { | |
3718 return HType::TaggedNumber(); | |
3719 } | |
3720 | |
3721 | |
3722 HType HUnaryMathOperation::CalculateInferredType() { | |
3723 return HType::TaggedNumber(); | |
3724 } | |
3725 | |
3726 | |
3727 Representation HUnaryMathOperation::RepresentationFromInputs() { | 3661 Representation HUnaryMathOperation::RepresentationFromInputs() { |
3728 Representation rep = representation(); | 3662 Representation rep = representation(); |
3729 // If any of the actual input representation is more general than what we | 3663 // If any of the actual input representation is more general than what we |
3730 // have so far but not Tagged, use that representation instead. | 3664 // have so far but not Tagged, use that representation instead. |
3731 Representation input_rep = value()->representation(); | 3665 Representation input_rep = value()->representation(); |
3732 if (!input_rep.IsTagged()) rep = rep.generalize(input_rep); | 3666 if (!input_rep.IsTagged()) rep = rep.generalize(input_rep); |
3733 return rep; | 3667 return rep; |
3734 } | 3668 } |
3735 | 3669 |
3736 | 3670 |
3737 HType HStringCharFromCode::CalculateInferredType() { | |
3738 return HType::String(); | |
3739 } | |
3740 | |
3741 | |
3742 void HAllocate::HandleSideEffectDominator(GVNFlag side_effect, | 3671 void HAllocate::HandleSideEffectDominator(GVNFlag side_effect, |
3743 HValue* dominator) { | 3672 HValue* dominator) { |
3744 ASSERT(side_effect == kChangesNewSpacePromotion); | 3673 ASSERT(side_effect == kChangesNewSpacePromotion); |
3745 if (!FLAG_use_allocation_folding) return; | 3674 if (!FLAG_use_allocation_folding) return; |
3746 | 3675 |
3747 // Try to fold allocations together with their dominating allocations. | 3676 // Try to fold allocations together with their dominating allocations. |
3748 if (!dominator->IsAllocate()) { | 3677 if (!dominator->IsAllocate()) { |
3749 if (FLAG_trace_allocation_folding) { | 3678 if (FLAG_trace_allocation_folding) { |
3750 PrintF("#%d (%s) cannot fold into #%d (%s)\n", | 3679 PrintF("#%d (%s) cannot fold into #%d (%s)\n", |
3751 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); | 3680 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); |
3752 } | 3681 } |
3753 return; | 3682 return; |
3754 } | 3683 } |
3755 | 3684 |
3756 HAllocate* dominator_allocate_instr = HAllocate::cast(dominator); | 3685 HAllocate* dominator_allocate_instr = HAllocate::cast(dominator); |
3757 HValue* dominator_size = dominator_allocate_instr->size(); | 3686 HValue* dominator_size = dominator_allocate_instr->size(); |
3758 HValue* current_size = size(); | 3687 HValue* current_size = size(); |
3759 // We can just fold allocations that are guaranteed in new space. | 3688 // We can just fold allocations that are guaranteed in new space. |
3760 // TODO(hpayer): Add support for non-constant allocation in dominator. | 3689 // TODO(hpayer): Add support for non-constant allocation in dominator. |
3761 if (!GuaranteedInNewSpace() || !current_size->IsInteger32Constant() || | 3690 if (!IsNewSpaceAllocation() || !current_size->IsInteger32Constant() || |
3762 !dominator_allocate_instr->GuaranteedInNewSpace() || | 3691 !dominator_allocate_instr->IsNewSpaceAllocation() || |
3763 !dominator_size->IsInteger32Constant()) { | 3692 !dominator_size->IsInteger32Constant()) { |
3764 if (FLAG_trace_allocation_folding) { | 3693 if (FLAG_trace_allocation_folding) { |
3765 PrintF("#%d (%s) cannot fold into #%d (%s)\n", | 3694 PrintF("#%d (%s) cannot fold into #%d (%s)\n", |
3766 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); | 3695 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); |
3767 } | 3696 } |
3768 return; | 3697 return; |
3769 } | 3698 } |
3770 | 3699 |
3771 // First update the size of the dominator allocate instruction. | 3700 // First update the size of the dominator allocate instruction. |
3772 int32_t dominator_size_constant = | 3701 int32_t dominator_size_constant = |
3773 HConstant::cast(dominator_size)->GetInteger32Constant(); | 3702 HConstant::cast(dominator_size)->GetInteger32Constant(); |
3774 int32_t current_size_constant = | 3703 int32_t current_size_constant = |
3775 HConstant::cast(current_size)->GetInteger32Constant(); | 3704 HConstant::cast(current_size)->GetInteger32Constant(); |
3776 int32_t new_dominator_size = dominator_size_constant + current_size_constant; | 3705 int32_t new_dominator_size = dominator_size_constant + current_size_constant; |
3777 | 3706 |
3778 if (MustAllocateDoubleAligned()) { | 3707 if (MustAllocateDoubleAligned()) { |
3779 if (!dominator_allocate_instr->MustAllocateDoubleAligned()) { | 3708 if (!dominator_allocate_instr->MustAllocateDoubleAligned()) { |
3780 dominator_allocate_instr->SetFlags(HAllocate::ALLOCATE_DOUBLE_ALIGNED); | 3709 dominator_allocate_instr->MakeDoubleAligned(); |
3781 } | 3710 } |
3782 if ((dominator_size_constant & kDoubleAlignmentMask) != 0) { | 3711 if ((dominator_size_constant & kDoubleAlignmentMask) != 0) { |
3783 dominator_size_constant += kDoubleSize / 2; | 3712 dominator_size_constant += kDoubleSize / 2; |
3784 new_dominator_size += kDoubleSize / 2; | 3713 new_dominator_size += kDoubleSize / 2; |
3785 } | 3714 } |
3786 } | 3715 } |
3787 | 3716 |
3788 if (new_dominator_size > Page::kMaxNonCodeHeapObjectSize) { | 3717 if (new_dominator_size > Page::kMaxNonCodeHeapObjectSize) { |
3789 if (FLAG_trace_allocation_folding) { | 3718 if (FLAG_trace_allocation_folding) { |
3790 PrintF("#%d (%s) cannot fold into #%d (%s) due to size: %d\n", | 3719 PrintF("#%d (%s) cannot fold into #%d (%s) due to size: %d\n", |
3791 id(), Mnemonic(), dominator->id(), dominator->Mnemonic(), | 3720 id(), Mnemonic(), dominator->id(), dominator->Mnemonic(), |
3792 new_dominator_size); | 3721 new_dominator_size); |
3793 } | 3722 } |
3794 return; | 3723 return; |
3795 } | 3724 } |
3796 HBasicBlock* block = dominator->block(); | 3725 HBasicBlock* block = dominator->block(); |
3797 Zone* zone = block->zone(); | 3726 Zone* zone = block->zone(); |
3798 HInstruction* new_dominator_size_constant = new(zone) HConstant( | 3727 HInstruction* new_dominator_size_constant = |
3799 new_dominator_size); | 3728 HConstant::New(zone, context(), new_dominator_size); |
3800 new_dominator_size_constant->InsertBefore(dominator_allocate_instr); | 3729 new_dominator_size_constant->InsertBefore(dominator_allocate_instr); |
3801 dominator_allocate_instr->UpdateSize(new_dominator_size_constant); | 3730 dominator_allocate_instr->UpdateSize(new_dominator_size_constant); |
3802 | 3731 |
3803 #ifdef VERIFY_HEAP | 3732 #ifdef VERIFY_HEAP |
3804 if (FLAG_verify_heap) { | 3733 if (FLAG_verify_heap) { |
3805 dominator_allocate_instr->SetFlags(HAllocate::PREFILL_WITH_FILLER); | 3734 dominator_allocate_instr->MakePrefillWithFiller(); |
3806 } | 3735 } |
3807 #endif | 3736 #endif |
3808 | 3737 |
3809 // After that replace the dominated allocate instruction. | 3738 // After that replace the dominated allocate instruction. |
3810 HInstruction* dominated_allocate_instr = | 3739 HInstruction* dominated_allocate_instr = |
3811 new(zone) HInnerAllocatedObject(dominator_allocate_instr, | 3740 HInnerAllocatedObject::New(zone, |
3812 dominator_size_constant, | 3741 context(), |
3813 type()); | 3742 dominator_allocate_instr, |
| 3743 dominator_size_constant, |
| 3744 type()); |
3814 dominated_allocate_instr->InsertBefore(this); | 3745 dominated_allocate_instr->InsertBefore(this); |
3815 DeleteAndReplaceWith(dominated_allocate_instr); | 3746 DeleteAndReplaceWith(dominated_allocate_instr); |
3816 if (FLAG_trace_allocation_folding) { | 3747 if (FLAG_trace_allocation_folding) { |
3817 PrintF("#%d (%s) folded into #%d (%s)\n", | 3748 PrintF("#%d (%s) folded into #%d (%s)\n", |
3818 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); | 3749 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); |
3819 } | 3750 } |
3820 } | 3751 } |
3821 | 3752 |
3822 | 3753 |
3823 void HAllocate::PrintDataTo(StringStream* stream) { | 3754 void HAllocate::PrintDataTo(StringStream* stream) { |
3824 size()->PrintNameTo(stream); | 3755 size()->PrintNameTo(stream); |
3825 if (!GuaranteedInNewSpace()) stream->Add(" (pretenure)"); | 3756 stream->Add(" ("); |
| 3757 if (IsNewSpaceAllocation()) stream->Add("N"); |
| 3758 if (IsOldPointerSpaceAllocation()) stream->Add("P"); |
| 3759 if (IsOldDataSpaceAllocation()) stream->Add("D"); |
| 3760 if (MustAllocateDoubleAligned()) stream->Add("A"); |
| 3761 if (MustPrefillWithFiller()) stream->Add("F"); |
| 3762 stream->Add(")"); |
3826 } | 3763 } |
3827 | 3764 |
3828 | 3765 |
3829 HType HRegExpLiteral::CalculateInferredType() { | |
3830 return HType::JSObject(); | |
3831 } | |
3832 | |
3833 | |
3834 HType HFunctionLiteral::CalculateInferredType() { | |
3835 return HType::JSObject(); | |
3836 } | |
3837 | |
3838 | |
3839 HValue* HUnaryMathOperation::EnsureAndPropagateNotMinusZero( | 3766 HValue* HUnaryMathOperation::EnsureAndPropagateNotMinusZero( |
3840 BitVector* visited) { | 3767 BitVector* visited) { |
3841 visited->Add(id()); | 3768 visited->Add(id()); |
3842 if (representation().IsSmiOrInteger32() && | 3769 if (representation().IsSmiOrInteger32() && |
3843 !value()->representation().Equals(representation())) { | 3770 !value()->representation().Equals(representation())) { |
3844 if (value()->range() == NULL || value()->range()->CanBeMinusZero()) { | 3771 if (value()->range() == NULL || value()->range()->CanBeMinusZero()) { |
3845 SetFlag(kBailoutOnMinusZero); | 3772 SetFlag(kBailoutOnMinusZero); |
3846 } | 3773 } |
3847 } | 3774 } |
3848 if (RequiredInputRepresentation(0).IsSmiOrInteger32() && | 3775 if (RequiredInputRepresentation(0).IsSmiOrInteger32() && |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3951 return false; | 3878 return false; |
3952 } | 3879 } |
3953 if (HChange::cast(value())->value()->type().IsSmi()) { | 3880 if (HChange::cast(value())->value()->type().IsSmi()) { |
3954 return false; | 3881 return false; |
3955 } | 3882 } |
3956 } | 3883 } |
3957 return true; | 3884 return true; |
3958 } | 3885 } |
3959 | 3886 |
3960 | 3887 |
3961 #define H_CONSTANT_INT(val) \ | 3888 #define H_CONSTANT_INT(val) \ |
3962 new(zone) HConstant(static_cast<int32_t>(val)) | 3889 HConstant::New(zone, context, static_cast<int32_t>(val)) |
3963 #define H_CONSTANT_DOUBLE(val) \ | 3890 #define H_CONSTANT_DOUBLE(val) \ |
3964 new(zone) HConstant(static_cast<double>(val), Representation::Double()) | 3891 HConstant::New(zone, context, static_cast<double>(val)) |
3965 | 3892 |
3966 #define DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HInstr, op) \ | 3893 #define DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HInstr, op) \ |
3967 HInstruction* HInstr::New( \ | 3894 HInstruction* HInstr::New( \ |
3968 Zone* zone, HValue* context, HValue* left, HValue* right) { \ | 3895 Zone* zone, HValue* context, HValue* left, HValue* right) { \ |
3969 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { \ | 3896 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { \ |
3970 HConstant* c_left = HConstant::cast(left); \ | 3897 HConstant* c_left = HConstant::cast(left); \ |
3971 HConstant* c_right = HConstant::cast(right); \ | 3898 HConstant* c_right = HConstant::cast(right); \ |
3972 if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { \ | 3899 if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { \ |
3973 double double_res = c_left->DoubleValue() op c_right->DoubleValue(); \ | 3900 double double_res = c_left->DoubleValue() op c_right->DoubleValue(); \ |
3974 if (TypeInfo::IsInt32Double(double_res)) { \ | 3901 if (TypeInfo::IsInt32Double(double_res)) { \ |
3975 return H_CONSTANT_INT(double_res); \ | 3902 return H_CONSTANT_INT(double_res); \ |
3976 } \ | 3903 } \ |
3977 return H_CONSTANT_DOUBLE(double_res); \ | 3904 return H_CONSTANT_DOUBLE(double_res); \ |
3978 } \ | 3905 } \ |
3979 } \ | 3906 } \ |
3980 return new(zone) HInstr(context, left, right); \ | 3907 return new(zone) HInstr(context, left, right); \ |
3981 } | 3908 } |
3982 | 3909 |
3983 | 3910 |
3984 DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HAdd, +) | 3911 DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HAdd, +) |
3985 DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HMul, *) | 3912 DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HMul, *) |
3986 DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HSub, -) | 3913 DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HSub, -) |
3987 | 3914 |
3988 #undef DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR | 3915 #undef DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR |
3989 | 3916 |
3990 | 3917 |
3991 HInstruction* HStringAdd::New(Zone* zone, | 3918 HInstruction* HStringAdd::New(Zone* zone, |
3992 HValue* context, | 3919 HValue* context, |
3993 HValue* left, | 3920 HValue* left, |
3994 HValue* right, | 3921 HValue* right, |
3995 StringAddFlags flags) { | 3922 StringAddFlags flags) { |
3996 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { | 3923 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { |
3997 HConstant* c_right = HConstant::cast(right); | 3924 HConstant* c_right = HConstant::cast(right); |
3998 HConstant* c_left = HConstant::cast(left); | 3925 HConstant* c_left = HConstant::cast(left); |
3999 if (c_left->HasStringValue() && c_right->HasStringValue()) { | 3926 if (c_left->HasStringValue() && c_right->HasStringValue()) { |
4000 Handle<String> concat = zone->isolate()->factory()->NewFlatConcatString( | 3927 Handle<String> concat = zone->isolate()->factory()->NewFlatConcatString( |
4001 c_left->StringValue(), c_right->StringValue()); | 3928 c_left->StringValue(), c_right->StringValue()); |
4002 return new(zone) HConstant(concat, Representation::Tagged()); | 3929 return HConstant::New(zone, context, concat); |
4003 } | 3930 } |
4004 } | 3931 } |
4005 return new(zone) HStringAdd(context, left, right, flags); | 3932 return new(zone) HStringAdd(context, left, right, flags); |
4006 } | 3933 } |
4007 | 3934 |
4008 | 3935 |
4009 HInstruction* HStringCharFromCode::New( | 3936 HInstruction* HStringCharFromCode::New( |
4010 Zone* zone, HValue* context, HValue* char_code) { | 3937 Zone* zone, HValue* context, HValue* char_code) { |
4011 if (FLAG_fold_constants && char_code->IsConstant()) { | 3938 if (FLAG_fold_constants && char_code->IsConstant()) { |
4012 HConstant* c_code = HConstant::cast(char_code); | 3939 HConstant* c_code = HConstant::cast(char_code); |
4013 Isolate* isolate = Isolate::Current(); | 3940 Isolate* isolate = Isolate::Current(); |
4014 if (c_code->HasNumberValue()) { | 3941 if (c_code->HasNumberValue()) { |
4015 if (std::isfinite(c_code->DoubleValue())) { | 3942 if (std::isfinite(c_code->DoubleValue())) { |
4016 uint32_t code = c_code->NumberValueAsInteger32() & 0xffff; | 3943 uint32_t code = c_code->NumberValueAsInteger32() & 0xffff; |
4017 return new(zone) HConstant(LookupSingleCharacterStringFromCode(isolate, | 3944 return HConstant::New(zone, context, |
4018 code), | 3945 LookupSingleCharacterStringFromCode(isolate, code)); |
4019 Representation::Tagged()); | |
4020 } | 3946 } |
4021 return new(zone) HConstant(isolate->factory()->empty_string(), | 3947 return HConstant::New(zone, context, isolate->factory()->empty_string()); |
4022 Representation::Tagged()); | |
4023 } | 3948 } |
4024 } | 3949 } |
4025 return new(zone) HStringCharFromCode(context, char_code); | 3950 return new(zone) HStringCharFromCode(context, char_code); |
4026 } | 3951 } |
4027 | 3952 |
4028 | 3953 |
4029 HInstruction* HStringLength::New(Zone* zone, HValue* string) { | |
4030 if (FLAG_fold_constants && string->IsConstant()) { | |
4031 HConstant* c_string = HConstant::cast(string); | |
4032 if (c_string->HasStringValue()) { | |
4033 return new(zone) HConstant(c_string->StringValue()->length()); | |
4034 } | |
4035 } | |
4036 return new(zone) HStringLength(string); | |
4037 } | |
4038 | |
4039 | |
4040 HInstruction* HUnaryMathOperation::New( | 3954 HInstruction* HUnaryMathOperation::New( |
4041 Zone* zone, HValue* context, HValue* value, BuiltinFunctionId op) { | 3955 Zone* zone, HValue* context, HValue* value, BuiltinFunctionId op) { |
4042 do { | 3956 do { |
4043 if (!FLAG_fold_constants) break; | 3957 if (!FLAG_fold_constants) break; |
4044 if (!value->IsConstant()) break; | 3958 if (!value->IsConstant()) break; |
4045 HConstant* constant = HConstant::cast(value); | 3959 HConstant* constant = HConstant::cast(value); |
4046 if (!constant->HasNumberValue()) break; | 3960 if (!constant->HasNumberValue()) break; |
4047 double d = constant->DoubleValue(); | 3961 double d = constant->DoubleValue(); |
4048 if (std::isnan(d)) { // NaN poisons everything. | 3962 if (std::isnan(d)) { // NaN poisons everything. |
4049 return H_CONSTANT_DOUBLE(OS::nan_value()); | 3963 return H_CONSTANT_DOUBLE(OS::nan_value()); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4098 return H_CONSTANT_DOUBLE(floor(d)); | 4012 return H_CONSTANT_DOUBLE(floor(d)); |
4099 default: | 4013 default: |
4100 UNREACHABLE(); | 4014 UNREACHABLE(); |
4101 break; | 4015 break; |
4102 } | 4016 } |
4103 } while (false); | 4017 } while (false); |
4104 return new(zone) HUnaryMathOperation(context, value, op); | 4018 return new(zone) HUnaryMathOperation(context, value, op); |
4105 } | 4019 } |
4106 | 4020 |
4107 | 4021 |
4108 HInstruction* HPower::New(Zone* zone, HValue* left, HValue* right) { | 4022 HInstruction* HPower::New(Zone* zone, |
| 4023 HValue* context, |
| 4024 HValue* left, |
| 4025 HValue* right) { |
4109 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { | 4026 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { |
4110 HConstant* c_left = HConstant::cast(left); | 4027 HConstant* c_left = HConstant::cast(left); |
4111 HConstant* c_right = HConstant::cast(right); | 4028 HConstant* c_right = HConstant::cast(right); |
4112 if (c_left->HasNumberValue() && c_right->HasNumberValue()) { | 4029 if (c_left->HasNumberValue() && c_right->HasNumberValue()) { |
4113 double result = power_helper(c_left->DoubleValue(), | 4030 double result = power_helper(c_left->DoubleValue(), |
4114 c_right->DoubleValue()); | 4031 c_right->DoubleValue()); |
4115 return H_CONSTANT_DOUBLE(std::isnan(result) ? OS::nan_value() : result); | 4032 return H_CONSTANT_DOUBLE(std::isnan(result) ? OS::nan_value() : result); |
4116 } | 4033 } |
4117 } | 4034 } |
4118 return new(zone) HPower(left, right); | 4035 return new(zone) HPower(left, right); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4197 Double(c_right->DoubleValue()).Sign(); // Right could be -0. | 4114 Double(c_right->DoubleValue()).Sign(); // Right could be -0. |
4198 return H_CONSTANT_DOUBLE(sign * V8_INFINITY); | 4115 return H_CONSTANT_DOUBLE(sign * V8_INFINITY); |
4199 } | 4116 } |
4200 } | 4117 } |
4201 } | 4118 } |
4202 return new(zone) HDiv(context, left, right); | 4119 return new(zone) HDiv(context, left, right); |
4203 } | 4120 } |
4204 | 4121 |
4205 | 4122 |
4206 HInstruction* HBitwise::New( | 4123 HInstruction* HBitwise::New( |
4207 Zone* zone, Token::Value op, HValue* context, HValue* left, HValue* right) { | 4124 Zone* zone, HValue* context, Token::Value op, HValue* left, HValue* right) { |
4208 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { | 4125 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { |
4209 HConstant* c_left = HConstant::cast(left); | 4126 HConstant* c_left = HConstant::cast(left); |
4210 HConstant* c_right = HConstant::cast(right); | 4127 HConstant* c_right = HConstant::cast(right); |
4211 if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { | 4128 if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { |
4212 int32_t result; | 4129 int32_t result; |
4213 int32_t v_left = c_left->NumberValueAsInteger32(); | 4130 int32_t v_left = c_left->NumberValueAsInteger32(); |
4214 int32_t v_right = c_right->NumberValueAsInteger32(); | 4131 int32_t v_right = c_right->NumberValueAsInteger32(); |
4215 switch (op) { | 4132 switch (op) { |
4216 case Token::BIT_XOR: | 4133 case Token::BIT_XOR: |
4217 result = v_left ^ v_right; | 4134 result = v_left ^ v_right; |
4218 break; | 4135 break; |
4219 case Token::BIT_AND: | 4136 case Token::BIT_AND: |
4220 result = v_left & v_right; | 4137 result = v_left & v_right; |
4221 break; | 4138 break; |
4222 case Token::BIT_OR: | 4139 case Token::BIT_OR: |
4223 result = v_left | v_right; | 4140 result = v_left | v_right; |
4224 break; | 4141 break; |
4225 default: | 4142 default: |
4226 result = 0; // Please the compiler. | 4143 result = 0; // Please the compiler. |
4227 UNREACHABLE(); | 4144 UNREACHABLE(); |
4228 } | 4145 } |
4229 return H_CONSTANT_INT(result); | 4146 return H_CONSTANT_INT(result); |
4230 } | 4147 } |
4231 } | 4148 } |
4232 return new(zone) HBitwise(op, context, left, right); | 4149 return new(zone) HBitwise(context, op, left, right); |
4233 } | 4150 } |
4234 | 4151 |
4235 | 4152 |
4236 #define DEFINE_NEW_H_BITWISE_INSTR(HInstr, result) \ | 4153 #define DEFINE_NEW_H_BITWISE_INSTR(HInstr, result) \ |
4237 HInstruction* HInstr::New( \ | 4154 HInstruction* HInstr::New( \ |
4238 Zone* zone, HValue* context, HValue* left, HValue* right) { \ | 4155 Zone* zone, HValue* context, HValue* left, HValue* right) { \ |
4239 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { \ | 4156 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { \ |
4240 HConstant* c_left = HConstant::cast(left); \ | 4157 HConstant* c_left = HConstant::cast(left); \ |
4241 HConstant* c_right = HConstant::cast(right); \ | 4158 HConstant* c_right = HConstant::cast(right); \ |
4242 if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { \ | 4159 if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { \ |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4291 for (int i = 0; i < OperandCount(); ++i) { | 4208 for (int i = 0; i < OperandCount(); ++i) { |
4292 if (!OperandAt(i)->IsConstant()) return; | 4209 if (!OperandAt(i)->IsConstant()) return; |
4293 } | 4210 } |
4294 HGraph* graph = block()->graph(); | 4211 HGraph* graph = block()->graph(); |
4295 for (int i = 0; i < OperandCount(); ++i) { | 4212 for (int i = 0; i < OperandCount(); ++i) { |
4296 HConstant* operand = HConstant::cast(OperandAt(i)); | 4213 HConstant* operand = HConstant::cast(OperandAt(i)); |
4297 if (operand->HasInteger32Value()) { | 4214 if (operand->HasInteger32Value()) { |
4298 continue; | 4215 continue; |
4299 } else if (operand->HasDoubleValue()) { | 4216 } else if (operand->HasDoubleValue()) { |
4300 HConstant* integer_input = | 4217 HConstant* integer_input = |
4301 new(graph->zone()) HConstant(DoubleToInt32(operand->DoubleValue())); | 4218 HConstant::New(graph->zone(), graph->GetInvalidContext(), |
| 4219 DoubleToInt32(operand->DoubleValue())); |
4302 integer_input->InsertAfter(operand); | 4220 integer_input->InsertAfter(operand); |
4303 SetOperandAt(i, integer_input); | 4221 SetOperandAt(i, integer_input); |
4304 } else if (operand == graph->GetConstantTrue()) { | 4222 } else if (operand == graph->GetConstantTrue()) { |
4305 SetOperandAt(i, graph->GetConstant1()); | 4223 SetOperandAt(i, graph->GetConstant1()); |
4306 } else { | 4224 } else { |
4307 // This catches |false|, |undefined|, strings and objects. | 4225 // This catches |false|, |undefined|, strings and objects. |
4308 SetOperandAt(i, graph->GetConstant0()); | 4226 SetOperandAt(i, graph->GetConstant0()); |
4309 } | 4227 } |
4310 } | 4228 } |
4311 // Overwrite observed input representations because they are likely Tagged. | 4229 // Overwrite observed input representations because they are likely Tagged. |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4360 } | 4278 } |
4361 return rep; | 4279 return rep; |
4362 } | 4280 } |
4363 | 4281 |
4364 | 4282 |
4365 bool HValue::HasNonSmiUse() { | 4283 bool HValue::HasNonSmiUse() { |
4366 for (HUseIterator it(uses()); !it.Done(); it.Advance()) { | 4284 for (HUseIterator it(uses()); !it.Done(); it.Advance()) { |
4367 // We check for observed_input_representation elsewhere. | 4285 // We check for observed_input_representation elsewhere. |
4368 Representation use_rep = | 4286 Representation use_rep = |
4369 it.value()->RequiredInputRepresentation(it.index()); | 4287 it.value()->RequiredInputRepresentation(it.index()); |
4370 if (!use_rep.IsNone() && !use_rep.IsSmi()) return true; | 4288 if (!use_rep.IsNone() && |
| 4289 !use_rep.IsSmi() && |
| 4290 !use_rep.IsTagged()) { |
| 4291 return true; |
| 4292 } |
4371 } | 4293 } |
4372 return false; | 4294 return false; |
4373 } | 4295 } |
4374 | 4296 |
4375 | 4297 |
4376 // Node-specific verification code is only included in debug mode. | 4298 // Node-specific verification code is only included in debug mode. |
4377 #ifdef DEBUG | 4299 #ifdef DEBUG |
4378 | 4300 |
4379 void HPhi::Verify() { | 4301 void HPhi::Verify() { |
4380 ASSERT(OperandCount() == block()->predecessors()->length()); | 4302 ASSERT(OperandCount() == block()->predecessors()->length()); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4499 // try to GVN loads, but don't hoist above map changes | 4421 // try to GVN loads, but don't hoist above map changes |
4500 instr->SetFlag(HValue::kUseGVN); | 4422 instr->SetFlag(HValue::kUseGVN); |
4501 instr->SetGVNFlag(kDependsOnMaps); | 4423 instr->SetGVNFlag(kDependsOnMaps); |
4502 } | 4424 } |
4503 | 4425 |
4504 switch (portion()) { | 4426 switch (portion()) { |
4505 case kArrayLengths: | 4427 case kArrayLengths: |
4506 instr->SetGVNFlag(is_store | 4428 instr->SetGVNFlag(is_store |
4507 ? kChangesArrayLengths : kDependsOnArrayLengths); | 4429 ? kChangesArrayLengths : kDependsOnArrayLengths); |
4508 break; | 4430 break; |
| 4431 case kStringLengths: |
| 4432 instr->SetGVNFlag(is_store |
| 4433 ? kChangesStringLengths : kDependsOnStringLengths); |
| 4434 break; |
4509 case kInobject: | 4435 case kInobject: |
4510 instr->SetGVNFlag(is_store | 4436 instr->SetGVNFlag(is_store |
4511 ? kChangesInobjectFields : kDependsOnInobjectFields); | 4437 ? kChangesInobjectFields : kDependsOnInobjectFields); |
4512 break; | 4438 break; |
4513 case kDouble: | 4439 case kDouble: |
4514 instr->SetGVNFlag(is_store | 4440 instr->SetGVNFlag(is_store |
4515 ? kChangesDoubleFields : kDependsOnDoubleFields); | 4441 ? kChangesDoubleFields : kDependsOnDoubleFields); |
4516 break; | 4442 break; |
4517 case kBackingStore: | 4443 case kBackingStore: |
4518 instr->SetGVNFlag(is_store | 4444 instr->SetGVNFlag(is_store |
4519 ? kChangesBackingStoreFields : kDependsOnBackingStoreFields); | 4445 ? kChangesBackingStoreFields : kDependsOnBackingStoreFields); |
4520 break; | 4446 break; |
4521 case kElementsPointer: | 4447 case kElementsPointer: |
4522 instr->SetGVNFlag(is_store | 4448 instr->SetGVNFlag(is_store |
4523 ? kChangesElementsPointer : kDependsOnElementsPointer); | 4449 ? kChangesElementsPointer : kDependsOnElementsPointer); |
4524 break; | 4450 break; |
4525 case kMaps: | 4451 case kMaps: |
4526 instr->SetGVNFlag(is_store | 4452 instr->SetGVNFlag(is_store |
4527 ? kChangesMaps : kDependsOnMaps); | 4453 ? kChangesMaps : kDependsOnMaps); |
4528 break; | 4454 break; |
| 4455 case kExternalMemory: |
| 4456 instr->SetGVNFlag(is_store |
| 4457 ? kChangesExternalMemory : kDependsOnExternalMemory); |
| 4458 break; |
4529 } | 4459 } |
4530 } | 4460 } |
4531 | 4461 |
4532 | 4462 |
4533 void HObjectAccess::PrintTo(StringStream* stream) { | 4463 void HObjectAccess::PrintTo(StringStream* stream) { |
4534 stream->Add("."); | 4464 stream->Add("."); |
4535 | 4465 |
4536 switch (portion()) { | 4466 switch (portion()) { |
4537 case kArrayLengths: | 4467 case kArrayLengths: |
| 4468 case kStringLengths: |
4538 stream->Add("%length"); | 4469 stream->Add("%length"); |
4539 break; | 4470 break; |
4540 case kElementsPointer: | 4471 case kElementsPointer: |
4541 stream->Add("%elements"); | 4472 stream->Add("%elements"); |
4542 break; | 4473 break; |
4543 case kMaps: | 4474 case kMaps: |
4544 stream->Add("%map"); | 4475 stream->Add("%map"); |
4545 break; | 4476 break; |
4546 case kDouble: // fall through | 4477 case kDouble: // fall through |
4547 case kInobject: | 4478 case kInobject: |
4548 if (!name_.is_null()) stream->Add(*String::cast(*name_)->ToCString()); | 4479 if (!name_.is_null()) stream->Add(*String::cast(*name_)->ToCString()); |
4549 stream->Add("[in-object]"); | 4480 stream->Add("[in-object]"); |
4550 break; | 4481 break; |
4551 case kBackingStore: | 4482 case kBackingStore: |
4552 if (!name_.is_null()) stream->Add(*String::cast(*name_)->ToCString()); | 4483 if (!name_.is_null()) stream->Add(*String::cast(*name_)->ToCString()); |
4553 stream->Add("[backing-store]"); | 4484 stream->Add("[backing-store]"); |
4554 break; | 4485 break; |
| 4486 case kExternalMemory: |
| 4487 stream->Add("[external-memory]"); |
| 4488 break; |
4555 } | 4489 } |
4556 | 4490 |
4557 stream->Add("@%d", offset()); | 4491 stream->Add("@%d", offset()); |
4558 } | 4492 } |
4559 | 4493 |
4560 } } // namespace v8::internal | 4494 } } // namespace v8::internal |
OLD | NEW |