Changeset 65042 in webkit for trunk/JavaScriptCore/assembler
- Timestamp:
- Aug 9, 2010, 8:19:19 PM (15 years ago)
- Location:
- trunk/JavaScriptCore/assembler
- Files:
-
- 1 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/assembler/ARMv7Assembler.h
r64608 r65042 382 382 u.d = d; 383 383 384 int sign = (u.i >> 63);385 int exponent = (u.i >> 52) & 0x7ff;384 int sign = static_cast<int>(u.i >> 63); 385 int exponent = static_cast<int>(u.i >> 52) & 0x7ff; 386 386 uint64_t mantissa = u.i & 0x000fffffffffffffull; 387 387 … … 445 445 } m_u; 446 446 }; 447 448 447 449 448 class ARMv7Assembler { … … 477 476 ConditionLE, 478 477 ConditionAL, 479 478 480 479 ConditionCS = ConditionHS, 481 480 ConditionCC = ConditionLO, 482 481 } Condition; 483 482 483 enum JumpType { JumpNoCondition, JumpCondition, JumpFullSize }; 484 enum JumpLinkType { LinkInvalid, LinkShortJump, LinkConditionalShortJump, LinkLongJump, JumpTypeCount }; 485 static const int JumpSizes[JumpTypeCount]; 486 enum { JumpPaddingSize = 5 * sizeof(uint16_t) }; 487 class LinkRecord { 488 public: 489 LinkRecord(intptr_t from, intptr_t to, JumpType type, Condition condition) 490 : m_from(from) 491 , m_to(to) 492 , m_type(type) 493 , m_linkType(LinkInvalid) 494 , m_condition(condition) 495 { 496 } 497 intptr_t from() const { return m_from; } 498 void setFrom(intptr_t from) { m_from = from; } 499 intptr_t to() const { return m_to; } 500 JumpType type() const { return m_type; } 501 JumpLinkType linkType() const { return m_linkType; } 502 void setLinkType(JumpLinkType linkType) { ASSERT(m_linkType == LinkInvalid); m_linkType = linkType; } 503 Condition condition() const { return m_condition; } 504 private: 505 intptr_t m_from : 31; 506 intptr_t m_to : 31; 507 JumpType m_type : 2; 508 JumpLinkType m_linkType : 3; 509 Condition m_condition : 16; 510 }; 511 484 512 class JmpSrc { 485 513 friend class ARMv7Assembler; 486 514 friend class ARMInstructionFormatter; 515 friend class LinkBuffer; 487 516 public: 488 517 JmpSrc() … … 492 521 493 522 private: 494 JmpSrc(int offset )523 JmpSrc(int offset, JumpType type) 495 524 : m_offset(offset) 496 { 525 , m_condition(0xffff) 526 , m_type(type) 527 { 528 ASSERT(m_type != JumpCondition); 529 } 530 531 JmpSrc(int offset, JumpType type, Condition condition) 532 : m_offset(offset) 533 , m_condition(condition) 534 , m_type(type) 535 { 536 ASSERT(m_type == JumpCondition || m_type == JumpFullSize); 497 537 } 498 538 499 539 int m_offset; 540 Condition m_condition : 16; 541 JumpType m_type : 16; 542 500 543 }; 501 544 … … 503 546 friend class ARMv7Assembler; 504 547 friend class ARMInstructionFormatter; 548 friend class LinkBuffer; 505 549 public: 506 550 JmpDst() … … 525 569 526 570 private: 527 528 struct LinkRecord {529 LinkRecord(intptr_t from, intptr_t to)530 : from(from)531 , to(to)532 {533 }534 535 intptr_t from;536 intptr_t to;537 };538 571 539 572 // ARMv7, Appx-A.6.3 … … 740 773 741 774 public: 742 775 743 776 void add(RegisterID rd, RegisterID rn, ARMThumbImmediate imm) 744 777 { … … 879 912 m_formatter.twoWordOp12Reg4FourFours(OP_ASR_reg_T2, rn, FourFours(0xf, rd, 0, rm)); 880 913 } 881 914 882 915 // Only allowed in IT (if then) block if last instruction. 883 JmpSrc b( )916 JmpSrc b(JumpType type) 884 917 { 885 918 m_formatter.twoWordOp16Op16(OP_B_T4a, OP_B_T4b); 886 return JmpSrc(m_formatter.size() );919 return JmpSrc(m_formatter.size(), type); 887 920 } 888 921 889 922 // Only allowed in IT (if then) block if last instruction. 890 JmpSrc blx(RegisterID rm )923 JmpSrc blx(RegisterID rm, JumpType type) 891 924 { 892 925 ASSERT(rm != ARMRegisters::pc); 893 926 m_formatter.oneWordOp8RegReg143(OP_BLX, rm, (RegisterID)8); 894 return JmpSrc(m_formatter.size() );927 return JmpSrc(m_formatter.size(), type); 895 928 } 896 929 897 930 // Only allowed in IT (if then) block if last instruction. 898 JmpSrc bx(RegisterID rm )931 JmpSrc bx(RegisterID rm, JumpType type, Condition condition) 899 932 { 900 933 m_formatter.oneWordOp8RegReg143(OP_BX, rm, (RegisterID)0); 901 return JmpSrc(m_formatter.size()); 934 return JmpSrc(m_formatter.size(), type, condition); 935 } 936 937 JmpSrc bx(RegisterID rm, JumpType type) 938 { 939 m_formatter.oneWordOp8RegReg143(OP_BX, rm, (RegisterID)0); 940 return JmpSrc(m_formatter.size(), type); 902 941 } 903 942 … … 1618 1657 return dst.m_offset - src.m_offset; 1619 1658 } 1659 1660 int executableOffsetFor(int location) 1661 { 1662 if (!location) 1663 return 0; 1664 return static_cast<int32_t*>(m_formatter.data())[location / sizeof(int32_t) - 1]; 1665 } 1666 1667 int jumpSizeDelta(JumpLinkType jumpLinkType) { return JumpPaddingSize - JumpSizes[jumpLinkType]; } 1620 1668 1621 1669 // Assembler admin methods: … … 1626 1674 } 1627 1675 1628 void* executableCopy(ExecutablePool* allocator) 1629 { 1630 void* copy = m_formatter.executableCopy(allocator); 1631 if (!copy) 1632 return 0; 1633 1634 unsigned jumpCount = m_jumpsToLink.size(); 1635 for (unsigned i = 0; i < jumpCount; ++i) { 1636 uint16_t* location = reinterpret_cast<uint16_t*>(reinterpret_cast<intptr_t>(copy) + m_jumpsToLink[i].from); 1637 uint16_t* target = reinterpret_cast<uint16_t*>(reinterpret_cast<intptr_t>(copy) + m_jumpsToLink[i].to); 1638 linkJumpAbsolute(location, target); 1639 } 1640 m_jumpsToLink.clear(); 1641 1642 return copy; 1643 } 1644 1676 static bool linkRecordSourceComparator(const LinkRecord& a, const LinkRecord& b) 1677 { 1678 return a.from() < b.from(); 1679 } 1680 1681 JumpLinkType computeJumpType(LinkRecord& record, const uint8_t* from, const uint8_t* to) 1682 { 1683 if (record.type() >= JumpFullSize) { 1684 record.setLinkType(LinkLongJump); 1685 return LinkLongJump; 1686 } 1687 bool mayTriggerErrata = false; 1688 const uint16_t* shortJumpLocation = reinterpret_cast<const uint16_t*>(from - (JumpPaddingSize - JumpSizes[LinkShortJump])); 1689 if (!canBeShortJump(shortJumpLocation, to, mayTriggerErrata)) { 1690 record.setLinkType(LinkLongJump); 1691 return LinkLongJump; 1692 } 1693 if (mayTriggerErrata) { 1694 record.setLinkType(LinkLongJump); 1695 return LinkLongJump; 1696 } 1697 if (record.type() == JumpCondition) { 1698 record.setLinkType(LinkConditionalShortJump); 1699 return LinkConditionalShortJump; 1700 } 1701 record.setLinkType(LinkShortJump); 1702 return LinkShortJump; 1703 } 1704 1705 void recordLinkOffsets(int32_t regionStart, int32_t regionEnd, int32_t offset) 1706 { 1707 int32_t ptr = regionStart / sizeof(int32_t); 1708 const int32_t end = regionEnd / sizeof(int32_t); 1709 int32_t* offsets = static_cast<int32_t*>(m_formatter.data()); 1710 while (ptr < end) 1711 offsets[ptr++] = offset; 1712 } 1713 1714 Vector<LinkRecord>& jumpsToLink() 1715 { 1716 std::sort(m_jumpsToLink.begin(), m_jumpsToLink.end(), linkRecordSourceComparator); 1717 return m_jumpsToLink; 1718 } 1719 1720 void link(LinkRecord& record, uint8_t* from, uint8_t* to) 1721 { 1722 uint16_t* itttLocation; 1723 if (record.linkType() == LinkConditionalShortJump) { 1724 itttLocation = reinterpret_cast<uint16_t*>(from - JumpSizes[LinkConditionalShortJump] - 2); 1725 itttLocation[0] = ifThenElse(record.condition()) | OP_IT; 1726 } 1727 ASSERT(record.linkType() != LinkInvalid); 1728 if (record.linkType() != LinkLongJump) 1729 linkShortJump(reinterpret_cast<uint16_t*>(from), to); 1730 else 1731 linkLongJump(reinterpret_cast<uint16_t*>(from), to); 1732 } 1733 1734 void* unlinkedCode() { return m_formatter.data(); } 1735 1645 1736 static unsigned getCallReturnOffset(JmpSrc call) 1646 1737 { … … 1661 1752 ASSERT(to.m_offset != -1); 1662 1753 ASSERT(from.m_offset != -1); 1663 m_jumpsToLink.append(LinkRecord(from.m_offset, to.m_offset ));1754 m_jumpsToLink.append(LinkRecord(from.m_offset, to.m_offset, from.m_type, from.m_condition)); 1664 1755 } 1665 1756 … … 1864 1955 } 1865 1956 1866 static void linkJumpAbsolute(uint16_t* instruction, void* target) 1867 { 1868 // FIMXE: this should be up in the MacroAssembler layer. :-( 1869 const uint16_t JUMP_TEMPORARY_REGISTER = ARMRegisters::ip; 1870 1957 static bool canBeShortJump(const uint16_t* instruction, const void* target, bool& mayTriggerErrata) 1958 { 1871 1959 ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1)); 1872 1960 ASSERT(!(reinterpret_cast<intptr_t>(target) & 1)); 1873 1874 ASSERT( (isMOV_imm_T3(instruction - 5) && isMOVT(instruction - 3) && isBX(instruction - 1)) 1875 || (isNOP_T1(instruction - 5) && isNOP_T2(instruction - 4) && isB(instruction - 2)) ); 1876 1961 1877 1962 intptr_t relative = reinterpret_cast<intptr_t>(target) - (reinterpret_cast<intptr_t>(instruction)); 1878 1879 1963 // From Cortex-A8 errata: 1880 1964 // If the 32-bit Thumb-2 branch instruction spans two 4KiB regions and … … 1885 1969 // The instruction is spanning two pages if it ends at an address ending 0x002 1886 1970 bool spansTwo4K = ((reinterpret_cast<intptr_t>(instruction) & 0xfff) == 0x002); 1971 mayTriggerErrata = spansTwo4K; 1887 1972 // The target is in the first page if the jump branch back by [3..0x1002] bytes 1888 1973 bool targetInFirstPage = (relative >= -0x1002) && (relative < -2); 1889 1974 bool wouldTriggerA8Errata = spansTwo4K && targetInFirstPage; 1890 1891 if (((relative << 7) >> 7) == relative && !wouldTriggerA8Errata) { 1975 return ((relative << 7) >> 7) == relative && !wouldTriggerA8Errata; 1976 } 1977 1978 static void linkLongJump(uint16_t* instruction, void* target) 1979 { 1980 linkJumpAbsolute(instruction, target); 1981 } 1982 1983 static void linkShortJump(uint16_t* instruction, void* target) 1984 { 1985 // FIMXE: this should be up in the MacroAssembler layer. :-( 1986 ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1)); 1987 ASSERT(!(reinterpret_cast<intptr_t>(target) & 1)); 1988 1989 intptr_t relative = reinterpret_cast<intptr_t>(target) - (reinterpret_cast<intptr_t>(instruction)); 1990 bool scratch; 1991 UNUSED_PARAM(scratch); 1992 ASSERT(canBeShortJump(instruction, target, scratch)); 1993 // ARM encoding for the top two bits below the sign bit is 'peculiar'. 1994 if (relative >= 0) 1995 relative ^= 0xC00000; 1996 1997 // All branch offsets should be an even distance. 1998 ASSERT(!(relative & 1)); 1999 instruction[-2] = OP_B_T4a | ((relative & 0x1000000) >> 14) | ((relative & 0x3ff000) >> 12); 2000 instruction[-1] = OP_B_T4b | ((relative & 0x800000) >> 10) | ((relative & 0x400000) >> 11) | ((relative & 0xffe) >> 1); 2001 } 2002 2003 static void linkJumpAbsolute(uint16_t* instruction, void* target) 2004 { 2005 // FIMXE: this should be up in the MacroAssembler layer. :-( 2006 ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1)); 2007 ASSERT(!(reinterpret_cast<intptr_t>(target) & 1)); 2008 2009 ASSERT((isMOV_imm_T3(instruction - 5) && isMOVT(instruction - 3) && isBX(instruction - 1)) 2010 || (isNOP_T1(instruction - 5) && isNOP_T2(instruction - 4) && isB(instruction - 2))); 2011 2012 intptr_t relative = reinterpret_cast<intptr_t>(target) - (reinterpret_cast<intptr_t>(instruction)); 2013 bool scratch; 2014 if (canBeShortJump(instruction, target, scratch)) { 1892 2015 // ARM encoding for the top two bits below the sign bit is 'peculiar'. 1893 2016 if (relative >= 0) … … 1907 2030 instruction[-1] = OP_B_T4b | ((relative & 0x800000) >> 10) | ((relative & 0x400000) >> 11) | ((relative & 0xffe) >> 1); 1908 2031 } else { 2032 const uint16_t JUMP_TEMPORARY_REGISTER = ARMRegisters::ip; 1909 2033 ARMThumbImmediate lo16 = ARMThumbImmediate::makeUInt16(static_cast<uint16_t>(reinterpret_cast<uint32_t>(target) + 1)); 1910 2034 ARMThumbImmediate hi16 = ARMThumbImmediate::makeUInt16(static_cast<uint16_t>(reinterpret_cast<uint32_t>(target) >> 16)); … … 1921 2045 return op | (imm.m_value.i << 10) | imm.m_value.imm4; 1922 2046 } 2047 1923 2048 static uint16_t twoWordOp5i6Imm4Reg4EncodedImmSecond(uint16_t rd, ARMThumbImmediate imm) 1924 2049 { … … 2037 2162 2038 2163 Vector<LinkRecord> m_jumpsToLink; 2164 Vector<int32_t> m_offsets; 2039 2165 }; 2040 2166 -
trunk/JavaScriptCore/assembler/AbstractMacroAssembler.h
r64943 r65042 419 419 420 420 // Section 3: Misc admin methods 421 422 static CodePtr trampolineAt(CodeRef ref, Label label)423 {424 return CodePtr(AssemblerType::getRelocatedAddress(ref.m_code.dataLocation(), label.m_label));425 }426 427 421 size_t size() 428 422 { … … 480 474 return AssemblerType::getDifferenceBetweenLabels(from.m_label, to.m_jmp); 481 475 } 476 477 void beginUninterruptedSequence() { } 478 void endUninterruptedSequence() { } 482 479 483 480 protected: -
trunk/JavaScriptCore/assembler/LinkBuffer.h
r64608 r65042 50 50 class LinkBuffer : public Noncopyable { 51 51 typedef MacroAssemblerCodeRef CodeRef; 52 typedef MacroAssemblerCodePtr CodePtr; 52 53 typedef MacroAssembler::Label Label; 53 54 typedef MacroAssembler::Jump Jump; … … 56 57 typedef MacroAssembler::DataLabel32 DataLabel32; 57 58 typedef MacroAssembler::DataLabelPtr DataLabelPtr; 59 typedef MacroAssembler::JmpDst JmpDst; 60 #if ENABLE(BRANCH_COMPACTION) 61 typedef MacroAssembler::LinkRecord LinkRecord; 62 typedef MacroAssembler::JumpLinkType JumpLinkType; 63 #endif 58 64 59 65 enum LinkBufferState { … … 67 73 // First, executablePool is copied into m_executablePool, then the initialization of 68 74 // m_code uses m_executablePool, *not* executablePool, since this is no longer valid. 69 LinkBuffer(MacroAssembler* masm, PassRefPtr<ExecutablePool> executablePool) 75 // The linkOffset parameter should only be non-null when recompiling for exception info 76 LinkBuffer(MacroAssembler* masm, PassRefPtr<ExecutablePool> executablePool, void* linkOffset) 70 77 : m_executablePool(executablePool) 71 , m_code(masm->m_assembler.executableCopy(m_executablePool.get())) 72 , m_size(masm->m_assembler.size()) 78 , m_size(0) 79 , m_code(0) 80 , m_assembler(masm) 73 81 #ifndef NDEBUG 74 82 , m_state(StateInit) 75 83 #endif 76 84 { 85 linkCode(linkOffset); 77 86 } 78 87 … … 98 107 { 99 108 ASSERT(call.isFlagSet(Call::Linkable)); 109 call.m_jmp = applyOffset(call.m_jmp); 100 110 MacroAssembler::linkCall(code(), call, function); 101 111 } … … 103 113 void link(Jump jump, CodeLocationLabel label) 104 114 { 115 jump.m_jmp = applyOffset(jump.m_jmp); 105 116 MacroAssembler::linkJump(code(), jump, label); 106 117 } … … 109 120 { 110 121 for (unsigned i = 0; i < list.m_jumps.size(); ++i) 111 MacroAssembler::linkJump(code(),list.m_jumps[i], label);122 link(list.m_jumps[i], label); 112 123 } 113 124 114 125 void patch(DataLabelPtr label, void* value) 115 126 { 116 MacroAssembler::linkPointer(code(), label.m_label, value); 127 JmpDst target = applyOffset(label.m_label); 128 MacroAssembler::linkPointer(code(), target, value); 117 129 } 118 130 119 131 void patch(DataLabelPtr label, CodeLocationLabel value) 120 132 { 121 MacroAssembler::linkPointer(code(), label.m_label, value.executableAddress()); 133 JmpDst target = applyOffset(label.m_label); 134 MacroAssembler::linkPointer(code(), target, value.executableAddress()); 122 135 } 123 136 … … 128 141 ASSERT(call.isFlagSet(Call::Linkable)); 129 142 ASSERT(!call.isFlagSet(Call::Near)); 130 return CodeLocationCall(MacroAssembler::getLinkerAddress(code(), call.m_jmp));143 return CodeLocationCall(MacroAssembler::getLinkerAddress(code(), applyOffset(call.m_jmp))); 131 144 } 132 145 … … 135 148 ASSERT(call.isFlagSet(Call::Linkable)); 136 149 ASSERT(call.isFlagSet(Call::Near)); 137 return CodeLocationNearCall(MacroAssembler::getLinkerAddress(code(), call.m_jmp));150 return CodeLocationNearCall(MacroAssembler::getLinkerAddress(code(), applyOffset(call.m_jmp))); 138 151 } 139 152 140 153 CodeLocationLabel locationOf(Label label) 141 154 { 142 return CodeLocationLabel(MacroAssembler::getLinkerAddress(code(), label.m_label));155 return CodeLocationLabel(MacroAssembler::getLinkerAddress(code(), applyOffset(label.m_label))); 143 156 } 144 157 145 158 CodeLocationDataLabelPtr locationOf(DataLabelPtr label) 146 159 { 147 return CodeLocationDataLabelPtr(MacroAssembler::getLinkerAddress(code(), label.m_label));160 return CodeLocationDataLabelPtr(MacroAssembler::getLinkerAddress(code(), applyOffset(label.m_label))); 148 161 } 149 162 150 163 CodeLocationDataLabel32 locationOf(DataLabel32 label) 151 164 { 152 return CodeLocationDataLabel32(MacroAssembler::getLinkerAddress(code(), label.m_label));165 return CodeLocationDataLabel32(MacroAssembler::getLinkerAddress(code(), applyOffset(label.m_label))); 153 166 } 154 167 … … 157 170 unsigned returnAddressOffset(Call call) 158 171 { 172 call.m_jmp = applyOffset(call.m_jmp); 159 173 return MacroAssembler::getLinkerCallReturnOffset(call); 160 174 } … … 170 184 return CodeRef(m_code, m_executablePool, m_size); 171 185 } 186 172 187 CodeLocationLabel finalizeCodeAddendum() 173 188 { … … 177 192 } 178 193 194 CodePtr trampolineAt(Label label) 195 { 196 return CodePtr(MacroAssembler::AssemblerType_T::getRelocatedAddress(code(), applyOffset(label.m_label))); 197 } 198 179 199 private: 200 template <typename T> T applyOffset(T src) 201 { 202 #if ENABLE(BRANCH_COMPACTION) 203 src.m_offset -= m_assembler->executableOffsetFor(src.m_offset); 204 #endif 205 return src; 206 } 207 180 208 // Keep this private! - the underlying code should only be obtained externally via 181 209 // finalizeCode() or finalizeCodeAddendum(). … … 185 213 } 186 214 215 void linkCode(void* linkOffset) 216 { 217 UNUSED_PARAM(linkOffset); 218 ASSERT(!m_code); 219 #if !ENABLE(BRANCH_COMPACTION) 220 m_code = m_assembler->m_assembler.executableCopy(m_executablePool.get()); 221 m_size = m_assembler->size(); 222 #else 223 size_t initialSize = m_assembler->size(); 224 m_code = (uint8_t*)m_executablePool->alloc(initialSize); 225 if (!m_code) 226 return; 227 ExecutableAllocator::makeWritable(m_code, m_assembler->size()); 228 uint8_t* inData = (uint8_t*)m_assembler->unlinkedCode(); 229 uint8_t* outData = reinterpret_cast<uint8_t*>(m_code); 230 const uint8_t* linkBase = linkOffset ? reinterpret_cast<uint8_t*>(linkOffset) : outData; 231 int readPtr = 0; 232 int writePtr = 0; 233 Vector<LinkRecord>& jumpsToLink = m_assembler->jumpsToLink(); 234 unsigned jumpCount = jumpsToLink.size(); 235 for (unsigned i = 0; i < jumpCount; ++i) { 236 int offset = readPtr - writePtr; 237 ASSERT(!(offset & 1)); 238 239 // Copy the instructions from the last jump to the current one. 240 size_t regionSize = jumpsToLink[i].from() - readPtr; 241 memcpy(outData + writePtr, inData + readPtr, regionSize); 242 m_assembler->recordLinkOffsets(readPtr, jumpsToLink[i].from(), offset); 243 readPtr += regionSize; 244 writePtr += regionSize; 245 246 // Calculate absolute address of the jump target, in the case of backwards 247 // branches we need to be precise, forward branches we are pessimistic 248 const uint8_t* target; 249 if (jumpsToLink[i].to() >= jumpsToLink[i].from()) 250 target = linkBase + jumpsToLink[i].to() - offset; // Compensate for what we have collapsed so far 251 else 252 target = linkBase + jumpsToLink[i].to() - m_assembler->executableOffsetFor(jumpsToLink[i].to()); 253 254 JumpLinkType jumpLinkType = m_assembler->computeJumpType(jumpsToLink[i], linkBase + writePtr, target); 255 256 // Step back in the write stream 257 int32_t delta = m_assembler->jumpSizeDelta(jumpLinkType); 258 if (delta) { 259 writePtr -= delta; 260 m_assembler->recordLinkOffsets(jumpsToLink[i].from() - delta, readPtr, readPtr - writePtr); 261 } 262 jumpsToLink[i].setFrom(writePtr); 263 } 264 // Copy everything after the last jump 265 memcpy(outData + writePtr, inData + readPtr, m_assembler->size() - readPtr); 266 m_assembler->recordLinkOffsets(readPtr, m_assembler->size(), readPtr - writePtr); 267 268 // Actually link everything (don't link if we've be given a linkoffset as it's a 269 // waste of time: linkOffset is used for recompiling to get exception info) 270 if (!linkOffset) { 271 for (unsigned i = 0; i < jumpCount; ++i) { 272 uint8_t* location = outData + jumpsToLink[i].from(); 273 uint8_t* target = outData + jumpsToLink[i].to() - m_assembler->executableOffsetFor(jumpsToLink[i].to()); 274 m_assembler->link(jumpsToLink[i], location, target); 275 } 276 } 277 278 jumpsToLink.clear(); 279 m_size = writePtr + m_assembler->size() - readPtr; 280 m_executablePool->returnLastBytes(initialSize - m_size); 281 #endif 282 } 283 187 284 void performFinalization() 188 285 { … … 197 294 198 295 RefPtr<ExecutablePool> m_executablePool; 296 size_t m_size; 199 297 void* m_code; 200 size_t m_size;298 MacroAssembler* m_assembler; 201 299 #ifndef NDEBUG 202 300 LinkBufferState m_state; -
trunk/JavaScriptCore/assembler/MacroAssemblerARMv7.h
r62419 r65042 46 46 47 47 public: 48 typedef ARMv7Assembler::LinkRecord LinkRecord; 49 typedef ARMv7Assembler::JumpLinkType JumpLinkType; 50 51 MacroAssemblerARMv7() 52 : m_inUninterruptedSequence(false) 53 { 54 } 55 56 void beginUninterruptedSequence() { m_inUninterruptedSequence = true; } 57 void endUninterruptedSequence() { m_inUninterruptedSequence = false; } 58 Vector<LinkRecord>& jumpsToLink() { return m_assembler.jumpsToLink(); } 59 void* unlinkedCode() { return m_assembler.unlinkedCode(); } 60 JumpLinkType computeJumpType(LinkRecord& record, const uint8_t* from, const uint8_t* to) { return m_assembler.computeJumpType(record, from, to); } 61 void recordLinkOffsets(int32_t regionStart, int32_t regionEnd, int32_t offset) {return m_assembler.recordLinkOffsets(regionStart, regionEnd, offset); } 62 int jumpSizeDelta(JumpLinkType jumpLinkType) { return m_assembler.jumpSizeDelta(jumpLinkType); } 63 void link(LinkRecord& record, uint8_t* from, uint8_t* to) { return m_assembler.link(record, from, to); } 64 48 65 struct ArmAddress { 49 66 enum AddressType { … … 970 987 void jump(RegisterID target) 971 988 { 972 m_assembler.bx(target );989 m_assembler.bx(target, inUninterruptedSequence() ? ARMv7Assembler::JumpFullSize : ARMv7Assembler::JumpNoCondition); 973 990 } 974 991 … … 977 994 { 978 995 load32(address, dataTempRegister); 979 m_assembler.bx(dataTempRegister );996 m_assembler.bx(dataTempRegister, inUninterruptedSequence() ? ARMv7Assembler::JumpFullSize : ARMv7Assembler::JumpNoCondition); 980 997 } 981 998 … … 1013 1030 Jump branchMul32(Condition cond, RegisterID src, RegisterID dest) 1014 1031 { 1015 ASSERT (cond == Overflow);1032 ASSERT_UNUSED(cond, cond == Overflow); 1016 1033 m_assembler.smull(dest, dataTempRegister, dest, src); 1017 1034 m_assembler.asr(addressTempRegister, dest, 31); … … 1021 1038 Jump branchMul32(Condition cond, Imm32 imm, RegisterID src, RegisterID dest) 1022 1039 { 1023 ASSERT (cond == Overflow);1040 ASSERT_UNUSED(cond, cond == Overflow); 1024 1041 move(imm, dataTempRegister); 1025 1042 m_assembler.smull(dest, dataTempRegister, src, dataTempRegister); … … 1060 1077 void breakpoint() 1061 1078 { 1062 m_assembler.bkpt( );1079 m_assembler.bkpt(0); 1063 1080 } 1064 1081 … … 1066 1083 { 1067 1084 moveFixedWidthEncoding(Imm32(0), dataTempRegister); 1068 return Call(m_assembler.blx(dataTempRegister ), Call::LinkableNear);1085 return Call(m_assembler.blx(dataTempRegister, ARMv7Assembler::JumpFullSize), Call::LinkableNear); 1069 1086 } 1070 1087 … … 1072 1089 { 1073 1090 moveFixedWidthEncoding(Imm32(0), dataTempRegister); 1074 return Call(m_assembler.blx(dataTempRegister ), Call::Linkable);1091 return Call(m_assembler.blx(dataTempRegister, ARMv7Assembler::JumpFullSize), Call::Linkable); 1075 1092 } 1076 1093 1077 1094 Call call(RegisterID target) 1078 1095 { 1079 return Call(m_assembler.blx(target ), Call::None);1096 return Call(m_assembler.blx(target, ARMv7Assembler::JumpFullSize), Call::None); 1080 1097 } 1081 1098 … … 1083 1100 { 1084 1101 load32(address, dataTempRegister); 1085 return Call(m_assembler.blx(dataTempRegister ), Call::None);1102 return Call(m_assembler.blx(dataTempRegister, ARMv7Assembler::JumpFullSize), Call::None); 1086 1103 } 1087 1104 1088 1105 void ret() 1089 1106 { 1090 m_assembler.bx(linkRegister );1107 m_assembler.bx(linkRegister, ARMv7Assembler::JumpFullSize); 1091 1108 } 1092 1109 … … 1188 1205 // Like a normal call, but don't link. 1189 1206 moveFixedWidthEncoding(Imm32(0), dataTempRegister); 1190 return Call(m_assembler.bx(dataTempRegister ), Call::Linkable);1207 return Call(m_assembler.bx(dataTempRegister, ARMv7Assembler::JumpFullSize), Call::Linkable); 1191 1208 } 1192 1209 … … 1197 1214 } 1198 1215 1216 1217 int executableOffsetFor(int location) 1218 { 1219 return m_assembler.executableOffsetFor(location); 1220 } 1199 1221 1200 1222 protected: 1223 bool inUninterruptedSequence() 1224 { 1225 return m_inUninterruptedSequence; 1226 } 1227 1201 1228 ARMv7Assembler::JmpSrc makeJump() 1202 1229 { 1203 1230 moveFixedWidthEncoding(Imm32(0), dataTempRegister); 1204 return m_assembler.bx(dataTempRegister );1231 return m_assembler.bx(dataTempRegister, inUninterruptedSequence() ? ARMv7Assembler::JumpFullSize : ARMv7Assembler::JumpNoCondition); 1205 1232 } 1206 1233 … … 1209 1236 m_assembler.it(cond, true, true); 1210 1237 moveFixedWidthEncoding(Imm32(0), dataTempRegister); 1211 return m_assembler.bx(dataTempRegister );1238 return m_assembler.bx(dataTempRegister, inUninterruptedSequence() ? ARMv7Assembler::JumpFullSize : ARMv7Assembler::JumpCondition, cond); 1212 1239 } 1213 1240 ARMv7Assembler::JmpSrc makeBranch(Condition cond) { return makeBranch(armV7Condition(cond)); } … … 1299 1326 ARMv7Assembler::relinkCall(call.dataLocation(), destination.executableAddress()); 1300 1327 } 1328 1329 bool m_inUninterruptedSequence; 1301 1330 }; 1302 1331
Note:
See TracChangeset
for help on using the changeset viewer.