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

Side by Side Diff: src/assembler.cc

Issue 1131783003: Embedded constant pools. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix debug-mode Arm issue. Created 5 years, 6 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
« no previous file with comments | « src/assembler.h ('k') | src/compiler/arm/code-generator-arm.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 (c) 1994-2006 Sun Microsystems Inc. 1 // Copyright (c) 1994-2006 Sun Microsystems Inc.
2 // All Rights Reserved. 2 // All Rights Reserved.
3 // 3 //
4 // Redistribution and use in source and binary forms, with or without 4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are 5 // modification, are permitted provided that the following conditions are
6 // met: 6 // met:
7 // 7 //
8 // - Redistributions of source code must retain the above copyright notice, 8 // - Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer. 9 // this list of conditions and the following disclaimer.
10 // 10 //
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 // Implementation of AssemblerBase 128 // Implementation of AssemblerBase
129 129
130 AssemblerBase::AssemblerBase(Isolate* isolate, void* buffer, int buffer_size) 130 AssemblerBase::AssemblerBase(Isolate* isolate, void* buffer, int buffer_size)
131 : isolate_(isolate), 131 : isolate_(isolate),
132 jit_cookie_(0), 132 jit_cookie_(0),
133 enabled_cpu_features_(0), 133 enabled_cpu_features_(0),
134 emit_debug_code_(FLAG_debug_code), 134 emit_debug_code_(FLAG_debug_code),
135 predictable_code_size_(false), 135 predictable_code_size_(false),
136 // We may use the assembler without an isolate. 136 // We may use the assembler without an isolate.
137 serializer_enabled_(isolate && isolate->serializer_enabled()), 137 serializer_enabled_(isolate && isolate->serializer_enabled()),
138 ool_constant_pool_available_(false) { 138 constant_pool_available_(false) {
139 if (FLAG_mask_constants_with_cookie && isolate != NULL) { 139 if (FLAG_mask_constants_with_cookie && isolate != NULL) {
140 jit_cookie_ = isolate->random_number_generator()->NextInt(); 140 jit_cookie_ = isolate->random_number_generator()->NextInt();
141 } 141 }
142 own_buffer_ = buffer == NULL; 142 own_buffer_ = buffer == NULL;
143 if (buffer_size == 0) buffer_size = kMinimalBufferSize; 143 if (buffer_size == 0) buffer_size = kMinimalBufferSize;
144 DCHECK(buffer_size > 0); 144 DCHECK(buffer_size > 0);
145 if (own_buffer_) buffer = NewArray<byte>(buffer_size); 145 if (own_buffer_) buffer = NewArray<byte>(buffer_size);
146 buffer_ = static_cast<byte*>(buffer); 146 buffer_ = static_cast<byte*>(buffer);
147 buffer_size_ = buffer_size; 147 buffer_size_ = buffer_size;
148 148
(...skipping 1479 matching lines...) Expand 10 before | Expand all | Expand 10 after
1628 assembler_->RecordRelocInfo(RelocInfo::POSITION, state_.current_position); 1628 assembler_->RecordRelocInfo(RelocInfo::POSITION, state_.current_position);
1629 written = true; 1629 written = true;
1630 } 1630 }
1631 state_.written_position = state_.current_position; 1631 state_.written_position = state_.current_position;
1632 1632
1633 // Return whether something was written. 1633 // Return whether something was written.
1634 return written; 1634 return written;
1635 } 1635 }
1636 1636
1637 1637
1638 ConstantPoolBuilder::ConstantPoolBuilder(int ptr_reach_bits,
1639 int double_reach_bits) {
1640 info_[ConstantPoolEntry::INTPTR].entries.reserve(64);
1641 info_[ConstantPoolEntry::INTPTR].regular_reach_bits = ptr_reach_bits;
1642 info_[ConstantPoolEntry::DOUBLE].regular_reach_bits = double_reach_bits;
1643 }
1644
1645
1646 ConstantPoolEntry::Access ConstantPoolBuilder::NextAccess(
1647 ConstantPoolEntry::Type type) const {
1648 const PerTypeEntryInfo& info = info_[type];
1649
1650 if (info.overflow()) return ConstantPoolEntry::OVERFLOWED;
1651
1652 int dbl_count = info_[ConstantPoolEntry::DOUBLE].regular_count;
1653 int dbl_offset = dbl_count * kDoubleSize;
1654 int ptr_count = info_[ConstantPoolEntry::INTPTR].regular_count;
1655 int ptr_offset = ptr_count * kPointerSize + dbl_offset;
1656
1657 if (type == ConstantPoolEntry::DOUBLE) {
1658 // Double overflow detection must take into account the reach for both types
1659 int ptr_reach_bits = info_[ConstantPoolEntry::INTPTR].regular_reach_bits;
1660 if (!is_uintn(dbl_offset, info.regular_reach_bits) ||
1661 (ptr_count > 0 &&
1662 !is_uintn(ptr_offset + kDoubleSize - kPointerSize, ptr_reach_bits))) {
1663 return ConstantPoolEntry::OVERFLOWED;
1664 }
1665 } else {
1666 DCHECK(type == ConstantPoolEntry::INTPTR);
1667 if (!is_uintn(ptr_offset, info.regular_reach_bits)) {
1668 return ConstantPoolEntry::OVERFLOWED;
1669 }
1670 }
1671
1672 return ConstantPoolEntry::REGULAR;
1673 }
1674
1675
1676 ConstantPoolEntry::Access ConstantPoolBuilder::AddEntry(
1677 ConstantPoolEntry& entry, ConstantPoolEntry::Type type) {
1678 DCHECK(!emitted_label_.is_bound());
1679 PerTypeEntryInfo& info = info_[type];
1680 const int entry_size = ConstantPoolEntry::size(type);
1681 bool merged = false;
1682
1683 if (entry.sharing_ok()) {
1684 // Try to merge entries
1685 std::vector<ConstantPoolEntry>::iterator it = info.shared_entries.begin();
1686 int end = static_cast<int>(info.shared_entries.size());
1687 for (int i = 0; i < end; i++, it++) {
1688 if ((entry_size == kPointerSize) ? entry.value() == it->value()
1689 : entry.value64() == it->value64()) {
1690 // Merge with found entry.
1691 entry.set_merged_index(i);
1692 merged = true;
1693 break;
1694 }
1695 }
1696 }
1697
1698 // By definition, merged entries have regular access.
1699 DCHECK(!merged || entry.merged_index() < info.regular_count);
1700 ConstantPoolEntry::Access access =
1701 (merged ? ConstantPoolEntry::REGULAR : NextAccess(type));
1702
1703 // Enforce an upper bound on search time by limiting the search to
1704 // unique sharable entries which fit in the regular section.
1705 if (entry.sharing_ok() && !merged && access == ConstantPoolEntry::REGULAR) {
1706 info.shared_entries.push_back(entry);
1707 } else {
1708 info.entries.push_back(entry);
1709 }
1710
1711 // We're done if we found a match or have already triggered the
1712 // overflow state.
1713 if (merged || info.overflow()) return access;
1714
1715 if (access == ConstantPoolEntry::REGULAR) {
1716 info.regular_count++;
1717 } else {
1718 info.overflow_start = static_cast<int>(info.entries.size()) - 1;
1719 }
1720
1721 return access;
1722 }
1723
1724
1725 void ConstantPoolBuilder::EmitSharedEntries(Assembler* assm,
1726 ConstantPoolEntry::Type type) {
1727 PerTypeEntryInfo& info = info_[type];
1728 std::vector<ConstantPoolEntry>& shared_entries = info.shared_entries;
1729 const int entry_size = ConstantPoolEntry::size(type);
1730 int base = emitted_label_.pos();
1731 DCHECK(base > 0);
1732 int shared_end = static_cast<int>(shared_entries.size());
1733 std::vector<ConstantPoolEntry>::iterator shared_it = shared_entries.begin();
1734 for (int i = 0; i < shared_end; i++, shared_it++) {
1735 int offset = assm->pc_offset() - base;
1736 shared_it->set_offset(offset); // Save offset for merged entries.
1737 if (entry_size == kPointerSize) {
1738 assm->dp(shared_it->value());
1739 } else {
1740 assm->dq(shared_it->value64());
1741 }
1742 DCHECK(is_uintn(offset, info.regular_reach_bits));
1743
1744 // Patch load sequence with correct offset.
1745 assm->PatchConstantPoolAccessInstruction(shared_it->position(), offset,
1746 ConstantPoolEntry::REGULAR, type);
1747 }
1748 }
1749
1750
1751 void ConstantPoolBuilder::EmitGroup(Assembler* assm,
1752 ConstantPoolEntry::Access access,
1753 ConstantPoolEntry::Type type) {
1754 PerTypeEntryInfo& info = info_[type];
1755 const bool overflow = info.overflow();
1756 std::vector<ConstantPoolEntry>& entries = info.entries;
1757 std::vector<ConstantPoolEntry>& shared_entries = info.shared_entries;
1758 const int entry_size = ConstantPoolEntry::size(type);
1759 int base = emitted_label_.pos();
1760 DCHECK(base > 0);
1761 int begin;
1762 int end;
1763
1764 if (access == ConstantPoolEntry::REGULAR) {
1765 // Emit any shared entries first
1766 EmitSharedEntries(assm, type);
1767 }
1768
1769 if (access == ConstantPoolEntry::REGULAR) {
1770 begin = 0;
1771 end = overflow ? info.overflow_start : static_cast<int>(entries.size());
1772 } else {
1773 DCHECK(access == ConstantPoolEntry::OVERFLOWED);
1774 if (!overflow) return;
1775 begin = info.overflow_start;
1776 end = static_cast<int>(entries.size());
1777 }
1778
1779 std::vector<ConstantPoolEntry>::iterator it = entries.begin();
1780 if (begin > 0) std::advance(it, begin);
1781 for (int i = begin; i < end; i++, it++) {
1782 // Update constant pool if necessary and get the entry's offset.
1783 int offset;
1784 ConstantPoolEntry::Access entry_access;
1785 if (!it->is_merged()) {
1786 // Emit new entry
1787 offset = assm->pc_offset() - base;
1788 entry_access = access;
1789 if (entry_size == kPointerSize) {
1790 assm->dp(it->value());
1791 } else {
1792 assm->dq(it->value64());
1793 }
1794 } else {
1795 // Retrieve offset from shared entry.
1796 offset = shared_entries[it->merged_index()].offset();
1797 entry_access = ConstantPoolEntry::REGULAR;
1798 }
1799
1800 DCHECK(entry_access == ConstantPoolEntry::OVERFLOWED ||
1801 is_uintn(offset, info.regular_reach_bits));
1802
1803 // Patch load sequence with correct offset.
1804 assm->PatchConstantPoolAccessInstruction(it->position(), offset,
1805 entry_access, type);
1806 }
1807 }
1808
1809
1810 // Emit and return position of pool. Zero implies no constant pool.
1811 int ConstantPoolBuilder::Emit(Assembler* assm) {
1812 bool emitted = emitted_label_.is_bound();
1813 bool empty = IsEmpty();
1814
1815 if (!emitted) {
1816 // Mark start of constant pool. Align if necessary.
1817 if (!empty) assm->Align(kDoubleSize);
1818 assm->bind(&emitted_label_);
1819 if (!empty) {
1820 // Emit in groups based on access and type.
1821 // Emit doubles first for alignment purposes.
1822 EmitGroup(assm, ConstantPoolEntry::REGULAR, ConstantPoolEntry::DOUBLE);
1823 EmitGroup(assm, ConstantPoolEntry::REGULAR, ConstantPoolEntry::INTPTR);
1824 if (info_[ConstantPoolEntry::DOUBLE].overflow()) {
1825 assm->Align(kDoubleSize);
1826 EmitGroup(assm, ConstantPoolEntry::OVERFLOWED,
1827 ConstantPoolEntry::DOUBLE);
1828 }
1829 if (info_[ConstantPoolEntry::INTPTR].overflow()) {
1830 EmitGroup(assm, ConstantPoolEntry::OVERFLOWED,
1831 ConstantPoolEntry::INTPTR);
1832 }
1833 }
1834 }
1835
1836 return !empty ? emitted_label_.pos() : 0;
1837 }
1838
1839
1638 // Platform specific but identical code for all the platforms. 1840 // Platform specific but identical code for all the platforms.
1639 1841
1640 1842
1641 void Assembler::RecordDeoptReason(const int reason, 1843 void Assembler::RecordDeoptReason(const int reason,
1642 const SourcePosition position) { 1844 const SourcePosition position) {
1643 if (FLAG_trace_deopt || isolate()->cpu_profiler()->is_profiling()) { 1845 if (FLAG_trace_deopt || isolate()->cpu_profiler()->is_profiling()) {
1644 EnsureSpace ensure_space(this); 1846 EnsureSpace ensure_space(this);
1645 int raw_position = position.IsUnknown() ? 0 : position.raw(); 1847 int raw_position = position.IsUnknown() ? 0 : position.raw();
1646 RecordRelocInfo(RelocInfo::POSITION, raw_position); 1848 RecordRelocInfo(RelocInfo::POSITION, raw_position);
1647 RecordRelocInfo(RelocInfo::DEOPT_REASON, reason); 1849 RecordRelocInfo(RelocInfo::DEOPT_REASON, reason);
(...skipping 16 matching lines...) Expand all
1664 } 1866 }
1665 1867
1666 1868
1667 void Assembler::RecordDebugBreakSlot() { 1869 void Assembler::RecordDebugBreakSlot() {
1668 positions_recorder()->WriteRecordedPositions(); 1870 positions_recorder()->WriteRecordedPositions();
1669 EnsureSpace ensure_space(this); 1871 EnsureSpace ensure_space(this);
1670 RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT); 1872 RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT);
1671 } 1873 }
1672 } // namespace internal 1874 } // namespace internal
1673 } // namespace v8 1875 } // namespace v8
OLDNEW
« no previous file with comments | « src/assembler.h ('k') | src/compiler/arm/code-generator-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698