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