Changeset 65042 in webkit
- Timestamp:
- Aug 9, 2010 8:19:19 PM (14 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 1 added
- 19 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r65032 r65042 1 2010-08-09 Oliver Hunt <oliver@apple.com> 2 3 Reviewed by Gavin Barraclough. 4 5 Allow an assembler/macroassembler to compact branches to more concise forms when linking 6 https://bugs.webkit.org/show_bug.cgi?id=43745 7 8 This patch makes it possible for an assembler to convert jumps into a different 9 (presumably more efficient) form at link time. Currently implemented in the 10 ARMv7 JIT as that already had logic to delay linking of jumps until the end of 11 compilation already. The ARMv7 JIT chooses between either a 4 byte short jump 12 or a full 32-bit offset (and rewrites ITTT instructions as appropriate), so does 13 not yet produce the most compact form possible. The general design of the linker 14 should make it relatively simple to introduce new branch types with little effort, 15 as the linker has no knowledge of the exact form of any of the branches. 16 17 * JavaScriptCore.xcodeproj/project.pbxproj: 18 * assembler/ARMv7Assembler.cpp: Added. 19 (JSC::): 20 Record jump sizes 21 22 * assembler/ARMv7Assembler.h: 23 (JSC::ARMv7Assembler::LinkRecord::LinkRecord): 24 (JSC::ARMv7Assembler::LinkRecord::from): 25 (JSC::ARMv7Assembler::LinkRecord::setFrom): 26 (JSC::ARMv7Assembler::LinkRecord::to): 27 (JSC::ARMv7Assembler::LinkRecord::type): 28 (JSC::ARMv7Assembler::LinkRecord::linkType): 29 (JSC::ARMv7Assembler::LinkRecord::setLinkType): 30 Encapsulate LinkRecord fields so we can compress the values somewhat 31 32 (JSC::ARMv7Assembler::JmpSrc::JmpSrc): 33 Need to record the jump type now 34 35 (JSC::ARMv7Assembler::b): 36 (JSC::ARMv7Assembler::blx): 37 (JSC::ARMv7Assembler::bx): 38 Need to pass the jump types 39 40 (JSC::ARMv7Assembler::executableOffsetFor): 41 (JSC::ARMv7Assembler::jumpSizeDelta): 42 (JSC::ARMv7Assembler::linkRecordSourceComparator): 43 (JSC::ARMv7Assembler::computeJumpType): 44 (JSC::ARMv7Assembler::convertJumpTo): 45 (JSC::ARMv7Assembler::recordLinkOffsets): 46 (JSC::ARMv7Assembler::jumpsToLink): 47 (JSC::ARMv7Assembler::link): 48 (JSC::ARMv7Assembler::unlinkedCode): 49 Helper functions for the linker 50 51 (JSC::ARMv7Assembler::linkJump): 52 (JSC::ARMv7Assembler::canBeShortJump): 53 (JSC::ARMv7Assembler::linkLongJump): 54 (JSC::ARMv7Assembler::linkShortJump): 55 (JSC::ARMv7Assembler::linkJumpAbsolute): 56 Moving code around for the various jump linking functions 57 58 * assembler/AbstractMacroAssembler.h: 59 (JSC::AbstractMacroAssembler::beginUninterruptedSequence): 60 (JSC::AbstractMacroAssembler::endUninterruptedSequence): 61 We have to track uninterrupted sequences in any assembler that compacts 62 branches as that's not something we're allowed to do in such sequences. 63 AbstractMacroAssembler has a nop version of these functions as it makes the 64 code elsewhere nicer. 65 66 * assembler/LinkBuffer.h: 67 (JSC::LinkBuffer::LinkBuffer): 68 (JSC::LinkBuffer::link): 69 (JSC::LinkBuffer::patch): 70 (JSC::LinkBuffer::locationOf): 71 (JSC::LinkBuffer::locationOfNearCall): 72 (JSC::LinkBuffer::returnAddressOffset): 73 (JSC::LinkBuffer::trampolineAt): 74 Updated these functions to adjust for any changed offsets in the linked code 75 76 (JSC::LinkBuffer::applyOffset): 77 A helper function to deal with the now potentially moved labels 78 79 (JSC::LinkBuffer::linkCode): 80 The new and mighty linker function 81 82 * assembler/MacroAssemblerARMv7.h: 83 (JSC::MacroAssemblerARMv7::MacroAssemblerARMv7): 84 (JSC::MacroAssemblerARMv7::beginUninterruptedSequence): 85 (JSC::MacroAssemblerARMv7::endUninterruptedSequence): 86 (JSC::MacroAssemblerARMv7::jumpsToLink): 87 (JSC::MacroAssemblerARMv7::unlinkedCode): 88 (JSC::MacroAssemblerARMv7::computeJumpType): 89 (JSC::MacroAssemblerARMv7::convertJumpTo): 90 (JSC::MacroAssemblerARMv7::recordLinkOffsets): 91 (JSC::MacroAssemblerARMv7::jumpSizeDelta): 92 (JSC::MacroAssemblerARMv7::link): 93 (JSC::MacroAssemblerARMv7::jump): 94 (JSC::MacroAssemblerARMv7::branchMul32): 95 (JSC::MacroAssemblerARMv7::breakpoint): 96 (JSC::MacroAssemblerARMv7::nearCall): 97 (JSC::MacroAssemblerARMv7::call): 98 (JSC::MacroAssemblerARMv7::ret): 99 (JSC::MacroAssemblerARMv7::tailRecursiveCall): 100 (JSC::MacroAssemblerARMv7::executableOffsetFor): 101 (JSC::MacroAssemblerARMv7::inUninterruptedSequence): 102 (JSC::MacroAssemblerARMv7::makeJump): 103 (JSC::MacroAssemblerARMv7::makeBranch): 104 All branches need to pass on their type now 105 106 * jit/ExecutableAllocator.h: 107 (JSC::ExecutablePool::returnLastBytes): 108 We can't know ahead of time how much space will be necessary to 109 hold the linked code if we're compacting branches, this new 110 function allows us to return the unused bytes at the end of linking 111 112 * jit/JIT.cpp: 113 (JSC::JIT::JIT): 114 (JSC::JIT::privateCompile): 115 * jit/JIT.h: 116 (JSC::JIT::compile): 117 The JIT class now needs to take a linker offset so that recompilation 118 can generate the same jumps when using branch compaction. 119 * jit/JITArithmetic32_64.cpp: 120 (JSC::JIT::emitSlow_op_mod): 121 * jit/JITOpcodes.cpp: 122 (JSC::JIT::privateCompileCTIMachineTrampolines): 123 * jit/JITOpcodes32_64.cpp: 124 (JSC::JIT::privateCompileCTIMachineTrampolines): 125 (JSC::JIT::privateCompileCTINativeCall): 126 Update for new trampolineAt changes 127 128 * wtf/FastMalloc.cpp: 129 (WTF::TCMallocStats::): 130 * wtf/Platform.h: 131 1 132 2010-08-09 Gavin Barraclough <barraclough@apple.com> 2 133 -
trunk/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r65021 r65042 312 312 A7482E93116A7CAD003B0712 /* JSWeakObjectMapRefInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = A7482E37116A697B003B0712 /* JSWeakObjectMapRefInternal.h */; settings = {ATTRIBUTES = (Private, ); }; }; 313 313 A74B3499102A5F8E0032AB98 /* MarkStack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A74B3498102A5F8E0032AB98 /* MarkStack.cpp */; }; 314 A74DE1D0120B875600D40D5B /* ARMv7Assembler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A74DE1CB120B86D600D40D5B /* ARMv7Assembler.cpp */; }; 314 315 A75706DE118A2BCF0057F88F /* JITArithmetic32_64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A75706DD118A2BCF0057F88F /* JITArithmetic32_64.cpp */; }; 315 316 A766B44F0EE8DCD1009518CA /* ExecutableAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = A7B48DB50EE74CFC00DCBDB6 /* ExecutableAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 928 929 A7482E37116A697B003B0712 /* JSWeakObjectMapRefInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSWeakObjectMapRefInternal.h; sourceTree = "<group>"; }; 929 930 A74B3498102A5F8E0032AB98 /* MarkStack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MarkStack.cpp; sourceTree = "<group>"; }; 931 A74DE1CB120B86D600D40D5B /* ARMv7Assembler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ARMv7Assembler.cpp; sourceTree = "<group>"; }; 930 932 A75706DD118A2BCF0057F88F /* JITArithmetic32_64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITArithmetic32_64.cpp; sourceTree = "<group>"; }; 931 933 A76C51741182748D00715B05 /* JSInterfaceJIT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSInterfaceJIT.h; sourceTree = "<group>"; }; … … 1849 1851 86D3B2C010156BDE002865E7 /* ARMAssembler.h */, 1850 1852 86ADD1430FDDEA980006EEC2 /* ARMv7Assembler.h */, 1853 A74DE1CB120B86D600D40D5B /* ARMv7Assembler.cpp */, 1851 1854 9688CB130ED12B4E001D649F /* AssemblerBuffer.h */, 1852 1855 86D3B2C110156BDE002865E7 /* AssemblerBufferWithConstantPool.h */, … … 2678 2681 8627E5EB11F1281900A313B5 /* PageAllocation.cpp in Sources */, 2679 2682 DDE82AD71209D955005C1756 /* GCHandle.cpp in Sources */, 2683 A74DE1D0120B875600D40D5B /* ARMv7Assembler.cpp in Sources */, 2680 2684 ); 2681 2685 runOnlyForDeploymentPostprocessing = 0; -
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 -
trunk/JavaScriptCore/jit/ExecutableAllocator.h
r64798 r65042 129 129 } 130 130 131 void returnLastBytes(size_t count) 132 { 133 m_freePtr -= count; 134 } 135 131 136 ~ExecutablePool() 132 137 { -
trunk/JavaScriptCore/jit/JIT.cpp
r64608 r65042 72 72 } 73 73 74 JIT::JIT(JSGlobalData* globalData, CodeBlock* codeBlock )74 JIT::JIT(JSGlobalData* globalData, CodeBlock* codeBlock, void* linkerOffset) 75 75 : m_interpreter(globalData->interpreter) 76 76 , m_globalData(globalData) … … 90 90 , m_jumpTargetsPosition(0) 91 91 #endif 92 , m_linkerOffset(linkerOffset) 92 93 { 93 94 } … … 512 513 if (!executablePool) 513 514 return JITCode(); 514 LinkBuffer patchBuffer(this, executablePool.release() );515 LinkBuffer patchBuffer(this, executablePool.release(), m_linkerOffset); 515 516 if (!patchBuffer.allocationSuccessful()) 516 517 return JITCode(); -
trunk/JavaScriptCore/jit/JIT.h
r64943 r65042 179 179 180 180 public: 181 static JITCode compile(JSGlobalData* globalData, CodeBlock* codeBlock, CodePtr* functionEntryArityCheck = 0 )182 { 183 return JIT(globalData, codeBlock ).privateCompile(functionEntryArityCheck);181 static JITCode compile(JSGlobalData* globalData, CodeBlock* codeBlock, CodePtr* functionEntryArityCheck = 0, void* offsetBase = 0) 182 { 183 return JIT(globalData, codeBlock, offsetBase).privateCompile(functionEntryArityCheck); 184 184 } 185 185 … … 222 222 if (!globalData->canUseJIT()) 223 223 return; 224 JIT jit(globalData );224 JIT jit(globalData, 0, 0); 225 225 jit.privateCompileCTIMachineTrampolines(executablePool, globalData, trampolines); 226 226 } … … 230 230 if (!globalData->canUseJIT()) 231 231 return CodePtr(); 232 JIT jit(globalData );232 JIT jit(globalData, 0, 0); 233 233 return jit.privateCompileCTINativeCall(executablePool, globalData, func); 234 234 } … … 260 260 }; 261 261 262 JIT(JSGlobalData*, CodeBlock* = 0 );262 JIT(JSGlobalData*, CodeBlock* = 0, void* = 0); 263 263 264 264 void privateCompileMainPass(); … … 667 667 #endif // USE(JSVALUE32_64) 668 668 669 #if defined(ASSEMBLER_HAS_CONSTANT_POOL) && ASSEMBLER_HAS_CONSTANT_POOL670 #define BEGIN_UNINTERRUPTED_SEQUENCE(name) beginUninterruptedSequence(name ## InstructionSpace, name ## ConstantSpace)671 #define END_UNINTERRUPTED_SEQUENCE(name) endUninterruptedSequence(name ## InstructionSpace, name ## ConstantSpace)669 #if (defined(ASSEMBLER_HAS_CONSTANT_POOL) && ASSEMBLER_HAS_CONSTANT_POOL) 670 #define BEGIN_UNINTERRUPTED_SEQUENCE(name) do { beginUninterruptedSequence(); beginUninterruptedSequence(name ## InstructionSpace, name ## ConstantSpace); } while (false) 671 #define END_UNINTERRUPTED_SEQUENCE(name) do { endUninterruptedSequence(name ## InstructionSpace, name ## ConstantSpace); endUninterruptedSequence(); } while (false) 672 672 673 673 void beginUninterruptedSequence(int, int); … … 675 675 676 676 #else 677 #define BEGIN_UNINTERRUPTED_SEQUENCE(name) 678 #define END_UNINTERRUPTED_SEQUENCE(name) 677 #define BEGIN_UNINTERRUPTED_SEQUENCE(name) do { beginUninterruptedSequence(); } while (false) 678 #define END_UNINTERRUPTED_SEQUENCE(name) do { endUninterruptedSequence(); } while (false) 679 679 #endif 680 680 … … 941 941 #endif 942 942 #endif 943 void* m_linkerOffset; 943 944 static CodePtr stringGetByValStubGenerator(JSGlobalData* globalData, ExecutablePool* pool); 944 945 } JIT_CLASS_ALIGNMENT; -
trunk/JavaScriptCore/jit/JITArithmetic32_64.cpp
r64176 r65042 1384 1384 void JIT::emitSlow_op_mod(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter) 1385 1385 { 1386 UNUSED_PARAM(currentInstruction); 1387 UNUSED_PARAM(iter); 1386 1388 #if ENABLE(JIT_USE_SOFT_MODULO) 1387 1389 unsigned result = currentInstruction[1].u.operand; -
trunk/JavaScriptCore/jit/JITOpcodes.cpp
r64790 r65042 166 166 if (!*executablePool) 167 167 CRASH(); 168 LinkBuffer patchBuffer(this, *executablePool );168 LinkBuffer patchBuffer(this, *executablePool, 0); 169 169 // We can't run without the JIT trampolines! 170 170 if (!patchBuffer.allocationSuccessful()) … … 185 185 CodeRef finalCode = patchBuffer.finalizeCode(); 186 186 187 trampolines->ctiVirtualCallLink = trampolineAt(finalCode,virtualCallLinkBegin);188 trampolines->ctiVirtualConstructLink = trampolineAt(finalCode,virtualConstructLinkBegin);189 trampolines->ctiVirtualCall = trampolineAt(finalCode,virtualCallBegin);190 trampolines->ctiVirtualConstruct = trampolineAt(finalCode,virtualConstructBegin);191 trampolines->ctiNativeCall = trampolineAt(finalCode,nativeCallThunk);192 trampolines->ctiNativeConstruct = trampolineAt(finalCode,nativeConstructThunk);187 trampolines->ctiVirtualCallLink = patchBuffer.trampolineAt(virtualCallLinkBegin); 188 trampolines->ctiVirtualConstructLink = patchBuffer.trampolineAt(virtualConstructLinkBegin); 189 trampolines->ctiVirtualCall = patchBuffer.trampolineAt(virtualCallBegin); 190 trampolines->ctiVirtualConstruct = patchBuffer.trampolineAt(virtualConstructBegin); 191 trampolines->ctiNativeCall = patchBuffer.trampolineAt(nativeCallThunk); 192 trampolines->ctiNativeConstruct = patchBuffer.trampolineAt(nativeConstructThunk); 193 193 #if ENABLE(JIT_USE_SOFT_MODULO) 194 trampolines->ctiSoftModulo = trampolineAt(finalCode,softModBegin);194 trampolines->ctiSoftModulo = patchBuffer.trampolineAt(softModBegin); 195 195 #endif 196 196 #if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) 197 trampolines->ctiStringLengthTrampoline = trampolineAt(finalCode,stringLengthBegin);197 trampolines->ctiStringLengthTrampoline = patchBuffer.trampolineAt(stringLengthBegin); 198 198 #endif 199 199 } -
trunk/JavaScriptCore/jit/JITOpcodes32_64.cpp
r64790 r65042 164 164 if (!*executablePool) 165 165 CRASH(); 166 LinkBuffer patchBuffer(this, *executablePool );166 LinkBuffer patchBuffer(this, *executablePool, 0); 167 167 // We can't run without the JIT trampolines! 168 168 if (!patchBuffer.allocationSuccessful()) … … 183 183 CodeRef finalCode = patchBuffer.finalizeCode(); 184 184 185 trampolines->ctiVirtualCall = trampolineAt(finalCode,virtualCallBegin);186 trampolines->ctiVirtualConstruct = trampolineAt(finalCode,virtualConstructBegin);187 trampolines->ctiNativeCall = trampolineAt(finalCode,nativeCallThunk);188 trampolines->ctiNativeConstruct = trampolineAt(finalCode,nativeConstructThunk);185 trampolines->ctiVirtualCall = patchBuffer.trampolineAt(virtualCallBegin); 186 trampolines->ctiVirtualConstruct = patchBuffer.trampolineAt(virtualConstructBegin); 187 trampolines->ctiNativeCall = patchBuffer.trampolineAt(nativeCallThunk); 188 trampolines->ctiNativeConstruct = patchBuffer.trampolineAt(nativeConstructThunk); 189 189 #if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) 190 trampolines->ctiStringLengthTrampoline = trampolineAt(finalCode,stringLengthBegin);190 trampolines->ctiStringLengthTrampoline = patchBuffer.trampolineAt(stringLengthBegin); 191 191 #endif 192 192 #if ENABLE(JIT_OPTIMIZE_CALL) 193 trampolines->ctiVirtualCallLink = trampolineAt(finalCode,virtualCallLinkBegin);194 trampolines->ctiVirtualConstructLink = trampolineAt(finalCode,virtualConstructLinkBegin);193 trampolines->ctiVirtualCallLink = patchBuffer.trampolineAt(virtualCallLinkBegin); 194 trampolines->ctiVirtualConstructLink = patchBuffer.trampolineAt(virtualConstructLinkBegin); 195 195 #endif 196 196 #if ENABLE(JIT_USE_SOFT_MODULO) 197 trampolines->ctiSoftModulo = trampolineAt(finalCode,softModBegin);197 trampolines->ctiSoftModulo = patchBuffer.trampolineAt(softModBegin); 198 198 #endif 199 199 } … … 363 363 364 364 // All trampolines constructed! copy the code, link up calls, and set the pointers on the Machine object. 365 LinkBuffer patchBuffer(this, executablePool );365 LinkBuffer patchBuffer(this, executablePool, 0); 366 366 // We can't continue if we can't call a function! 367 367 if (!patchBuffer.allocationSuccessful()) … … 369 369 370 370 patchBuffer.link(nativeCall, FunctionPtr(func)); 371 372 CodeRef finalCode = patchBuffer.finalizeCode(); 373 return trampolineAt(finalCode,nativeCallThunk);371 patchBuffer.finalizeCode(); 372 373 return patchBuffer.trampolineAt(nativeCallThunk); 374 374 } 375 375 -
trunk/JavaScriptCore/jit/JITPropertyAccess.cpp
r64943 r65042 78 78 jit.ret(); 79 79 80 LinkBuffer patchBuffer(&jit, pool );80 LinkBuffer patchBuffer(&jit, pool, 0); 81 81 // We can't run without the JIT trampolines! 82 82 if (!patchBuffer.allocationSuccessful()) … … 653 653 Call failureCall = tailRecursiveCall(); 654 654 655 LinkBuffer patchBuffer(this, m_codeBlock->executablePool() );655 LinkBuffer patchBuffer(this, m_codeBlock->executablePool(), 0); 656 656 if (!patchBuffer.allocationSuccessful()) 657 657 return false; … … 744 744 Jump success = jump(); 745 745 746 LinkBuffer patchBuffer(this, m_codeBlock->executablePool() );746 LinkBuffer patchBuffer(this, m_codeBlock->executablePool(), 0); 747 747 if (!patchBuffer.allocationSuccessful()) 748 748 return false; … … 810 810 compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset); 811 811 Jump success = jump(); 812 LinkBuffer patchBuffer(this, m_codeBlock->executablePool() );812 LinkBuffer patchBuffer(this, m_codeBlock->executablePool(), 0); 813 813 if (!patchBuffer.allocationSuccessful()) 814 814 return false; … … 873 873 Jump success = jump(); 874 874 875 LinkBuffer patchBuffer(this, m_codeBlock->executablePool() );875 LinkBuffer patchBuffer(this, m_codeBlock->executablePool(), 0); 876 876 if (!patchBuffer.allocationSuccessful()) 877 877 return false; … … 951 951 Jump success = jump(); 952 952 953 LinkBuffer patchBuffer(this, m_codeBlock->executablePool() );953 LinkBuffer patchBuffer(this, m_codeBlock->executablePool(), 0); 954 954 if (!patchBuffer.allocationSuccessful()) 955 955 return false; … … 1027 1027 Jump success = jump(); 1028 1028 1029 LinkBuffer patchBuffer(this, m_codeBlock->executablePool() );1029 LinkBuffer patchBuffer(this, m_codeBlock->executablePool(), 0); 1030 1030 if (!patchBuffer.allocationSuccessful()) 1031 1031 return false; … … 1101 1101 Jump success = jump(); 1102 1102 1103 LinkBuffer patchBuffer(this, m_codeBlock->executablePool() );1103 LinkBuffer patchBuffer(this, m_codeBlock->executablePool(), 0); 1104 1104 if (!patchBuffer.allocationSuccessful()) 1105 1105 return false; -
trunk/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
r64943 r65042 296 296 jit.ret(); 297 297 298 LinkBuffer patchBuffer(&jit, pool );298 LinkBuffer patchBuffer(&jit, pool, 0); 299 299 // We can't run without the JIT trampolines! 300 300 if (!patchBuffer.allocationSuccessful()) … … 657 657 Call failureCall = tailRecursiveCall(); 658 658 659 LinkBuffer patchBuffer(this, m_codeBlock->executablePool() );659 LinkBuffer patchBuffer(this, m_codeBlock->executablePool(), 0); 660 660 if (!patchBuffer.allocationSuccessful()) 661 661 return false; … … 753 753 Jump success = jump(); 754 754 755 LinkBuffer patchBuffer(this, m_codeBlock->executablePool() );755 LinkBuffer patchBuffer(this, m_codeBlock->executablePool(), 0); 756 756 if (!patchBuffer.allocationSuccessful()) 757 757 return false; … … 820 820 Jump success = jump(); 821 821 822 LinkBuffer patchBuffer(this, m_codeBlock->executablePool() );822 LinkBuffer patchBuffer(this, m_codeBlock->executablePool(), 0); 823 823 if (!patchBuffer.allocationSuccessful()) 824 824 return false; … … 887 887 Jump success = jump(); 888 888 889 LinkBuffer patchBuffer(this, m_codeBlock->executablePool() );889 LinkBuffer patchBuffer(this, m_codeBlock->executablePool(), 0); 890 890 if (!patchBuffer.allocationSuccessful()) 891 891 return false; … … 965 965 Jump success = jump(); 966 966 967 LinkBuffer patchBuffer(this, m_codeBlock->executablePool() );967 LinkBuffer patchBuffer(this, m_codeBlock->executablePool(), 0); 968 968 if (!patchBuffer.allocationSuccessful()) 969 969 return false; … … 1042 1042 Jump success = jump(); 1043 1043 1044 LinkBuffer patchBuffer(this, m_codeBlock->executablePool() );1044 LinkBuffer patchBuffer(this, m_codeBlock->executablePool(), 0); 1045 1045 if (!patchBuffer.allocationSuccessful()) 1046 1046 return false; … … 1116 1116 Jump success = jump(); 1117 1117 1118 LinkBuffer patchBuffer(this, m_codeBlock->executablePool() );1118 LinkBuffer patchBuffer(this, m_codeBlock->executablePool(), 0); 1119 1119 if (!patchBuffer.allocationSuccessful()) 1120 1120 return false; -
trunk/JavaScriptCore/jit/SpecializedThunkJIT.h
r64608 r65042 130 130 MacroAssemblerCodePtr finalize(MacroAssemblerCodePtr fallback) 131 131 { 132 LinkBuffer patchBuffer(this, m_pool.get() );132 LinkBuffer patchBuffer(this, m_pool.get(), 0); 133 133 // We can't continue if we can't call a function! 134 134 if (!patchBuffer.allocationSuccessful()) -
trunk/JavaScriptCore/runtime/Executable.cpp
r64790 r65042 305 305 #if ENABLE(JIT) 306 306 if (globalData->canUseJIT()) { 307 JITCode newJITCode = JIT::compile(globalData, newCodeBlock.get() );307 JITCode newJITCode = JIT::compile(globalData, newCodeBlock.get(), 0, codeBlock->m_isConstructor ? generatedJITCodeForConstruct().start() : generatedJITCodeForCall().start()); 308 308 if (!newJITCode) { 309 309 globalData->functionCodeBlockBeingReparsed = 0; … … 338 338 #if ENABLE(JIT) 339 339 if (globalData->canUseJIT()) { 340 JITCode newJITCode = JIT::compile(globalData, newCodeBlock.get() );340 JITCode newJITCode = JIT::compile(globalData, newCodeBlock.get(), 0, generatedJITCodeForCall().start()); 341 341 if (!newJITCode) { 342 342 globalData->functionCodeBlockBeingReparsed = 0; -
trunk/JavaScriptCore/wtf/FastMalloc.cpp
r64798 r65042 4455 4455 &FastMallocZone::log, &FastMallocZone::forceLock, &FastMallocZone::forceUnlock, &FastMallocZone::statistics 4456 4456 4457 #if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !OS(IOS)4457 #if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) 4458 4458 , 0 // zone_locked will not be called on the zone unless it advertises itself as version five or higher. 4459 4459 #endif 4460 #if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) && !OS(IOS)4460 #if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) 4461 4461 , 0, 0, 0, 0 // These members will not be used unless the zone advertises itself as version seven or higher. 4462 4462 #endif -
trunk/JavaScriptCore/wtf/Platform.h
r64943 r65042 1095 1095 #endif 1096 1096 1097 #if CPU(ARM_THUMB2) 1098 #define ENABLE_BRANCH_COMPACTION 1 1099 #endif 1100 1097 1101 #endif /* WTF_Platform_h */ -
trunk/JavaScriptCore/yarr/RegexJIT.cpp
r64608 r65042 1473 1473 } 1474 1474 1475 LinkBuffer patchBuffer(this, executablePool.release() );1475 LinkBuffer patchBuffer(this, executablePool.release(), 0); 1476 1476 if (!patchBuffer.allocationSuccessful()) { 1477 1477 m_shouldFallBack = true;
Note: See TracChangeset
for help on using the changeset viewer.