Changeset 213753 in webkit


Ignore:
Timestamp:
Mar 10, 2017 11:17:48 PM (7 years ago)
Author:
fpizlo@apple.com
Message:

The JITs should be able to emit fast TLS loads
https://bugs.webkit.org/show_bug.cgi?id=169483

Reviewed by Keith Miller.

Source/JavaScriptCore:

Added loadFromTLS32/64/Ptr to the MacroAssembler and added a B3 test for this.

  • assembler/ARM64Assembler.h:

(JSC::ARM64Assembler::mrs_TPIDRRO_EL0):

  • assembler/MacroAssembler.h:

(JSC::MacroAssembler::loadFromTLSPtr):

  • assembler/MacroAssemblerARM64.h:

(JSC::MacroAssemblerARM64::loadFromTLS32):
(JSC::MacroAssemblerARM64::loadFromTLS64):

  • assembler/MacroAssemblerX86Common.h:

(JSC::MacroAssemblerX86Common::loadFromTLS32):

  • assembler/MacroAssemblerX86_64.h:

(JSC::MacroAssemblerX86_64::loadFromTLS64):

  • assembler/X86Assembler.h:

(JSC::X86Assembler::adcl_im):
(JSC::X86Assembler::addl_mr):
(JSC::X86Assembler::addl_im):
(JSC::X86Assembler::andl_im):
(JSC::X86Assembler::orl_im):
(JSC::X86Assembler::orl_rm):
(JSC::X86Assembler::subl_im):
(JSC::X86Assembler::cmpb_im):
(JSC::X86Assembler::cmpl_rm):
(JSC::X86Assembler::cmpl_im):
(JSC::X86Assembler::testb_im):
(JSC::X86Assembler::movb_i8m):
(JSC::X86Assembler::movb_rm):
(JSC::X86Assembler::movl_mr):
(JSC::X86Assembler::movq_mr):
(JSC::X86Assembler::movsxd_rr):
(JSC::X86Assembler::gs):
(JSC::X86Assembler::X86InstructionFormatter::SingleInstructionBufferWriter::memoryModRM):

  • b3/testb3.cpp:

(JSC::B3::testFastTLS):
(JSC::B3::run):

Source/WTF:

Consolidated what we know about fast TLS in FastTLS.h.

  • WTF.xcodeproj/project.pbxproj:
  • wtf/CMakeLists.txt:
  • wtf/FastTLS.h: Added.

(WTF::loadFastTLS):
(WTF::fastTLSOffsetForKey):

  • wtf/Platform.h:
  • wtf/WTFThreadData.cpp:

(WTF::WTFThreadData::createAndRegisterForGetspecificDirect):

  • wtf/WTFThreadData.h:

(WTF::wtfThreadData):

Location:
trunk/Source
Files:
1 added
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r213752 r213753  
     12017-03-10  Filip Pizlo  <fpizlo@apple.com>
     2
     3        The JITs should be able to emit fast TLS loads
     4        https://bugs.webkit.org/show_bug.cgi?id=169483
     5
     6        Reviewed by Keith Miller.
     7       
     8        Added loadFromTLS32/64/Ptr to the MacroAssembler and added a B3 test for this.
     9
     10        * assembler/ARM64Assembler.h:
     11        (JSC::ARM64Assembler::mrs_TPIDRRO_EL0):
     12        * assembler/MacroAssembler.h:
     13        (JSC::MacroAssembler::loadFromTLSPtr):
     14        * assembler/MacroAssemblerARM64.h:
     15        (JSC::MacroAssemblerARM64::loadFromTLS32):
     16        (JSC::MacroAssemblerARM64::loadFromTLS64):
     17        * assembler/MacroAssemblerX86Common.h:
     18        (JSC::MacroAssemblerX86Common::loadFromTLS32):
     19        * assembler/MacroAssemblerX86_64.h:
     20        (JSC::MacroAssemblerX86_64::loadFromTLS64):
     21        * assembler/X86Assembler.h:
     22        (JSC::X86Assembler::adcl_im):
     23        (JSC::X86Assembler::addl_mr):
     24        (JSC::X86Assembler::addl_im):
     25        (JSC::X86Assembler::andl_im):
     26        (JSC::X86Assembler::orl_im):
     27        (JSC::X86Assembler::orl_rm):
     28        (JSC::X86Assembler::subl_im):
     29        (JSC::X86Assembler::cmpb_im):
     30        (JSC::X86Assembler::cmpl_rm):
     31        (JSC::X86Assembler::cmpl_im):
     32        (JSC::X86Assembler::testb_im):
     33        (JSC::X86Assembler::movb_i8m):
     34        (JSC::X86Assembler::movb_rm):
     35        (JSC::X86Assembler::movl_mr):
     36        (JSC::X86Assembler::movq_mr):
     37        (JSC::X86Assembler::movsxd_rr):
     38        (JSC::X86Assembler::gs):
     39        (JSC::X86Assembler::X86InstructionFormatter::SingleInstructionBufferWriter::memoryModRM):
     40        * b3/testb3.cpp:
     41        (JSC::B3::testFastTLS):
     42        (JSC::B3::run):
     43
    1442017-03-10  Alex Christensen  <achristensen@webkit.org>
    245
  • trunk/Source/JavaScriptCore/assembler/ARM64Assembler.h

    r213714 r213753  
    15891589        insn(exoticStore(MEMOPSIZE, ExoticStoreFence_Release, result, src, dst));
    15901590    }
     1591   
     1592#if ENABLE(FAST_TLS_JIT)
     1593    void mrs_TPIDRRO_EL0(RegisterID dst)
     1594    {
     1595        insn(0xd53bd060 | dst); // Thanks, otool -t!
     1596    }
     1597#endif
    15911598
    15921599    template<int datasize>
  • trunk/Source/JavaScriptCore/assembler/MacroAssembler.h

    r213714 r213753  
    628628    }
    629629
     630#if ENABLE(FAST_TLS_JIT)
     631    void loadFromTLSPtr(uint32_t offset, RegisterID dst)
     632    {
     633        loadFromTLS32(offset, dst);
     634    }
     635#endif
     636
    630637    DataLabel32 loadPtrWithAddressOffsetPatch(Address address, RegisterID dest)
    631638    {
     
    934941        load64(address, dest);
    935942    }
     943
     944#if ENABLE(FAST_TLS_JIT)
     945    void loadFromTLSPtr(uint32_t offset, RegisterID dst)
     946    {
     947        loadFromTLS64(offset, dst);
     948    }
     949#endif
    936950
    937951    DataLabel32 loadPtrWithAddressOffsetPatch(Address address, RegisterID dest)
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerARM64.h

    r213714 r213753  
    35993599    }
    36003600   
     3601#if ENABLE(FAST_TLS_JIT)
     3602    // This will use scratch registers if the offset is not legal.
     3603   
     3604    void loadFromTLS32(uint32_t offset, RegisterID dst)
     3605    {
     3606        m_assembler.mrs_TPIDRRO_EL0(dst);
     3607        and64(TrustedImm32(~7), dst);
     3608        load32(Address(dst, offset), dst);
     3609    }
     3610   
     3611    void loadFromTLS64(uint32_t offset, RegisterID dst)
     3612    {
     3613        m_assembler.mrs_TPIDRRO_EL0(dst);
     3614        and64(TrustedImm32(~7), dst);
     3615        load64(Address(dst, offset), dst);
     3616    }
     3617#endif // ENABLE(FAST_TLS_JIT)
     3618   
    36013619    // Misc helper functions.
    36023620
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h

    r213714 r213753  
    38583858    {
    38593859    }
     3860   
     3861#if ENABLE(FAST_TLS_JIT)
     3862    void loadFromTLS32(uint32_t offset, RegisterID dst)
     3863    {
     3864        m_assembler.gs();
     3865        m_assembler.movl_mr(offset, dst);
     3866    }
     3867#endif
    38603868
    38613869    static void replaceWithBreakpoint(CodeLocationLabel instructionStart)
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h

    r213714 r213753  
    17021702    }
    17031703   
     1704#if ENABLE(FAST_TLS_JIT)
     1705    void loadFromTLS64(uint32_t offset, RegisterID dst)
     1706    {
     1707        m_assembler.gs();
     1708        m_assembler.movl_mr(offset, dst);
     1709    }
     1710#endif
     1711
    17041712    void truncateDoubleToUint32(FPRegisterID src, RegisterID dest)
    17051713    {
  • trunk/Source/JavaScriptCore/assembler/X86Assembler.h

    r213714 r213753  
    219219        OP_MOVSXD_GvEv                  = 0x63,
    220220#endif
     221        PRE_GS                          = 0x65,
    221222        PRE_OPERAND_SIZE                = 0x66,
    222223        PRE_SSE_66                      = 0x66,
     
    432433    {
    433434        if (CAN_SIGN_EXTEND_8_32(imm)) {
    434             m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADC, addr);
    435             m_formatter.immediate8(imm);
    436         } else {
    437             m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADC, addr);
     435            m_formatter.oneByteOpAddr(OP_GROUP1_EvIb, GROUP1_OP_ADC, bitwise_cast<uint32_t>(addr));
     436            m_formatter.immediate8(imm);
     437        } else {
     438            m_formatter.oneByteOpAddr(OP_GROUP1_EvIz, GROUP1_OP_ADC, bitwise_cast<uint32_t>(addr));
    438439            m_formatter.immediate32(imm);
    439440        }
     
    459460    void addl_mr(const void* addr, RegisterID dst)
    460461    {
    461         m_formatter.oneByteOp(OP_ADD_GvEv, dst, addr);
     462        m_formatter.oneByteOpAddr(OP_ADD_GvEv, dst, bitwise_cast<uint32_t>(addr));
    462463    }
    463464#endif
     
    632633    {
    633634        if (CAN_SIGN_EXTEND_8_32(imm)) {
    634             m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADD, addr);
    635             m_formatter.immediate8(imm);
    636         } else {
    637             m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADD, addr);
     635            m_formatter.oneByteOpAddr(OP_GROUP1_EvIb, GROUP1_OP_ADD, bitwise_cast<uint32_t>(addr));
     636            m_formatter.immediate8(imm);
     637        } else {
     638            m_formatter.oneByteOpAddr(OP_GROUP1_EvIz, GROUP1_OP_ADD, bitwise_cast<uint32_t>(addr));
    638639            m_formatter.immediate32(imm);
    639640        }
     
    819820    {
    820821        if (CAN_SIGN_EXTEND_8_32(imm)) {
    821             m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_AND, addr);
    822             m_formatter.immediate8(imm);
    823         } else {
    824             m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_AND, addr);
     822            m_formatter.oneByteOpAddr(OP_GROUP1_EvIb, GROUP1_OP_AND, bitwise_cast<uint32_t>(addr));
     823            m_formatter.immediate8(imm);
     824        } else {
     825            m_formatter.oneByteOpAddr(OP_GROUP1_EvIz, GROUP1_OP_AND, bitwise_cast<uint32_t>(addr));
    825826            m_formatter.immediate32(imm);
    826827        }
     
    11601161    {
    11611162        if (CAN_SIGN_EXTEND_8_32(imm)) {
    1162             m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_OR, addr);
    1163             m_formatter.immediate8(imm);
    1164         } else {
    1165             m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_OR, addr);
     1163            m_formatter.oneByteOpAddr(OP_GROUP1_EvIb, GROUP1_OP_OR, bitwise_cast<uint32_t>(addr));
     1164            m_formatter.immediate8(imm);
     1165        } else {
     1166            m_formatter.oneByteOpAddr(OP_GROUP1_EvIz, GROUP1_OP_OR, bitwise_cast<uint32_t>(addr));
    11661167            m_formatter.immediate32(imm);
    11671168        }
     
    11701171    void orl_rm(RegisterID src, const void* addr)
    11711172    {
    1172         m_formatter.oneByteOp(OP_OR_EvGv, src, addr);
     1173        m_formatter.oneByteOpAddr(OP_OR_EvGv, src, bitwise_cast<uint32_t>(addr));
    11731174    }
    11741175#endif
     
    13581359    {
    13591360        if (CAN_SIGN_EXTEND_8_32(imm)) {
    1360             m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_SUB, addr);
    1361             m_formatter.immediate8(imm);
    1362         } else {
    1363             m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_SUB, addr);
     1361            m_formatter.oneByteOpAddr(OP_GROUP1_EvIb, GROUP1_OP_SUB, bitwise_cast<uint32_t>(addr));
     1362            m_formatter.immediate8(imm);
     1363        } else {
     1364            m_formatter.oneByteOpAddr(OP_GROUP1_EvIz, GROUP1_OP_SUB, bitwise_cast<uint32_t>(addr));
    13641365            m_formatter.immediate32(imm);
    13651366        }
     
    18581859    void cmpb_im(int imm, const void* addr)
    18591860    {
    1860         m_formatter.oneByteOp(OP_GROUP1_EbIb, GROUP1_OP_CMP, addr);
     1861        m_formatter.oneByteOpAddr(OP_GROUP1_EbIb, GROUP1_OP_CMP, bitwise_cast<uint32_t>(addr));
    18611862        m_formatter.immediate8(imm);
    18621863    }
     
    19391940    void cmpl_rm(RegisterID reg, const void* addr)
    19401941    {
    1941         m_formatter.oneByteOp(OP_CMP_EvGv, reg, addr);
     1942        m_formatter.oneByteOpAddr(OP_CMP_EvGv, reg, bitwise_cast<uint32_t>(addr));
    19421943    }
    19431944
     
    19451946    {
    19461947        if (CAN_SIGN_EXTEND_8_32(imm)) {
    1947             m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, addr);
    1948             m_formatter.immediate8(imm);
    1949         } else {
    1950             m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, addr);
     1948            m_formatter.oneByteOpAddr(OP_GROUP1_EvIb, GROUP1_OP_CMP, bitwise_cast<uint32_t>(addr));
     1949            m_formatter.immediate8(imm);
     1950        } else {
     1951            m_formatter.oneByteOpAddr(OP_GROUP1_EvIz, GROUP1_OP_CMP, bitwise_cast<uint32_t>(addr));
    19511952            m_formatter.immediate32(imm);
    19521953        }
     
    20262027    void testb_im(int imm, const void* addr)
    20272028    {
    2028         m_formatter.oneByteOp(OP_GROUP3_EbIb, GROUP3_OP_TEST, addr);
     2029        m_formatter.oneByteOpAddr(OP_GROUP3_EbIb, GROUP3_OP_TEST, bitwise_cast<uint32_t>(addr));
    20292030        m_formatter.immediate8(imm);
    20302031    }
     
    22802281    {
    22812282        ASSERT(-128 <= imm && imm < 128);
    2282         m_formatter.oneByteOp(OP_GROUP11_EvIb, GROUP11_MOV, addr);
     2283        m_formatter.oneByteOpAddr(OP_GROUP11_EvIb, GROUP11_MOV, bitwise_cast<uint32_t>(addr));
    22832284        m_formatter.immediate8(imm);
    22842285    }
     
    23022303    void movb_rm(RegisterID src, const void* addr)
    23032304    {
    2304         m_formatter.oneByteOp(OP_MOV_EbGb, src, addr);
     2305        m_formatter.oneByteOpAddr(OP_MOV_EbGb, src, bitwise_cast<uint32_t>(addr));
    23052306    }
    23062307#endif
     
    23552356    }
    23562357
     2358    void movl_mr(uint32_t addr, RegisterID dst)
     2359    {
     2360        m_formatter.oneByteOpAddr(OP_MOV_GvEv, dst, addr);
     2361    }
     2362
    23572363#if CPU(X86_64)
    23582364    void movq_rr(RegisterID src, RegisterID dst)
     
    24082414    }
    24092415
     2416    void movq_mr(uint32_t addr, RegisterID dst)
     2417    {
     2418        m_formatter.oneByteOp64Addr(OP_MOV_GvEv, dst, addr);
     2419    }
     2420
    24102421    void movq_i32m(int imm, int offset, RegisterID base)
    24112422    {
     
    24362447        m_formatter.oneByteOp64(OP_MOVSXD_GvEv, dst, src);
    24372448    }
    2438    
    2439    
    24402449#else
     2450    void movl_mr(const void* addr, RegisterID dst)
     2451    {
     2452        if (dst == X86Registers::eax)
     2453            movl_mEAX(addr);
     2454        else
     2455            m_formatter.oneByteOpAddr(OP_MOV_GvEv, dst, bitwise_cast<uint32_t>(addr));
     2456    }
     2457
    24412458    void movl_rm(RegisterID src, const void* addr)
    24422459    {
     
    24442461            movl_EAXm(addr);
    24452462        else
    2446             m_formatter.oneByteOp(OP_MOV_EvGv, src, addr);
    2447     }
    2448    
    2449     void movl_mr(const void* addr, RegisterID dst)
    2450     {
    2451         if (dst == X86Registers::eax)
    2452             movl_mEAX(addr);
    2453         else
    2454             m_formatter.oneByteOp(OP_MOV_GvEv, dst, addr);
    2455     }
    2456 
     2463            m_formatter.oneByteOpAddr(OP_MOV_EvGv, src, bitwise_cast<uint32_t>(addr));
     2464    }
     2465   
    24572466    void movl_i32m(int imm, const void* addr)
    24582467    {
    2459         m_formatter.oneByteOp(OP_GROUP11_EvIz, GROUP11_MOV, addr);
     2468        m_formatter.oneByteOpAddr(OP_GROUP11_EvIz, GROUP11_MOV, bitwise_cast<uint32_t>(addr));
    24602469        m_formatter.immediate32(imm);
    24612470    }
     
    24952504    void movzbl_mr(const void* address, RegisterID dst)
    24962505    {
    2497         m_formatter.twoByteOp(OP2_MOVZX_GvEb, dst, address);
     2506        m_formatter.twoByteOpAddr(OP2_MOVZX_GvEb, dst, bitwise_cast<uint32_t>(address));
    24982507    }
    24992508#endif
     
    26052614    void cmovl_mr(Condition cond, const void* addr, RegisterID dst)
    26062615    {
    2607         m_formatter.twoByteOp(cmovcc(cond), dst, addr);
     2616        m_formatter.twoByteOpAddr(cmovcc(cond), dst, bitwise_cast<uint32_t>(addr));
    26082617    }
    26092618#endif
     
    26782687    void jmp_m(const void* address)
    26792688    {
    2680         m_formatter.oneByteOp(OP_GROUP5_Ev, GROUP5_OP_JMPN, address);
     2689        m_formatter.oneByteOpAddr(OP_GROUP5_Ev, GROUP5_OP_JMPN, bitwise_cast<uint32_t>(address));
    26812690    }
    26822691#endif
     
    28542863    {
    28552864        m_formatter.prefix(PRE_SSE_F2);
    2856         m_formatter.twoByteOp(OP2_ADDSD_VsdWsd, (RegisterID)dst, address);
     2865        m_formatter.twoByteOpAddr(OP2_ADDSD_VsdWsd, (RegisterID)dst, bitwise_cast<uint32_t>(address));
    28572866    }
    28582867#endif
     
    29122921    {
    29132922        m_formatter.prefix(PRE_SSE_F2);
    2914         m_formatter.twoByteOp(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, address);
     2923        m_formatter.twoByteOpAddr(OP2_CVTSI2SD_VsdEd, (RegisterID)dst, bitwise_cast<uint32_t>(address));
    29152924    }
    29162925#endif
     
    30693078    {
    30703079        m_formatter.prefix(PRE_SSE_F2);
    3071         m_formatter.twoByteOp(OP2_MOVSD_VsdWsd, (RegisterID)dst, address);
     3080        m_formatter.twoByteOpAddr(OP2_MOVSD_VsdWsd, (RegisterID)dst, bitwise_cast<uint32_t>(address));
    30723081    }
    30733082    void movsd_rm(XMMRegisterID src, const void* address)
    30743083    {
    30753084        m_formatter.prefix(PRE_SSE_F2);
    3076         m_formatter.twoByteOp(OP2_MOVSD_WsdVsd, (RegisterID)src, address);
     3085        m_formatter.twoByteOpAddr(OP2_MOVSD_WsdVsd, (RegisterID)src, bitwise_cast<uint32_t>(address));
    30773086    }
    30783087#endif
     
    33993408    {
    34003409        m_formatter.prefix(PRE_LOCK);
     3410    }
     3411   
     3412    // Causes the memory access in the next instruction to be offset by %gs. Usually you use
     3413    // this with a 32-bit absolute address load. That "address" ends up being the offset to
     3414    // %gs. This prefix is ignored by lea. Getting the value of %gs is hard - you can pretty
     3415    // much just use it as a secret offset.
     3416    void gs()
     3417    {
     3418        m_formatter.prefix(PRE_GS);
    34013419    }
    34023420   
     
    40544072            }
    40554073
    4056 #if !CPU(X86_64)
    4057             ALWAYS_INLINE void memoryModRM(int reg, const void* address)
     4074            ALWAYS_INLINE void memoryModRMAddr(int reg, uint32_t address)
    40584075            {
     4076#if CPU(X86_64)
     4077                putModRmSib(ModRmMemoryNoDisp, reg, noBase, noIndex, 0);
     4078#else
    40594079                // noBase + ModRmMemoryNoDisp means noBase + ModRmMemoryDisp32!
    40604080                putModRm(ModRmMemoryNoDisp, reg, noBase);
    4061                 putIntUnchecked(reinterpret_cast<int32_t>(address));
     4081#endif
     4082                putIntUnchecked(address);
    40624083            }
    4063 #endif
     4084
    40644085            ALWAYS_INLINE void twoBytesVex(OneByteOpcodeID simdPrefix, RegisterID inOpReg, RegisterID r)
    40654086            {
     
    41864207        }
    41874208
    4188 #if !CPU(X86_64)
    4189         void oneByteOp(OneByteOpcodeID opcode, int reg, const void* address)
     4209        void oneByteOpAddr(OneByteOpcodeID opcode, int reg, uint32_t address)
    41904210        {
    41914211            SingleInstructionBufferWriter writer(m_buffer);
    41924212            writer.putByteUnchecked(opcode);
    4193             writer.memoryModRM(reg, address);
    4194         }
    4195 #endif
     4213            writer.memoryModRMAddr(reg, address);
     4214        }
    41964215
    41974216        void twoByteOp(TwoByteOpcodeID opcode)
     
    42294248        }
    42304249
    4231 #if !CPU(X86_64)
    4232         void twoByteOp(TwoByteOpcodeID opcode, int reg, const void* address)
     4250        void twoByteOpAddr(TwoByteOpcodeID opcode, int reg, uint32_t address)
    42334251        {
    42344252            SingleInstructionBufferWriter writer(m_buffer);
    42354253            writer.putByteUnchecked(OP_2BYTE_ESCAPE);
    42364254            writer.putByteUnchecked(opcode);
    4237             writer.memoryModRM(reg, address);
    4238         }
    4239 #endif
     4255            writer.memoryModRMAddr(reg, address);
     4256        }
     4257
    42404258        void vexNdsLigWigTwoByteOp(OneByteOpcodeID simdPrefix, TwoByteOpcodeID opcode, RegisterID dest, RegisterID a, RegisterID b)
    42414259        {
     
    43664384            writer.putByteUnchecked(opcode);
    43674385            writer.memoryModRM(reg, base, index, scale, offset);
     4386        }
     4387
     4388        void oneByteOp64Addr(OneByteOpcodeID opcode, int reg, uint32_t address)
     4389        {
     4390            SingleInstructionBufferWriter writer(m_buffer);
     4391            writer.emitRexW(reg, 0, 0);
     4392            writer.putByteUnchecked(opcode);
     4393            writer.memoryModRMAddr(reg, address);
    43684394        }
    43694395
  • trunk/Source/JavaScriptCore/b3/testb3.cpp

    r213714 r213753  
    7070#include <cmath>
    7171#include <string>
     72#include <wtf/FastTLS.h>
    7273#include <wtf/ListDump.h>
    7374#include <wtf/Lock.h>
     
    1520915210    for (unsigned value : values)
    1521015211        CHECK_EQ(numToStore, value);
     15212}
     15213
     15214void testFastTLS()
     15215{
     15216#if ENABLE(FAST_TLS_JIT)
     15217    _pthread_setspecific_direct(WTF_TESTING_KEY, bitwise_cast<void*>(static_cast<uintptr_t>(0xbeef)));
     15218   
     15219    Procedure proc;
     15220    BasicBlock* root = proc.addBlock();
     15221   
     15222    PatchpointValue* patchpoint = root->appendNew<PatchpointValue>(proc, pointerType(), Origin());
     15223    patchpoint->clobber(RegisterSet::macroScratchRegisters());
     15224    patchpoint->setGenerator(
     15225        [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
     15226            AllowMacroScratchRegisterUsage allowScratch(jit);
     15227            jit.loadFromTLSPtr(fastTLSOffsetForKey(WTF_TESTING_KEY), params[0].gpr());
     15228        });
     15229   
     15230    root->appendNew<Value>(proc, Return, Origin(), patchpoint);
     15231   
     15232    CHECK_EQ(compileAndRun<uintptr_t>(proc), static_cast<uintptr_t>(0xbeef));
     15233#endif
    1521115234}
    1521215235
     
    1673716760    RUN(testWasmBoundsCheck(std::numeric_limits<unsigned>::max() - 5));
    1673816761    RUN(testWasmAddress());
     16762   
     16763    RUN(testFastTLS());
    1673916764
    1674016765    if (isX86()) {
  • trunk/Source/WTF/ChangeLog

    r213743 r213753  
     12017-03-10  Filip Pizlo  <fpizlo@apple.com>
     2
     3        The JITs should be able to emit fast TLS loads
     4        https://bugs.webkit.org/show_bug.cgi?id=169483
     5
     6        Reviewed by Keith Miller.
     7       
     8        Consolidated what we know about fast TLS in FastTLS.h.
     9
     10        * WTF.xcodeproj/project.pbxproj:
     11        * wtf/CMakeLists.txt:
     12        * wtf/FastTLS.h: Added.
     13        (WTF::loadFastTLS):
     14        (WTF::fastTLSOffsetForKey):
     15        * wtf/Platform.h:
     16        * wtf/WTFThreadData.cpp:
     17        (WTF::WTFThreadData::createAndRegisterForGetspecificDirect):
     18        * wtf/WTFThreadData.h:
     19        (WTF::wtfThreadData):
     20
    1212017-03-10  Mark Lam  <mark.lam@apple.com>
    222
  • trunk/Source/WTF/WTF.xcodeproj/project.pbxproj

    r213214 r213753  
    4444                0F66B2931DC97BAB004A1D3F /* WallTime.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F66B2891DC97BAB004A1D3F /* WallTime.h */; };
    4545                0F725CAC1C50461600AD943A /* RangeSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F725CAB1C50461600AD943A /* RangeSet.h */; };
     46                0F79C7C41E73511800EB34D1 /* FastTLS.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F79C7C31E73511800EB34D1 /* FastTLS.h */; };
    4647                0F7C5FB61D885CF20044F5E2 /* FastBitVector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F7C5FB51D885CF20044F5E2 /* FastBitVector.cpp */; };
    4748                0F824A681B7443A0002E345D /* ParkingLot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F824A641B7443A0002E345D /* ParkingLot.cpp */; };
     
    422423                0F66B2891DC97BAB004A1D3F /* WallTime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WallTime.h; sourceTree = "<group>"; };
    423424                0F725CAB1C50461600AD943A /* RangeSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RangeSet.h; sourceTree = "<group>"; };
     425                0F79C7C31E73511800EB34D1 /* FastTLS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FastTLS.h; sourceTree = "<group>"; };
    424426                0F7C5FB51D885CF20044F5E2 /* FastBitVector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FastBitVector.cpp; sourceTree = "<group>"; };
    425427                0F824A641B7443A0002E345D /* ParkingLot.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParkingLot.cpp; sourceTree = "<group>"; };
     
    975977                                A8A472A1151A825A004123FF /* FastMalloc.cpp */,
    976978                                A8A472A2151A825A004123FF /* FastMalloc.h */,
     979                                0F79C7C31E73511800EB34D1 /* FastTLS.h */,
    977980                                B38FD7BC168953E80065C969 /* FeatureDefines.h */,
    978981                                0F9D335B165DBA73005AD387 /* FilePrintStream.cpp */,
     
    14871490                                A8A473EF151A825B004123FF /* Noncopyable.h in Headers */,
    14881491                                CE46516E19DB1FB4003ECA05 /* NSMapTableSPI.h in Headers */,
     1492                                0F79C7C41E73511800EB34D1 /* FastTLS.h in Headers */,
    14891493                                A8A473F5151A825B004123FF /* NumberOfCores.h in Headers */,
    14901494                                7E29C33E15FFD79B00516D61 /* ObjcRuntimeExtras.h in Headers */,
  • trunk/Source/WTF/wtf/CMakeLists.txt

    r213214 r213753  
    3131    DoublyLinkedList.h
    3232    FastMalloc.h
     33    FastTLS.h
    3334    FeatureDefines.h
    3435    FilePrintStream.h
  • trunk/Source/WTF/wtf/Platform.h

    r213743 r213753  
    762762#endif // CPU(ARM64)
    763763
     764#if __has_include(<System/pthread_machdep.h>)
     765#define HAVE_FAST_TLS 1
     766#endif
     767
     768#if (CPU(X86_64) || CPU(ARM64)) && HAVE(FAST_TLS)
     769#define ENABLE_FAST_TLS_JIT 1
     770#endif
     771
    764772/* This controls whether B3 is built. B3 is needed for FTL JIT and WebAssembly */
    765773#if ENABLE(FTL_JIT) || ENABLE(WEBASSEMBLY)
  • trunk/Source/WTF/wtf/WTFThreadData.cpp

    r187026 r213753  
    3636namespace WTF {
    3737
    38 #if !USE(PTHREAD_GETSPECIFIC_DIRECT)
     38#if !HAVE(FAST_TLS)
    3939ThreadSpecific<WTFThreadData>* WTFThreadData::staticData;
    4040#endif
     
    6262}
    6363
    64 #if USE(PTHREAD_GETSPECIFIC_DIRECT)
     64#if HAVE(FAST_TLS)
    6565WTFThreadData& WTFThreadData::createAndRegisterForGetspecificDirect()
    6666{
    6767    WTFThreadData* data = new WTFThreadData;
    68     _pthread_setspecific_direct(directKey, data);
    69     pthread_key_init_np(directKey, [](void* data){
     68    _pthread_setspecific_direct(WTF_THREAD_DATA_KEY, data);
     69    pthread_key_init_np(WTF_THREAD_DATA_KEY, [](void* data){
    7070        delete static_cast<WTFThreadData*>(data);
    7171    });
  • trunk/Source/WTF/wtf/WTFThreadData.h

    r205895 r213753  
    11/*
    2  * Copyright (C) 2008 Apple Inc. All Rights Reserved.
     2 * Copyright (C) 2008-2017 Apple Inc. All Rights Reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2828#define WTFThreadData_h
    2929
     30#include <wtf/FastTLS.h>
    3031#include <wtf/HashMap.h>
    3132#include <wtf/HashSet.h>
     
    3334#include <wtf/StackBounds.h>
    3435#include <wtf/StackStats.h>
    35 #include <wtf/text/StringHash.h>
    36 
    37 #if USE(APPLE_INTERNAL_SDK)
    38 #include <System/pthread_machdep.h>
    39 #endif
    40 
    41 #if defined(__PTK_FRAMEWORK_JAVASCRIPTCORE_KEY1)
    42 #define USE_PTHREAD_GETSPECIFIC_DIRECT 1
    43 #endif
    44 
    45 #if !USE(PTHREAD_GETSPECIFIC_DIRECT)
    4636#include <wtf/ThreadSpecific.h>
    4737#include <wtf/Threading.h>
    48 #endif
     38#include <wtf/text/StringHash.h>
    4939
    5040namespace WTF {
     
    123113    void* m_savedLastStackTop;
    124114
    125 #if USE(PTHREAD_GETSPECIFIC_DIRECT)
    126     static const pthread_key_t directKey = __PTK_FRAMEWORK_JAVASCRIPTCORE_KEY1;
     115#if HAVE(FAST_TLS)
    127116    WTF_EXPORT_PRIVATE static WTFThreadData& createAndRegisterForGetspecificDirect();
    128117#else
     
    142131    //    wtfThreadData() is initially called from initializeThreading(), ensuring
    143132    //    this is initially called in a pthread_once locked context.
    144 #if !USE(PTHREAD_GETSPECIFIC_DIRECT)
     133#if !HAVE(FAST_TLS)
    145134    if (!WTFThreadData::staticData)
    146135        WTFThreadData::staticData = new ThreadSpecific<WTFThreadData>;
    147136    return **WTFThreadData::staticData;
    148137#else
    149     if (WTFThreadData* data = static_cast<WTFThreadData*>(_pthread_getspecific_direct(WTFThreadData::directKey)))
     138    if (WTFThreadData* data = static_cast<WTFThreadData*>(_pthread_getspecific_direct(WTF_THREAD_DATA_KEY)))
    150139        return *data;
    151140    return WTFThreadData::createAndRegisterForGetspecificDirect();
Note: See TracChangeset for help on using the changeset viewer.