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

Side by Side Diff: src/hydrogen.cc

Issue 71163006: Merge bleeding_edge r17376:17693. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Fix all.gyp Created 7 years, 1 month 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.h ('k') | src/hydrogen-gvn.cc » ('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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 690 matching lines...) Expand 10 before | Expand all | Expand 10 after
701 701
702 DEFINE_GET_CONSTANT(Undefined, undefined, HType::Tagged(), false) 702 DEFINE_GET_CONSTANT(Undefined, undefined, HType::Tagged(), false)
703 DEFINE_GET_CONSTANT(True, true, HType::Boolean(), true) 703 DEFINE_GET_CONSTANT(True, true, HType::Boolean(), true)
704 DEFINE_GET_CONSTANT(False, false, HType::Boolean(), false) 704 DEFINE_GET_CONSTANT(False, false, HType::Boolean(), false)
705 DEFINE_GET_CONSTANT(Hole, the_hole, HType::Tagged(), false) 705 DEFINE_GET_CONSTANT(Hole, the_hole, HType::Tagged(), false)
706 DEFINE_GET_CONSTANT(Null, null, HType::Tagged(), false) 706 DEFINE_GET_CONSTANT(Null, null, HType::Tagged(), false)
707 707
708 708
709 #undef DEFINE_GET_CONSTANT 709 #undef DEFINE_GET_CONSTANT
710 710
711 #define DEFINE_IS_CONSTANT(Name, name) \
712 bool HGraph::IsConstant##Name(HConstant* constant) { \
713 return constant_##name##_.is_set() && constant == constant_##name##_.get(); \
714 }
715 DEFINE_IS_CONSTANT(Undefined, undefined)
716 DEFINE_IS_CONSTANT(0, 0)
717 DEFINE_IS_CONSTANT(1, 1)
718 DEFINE_IS_CONSTANT(Minus1, minus1)
719 DEFINE_IS_CONSTANT(True, true)
720 DEFINE_IS_CONSTANT(False, false)
721 DEFINE_IS_CONSTANT(Hole, the_hole)
722 DEFINE_IS_CONSTANT(Null, null)
723
724 #undef DEFINE_IS_CONSTANT
725
711 726
712 HConstant* HGraph::GetInvalidContext() { 727 HConstant* HGraph::GetInvalidContext() {
713 return GetConstant(&constant_invalid_context_, 0xFFFFC0C7); 728 return GetConstant(&constant_invalid_context_, 0xFFFFC0C7);
714 } 729 }
715 730
716 731
717 bool HGraph::IsStandardConstant(HConstant* constant) { 732 bool HGraph::IsStandardConstant(HConstant* constant) {
718 if (constant == GetConstantUndefined()) return true; 733 if (IsConstantUndefined(constant)) return true;
719 if (constant == GetConstant0()) return true; 734 if (IsConstant0(constant)) return true;
720 if (constant == GetConstant1()) return true; 735 if (IsConstant1(constant)) return true;
721 if (constant == GetConstantMinus1()) return true; 736 if (IsConstantMinus1(constant)) return true;
722 if (constant == GetConstantTrue()) return true; 737 if (IsConstantTrue(constant)) return true;
723 if (constant == GetConstantFalse()) return true; 738 if (IsConstantFalse(constant)) return true;
724 if (constant == GetConstantHole()) return true; 739 if (IsConstantHole(constant)) return true;
725 if (constant == GetConstantNull()) return true; 740 if (IsConstantNull(constant)) return true;
726 return false; 741 return false;
727 } 742 }
728 743
729 744
730 HGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder) 745 HGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder)
731 : builder_(builder), 746 : builder_(builder),
732 finished_(false), 747 finished_(false),
733 deopt_then_(false), 748 deopt_then_(false),
734 deopt_else_(false), 749 deopt_else_(false),
735 did_then_(false), 750 did_then_(false),
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
837 : first_false_block_; 852 : first_false_block_;
838 continuation->Capture(true_block, false_block); 853 continuation->Capture(true_block, false_block);
839 captured_ = true; 854 captured_ = true;
840 End(); 855 End();
841 } 856 }
842 857
843 858
844 void HGraphBuilder::IfBuilder::JoinContinuation(HIfContinuation* continuation) { 859 void HGraphBuilder::IfBuilder::JoinContinuation(HIfContinuation* continuation) {
845 ASSERT(!finished_); 860 ASSERT(!finished_);
846 ASSERT(!captured_); 861 ASSERT(!captured_);
862 ASSERT(did_then_);
863 if (!did_else_) Else();
847 HBasicBlock* true_block = last_true_block_ == NULL 864 HBasicBlock* true_block = last_true_block_ == NULL
848 ? first_true_block_ 865 ? first_true_block_
849 : last_true_block_; 866 : last_true_block_;
850 HBasicBlock* false_block = did_else_ && (first_false_block_ != NULL) 867 HBasicBlock* false_block = builder_->current_block();
851 ? builder_->current_block()
852 : first_false_block_;
853 if (true_block != NULL && !true_block->IsFinished()) { 868 if (true_block != NULL && !true_block->IsFinished()) {
854 ASSERT(continuation->IsTrueReachable()); 869 ASSERT(continuation->IsTrueReachable());
855 builder_->GotoNoSimulate(true_block, continuation->true_branch()); 870 builder_->GotoNoSimulate(true_block, continuation->true_branch());
856 } 871 }
857 if (false_block != NULL && !false_block->IsFinished()) { 872 if (false_block != NULL && !false_block->IsFinished()) {
858 ASSERT(continuation->IsFalseReachable()); 873 ASSERT(continuation->IsFalseReachable());
859 builder_->GotoNoSimulate(false_block, continuation->false_branch()); 874 builder_->GotoNoSimulate(false_block, continuation->false_branch());
860 } 875 }
861 captured_ = true; 876 captured_ = true;
862 End(); 877 End();
(...skipping 584 matching lines...) Expand 10 before | Expand all | Expand 10 after
1447 isolate()->factory()->empty_string(), 1462 isolate()->factory()->empty_string(),
1448 Runtime::FunctionForId(Runtime::kNumberToStringSkipCache), 1463 Runtime::FunctionForId(Runtime::kNumberToStringSkipCache),
1449 1)); 1464 1));
1450 } 1465 }
1451 if_found.End(); 1466 if_found.End();
1452 1467
1453 return Pop(); 1468 return Pop();
1454 } 1469 }
1455 1470
1456 1471
1472 HValue* HGraphBuilder::BuildSeqStringSizeFor(HValue* length,
1473 String::Encoding encoding) {
1474 STATIC_ASSERT((SeqString::kHeaderSize & kObjectAlignmentMask) == 0);
1475 HValue* size = length;
1476 if (encoding == String::TWO_BYTE_ENCODING) {
1477 size = Add<HShl>(length, graph()->GetConstant1());
1478 size->ClearFlag(HValue::kCanOverflow);
1479 size->SetFlag(HValue::kUint32);
1480 }
1481 size = Add<HAdd>(size, Add<HConstant>(static_cast<int32_t>(
1482 SeqString::kHeaderSize + kObjectAlignmentMask)));
1483 size->ClearFlag(HValue::kCanOverflow);
1484 size = Add<HBitwise>(
1485 Token::BIT_AND, size, Add<HConstant>(static_cast<int32_t>(
1486 ~kObjectAlignmentMask)));
1487 return size;
1488 }
1489
1490
1491 void HGraphBuilder::BuildCopySeqStringChars(HValue* src,
1492 HValue* src_offset,
1493 String::Encoding src_encoding,
1494 HValue* dst,
1495 HValue* dst_offset,
1496 String::Encoding dst_encoding,
1497 HValue* length) {
1498 ASSERT(dst_encoding != String::ONE_BYTE_ENCODING ||
1499 src_encoding == String::ONE_BYTE_ENCODING);
1500 LoopBuilder loop(this, context(), LoopBuilder::kPostIncrement);
1501 HValue* index = loop.BeginBody(graph()->GetConstant0(), length, Token::LT);
1502 {
1503 HValue* src_index = Add<HAdd>(src_offset, index);
1504 HValue* value = Add<HSeqStringGetChar>(src_encoding, src, src_index);
1505 HValue* dst_index = Add<HAdd>(dst_offset, index);
1506 Add<HSeqStringSetChar>(dst_encoding, dst, dst_index, value);
1507 }
1508 loop.EndBody();
1509 }
1510
1511
1512 HValue* HGraphBuilder::BuildUncheckedStringAdd(HValue* left,
1513 HValue* right,
1514 PretenureFlag pretenure_flag) {
1515 // Determine the string lengths.
1516 HValue* left_length = Add<HLoadNamedField>(
1517 left, HObjectAccess::ForStringLength());
1518 HValue* right_length = Add<HLoadNamedField>(
1519 right, HObjectAccess::ForStringLength());
1520
1521 // Check if we concatenated the strings here, or if we have to resort to the
1522 // runtime function.
1523 HIfContinuation handled(graph()->CreateBasicBlock(),
1524 graph()->CreateBasicBlock());
1525
1526 // Check if both parameters do not exceed half the max string length, because
1527 // exceptionally long strings should be handled in the runtime. Unfortunately
1528 // we cannot actually check whether the combined length of both strings
1529 // exceeds String::kMaxLength (because of unclear results from the
1530 // representation inference phase), so we use a pessimistic approach here
1531 // instead, checking that the length of either substring does not exceed half
1532 // of String::kMaxLength.
1533 HConstant* max_length = Add<HConstant>(String::kMaxLength / 2);
1534 IfBuilder if_nooverflow(this);
1535 if_nooverflow.If<HCompareNumericAndBranch>(
1536 left_length, max_length, Token::LTE);
1537 if_nooverflow.AndIf<HCompareNumericAndBranch>(
1538 right_length, max_length, Token::LTE);
1539 if_nooverflow.Then();
1540 {
1541 // Determine the string instance types.
1542 HLoadNamedField* left_instance_type = Add<HLoadNamedField>(
1543 Add<HLoadNamedField>(left, HObjectAccess::ForMap()),
1544 HObjectAccess::ForMapInstanceType());
1545 HLoadNamedField* right_instance_type = Add<HLoadNamedField>(
1546 Add<HLoadNamedField>(right, HObjectAccess::ForMap()),
1547 HObjectAccess::ForMapInstanceType());
1548
1549 // Compute difference of instance types.
1550 HValue* xored_instance_types = Add<HBitwise>(
1551 Token::BIT_XOR, left_instance_type, right_instance_type);
1552
1553 // Compute the length of the resulting string.
1554 HValue* length = Add<HAdd>(left_length, right_length);
1555
1556 // Check if we should create a cons string.
1557 IfBuilder if_createcons(this);
1558 if_createcons.If<HCompareNumericAndBranch>(
1559 length, Add<HConstant>(ConsString::kMinLength), Token::GTE);
1560 if_createcons.Then();
1561 {
1562 // Allocate the cons string object. HAllocate does not care whether we
1563 // pass CONS_STRING_TYPE or CONS_ASCII_STRING_TYPE here, so we just use
1564 // CONS_STRING_TYPE here. Below we decide whether the cons string is
1565 // one-byte or two-byte and set the appropriate map.
1566 HAllocate* string = Add<HAllocate>(Add<HConstant>(ConsString::kSize),
1567 HType::String(), pretenure_flag,
1568 CONS_STRING_TYPE);
1569
1570 // Compute the intersection of instance types.
1571 HValue* anded_instance_types = Add<HBitwise>(
1572 Token::BIT_AND, left_instance_type, right_instance_type);
1573
1574 // We create a one-byte cons string if
1575 // 1. both strings are one-byte, or
1576 // 2. at least one of the strings is two-byte, but happens to contain only
1577 // one-byte characters.
1578 // To do this, we check
1579 // 1. if both strings are one-byte, or if the one-byte data hint is set in
1580 // both strings, or
1581 // 2. if one of the strings has the one-byte data hint set and the other
1582 // string is one-byte.
1583 IfBuilder if_onebyte(this);
1584 STATIC_ASSERT(kOneByteStringTag != 0);
1585 STATIC_ASSERT(kOneByteDataHintMask != 0);
1586 if_onebyte.If<HCompareNumericAndBranch>(
1587 Add<HBitwise>(
1588 Token::BIT_AND, anded_instance_types,
1589 Add<HConstant>(static_cast<int32_t>(
1590 kStringEncodingMask | kOneByteDataHintMask))),
1591 graph()->GetConstant0(), Token::NE);
1592 if_onebyte.Or();
1593 STATIC_ASSERT(kOneByteStringTag != 0 &&
1594 kOneByteDataHintTag != 0 &&
1595 kOneByteDataHintTag != kOneByteStringTag);
1596 if_onebyte.If<HCompareNumericAndBranch>(
1597 Add<HBitwise>(
1598 Token::BIT_AND, xored_instance_types,
1599 Add<HConstant>(static_cast<int32_t>(
1600 kOneByteStringTag | kOneByteDataHintTag))),
1601 Add<HConstant>(static_cast<int32_t>(
1602 kOneByteStringTag | kOneByteDataHintTag)), Token::EQ);
1603 if_onebyte.Then();
1604 {
1605 // We can safely skip the write barrier for storing the map here.
1606 Handle<Map> map = isolate()->factory()->cons_ascii_string_map();
1607 AddStoreMapConstantNoWriteBarrier(string, map);
1608 }
1609 if_onebyte.Else();
1610 {
1611 // We can safely skip the write barrier for storing the map here.
1612 Handle<Map> map = isolate()->factory()->cons_string_map();
1613 AddStoreMapConstantNoWriteBarrier(string, map);
1614 }
1615 if_onebyte.End();
1616
1617 // Initialize the cons string fields.
1618 Add<HStoreNamedField>(string, HObjectAccess::ForStringHashField(),
1619 Add<HConstant>(String::kEmptyHashField));
1620 Add<HStoreNamedField>(string, HObjectAccess::ForStringLength(), length);
1621 Add<HStoreNamedField>(string, HObjectAccess::ForConsStringFirst(), left);
1622 Add<HStoreNamedField>(string, HObjectAccess::ForConsStringSecond(),
1623 right);
1624
1625 // Cons string is result.
1626 Push(string);
1627 }
1628 if_createcons.Else();
1629 {
1630 // Compute union of instance types.
1631 HValue* ored_instance_types = Add<HBitwise>(
1632 Token::BIT_OR, left_instance_type, right_instance_type);
1633
1634 // Check if both strings have the same encoding and both are
1635 // sequential.
1636 IfBuilder if_sameencodingandsequential(this);
1637 if_sameencodingandsequential.If<HCompareNumericAndBranch>(
1638 Add<HBitwise>(
1639 Token::BIT_AND, xored_instance_types,
1640 Add<HConstant>(static_cast<int32_t>(kStringEncodingMask))),
1641 graph()->GetConstant0(), Token::EQ);
1642 if_sameencodingandsequential.And();
1643 STATIC_ASSERT(kSeqStringTag == 0);
1644 if_sameencodingandsequential.If<HCompareNumericAndBranch>(
1645 Add<HBitwise>(
1646 Token::BIT_AND, ored_instance_types,
1647 Add<HConstant>(static_cast<int32_t>(kStringRepresentationMask))),
1648 graph()->GetConstant0(), Token::EQ);
1649 if_sameencodingandsequential.Then();
1650 {
1651 // Check if the result is a one-byte string.
1652 IfBuilder if_onebyte(this);
1653 STATIC_ASSERT(kOneByteStringTag != 0);
1654 if_onebyte.If<HCompareNumericAndBranch>(
1655 Add<HBitwise>(
1656 Token::BIT_AND, ored_instance_types,
1657 Add<HConstant>(static_cast<int32_t>(kStringEncodingMask))),
1658 graph()->GetConstant0(), Token::NE);
1659 if_onebyte.Then();
1660 {
1661 // Calculate the number of bytes needed for the characters in the
1662 // string while observing object alignment.
1663 HValue* size = BuildSeqStringSizeFor(
1664 length, String::ONE_BYTE_ENCODING);
1665
1666 // Allocate the ASCII string object.
1667 Handle<Map> map = isolate()->factory()->ascii_string_map();
1668 HAllocate* string = Add<HAllocate>(size, HType::String(),
1669 pretenure_flag, ASCII_STRING_TYPE);
1670 string->set_known_initial_map(map);
1671
1672 // We can safely skip the write barrier for storing map here.
1673 AddStoreMapConstantNoWriteBarrier(string, map);
1674
1675 // Copy bytes from the left string.
1676 BuildCopySeqStringChars(
1677 left, graph()->GetConstant0(), String::ONE_BYTE_ENCODING,
1678 string, graph()->GetConstant0(), String::ONE_BYTE_ENCODING,
1679 left_length);
1680
1681 // Copy bytes from the right string.
1682 BuildCopySeqStringChars(
1683 right, graph()->GetConstant0(), String::ONE_BYTE_ENCODING,
1684 string, left_length, String::ONE_BYTE_ENCODING,
1685 right_length);
1686
1687 // Return the string.
1688 Push(string);
1689 }
1690 if_onebyte.Else();
1691 {
1692 // Calculate the number of bytes needed for the characters in the
1693 // string while observing object alignment.
1694 HValue* size = BuildSeqStringSizeFor(
1695 length, String::TWO_BYTE_ENCODING);
1696
1697 // Allocate the two-byte string object.
1698 Handle<Map> map = isolate()->factory()->string_map();
1699 HAllocate* string = Add<HAllocate>(size, HType::String(),
1700 pretenure_flag, STRING_TYPE);
1701 string->set_known_initial_map(map);
1702
1703 // We can safely skip the write barrier for storing map here.
1704 AddStoreMapConstantNoWriteBarrier(string, map);
1705
1706 // Copy bytes from the left string.
1707 BuildCopySeqStringChars(
1708 left, graph()->GetConstant0(), String::TWO_BYTE_ENCODING,
1709 string, graph()->GetConstant0(), String::TWO_BYTE_ENCODING,
1710 left_length);
1711
1712 // Copy bytes from the right string.
1713 BuildCopySeqStringChars(
1714 right, graph()->GetConstant0(), String::TWO_BYTE_ENCODING,
1715 string, left_length, String::TWO_BYTE_ENCODING,
1716 right_length);
1717
1718 // Return the string.
1719 Push(string);
1720 }
1721 if_onebyte.End();
1722
1723 // Initialize the (common) string fields.
1724 HValue* string = Pop();
1725 Add<HStoreNamedField>(string, HObjectAccess::ForStringHashField(),
1726 Add<HConstant>(String::kEmptyHashField));
1727 Add<HStoreNamedField>(string, HObjectAccess::ForStringLength(),
1728 length);
1729 Push(string);
1730 }
1731 if_sameencodingandsequential.JoinContinuation(&handled);
1732 }
1733 if_createcons.JoinContinuation(&handled);
1734 }
1735 if_nooverflow.JoinContinuation(&handled);
1736
1737 // Check if the strings were concatenated successfully, otherwise fallback to
1738 // add the strings in the runtime.
1739 IfBuilder if_handled(this, &handled);
1740 if_handled.Then();
1741 {
1742 // Count the native string addition.
1743 AddIncrementCounter(isolate()->counters()->string_add_native());
1744 }
1745 if_handled.Else();
1746 {
1747 // Fallback to the runtime to add the two strings.
1748 Add<HPushArgument>(left);
1749 Add<HPushArgument>(right);
1750 Push(Add<HCallRuntime>(isolate()->factory()->empty_string(),
1751 Runtime::FunctionForId(Runtime::kStringAdd),
1752 2));
1753 }
1754 if_handled.End();
1755
1756 return Pop();
1757 }
1758
1759
1760 HValue* HGraphBuilder::BuildStringAdd(HValue* left,
1761 HValue* right,
1762 PretenureFlag pretenure_flag) {
1763 // Determine the string lengths.
1764 HValue* left_length = Add<HLoadNamedField>(
1765 left, HObjectAccess::ForStringLength());
1766 HValue* right_length = Add<HLoadNamedField>(
1767 right, HObjectAccess::ForStringLength());
1768
1769 // Check if left string is empty.
1770 IfBuilder if_leftisempty(this);
1771 if_leftisempty.If<HCompareNumericAndBranch>(
1772 left_length, graph()->GetConstant0(), Token::EQ);
1773 if_leftisempty.Then();
1774 {
1775 // Count the native string addition.
1776 AddIncrementCounter(isolate()->counters()->string_add_native());
1777
1778 // Just return the right string.
1779 Push(right);
1780 }
1781 if_leftisempty.Else();
1782 {
1783 // Check if right string is empty.
1784 IfBuilder if_rightisempty(this);
1785 if_rightisempty.If<HCompareNumericAndBranch>(
1786 right_length, graph()->GetConstant0(), Token::EQ);
1787 if_rightisempty.Then();
1788 {
1789 // Count the native string addition.
1790 AddIncrementCounter(isolate()->counters()->string_add_native());
1791
1792 // Just return the left string.
1793 Push(left);
1794 }
1795 if_rightisempty.Else();
1796 {
1797 // Concatenate the two non-empty strings.
1798 Push(BuildUncheckedStringAdd(left, right, pretenure_flag));
1799 }
1800 if_rightisempty.End();
1801 }
1802 if_leftisempty.End();
1803
1804 return Pop();
1805 }
1806
1807
1457 HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( 1808 HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess(
1458 HValue* checked_object, 1809 HValue* checked_object,
1459 HValue* key, 1810 HValue* key,
1460 HValue* val, 1811 HValue* val,
1461 bool is_js_array, 1812 bool is_js_array,
1462 ElementsKind elements_kind, 1813 ElementsKind elements_kind,
1463 bool is_store, 1814 bool is_store,
1464 LoadKeyedHoleMode load_mode, 1815 LoadKeyedHoleMode load_mode,
1465 KeyedAccessStoreMode store_mode) { 1816 KeyedAccessStoreMode store_mode) {
1466 ASSERT(!IsExternalArrayElementsKind(elements_kind) || !is_js_array); 1817 ASSERT(!IsExternalArrayElementsKind(elements_kind) || !is_js_array);
(...skipping 652 matching lines...) Expand 10 before | Expand all | Expand 10 after
2119 // objects we construct, and an int32-to-smi HChange could deopt. Accept 2470 // objects we construct, and an int32-to-smi HChange could deopt. Accept
2120 // the deopt possibility now, before allocation occurs. 2471 // the deopt possibility now, before allocation occurs.
2121 capacity = builder()->Add<HForceRepresentation>(capacity, 2472 capacity = builder()->Add<HForceRepresentation>(capacity,
2122 Representation::Smi()); 2473 Representation::Smi());
2123 length_field = builder()->Add<HForceRepresentation>(length_field, 2474 length_field = builder()->Add<HForceRepresentation>(length_field,
2124 Representation::Smi()); 2475 Representation::Smi());
2125 // Allocate (dealing with failure appropriately) 2476 // Allocate (dealing with failure appropriately)
2126 HAllocate* new_object = builder()->Add<HAllocate>(size_in_bytes, 2477 HAllocate* new_object = builder()->Add<HAllocate>(size_in_bytes,
2127 HType::JSArray(), NOT_TENURED, JS_ARRAY_TYPE); 2478 HType::JSArray(), NOT_TENURED, JS_ARRAY_TYPE);
2128 2479
2480 // Folded array allocation should be aligned if it has fast double elements.
2481 if (IsFastDoubleElementsKind(kind_)) {
2482 new_object->MakeDoubleAligned();
2483 }
2484
2129 // Fill in the fields: map, properties, length 2485 // Fill in the fields: map, properties, length
2130 HValue* map; 2486 HValue* map;
2131 if (allocation_site_payload_ == NULL) { 2487 if (allocation_site_payload_ == NULL) {
2132 map = EmitInternalMapCode(); 2488 map = EmitInternalMapCode();
2133 } else { 2489 } else {
2134 map = EmitMapCode(); 2490 map = EmitMapCode();
2135 } 2491 }
2136 elements_location_ = builder()->BuildJSArrayHeader(new_object, 2492 elements_location_ = builder()->BuildJSArrayHeader(new_object,
2137 map, 2493 map,
2138 mode_, 2494 mode_,
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
2269 phi_list_(NULL), 2625 phi_list_(NULL),
2270 uint32_instructions_(NULL), 2626 uint32_instructions_(NULL),
2271 osr_(NULL), 2627 osr_(NULL),
2272 info_(info), 2628 info_(info),
2273 zone_(info->zone()), 2629 zone_(info->zone()),
2274 is_recursive_(false), 2630 is_recursive_(false),
2275 use_optimistic_licm_(false), 2631 use_optimistic_licm_(false),
2276 depends_on_empty_array_proto_elements_(false), 2632 depends_on_empty_array_proto_elements_(false),
2277 type_change_checksum_(0), 2633 type_change_checksum_(0),
2278 maximum_environment_size_(0), 2634 maximum_environment_size_(0),
2279 no_side_effects_scope_count_(0) { 2635 no_side_effects_scope_count_(0),
2636 disallow_adding_new_values_(false) {
2280 if (info->IsStub()) { 2637 if (info->IsStub()) {
2281 HydrogenCodeStub* stub = info->code_stub(); 2638 HydrogenCodeStub* stub = info->code_stub();
2282 CodeStubInterfaceDescriptor* descriptor = 2639 CodeStubInterfaceDescriptor* descriptor =
2283 stub->GetInterfaceDescriptor(isolate_); 2640 stub->GetInterfaceDescriptor(isolate_);
2284 start_environment_ = 2641 start_environment_ =
2285 new(zone_) HEnvironment(zone_, descriptor->environment_length()); 2642 new(zone_) HEnvironment(zone_, descriptor->environment_length());
2286 } else { 2643 } else {
2287 start_environment_ = 2644 start_environment_ =
2288 new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_); 2645 new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_);
2289 } 2646 }
(...skipping 2008 matching lines...) Expand 10 before | Expand all | Expand 10 after
4298 } 4655 }
4299 } 4656 }
4300 return true; 4657 return true;
4301 } 4658 }
4302 4659
4303 4660
4304 void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { 4661 void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
4305 ASSERT(!HasStackOverflow()); 4662 ASSERT(!HasStackOverflow());
4306 ASSERT(current_block() != NULL); 4663 ASSERT(current_block() != NULL);
4307 ASSERT(current_block()->HasPredecessor()); 4664 ASSERT(current_block()->HasPredecessor());
4665 expr->BuildConstantProperties(isolate());
4308 Handle<JSFunction> closure = function_state()->compilation_info()->closure(); 4666 Handle<JSFunction> closure = function_state()->compilation_info()->closure();
4309 HInstruction* literal; 4667 HInstruction* literal;
4310 4668
4311 // Check whether to use fast or slow deep-copying for boilerplate. 4669 // Check whether to use fast or slow deep-copying for boilerplate.
4312 int max_properties = kMaxFastLiteralProperties; 4670 int max_properties = kMaxFastLiteralProperties;
4313 Handle<Object> literals_cell(closure->literals()->get(expr->literal_index()), 4671 Handle<Object> literals_cell(closure->literals()->get(expr->literal_index()),
4314 isolate()); 4672 isolate());
4315 Handle<AllocationSite> site; 4673 Handle<AllocationSite> site;
4316 Handle<JSObject> boilerplate; 4674 Handle<JSObject> boilerplate;
4317 if (!literals_cell->IsUndefined()) { 4675 if (!literals_cell->IsUndefined()) {
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
4419 } else { 4777 } else {
4420 return ast_context()->ReturnValue(Pop()); 4778 return ast_context()->ReturnValue(Pop());
4421 } 4779 }
4422 } 4780 }
4423 4781
4424 4782
4425 void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { 4783 void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
4426 ASSERT(!HasStackOverflow()); 4784 ASSERT(!HasStackOverflow());
4427 ASSERT(current_block() != NULL); 4785 ASSERT(current_block() != NULL);
4428 ASSERT(current_block()->HasPredecessor()); 4786 ASSERT(current_block()->HasPredecessor());
4787 expr->BuildConstantElements(isolate());
4429 ZoneList<Expression*>* subexprs = expr->values(); 4788 ZoneList<Expression*>* subexprs = expr->values();
4430 int length = subexprs->length(); 4789 int length = subexprs->length();
4431 HInstruction* literal; 4790 HInstruction* literal;
4432 4791
4433 Handle<AllocationSite> site; 4792 Handle<AllocationSite> site;
4434 Handle<FixedArray> literals(environment()->closure()->literals(), isolate()); 4793 Handle<FixedArray> literals(environment()->closure()->literals(), isolate());
4435 bool uninitialized = false; 4794 bool uninitialized = false;
4436 Handle<Object> literals_cell(literals->get(expr->literal_index()), 4795 Handle<Object> literals_cell(literals->get(expr->literal_index()),
4437 isolate()); 4796 isolate());
4438 Handle<JSObject> boilerplate_object; 4797 Handle<JSObject> boilerplate_object;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
4486 Handle<FixedArray> constants = isolate()->factory()->empty_fixed_array(); 4845 Handle<FixedArray> constants = isolate()->factory()->empty_fixed_array();
4487 int literal_index = expr->literal_index(); 4846 int literal_index = expr->literal_index();
4488 4847
4489 Add<HPushArgument>(Add<HConstant>(literals)); 4848 Add<HPushArgument>(Add<HConstant>(literals));
4490 Add<HPushArgument>(Add<HConstant>(literal_index)); 4849 Add<HPushArgument>(Add<HConstant>(literal_index));
4491 Add<HPushArgument>(Add<HConstant>(constants)); 4850 Add<HPushArgument>(Add<HConstant>(constants));
4492 4851
4493 // TODO(mvstanton): Consider a flag to turn off creation of any 4852 // TODO(mvstanton): Consider a flag to turn off creation of any
4494 // AllocationMementos for this call: we are in crankshaft and should have 4853 // AllocationMementos for this call: we are in crankshaft and should have
4495 // learned enough about transition behavior to stop emitting mementos. 4854 // learned enough about transition behavior to stop emitting mementos.
4496 Runtime::FunctionId function_id = (expr->depth() > 1) 4855 Runtime::FunctionId function_id = Runtime::kCreateArrayLiteral;
4497 ? Runtime::kCreateArrayLiteral : Runtime::kCreateArrayLiteralShallow;
4498 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(), 4856 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(),
4499 Runtime::FunctionForId(function_id), 4857 Runtime::FunctionForId(function_id),
4500 3); 4858 3);
4501 4859
4502 // De-opt if elements kind changed from boilerplate_elements_kind. 4860 // De-opt if elements kind changed from boilerplate_elements_kind.
4503 Handle<Map> map = Handle<Map>(boilerplate_object->map(), isolate()); 4861 Handle<Map> map = Handle<Map>(boilerplate_object->map(), isolate());
4504 literal = Add<HCheckMaps>(literal, map, top_info()); 4862 literal = Add<HCheckMaps>(literal, map, top_info());
4505 } 4863 }
4506 4864
4507 // The array is expected in the bailout environment during computation 4865 // The array is expected in the bailout environment during computation
(...skipping 1057 matching lines...) Expand 10 before | Expand all | Expand 10 after
5565 HValue* dependency, 5923 HValue* dependency,
5566 Handle<Map> map, 5924 Handle<Map> map,
5567 bool is_store, 5925 bool is_store,
5568 KeyedAccessStoreMode store_mode) { 5926 KeyedAccessStoreMode store_mode) {
5569 HCheckMaps* checked_object = Add<HCheckMaps>(object, map, top_info(), 5927 HCheckMaps* checked_object = Add<HCheckMaps>(object, map, top_info(),
5570 dependency); 5928 dependency);
5571 if (dependency) { 5929 if (dependency) {
5572 checked_object->ClearGVNFlag(kDependsOnElementsKind); 5930 checked_object->ClearGVNFlag(kDependsOnElementsKind);
5573 } 5931 }
5574 5932
5933 if (is_store && map->prototype()->IsJSObject()) {
5934 // monomorphic stores need a prototype chain check because shape
5935 // changes could allow callbacks on elements in the chain that
5936 // aren't compatible with monomorphic keyed stores.
5937 Handle<JSObject> prototype(JSObject::cast(map->prototype()));
5938 Object* holder = map->prototype();
5939 while (holder->GetPrototype(isolate())->IsJSObject()) {
5940 holder = holder->GetPrototype(isolate());
5941 }
5942 ASSERT(holder->GetPrototype(isolate())->IsNull());
5943
5944 BuildCheckPrototypeMaps(prototype,
5945 Handle<JSObject>(JSObject::cast(holder)));
5946 }
5947
5575 LoadKeyedHoleMode load_mode = BuildKeyedHoleMode(map); 5948 LoadKeyedHoleMode load_mode = BuildKeyedHoleMode(map);
5576 return BuildUncheckedMonomorphicElementAccess( 5949 return BuildUncheckedMonomorphicElementAccess(
5577 checked_object, key, val, 5950 checked_object, key, val,
5578 map->instance_type() == JS_ARRAY_TYPE, 5951 map->instance_type() == JS_ARRAY_TYPE,
5579 map->elements_kind(), is_store, 5952 map->elements_kind(), is_store,
5580 load_mode, store_mode); 5953 load_mode, store_mode);
5581 } 5954 }
5582 5955
5583 5956
5584 HInstruction* HOptimizedGraphBuilder::TryBuildConsolidatedElementLoad( 5957 HInstruction* HOptimizedGraphBuilder::TryBuildConsolidatedElementLoad(
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
5778 HValue* val, 6151 HValue* val,
5779 Expression* expr, 6152 Expression* expr,
5780 bool is_store, 6153 bool is_store,
5781 bool* has_side_effects) { 6154 bool* has_side_effects) {
5782 ASSERT(!expr->IsPropertyName()); 6155 ASSERT(!expr->IsPropertyName());
5783 HInstruction* instr = NULL; 6156 HInstruction* instr = NULL;
5784 6157
5785 SmallMapList* types; 6158 SmallMapList* types;
5786 bool monomorphic = ComputeReceiverTypes(expr, obj, &types); 6159 bool monomorphic = ComputeReceiverTypes(expr, obj, &types);
5787 6160
6161 bool force_generic = false;
6162 if (is_store && (monomorphic || (types != NULL && !types->is_empty()))) {
6163 // Stores can't be mono/polymorphic if their prototype chain has dictionary
6164 // elements. However a receiver map that has dictionary elements itself
6165 // should be left to normal mono/poly behavior (the other maps may benefit
6166 // from highly optimized stores).
6167 for (int i = 0; i < types->length(); i++) {
6168 Handle<Map> current_map = types->at(i);
6169 if (current_map->DictionaryElementsInPrototypeChainOnly()) {
6170 force_generic = true;
6171 monomorphic = false;
6172 break;
6173 }
6174 }
6175 }
6176
5788 if (monomorphic) { 6177 if (monomorphic) {
5789 Handle<Map> map = types->first(); 6178 Handle<Map> map = types->first();
5790 if (map->has_slow_elements_kind()) { 6179 if (map->has_slow_elements_kind()) {
5791 instr = is_store ? BuildStoreKeyedGeneric(obj, key, val) 6180 instr = is_store ? BuildStoreKeyedGeneric(obj, key, val)
5792 : BuildLoadKeyedGeneric(obj, key); 6181 : BuildLoadKeyedGeneric(obj, key);
5793 AddInstruction(instr); 6182 AddInstruction(instr);
5794 } else { 6183 } else {
5795 BuildCheckHeapObject(obj); 6184 BuildCheckHeapObject(obj);
5796 instr = BuildMonomorphicElementAccess( 6185 instr = BuildMonomorphicElementAccess(
5797 obj, key, val, NULL, map, is_store, expr->GetStoreMode()); 6186 obj, key, val, NULL, map, is_store, expr->GetStoreMode());
5798 } 6187 }
5799 } else if (types != NULL && !types->is_empty()) { 6188 } else if (!force_generic && (types != NULL && !types->is_empty())) {
5800 return HandlePolymorphicElementAccess( 6189 return HandlePolymorphicElementAccess(
5801 obj, key, val, types, is_store, 6190 obj, key, val, types, is_store,
5802 expr->GetStoreMode(), has_side_effects); 6191 expr->GetStoreMode(), has_side_effects);
5803 } else { 6192 } else {
5804 if (is_store) { 6193 if (is_store) {
5805 if (expr->IsAssignment() && 6194 if (expr->IsAssignment() &&
5806 expr->AsAssignment()->HasNoTypeInformation()) { 6195 expr->AsAssignment()->HasNoTypeInformation()) {
5807 Add<HDeoptimize>("Insufficient type feedback for keyed store", 6196 Add<HDeoptimize>("Insufficient type feedback for keyed store",
5808 Deoptimizer::SOFT); 6197 Deoptimizer::SOFT);
5809 } 6198 }
(...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after
6309 6698
6310 6699
6311 int HOptimizedGraphBuilder::InliningAstSize(Handle<JSFunction> target) { 6700 int HOptimizedGraphBuilder::InliningAstSize(Handle<JSFunction> target) {
6312 if (!FLAG_use_inlining) return kNotInlinable; 6701 if (!FLAG_use_inlining) return kNotInlinable;
6313 6702
6314 // Precondition: call is monomorphic and we have found a target with the 6703 // Precondition: call is monomorphic and we have found a target with the
6315 // appropriate arity. 6704 // appropriate arity.
6316 Handle<JSFunction> caller = current_info()->closure(); 6705 Handle<JSFunction> caller = current_info()->closure();
6317 Handle<SharedFunctionInfo> target_shared(target->shared()); 6706 Handle<SharedFunctionInfo> target_shared(target->shared());
6318 6707
6708 // Always inline builtins marked for inlining.
6709 if (target->IsBuiltin()) {
6710 return target_shared->inline_builtin() ? 0 : kNotInlinable;
6711 }
6712
6319 // Do a quick check on source code length to avoid parsing large 6713 // Do a quick check on source code length to avoid parsing large
6320 // inlining candidates. 6714 // inlining candidates.
6321 if (target_shared->SourceSize() > 6715 if (target_shared->SourceSize() >
6322 Min(FLAG_max_inlined_source_size, kUnlimitedMaxInlinedSourceSize)) { 6716 Min(FLAG_max_inlined_source_size, kUnlimitedMaxInlinedSourceSize)) {
6323 TraceInline(target, caller, "target text too big"); 6717 TraceInline(target, caller, "target text too big");
6324 return kNotInlinable; 6718 return kNotInlinable;
6325 } 6719 }
6326 6720
6327 // Target must be inlineable. 6721 // Target must be inlineable.
6328 if (!target->IsInlineable()) { 6722 if (!target_shared->IsInlineable()) {
6329 TraceInline(target, caller, "target not inlineable"); 6723 TraceInline(target, caller, "target not inlineable");
6330 return kNotInlinable; 6724 return kNotInlinable;
6331 } 6725 }
6332 if (target_shared->dont_inline() || target_shared->dont_optimize()) { 6726 if (target_shared->dont_inline() || target_shared->dont_optimize()) {
6333 TraceInline(target, caller, "target contains unsupported syntax [early]"); 6727 TraceInline(target, caller, "target contains unsupported syntax [early]");
6334 return kNotInlinable; 6728 return kNotInlinable;
6335 } 6729 }
6336 6730
6337 int nodes_added = target_shared->ast_node_count(); 6731 int nodes_added = target_shared->ast_node_count();
6338 return nodes_added; 6732 return nodes_added;
(...skipping 10 matching lines...) Expand all
6349 int nodes_added = InliningAstSize(target); 6743 int nodes_added = InliningAstSize(target);
6350 if (nodes_added == kNotInlinable) return false; 6744 if (nodes_added == kNotInlinable) return false;
6351 6745
6352 Handle<JSFunction> caller = current_info()->closure(); 6746 Handle<JSFunction> caller = current_info()->closure();
6353 6747
6354 if (nodes_added > Min(FLAG_max_inlined_nodes, kUnlimitedMaxInlinedNodes)) { 6748 if (nodes_added > Min(FLAG_max_inlined_nodes, kUnlimitedMaxInlinedNodes)) {
6355 TraceInline(target, caller, "target AST is too large [early]"); 6749 TraceInline(target, caller, "target AST is too large [early]");
6356 return false; 6750 return false;
6357 } 6751 }
6358 6752
6359 #if !V8_TARGET_ARCH_IA32 && !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_MIPS
6360 // Target must be able to use caller's context.
6361 CompilationInfo* outer_info = current_info();
6362 if (target->context() != outer_info->closure()->context() ||
6363 outer_info->scope()->contains_with() ||
6364 outer_info->scope()->num_heap_slots() > 0) {
6365 TraceInline(target, caller, "target requires context change");
6366 return false;
6367 }
6368 #endif
6369
6370
6371 // Don't inline deeper than the maximum number of inlining levels. 6753 // Don't inline deeper than the maximum number of inlining levels.
6372 HEnvironment* env = environment(); 6754 HEnvironment* env = environment();
6373 int current_level = 1; 6755 int current_level = 1;
6374 while (env->outer() != NULL) { 6756 while (env->outer() != NULL) {
6375 if (current_level == FLAG_max_inlining_levels) { 6757 if (current_level == FLAG_max_inlining_levels) {
6376 TraceInline(target, caller, "inline depth limit reached"); 6758 TraceInline(target, caller, "inline depth limit reached");
6377 return false; 6759 return false;
6378 } 6760 }
6379 if (env->outer()->frame_type() == JS_FUNCTION) { 6761 if (env->outer()->frame_type() == JS_FUNCTION) {
6380 current_level++; 6762 current_level++;
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
6498 HConstant* undefined = graph()->GetConstantUndefined(); 6880 HConstant* undefined = graph()->GetConstantUndefined();
6499 bool undefined_receiver = HEnvironment::UseUndefinedReceiver( 6881 bool undefined_receiver = HEnvironment::UseUndefinedReceiver(
6500 target, function, call_kind, inlining_kind); 6882 target, function, call_kind, inlining_kind);
6501 HEnvironment* inner_env = 6883 HEnvironment* inner_env =
6502 environment()->CopyForInlining(target, 6884 environment()->CopyForInlining(target,
6503 arguments_count, 6885 arguments_count,
6504 function, 6886 function,
6505 undefined, 6887 undefined,
6506 function_state()->inlining_kind(), 6888 function_state()->inlining_kind(),
6507 undefined_receiver); 6889 undefined_receiver);
6508 #if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS 6890
6509 // IA32, ARM and MIPS only, overwrite the caller's context in the
6510 // deoptimization environment with the correct one.
6511 //
6512 // TODO(kmillikin): implement the same inlining on other platforms so we
6513 // can remove the unsightly ifdefs in this function.
6514 HConstant* context = Add<HConstant>(Handle<Context>(target->context())); 6891 HConstant* context = Add<HConstant>(Handle<Context>(target->context()));
6515 inner_env->BindContext(context); 6892 inner_env->BindContext(context);
6516 #endif
6517 6893
6518 Add<HSimulate>(return_id); 6894 Add<HSimulate>(return_id);
6519 current_block()->UpdateEnvironment(inner_env); 6895 current_block()->UpdateEnvironment(inner_env);
6520 HArgumentsObject* arguments_object = NULL; 6896 HArgumentsObject* arguments_object = NULL;
6521 6897
6522 // If the function uses arguments object create and bind one, also copy 6898 // If the function uses arguments object create and bind one, also copy
6523 // current arguments values to use them for materialization. 6899 // current arguments values to use them for materialization.
6524 if (function->scope()->arguments() != NULL) { 6900 if (function->scope()->arguments() != NULL) {
6525 ASSERT(function->scope()->arguments()->IsStackAllocated()); 6901 ASSERT(function->scope()->arguments()->IsStackAllocated());
6526 HEnvironment* arguments_env = inner_env->arguments_environment(); 6902 HEnvironment* arguments_env = inner_env->arguments_environment();
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
6716 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id(); 7092 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id();
6717 switch (id) { 7093 switch (id) {
6718 case kMathExp: 7094 case kMathExp:
6719 if (!FLAG_fast_math) break; 7095 if (!FLAG_fast_math) break;
6720 // Fall through if FLAG_fast_math. 7096 // Fall through if FLAG_fast_math.
6721 case kMathRound: 7097 case kMathRound:
6722 case kMathFloor: 7098 case kMathFloor:
6723 case kMathAbs: 7099 case kMathAbs:
6724 case kMathSqrt: 7100 case kMathSqrt:
6725 case kMathLog: 7101 case kMathLog:
6726 case kMathSin:
6727 case kMathCos:
6728 case kMathTan:
6729 if (expr->arguments()->length() == 1) { 7102 if (expr->arguments()->length() == 1) {
6730 HValue* argument = Pop(); 7103 HValue* argument = Pop();
6731 Drop(1); // Receiver. 7104 Drop(1); // Receiver.
6732 HInstruction* op = NewUncasted<HUnaryMathOperation>(argument, id); 7105 HInstruction* op = NewUncasted<HUnaryMathOperation>(argument, id);
6733 if (drop_extra) Drop(1); // Optionally drop the function. 7106 if (drop_extra) Drop(1); // Optionally drop the function.
6734 ast_context()->ReturnInstruction(op, expr->id()); 7107 ast_context()->ReturnInstruction(op, expr->id());
6735 return true; 7108 return true;
6736 } 7109 }
6737 break; 7110 break;
6738 case kMathImul: 7111 case kMathImul:
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
6797 } 7170 }
6798 break; 7171 break;
6799 case kMathExp: 7172 case kMathExp:
6800 if (!FLAG_fast_math) break; 7173 if (!FLAG_fast_math) break;
6801 // Fall through if FLAG_fast_math. 7174 // Fall through if FLAG_fast_math.
6802 case kMathRound: 7175 case kMathRound:
6803 case kMathFloor: 7176 case kMathFloor:
6804 case kMathAbs: 7177 case kMathAbs:
6805 case kMathSqrt: 7178 case kMathSqrt:
6806 case kMathLog: 7179 case kMathLog:
6807 case kMathSin:
6808 case kMathCos:
6809 case kMathTan:
6810 if (argument_count == 2 && check_type == RECEIVER_MAP_CHECK) { 7180 if (argument_count == 2 && check_type == RECEIVER_MAP_CHECK) {
6811 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); 7181 AddCheckConstantFunction(expr->holder(), receiver, receiver_map);
6812 HValue* argument = Pop(); 7182 HValue* argument = Pop();
6813 Drop(1); // Receiver. 7183 Drop(1); // Receiver.
6814 HInstruction* op = NewUncasted<HUnaryMathOperation>(argument, id); 7184 HInstruction* op = NewUncasted<HUnaryMathOperation>(argument, id);
6815 ast_context()->ReturnInstruction(op, expr->id()); 7185 ast_context()->ReturnInstruction(op, expr->id());
6816 return true; 7186 return true;
6817 } 7187 }
6818 break; 7188 break;
6819 case kMathPow: 7189 case kMathPow:
(...skipping 1916 matching lines...) Expand 10 before | Expand all | Expand 10 after
8736 void HOptimizedGraphBuilder::GenerateIsFunction(CallRuntime* call) { 9106 void HOptimizedGraphBuilder::GenerateIsFunction(CallRuntime* call) {
8737 ASSERT(call->arguments()->length() == 1); 9107 ASSERT(call->arguments()->length() == 1);
8738 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 9108 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
8739 HValue* value = Pop(); 9109 HValue* value = Pop();
8740 HHasInstanceTypeAndBranch* result = 9110 HHasInstanceTypeAndBranch* result =
8741 New<HHasInstanceTypeAndBranch>(value, JS_FUNCTION_TYPE); 9111 New<HHasInstanceTypeAndBranch>(value, JS_FUNCTION_TYPE);
8742 return ast_context()->ReturnControl(result, call->id()); 9112 return ast_context()->ReturnControl(result, call->id());
8743 } 9113 }
8744 9114
8745 9115
9116 void HOptimizedGraphBuilder::GenerateIsMinusZero(CallRuntime* call) {
9117 ASSERT(call->arguments()->length() == 1);
9118 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9119 HValue* value = Pop();
9120 HCompareMinusZeroAndBranch* result = New<HCompareMinusZeroAndBranch>(value);
9121 return ast_context()->ReturnControl(result, call->id());
9122 }
9123
9124
8746 void HOptimizedGraphBuilder::GenerateHasCachedArrayIndex(CallRuntime* call) { 9125 void HOptimizedGraphBuilder::GenerateHasCachedArrayIndex(CallRuntime* call) {
8747 ASSERT(call->arguments()->length() == 1); 9126 ASSERT(call->arguments()->length() == 1);
8748 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 9127 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
8749 HValue* value = Pop(); 9128 HValue* value = Pop();
8750 HHasCachedArrayIndexAndBranch* result = 9129 HHasCachedArrayIndexAndBranch* result =
8751 New<HHasCachedArrayIndexAndBranch>(value); 9130 New<HHasCachedArrayIndexAndBranch>(value);
8752 return ast_context()->ReturnControl(result, call->id()); 9131 return ast_context()->ReturnControl(result, call->id());
8753 } 9132 }
8754 9133
8755 9134
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after
9119 ASSERT_EQ(2, call->arguments()->length()); 9498 ASSERT_EQ(2, call->arguments()->length());
9120 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 9499 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9121 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 9500 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
9122 HValue* right = Pop(); 9501 HValue* right = Pop();
9123 HValue* left = Pop(); 9502 HValue* left = Pop();
9124 HInstruction* result = NewUncasted<HPower>(left, right); 9503 HInstruction* result = NewUncasted<HPower>(left, right);
9125 return ast_context()->ReturnInstruction(result, call->id()); 9504 return ast_context()->ReturnInstruction(result, call->id());
9126 } 9505 }
9127 9506
9128 9507
9129 void HOptimizedGraphBuilder::GenerateMathSin(CallRuntime* call) {
9130 ASSERT_EQ(1, call->arguments()->length());
9131 CHECK_ALIVE(VisitArgumentList(call->arguments()));
9132 HCallStub* result = New<HCallStub>(CodeStub::TranscendentalCache, 1);
9133 result->set_transcendental_type(TranscendentalCache::SIN);
9134 Drop(1);
9135 return ast_context()->ReturnInstruction(result, call->id());
9136 }
9137
9138
9139 void HOptimizedGraphBuilder::GenerateMathCos(CallRuntime* call) {
9140 ASSERT_EQ(1, call->arguments()->length());
9141 CHECK_ALIVE(VisitArgumentList(call->arguments()));
9142 HCallStub* result = New<HCallStub>(CodeStub::TranscendentalCache, 1);
9143 result->set_transcendental_type(TranscendentalCache::COS);
9144 Drop(1);
9145 return ast_context()->ReturnInstruction(result, call->id());
9146 }
9147
9148
9149 void HOptimizedGraphBuilder::GenerateMathTan(CallRuntime* call) {
9150 ASSERT_EQ(1, call->arguments()->length());
9151 CHECK_ALIVE(VisitArgumentList(call->arguments()));
9152 HCallStub* result = New<HCallStub>(CodeStub::TranscendentalCache, 1);
9153 result->set_transcendental_type(TranscendentalCache::TAN);
9154 Drop(1);
9155 return ast_context()->ReturnInstruction(result, call->id());
9156 }
9157
9158
9159 void HOptimizedGraphBuilder::GenerateMathLog(CallRuntime* call) { 9508 void HOptimizedGraphBuilder::GenerateMathLog(CallRuntime* call) {
9160 ASSERT_EQ(1, call->arguments()->length()); 9509 ASSERT_EQ(1, call->arguments()->length());
9161 CHECK_ALIVE(VisitArgumentList(call->arguments())); 9510 CHECK_ALIVE(VisitArgumentList(call->arguments()));
9162 HCallStub* result = New<HCallStub>(CodeStub::TranscendentalCache, 1); 9511 HCallStub* result = New<HCallStub>(CodeStub::TranscendentalCache, 1);
9163 result->set_transcendental_type(TranscendentalCache::LOG); 9512 result->set_transcendental_type(TranscendentalCache::LOG);
9164 Drop(1); 9513 Drop(1);
9165 return ast_context()->ReturnInstruction(result, call->id()); 9514 return ast_context()->ReturnInstruction(result, call->id());
9166 } 9515 }
9167 9516
9168 9517
(...skipping 650 matching lines...) Expand 10 before | Expand all | Expand 10 after
9819 if (ShouldProduceTraceOutput()) { 10168 if (ShouldProduceTraceOutput()) {
9820 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 10169 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
9821 } 10170 }
9822 10171
9823 #ifdef DEBUG 10172 #ifdef DEBUG
9824 graph_->Verify(false); // No full verify. 10173 graph_->Verify(false); // No full verify.
9825 #endif 10174 #endif
9826 } 10175 }
9827 10176
9828 } } // namespace v8::internal 10177 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-gvn.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698