| 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 |