Source/JavaScriptCore/ChangeLog

 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 NOBODY (OOPS!).
 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
346 Fix CMake build.
213728

Source/JavaScriptCore/assembler/ARM64Assembler.h

@@public:
15881588 CHECK_DATASIZE();
15891589 insn(exoticStore(MEMOPSIZE, ExoticStoreFence_Release, result, src, dst));
15901590 }
 1591
 1592#if ENABLE(FAST_TLS_JIT)
 1593 void mrs_TPIDRRO_EL0(RegiterID dst)
 1594 {
 1595 insn(d53bd060 | dst);
 1596 }
 1597#endif
15911598
15921599 template<int datasize>
15931600 ALWAYS_INLINE void orn(RegisterID rd, RegisterID rn, RegisterID rm)
213724

Source/JavaScriptCore/assembler/MacroAssembler.h

@@public:
627627 load32(address, dest);
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 {
632639 return load32WithAddressOffsetPatch(address, dest);

@@public:
934941 load64(address, dest);
935942 }
936943
 944#if ENABLE(FAST_TLS_JIT)
 945 void loadFromTLSPtr(uint32_t offset, RegisterID dst)
 946 {
 947 loadFromTLS64(offset, dst);
 948 }
 949#endif
 950
937951 DataLabel32 loadPtrWithAddressOffsetPatch(Address address, RegisterID dest)
938952 {
939953 return load64WithAddressOffsetPatch(address, dest);
213724

Source/JavaScriptCore/assembler/MacroAssemblerARM64.h

@@private:
42474247 RELEASE_ASSERT_NOT_REACHED();
42484248 }
42494249
 4250#if ENABLE(FAST_TLS_JIT)
 4251 // This will use scratch registers if the offset is not legal.
 4252
 4253 void loadFromTLS32(uint32_t offset, RegisterID dst)
 4254 {
 4255 m_assembler.mrs_TPIDRRO_EL0(dst);
 4256 and64(TrustedImm32(~7), dst);
 4257 load32(Address(offset, dst), dst);
 4258 }
 4259
 4260 void loadFromTLS64(uint32_t offset, RegisterID dst)
 4261 {
 4262 m_assembler.mrs_TPIDRRO_EL0(dst);
 4263 and64(TrustedImm32(~7), dst);
 4264 load64(Address(offset, dst), dst);
 4265 }
 4266#endif // ENABLE(FAST_TLS_JIT)
 4267
42504268 RegisterID extractSimpleAddress(ImplicitAddress address)
42514269 {
42524270 if (!address.offset)
213724

Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h

@@public:
38573857 void loadFence()
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)
38623870 {
213724

Source/JavaScriptCore/assembler/MacroAssemblerX86_64.h

@@public:
17011701 store64(imm, dest);
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 {
17061714 m_assembler.cvttsd2siq_rr(src, dest);
213724

Source/JavaScriptCore/assembler/X86Assembler.h

@@private:
218218#if CPU(X86_64)
219219 OP_MOVSXD_GvEv = 0x63,
220220#endif
 221 PRE_GS = 0x65,
221222 PRE_OPERAND_SIZE = 0x66,
222223 PRE_SSE_66 = 0x66,
223224 OP_PUSH_Iz = 0x68,

@@public:
431432 void adcl_im(int imm, const void* addr)
432433 {
433434 if (CAN_SIGN_EXTEND_8_32(imm)) {
434  m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADC, addr);
 435 m_formatter.oneByteOpAddr(OP_GROUP1_EvIb, GROUP1_OP_ADC, bitwise_cast<uint32_t>(addr));
435436 m_formatter.immediate8(imm);
436437 } else {
437  m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADC, addr);
 438 m_formatter.oneByteOpAddr(OP_GROUP1_EvIz, GROUP1_OP_ADC, bitwise_cast<uint32_t>(addr));
438439 m_formatter.immediate32(imm);
439440 }
440441 }

@@public:
458459#if !CPU(X86_64)
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
464465

@@public:
631632 void addl_im(int imm, const void* addr)
632633 {
633634 if (CAN_SIGN_EXTEND_8_32(imm)) {
634  m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_ADD, addr);
 635 m_formatter.oneByteOpAddr(OP_GROUP1_EvIb, GROUP1_OP_ADD, bitwise_cast<uint32_t>(addr));
635636 m_formatter.immediate8(imm);
636637 } else {
637  m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_ADD, addr);
 638 m_formatter.oneByteOpAddr(OP_GROUP1_EvIz, GROUP1_OP_ADD, bitwise_cast<uint32_t>(addr));
638639 m_formatter.immediate32(imm);
639640 }
640641 }

@@public:
818819 void andl_im(int imm, const void* addr)
819820 {
820821 if (CAN_SIGN_EXTEND_8_32(imm)) {
821  m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_AND, addr);
 822 m_formatter.oneByteOpAddr(OP_GROUP1_EvIb, GROUP1_OP_AND, bitwise_cast<uint32_t>(addr));
822823 m_formatter.immediate8(imm);
823824 } else {
824  m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_AND, addr);
 825 m_formatter.oneByteOpAddr(OP_GROUP1_EvIz, GROUP1_OP_AND, bitwise_cast<uint32_t>(addr));
825826 m_formatter.immediate32(imm);
826827 }
827828 }

@@public:
11591160 void orl_im(int imm, const void* addr)
11601161 {
11611162 if (CAN_SIGN_EXTEND_8_32(imm)) {
1162  m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_OR, addr);
 1163 m_formatter.oneByteOpAddr(OP_GROUP1_EvIb, GROUP1_OP_OR, bitwise_cast<uint32_t>(addr));
11631164 m_formatter.immediate8(imm);
11641165 } else {
1165  m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_OR, addr);
 1166 m_formatter.oneByteOpAddr(OP_GROUP1_EvIz, GROUP1_OP_OR, bitwise_cast<uint32_t>(addr));
11661167 m_formatter.immediate32(imm);
11671168 }
11681169 }
11691170
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
11751176

@@public:
13571358 void subl_im(int imm, const void* addr)
13581359 {
13591360 if (CAN_SIGN_EXTEND_8_32(imm)) {
1360  m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_SUB, addr);
 1361 m_formatter.oneByteOpAddr(OP_GROUP1_EvIb, GROUP1_OP_SUB, bitwise_cast<uint32_t>(addr));
13611362 m_formatter.immediate8(imm);
13621363 } else {
1363  m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_SUB, addr);
 1364 m_formatter.oneByteOpAddr(OP_GROUP1_EvIz, GROUP1_OP_SUB, bitwise_cast<uint32_t>(addr));
13641365 m_formatter.immediate32(imm);
13651366 }
13661367 }

@@public:
18571858#if CPU(X86)
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 }
18631864#endif

@@public:
19381939#else
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
19441945 void cmpl_im(int imm, const void* addr)
19451946 {
19461947 if (CAN_SIGN_EXTEND_8_32(imm)) {
1947  m_formatter.oneByteOp(OP_GROUP1_EvIb, GROUP1_OP_CMP, addr);
 1948 m_formatter.oneByteOpAddr(OP_GROUP1_EvIb, GROUP1_OP_CMP, bitwise_cast<uint32_t>(addr));
19481949 m_formatter.immediate8(imm);
19491950 } else {
1950  m_formatter.oneByteOp(OP_GROUP1_EvIz, GROUP1_OP_CMP, addr);
 1951 m_formatter.oneByteOpAddr(OP_GROUP1_EvIz, GROUP1_OP_CMP, bitwise_cast<uint32_t>(addr));
19511952 m_formatter.immediate32(imm);
19521953 }
19531954 }

@@public:
20252026#if CPU(X86)
20262027 void testb_im(int imm, const void* addr)
20272028 {
2028  m_formatter.oneByteOp(OP_GROUP3_EbIb, GROUP3_OP_TEST, addr);
 2029 m_formatter.oneByteOp64(OP_GROUP3_EbIb, GROUP3_OP_TEST, bitwise_cast<uint32_t>(addr));
20292030 m_formatter.immediate8(imm);
20302031 }
20312032#endif

@@public:
22792280 void movb_i8m(int imm, const void* addr)
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 }
22852286#endif

@@public:
23012302#if !CPU(X86_64)
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
23072308

@@public:
23542355#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)
23592365 {

@@public:
24072413 m_formatter.oneByteOp64(OP_MOV_GvEv, dst, base, index, scale, offset);
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 {
24122423 m_formatter.oneByteOp64(OP_GROUP11_EvIz, GROUP11_MOV, base, offset);

@@public:
24352446 {
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 {
24432460 if (src == X86Registers::eax)

@@public:
24462463 m_formatter.oneByteOp(OP_MOV_EvGv, src, addr);
24472464 }
24482465
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 
24572466 void movl_i32m(int imm, const void* addr)
24582467 {
24592468 m_formatter.oneByteOp(OP_GROUP11_EvIz, GROUP11_MOV, addr);

@@public:
34003409 m_formatter.prefix(PRE_LOCK);
34013410 }
34023411
 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);
 3419 }
 3420
34033421 void cmpxchgb_rm(RegisterID src, int offset, RegisterID base)
34043422 {
34053423 m_formatter.twoByteOp8(OP2_CMPXCHGb, src, base, offset);

@@private:
40534071 }
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 {
40594076 // noBase + ModRmMemoryNoDisp means noBase + ModRmMemoryDisp32!
40604077 putModRm(ModRmMemoryNoDisp, reg, noBase);
4061  putIntUnchecked(reinterpret_cast<int32_t>(address));
 4078 putIntUnchecked(address);
40624079 }
4063 #endif
 4080
40644081 ALWAYS_INLINE void twoBytesVex(OneByteOpcodeID simdPrefix, RegisterID inOpReg, RegisterID r)
40654082 {
40664083 putByteUnchecked(VexPrefix::TwoBytes);

@@private:
41854202 writer.memoryModRM(reg, base, index, scale, offset);
41864203 }
41874204
4188 #if !CPU(X86_64)
4189  void oneByteOp(OneByteOpcodeID opcode, int reg, const void* address)
 4205 void oneByteOpAddr(OneByteOpcodeID opcode, int reg, uint32_t address)
41904206 {
41914207 SingleInstructionBufferWriter writer(m_buffer);
41924208 writer.putByteUnchecked(opcode);
4193  writer.memoryModRM(reg, address);
 4209 writer.memoryModRMAddr(reg, address);
41944210 }
4195 #endif
41964211
41974212 void twoByteOp(TwoByteOpcodeID opcode)
41984213 {

@@private:
42284243 writer.memoryModRM(reg, base, index, scale, offset);
42294244 }
42304245
4231 #if !CPU(X86_64)
4232  void twoByteOp(TwoByteOpcodeID opcode, int reg, const void* address)
 4246 void twoByteOpAddr(TwoByteOpcodeID opcode, int reg, uint32_t address)
42334247 {
42344248 SingleInstructionBufferWriter writer(m_buffer);
42354249 writer.putByteUnchecked(OP_2BYTE_ESCAPE);
42364250 writer.putByteUnchecked(opcode);
4237  writer.memoryModRM(reg, address);
 4251 writer.memoryModRMAddr(reg, address);
42384252 }
4239 #endif
 4253
42404254 void vexNdsLigWigTwoByteOp(OneByteOpcodeID simdPrefix, TwoByteOpcodeID opcode, RegisterID dest, RegisterID a, RegisterID b)
42414255 {
42424256 SingleInstructionBufferWriter writer(m_buffer);

@@private:
43674381 writer.memoryModRM(reg, base, index, scale, offset);
43684382 }
43694383
 4384 void oneByteOp64Addr(OneByteOpcodeID opcode, int reg, uint32_t address)
 4385 {
 4386 SingleInstructionBufferWriter writer(m_buffer);
 4387 writer.emitRexW(reg, 0, 0);
 4388 writer.putByteUnchecked(opcode);
 4389 writer.memoryModRMAddr(reg, address);
 4390 }
 4391
43704392 void twoByteOp64(TwoByteOpcodeID opcode, int reg, RegisterID rm)
43714393 {
43724394 SingleInstructionBufferWriter writer(m_buffer);
213724

Source/JavaScriptCore/b3/testb3.cpp

6969#include "VM.h"
7070#include <cmath>
7171#include <string>
 72#include <wtf/FastTLS.h>
7273#include <wtf/ListDump.h>
7374#include <wtf/Lock.h>
7475#include <wtf/NumberOfCores.h>

@@void testWasmAddress()
1521015211 CHECK_EQ(numToStore, value);
1521115212}
1521215213
 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->append<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->append<Value>(proc, Return, Origin(), patchpoint);
 15231
 15232 CHECK_EQ(compileAndRun<uintptr_t>, static_cast<uintptr_t>(0xbeef));
 15233#endif
 15234}
 15235
1521315236// Make sure the compiler does not try to optimize anything out.
1521415237NEVER_INLINE double zero()
1521515238{

@@void run(const char* filter)
1673616759 RUN(testWasmBoundsCheck(10000));
1673716760 RUN(testWasmBoundsCheck(std::numeric_limits<unsigned>::max() - 5));
1673816761 RUN(testWasmAddress());
 16762
 16763 RUN(testFastTLS());
1673916764
1674016765 if (isX86()) {
1674116766 RUN(testBranchBitAndImmFusion(Identity, Int64, 1, Air::BranchTest32, Air::Arg::Tmp));
213724

Source/WTF/ChangeLog

 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 NOBODY (OOPS!).
 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 Csaba Osztrogonác <ossy@webkit.org>
222
323 Unreviewed AArch64 Linux buildfix after r213645.
213724

Source/WTF/WTF.xcodeproj/project.pbxproj

4343 0F66B2921DC97BAB004A1D3F /* WallTime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F66B2881DC97BAB004A1D3F /* WallTime.cpp */; };
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 */; };
4849 0F824A691B7443A0002E345D /* ParkingLot.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F824A651B7443A0002E345D /* ParkingLot.h */; };

421422 0F66B2881DC97BAB004A1D3F /* WallTime.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WallTime.cpp; sourceTree = "<group>"; };
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>"; };
426428 0F824A651B7443A0002E345D /* ParkingLot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParkingLot.h; sourceTree = "<group>"; };

974976 0FD81AC4154FB22E00983E72 /* FastBitVector.h */,
975977 A8A472A1151A825A004123FF /* FastMalloc.cpp */,
976978 A8A472A2151A825A004123FF /* FastMalloc.h */,
 979 0F79C7C31E73511800EB34D1 /* FastTLS.h */,
977980 B38FD7BC168953E80065C969 /* FeatureDefines.h */,
978981 0F9D335B165DBA73005AD387 /* FilePrintStream.cpp */,
979982 0F9D335C165DBA73005AD387 /* FilePrintStream.h */,

14861489 0F0D85B417234CC100338210 /* NoLock.h in Headers */,
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 */,
14911495 1AFDE6531953B23D00C48FFA /* Optional.h in Headers */,
213724

Source/WTF/wtf/CMakeLists.txt

@@set(WTF_HEADERS
3030 DisallowCType.h
3131 DoublyLinkedList.h
3232 FastMalloc.h
 33 FastTLS.h
3334 FeatureDefines.h
3435 FilePrintStream.h
3536 FlipBytes.h
213724

Source/WTF/wtf/FastTLS.h

 1/*
 2 * Copyright (C) 2017 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#pragma once
 27
 28#if HAVE(FAST_TLS)
 29
 30#include <pthread.h>
 31#include <System/pthread_machdep.h>
 32
 33namespace WTF {
 34
 35// KEY0 is taken by bmalloc.
 36#define WTF_FAST_TLS_KEY0 __PTK_FRAMEWORK_JAVASCRIPTCORE_KEY1
 37#define WTF_FAST_TLS_KEY1 __PTK_FRAMEWORK_JAVASCRIPTCORE_KEY2
 38#define WTF_FAST_TLS_KEY2 __PTK_FRAMEWORK_JAVASCRIPTCORE_KEY3
 39#define WTF_FAST_TLS_KEY3 __PTK_FRAMEWORK_JAVASCRIPTCORE_KEY4
 40
 41// NOTE: We should manage our use of these keys here. If you want to use a key for something,
 42// put a #define in here to give your key a symbolic name, like we do for WTFThreadData.
 43
 44#define WTF_THREAD_DATA_KEY WTF_FAST_TLS_KEY0
 45#define WTF_TESTING_KEY WTF_FAST_TLS_KEY3
 46
 47#if ENABLE(FAST_TLS_JIT)
 48#if CPU(X86_64)
 49inline uintptr_t loadFastTLS(unsigned offset)
 50{
 51 uintptr_t result;
 52 asm volatile(
 53 "movq %%gs:%1, %0"
 54 : "=r"(result)
 55 : "r"(offset)
 56 : "memory");
 57 return result;
 58}
 59#elif CPU(ARM64)
 60inline uintptr_t loadFastTLS(unsigned offset)
 61{
 62 uintptr_t result;
 63 asm volatile(
 64 "mrs %0, TPIDRRO_EL0\n\t"
 65 "and %0, %0, #0xfffffffffffffff8\n\t"
 66 "ldr %0, [%0, %1]"
 67 : "=r"(result)
 68 : "r"(offset)
 69 : "memory");
 70 return result;
 71}
 72#else
 73#error "Bad architecture"
 74#endif
 75#endif // ENABLE(FAST_TLS_JIT)
 76
 77inline unsigned fastTLSOffsetForKey(unsigned long slot)
 78{
 79 return slot * sizeof(void*);
 80}
 81
 82} // namespace WTF
 83
 84#endif // HAVE(FAST_TLS)
 85
nonexistent

Source/WTF/wtf/Platform.h

761761#define HAVE_LL_SC 1
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)
766774#define ENABLE_B3_JIT 1
213724

Source/WTF/wtf/WTFThreadData.cpp

3535
3636namespace WTF {
3737
38 #if !USE(PTHREAD_GETSPECIFIC_DIRECT)
 38#if !HAVE(FAST_TLS)
3939ThreadSpecific<WTFThreadData>* WTFThreadData::staticData;
4040#endif
4141

@@WTFThreadData::~WTFThreadData()
6161 m_atomicStringTableDestructor(m_defaultAtomicStringTable);
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 });
7272 return *data;
213724

Source/WTF/wtf/WTFThreadData.h

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
55 * modification, are permitted provided that the following conditions

2727#ifndef WTFThreadData_h
2828#define WTFThreadData_h
2929
 30#include <wtf/FastTLS.h>
3031#include <wtf/HashMap.h>
3132#include <wtf/HashSet.h>
3233#include <wtf/Noncopyable.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 {
5141

@@private:
122112 void* m_savedStackPointerAtVMEntry;
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
129118 static WTF_EXPORTDATA ThreadSpecific<WTFThreadData>* staticData;

@@inline WTFThreadData& wtfThreadData()
141130 // WRT JavaScriptCore:
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();
152141#endif
213724