Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(98)

Side by Side Diff: src/hydrogen-instructions.cc

Issue 196133017: Experimental parser: merge r19949 (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen-instructions.h ('k') | src/hydrogen-minus-zero.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/hydrogen-instructions.h ('k') | src/hydrogen-minus-zero.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698