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

Side by Side Diff: src/hydrogen.cc

Issue 132373011: A64: Synchronize with r17635. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 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.h ('k') | src/hydrogen-instructions.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 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 692 matching lines...) Expand 10 before | Expand all | Expand 10 after
703 703
704 DEFINE_GET_CONSTANT(Undefined, undefined, HType::Tagged(), false) 704 DEFINE_GET_CONSTANT(Undefined, undefined, HType::Tagged(), false)
705 DEFINE_GET_CONSTANT(True, true, HType::Boolean(), true) 705 DEFINE_GET_CONSTANT(True, true, HType::Boolean(), true)
706 DEFINE_GET_CONSTANT(False, false, HType::Boolean(), false) 706 DEFINE_GET_CONSTANT(False, false, HType::Boolean(), false)
707 DEFINE_GET_CONSTANT(Hole, the_hole, HType::Tagged(), false) 707 DEFINE_GET_CONSTANT(Hole, the_hole, HType::Tagged(), false)
708 DEFINE_GET_CONSTANT(Null, null, HType::Tagged(), false) 708 DEFINE_GET_CONSTANT(Null, null, HType::Tagged(), false)
709 709
710 710
711 #undef DEFINE_GET_CONSTANT 711 #undef DEFINE_GET_CONSTANT
712 712
713 #define DEFINE_IS_CONSTANT(Name, name) \
714 bool HGraph::IsConstant##Name(HConstant* constant) { \
715 return constant_##name##_.is_set() && constant == constant_##name##_.get(); \
716 }
717 DEFINE_IS_CONSTANT(Undefined, undefined)
718 DEFINE_IS_CONSTANT(0, 0)
719 DEFINE_IS_CONSTANT(1, 1)
720 DEFINE_IS_CONSTANT(Minus1, minus1)
721 DEFINE_IS_CONSTANT(True, true)
722 DEFINE_IS_CONSTANT(False, false)
723 DEFINE_IS_CONSTANT(Hole, the_hole)
724 DEFINE_IS_CONSTANT(Null, null)
725
726 #undef DEFINE_IS_CONSTANT
727
713 728
714 HConstant* HGraph::GetInvalidContext() { 729 HConstant* HGraph::GetInvalidContext() {
715 return GetConstant(&constant_invalid_context_, 0xFFFFC0C7); 730 return GetConstant(&constant_invalid_context_, 0xFFFFC0C7);
716 } 731 }
717 732
718 733
719 bool HGraph::IsStandardConstant(HConstant* constant) { 734 bool HGraph::IsStandardConstant(HConstant* constant) {
720 if (constant == GetConstantUndefined()) return true; 735 if (IsConstantUndefined(constant)) return true;
721 if (constant == GetConstant0()) return true; 736 if (IsConstant0(constant)) return true;
722 if (constant == GetConstant1()) return true; 737 if (IsConstant1(constant)) return true;
723 if (constant == GetConstantMinus1()) return true; 738 if (IsConstantMinus1(constant)) return true;
724 if (constant == GetConstantTrue()) return true; 739 if (IsConstantTrue(constant)) return true;
725 if (constant == GetConstantFalse()) return true; 740 if (IsConstantFalse(constant)) return true;
726 if (constant == GetConstantHole()) return true; 741 if (IsConstantHole(constant)) return true;
727 if (constant == GetConstantNull()) return true; 742 if (IsConstantNull(constant)) return true;
728 return false; 743 return false;
729 } 744 }
730 745
731 746
732 HGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder) 747 HGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder)
733 : builder_(builder), 748 : builder_(builder),
734 finished_(false), 749 finished_(false),
735 deopt_then_(false), 750 deopt_then_(false),
736 deopt_else_(false), 751 deopt_else_(false),
737 did_then_(false), 752 did_then_(false),
(...skipping 711 matching lines...) Expand 10 before | Expand all | Expand 10 after
1449 isolate()->factory()->empty_string(), 1464 isolate()->factory()->empty_string(),
1450 Runtime::FunctionForId(Runtime::kNumberToStringSkipCache), 1465 Runtime::FunctionForId(Runtime::kNumberToStringSkipCache),
1451 1)); 1466 1));
1452 } 1467 }
1453 if_found.End(); 1468 if_found.End();
1454 1469
1455 return Pop(); 1470 return Pop();
1456 } 1471 }
1457 1472
1458 1473
1474 HValue* HGraphBuilder::BuildSeqStringSizeFor(HValue* length,
1475 String::Encoding encoding) {
1476 STATIC_ASSERT((SeqString::kHeaderSize & kObjectAlignmentMask) == 0);
1477 HValue* size = length;
1478 if (encoding == String::TWO_BYTE_ENCODING) {
1479 size = Add<HShl>(length, graph()->GetConstant1());
1480 size->ClearFlag(HValue::kCanOverflow);
1481 size->SetFlag(HValue::kUint32);
1482 }
1483 size = Add<HAdd>(size, Add<HConstant>(static_cast<int32_t>(
1484 SeqString::kHeaderSize + kObjectAlignmentMask)));
1485 size->ClearFlag(HValue::kCanOverflow);
1486 size = Add<HBitwise>(
1487 Token::BIT_AND, size, Add<HConstant>(static_cast<int32_t>(
1488 ~kObjectAlignmentMask)));
1489 return size;
1490 }
1491
1492
1493 void HGraphBuilder::BuildCopySeqStringChars(HValue* src,
1494 HValue* src_offset,
1495 String::Encoding src_encoding,
1496 HValue* dst,
1497 HValue* dst_offset,
1498 String::Encoding dst_encoding,
1499 HValue* length) {
1500 ASSERT(dst_encoding != String::ONE_BYTE_ENCODING ||
1501 src_encoding == String::ONE_BYTE_ENCODING);
1502 LoopBuilder loop(this, context(), LoopBuilder::kPostIncrement);
1503 HValue* index = loop.BeginBody(graph()->GetConstant0(), length, Token::LT);
1504 {
1505 HValue* src_index = Add<HAdd>(src_offset, index);
1506 HValue* value = Add<HSeqStringGetChar>(src_encoding, src, src_index);
1507 HValue* dst_index = Add<HAdd>(dst_offset, index);
1508 Add<HSeqStringSetChar>(dst_encoding, dst, dst_index, value);
1509 }
1510 loop.EndBody();
1511 }
1512
1513
1514 HValue* HGraphBuilder::BuildUncheckedStringAdd(HValue* left,
1515 HValue* right,
1516 PretenureFlag pretenure_flag) {
1517 // Determine the string lengths.
1518 HValue* left_length = Add<HLoadNamedField>(
1519 left, HObjectAccess::ForStringLength());
1520 HValue* right_length = Add<HLoadNamedField>(
1521 right, HObjectAccess::ForStringLength());
1522
1523 // Check if we concatenated the strings here, or if we have to resort to the
1524 // runtime function.
1525 HIfContinuation handled(graph()->CreateBasicBlock(),
1526 graph()->CreateBasicBlock());
1527
1528 // Check if both parameters do not exceed half the max string length, because
1529 // exceptionally long strings should be handled in the runtime. Unfortunately
1530 // we cannot actually check whether the combined length of both strings
1531 // exceeds String::kMaxLength (because of unclear results from the
1532 // representation inference phase), so we use a pessimistic approach here
1533 // instead, checking that the length of either substring does not exceed half
1534 // of String::kMaxLength.
1535 HConstant* max_length = Add<HConstant>(String::kMaxLength / 2);
1536 IfBuilder if_nooverflow(this);
1537 if_nooverflow.If<HCompareNumericAndBranch>(
1538 left_length, max_length, Token::LTE);
1539 if_nooverflow.AndIf<HCompareNumericAndBranch>(
1540 right_length, max_length, Token::LTE);
1541 if_nooverflow.Then();
1542 {
1543 // Determine the string instance types.
1544 HLoadNamedField* left_instance_type = Add<HLoadNamedField>(
1545 Add<HLoadNamedField>(left, HObjectAccess::ForMap()),
1546 HObjectAccess::ForMapInstanceType());
1547 HLoadNamedField* right_instance_type = Add<HLoadNamedField>(
1548 Add<HLoadNamedField>(right, HObjectAccess::ForMap()),
1549 HObjectAccess::ForMapInstanceType());
1550
1551 // Compute difference of instance types.
1552 HValue* xored_instance_types = Add<HBitwise>(
1553 Token::BIT_XOR, left_instance_type, right_instance_type);
1554
1555 // Compute the length of the resulting string.
1556 HValue* length = Add<HAdd>(left_length, right_length);
1557
1558 // Check if we should create a cons string.
1559 IfBuilder if_createcons(this);
1560 if_createcons.If<HCompareNumericAndBranch>(
1561 length, Add<HConstant>(ConsString::kMinLength), Token::GTE);
1562 if_createcons.Then();
1563 {
1564 // Allocate the cons string object. HAllocate does not care whether we
1565 // pass CONS_STRING_TYPE or CONS_ASCII_STRING_TYPE here, so we just use
1566 // CONS_STRING_TYPE here. Below we decide whether the cons string is
1567 // one-byte or two-byte and set the appropriate map.
1568 HAllocate* string = Add<HAllocate>(Add<HConstant>(ConsString::kSize),
1569 HType::String(), pretenure_flag,
1570 CONS_STRING_TYPE);
1571
1572 // Compute the intersection of instance types.
1573 HValue* anded_instance_types = Add<HBitwise>(
1574 Token::BIT_AND, left_instance_type, right_instance_type);
1575
1576 // We create a one-byte cons string if
1577 // 1. both strings are one-byte, or
1578 // 2. at least one of the strings is two-byte, but happens to contain only
1579 // one-byte characters.
1580 // To do this, we check
1581 // 1. if both strings are one-byte, or if the one-byte data hint is set in
1582 // both strings, or
1583 // 2. if one of the strings has the one-byte data hint set and the other
1584 // string is one-byte.
1585 IfBuilder if_onebyte(this);
1586 STATIC_ASSERT(kOneByteStringTag != 0);
1587 STATIC_ASSERT(kOneByteDataHintMask != 0);
1588 if_onebyte.If<HCompareNumericAndBranch>(
1589 Add<HBitwise>(
1590 Token::BIT_AND, anded_instance_types,
1591 Add<HConstant>(static_cast<int32_t>(
1592 kStringEncodingMask | kOneByteDataHintMask))),
1593 graph()->GetConstant0(), Token::NE);
1594 if_onebyte.Or();
1595 STATIC_ASSERT(kOneByteStringTag != 0 &&
1596 kOneByteDataHintTag != 0 &&
1597 kOneByteDataHintTag != kOneByteStringTag);
1598 if_onebyte.If<HCompareNumericAndBranch>(
1599 Add<HBitwise>(
1600 Token::BIT_AND, xored_instance_types,
1601 Add<HConstant>(static_cast<int32_t>(
1602 kOneByteStringTag | kOneByteDataHintTag))),
1603 Add<HConstant>(static_cast<int32_t>(
1604 kOneByteStringTag | kOneByteDataHintTag)), Token::EQ);
1605 if_onebyte.Then();
1606 {
1607 // We can safely skip the write barrier for storing the map here.
1608 Handle<Map> map = isolate()->factory()->cons_ascii_string_map();
1609 AddStoreMapConstantNoWriteBarrier(string, map);
1610 }
1611 if_onebyte.Else();
1612 {
1613 // We can safely skip the write barrier for storing the map here.
1614 Handle<Map> map = isolate()->factory()->cons_string_map();
1615 AddStoreMapConstantNoWriteBarrier(string, map);
1616 }
1617 if_onebyte.End();
1618
1619 // Initialize the cons string fields.
1620 Add<HStoreNamedField>(string, HObjectAccess::ForStringHashField(),
1621 Add<HConstant>(String::kEmptyHashField));
1622 Add<HStoreNamedField>(string, HObjectAccess::ForStringLength(), length);
1623 Add<HStoreNamedField>(string, HObjectAccess::ForConsStringFirst(), left);
1624 Add<HStoreNamedField>(string, HObjectAccess::ForConsStringSecond(),
1625 right);
1626
1627 // Cons string is result.
1628 Push(string);
1629 }
1630 if_createcons.Else();
1631 {
1632 // Compute union of instance types.
1633 HValue* ored_instance_types = Add<HBitwise>(
1634 Token::BIT_OR, left_instance_type, right_instance_type);
1635
1636 // Check if both strings have the same encoding and both are
1637 // sequential.
1638 IfBuilder if_sameencodingandsequential(this);
1639 if_sameencodingandsequential.If<HCompareNumericAndBranch>(
1640 Add<HBitwise>(
1641 Token::BIT_AND, xored_instance_types,
1642 Add<HConstant>(static_cast<int32_t>(kStringEncodingMask))),
1643 graph()->GetConstant0(), Token::EQ);
1644 if_sameencodingandsequential.And();
1645 STATIC_ASSERT(kSeqStringTag == 0);
1646 if_sameencodingandsequential.If<HCompareNumericAndBranch>(
1647 Add<HBitwise>(
1648 Token::BIT_AND, ored_instance_types,
1649 Add<HConstant>(static_cast<int32_t>(kStringRepresentationMask))),
1650 graph()->GetConstant0(), Token::EQ);
1651 if_sameencodingandsequential.Then();
1652 {
1653 // Check if the result is a one-byte string.
1654 IfBuilder if_onebyte(this);
1655 STATIC_ASSERT(kOneByteStringTag != 0);
1656 if_onebyte.If<HCompareNumericAndBranch>(
1657 Add<HBitwise>(
1658 Token::BIT_AND, ored_instance_types,
1659 Add<HConstant>(static_cast<int32_t>(kStringEncodingMask))),
1660 graph()->GetConstant0(), Token::NE);
1661 if_onebyte.Then();
1662 {
1663 // Calculate the number of bytes needed for the characters in the
1664 // string while observing object alignment.
1665 HValue* size = BuildSeqStringSizeFor(
1666 length, String::ONE_BYTE_ENCODING);
1667
1668 // Allocate the ASCII string object.
1669 Handle<Map> map = isolate()->factory()->ascii_string_map();
1670 HAllocate* string = Add<HAllocate>(size, HType::String(),
1671 pretenure_flag, ASCII_STRING_TYPE);
1672 string->set_known_initial_map(map);
1673
1674 // We can safely skip the write barrier for storing map here.
1675 AddStoreMapConstantNoWriteBarrier(string, map);
1676
1677 // Copy bytes from the left string.
1678 BuildCopySeqStringChars(
1679 left, graph()->GetConstant0(), String::ONE_BYTE_ENCODING,
1680 string, graph()->GetConstant0(), String::ONE_BYTE_ENCODING,
1681 left_length);
1682
1683 // Copy bytes from the right string.
1684 BuildCopySeqStringChars(
1685 right, graph()->GetConstant0(), String::ONE_BYTE_ENCODING,
1686 string, left_length, String::ONE_BYTE_ENCODING,
1687 right_length);
1688
1689 // Return the string.
1690 Push(string);
1691 }
1692 if_onebyte.Else();
1693 {
1694 // Calculate the number of bytes needed for the characters in the
1695 // string while observing object alignment.
1696 HValue* size = BuildSeqStringSizeFor(
1697 length, String::TWO_BYTE_ENCODING);
1698
1699 // Allocate the two-byte string object.
1700 Handle<Map> map = isolate()->factory()->string_map();
1701 HAllocate* string = Add<HAllocate>(size, HType::String(),
1702 pretenure_flag, STRING_TYPE);
1703 string->set_known_initial_map(map);
1704
1705 // We can safely skip the write barrier for storing map here.
1706 AddStoreMapConstantNoWriteBarrier(string, map);
1707
1708 // Copy bytes from the left string.
1709 BuildCopySeqStringChars(
1710 left, graph()->GetConstant0(), String::TWO_BYTE_ENCODING,
1711 string, graph()->GetConstant0(), String::TWO_BYTE_ENCODING,
1712 left_length);
1713
1714 // Copy bytes from the right string.
1715 BuildCopySeqStringChars(
1716 right, graph()->GetConstant0(), String::TWO_BYTE_ENCODING,
1717 string, left_length, String::TWO_BYTE_ENCODING,
1718 right_length);
1719
1720 // Return the string.
1721 Push(string);
1722 }
1723 if_onebyte.End();
1724
1725 // Initialize the (common) string fields.
1726 HValue* string = Pop();
1727 Add<HStoreNamedField>(string, HObjectAccess::ForStringHashField(),
1728 Add<HConstant>(String::kEmptyHashField));
1729 Add<HStoreNamedField>(string, HObjectAccess::ForStringLength(),
1730 length);
1731 Push(string);
1732 }
1733 if_sameencodingandsequential.JoinContinuation(&handled);
1734 }
1735 if_createcons.JoinContinuation(&handled);
1736 }
1737 if_nooverflow.JoinContinuation(&handled);
1738
1739 // Check if the strings were concatenated successfully, otherwise fallback to
1740 // add the strings in the runtime.
1741 IfBuilder if_handled(this, &handled);
1742 if_handled.Then();
1743 {
1744 // Count the native string addition.
1745 AddIncrementCounter(isolate()->counters()->string_add_native());
1746 }
1747 if_handled.Else();
1748 {
1749 // Fallback to the runtime to add the two strings.
1750 Add<HPushArgument>(left);
1751 Add<HPushArgument>(right);
1752 Push(Add<HCallRuntime>(isolate()->factory()->empty_string(),
1753 Runtime::FunctionForId(Runtime::kStringAdd),
1754 2));
1755 }
1756 if_handled.End();
1757
1758 return Pop();
1759 }
1760
1761
1762 HValue* HGraphBuilder::BuildStringAdd(HValue* left,
1763 HValue* right,
1764 PretenureFlag pretenure_flag) {
1765 // Determine the string lengths.
1766 HValue* left_length = Add<HLoadNamedField>(
1767 left, HObjectAccess::ForStringLength());
1768 HValue* right_length = Add<HLoadNamedField>(
1769 right, HObjectAccess::ForStringLength());
1770
1771 // Check if left string is empty.
1772 IfBuilder if_leftisempty(this);
1773 if_leftisempty.If<HCompareNumericAndBranch>(
1774 left_length, graph()->GetConstant0(), Token::EQ);
1775 if_leftisempty.Then();
1776 {
1777 // Count the native string addition.
1778 AddIncrementCounter(isolate()->counters()->string_add_native());
1779
1780 // Just return the right string.
1781 Push(right);
1782 }
1783 if_leftisempty.Else();
1784 {
1785 // Check if right string is empty.
1786 IfBuilder if_rightisempty(this);
1787 if_rightisempty.If<HCompareNumericAndBranch>(
1788 right_length, graph()->GetConstant0(), Token::EQ);
1789 if_rightisempty.Then();
1790 {
1791 // Count the native string addition.
1792 AddIncrementCounter(isolate()->counters()->string_add_native());
1793
1794 // Just return the left string.
1795 Push(left);
1796 }
1797 if_rightisempty.Else();
1798 {
1799 // Concatenate the two non-empty strings.
1800 Push(BuildUncheckedStringAdd(left, right, pretenure_flag));
1801 }
1802 if_rightisempty.End();
1803 }
1804 if_leftisempty.End();
1805
1806 return Pop();
1807 }
1808
1809
1459 HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( 1810 HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess(
1460 HValue* checked_object, 1811 HValue* checked_object,
1461 HValue* key, 1812 HValue* key,
1462 HValue* val, 1813 HValue* val,
1463 bool is_js_array, 1814 bool is_js_array,
1464 ElementsKind elements_kind, 1815 ElementsKind elements_kind,
1465 bool is_store, 1816 bool is_store,
1466 LoadKeyedHoleMode load_mode, 1817 LoadKeyedHoleMode load_mode,
1467 KeyedAccessStoreMode store_mode) { 1818 KeyedAccessStoreMode store_mode) {
1468 ASSERT(!IsExternalArrayElementsKind(elements_kind) || !is_js_array); 1819 ASSERT(!IsExternalArrayElementsKind(elements_kind) || !is_js_array);
(...skipping 807 matching lines...) Expand 10 before | Expand all | Expand 10 after
2276 phi_list_(NULL), 2627 phi_list_(NULL),
2277 uint32_instructions_(NULL), 2628 uint32_instructions_(NULL),
2278 osr_(NULL), 2629 osr_(NULL),
2279 info_(info), 2630 info_(info),
2280 zone_(info->zone()), 2631 zone_(info->zone()),
2281 is_recursive_(false), 2632 is_recursive_(false),
2282 use_optimistic_licm_(false), 2633 use_optimistic_licm_(false),
2283 depends_on_empty_array_proto_elements_(false), 2634 depends_on_empty_array_proto_elements_(false),
2284 type_change_checksum_(0), 2635 type_change_checksum_(0),
2285 maximum_environment_size_(0), 2636 maximum_environment_size_(0),
2286 no_side_effects_scope_count_(0) { 2637 no_side_effects_scope_count_(0),
2638 disallow_adding_new_values_(false) {
2287 if (info->IsStub()) { 2639 if (info->IsStub()) {
2288 HydrogenCodeStub* stub = info->code_stub(); 2640 HydrogenCodeStub* stub = info->code_stub();
2289 CodeStubInterfaceDescriptor* descriptor = 2641 CodeStubInterfaceDescriptor* descriptor =
2290 stub->GetInterfaceDescriptor(isolate_); 2642 stub->GetInterfaceDescriptor(isolate_);
2291 start_environment_ = 2643 start_environment_ =
2292 new(zone_) HEnvironment(zone_, descriptor->environment_length()); 2644 new(zone_) HEnvironment(zone_, descriptor->environment_length());
2293 } else { 2645 } else {
2294 start_environment_ = 2646 start_environment_ =
2295 new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_); 2647 new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_);
2296 } 2648 }
(...skipping 2008 matching lines...) Expand 10 before | Expand all | Expand 10 after
4305 } 4657 }
4306 } 4658 }
4307 return true; 4659 return true;
4308 } 4660 }
4309 4661
4310 4662
4311 void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { 4663 void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
4312 ASSERT(!HasStackOverflow()); 4664 ASSERT(!HasStackOverflow());
4313 ASSERT(current_block() != NULL); 4665 ASSERT(current_block() != NULL);
4314 ASSERT(current_block()->HasPredecessor()); 4666 ASSERT(current_block()->HasPredecessor());
4667 expr->BuildConstantProperties(isolate());
4315 Handle<JSFunction> closure = function_state()->compilation_info()->closure(); 4668 Handle<JSFunction> closure = function_state()->compilation_info()->closure();
4316 HInstruction* literal; 4669 HInstruction* literal;
4317 4670
4318 // Check whether to use fast or slow deep-copying for boilerplate. 4671 // Check whether to use fast or slow deep-copying for boilerplate.
4319 int max_properties = kMaxFastLiteralProperties; 4672 int max_properties = kMaxFastLiteralProperties;
4320 Handle<Object> literals_cell(closure->literals()->get(expr->literal_index()), 4673 Handle<Object> literals_cell(closure->literals()->get(expr->literal_index()),
4321 isolate()); 4674 isolate());
4322 Handle<AllocationSite> site; 4675 Handle<AllocationSite> site;
4323 Handle<JSObject> boilerplate; 4676 Handle<JSObject> boilerplate;
4324 if (!literals_cell->IsUndefined()) { 4677 if (!literals_cell->IsUndefined()) {
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
4426 } else { 4779 } else {
4427 return ast_context()->ReturnValue(Pop()); 4780 return ast_context()->ReturnValue(Pop());
4428 } 4781 }
4429 } 4782 }
4430 4783
4431 4784
4432 void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { 4785 void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
4433 ASSERT(!HasStackOverflow()); 4786 ASSERT(!HasStackOverflow());
4434 ASSERT(current_block() != NULL); 4787 ASSERT(current_block() != NULL);
4435 ASSERT(current_block()->HasPredecessor()); 4788 ASSERT(current_block()->HasPredecessor());
4789 expr->BuildConstantElements(isolate());
4436 ZoneList<Expression*>* subexprs = expr->values(); 4790 ZoneList<Expression*>* subexprs = expr->values();
4437 int length = subexprs->length(); 4791 int length = subexprs->length();
4438 HInstruction* literal; 4792 HInstruction* literal;
4439 4793
4440 Handle<AllocationSite> site; 4794 Handle<AllocationSite> site;
4441 Handle<FixedArray> literals(environment()->closure()->literals(), isolate()); 4795 Handle<FixedArray> literals(environment()->closure()->literals(), isolate());
4442 bool uninitialized = false; 4796 bool uninitialized = false;
4443 Handle<Object> literals_cell(literals->get(expr->literal_index()), 4797 Handle<Object> literals_cell(literals->get(expr->literal_index()),
4444 isolate()); 4798 isolate());
4445 Handle<JSObject> boilerplate_object; 4799 Handle<JSObject> boilerplate_object;
(...skipping 1940 matching lines...) Expand 10 before | Expand all | Expand 10 after
6386 int nodes_added = InliningAstSize(target); 6740 int nodes_added = InliningAstSize(target);
6387 if (nodes_added == kNotInlinable) return false; 6741 if (nodes_added == kNotInlinable) return false;
6388 6742
6389 Handle<JSFunction> caller = current_info()->closure(); 6743 Handle<JSFunction> caller = current_info()->closure();
6390 6744
6391 if (nodes_added > Min(FLAG_max_inlined_nodes, kUnlimitedMaxInlinedNodes)) { 6745 if (nodes_added > Min(FLAG_max_inlined_nodes, kUnlimitedMaxInlinedNodes)) {
6392 TraceInline(target, caller, "target AST is too large [early]"); 6746 TraceInline(target, caller, "target AST is too large [early]");
6393 return false; 6747 return false;
6394 } 6748 }
6395 6749
6396 #if !V8_TARGET_ARCH_IA32 && !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_MIPS
6397 // Target must be able to use caller's context.
6398 CompilationInfo* outer_info = current_info();
6399 if (target->context() != outer_info->closure()->context() ||
6400 outer_info->scope()->contains_with() ||
6401 outer_info->scope()->num_heap_slots() > 0) {
6402 TraceInline(target, caller, "target requires context change");
6403 return false;
6404 }
6405 #endif
6406
6407
6408 // Don't inline deeper than the maximum number of inlining levels. 6750 // Don't inline deeper than the maximum number of inlining levels.
6409 HEnvironment* env = environment(); 6751 HEnvironment* env = environment();
6410 int current_level = 1; 6752 int current_level = 1;
6411 while (env->outer() != NULL) { 6753 while (env->outer() != NULL) {
6412 if (current_level == FLAG_max_inlining_levels) { 6754 if (current_level == FLAG_max_inlining_levels) {
6413 TraceInline(target, caller, "inline depth limit reached"); 6755 TraceInline(target, caller, "inline depth limit reached");
6414 return false; 6756 return false;
6415 } 6757 }
6416 if (env->outer()->frame_type() == JS_FUNCTION) { 6758 if (env->outer()->frame_type() == JS_FUNCTION) {
6417 current_level++; 6759 current_level++;
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
6535 HConstant* undefined = graph()->GetConstantUndefined(); 6877 HConstant* undefined = graph()->GetConstantUndefined();
6536 bool undefined_receiver = HEnvironment::UseUndefinedReceiver( 6878 bool undefined_receiver = HEnvironment::UseUndefinedReceiver(
6537 target, function, call_kind, inlining_kind); 6879 target, function, call_kind, inlining_kind);
6538 HEnvironment* inner_env = 6880 HEnvironment* inner_env =
6539 environment()->CopyForInlining(target, 6881 environment()->CopyForInlining(target,
6540 arguments_count, 6882 arguments_count,
6541 function, 6883 function,
6542 undefined, 6884 undefined,
6543 function_state()->inlining_kind(), 6885 function_state()->inlining_kind(),
6544 undefined_receiver); 6886 undefined_receiver);
6545 #if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS 6887
6546 // IA32, ARM and MIPS only, overwrite the caller's context in the
6547 // deoptimization environment with the correct one.
6548 //
6549 // TODO(kmillikin): implement the same inlining on other platforms so we
6550 // can remove the unsightly ifdefs in this function.
6551 HConstant* context = Add<HConstant>(Handle<Context>(target->context())); 6888 HConstant* context = Add<HConstant>(Handle<Context>(target->context()));
6552 inner_env->BindContext(context); 6889 inner_env->BindContext(context);
6553 #endif
6554 6890
6555 Add<HSimulate>(return_id); 6891 Add<HSimulate>(return_id);
6556 current_block()->UpdateEnvironment(inner_env); 6892 current_block()->UpdateEnvironment(inner_env);
6557 HArgumentsObject* arguments_object = NULL; 6893 HArgumentsObject* arguments_object = NULL;
6558 6894
6559 // If the function uses arguments object create and bind one, also copy 6895 // If the function uses arguments object create and bind one, also copy
6560 // current arguments values to use them for materialization. 6896 // current arguments values to use them for materialization.
6561 if (function->scope()->arguments() != NULL) { 6897 if (function->scope()->arguments() != NULL) {
6562 ASSERT(function->scope()->arguments()->IsStackAllocated()); 6898 ASSERT(function->scope()->arguments()->IsStackAllocated());
6563 HEnvironment* arguments_env = inner_env->arguments_environment(); 6899 HEnvironment* arguments_env = inner_env->arguments_environment();
(...skipping 3292 matching lines...) Expand 10 before | Expand all | Expand 10 after
9856 if (ShouldProduceTraceOutput()) { 10192 if (ShouldProduceTraceOutput()) {
9857 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 10193 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
9858 } 10194 }
9859 10195
9860 #ifdef DEBUG 10196 #ifdef DEBUG
9861 graph_->Verify(false); // No full verify. 10197 graph_->Verify(false); // No full verify.
9862 #endif 10198 #endif
9863 } 10199 }
9864 10200
9865 } } // namespace v8::internal 10201 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698