OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
8 #include "src/double.h" | 8 #include "src/double.h" |
9 #include "src/factory.h" | 9 #include "src/factory.h" |
10 #include "src/hydrogen-infer-representation.h" | 10 #include "src/hydrogen-infer-representation.h" |
(...skipping 924 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
935 std::ostream& HUnaryCall::PrintDataTo(std::ostream& os) const { // NOLINT | 935 std::ostream& HUnaryCall::PrintDataTo(std::ostream& os) const { // NOLINT |
936 return os << NameOf(value()) << " #" << argument_count(); | 936 return os << NameOf(value()) << " #" << argument_count(); |
937 } | 937 } |
938 | 938 |
939 | 939 |
940 std::ostream& HCallJSFunction::PrintDataTo(std::ostream& os) const { // NOLINT | 940 std::ostream& HCallJSFunction::PrintDataTo(std::ostream& os) const { // NOLINT |
941 return os << NameOf(function()) << " #" << argument_count(); | 941 return os << NameOf(function()) << " #" << argument_count(); |
942 } | 942 } |
943 | 943 |
944 | 944 |
945 HCallJSFunction* HCallJSFunction::New( | 945 HCallJSFunction* HCallJSFunction::New(Isolate* isolate, Zone* zone, |
946 Zone* zone, | 946 HValue* context, HValue* function, |
947 HValue* context, | 947 int argument_count, |
948 HValue* function, | 948 bool pass_argument_count) { |
949 int argument_count, | |
950 bool pass_argument_count) { | |
951 bool has_stack_check = false; | 949 bool has_stack_check = false; |
952 if (function->IsConstant()) { | 950 if (function->IsConstant()) { |
953 HConstant* fun_const = HConstant::cast(function); | 951 HConstant* fun_const = HConstant::cast(function); |
954 Handle<JSFunction> jsfun = | 952 Handle<JSFunction> jsfun = |
955 Handle<JSFunction>::cast(fun_const->handle(zone->isolate())); | 953 Handle<JSFunction>::cast(fun_const->handle(isolate)); |
956 has_stack_check = !jsfun.is_null() && | 954 has_stack_check = !jsfun.is_null() && |
957 (jsfun->code()->kind() == Code::FUNCTION || | 955 (jsfun->code()->kind() == Code::FUNCTION || |
958 jsfun->code()->kind() == Code::OPTIMIZED_FUNCTION); | 956 jsfun->code()->kind() == Code::OPTIMIZED_FUNCTION); |
959 } | 957 } |
960 | 958 |
961 return new(zone) HCallJSFunction( | 959 return new(zone) HCallJSFunction( |
962 function, argument_count, pass_argument_count, | 960 function, argument_count, pass_argument_count, |
963 has_stack_check); | 961 has_stack_check); |
964 } | 962 } |
965 | 963 |
(...skipping 16 matching lines...) Expand all Loading... |
982 } else { | 980 } else { |
983 return; | 981 return; |
984 } | 982 } |
985 | 983 |
986 ReplaceAllUsesWith(index()); | 984 ReplaceAllUsesWith(index()); |
987 | 985 |
988 HValue* current_index = decomposition.base(); | 986 HValue* current_index = decomposition.base(); |
989 int actual_offset = decomposition.offset() + offset(); | 987 int actual_offset = decomposition.offset() + offset(); |
990 int actual_scale = decomposition.scale() + scale(); | 988 int actual_scale = decomposition.scale() + scale(); |
991 | 989 |
992 Zone* zone = block()->graph()->zone(); | 990 HGraph* graph = block()->graph(); |
993 HValue* context = block()->graph()->GetInvalidContext(); | 991 Isolate* isolate = graph->isolate(); |
| 992 Zone* zone = graph->zone(); |
| 993 HValue* context = graph->GetInvalidContext(); |
994 if (actual_offset != 0) { | 994 if (actual_offset != 0) { |
995 HConstant* add_offset = HConstant::New(zone, context, actual_offset); | 995 HConstant* add_offset = |
| 996 HConstant::New(isolate, zone, context, actual_offset); |
996 add_offset->InsertBefore(this); | 997 add_offset->InsertBefore(this); |
997 HInstruction* add = HAdd::New(zone, context, | 998 HInstruction* add = |
998 current_index, add_offset); | 999 HAdd::New(isolate, zone, context, current_index, add_offset); |
999 add->InsertBefore(this); | 1000 add->InsertBefore(this); |
1000 add->AssumeRepresentation(index()->representation()); | 1001 add->AssumeRepresentation(index()->representation()); |
1001 add->ClearFlag(kCanOverflow); | 1002 add->ClearFlag(kCanOverflow); |
1002 current_index = add; | 1003 current_index = add; |
1003 } | 1004 } |
1004 | 1005 |
1005 if (actual_scale != 0) { | 1006 if (actual_scale != 0) { |
1006 HConstant* sar_scale = HConstant::New(zone, context, actual_scale); | 1007 HConstant* sar_scale = HConstant::New(isolate, zone, context, actual_scale); |
1007 sar_scale->InsertBefore(this); | 1008 sar_scale->InsertBefore(this); |
1008 HInstruction* sar = HSar::New(zone, context, | 1009 HInstruction* sar = |
1009 current_index, sar_scale); | 1010 HSar::New(isolate, zone, context, current_index, sar_scale); |
1010 sar->InsertBefore(this); | 1011 sar->InsertBefore(this); |
1011 sar->AssumeRepresentation(index()->representation()); | 1012 sar->AssumeRepresentation(index()->representation()); |
1012 current_index = sar; | 1013 current_index = sar; |
1013 } | 1014 } |
1014 | 1015 |
1015 SetOperandAt(0, current_index); | 1016 SetOperandAt(0, current_index); |
1016 | 1017 |
1017 base_ = NULL; | 1018 base_ = NULL; |
1018 offset_ = 0; | 1019 offset_ = 0; |
1019 scale_ = 0; | 1020 scale_ = 0; |
(...skipping 495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1515 } | 1516 } |
1516 return this; | 1517 return this; |
1517 } | 1518 } |
1518 | 1519 |
1519 | 1520 |
1520 std::ostream& HTypeof::PrintDataTo(std::ostream& os) const { // NOLINT | 1521 std::ostream& HTypeof::PrintDataTo(std::ostream& os) const { // NOLINT |
1521 return os << NameOf(value()); | 1522 return os << NameOf(value()); |
1522 } | 1523 } |
1523 | 1524 |
1524 | 1525 |
1525 HInstruction* HForceRepresentation::New(Zone* zone, HValue* context, | 1526 HInstruction* HForceRepresentation::New(Isolate* isolate, Zone* zone, |
1526 HValue* value, Representation representation) { | 1527 HValue* context, HValue* value, |
| 1528 Representation representation) { |
1527 if (FLAG_fold_constants && value->IsConstant()) { | 1529 if (FLAG_fold_constants && value->IsConstant()) { |
1528 HConstant* c = HConstant::cast(value); | 1530 HConstant* c = HConstant::cast(value); |
1529 c = c->CopyToRepresentation(representation, zone); | 1531 c = c->CopyToRepresentation(representation, zone); |
1530 if (c != NULL) return c; | 1532 if (c != NULL) return c; |
1531 } | 1533 } |
1532 return new(zone) HForceRepresentation(value, representation); | 1534 return new(zone) HForceRepresentation(value, representation); |
1533 } | 1535 } |
1534 | 1536 |
1535 | 1537 |
1536 std::ostream& HForceRepresentation::PrintDataTo( | 1538 std::ostream& HForceRepresentation::PrintDataTo( |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1588 // A change from an integer32 can be replaced by the integer32 value. | 1590 // A change from an integer32 can be replaced by the integer32 value. |
1589 right = HChange::cast(right)->value(); | 1591 right = HChange::cast(right)->value(); |
1590 } else if (hdiv->observed_input_representation(2).IsSmiOrInteger32()) { | 1592 } else if (hdiv->observed_input_representation(2).IsSmiOrInteger32()) { |
1591 right = Prepend(new(block()->zone()) HChange( | 1593 right = Prepend(new(block()->zone()) HChange( |
1592 right, Representation::Integer32(), false, false)); | 1594 right, Representation::Integer32(), false, false)); |
1593 } else { | 1595 } else { |
1594 return this; | 1596 return this; |
1595 } | 1597 } |
1596 | 1598 |
1597 return Prepend(HMathFloorOfDiv::New( | 1599 return Prepend(HMathFloorOfDiv::New( |
1598 block()->zone(), context(), left, right)); | 1600 block()->graph()->isolate(), block()->zone(), context(), left, right)); |
1599 } | 1601 } |
1600 return this; | 1602 return this; |
1601 } | 1603 } |
1602 | 1604 |
1603 | 1605 |
1604 HValue* HCheckInstanceType::Canonicalize() { | 1606 HValue* HCheckInstanceType::Canonicalize() { |
1605 if ((check_ == IS_SPEC_OBJECT && value()->type().IsJSObject()) || | 1607 if ((check_ == IS_SPEC_OBJECT && value()->type().IsJSObject()) || |
1606 (check_ == IS_JS_ARRAY && value()->type().IsJSArray()) || | 1608 (check_ == IS_JS_ARRAY && value()->type().IsJSArray()) || |
1607 (check_ == IS_STRING && value()->type().IsString())) { | 1609 (check_ == IS_STRING && value()->type().IsString())) { |
1608 return value(); | 1610 return value(); |
(...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2115 void InductionVariableData::ChecksRelatedToLength::UseNewIndexInCurrentBlock( | 2117 void InductionVariableData::ChecksRelatedToLength::UseNewIndexInCurrentBlock( |
2116 Token::Value token, | 2118 Token::Value token, |
2117 int32_t mask, | 2119 int32_t mask, |
2118 HValue* index_base, | 2120 HValue* index_base, |
2119 HValue* context) { | 2121 HValue* context) { |
2120 DCHECK(first_check_in_block() != NULL); | 2122 DCHECK(first_check_in_block() != NULL); |
2121 HValue* previous_index = first_check_in_block()->index(); | 2123 HValue* previous_index = first_check_in_block()->index(); |
2122 DCHECK(context != NULL); | 2124 DCHECK(context != NULL); |
2123 | 2125 |
2124 Zone* zone = index_base->block()->graph()->zone(); | 2126 Zone* zone = index_base->block()->graph()->zone(); |
2125 set_added_constant(HConstant::New(zone, context, mask)); | 2127 Isolate* isolate = index_base->block()->graph()->isolate(); |
| 2128 set_added_constant(HConstant::New(isolate, zone, context, mask)); |
2126 if (added_index() != NULL) { | 2129 if (added_index() != NULL) { |
2127 added_constant()->InsertBefore(added_index()); | 2130 added_constant()->InsertBefore(added_index()); |
2128 } else { | 2131 } else { |
2129 added_constant()->InsertBefore(first_check_in_block()); | 2132 added_constant()->InsertBefore(first_check_in_block()); |
2130 } | 2133 } |
2131 | 2134 |
2132 if (added_index() == NULL) { | 2135 if (added_index() == NULL) { |
2133 first_check_in_block()->ReplaceAllUsesWith(first_check_in_block()->index()); | 2136 first_check_in_block()->ReplaceAllUsesWith(first_check_in_block()->index()); |
2134 HInstruction* new_index = HBitwise::New(zone, context, token, index_base, | 2137 HInstruction* new_index = HBitwise::New(isolate, zone, context, token, |
2135 added_constant()); | 2138 index_base, added_constant()); |
2136 DCHECK(new_index->IsBitwise()); | 2139 DCHECK(new_index->IsBitwise()); |
2137 new_index->ClearAllSideEffects(); | 2140 new_index->ClearAllSideEffects(); |
2138 new_index->AssumeRepresentation(Representation::Integer32()); | 2141 new_index->AssumeRepresentation(Representation::Integer32()); |
2139 set_added_index(HBitwise::cast(new_index)); | 2142 set_added_index(HBitwise::cast(new_index)); |
2140 added_index()->InsertBefore(first_check_in_block()); | 2143 added_index()->InsertBefore(first_check_in_block()); |
2141 } | 2144 } |
2142 DCHECK(added_index()->op() == token); | 2145 DCHECK(added_index()->op() == token); |
2143 | 2146 |
2144 added_index()->SetOperandAt(1, index_base); | 2147 added_index()->SetOperandAt(1, index_base); |
2145 added_index()->SetOperandAt(2, added_constant()); | 2148 added_index()->SetOperandAt(2, added_constant()); |
(...skipping 798 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2944 NotInNewSpace(), object_); | 2947 NotInNewSpace(), object_); |
2945 } else if (HasDoubleValue()) { | 2948 } else if (HasDoubleValue()) { |
2946 res = new (zone) | 2949 res = new (zone) |
2947 HConstant(DoubleToInt32(double_value_), Representation::Integer32(), | 2950 HConstant(DoubleToInt32(double_value_), Representation::Integer32(), |
2948 NotInNewSpace(), object_); | 2951 NotInNewSpace(), object_); |
2949 } | 2952 } |
2950 return Maybe<HConstant*>(res != NULL, res); | 2953 return Maybe<HConstant*>(res != NULL, res); |
2951 } | 2954 } |
2952 | 2955 |
2953 | 2956 |
2954 Maybe<HConstant*> HConstant::CopyToTruncatedNumber(Zone* zone) { | 2957 Maybe<HConstant*> HConstant::CopyToTruncatedNumber(Isolate* isolate, |
| 2958 Zone* zone) { |
2955 HConstant* res = NULL; | 2959 HConstant* res = NULL; |
2956 Handle<Object> handle = this->handle(zone->isolate()); | 2960 Handle<Object> handle = this->handle(isolate); |
2957 if (handle->IsBoolean()) { | 2961 if (handle->IsBoolean()) { |
2958 res = handle->BooleanValue() ? | 2962 res = handle->BooleanValue() ? |
2959 new(zone) HConstant(1) : new(zone) HConstant(0); | 2963 new(zone) HConstant(1) : new(zone) HConstant(0); |
2960 } else if (handle->IsUndefined()) { | 2964 } else if (handle->IsUndefined()) { |
2961 res = new (zone) HConstant(std::numeric_limits<double>::quiet_NaN()); | 2965 res = new (zone) HConstant(std::numeric_limits<double>::quiet_NaN()); |
2962 } else if (handle->IsNull()) { | 2966 } else if (handle->IsNull()) { |
2963 res = new(zone) HConstant(0); | 2967 res = new(zone) HConstant(0); |
2964 } | 2968 } |
2965 return Maybe<HConstant*>(res != NULL, res); | 2969 return Maybe<HConstant*>(res != NULL, res); |
2966 } | 2970 } |
(...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3545 // by index. | 3549 // by index. |
3546 if (key()->IsLoadKeyed()) { | 3550 if (key()->IsLoadKeyed()) { |
3547 HLoadKeyed* key_load = HLoadKeyed::cast(key()); | 3551 HLoadKeyed* key_load = HLoadKeyed::cast(key()); |
3548 if (key_load->elements()->IsForInCacheArray()) { | 3552 if (key_load->elements()->IsForInCacheArray()) { |
3549 HForInCacheArray* names_cache = | 3553 HForInCacheArray* names_cache = |
3550 HForInCacheArray::cast(key_load->elements()); | 3554 HForInCacheArray::cast(key_load->elements()); |
3551 | 3555 |
3552 if (names_cache->enumerable() == object()) { | 3556 if (names_cache->enumerable() == object()) { |
3553 HForInCacheArray* index_cache = | 3557 HForInCacheArray* index_cache = |
3554 names_cache->index_cache(); | 3558 names_cache->index_cache(); |
3555 HCheckMapValue* map_check = | 3559 HCheckMapValue* map_check = HCheckMapValue::New( |
3556 HCheckMapValue::New(block()->graph()->zone(), | 3560 block()->graph()->isolate(), block()->graph()->zone(), |
3557 block()->graph()->GetInvalidContext(), | 3561 block()->graph()->GetInvalidContext(), object(), |
3558 object(), | 3562 names_cache->map()); |
3559 names_cache->map()); | |
3560 HInstruction* index = HLoadKeyed::New( | 3563 HInstruction* index = HLoadKeyed::New( |
3561 block()->graph()->zone(), | 3564 block()->graph()->isolate(), block()->graph()->zone(), |
3562 block()->graph()->GetInvalidContext(), | 3565 block()->graph()->GetInvalidContext(), index_cache, key_load->key(), |
3563 index_cache, | 3566 key_load->key(), key_load->elements_kind()); |
3564 key_load->key(), | |
3565 key_load->key(), | |
3566 key_load->elements_kind()); | |
3567 map_check->InsertBefore(this); | 3567 map_check->InsertBefore(this); |
3568 index->InsertBefore(this); | 3568 index->InsertBefore(this); |
3569 return Prepend(new(block()->zone()) HLoadFieldByIndex( | 3569 return Prepend(new(block()->zone()) HLoadFieldByIndex( |
3570 object(), index)); | 3570 object(), index)); |
3571 } | 3571 } |
3572 } | 3572 } |
3573 } | 3573 } |
3574 | 3574 |
3575 return this; | 3575 return this; |
3576 } | 3576 } |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3719 rep = rep.generalize(input_rep); | 3719 rep = rep.generalize(input_rep); |
3720 } | 3720 } |
3721 return rep; | 3721 return rep; |
3722 } | 3722 } |
3723 | 3723 |
3724 | 3724 |
3725 bool HAllocate::HandleSideEffectDominator(GVNFlag side_effect, | 3725 bool HAllocate::HandleSideEffectDominator(GVNFlag side_effect, |
3726 HValue* dominator) { | 3726 HValue* dominator) { |
3727 DCHECK(side_effect == kNewSpacePromotion); | 3727 DCHECK(side_effect == kNewSpacePromotion); |
3728 Zone* zone = block()->zone(); | 3728 Zone* zone = block()->zone(); |
| 3729 Isolate* isolate = block()->isolate(); |
3729 if (!FLAG_use_allocation_folding) return false; | 3730 if (!FLAG_use_allocation_folding) return false; |
3730 | 3731 |
3731 // Try to fold allocations together with their dominating allocations. | 3732 // Try to fold allocations together with their dominating allocations. |
3732 if (!dominator->IsAllocate()) { | 3733 if (!dominator->IsAllocate()) { |
3733 if (FLAG_trace_allocation_folding) { | 3734 if (FLAG_trace_allocation_folding) { |
3734 PrintF("#%d (%s) cannot fold into #%d (%s)\n", | 3735 PrintF("#%d (%s) cannot fold into #%d (%s)\n", |
3735 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); | 3736 id(), Mnemonic(), dominator->id(), dominator->Mnemonic()); |
3736 } | 3737 } |
3737 return false; | 3738 return false; |
3738 } | 3739 } |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3820 PrintF("#%d (%s) cannot fold into #%d (%s) due to size: %d\n", | 3821 PrintF("#%d (%s) cannot fold into #%d (%s) due to size: %d\n", |
3821 id(), Mnemonic(), dominator_allocate->id(), | 3822 id(), Mnemonic(), dominator_allocate->id(), |
3822 dominator_allocate->Mnemonic(), new_dominator_size); | 3823 dominator_allocate->Mnemonic(), new_dominator_size); |
3823 } | 3824 } |
3824 return false; | 3825 return false; |
3825 } | 3826 } |
3826 | 3827 |
3827 HInstruction* new_dominator_size_value; | 3828 HInstruction* new_dominator_size_value; |
3828 | 3829 |
3829 if (current_size->IsInteger32Constant()) { | 3830 if (current_size->IsInteger32Constant()) { |
3830 new_dominator_size_value = | 3831 new_dominator_size_value = HConstant::CreateAndInsertBefore( |
3831 HConstant::CreateAndInsertBefore(zone, | 3832 isolate, zone, context(), new_dominator_size, Representation::None(), |
3832 context(), | 3833 dominator_allocate); |
3833 new_dominator_size, | |
3834 Representation::None(), | |
3835 dominator_allocate); | |
3836 } else { | 3834 } else { |
3837 HValue* new_dominator_size_constant = | 3835 HValue* new_dominator_size_constant = HConstant::CreateAndInsertBefore( |
3838 HConstant::CreateAndInsertBefore(zone, | 3836 isolate, zone, context(), dominator_size_constant, |
3839 context(), | 3837 Representation::Integer32(), dominator_allocate); |
3840 dominator_size_constant, | |
3841 Representation::Integer32(), | |
3842 dominator_allocate); | |
3843 | 3838 |
3844 // Add old and new size together and insert. | 3839 // Add old and new size together and insert. |
3845 current_size->ChangeRepresentation(Representation::Integer32()); | 3840 current_size->ChangeRepresentation(Representation::Integer32()); |
3846 | 3841 |
3847 new_dominator_size_value = HAdd::New(zone, context(), | 3842 new_dominator_size_value = HAdd::New( |
3848 new_dominator_size_constant, current_size); | 3843 isolate, zone, context(), new_dominator_size_constant, current_size); |
3849 new_dominator_size_value->ClearFlag(HValue::kCanOverflow); | 3844 new_dominator_size_value->ClearFlag(HValue::kCanOverflow); |
3850 new_dominator_size_value->ChangeRepresentation(Representation::Integer32()); | 3845 new_dominator_size_value->ChangeRepresentation(Representation::Integer32()); |
3851 | 3846 |
3852 new_dominator_size_value->InsertBefore(dominator_allocate); | 3847 new_dominator_size_value->InsertBefore(dominator_allocate); |
3853 } | 3848 } |
3854 | 3849 |
3855 dominator_allocate->UpdateSize(new_dominator_size_value); | 3850 dominator_allocate->UpdateSize(new_dominator_size_value); |
3856 | 3851 |
3857 if (MustAllocateDoubleAligned()) { | 3852 if (MustAllocateDoubleAligned()) { |
3858 if (!dominator_allocate->MustAllocateDoubleAligned()) { | 3853 if (!dominator_allocate->MustAllocateDoubleAligned()) { |
(...skipping 11 matching lines...) Expand all Loading... |
3870 } else { | 3865 } else { |
3871 // TODO(hpayer): This is a short-term hack to make allocation mementos | 3866 // TODO(hpayer): This is a short-term hack to make allocation mementos |
3872 // work again in new space. | 3867 // work again in new space. |
3873 dominator_allocate->ClearNextMapWord(original_object_size); | 3868 dominator_allocate->ClearNextMapWord(original_object_size); |
3874 } | 3869 } |
3875 | 3870 |
3876 dominator_allocate->UpdateClearNextMapWord(MustClearNextMapWord()); | 3871 dominator_allocate->UpdateClearNextMapWord(MustClearNextMapWord()); |
3877 | 3872 |
3878 // After that replace the dominated allocate instruction. | 3873 // After that replace the dominated allocate instruction. |
3879 HInstruction* inner_offset = HConstant::CreateAndInsertBefore( | 3874 HInstruction* inner_offset = HConstant::CreateAndInsertBefore( |
3880 zone, | 3875 isolate, zone, context(), dominator_size_constant, Representation::None(), |
3881 context(), | |
3882 dominator_size_constant, | |
3883 Representation::None(), | |
3884 this); | 3876 this); |
3885 | 3877 |
3886 HInstruction* dominated_allocate_instr = | 3878 HInstruction* dominated_allocate_instr = HInnerAllocatedObject::New( |
3887 HInnerAllocatedObject::New(zone, | 3879 isolate, zone, context(), dominator_allocate, inner_offset, type()); |
3888 context(), | |
3889 dominator_allocate, | |
3890 inner_offset, | |
3891 type()); | |
3892 dominated_allocate_instr->InsertBefore(this); | 3880 dominated_allocate_instr->InsertBefore(this); |
3893 DeleteAndReplaceWith(dominated_allocate_instr); | 3881 DeleteAndReplaceWith(dominated_allocate_instr); |
3894 if (FLAG_trace_allocation_folding) { | 3882 if (FLAG_trace_allocation_folding) { |
3895 PrintF("#%d (%s) folded into #%d (%s)\n", | 3883 PrintF("#%d (%s) folded into #%d (%s)\n", |
3896 id(), Mnemonic(), dominator_allocate->id(), | 3884 id(), Mnemonic(), dominator_allocate->id(), |
3897 dominator_allocate->Mnemonic()); | 3885 dominator_allocate->Mnemonic()); |
3898 } | 3886 } |
3899 return true; | 3887 return true; |
3900 } | 3888 } |
3901 | 3889 |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3964 } | 3952 } |
3965 | 3953 |
3966 | 3954 |
3967 void HAllocate::UpdateFreeSpaceFiller(int32_t free_space_size) { | 3955 void HAllocate::UpdateFreeSpaceFiller(int32_t free_space_size) { |
3968 DCHECK(filler_free_space_size_ != NULL); | 3956 DCHECK(filler_free_space_size_ != NULL); |
3969 Zone* zone = block()->zone(); | 3957 Zone* zone = block()->zone(); |
3970 // We must explicitly force Smi representation here because on x64 we | 3958 // We must explicitly force Smi representation here because on x64 we |
3971 // would otherwise automatically choose int32, but the actual store | 3959 // would otherwise automatically choose int32, but the actual store |
3972 // requires a Smi-tagged value. | 3960 // requires a Smi-tagged value. |
3973 HConstant* new_free_space_size = HConstant::CreateAndInsertBefore( | 3961 HConstant* new_free_space_size = HConstant::CreateAndInsertBefore( |
3974 zone, | 3962 block()->isolate(), zone, context(), |
3975 context(), | |
3976 filler_free_space_size_->value()->GetInteger32Constant() + | 3963 filler_free_space_size_->value()->GetInteger32Constant() + |
3977 free_space_size, | 3964 free_space_size, |
3978 Representation::Smi(), | 3965 Representation::Smi(), filler_free_space_size_); |
3979 filler_free_space_size_); | |
3980 filler_free_space_size_->UpdateValue(new_free_space_size); | 3966 filler_free_space_size_->UpdateValue(new_free_space_size); |
3981 } | 3967 } |
3982 | 3968 |
3983 | 3969 |
3984 void HAllocate::CreateFreeSpaceFiller(int32_t free_space_size) { | 3970 void HAllocate::CreateFreeSpaceFiller(int32_t free_space_size) { |
3985 DCHECK(filler_free_space_size_ == NULL); | 3971 DCHECK(filler_free_space_size_ == NULL); |
| 3972 Isolate* isolate = block()->isolate(); |
3986 Zone* zone = block()->zone(); | 3973 Zone* zone = block()->zone(); |
3987 HInstruction* free_space_instr = | 3974 HInstruction* free_space_instr = |
3988 HInnerAllocatedObject::New(zone, context(), dominating_allocate_, | 3975 HInnerAllocatedObject::New(isolate, zone, context(), dominating_allocate_, |
3989 dominating_allocate_->size(), type()); | 3976 dominating_allocate_->size(), type()); |
3990 free_space_instr->InsertBefore(this); | 3977 free_space_instr->InsertBefore(this); |
3991 HConstant* filler_map = HConstant::CreateAndInsertAfter( | 3978 HConstant* filler_map = HConstant::CreateAndInsertAfter( |
3992 zone, Unique<Map>::CreateImmovable( | 3979 zone, Unique<Map>::CreateImmovable(isolate->factory()->free_space_map()), |
3993 isolate()->factory()->free_space_map()), true, free_space_instr); | 3980 true, free_space_instr); |
3994 HInstruction* store_map = HStoreNamedField::New(zone, context(), | 3981 HInstruction* store_map = |
3995 free_space_instr, HObjectAccess::ForMap(), filler_map); | 3982 HStoreNamedField::New(isolate, zone, context(), free_space_instr, |
| 3983 HObjectAccess::ForMap(), filler_map); |
3996 store_map->SetFlag(HValue::kHasNoObservableSideEffects); | 3984 store_map->SetFlag(HValue::kHasNoObservableSideEffects); |
3997 store_map->InsertAfter(filler_map); | 3985 store_map->InsertAfter(filler_map); |
3998 | 3986 |
3999 // We must explicitly force Smi representation here because on x64 we | 3987 // We must explicitly force Smi representation here because on x64 we |
4000 // would otherwise automatically choose int32, but the actual store | 3988 // would otherwise automatically choose int32, but the actual store |
4001 // requires a Smi-tagged value. | 3989 // requires a Smi-tagged value. |
4002 HConstant* filler_size = HConstant::CreateAndInsertAfter( | 3990 HConstant* filler_size = |
4003 zone, context(), free_space_size, Representation::Smi(), store_map); | 3991 HConstant::CreateAndInsertAfter(isolate, zone, context(), free_space_size, |
| 3992 Representation::Smi(), store_map); |
4004 // Must force Smi representation for x64 (see comment above). | 3993 // Must force Smi representation for x64 (see comment above). |
4005 HObjectAccess access = | 3994 HObjectAccess access = HObjectAccess::ForMapAndOffset( |
4006 HObjectAccess::ForMapAndOffset(isolate()->factory()->free_space_map(), | 3995 isolate->factory()->free_space_map(), FreeSpace::kSizeOffset, |
4007 FreeSpace::kSizeOffset, | 3996 Representation::Smi()); |
4008 Representation::Smi()); | 3997 HStoreNamedField* store_size = HStoreNamedField::New( |
4009 HStoreNamedField* store_size = HStoreNamedField::New(zone, context(), | 3998 isolate, zone, context(), free_space_instr, access, filler_size); |
4010 free_space_instr, access, filler_size); | |
4011 store_size->SetFlag(HValue::kHasNoObservableSideEffects); | 3999 store_size->SetFlag(HValue::kHasNoObservableSideEffects); |
4012 store_size->InsertAfter(filler_size); | 4000 store_size->InsertAfter(filler_size); |
4013 filler_free_space_size_ = store_size; | 4001 filler_free_space_size_ = store_size; |
4014 } | 4002 } |
4015 | 4003 |
4016 | 4004 |
4017 void HAllocate::ClearNextMapWord(int offset) { | 4005 void HAllocate::ClearNextMapWord(int offset) { |
4018 if (MustClearNextMapWord()) { | 4006 if (MustClearNextMapWord()) { |
4019 Zone* zone = block()->zone(); | 4007 Zone* zone = block()->zone(); |
4020 HObjectAccess access = | 4008 HObjectAccess access = |
4021 HObjectAccess::ForObservableJSObjectOffset(offset); | 4009 HObjectAccess::ForObservableJSObjectOffset(offset); |
4022 HStoreNamedField* clear_next_map = | 4010 HStoreNamedField* clear_next_map = |
4023 HStoreNamedField::New(zone, context(), this, access, | 4011 HStoreNamedField::New(block()->isolate(), zone, context(), this, access, |
4024 block()->graph()->GetConstant0()); | 4012 block()->graph()->GetConstant0()); |
4025 clear_next_map->ClearAllSideEffects(); | 4013 clear_next_map->ClearAllSideEffects(); |
4026 clear_next_map->InsertAfter(this); | 4014 clear_next_map->InsertAfter(this); |
4027 } | 4015 } |
4028 } | 4016 } |
4029 | 4017 |
4030 | 4018 |
4031 std::ostream& HAllocate::PrintDataTo(std::ostream& os) const { // NOLINT | 4019 std::ostream& HAllocate::PrintDataTo(std::ostream& os) const { // NOLINT |
4032 os << NameOf(size()) << " ("; | 4020 os << NameOf(size()) << " ("; |
4033 if (IsNewSpaceAllocation()) os << "N"; | 4021 if (IsNewSpaceAllocation()) os << "N"; |
4034 if (IsOldPointerSpaceAllocation()) os << "P"; | 4022 if (IsOldPointerSpaceAllocation()) os << "P"; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4067 case kPhi: { | 4055 case kPhi: { |
4068 // Better safe than sorry... | 4056 // Better safe than sorry... |
4069 return true; | 4057 return true; |
4070 } | 4058 } |
4071 default: | 4059 default: |
4072 return false; | 4060 return false; |
4073 } | 4061 } |
4074 } | 4062 } |
4075 | 4063 |
4076 | 4064 |
4077 #define H_CONSTANT_INT(val) \ | 4065 #define H_CONSTANT_INT(val) \ |
4078 HConstant::New(zone, context, static_cast<int32_t>(val)) | 4066 HConstant::New(isolate, zone, context, static_cast<int32_t>(val)) |
4079 #define H_CONSTANT_DOUBLE(val) \ | 4067 #define H_CONSTANT_DOUBLE(val) \ |
4080 HConstant::New(zone, context, static_cast<double>(val)) | 4068 HConstant::New(isolate, zone, context, static_cast<double>(val)) |
4081 | 4069 |
4082 #define DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HInstr, op) \ | 4070 #define DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HInstr, op) \ |
4083 HInstruction* HInstr::New( \ | 4071 HInstruction* HInstr::New(Isolate* isolate, Zone* zone, HValue* context, \ |
4084 Zone* zone, HValue* context, HValue* left, HValue* right) { \ | 4072 HValue* left, HValue* right) { \ |
4085 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { \ | 4073 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { \ |
4086 HConstant* c_left = HConstant::cast(left); \ | 4074 HConstant* c_left = HConstant::cast(left); \ |
4087 HConstant* c_right = HConstant::cast(right); \ | 4075 HConstant* c_right = HConstant::cast(right); \ |
4088 if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { \ | 4076 if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { \ |
4089 double double_res = c_left->DoubleValue() op c_right->DoubleValue(); \ | 4077 double double_res = c_left->DoubleValue() op c_right->DoubleValue(); \ |
4090 if (IsInt32Double(double_res)) { \ | 4078 if (IsInt32Double(double_res)) { \ |
4091 return H_CONSTANT_INT(double_res); \ | 4079 return H_CONSTANT_INT(double_res); \ |
4092 } \ | 4080 } \ |
4093 return H_CONSTANT_DOUBLE(double_res); \ | 4081 return H_CONSTANT_DOUBLE(double_res); \ |
4094 } \ | 4082 } \ |
4095 } \ | 4083 } \ |
4096 return new(zone) HInstr(context, left, right); \ | 4084 return new (zone) HInstr(context, left, right); \ |
4097 } | 4085 } |
4098 | 4086 |
4099 | 4087 |
4100 DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HAdd, +) | 4088 DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HAdd, +) |
4101 DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HMul, *) | 4089 DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HMul, *) |
4102 DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HSub, -) | 4090 DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR(HSub, -) |
4103 | 4091 |
4104 #undef DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR | 4092 #undef DEFINE_NEW_H_SIMPLE_ARITHMETIC_INSTR |
4105 | 4093 |
4106 | 4094 |
4107 HInstruction* HStringAdd::New(Zone* zone, | 4095 HInstruction* HStringAdd::New(Isolate* isolate, Zone* zone, HValue* context, |
4108 HValue* context, | 4096 HValue* left, HValue* right, |
4109 HValue* left, | |
4110 HValue* right, | |
4111 PretenureFlag pretenure_flag, | 4097 PretenureFlag pretenure_flag, |
4112 StringAddFlags flags, | 4098 StringAddFlags flags, |
4113 Handle<AllocationSite> allocation_site) { | 4099 Handle<AllocationSite> allocation_site) { |
4114 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { | 4100 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { |
4115 HConstant* c_right = HConstant::cast(right); | 4101 HConstant* c_right = HConstant::cast(right); |
4116 HConstant* c_left = HConstant::cast(left); | 4102 HConstant* c_left = HConstant::cast(left); |
4117 if (c_left->HasStringValue() && c_right->HasStringValue()) { | 4103 if (c_left->HasStringValue() && c_right->HasStringValue()) { |
4118 Handle<String> left_string = c_left->StringValue(); | 4104 Handle<String> left_string = c_left->StringValue(); |
4119 Handle<String> right_string = c_right->StringValue(); | 4105 Handle<String> right_string = c_right->StringValue(); |
4120 // Prevent possible exception by invalid string length. | 4106 // Prevent possible exception by invalid string length. |
4121 if (left_string->length() + right_string->length() < String::kMaxLength) { | 4107 if (left_string->length() + right_string->length() < String::kMaxLength) { |
4122 MaybeHandle<String> concat = zone->isolate()->factory()->NewConsString( | 4108 MaybeHandle<String> concat = isolate->factory()->NewConsString( |
4123 c_left->StringValue(), c_right->StringValue()); | 4109 c_left->StringValue(), c_right->StringValue()); |
4124 return HConstant::New(zone, context, concat.ToHandleChecked()); | 4110 return HConstant::New(isolate, zone, context, concat.ToHandleChecked()); |
4125 } | 4111 } |
4126 } | 4112 } |
4127 } | 4113 } |
4128 return new(zone) HStringAdd( | 4114 return new(zone) HStringAdd( |
4129 context, left, right, pretenure_flag, flags, allocation_site); | 4115 context, left, right, pretenure_flag, flags, allocation_site); |
4130 } | 4116 } |
4131 | 4117 |
4132 | 4118 |
4133 std::ostream& HStringAdd::PrintDataTo(std::ostream& os) const { // NOLINT | 4119 std::ostream& HStringAdd::PrintDataTo(std::ostream& os) const { // NOLINT |
4134 if ((flags() & STRING_ADD_CHECK_BOTH) == STRING_ADD_CHECK_BOTH) { | 4120 if ((flags() & STRING_ADD_CHECK_BOTH) == STRING_ADD_CHECK_BOTH) { |
4135 os << "_CheckBoth"; | 4121 os << "_CheckBoth"; |
4136 } else if ((flags() & STRING_ADD_CHECK_BOTH) == STRING_ADD_CHECK_LEFT) { | 4122 } else if ((flags() & STRING_ADD_CHECK_BOTH) == STRING_ADD_CHECK_LEFT) { |
4137 os << "_CheckLeft"; | 4123 os << "_CheckLeft"; |
4138 } else if ((flags() & STRING_ADD_CHECK_BOTH) == STRING_ADD_CHECK_RIGHT) { | 4124 } else if ((flags() & STRING_ADD_CHECK_BOTH) == STRING_ADD_CHECK_RIGHT) { |
4139 os << "_CheckRight"; | 4125 os << "_CheckRight"; |
4140 } | 4126 } |
4141 HBinaryOperation::PrintDataTo(os); | 4127 HBinaryOperation::PrintDataTo(os); |
4142 os << " ("; | 4128 os << " ("; |
4143 if (pretenure_flag() == NOT_TENURED) | 4129 if (pretenure_flag() == NOT_TENURED) |
4144 os << "N"; | 4130 os << "N"; |
4145 else if (pretenure_flag() == TENURED) | 4131 else if (pretenure_flag() == TENURED) |
4146 os << "D"; | 4132 os << "D"; |
4147 return os << ")"; | 4133 return os << ")"; |
4148 } | 4134 } |
4149 | 4135 |
4150 | 4136 |
4151 HInstruction* HStringCharFromCode::New( | 4137 HInstruction* HStringCharFromCode::New(Isolate* isolate, Zone* zone, |
4152 Zone* zone, HValue* context, HValue* char_code) { | 4138 HValue* context, HValue* char_code) { |
4153 if (FLAG_fold_constants && char_code->IsConstant()) { | 4139 if (FLAG_fold_constants && char_code->IsConstant()) { |
4154 HConstant* c_code = HConstant::cast(char_code); | 4140 HConstant* c_code = HConstant::cast(char_code); |
4155 Isolate* isolate = zone->isolate(); | |
4156 if (c_code->HasNumberValue()) { | 4141 if (c_code->HasNumberValue()) { |
4157 if (std::isfinite(c_code->DoubleValue())) { | 4142 if (std::isfinite(c_code->DoubleValue())) { |
4158 uint32_t code = c_code->NumberValueAsInteger32() & 0xffff; | 4143 uint32_t code = c_code->NumberValueAsInteger32() & 0xffff; |
4159 return HConstant::New(zone, context, | 4144 return HConstant::New( |
| 4145 isolate, zone, context, |
4160 isolate->factory()->LookupSingleCharacterStringFromCode(code)); | 4146 isolate->factory()->LookupSingleCharacterStringFromCode(code)); |
4161 } | 4147 } |
4162 return HConstant::New(zone, context, isolate->factory()->empty_string()); | 4148 return HConstant::New(isolate, zone, context, |
| 4149 isolate->factory()->empty_string()); |
4163 } | 4150 } |
4164 } | 4151 } |
4165 return new(zone) HStringCharFromCode(context, char_code); | 4152 return new(zone) HStringCharFromCode(context, char_code); |
4166 } | 4153 } |
4167 | 4154 |
4168 | 4155 |
4169 HInstruction* HUnaryMathOperation::New( | 4156 HInstruction* HUnaryMathOperation::New(Isolate* isolate, Zone* zone, |
4170 Zone* zone, HValue* context, HValue* value, BuiltinFunctionId op) { | 4157 HValue* context, HValue* value, |
| 4158 BuiltinFunctionId op) { |
4171 do { | 4159 do { |
4172 if (!FLAG_fold_constants) break; | 4160 if (!FLAG_fold_constants) break; |
4173 if (!value->IsConstant()) break; | 4161 if (!value->IsConstant()) break; |
4174 HConstant* constant = HConstant::cast(value); | 4162 HConstant* constant = HConstant::cast(value); |
4175 if (!constant->HasNumberValue()) break; | 4163 if (!constant->HasNumberValue()) break; |
4176 double d = constant->DoubleValue(); | 4164 double d = constant->DoubleValue(); |
4177 if (std::isnan(d)) { // NaN poisons everything. | 4165 if (std::isnan(d)) { // NaN poisons everything. |
4178 return H_CONSTANT_DOUBLE(std::numeric_limits<double>::quiet_NaN()); | 4166 return H_CONSTANT_DOUBLE(std::numeric_limits<double>::quiet_NaN()); |
4179 } | 4167 } |
4180 if (std::isinf(d)) { // +Infinity and -Infinity. | 4168 if (std::isinf(d)) { // +Infinity and -Infinity. |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4264 id(), Mnemonic(), use->id(), | 4252 id(), Mnemonic(), use->id(), |
4265 use->Mnemonic(), rep_required.Mnemonic(), | 4253 use->Mnemonic(), rep_required.Mnemonic(), |
4266 (use->CheckFlag(kTruncatingToInt32) ? "-trunc" : "")); | 4254 (use->CheckFlag(kTruncatingToInt32) ? "-trunc" : "")); |
4267 } | 4255 } |
4268 } | 4256 } |
4269 } | 4257 } |
4270 return use_double ? Representation::Double() : Representation::Integer32(); | 4258 return use_double ? Representation::Double() : Representation::Integer32(); |
4271 } | 4259 } |
4272 | 4260 |
4273 | 4261 |
4274 HInstruction* HPower::New(Zone* zone, | 4262 HInstruction* HPower::New(Isolate* isolate, Zone* zone, HValue* context, |
4275 HValue* context, | 4263 HValue* left, HValue* right) { |
4276 HValue* left, | |
4277 HValue* right) { | |
4278 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { | 4264 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { |
4279 HConstant* c_left = HConstant::cast(left); | 4265 HConstant* c_left = HConstant::cast(left); |
4280 HConstant* c_right = HConstant::cast(right); | 4266 HConstant* c_right = HConstant::cast(right); |
4281 if (c_left->HasNumberValue() && c_right->HasNumberValue()) { | 4267 if (c_left->HasNumberValue() && c_right->HasNumberValue()) { |
4282 double result = power_helper(c_left->DoubleValue(), | 4268 double result = power_helper(c_left->DoubleValue(), |
4283 c_right->DoubleValue()); | 4269 c_right->DoubleValue()); |
4284 return H_CONSTANT_DOUBLE(std::isnan(result) | 4270 return H_CONSTANT_DOUBLE(std::isnan(result) |
4285 ? std::numeric_limits<double>::quiet_NaN() | 4271 ? std::numeric_limits<double>::quiet_NaN() |
4286 : result); | 4272 : result); |
4287 } | 4273 } |
4288 } | 4274 } |
4289 return new(zone) HPower(left, right); | 4275 return new(zone) HPower(left, right); |
4290 } | 4276 } |
4291 | 4277 |
4292 | 4278 |
4293 HInstruction* HMathMinMax::New( | 4279 HInstruction* HMathMinMax::New(Isolate* isolate, Zone* zone, HValue* context, |
4294 Zone* zone, HValue* context, HValue* left, HValue* right, Operation op) { | 4280 HValue* left, HValue* right, Operation op) { |
4295 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { | 4281 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { |
4296 HConstant* c_left = HConstant::cast(left); | 4282 HConstant* c_left = HConstant::cast(left); |
4297 HConstant* c_right = HConstant::cast(right); | 4283 HConstant* c_right = HConstant::cast(right); |
4298 if (c_left->HasNumberValue() && c_right->HasNumberValue()) { | 4284 if (c_left->HasNumberValue() && c_right->HasNumberValue()) { |
4299 double d_left = c_left->DoubleValue(); | 4285 double d_left = c_left->DoubleValue(); |
4300 double d_right = c_right->DoubleValue(); | 4286 double d_right = c_right->DoubleValue(); |
4301 if (op == kMathMin) { | 4287 if (op == kMathMin) { |
4302 if (d_left > d_right) return H_CONSTANT_DOUBLE(d_right); | 4288 if (d_left > d_right) return H_CONSTANT_DOUBLE(d_right); |
4303 if (d_left < d_right) return H_CONSTANT_DOUBLE(d_left); | 4289 if (d_left < d_right) return H_CONSTANT_DOUBLE(d_left); |
4304 if (d_left == d_right) { | 4290 if (d_left == d_right) { |
(...skipping 11 matching lines...) Expand all Loading... |
4316 } | 4302 } |
4317 } | 4303 } |
4318 // All comparisons failed, must be NaN. | 4304 // All comparisons failed, must be NaN. |
4319 return H_CONSTANT_DOUBLE(std::numeric_limits<double>::quiet_NaN()); | 4305 return H_CONSTANT_DOUBLE(std::numeric_limits<double>::quiet_NaN()); |
4320 } | 4306 } |
4321 } | 4307 } |
4322 return new(zone) HMathMinMax(context, left, right, op); | 4308 return new(zone) HMathMinMax(context, left, right, op); |
4323 } | 4309 } |
4324 | 4310 |
4325 | 4311 |
4326 HInstruction* HMod::New(Zone* zone, | 4312 HInstruction* HMod::New(Isolate* isolate, Zone* zone, HValue* context, |
4327 HValue* context, | 4313 HValue* left, HValue* right) { |
4328 HValue* left, | |
4329 HValue* right) { | |
4330 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { | 4314 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { |
4331 HConstant* c_left = HConstant::cast(left); | 4315 HConstant* c_left = HConstant::cast(left); |
4332 HConstant* c_right = HConstant::cast(right); | 4316 HConstant* c_right = HConstant::cast(right); |
4333 if (c_left->HasInteger32Value() && c_right->HasInteger32Value()) { | 4317 if (c_left->HasInteger32Value() && c_right->HasInteger32Value()) { |
4334 int32_t dividend = c_left->Integer32Value(); | 4318 int32_t dividend = c_left->Integer32Value(); |
4335 int32_t divisor = c_right->Integer32Value(); | 4319 int32_t divisor = c_right->Integer32Value(); |
4336 if (dividend == kMinInt && divisor == -1) { | 4320 if (dividend == kMinInt && divisor == -1) { |
4337 return H_CONSTANT_DOUBLE(-0.0); | 4321 return H_CONSTANT_DOUBLE(-0.0); |
4338 } | 4322 } |
4339 if (divisor != 0) { | 4323 if (divisor != 0) { |
4340 int32_t res = dividend % divisor; | 4324 int32_t res = dividend % divisor; |
4341 if ((res == 0) && (dividend < 0)) { | 4325 if ((res == 0) && (dividend < 0)) { |
4342 return H_CONSTANT_DOUBLE(-0.0); | 4326 return H_CONSTANT_DOUBLE(-0.0); |
4343 } | 4327 } |
4344 return H_CONSTANT_INT(res); | 4328 return H_CONSTANT_INT(res); |
4345 } | 4329 } |
4346 } | 4330 } |
4347 } | 4331 } |
4348 return new(zone) HMod(context, left, right); | 4332 return new(zone) HMod(context, left, right); |
4349 } | 4333 } |
4350 | 4334 |
4351 | 4335 |
4352 HInstruction* HDiv::New( | 4336 HInstruction* HDiv::New(Isolate* isolate, Zone* zone, HValue* context, |
4353 Zone* zone, HValue* context, HValue* left, HValue* right) { | 4337 HValue* left, HValue* right) { |
4354 // If left and right are constant values, try to return a constant value. | 4338 // If left and right are constant values, try to return a constant value. |
4355 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { | 4339 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { |
4356 HConstant* c_left = HConstant::cast(left); | 4340 HConstant* c_left = HConstant::cast(left); |
4357 HConstant* c_right = HConstant::cast(right); | 4341 HConstant* c_right = HConstant::cast(right); |
4358 if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { | 4342 if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { |
4359 if (c_right->DoubleValue() != 0) { | 4343 if (c_right->DoubleValue() != 0) { |
4360 double double_res = c_left->DoubleValue() / c_right->DoubleValue(); | 4344 double double_res = c_left->DoubleValue() / c_right->DoubleValue(); |
4361 if (IsInt32Double(double_res)) { | 4345 if (IsInt32Double(double_res)) { |
4362 return H_CONSTANT_INT(double_res); | 4346 return H_CONSTANT_INT(double_res); |
4363 } | 4347 } |
4364 return H_CONSTANT_DOUBLE(double_res); | 4348 return H_CONSTANT_DOUBLE(double_res); |
4365 } else { | 4349 } else { |
4366 int sign = Double(c_left->DoubleValue()).Sign() * | 4350 int sign = Double(c_left->DoubleValue()).Sign() * |
4367 Double(c_right->DoubleValue()).Sign(); // Right could be -0. | 4351 Double(c_right->DoubleValue()).Sign(); // Right could be -0. |
4368 return H_CONSTANT_DOUBLE(sign * V8_INFINITY); | 4352 return H_CONSTANT_DOUBLE(sign * V8_INFINITY); |
4369 } | 4353 } |
4370 } | 4354 } |
4371 } | 4355 } |
4372 return new(zone) HDiv(context, left, right); | 4356 return new(zone) HDiv(context, left, right); |
4373 } | 4357 } |
4374 | 4358 |
4375 | 4359 |
4376 HInstruction* HBitwise::New( | 4360 HInstruction* HBitwise::New(Isolate* isolate, Zone* zone, HValue* context, |
4377 Zone* zone, HValue* context, Token::Value op, HValue* left, HValue* right) { | 4361 Token::Value op, HValue* left, HValue* right) { |
4378 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { | 4362 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { |
4379 HConstant* c_left = HConstant::cast(left); | 4363 HConstant* c_left = HConstant::cast(left); |
4380 HConstant* c_right = HConstant::cast(right); | 4364 HConstant* c_right = HConstant::cast(right); |
4381 if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { | 4365 if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { |
4382 int32_t result; | 4366 int32_t result; |
4383 int32_t v_left = c_left->NumberValueAsInteger32(); | 4367 int32_t v_left = c_left->NumberValueAsInteger32(); |
4384 int32_t v_right = c_right->NumberValueAsInteger32(); | 4368 int32_t v_right = c_right->NumberValueAsInteger32(); |
4385 switch (op) { | 4369 switch (op) { |
4386 case Token::BIT_XOR: | 4370 case Token::BIT_XOR: |
4387 result = v_left ^ v_right; | 4371 result = v_left ^ v_right; |
4388 break; | 4372 break; |
4389 case Token::BIT_AND: | 4373 case Token::BIT_AND: |
4390 result = v_left & v_right; | 4374 result = v_left & v_right; |
4391 break; | 4375 break; |
4392 case Token::BIT_OR: | 4376 case Token::BIT_OR: |
4393 result = v_left | v_right; | 4377 result = v_left | v_right; |
4394 break; | 4378 break; |
4395 default: | 4379 default: |
4396 result = 0; // Please the compiler. | 4380 result = 0; // Please the compiler. |
4397 UNREACHABLE(); | 4381 UNREACHABLE(); |
4398 } | 4382 } |
4399 return H_CONSTANT_INT(result); | 4383 return H_CONSTANT_INT(result); |
4400 } | 4384 } |
4401 } | 4385 } |
4402 return new(zone) HBitwise(context, op, left, right); | 4386 return new(zone) HBitwise(context, op, left, right); |
4403 } | 4387 } |
4404 | 4388 |
4405 | 4389 |
4406 #define DEFINE_NEW_H_BITWISE_INSTR(HInstr, result) \ | 4390 #define DEFINE_NEW_H_BITWISE_INSTR(HInstr, result) \ |
4407 HInstruction* HInstr::New( \ | 4391 HInstruction* HInstr::New(Isolate* isolate, Zone* zone, HValue* context, \ |
4408 Zone* zone, HValue* context, HValue* left, HValue* right) { \ | 4392 HValue* left, HValue* right) { \ |
4409 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { \ | 4393 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { \ |
4410 HConstant* c_left = HConstant::cast(left); \ | 4394 HConstant* c_left = HConstant::cast(left); \ |
4411 HConstant* c_right = HConstant::cast(right); \ | 4395 HConstant* c_right = HConstant::cast(right); \ |
4412 if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { \ | 4396 if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { \ |
4413 return H_CONSTANT_INT(result); \ | 4397 return H_CONSTANT_INT(result); \ |
4414 } \ | 4398 } \ |
4415 } \ | 4399 } \ |
4416 return new(zone) HInstr(context, left, right); \ | 4400 return new (zone) HInstr(context, left, right); \ |
4417 } | 4401 } |
4418 | 4402 |
4419 | 4403 |
4420 DEFINE_NEW_H_BITWISE_INSTR(HSar, | 4404 DEFINE_NEW_H_BITWISE_INSTR(HSar, |
4421 c_left->NumberValueAsInteger32() >> (c_right->NumberValueAsInteger32() & 0x1f)) | 4405 c_left->NumberValueAsInteger32() >> (c_right->NumberValueAsInteger32() & 0x1f)) |
4422 DEFINE_NEW_H_BITWISE_INSTR(HShl, | 4406 DEFINE_NEW_H_BITWISE_INSTR(HShl, |
4423 c_left->NumberValueAsInteger32() << (c_right->NumberValueAsInteger32() & 0x1f)) | 4407 c_left->NumberValueAsInteger32() << (c_right->NumberValueAsInteger32() & 0x1f)) |
4424 | 4408 |
4425 #undef DEFINE_NEW_H_BITWISE_INSTR | 4409 #undef DEFINE_NEW_H_BITWISE_INSTR |
4426 | 4410 |
4427 | 4411 |
4428 HInstruction* HShr::New( | 4412 HInstruction* HShr::New(Isolate* isolate, Zone* zone, HValue* context, |
4429 Zone* zone, HValue* context, HValue* left, HValue* right) { | 4413 HValue* left, HValue* right) { |
4430 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { | 4414 if (FLAG_fold_constants && left->IsConstant() && right->IsConstant()) { |
4431 HConstant* c_left = HConstant::cast(left); | 4415 HConstant* c_left = HConstant::cast(left); |
4432 HConstant* c_right = HConstant::cast(right); | 4416 HConstant* c_right = HConstant::cast(right); |
4433 if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { | 4417 if ((c_left->HasNumberValue() && c_right->HasNumberValue())) { |
4434 int32_t left_val = c_left->NumberValueAsInteger32(); | 4418 int32_t left_val = c_left->NumberValueAsInteger32(); |
4435 int32_t right_val = c_right->NumberValueAsInteger32() & 0x1f; | 4419 int32_t right_val = c_right->NumberValueAsInteger32() & 0x1f; |
4436 if ((right_val == 0) && (left_val < 0)) { | 4420 if ((right_val == 0) && (left_val < 0)) { |
4437 return H_CONSTANT_DOUBLE(static_cast<uint32_t>(left_val)); | 4421 return H_CONSTANT_DOUBLE(static_cast<uint32_t>(left_val)); |
4438 } | 4422 } |
4439 return H_CONSTANT_INT(static_cast<uint32_t>(left_val) >> right_val); | 4423 return H_CONSTANT_INT(static_cast<uint32_t>(left_val) >> right_val); |
4440 } | 4424 } |
4441 } | 4425 } |
4442 return new(zone) HShr(context, left, right); | 4426 return new(zone) HShr(context, left, right); |
4443 } | 4427 } |
4444 | 4428 |
4445 | 4429 |
4446 HInstruction* HSeqStringGetChar::New(Zone* zone, | 4430 HInstruction* HSeqStringGetChar::New(Isolate* isolate, Zone* zone, |
4447 HValue* context, | 4431 HValue* context, String::Encoding encoding, |
4448 String::Encoding encoding, | 4432 HValue* string, HValue* index) { |
4449 HValue* string, | |
4450 HValue* index) { | |
4451 if (FLAG_fold_constants && string->IsConstant() && index->IsConstant()) { | 4433 if (FLAG_fold_constants && string->IsConstant() && index->IsConstant()) { |
4452 HConstant* c_string = HConstant::cast(string); | 4434 HConstant* c_string = HConstant::cast(string); |
4453 HConstant* c_index = HConstant::cast(index); | 4435 HConstant* c_index = HConstant::cast(index); |
4454 if (c_string->HasStringValue() && c_index->HasInteger32Value()) { | 4436 if (c_string->HasStringValue() && c_index->HasInteger32Value()) { |
4455 Handle<String> s = c_string->StringValue(); | 4437 Handle<String> s = c_string->StringValue(); |
4456 int32_t i = c_index->Integer32Value(); | 4438 int32_t i = c_index->Integer32Value(); |
4457 DCHECK_LE(0, i); | 4439 DCHECK_LE(0, i); |
4458 DCHECK_LT(i, s->length()); | 4440 DCHECK_LT(i, s->length()); |
4459 return H_CONSTANT_INT(s->Get(i)); | 4441 return H_CONSTANT_INT(s->Get(i)); |
4460 } | 4442 } |
(...skipping 18 matching lines...) Expand all Loading... |
4479 if (!CheckUsesForFlag(kTruncatingToInt32)) return; | 4461 if (!CheckUsesForFlag(kTruncatingToInt32)) return; |
4480 for (int i = 0; i < OperandCount(); ++i) { | 4462 for (int i = 0; i < OperandCount(); ++i) { |
4481 if (!OperandAt(i)->IsConstant()) return; | 4463 if (!OperandAt(i)->IsConstant()) return; |
4482 } | 4464 } |
4483 HGraph* graph = block()->graph(); | 4465 HGraph* graph = block()->graph(); |
4484 for (int i = 0; i < OperandCount(); ++i) { | 4466 for (int i = 0; i < OperandCount(); ++i) { |
4485 HConstant* operand = HConstant::cast(OperandAt(i)); | 4467 HConstant* operand = HConstant::cast(OperandAt(i)); |
4486 if (operand->HasInteger32Value()) { | 4468 if (operand->HasInteger32Value()) { |
4487 continue; | 4469 continue; |
4488 } else if (operand->HasDoubleValue()) { | 4470 } else if (operand->HasDoubleValue()) { |
4489 HConstant* integer_input = | 4471 HConstant* integer_input = HConstant::New( |
4490 HConstant::New(graph->zone(), graph->GetInvalidContext(), | 4472 graph->isolate(), graph->zone(), graph->GetInvalidContext(), |
4491 DoubleToInt32(operand->DoubleValue())); | 4473 DoubleToInt32(operand->DoubleValue())); |
4492 integer_input->InsertAfter(operand); | 4474 integer_input->InsertAfter(operand); |
4493 SetOperandAt(i, integer_input); | 4475 SetOperandAt(i, integer_input); |
4494 } else if (operand->HasBooleanValue()) { | 4476 } else if (operand->HasBooleanValue()) { |
4495 SetOperandAt(i, operand->BooleanValue() ? graph->GetConstant1() | 4477 SetOperandAt(i, operand->BooleanValue() ? graph->GetConstant1() |
4496 : graph->GetConstant0()); | 4478 : graph->GetConstant0()); |
4497 } else if (operand->ImmortalImmovable()) { | 4479 } else if (operand->ImmortalImmovable()) { |
4498 SetOperandAt(i, graph->GetConstant0()); | 4480 SetOperandAt(i, graph->GetConstant0()); |
4499 } | 4481 } |
4500 } | 4482 } |
4501 // Overwrite observed input representations because they are likely Tagged. | 4483 // Overwrite observed input representations because they are likely Tagged. |
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4825 break; | 4807 break; |
4826 case HObjectAccess::kExternalMemory: | 4808 case HObjectAccess::kExternalMemory: |
4827 os << "[external-memory]"; | 4809 os << "[external-memory]"; |
4828 break; | 4810 break; |
4829 } | 4811 } |
4830 | 4812 |
4831 return os << "@" << access.offset(); | 4813 return os << "@" << access.offset(); |
4832 } | 4814 } |
4833 | 4815 |
4834 } } // namespace v8::internal | 4816 } } // namespace v8::internal |
OLD | NEW |