| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 #include "v8.h" | 28 #include "v8.h" |
| 29 | 29 |
| 30 #include "double.h" | 30 #include "double.h" |
| 31 #include "factory.h" | 31 #include "factory.h" |
| 32 #include "hydrogen-infer-representation.h" | 32 #include "hydrogen-infer-representation.h" |
| 33 #include "property-details-inl.h" |
| 33 | 34 |
| 34 #if V8_TARGET_ARCH_IA32 | 35 #if V8_TARGET_ARCH_IA32 |
| 35 #include "ia32/lithium-ia32.h" | 36 #include "ia32/lithium-ia32.h" |
| 36 #elif V8_TARGET_ARCH_X64 | 37 #elif V8_TARGET_ARCH_X64 |
| 37 #include "x64/lithium-x64.h" | 38 #include "x64/lithium-x64.h" |
| 38 #elif V8_TARGET_ARCH_A64 | 39 #elif V8_TARGET_ARCH_A64 |
| 39 #include "a64/lithium-a64.h" | 40 #include "a64/lithium-a64.h" |
| 40 #elif V8_TARGET_ARCH_ARM | 41 #elif V8_TARGET_ARCH_ARM |
| 41 #include "arm/lithium-arm.h" | 42 #include "arm/lithium-arm.h" |
| 42 #elif V8_TARGET_ARCH_MIPS | 43 #elif V8_TARGET_ARCH_MIPS |
| (...skipping 1165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1208 if (to_ == JS_FUNCTION_TYPE) stream->Add(" function"); | 1209 if (to_ == JS_FUNCTION_TYPE) stream->Add(" function"); |
| 1209 break; | 1210 break; |
| 1210 default: | 1211 default: |
| 1211 break; | 1212 break; |
| 1212 } | 1213 } |
| 1213 } | 1214 } |
| 1214 | 1215 |
| 1215 | 1216 |
| 1216 void HTypeofIsAndBranch::PrintDataTo(StringStream* stream) { | 1217 void HTypeofIsAndBranch::PrintDataTo(StringStream* stream) { |
| 1217 value()->PrintNameTo(stream); | 1218 value()->PrintNameTo(stream); |
| 1218 stream->Add(" == %o", *type_literal_); | 1219 stream->Add(" == %o", *type_literal_.handle()); |
| 1219 HControlInstruction::PrintDataTo(stream); | 1220 HControlInstruction::PrintDataTo(stream); |
| 1220 } | 1221 } |
| 1221 | 1222 |
| 1222 | 1223 |
| 1224 static String* TypeOfString(HConstant* constant, Isolate* isolate) { |
| 1225 Heap* heap = isolate->heap(); |
| 1226 if (constant->HasNumberValue()) return heap->number_string(); |
| 1227 if (constant->IsUndetectable()) return heap->undefined_string(); |
| 1228 if (constant->HasStringValue()) return heap->string_string(); |
| 1229 switch (constant->GetInstanceType()) { |
| 1230 case ODDBALL_TYPE: { |
| 1231 Unique<Object> unique = constant->GetUnique(); |
| 1232 if (unique.IsKnownGlobal(heap->true_value()) || |
| 1233 unique.IsKnownGlobal(heap->false_value())) { |
| 1234 return heap->boolean_string(); |
| 1235 } |
| 1236 if (unique.IsKnownGlobal(heap->null_value())) { |
| 1237 return FLAG_harmony_typeof ? heap->null_string() |
| 1238 : heap->object_string(); |
| 1239 } |
| 1240 ASSERT(unique.IsKnownGlobal(heap->undefined_value())); |
| 1241 return heap->undefined_string(); |
| 1242 } |
| 1243 case SYMBOL_TYPE: |
| 1244 return heap->symbol_string(); |
| 1245 case JS_FUNCTION_TYPE: |
| 1246 case JS_FUNCTION_PROXY_TYPE: |
| 1247 return heap->function_string(); |
| 1248 default: |
| 1249 return heap->object_string(); |
| 1250 } |
| 1251 } |
| 1252 |
| 1253 |
| 1223 bool HTypeofIsAndBranch::KnownSuccessorBlock(HBasicBlock** block) { | 1254 bool HTypeofIsAndBranch::KnownSuccessorBlock(HBasicBlock** block) { |
| 1224 if (value()->representation().IsSpecialization()) { | 1255 if (FLAG_fold_constants && value()->IsConstant()) { |
| 1225 if (compares_number_type()) { | 1256 HConstant* constant = HConstant::cast(value()); |
| 1226 *block = FirstSuccessor(); | 1257 String* type_string = TypeOfString(constant, isolate()); |
| 1227 } else { | 1258 bool same_type = type_literal_.IsKnownGlobal(type_string); |
| 1228 *block = SecondSuccessor(); | 1259 *block = same_type ? FirstSuccessor() : SecondSuccessor(); |
| 1229 } | 1260 return true; |
| 1261 } else if (value()->representation().IsSpecialization()) { |
| 1262 bool number_type = |
| 1263 type_literal_.IsKnownGlobal(isolate()->heap()->number_string()); |
| 1264 *block = number_type ? FirstSuccessor() : SecondSuccessor(); |
| 1230 return true; | 1265 return true; |
| 1231 } | 1266 } |
| 1232 *block = NULL; | 1267 *block = NULL; |
| 1233 return false; | 1268 return false; |
| 1234 } | 1269 } |
| 1235 | 1270 |
| 1236 | 1271 |
| 1237 void HCheckMapValue::PrintDataTo(StringStream* stream) { | 1272 void HCheckMapValue::PrintDataTo(StringStream* stream) { |
| 1238 value()->PrintNameTo(stream); | 1273 value()->PrintNameTo(stream); |
| 1239 stream->Add(" "); | 1274 stream->Add(" "); |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1392 return this; | 1427 return this; |
| 1393 } | 1428 } |
| 1394 | 1429 |
| 1395 | 1430 |
| 1396 void HTypeof::PrintDataTo(StringStream* stream) { | 1431 void HTypeof::PrintDataTo(StringStream* stream) { |
| 1397 value()->PrintNameTo(stream); | 1432 value()->PrintNameTo(stream); |
| 1398 } | 1433 } |
| 1399 | 1434 |
| 1400 | 1435 |
| 1401 HInstruction* HForceRepresentation::New(Zone* zone, HValue* context, | 1436 HInstruction* HForceRepresentation::New(Zone* zone, HValue* context, |
| 1402 HValue* value, Representation required_representation) { | 1437 HValue* value, Representation representation) { |
| 1403 if (FLAG_fold_constants && value->IsConstant()) { | 1438 if (FLAG_fold_constants && value->IsConstant()) { |
| 1404 HConstant* c = HConstant::cast(value); | 1439 HConstant* c = HConstant::cast(value); |
| 1405 if (c->HasNumberValue()) { | 1440 if (c->HasNumberValue()) { |
| 1406 double double_res = c->DoubleValue(); | 1441 double double_res = c->DoubleValue(); |
| 1407 if (IsInt32Double(double_res)) { | 1442 if (representation.CanContainDouble(double_res)) { |
| 1408 return HConstant::New(zone, context, | 1443 return HConstant::New(zone, context, |
| 1409 static_cast<int32_t>(double_res), | 1444 static_cast<int32_t>(double_res), |
| 1410 required_representation); | 1445 representation); |
| 1411 } | 1446 } |
| 1412 } | 1447 } |
| 1413 } | 1448 } |
| 1414 return new(zone) HForceRepresentation(value, required_representation); | 1449 return new(zone) HForceRepresentation(value, representation); |
| 1415 } | 1450 } |
| 1416 | 1451 |
| 1417 | 1452 |
| 1418 void HForceRepresentation::PrintDataTo(StringStream* stream) { | 1453 void HForceRepresentation::PrintDataTo(StringStream* stream) { |
| 1419 stream->Add("%s ", representation().Mnemonic()); | 1454 stream->Add("%s ", representation().Mnemonic()); |
| 1420 value()->PrintNameTo(stream); | 1455 value()->PrintNameTo(stream); |
| 1421 } | 1456 } |
| 1422 | 1457 |
| 1423 | 1458 |
| 1424 void HChange::PrintDataTo(StringStream* stream) { | 1459 void HChange::PrintDataTo(StringStream* stream) { |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1532 bool HCheckMaps::HandleSideEffectDominator(GVNFlag side_effect, | 1567 bool HCheckMaps::HandleSideEffectDominator(GVNFlag side_effect, |
| 1533 HValue* dominator) { | 1568 HValue* dominator) { |
| 1534 ASSERT(side_effect == kMaps); | 1569 ASSERT(side_effect == kMaps); |
| 1535 // TODO(mstarzinger): For now we specialize on HStoreNamedField, but once | 1570 // TODO(mstarzinger): For now we specialize on HStoreNamedField, but once |
| 1536 // type information is rich enough we should generalize this to any HType | 1571 // type information is rich enough we should generalize this to any HType |
| 1537 // for which the map is known. | 1572 // for which the map is known. |
| 1538 if (HasNoUses() && dominator->IsStoreNamedField()) { | 1573 if (HasNoUses() && dominator->IsStoreNamedField()) { |
| 1539 HStoreNamedField* store = HStoreNamedField::cast(dominator); | 1574 HStoreNamedField* store = HStoreNamedField::cast(dominator); |
| 1540 if (!store->has_transition() || store->object() != value()) return false; | 1575 if (!store->has_transition() || store->object() != value()) return false; |
| 1541 HConstant* transition = HConstant::cast(store->transition()); | 1576 HConstant* transition = HConstant::cast(store->transition()); |
| 1542 if (map_set_.Contains(transition->GetUnique())) { | 1577 if (map_set_.Contains(Unique<Map>::cast(transition->GetUnique()))) { |
| 1543 DeleteAndReplaceWith(NULL); | 1578 DeleteAndReplaceWith(NULL); |
| 1544 return true; | 1579 return true; |
| 1545 } | 1580 } |
| 1546 } | 1581 } |
| 1547 return false; | 1582 return false; |
| 1548 } | 1583 } |
| 1549 | 1584 |
| 1550 | 1585 |
| 1551 void HCheckMaps::PrintDataTo(StringStream* stream) { | 1586 void HCheckMaps::PrintDataTo(StringStream* stream) { |
| 1552 value()->PrintNameTo(stream); | 1587 value()->PrintNameTo(stream); |
| 1553 stream->Add(" [%p", *map_set_.at(0).handle()); | 1588 stream->Add(" [%p", *map_set_.at(0).handle()); |
| 1554 for (int i = 1; i < map_set_.size(); ++i) { | 1589 for (int i = 1; i < map_set_.size(); ++i) { |
| 1555 stream->Add(",%p", *map_set_.at(i).handle()); | 1590 stream->Add(",%p", *map_set_.at(i).handle()); |
| 1556 } | 1591 } |
| 1557 stream->Add("]%s", CanOmitMapChecks() ? "(omitted)" : ""); | 1592 stream->Add("]%s", CanOmitMapChecks() ? "(omitted)" : ""); |
| 1558 } | 1593 } |
| 1559 | 1594 |
| 1560 | 1595 |
| 1561 void HCheckValue::PrintDataTo(StringStream* stream) { | 1596 void HCheckValue::PrintDataTo(StringStream* stream) { |
| 1562 value()->PrintNameTo(stream); | 1597 value()->PrintNameTo(stream); |
| 1563 stream->Add(" "); | 1598 stream->Add(" "); |
| 1564 object().handle()->ShortPrint(stream); | 1599 object().handle()->ShortPrint(stream); |
| 1565 } | 1600 } |
| 1566 | 1601 |
| 1567 | 1602 |
| 1568 HValue* HCheckValue::Canonicalize() { | 1603 HValue* HCheckValue::Canonicalize() { |
| 1569 return (value()->IsConstant() && | 1604 return (value()->IsConstant() && |
| 1570 HConstant::cast(value())->GetUnique() == object_) | 1605 HConstant::cast(value())->EqualsUnique(object_)) ? NULL : this; |
| 1571 ? NULL | |
| 1572 : this; | |
| 1573 } | 1606 } |
| 1574 | 1607 |
| 1575 | 1608 |
| 1576 const char* HCheckInstanceType::GetCheckName() { | 1609 const char* HCheckInstanceType::GetCheckName() { |
| 1577 switch (check_) { | 1610 switch (check_) { |
| 1578 case IS_SPEC_OBJECT: return "object"; | 1611 case IS_SPEC_OBJECT: return "object"; |
| 1579 case IS_JS_ARRAY: return "array"; | 1612 case IS_JS_ARRAY: return "array"; |
| 1580 case IS_STRING: return "string"; | 1613 case IS_STRING: return "string"; |
| 1581 case IS_INTERNALIZED_STRING: return "internalized_string"; | 1614 case IS_INTERNALIZED_STRING: return "internalized_string"; |
| 1582 } | 1615 } |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1634 Range* HChange::InferRange(Zone* zone) { | 1667 Range* HChange::InferRange(Zone* zone) { |
| 1635 Range* input_range = value()->range(); | 1668 Range* input_range = value()->range(); |
| 1636 if (from().IsInteger32() && !value()->CheckFlag(HInstruction::kUint32) && | 1669 if (from().IsInteger32() && !value()->CheckFlag(HInstruction::kUint32) && |
| 1637 (to().IsSmi() || | 1670 (to().IsSmi() || |
| 1638 (to().IsTagged() && | 1671 (to().IsTagged() && |
| 1639 input_range != NULL && | 1672 input_range != NULL && |
| 1640 input_range->IsInSmiRange()))) { | 1673 input_range->IsInSmiRange()))) { |
| 1641 set_type(HType::Smi()); | 1674 set_type(HType::Smi()); |
| 1642 ClearChangesFlag(kNewSpacePromotion); | 1675 ClearChangesFlag(kNewSpacePromotion); |
| 1643 } | 1676 } |
| 1677 if (to().IsSmiOrTagged() && |
| 1678 input_range != NULL && |
| 1679 input_range->IsInSmiRange() && |
| 1680 (!SmiValuesAre32Bits() || |
| 1681 !value()->CheckFlag(HValue::kUint32) || |
| 1682 input_range->upper() != kMaxInt)) { |
| 1683 // The Range class can't express upper bounds in the (kMaxInt, kMaxUint32] |
| 1684 // interval, so we treat kMaxInt as a sentinel for this entire interval. |
| 1685 ClearFlag(kCanOverflow); |
| 1686 } |
| 1644 Range* result = (input_range != NULL) | 1687 Range* result = (input_range != NULL) |
| 1645 ? input_range->Copy(zone) | 1688 ? input_range->Copy(zone) |
| 1646 : HValue::InferRange(zone); | 1689 : HValue::InferRange(zone); |
| 1647 result->set_can_be_minus_zero(!to().IsSmiOrInteger32() || | 1690 result->set_can_be_minus_zero(!to().IsSmiOrInteger32() || |
| 1648 !(CheckFlag(kAllUsesTruncatingToInt32) || | 1691 !(CheckFlag(kAllUsesTruncatingToInt32) || |
| 1649 CheckFlag(kAllUsesTruncatingToSmi))); | 1692 CheckFlag(kAllUsesTruncatingToSmi))); |
| 1650 if (to().IsSmi()) result->ClampToSmi(); | 1693 if (to().IsSmi()) result->ClampToSmi(); |
| 1651 return result; | 1694 return result; |
| 1652 } | 1695 } |
| 1653 | 1696 |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1758 | 1801 |
| 1759 Range* HDiv::InferRange(Zone* zone) { | 1802 Range* HDiv::InferRange(Zone* zone) { |
| 1760 if (representation().IsInteger32()) { | 1803 if (representation().IsInteger32()) { |
| 1761 Range* a = left()->range(); | 1804 Range* a = left()->range(); |
| 1762 Range* b = right()->range(); | 1805 Range* b = right()->range(); |
| 1763 Range* result = new(zone) Range(); | 1806 Range* result = new(zone) Range(); |
| 1764 result->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) && | 1807 result->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) && |
| 1765 (a->CanBeMinusZero() || | 1808 (a->CanBeMinusZero() || |
| 1766 (a->CanBeZero() && b->CanBeNegative()))); | 1809 (a->CanBeZero() && b->CanBeNegative()))); |
| 1767 if (!a->Includes(kMinInt) || !b->Includes(-1)) { | 1810 if (!a->Includes(kMinInt) || !b->Includes(-1)) { |
| 1768 ClearFlag(HValue::kCanOverflow); | 1811 ClearFlag(kCanOverflow); |
| 1769 } | 1812 } |
| 1770 | 1813 |
| 1771 if (!b->CanBeZero()) { | 1814 if (!b->CanBeZero()) { |
| 1772 ClearFlag(HValue::kCanBeDivByZero); | 1815 ClearFlag(kCanBeDivByZero); |
| 1773 } | 1816 } |
| 1774 return result; | 1817 return result; |
| 1775 } else { | 1818 } else { |
| 1819 return HValue::InferRange(zone); |
| 1820 } |
| 1821 } |
| 1822 |
| 1823 |
| 1824 Range* HMathFloorOfDiv::InferRange(Zone* zone) { |
| 1825 if (representation().IsInteger32()) { |
| 1826 Range* a = left()->range(); |
| 1827 Range* b = right()->range(); |
| 1828 Range* result = new(zone) Range(); |
| 1829 result->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) && |
| 1830 (a->CanBeMinusZero() || |
| 1831 (a->CanBeZero() && b->CanBeNegative()))); |
| 1832 if (!a->Includes(kMinInt)) { |
| 1833 ClearFlag(kLeftCanBeMinInt); |
| 1834 } |
| 1835 |
| 1836 if (!a->Includes(kMinInt) || !b->Includes(-1)) { |
| 1837 ClearFlag(kCanOverflow); |
| 1838 } |
| 1839 |
| 1840 if (!b->CanBeZero()) { |
| 1841 ClearFlag(kCanBeDivByZero); |
| 1842 } |
| 1843 return result; |
| 1844 } else { |
| 1776 return HValue::InferRange(zone); | 1845 return HValue::InferRange(zone); |
| 1777 } | 1846 } |
| 1778 } | 1847 } |
| 1779 | 1848 |
| 1780 | 1849 |
| 1781 Range* HMod::InferRange(Zone* zone) { | 1850 Range* HMod::InferRange(Zone* zone) { |
| 1782 if (representation().IsInteger32()) { | 1851 if (representation().IsInteger32()) { |
| 1783 Range* a = left()->range(); | 1852 Range* a = left()->range(); |
| 1784 Range* b = right()->range(); | 1853 Range* b = right()->range(); |
| 1785 | 1854 |
| 1786 // The magnitude of the modulus is bounded by the right operand. Note that | 1855 // The magnitude of the modulus is bounded by the right operand. Note that |
| 1787 // apart for the cases involving kMinInt, the calculation below is the same | 1856 // apart for the cases involving kMinInt, the calculation below is the same |
| 1788 // as Max(Abs(b->lower()), Abs(b->upper())) - 1. | 1857 // as Max(Abs(b->lower()), Abs(b->upper())) - 1. |
| 1789 int32_t positive_bound = -(Min(NegAbs(b->lower()), NegAbs(b->upper())) + 1); | 1858 int32_t positive_bound = -(Min(NegAbs(b->lower()), NegAbs(b->upper())) + 1); |
| 1790 | 1859 |
| 1791 // The result of the modulo operation has the sign of its left operand. | 1860 // The result of the modulo operation has the sign of its left operand. |
| 1792 bool left_can_be_negative = a->CanBeMinusZero() || a->CanBeNegative(); | 1861 bool left_can_be_negative = a->CanBeMinusZero() || a->CanBeNegative(); |
| 1793 Range* result = new(zone) Range(left_can_be_negative ? -positive_bound : 0, | 1862 Range* result = new(zone) Range(left_can_be_negative ? -positive_bound : 0, |
| 1794 a->CanBePositive() ? positive_bound : 0); | 1863 a->CanBePositive() ? positive_bound : 0); |
| 1795 | 1864 |
| 1796 result->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) && | 1865 result->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) && |
| 1797 left_can_be_negative); | 1866 left_can_be_negative); |
| 1798 | 1867 |
| 1868 if (!a->CanBeNegative()) { |
| 1869 ClearFlag(HValue::kLeftCanBeNegative); |
| 1870 } |
| 1871 |
| 1799 if (!a->Includes(kMinInt) || !b->Includes(-1)) { | 1872 if (!a->Includes(kMinInt) || !b->Includes(-1)) { |
| 1800 ClearFlag(HValue::kCanOverflow); | 1873 ClearFlag(HValue::kCanOverflow); |
| 1801 } | 1874 } |
| 1802 | 1875 |
| 1803 if (!b->CanBeZero()) { | 1876 if (!b->CanBeZero()) { |
| 1804 ClearFlag(HValue::kCanBeDivByZero); | 1877 ClearFlag(HValue::kCanBeDivByZero); |
| 1805 } | 1878 } |
| 1806 return result; | 1879 return result; |
| 1807 } else { | 1880 } else { |
| 1808 return HValue::InferRange(zone); | 1881 return HValue::InferRange(zone); |
| (...skipping 612 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2421 stream->Add(" push "); | 2494 stream->Add(" push "); |
| 2422 } | 2495 } |
| 2423 values_[i]->PrintNameTo(stream); | 2496 values_[i]->PrintNameTo(stream); |
| 2424 if (i > 0) stream->Add(","); | 2497 if (i > 0) stream->Add(","); |
| 2425 } | 2498 } |
| 2426 } | 2499 } |
| 2427 } | 2500 } |
| 2428 | 2501 |
| 2429 | 2502 |
| 2430 void HSimulate::ReplayEnvironment(HEnvironment* env) { | 2503 void HSimulate::ReplayEnvironment(HEnvironment* env) { |
| 2504 if (done_with_replay_) return; |
| 2431 ASSERT(env != NULL); | 2505 ASSERT(env != NULL); |
| 2432 env->set_ast_id(ast_id()); | 2506 env->set_ast_id(ast_id()); |
| 2433 env->Drop(pop_count()); | 2507 env->Drop(pop_count()); |
| 2434 for (int i = values()->length() - 1; i >= 0; --i) { | 2508 for (int i = values()->length() - 1; i >= 0; --i) { |
| 2435 HValue* value = values()->at(i); | 2509 HValue* value = values()->at(i); |
| 2436 if (HasAssignedIndexAt(i)) { | 2510 if (HasAssignedIndexAt(i)) { |
| 2437 env->Bind(GetAssignedIndexAt(i), value); | 2511 env->Bind(GetAssignedIndexAt(i), value); |
| 2438 } else { | 2512 } else { |
| 2439 env->Push(value); | 2513 env->Push(value); |
| 2440 } | 2514 } |
| 2441 } | 2515 } |
| 2516 done_with_replay_ = true; |
| 2442 } | 2517 } |
| 2443 | 2518 |
| 2444 | 2519 |
| 2445 static void ReplayEnvironmentNested(const ZoneList<HValue*>* values, | 2520 static void ReplayEnvironmentNested(const ZoneList<HValue*>* values, |
| 2446 HCapturedObject* other) { | 2521 HCapturedObject* other) { |
| 2447 for (int i = 0; i < values->length(); ++i) { | 2522 for (int i = 0; i < values->length(); ++i) { |
| 2448 HValue* value = values->at(i); | 2523 HValue* value = values->at(i); |
| 2449 if (value->IsCapturedObject()) { | 2524 if (value->IsCapturedObject()) { |
| 2450 if (HCapturedObject::cast(value)->capture_id() == other->capture_id()) { | 2525 if (HCapturedObject::cast(value)->capture_id() == other->capture_id()) { |
| 2451 values->at(i) = other; | 2526 values->at(i) = other; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2493 } | 2568 } |
| 2494 | 2569 |
| 2495 | 2570 |
| 2496 HConstant::HConstant(Handle<Object> handle, Representation r) | 2571 HConstant::HConstant(Handle<Object> handle, Representation r) |
| 2497 : HTemplateInstruction<0>(HType::TypeFromValue(handle)), | 2572 : HTemplateInstruction<0>(HType::TypeFromValue(handle)), |
| 2498 object_(Unique<Object>::CreateUninitialized(handle)), | 2573 object_(Unique<Object>::CreateUninitialized(handle)), |
| 2499 has_smi_value_(false), | 2574 has_smi_value_(false), |
| 2500 has_int32_value_(false), | 2575 has_int32_value_(false), |
| 2501 has_double_value_(false), | 2576 has_double_value_(false), |
| 2502 has_external_reference_value_(false), | 2577 has_external_reference_value_(false), |
| 2503 is_internalized_string_(false), | |
| 2504 is_not_in_new_space_(true), | 2578 is_not_in_new_space_(true), |
| 2505 is_cell_(false), | 2579 boolean_value_(handle->BooleanValue()), |
| 2506 boolean_value_(handle->BooleanValue()) { | 2580 is_undetectable_(false), |
| 2581 instance_type_(kUnknownInstanceType) { |
| 2507 if (handle->IsHeapObject()) { | 2582 if (handle->IsHeapObject()) { |
| 2508 Heap* heap = Handle<HeapObject>::cast(handle)->GetHeap(); | 2583 Handle<HeapObject> heap_obj = Handle<HeapObject>::cast(handle); |
| 2584 Heap* heap = heap_obj->GetHeap(); |
| 2509 is_not_in_new_space_ = !heap->InNewSpace(*handle); | 2585 is_not_in_new_space_ = !heap->InNewSpace(*handle); |
| 2586 instance_type_ = heap_obj->map()->instance_type(); |
| 2587 is_undetectable_ = heap_obj->map()->is_undetectable(); |
| 2510 } | 2588 } |
| 2511 if (handle->IsNumber()) { | 2589 if (handle->IsNumber()) { |
| 2512 double n = handle->Number(); | 2590 double n = handle->Number(); |
| 2513 has_int32_value_ = IsInteger32(n); | 2591 has_int32_value_ = IsInteger32(n); |
| 2514 int32_value_ = DoubleToInt32(n); | 2592 int32_value_ = DoubleToInt32(n); |
| 2515 has_smi_value_ = has_int32_value_ && Smi::IsValid(int32_value_); | 2593 has_smi_value_ = has_int32_value_ && Smi::IsValid(int32_value_); |
| 2516 double_value_ = n; | 2594 double_value_ = n; |
| 2517 has_double_value_ = true; | 2595 has_double_value_ = true; |
| 2518 // TODO(titzer): if this heap number is new space, tenure a new one. | 2596 // TODO(titzer): if this heap number is new space, tenure a new one. |
| 2519 } else { | |
| 2520 is_internalized_string_ = handle->IsInternalizedString(); | |
| 2521 } | 2597 } |
| 2522 | 2598 |
| 2523 is_cell_ = !handle.is_null() && | |
| 2524 (handle->IsCell() || handle->IsPropertyCell()); | |
| 2525 Initialize(r); | 2599 Initialize(r); |
| 2526 } | 2600 } |
| 2527 | 2601 |
| 2528 | 2602 |
| 2529 HConstant::HConstant(Unique<Object> unique, | 2603 HConstant::HConstant(Unique<Object> unique, |
| 2530 Representation r, | 2604 Representation r, |
| 2531 HType type, | 2605 HType type, |
| 2532 bool is_internalize_string, | |
| 2533 bool is_not_in_new_space, | 2606 bool is_not_in_new_space, |
| 2534 bool is_cell, | 2607 bool boolean_value, |
| 2535 bool boolean_value) | 2608 bool is_undetectable, |
| 2609 InstanceType instance_type) |
| 2536 : HTemplateInstruction<0>(type), | 2610 : HTemplateInstruction<0>(type), |
| 2537 object_(unique), | 2611 object_(unique), |
| 2538 has_smi_value_(false), | 2612 has_smi_value_(false), |
| 2539 has_int32_value_(false), | 2613 has_int32_value_(false), |
| 2540 has_double_value_(false), | 2614 has_double_value_(false), |
| 2541 has_external_reference_value_(false), | 2615 has_external_reference_value_(false), |
| 2542 is_internalized_string_(is_internalize_string), | |
| 2543 is_not_in_new_space_(is_not_in_new_space), | 2616 is_not_in_new_space_(is_not_in_new_space), |
| 2544 is_cell_(is_cell), | 2617 boolean_value_(boolean_value), |
| 2545 boolean_value_(boolean_value) { | 2618 is_undetectable_(is_undetectable), |
| 2619 instance_type_(instance_type) { |
| 2546 ASSERT(!unique.handle().is_null()); | 2620 ASSERT(!unique.handle().is_null()); |
| 2547 ASSERT(!type.IsTaggedNumber()); | 2621 ASSERT(!type.IsTaggedNumber()); |
| 2548 Initialize(r); | 2622 Initialize(r); |
| 2549 } | 2623 } |
| 2550 | 2624 |
| 2551 | 2625 |
| 2552 HConstant::HConstant(int32_t integer_value, | 2626 HConstant::HConstant(int32_t integer_value, |
| 2553 Representation r, | 2627 Representation r, |
| 2554 bool is_not_in_new_space, | 2628 bool is_not_in_new_space, |
| 2555 Unique<Object> object) | 2629 Unique<Object> object) |
| 2556 : object_(object), | 2630 : object_(object), |
| 2557 has_smi_value_(Smi::IsValid(integer_value)), | 2631 has_smi_value_(Smi::IsValid(integer_value)), |
| 2558 has_int32_value_(true), | 2632 has_int32_value_(true), |
| 2559 has_double_value_(true), | 2633 has_double_value_(true), |
| 2560 has_external_reference_value_(false), | 2634 has_external_reference_value_(false), |
| 2561 is_internalized_string_(false), | |
| 2562 is_not_in_new_space_(is_not_in_new_space), | 2635 is_not_in_new_space_(is_not_in_new_space), |
| 2563 is_cell_(false), | |
| 2564 boolean_value_(integer_value != 0), | 2636 boolean_value_(integer_value != 0), |
| 2637 is_undetectable_(false), |
| 2565 int32_value_(integer_value), | 2638 int32_value_(integer_value), |
| 2566 double_value_(FastI2D(integer_value)) { | 2639 double_value_(FastI2D(integer_value)), |
| 2567 set_type(has_smi_value_ ? HType::Smi() : HType::TaggedNumber()); | 2640 instance_type_(kUnknownInstanceType) { |
| 2641 // It's possible to create a constant with a value in Smi-range but stored |
| 2642 // in a (pre-existing) HeapNumber. See crbug.com/349878. |
| 2643 bool could_be_heapobject = r.IsTagged() && !object.handle().is_null(); |
| 2644 bool is_smi = has_smi_value_ && !could_be_heapobject; |
| 2645 set_type(is_smi ? HType::Smi() : HType::TaggedNumber()); |
| 2568 Initialize(r); | 2646 Initialize(r); |
| 2569 } | 2647 } |
| 2570 | 2648 |
| 2571 | 2649 |
| 2572 HConstant::HConstant(double double_value, | 2650 HConstant::HConstant(double double_value, |
| 2573 Representation r, | 2651 Representation r, |
| 2574 bool is_not_in_new_space, | 2652 bool is_not_in_new_space, |
| 2575 Unique<Object> object) | 2653 Unique<Object> object) |
| 2576 : object_(object), | 2654 : object_(object), |
| 2577 has_int32_value_(IsInteger32(double_value)), | 2655 has_int32_value_(IsInteger32(double_value)), |
| 2578 has_double_value_(true), | 2656 has_double_value_(true), |
| 2579 has_external_reference_value_(false), | 2657 has_external_reference_value_(false), |
| 2580 is_internalized_string_(false), | |
| 2581 is_not_in_new_space_(is_not_in_new_space), | 2658 is_not_in_new_space_(is_not_in_new_space), |
| 2582 is_cell_(false), | |
| 2583 boolean_value_(double_value != 0 && !std::isnan(double_value)), | 2659 boolean_value_(double_value != 0 && !std::isnan(double_value)), |
| 2660 is_undetectable_(false), |
| 2584 int32_value_(DoubleToInt32(double_value)), | 2661 int32_value_(DoubleToInt32(double_value)), |
| 2585 double_value_(double_value) { | 2662 double_value_(double_value), |
| 2663 instance_type_(kUnknownInstanceType) { |
| 2586 has_smi_value_ = has_int32_value_ && Smi::IsValid(int32_value_); | 2664 has_smi_value_ = has_int32_value_ && Smi::IsValid(int32_value_); |
| 2587 set_type(has_smi_value_ ? HType::Smi() : HType::TaggedNumber()); | 2665 // It's possible to create a constant with a value in Smi-range but stored |
| 2666 // in a (pre-existing) HeapNumber. See crbug.com/349878. |
| 2667 bool could_be_heapobject = r.IsTagged() && !object.handle().is_null(); |
| 2668 bool is_smi = has_smi_value_ && !could_be_heapobject; |
| 2669 set_type(is_smi ? HType::Smi() : HType::TaggedNumber()); |
| 2588 Initialize(r); | 2670 Initialize(r); |
| 2589 } | 2671 } |
| 2590 | 2672 |
| 2591 | 2673 |
| 2592 HConstant::HConstant(ExternalReference reference) | 2674 HConstant::HConstant(ExternalReference reference) |
| 2593 : HTemplateInstruction<0>(HType::None()), | 2675 : HTemplateInstruction<0>(HType::None()), |
| 2594 object_(Unique<Object>(Handle<Object>::null())), | 2676 object_(Unique<Object>(Handle<Object>::null())), |
| 2595 has_smi_value_(false), | 2677 has_smi_value_(false), |
| 2596 has_int32_value_(false), | 2678 has_int32_value_(false), |
| 2597 has_double_value_(false), | 2679 has_double_value_(false), |
| 2598 has_external_reference_value_(true), | 2680 has_external_reference_value_(true), |
| 2599 is_internalized_string_(false), | |
| 2600 is_not_in_new_space_(true), | 2681 is_not_in_new_space_(true), |
| 2601 is_cell_(false), | |
| 2602 boolean_value_(true), | 2682 boolean_value_(true), |
| 2603 external_reference_value_(reference) { | 2683 is_undetectable_(false), |
| 2684 external_reference_value_(reference), |
| 2685 instance_type_(kUnknownInstanceType) { |
| 2604 Initialize(Representation::External()); | 2686 Initialize(Representation::External()); |
| 2605 } | 2687 } |
| 2606 | 2688 |
| 2607 | 2689 |
| 2608 void HConstant::Initialize(Representation r) { | 2690 void HConstant::Initialize(Representation r) { |
| 2609 if (r.IsNone()) { | 2691 if (r.IsNone()) { |
| 2610 if (has_smi_value_ && SmiValuesAre31Bits()) { | 2692 if (has_smi_value_ && SmiValuesAre31Bits()) { |
| 2611 r = Representation::Smi(); | 2693 r = Representation::Smi(); |
| 2612 } else if (has_int32_value_) { | 2694 } else if (has_int32_value_) { |
| 2613 r = Representation::Integer32(); | 2695 r = Representation::Integer32(); |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2692 if (has_double_value_) { | 2774 if (has_double_value_) { |
| 2693 return new(zone) HConstant(double_value_, r, is_not_in_new_space_, object_); | 2775 return new(zone) HConstant(double_value_, r, is_not_in_new_space_, object_); |
| 2694 } | 2776 } |
| 2695 if (has_external_reference_value_) { | 2777 if (has_external_reference_value_) { |
| 2696 return new(zone) HConstant(external_reference_value_); | 2778 return new(zone) HConstant(external_reference_value_); |
| 2697 } | 2779 } |
| 2698 ASSERT(!object_.handle().is_null()); | 2780 ASSERT(!object_.handle().is_null()); |
| 2699 return new(zone) HConstant(object_, | 2781 return new(zone) HConstant(object_, |
| 2700 r, | 2782 r, |
| 2701 type_, | 2783 type_, |
| 2702 is_internalized_string_, | |
| 2703 is_not_in_new_space_, | 2784 is_not_in_new_space_, |
| 2704 is_cell_, | 2785 boolean_value_, |
| 2705 boolean_value_); | 2786 is_undetectable_, |
| 2787 instance_type_); |
| 2706 } | 2788 } |
| 2707 | 2789 |
| 2708 | 2790 |
| 2709 Maybe<HConstant*> HConstant::CopyToTruncatedInt32(Zone* zone) { | 2791 Maybe<HConstant*> HConstant::CopyToTruncatedInt32(Zone* zone) { |
| 2710 HConstant* res = NULL; | 2792 HConstant* res = NULL; |
| 2711 if (has_int32_value_) { | 2793 if (has_int32_value_) { |
| 2712 res = new(zone) HConstant(int32_value_, | 2794 res = new(zone) HConstant(int32_value_, |
| 2713 Representation::Integer32(), | 2795 Representation::Integer32(), |
| 2714 is_not_in_new_space_, | 2796 is_not_in_new_space_, |
| 2715 object_); | 2797 object_); |
| (...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3009 | 3091 |
| 3010 void HCompareObjectEqAndBranch::PrintDataTo(StringStream* stream) { | 3092 void HCompareObjectEqAndBranch::PrintDataTo(StringStream* stream) { |
| 3011 left()->PrintNameTo(stream); | 3093 left()->PrintNameTo(stream); |
| 3012 stream->Add(" "); | 3094 stream->Add(" "); |
| 3013 right()->PrintNameTo(stream); | 3095 right()->PrintNameTo(stream); |
| 3014 HControlInstruction::PrintDataTo(stream); | 3096 HControlInstruction::PrintDataTo(stream); |
| 3015 } | 3097 } |
| 3016 | 3098 |
| 3017 | 3099 |
| 3018 bool HCompareObjectEqAndBranch::KnownSuccessorBlock(HBasicBlock** block) { | 3100 bool HCompareObjectEqAndBranch::KnownSuccessorBlock(HBasicBlock** block) { |
| 3019 if (left()->IsConstant() && right()->IsConstant()) { | 3101 if (FLAG_fold_constants && left()->IsConstant() && right()->IsConstant()) { |
| 3020 bool comparison_result = | 3102 *block = HConstant::cast(left())->DataEquals(HConstant::cast(right())) |
| 3021 HConstant::cast(left())->Equals(HConstant::cast(right())); | 3103 ? FirstSuccessor() : SecondSuccessor(); |
| 3022 *block = comparison_result | |
| 3023 ? FirstSuccessor() | |
| 3024 : SecondSuccessor(); | |
| 3025 return true; | 3104 return true; |
| 3026 } | 3105 } |
| 3027 *block = NULL; | 3106 *block = NULL; |
| 3107 return false; |
| 3108 } |
| 3109 |
| 3110 |
| 3111 bool ConstantIsObject(HConstant* constant, Isolate* isolate) { |
| 3112 if (constant->HasNumberValue()) return false; |
| 3113 if (constant->GetUnique().IsKnownGlobal(isolate->heap()->null_value())) { |
| 3114 return true; |
| 3115 } |
| 3116 if (constant->IsUndetectable()) return false; |
| 3117 InstanceType type = constant->GetInstanceType(); |
| 3118 return (FIRST_NONCALLABLE_SPEC_OBJECT_TYPE <= type) && |
| 3119 (type <= LAST_NONCALLABLE_SPEC_OBJECT_TYPE); |
| 3120 } |
| 3121 |
| 3122 |
| 3123 bool HIsObjectAndBranch::KnownSuccessorBlock(HBasicBlock** block) { |
| 3124 if (FLAG_fold_constants && value()->IsConstant()) { |
| 3125 *block = ConstantIsObject(HConstant::cast(value()), isolate()) |
| 3126 ? FirstSuccessor() : SecondSuccessor(); |
| 3127 return true; |
| 3128 } |
| 3129 *block = NULL; |
| 3130 return false; |
| 3131 } |
| 3132 |
| 3133 |
| 3134 bool HIsStringAndBranch::KnownSuccessorBlock(HBasicBlock** block) { |
| 3135 if (FLAG_fold_constants && value()->IsConstant()) { |
| 3136 *block = HConstant::cast(value())->HasStringValue() |
| 3137 ? FirstSuccessor() : SecondSuccessor(); |
| 3138 return true; |
| 3139 } |
| 3140 *block = NULL; |
| 3141 return false; |
| 3142 } |
| 3143 |
| 3144 |
| 3145 bool HIsUndetectableAndBranch::KnownSuccessorBlock(HBasicBlock** block) { |
| 3146 if (FLAG_fold_constants && value()->IsConstant()) { |
| 3147 *block = HConstant::cast(value())->IsUndetectable() |
| 3148 ? FirstSuccessor() : SecondSuccessor(); |
| 3149 return true; |
| 3150 } |
| 3151 *block = NULL; |
| 3152 return false; |
| 3153 } |
| 3154 |
| 3155 |
| 3156 bool HHasInstanceTypeAndBranch::KnownSuccessorBlock(HBasicBlock** block) { |
| 3157 if (FLAG_fold_constants && value()->IsConstant()) { |
| 3158 InstanceType type = HConstant::cast(value())->GetInstanceType(); |
| 3159 *block = (from_ <= type) && (type <= to_) |
| 3160 ? FirstSuccessor() : SecondSuccessor(); |
| 3161 return true; |
| 3162 } |
| 3163 *block = NULL; |
| 3028 return false; | 3164 return false; |
| 3029 } | 3165 } |
| 3030 | 3166 |
| 3031 | 3167 |
| 3032 void HCompareHoleAndBranch::InferRepresentation( | 3168 void HCompareHoleAndBranch::InferRepresentation( |
| 3033 HInferRepresentationPhase* h_infer) { | 3169 HInferRepresentationPhase* h_infer) { |
| 3034 ChangeRepresentation(value()->representation()); | 3170 ChangeRepresentation(value()->representation()); |
| 3035 } | 3171 } |
| 3036 | 3172 |
| 3037 | 3173 |
| 3038 bool HCompareMinusZeroAndBranch::KnownSuccessorBlock(HBasicBlock** block) { | 3174 bool HCompareMinusZeroAndBranch::KnownSuccessorBlock(HBasicBlock** block) { |
| 3175 if (FLAG_fold_constants && value()->IsConstant()) { |
| 3176 HConstant* constant = HConstant::cast(value()); |
| 3177 if (constant->HasDoubleValue()) { |
| 3178 *block = IsMinusZero(constant->DoubleValue()) |
| 3179 ? FirstSuccessor() : SecondSuccessor(); |
| 3180 return true; |
| 3181 } |
| 3182 } |
| 3039 if (value()->representation().IsSmiOrInteger32()) { | 3183 if (value()->representation().IsSmiOrInteger32()) { |
| 3040 // A Smi or Integer32 cannot contain minus zero. | 3184 // A Smi or Integer32 cannot contain minus zero. |
| 3041 *block = SecondSuccessor(); | 3185 *block = SecondSuccessor(); |
| 3042 return true; | 3186 return true; |
| 3043 } | 3187 } |
| 3044 *block = NULL; | 3188 *block = NULL; |
| 3045 return false; | 3189 return false; |
| 3046 } | 3190 } |
| 3047 | 3191 |
| 3048 | 3192 |
| (...skipping 641 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3690 stream->Add(" ("); | 3834 stream->Add(" ("); |
| 3691 if (IsNewSpaceAllocation()) stream->Add("N"); | 3835 if (IsNewSpaceAllocation()) stream->Add("N"); |
| 3692 if (IsOldPointerSpaceAllocation()) stream->Add("P"); | 3836 if (IsOldPointerSpaceAllocation()) stream->Add("P"); |
| 3693 if (IsOldDataSpaceAllocation()) stream->Add("D"); | 3837 if (IsOldDataSpaceAllocation()) stream->Add("D"); |
| 3694 if (MustAllocateDoubleAligned()) stream->Add("A"); | 3838 if (MustAllocateDoubleAligned()) stream->Add("A"); |
| 3695 if (MustPrefillWithFiller()) stream->Add("F"); | 3839 if (MustPrefillWithFiller()) stream->Add("F"); |
| 3696 stream->Add(")"); | 3840 stream->Add(")"); |
| 3697 } | 3841 } |
| 3698 | 3842 |
| 3699 | 3843 |
| 3700 HValue* HUnaryMathOperation::EnsureAndPropagateNotMinusZero( | |
| 3701 BitVector* visited) { | |
| 3702 visited->Add(id()); | |
| 3703 if (representation().IsSmiOrInteger32() && | |
| 3704 !value()->representation().Equals(representation())) { | |
| 3705 if (value()->range() == NULL || value()->range()->CanBeMinusZero()) { | |
| 3706 SetFlag(kBailoutOnMinusZero); | |
| 3707 } | |
| 3708 } | |
| 3709 if (RequiredInputRepresentation(0).IsSmiOrInteger32() && | |
| 3710 representation().Equals(RequiredInputRepresentation(0))) { | |
| 3711 return value(); | |
| 3712 } | |
| 3713 return NULL; | |
| 3714 } | |
| 3715 | |
| 3716 | |
| 3717 HValue* HChange::EnsureAndPropagateNotMinusZero(BitVector* visited) { | |
| 3718 visited->Add(id()); | |
| 3719 if (from().IsSmiOrInteger32()) return NULL; | |
| 3720 if (CanTruncateToInt32()) return NULL; | |
| 3721 if (value()->range() == NULL || value()->range()->CanBeMinusZero()) { | |
| 3722 SetFlag(kBailoutOnMinusZero); | |
| 3723 } | |
| 3724 ASSERT(!from().IsSmiOrInteger32() || !to().IsSmiOrInteger32()); | |
| 3725 return NULL; | |
| 3726 } | |
| 3727 | |
| 3728 | |
| 3729 HValue* HForceRepresentation::EnsureAndPropagateNotMinusZero( | |
| 3730 BitVector* visited) { | |
| 3731 visited->Add(id()); | |
| 3732 return value(); | |
| 3733 } | |
| 3734 | |
| 3735 | |
| 3736 HValue* HMod::EnsureAndPropagateNotMinusZero(BitVector* visited) { | |
| 3737 visited->Add(id()); | |
| 3738 if (range() == NULL || range()->CanBeMinusZero()) { | |
| 3739 SetFlag(kBailoutOnMinusZero); | |
| 3740 return left(); | |
| 3741 } | |
| 3742 return NULL; | |
| 3743 } | |
| 3744 | |
| 3745 | |
| 3746 HValue* HDiv::EnsureAndPropagateNotMinusZero(BitVector* visited) { | |
| 3747 visited->Add(id()); | |
| 3748 if (range() == NULL || range()->CanBeMinusZero()) { | |
| 3749 SetFlag(kBailoutOnMinusZero); | |
| 3750 } | |
| 3751 return NULL; | |
| 3752 } | |
| 3753 | |
| 3754 | |
| 3755 HValue* HMathFloorOfDiv::EnsureAndPropagateNotMinusZero(BitVector* visited) { | |
| 3756 visited->Add(id()); | |
| 3757 SetFlag(kBailoutOnMinusZero); | |
| 3758 return NULL; | |
| 3759 } | |
| 3760 | |
| 3761 | |
| 3762 HValue* HMul::EnsureAndPropagateNotMinusZero(BitVector* visited) { | |
| 3763 visited->Add(id()); | |
| 3764 if (range() == NULL || range()->CanBeMinusZero()) { | |
| 3765 SetFlag(kBailoutOnMinusZero); | |
| 3766 } | |
| 3767 return NULL; | |
| 3768 } | |
| 3769 | |
| 3770 | |
| 3771 HValue* HSub::EnsureAndPropagateNotMinusZero(BitVector* visited) { | |
| 3772 visited->Add(id()); | |
| 3773 // Propagate to the left argument. If the left argument cannot be -0, then | |
| 3774 // the result of the add operation cannot be either. | |
| 3775 if (range() == NULL || range()->CanBeMinusZero()) { | |
| 3776 return left(); | |
| 3777 } | |
| 3778 return NULL; | |
| 3779 } | |
| 3780 | |
| 3781 | |
| 3782 HValue* HAdd::EnsureAndPropagateNotMinusZero(BitVector* visited) { | |
| 3783 visited->Add(id()); | |
| 3784 // Propagate to the left argument. If the left argument cannot be -0, then | |
| 3785 // the result of the sub operation cannot be either. | |
| 3786 if (range() == NULL || range()->CanBeMinusZero()) { | |
| 3787 return left(); | |
| 3788 } | |
| 3789 return NULL; | |
| 3790 } | |
| 3791 | |
| 3792 | |
| 3793 bool HStoreKeyed::NeedsCanonicalization() { | 3844 bool HStoreKeyed::NeedsCanonicalization() { |
| 3794 // If value is an integer or smi or comes from the result of a keyed load or | 3845 // If value is an integer or smi or comes from the result of a keyed load or |
| 3795 // constant then it is either be a non-hole value or in the case of a constant | 3846 // constant then it is either be a non-hole value or in the case of a constant |
| 3796 // the hole is only being stored explicitly: no need for canonicalization. | 3847 // the hole is only being stored explicitly: no need for canonicalization. |
| 3797 // | 3848 // |
| 3798 // The exception to that is keyed loads from external float or double arrays: | 3849 // The exception to that is keyed loads from external float or double arrays: |
| 3799 // these can load arbitrary representation of NaN. | 3850 // these can load arbitrary representation of NaN. |
| 3800 | 3851 |
| 3801 if (value()->IsConstant()) { | 3852 if (value()->IsConstant()) { |
| 3802 return false; | 3853 return false; |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3871 | 3922 |
| 3872 | 3923 |
| 3873 void HStringAdd::PrintDataTo(StringStream* stream) { | 3924 void HStringAdd::PrintDataTo(StringStream* stream) { |
| 3874 if ((flags() & STRING_ADD_CHECK_BOTH) == STRING_ADD_CHECK_BOTH) { | 3925 if ((flags() & STRING_ADD_CHECK_BOTH) == STRING_ADD_CHECK_BOTH) { |
| 3875 stream->Add("_CheckBoth"); | 3926 stream->Add("_CheckBoth"); |
| 3876 } else if ((flags() & STRING_ADD_CHECK_BOTH) == STRING_ADD_CHECK_LEFT) { | 3927 } else if ((flags() & STRING_ADD_CHECK_BOTH) == STRING_ADD_CHECK_LEFT) { |
| 3877 stream->Add("_CheckLeft"); | 3928 stream->Add("_CheckLeft"); |
| 3878 } else if ((flags() & STRING_ADD_CHECK_BOTH) == STRING_ADD_CHECK_RIGHT) { | 3929 } else if ((flags() & STRING_ADD_CHECK_BOTH) == STRING_ADD_CHECK_RIGHT) { |
| 3879 stream->Add("_CheckRight"); | 3930 stream->Add("_CheckRight"); |
| 3880 } | 3931 } |
| 3932 HBinaryOperation::PrintDataTo(stream); |
| 3881 stream->Add(" ("); | 3933 stream->Add(" ("); |
| 3882 if (pretenure_flag() == NOT_TENURED) stream->Add("N"); | 3934 if (pretenure_flag() == NOT_TENURED) stream->Add("N"); |
| 3883 else if (pretenure_flag() == TENURED) stream->Add("D"); | 3935 else if (pretenure_flag() == TENURED) stream->Add("D"); |
| 3884 stream->Add(")"); | 3936 stream->Add(")"); |
| 3885 } | 3937 } |
| 3886 | 3938 |
| 3887 | 3939 |
| 3888 HInstruction* HStringCharFromCode::New( | 3940 HInstruction* HStringCharFromCode::New( |
| 3889 Zone* zone, HValue* context, HValue* char_code) { | 3941 Zone* zone, HValue* context, HValue* char_code) { |
| 3890 if (FLAG_fold_constants && char_code->IsConstant()) { | 3942 if (FLAG_fold_constants && char_code->IsConstant()) { |
| (...skipping 632 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4523 break; | 4575 break; |
| 4524 case kExternalMemory: | 4576 case kExternalMemory: |
| 4525 stream->Add("[external-memory]"); | 4577 stream->Add("[external-memory]"); |
| 4526 break; | 4578 break; |
| 4527 } | 4579 } |
| 4528 | 4580 |
| 4529 stream->Add("@%d", offset()); | 4581 stream->Add("@%d", offset()); |
| 4530 } | 4582 } |
| 4531 | 4583 |
| 4532 } } // namespace v8::internal | 4584 } } // namespace v8::internal |
| OLD | NEW |