Changeset 44514 in webkit for trunk/JavaScriptCore
- Timestamp:
- Jun 8, 2009, 6:40:59 PM (16 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 2 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r44513 r44514 1 2009-06-08 Gavin Barraclough <[email protected]> 2 3 Reviewed by Geoff Garen. 4 5 Add (incomplete) support to YARR for running with the jit enabled 6 on Arm thumb2 platforms. Adds new Assembler/MacroAssembler classes, 7 along with cache flushing support, tweaks to MacroAssemblerCodePtr 8 to support decorated thumb code pointers, and new enter/exit code 9 to YARR jit for the platform. 10 11 Support for this platform is still under development - the assembler 12 currrently only supports planting and linking jumps with a 16Mb range. 13 As such, initially commiting in a disabled state. 14 15 * JavaScriptCore.xcodeproj/project.pbxproj: 16 Add new assembler files. 17 * assembler/ARMv7Assembler.h: Added. 18 Add new Assembler. 19 * assembler/AbstractMacroAssembler.h: 20 Tweaks to ensure sizes of pointer values planted in JIT code do not change. 21 * assembler/MacroAssembler.h: 22 On ARMv7 platforms use MacroAssemblerARMv7. 23 * assembler/MacroAssemblerARMv7.h: Added. 24 Add new MacroAssembler. 25 * assembler/MacroAssemblerCodeRef.h: 26 (JSC::FunctionPtr::FunctionPtr): 27 Add better ASSERT. 28 (JSC::ReturnAddressPtr::ReturnAddressPtr): 29 Add better ASSERT. 30 (JSC::MacroAssemblerCodePtr::MacroAssemblerCodePtr): 31 On ARMv7, MacroAssemblerCodePtr's mush be 'decorated' with a low bit set, 32 to indicate to the processor that the code is thumb code, not traditional 33 32-bit ARM. 34 (JSC::MacroAssemblerCodePtr::dataLocation): 35 On ARMv7, decoration must be removed. 36 * jit/ExecutableAllocator.h: 37 (JSC::ExecutableAllocator::makeWritable): 38 Reformatted, no change. 39 (JSC::ExecutableAllocator::makeExecutable): 40 When marking code executable also cache flush it, where necessary. 41 (JSC::ExecutableAllocator::MakeWritable::MakeWritable): 42 Only use the null implementation of this class if both !ASSEMBLER_WX_EXCLUSIVE 43 and running on x86(_64) - on other platforms we may also need ensure that 44 makeExecutable is called at the end to flush caches. 45 (JSC::ExecutableAllocator::reprotectRegion): 46 Reformatted, no change. 47 (JSC::ExecutableAllocator::cacheFlush): 48 Cache flush a region of memory, or platforms where this is necessary. 49 * wtf/Platform.h: 50 Add changes necessary to allow YARR jit to build on this platform, disabled. 51 * yarr/RegexJIT.cpp: 52 (JSC::Yarr::RegexGenerator::generateEnter): 53 (JSC::Yarr::RegexGenerator::generateReturn): 54 Add support to these methods for ARMv7. 55 1 56 2009-06-08 Dimitri Glazkov <[email protected]> 2 57 -
trunk/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r44508 r44514 129 129 869EBCB70E8C6D4A008722CC /* ResultType.h in Headers */ = {isa = PBXBuildFile; fileRef = 869EBCB60E8C6D4A008722CC /* ResultType.h */; settings = {ATTRIBUTES = (Private, ); }; }; 130 130 86A90ED00EE7D51F00AB350D /* JITArithmetic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86A90ECF0EE7D51F00AB350D /* JITArithmetic.cpp */; }; 131 86ADD1450FDDEA980006EEC2 /* ARMv7Assembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86ADD1430FDDEA980006EEC2 /* ARMv7Assembler.h */; }; 132 86ADD1460FDDEA980006EEC2 /* MacroAssemblerARMv7.h in Headers */ = {isa = PBXBuildFile; fileRef = 86ADD1440FDDEA980006EEC2 /* MacroAssemblerARMv7.h */; }; 131 133 86C36EEA0EE1289D00B3DF59 /* MacroAssembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86C36EE90EE1289D00B3DF59 /* MacroAssembler.h */; }; 132 134 86CC85A10EE79A4700288682 /* JITInlineMethods.h in Headers */ = {isa = PBXBuildFile; fileRef = 86CC85A00EE79A4700288682 /* JITInlineMethods.h */; }; … … 628 630 869EBCB60E8C6D4A008722CC /* ResultType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResultType.h; sourceTree = "<group>"; }; 629 631 86A90ECF0EE7D51F00AB350D /* JITArithmetic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITArithmetic.cpp; sourceTree = "<group>"; }; 632 86ADD1430FDDEA980006EEC2 /* ARMv7Assembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARMv7Assembler.h; sourceTree = "<group>"; }; 633 86ADD1440FDDEA980006EEC2 /* MacroAssemblerARMv7.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssemblerARMv7.h; sourceTree = "<group>"; }; 630 634 86C36EE90EE1289D00B3DF59 /* MacroAssembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssembler.h; sourceTree = "<group>"; }; 631 635 86CC85A00EE79A4700288682 /* JITInlineMethods.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JITInlineMethods.h; sourceTree = "<group>"; }; … … 1532 1536 children = ( 1533 1537 860161DF0F3A83C100F84710 /* AbstractMacroAssembler.h */, 1538 86ADD1430FDDEA980006EEC2 /* ARMv7Assembler.h */, 1534 1539 9688CB130ED12B4E001D649F /* AssemblerBuffer.h */, 1535 1540 863B23DF0FC60E6200703AA4 /* MacroAssemblerCodeRef.h */, 1541 86ADD1440FDDEA980006EEC2 /* MacroAssemblerARMv7.h */, 1536 1542 860161E00F3A83C100F84710 /* MacroAssemblerX86.h */, 1537 1543 860161E10F3A83C100F84710 /* MacroAssemblerX86_64.h */, … … 1841 1847 0BDFFAE00FC6192900D69EF4 /* CrossThreadRefCounted.h in Headers */, 1842 1848 0BDFFAE10FC6193100D69EF4 /* OwnFastMallocPtr.h in Headers */, 1849 86ADD1450FDDEA980006EEC2 /* ARMv7Assembler.h in Headers */, 1850 86ADD1460FDDEA980006EEC2 /* MacroAssemblerARMv7.h in Headers */, 1843 1851 ); 1844 1852 runOnlyForDeploymentPostprocessing = 0; -
trunk/JavaScriptCore/assembler/AbstractMacroAssembler.h
r44476 r44514 182 182 explicit Imm32(int32_t value) 183 183 : m_value(value) 184 #if PLATFORM(ARM_V7) 185 , m_isPointer(false) 186 #endif 184 187 { 185 188 } … … 188 191 explicit Imm32(ImmPtr ptr) 189 192 : m_value(ptr.asIntptr()) 190 { 191 }193 #if PLATFORM(ARM_V7) 194 , m_isPointer(true) 192 195 #endif 196 { 197 } 198 #endif 193 199 194 200 int32_t m_value; 201 #if PLATFORM(ARM_V7) 202 // We rely on being able to regenerate code to recover exception handling 203 // information. Since ARMv7 supports 16-bit immediates there is a danger 204 // that if pointer values change the layout of the generated code will change. 205 // To avoid this problem, always generate pointers (and thus Imm32s constructed 206 // from ImmPtrs) with a code sequence that is able to represent any pointer 207 // value - don't use a more compact form in these cases. 208 bool m_isPointer; 209 #endif 195 210 }; 196 211 … … 529 544 void relink(CodeLocationLabel destination) 530 545 { 531 AssemblerType::relinkJump(this->dataLocation(), destination. executableAddress());546 AssemblerType::relinkJump(this->dataLocation(), destination.dataLocation()); 532 547 } 533 548 … … 787 802 void link(Jump jump, CodeLocationLabel label) 788 803 { 789 AssemblerType::linkJump(code(), jump.m_jmp, label. executableAddress());804 AssemblerType::linkJump(code(), jump.m_jmp, label.dataLocation()); 790 805 } 791 806 … … 793 808 { 794 809 for (unsigned i = 0; i < list.m_jumps.size(); ++i) 795 AssemblerType::linkJump(code(), list.m_jumps[i].m_jmp, label. executableAddress());810 AssemblerType::linkJump(code(), list.m_jumps[i].m_jmp, label.dataLocation()); 796 811 } 797 812 -
trunk/JavaScriptCore/assembler/MacroAssembler.h
r43432 r44514 31 31 #if ENABLE(ASSEMBLER) 32 32 33 #if PLATFORM(X86) 33 #if PLATFORM(ARM_V7) 34 #include "MacroAssemblerARMv7.h" 35 namespace JSC { typedef MacroAssemblerARMv7 MacroAssemblerBase; }; 36 37 #elif PLATFORM(X86) 34 38 #include "MacroAssemblerX86.h" 35 39 namespace JSC { typedef MacroAssemblerX86 MacroAssemblerBase; }; -
trunk/JavaScriptCore/assembler/MacroAssemblerCodeRef.h
r44455 r44514 36 36 #if ENABLE(ASSEMBLER) 37 37 38 // ASSERT_VALID_CODE_POINTER checks that ptr is a non-null pointer, and that it is a valid 39 // instruction address on the platform (for example, check any alignment requirements). 40 #if PLATFORM(ARM_V7) 41 // ARM/thumb instructions must be 16-bit aligned, but all code pointers to be loaded 42 // into the processor are decorated with the bottom bit set, indicating that this is 43 // thumb code (as oposed to 32-bit traditional ARM). The first test checks for both 44 // decorated and undectorated null, and the second test ensures that the pointer is 45 // decorated. 46 #define ASSERT_VALID_CODE_POINTER(ptr) \ 47 ASSERT(reinterpret_cast<intptr_t>(ptr) & ~1); \ 48 ASSERT(reinterpret_cast<intptr_t>(ptr) & 1) 49 #else 50 #define ASSERT_VALID_CODE_POINTER(ptr) \ 51 ASSERT(ptr) 52 #endif 53 38 54 namespace JSC { 39 55 … … 53 69 : m_value(reinterpret_cast<void*>(value)) 54 70 { 55 ASSERT (m_value);71 ASSERT_VALID_CODE_POINTER(m_value); 56 72 } 57 73 … … 80 96 : m_value(value) 81 97 { 82 ASSERT (m_value);98 ASSERT_VALID_CODE_POINTER(m_value); 83 99 } 84 100 … … 100 116 101 117 explicit MacroAssemblerCodePtr(void* value) 118 #if PLATFORM(ARM_V7) 119 // Decorate the pointer as a thumb code pointer. 120 : m_value(reinterpret_cast<char*>(value) + 1) 121 #else 102 122 : m_value(value) 123 #endif 103 124 { 104 ASSERT (m_value);125 ASSERT_VALID_CODE_POINTER(m_value); 105 126 } 106 127 … … 108 129 : m_value(ra.value()) 109 130 { 110 ASSERT (m_value);131 ASSERT_VALID_CODE_POINTER(m_value); 111 132 } 112 133 113 134 void* executableAddress() const { return m_value; } 114 void* dataLocation() const { ASSERT(m_value); return m_value; } 135 #if PLATFORM(ARM_V7) 136 // To use this pointer as a data address remove the decoration. 137 void* dataLocation() const { ASSERT_VALID_CODE_POINTER(m_value); return reinterpret_cast<char*>(m_value) - 1; } 138 #else 139 void* dataLocation() const { ASSERT_VALID_CODE_POINTER(m_value); return m_value; } 140 #endif 115 141 116 142 private: -
trunk/JavaScriptCore/jit/ExecutableAllocator.h
r44341 r44514 27 27 #define ExecutableAllocator_h 28 28 29 #include <limits> 29 30 #include <wtf/Assertions.h> 30 31 #include <wtf/PassRefPtr.h> 31 32 #include <wtf/RefCounted.h> 33 #include <wtf/UnusedParam.h> 32 34 #include <wtf/Vector.h> 33 35 34 #include <limits> 36 #if PLATFORM(IPHONE) 37 #include <libkern/OSCacheControl.h> 38 #include <sys/mman.h> 39 #endif 35 40 36 41 #define JIT_ALLOCATOR_PAGE_SIZE (ExecutableAllocator::pageSize) … … 152 157 } 153 158 154 #if ENABLE(ASSEMBLER_WX_EXCLUSIVE) 155 static void makeWritable(void* start, size_t size) { reprotectRegion(start, size, Writable); } 156 static void makeExecutable(void* start, size_t size) { reprotectRegion(start, size, Executable); } 157 159 static void makeWritable(void* start, size_t size) 160 { 161 reprotectRegion(start, size, Writable); 162 } 163 164 static void makeExecutable(void* start, size_t size) 165 { 166 reprotectRegion(start, size, Executable); 167 cacheFlush(start, size); 168 } 169 170 #if !ENABLE(ASSEMBLER_WX_EXCLUSIVE) && (PLATFORM(X86) || PLATFORM(X86_64)) 171 // If ASSEMBLER_WX_EXCLUSIVE protection is turned off, and if we're running 172 // on x86, then MakeWritable has nothing to do. On non-x86 platforms we need 173 // to track start & size so we can cache-flush at the end. 174 class MakeWritable { public: MakeWritable(void*, size_t) {} }; 175 #else 158 176 class MakeWritable { 159 177 public: … … 174 192 size_t m_size; 175 193 }; 176 #else177 static void makeWritable(void*, size_t) {}178 static void makeExecutable(void*, size_t) {}179 class MakeWritable { public: MakeWritable(void*, size_t) {} };180 194 #endif 181 195 … … 184 198 #if ENABLE(ASSEMBLER_WX_EXCLUSIVE) 185 199 static void reprotectRegion(void*, size_t, ProtectionSeting); 186 #endif 200 #else 201 static void reprotectRegion(void*, size_t, ProtectionSeting) {} 202 #endif 203 204 static void cacheFlush(void* code, size_t size) 205 { 206 #if PLATFORM(X86) || PLATFORM(X86_64) 207 UNUSED_PARAM(code); 208 UNUSED_PARAM(size); 209 #elif PLATFORM(ARM_V7) && PLATFORM(IPHONE) 210 sys_dcache_flush(code, size); 211 sys_icache_invalidate(code, size); 212 #else 213 #error "ExecutableAllocator::cacheFlush not implemented on this platform." 214 #endif 215 } 187 216 188 217 RefPtr<ExecutablePool> m_smallAllocationPool; -
trunk/JavaScriptCore/wtf/Platform.h
r44511 r44514 229 229 #endif 230 230 #endif 231 #if defined(__ARM_ARCH_7A__) 232 #define WTF_PLATFORM_ARM_V7 1 233 #endif 231 234 232 235 /* PLATFORM(X86) */ … … 556 559 #if (!defined(ENABLE_YARR_JIT) && PLATFORM(X86) && PLATFORM(MAC)) \ 557 560 || (!defined(ENABLE_YARR_JIT) && PLATFORM(X86_64) && PLATFORM(MAC)) \ 561 /* Under development, temporarily disabled until 16Mb link range limit in assembler is fixed. */ \ 562 || (!defined(ENABLE_YARR_JIT) && PLATFORM(ARM_V7) && PLATFORM(IPHONE) && 0) \ 558 563 || (!defined(ENABLE_YARR_JIT) && PLATFORM(X86) && PLATFORM(WIN)) 559 564 #define ENABLE_YARR 1 … … 570 575 /* Setting this flag prevents the assembler from using RWX memory; this may improve 571 576 security but currectly comes at a significant performance cost. */ 577 #if PLATFORM(ARM_V7) && PLATFORM(IPHONE) 578 #define ENABLE_ASSEMBLER_WX_EXCLUSIVE 1 579 #else 572 580 #define ENABLE_ASSEMBLER_WX_EXCLUSIVE 0 581 #endif 573 582 574 583 #if !defined(ENABLE_PAN_SCROLLING) && PLATFORM(WIN_OS) -
trunk/JavaScriptCore/yarr/RegexJIT.cpp
r44477 r44514 44 44 friend void jitCompileRegex(JSGlobalData* globalData, RegexCodeBlock& jitObject, const UString& pattern, unsigned& numSubpatterns, const char*& error, bool ignoreCase, bool multiline); 45 45 46 #if PLATFORM(ARM_V7) 47 static const RegisterID input = ARM::r0; 48 static const RegisterID index = ARM::r1; 49 static const RegisterID length = ARM::r2; 50 51 static const RegisterID output = ARM::r4; 52 static const RegisterID regT0 = ARM::r5; 53 static const RegisterID regT1 = ARM::r6; 54 55 static const RegisterID returnRegister = ARM::r0; 56 #endif 46 57 #if PLATFORM(X86) 47 58 static const RegisterID input = X86::eax; … … 1279 1290 void generateEnter() 1280 1291 { 1281 // On x86 edi & esi are callee preserved registers. 1292 #if PLATFORM(X86_64) 1282 1293 push(X86::ebp); 1283 1294 move(stackPointerRegister, X86::ebp); 1284 #if PLATFORM(X86) 1295 #elif PLATFORM(X86) 1296 push(X86::ebp); 1297 move(stackPointerRegister, X86::ebp); 1285 1298 // TODO: do we need spill registers to fill the output pointer if there are no sub captures? 1286 1299 push(X86::ebx); … … 1288 1301 push(X86::esi); 1289 1302 // load output into edi (2 = saved ebp + return address). 1290 #if COMPILER(MSVC)1303 #if COMPILER(MSVC) 1291 1304 loadPtr(Address(X86::ebp, 2 * sizeof(void*)), input); 1292 1305 loadPtr(Address(X86::ebp, 3 * sizeof(void*)), index); 1293 1306 loadPtr(Address(X86::ebp, 4 * sizeof(void*)), length); 1294 1307 loadPtr(Address(X86::ebp, 5 * sizeof(void*)), output); 1295 #else1308 #else 1296 1309 loadPtr(Address(X86::ebp, 2 * sizeof(void*)), output); 1310 #endif 1311 #elif PLATFORM(ARM_V7) 1312 push(ARM::r4); 1313 push(ARM::r5); 1314 push(ARM::r6); 1315 move(ARM::r3, output); 1297 1316 #endif 1298 #endif1299 1317 } 1300 1318 1301 1319 void generateReturn() 1302 1320 { 1303 #if PLATFORM(X86) 1321 #if PLATFORM(X86_64) 1322 pop(X86::ebp); 1323 #elif PLATFORM(X86) 1304 1324 pop(X86::esi); 1305 1325 pop(X86::edi); 1306 1326 pop(X86::ebx); 1327 pop(X86::ebp); 1328 #elif PLATFORM(ARM_V7) 1329 pop(ARM::r6); 1330 pop(ARM::r5); 1331 pop(ARM::r4); 1307 1332 #endif 1308 pop(X86::ebp);1309 1333 ret(); 1310 1334 }
Note:
See TracChangeset
for help on using the changeset viewer.