Remove the need to pass performJITMemcpy as a pointer.
authormark.lam@apple.com <mark.lam@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 4 Sep 2019 01:47:02 +0000 (01:47 +0000)
committermark.lam@apple.com <mark.lam@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 4 Sep 2019 01:47:02 +0000 (01:47 +0000)
https://bugs.webkit.org/show_bug.cgi?id=201413

Reviewed by Michael Saboff.

We want performJITMemcpy to always be inlined.  In this patch, we also clean up
some template parameters to use enums instead of booleans to better document the
intent of the code.

* assembler/ARM64Assembler.h:
(JSC::ARM64Assembler::fillNops):
(JSC::ARM64Assembler::linkJump):
(JSC::ARM64Assembler::linkCall):
(JSC::ARM64Assembler::relinkJump):
(JSC::ARM64Assembler::relinkCall):
(JSC::ARM64Assembler::link):
(JSC::ARM64Assembler::linkJumpOrCall):
(JSC::ARM64Assembler::linkCompareAndBranch):
(JSC::ARM64Assembler::linkConditionalBranch):
(JSC::ARM64Assembler::linkTestAndBranch):
(JSC::ARM64Assembler::relinkJumpOrCall):
(JSC::ARM64Assembler::CopyFunction::CopyFunction): Deleted.
(JSC::ARM64Assembler::CopyFunction::operator()): Deleted.
* assembler/ARMv7Assembler.h:
(JSC::ARMv7Assembler::fillNops):
(JSC::ARMv7Assembler::link):
(JSC::ARMv7Assembler::linkJumpT1):
(JSC::ARMv7Assembler::linkJumpT2):
(JSC::ARMv7Assembler::linkJumpT3):
(JSC::ARMv7Assembler::linkJumpT4):
(JSC::ARMv7Assembler::linkConditionalJumpT4):
(JSC::ARMv7Assembler::linkBX):
(JSC::ARMv7Assembler::linkConditionalBX):
* assembler/AbstractMacroAssembler.h:
(JSC::AbstractMacroAssembler::emitNops):
* assembler/LinkBuffer.cpp:
(JSC::LinkBuffer::copyCompactAndLinkCode):
* assembler/MIPSAssembler.h:
(JSC::MIPSAssembler::fillNops):
* assembler/MacroAssemblerARM64.h:
(JSC::MacroAssemblerARM64::link):
* assembler/MacroAssemblerARMv7.h:
(JSC::MacroAssemblerARMv7::link):
* assembler/X86Assembler.h:
(JSC::X86Assembler::fillNops):
* jit/ExecutableAllocator.h:
(JSC::performJITMemcpy):
* runtime/JSCPtrTag.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@249449 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/assembler/ARM64Assembler.h
Source/JavaScriptCore/assembler/ARMv7Assembler.h
Source/JavaScriptCore/assembler/AbstractMacroAssembler.h
Source/JavaScriptCore/assembler/LinkBuffer.cpp
Source/JavaScriptCore/assembler/MIPSAssembler.h
Source/JavaScriptCore/assembler/MacroAssemblerARM64.h
Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
Source/JavaScriptCore/assembler/X86Assembler.h
Source/JavaScriptCore/jit/ExecutableAllocator.h
Source/JavaScriptCore/runtime/JSCPtrTag.h

index 1d71fc7..8bf8d92 100644 (file)
@@ -1,3 +1,54 @@
+2019-09-03  Mark Lam  <mark.lam@apple.com>
+
+        Remove the need to pass performJITMemcpy as a pointer.
+        https://bugs.webkit.org/show_bug.cgi?id=201413
+
+        Reviewed by Michael Saboff.
+
+        We want performJITMemcpy to always be inlined.  In this patch, we also clean up
+        some template parameters to use enums instead of booleans to better document the
+        intent of the code.
+
+        * assembler/ARM64Assembler.h:
+        (JSC::ARM64Assembler::fillNops):
+        (JSC::ARM64Assembler::linkJump):
+        (JSC::ARM64Assembler::linkCall):
+        (JSC::ARM64Assembler::relinkJump):
+        (JSC::ARM64Assembler::relinkCall):
+        (JSC::ARM64Assembler::link):
+        (JSC::ARM64Assembler::linkJumpOrCall):
+        (JSC::ARM64Assembler::linkCompareAndBranch):
+        (JSC::ARM64Assembler::linkConditionalBranch):
+        (JSC::ARM64Assembler::linkTestAndBranch):
+        (JSC::ARM64Assembler::relinkJumpOrCall):
+        (JSC::ARM64Assembler::CopyFunction::CopyFunction): Deleted.
+        (JSC::ARM64Assembler::CopyFunction::operator()): Deleted.
+        * assembler/ARMv7Assembler.h:
+        (JSC::ARMv7Assembler::fillNops):
+        (JSC::ARMv7Assembler::link):
+        (JSC::ARMv7Assembler::linkJumpT1):
+        (JSC::ARMv7Assembler::linkJumpT2):
+        (JSC::ARMv7Assembler::linkJumpT3):
+        (JSC::ARMv7Assembler::linkJumpT4):
+        (JSC::ARMv7Assembler::linkConditionalJumpT4):
+        (JSC::ARMv7Assembler::linkBX):
+        (JSC::ARMv7Assembler::linkConditionalBX):
+        * assembler/AbstractMacroAssembler.h:
+        (JSC::AbstractMacroAssembler::emitNops):
+        * assembler/LinkBuffer.cpp:
+        (JSC::LinkBuffer::copyCompactAndLinkCode):
+        * assembler/MIPSAssembler.h:
+        (JSC::MIPSAssembler::fillNops):
+        * assembler/MacroAssemblerARM64.h:
+        (JSC::MacroAssemblerARM64::link):
+        * assembler/MacroAssemblerARMv7.h:
+        (JSC::MacroAssemblerARMv7::link):
+        * assembler/X86Assembler.h:
+        (JSC::X86Assembler::fillNops):
+        * jit/ExecutableAllocator.h:
+        (JSC::performJITMemcpy):
+        * runtime/JSCPtrTag.h:
+
 2019-09-03  Devin Rousso  <drousso@apple.com>
 
         REGRESSION (r249078): Flaky crash in com.apple.JavaScriptCore: Inspector::InjectedScriptModule::ensureInjected
index a961f6f..ee6f1a6 100644 (file)
@@ -1494,8 +1494,11 @@ public:
         insn(nopPseudo());
     }
     
-    template <typename CopyFunction>
-    static void fillNops(void* base, size_t size, CopyFunction copy)
+    enum BranchTargetType { DirectBranch, IndirectBranch  };
+    using CopyFunction = void*(&)(void*, const void*, size_t);
+
+    template <CopyFunction copy>
+    static void fillNops(void* base, size_t size)
     {
         RELEASE_ASSERT(!(size % sizeof(int32_t)));
         size_t n = size / sizeof(int32_t);
@@ -2552,13 +2555,13 @@ public:
     static void linkJump(void* code, AssemblerLabel from, void* to)
     {
         ASSERT(from.isSet());
-        relinkJumpOrCall<false>(addressOf(code, from), addressOf(code, from), to);
+        relinkJumpOrCall<BranchType_JMP>(addressOf(code, from), addressOf(code, from), to);
     }
 
     static void linkCall(void* code, AssemblerLabel from, void* to)
     {
         ASSERT(from.isSet());
-        linkJumpOrCall<true>(addressOf(code, from) - 1, addressOf(code, from) - 1, to);
+        linkJumpOrCall<BranchType_CALL>(addressOf(code, from) - 1, addressOf(code, from) - 1, to);
     }
 
     static void linkPointer(void* code, AssemblerLabel where, void* valuePtr)
@@ -2754,7 +2757,7 @@ public:
     // computation.
     static void relinkJump(void* from, void* to)
     {
-        relinkJumpOrCall<false>(reinterpret_cast<int*>(from), reinterpret_cast<const int*>(from), to);
+        relinkJumpOrCall<BranchType_JMP>(reinterpret_cast<int*>(from), reinterpret_cast<const int*>(from), to);
         cacheFlush(from, sizeof(int));
     }
     
@@ -2765,7 +2768,7 @@ public:
     
     static void relinkCall(void* from, void* to)
     {
-        relinkJumpOrCall<true>(reinterpret_cast<int*>(from) - 1, reinterpret_cast<const int*>(from) - 1, to);
+        relinkJumpOrCall<BranchType_CALL>(reinterpret_cast<int*>(from) - 1, reinterpret_cast<const int*>(from) - 1, to);
         cacheFlush(reinterpret_cast<int*>(from) - 1, sizeof(int));
     }
     
@@ -2910,52 +2913,31 @@ public:
         return m_jumpsToLink;
     }
 
-#if CPU(ARM64E)
-    class CopyFunction {
-        typedef void* (*Func)(void*, const void*, size_t);
-    public:
-        CopyFunction(Func func)
-            : m_func(func)
-        {
-            assertIsNullOrTaggedWith(func, CopyFunctionPtrTag);
-        }
-
-        void* operator()(void* dst, const void* src, size_t size)
-        {
-            return ptrauth_auth_function(m_func, ptrauth_key_process_dependent_code, CopyFunctionPtrTag)(dst, src, size);
-        }
-
-    private:
-        Func m_func;
-    };
-#else
-    typedef void* (*CopyFunction)(void*, const void*, size_t);
-#endif
-
-    static void ALWAYS_INLINE link(LinkRecord& record, uint8_t* from, const uint8_t* fromInstruction8, uint8_t* to, CopyFunction copy)
+    template<CopyFunction copy>
+    static void ALWAYS_INLINE link(LinkRecord& record, uint8_t* from, const uint8_t* fromInstruction8, uint8_t* to)
     {
         const int* fromInstruction = reinterpret_cast<const int*>(fromInstruction8);
         switch (record.linkType()) {
         case LinkJumpNoCondition:
-            linkJumpOrCall<false>(reinterpret_cast<int*>(from), fromInstruction, to, copy);
+            linkJumpOrCall<BranchType_JMP, copy>(reinterpret_cast<int*>(from), fromInstruction, to);
             break;
         case LinkJumpConditionDirect:
-            linkConditionalBranch<true>(record.condition(), reinterpret_cast<int*>(from), fromInstruction, to, copy);
+            linkConditionalBranch<DirectBranch, copy>(record.condition(), reinterpret_cast<int*>(from), fromInstruction, to);
             break;
         case LinkJumpCondition:
-            linkConditionalBranch<false>(record.condition(), reinterpret_cast<int*>(from) - 1, fromInstruction - 1, to, copy);
+            linkConditionalBranch<IndirectBranch, copy>(record.condition(), reinterpret_cast<int*>(from) - 1, fromInstruction - 1, to);
             break;
         case LinkJumpCompareAndBranchDirect:
-            linkCompareAndBranch<true>(record.condition(), record.is64Bit(), record.compareRegister(), reinterpret_cast<int*>(from), fromInstruction, to, copy);
+            linkCompareAndBranch<DirectBranch, copy>(record.condition(), record.is64Bit(), record.compareRegister(), reinterpret_cast<int*>(from), fromInstruction, to);
             break;
         case LinkJumpCompareAndBranch:
-            linkCompareAndBranch<false>(record.condition(), record.is64Bit(), record.compareRegister(), reinterpret_cast<int*>(from) - 1, fromInstruction - 1, to, copy);
+            linkCompareAndBranch<IndirectBranch, copy>(record.condition(), record.is64Bit(), record.compareRegister(), reinterpret_cast<int*>(from) - 1, fromInstruction - 1, to);
             break;
         case LinkJumpTestBitDirect:
-            linkTestAndBranch<true>(record.condition(), record.bitNumber(), record.compareRegister(), reinterpret_cast<int*>(from), fromInstruction, to, copy);
+            linkTestAndBranch<DirectBranch, copy>(record.condition(), record.bitNumber(), record.compareRegister(), reinterpret_cast<int*>(from), fromInstruction, to);
             break;
         case LinkJumpTestBit:
-            linkTestAndBranch<false>(record.condition(), record.bitNumber(), record.compareRegister(), reinterpret_cast<int*>(from) - 1, fromInstruction - 1, to, copy);
+            linkTestAndBranch<IndirectBranch, copy>(record.condition(), record.bitNumber(), record.compareRegister(), reinterpret_cast<int*>(from) - 1, fromInstruction - 1, to);
             break;
         default:
             ASSERT_NOT_REACHED();
@@ -2996,14 +2978,17 @@ protected:
         setPointer(address, valuePtr, rd, flush);
     }
 
-    template<bool isCall>
-    static void linkJumpOrCall(int* from, const int* fromInstruction, void* to, CopyFunction copy = tagCFunctionPtr<CopyFunctionPtrTag>(performJITMemcpy))
+    template<BranchType type, CopyFunction copy = performJITMemcpy>
+    static void linkJumpOrCall(int* from, const int* fromInstruction, void* to)
     {
+        static_assert(type == BranchType_JMP || type == BranchType_CALL, "");
+
         bool link;
         int imm26;
         bool isUnconditionalBranchImmediateOrNop = disassembleUnconditionalBranchImmediate(from, link, imm26) || disassembleNop(from);
 
         ASSERT_UNUSED(isUnconditionalBranchImmediateOrNop, isUnconditionalBranchImmediateOrNop);
+        constexpr bool isCall = (type == BranchType_CALL);
         ASSERT_UNUSED(isCall, (link == isCall) || disassembleNop(from));
         ASSERT(!(reinterpret_cast<intptr_t>(from) & 3));
         ASSERT(!(reinterpret_cast<intptr_t>(to) & 3));
@@ -3017,8 +3002,8 @@ protected:
         copy(from, &insn, sizeof(int));
     }
 
-    template<bool isDirect>
-    static void linkCompareAndBranch(Condition condition, bool is64Bit, RegisterID rt, int* from, const int* fromInstruction, void* to, CopyFunction copy = tagCFunctionPtr<CopyFunctionPtrTag>(performJITMemcpy))
+    template<BranchTargetType type, CopyFunction copy = performJITMemcpy>
+    static void linkCompareAndBranch(Condition condition, bool is64Bit, RegisterID rt, int* from, const int* fromInstruction, void* to)
     {
         ASSERT(!(reinterpret_cast<intptr_t>(from) & 3));
         ASSERT(!(reinterpret_cast<intptr_t>(to) & 3));
@@ -3026,13 +3011,13 @@ protected:
         ASSERT(isInt<26>(offset));
 
         bool useDirect = isInt<19>(offset);
-        ASSERT(!isDirect || useDirect);
+        ASSERT(type == IndirectBranch || useDirect);
 
-        if (useDirect || isDirect) {
+        if (useDirect || type == DirectBranch) {
             int insn = compareAndBranchImmediate(is64Bit ? Datasize_64 : Datasize_32, condition == ConditionNE, static_cast<int>(offset), rt);
             RELEASE_ASSERT(roundUpToMultipleOf<instructionSize>(from) == from);
             copy(from, &insn, sizeof(int));
-            if (!isDirect) {
+            if (type == IndirectBranch) {
                 insn = nopPseudo();
                 RELEASE_ASSERT(roundUpToMultipleOf<instructionSize>(from + 1) == (from + 1));
                 copy(from + 1, &insn, sizeof(int));
@@ -3041,12 +3026,12 @@ protected:
             int insn = compareAndBranchImmediate(is64Bit ? Datasize_64 : Datasize_32, invert(condition) == ConditionNE, 2, rt);
             RELEASE_ASSERT(roundUpToMultipleOf<instructionSize>(from) == from);
             copy(from, &insn, sizeof(int));
-            linkJumpOrCall<false>(from + 1, fromInstruction + 1, to, copy);
+            linkJumpOrCall<BranchType_JMP, copy>(from + 1, fromInstruction + 1, to);
         }
     }
 
-    template<bool isDirect>
-    static void linkConditionalBranch(Condition condition, int* from, const int* fromInstruction, void* to, CopyFunction copy = tagCFunctionPtr<CopyFunctionPtrTag>(performJITMemcpy))
+    template<BranchTargetType type, CopyFunction copy = performJITMemcpy>
+    static void linkConditionalBranch(Condition condition, int* from, const int* fromInstruction, void* to)
     {
         ASSERT(!(reinterpret_cast<intptr_t>(from) & 3));
         ASSERT(!(reinterpret_cast<intptr_t>(to) & 3));
@@ -3054,13 +3039,13 @@ protected:
         ASSERT(isInt<26>(offset));
 
         bool useDirect = isInt<19>(offset);
-        ASSERT(!isDirect || useDirect);
+        ASSERT(type == IndirectBranch || useDirect);
 
-        if (useDirect || isDirect) {
+        if (useDirect || type == DirectBranch) {
             int insn = conditionalBranchImmediate(static_cast<int>(offset), condition);
             RELEASE_ASSERT(roundUpToMultipleOf<instructionSize>(from) == from);
             copy(from, &insn, sizeof(int));
-            if (!isDirect) {
+            if (type == IndirectBranch) {
                 insn = nopPseudo();
                 RELEASE_ASSERT(roundUpToMultipleOf<instructionSize>(from + 1) == (from + 1));
                 copy(from + 1, &insn, sizeof(int));
@@ -3069,12 +3054,12 @@ protected:
             int insn = conditionalBranchImmediate(2, invert(condition));
             RELEASE_ASSERT(roundUpToMultipleOf<instructionSize>(from) == from);
             copy(from, &insn, sizeof(int));
-            linkJumpOrCall<false>(from + 1, fromInstruction + 1, to, copy);
+            linkJumpOrCall<BranchType_JMP, copy>(from + 1, fromInstruction + 1, to);
         }
     }
 
-    template<bool isDirect>
-    static void linkTestAndBranch(Condition condition, unsigned bitNumber, RegisterID rt, int* from, const int* fromInstruction, void* to, CopyFunction copy = tagCFunctionPtr<CopyFunctionPtrTag>(performJITMemcpy))
+    template<BranchTargetType type, CopyFunction copy = performJITMemcpy>
+    static void linkTestAndBranch(Condition condition, unsigned bitNumber, RegisterID rt, int* from, const int* fromInstruction, void* to)
     {
         ASSERT(!(reinterpret_cast<intptr_t>(from) & 3));
         ASSERT(!(reinterpret_cast<intptr_t>(to) & 3));
@@ -3083,13 +3068,13 @@ protected:
         ASSERT(isInt<26>(offset));
 
         bool useDirect = isInt<14>(offset);
-        ASSERT(!isDirect || useDirect);
+        ASSERT(type == IndirectBranch || useDirect);
 
-        if (useDirect || isDirect) {
+        if (useDirect || type == DirectBranch) {
             int insn = testAndBranchImmediate(condition == ConditionNE, static_cast<int>(bitNumber), static_cast<int>(offset), rt);
             RELEASE_ASSERT(roundUpToMultipleOf<instructionSize>(from) == from);
             copy(from, &insn, sizeof(int));
-            if (!isDirect) {
+            if (type == IndirectBranch) {
                 insn = nopPseudo();
                 RELEASE_ASSERT(roundUpToMultipleOf<instructionSize>(from + 1) == (from + 1));
                 copy(from + 1, &insn, sizeof(int));
@@ -3098,14 +3083,15 @@ protected:
             int insn = testAndBranchImmediate(invert(condition) == ConditionNE, static_cast<int>(bitNumber), 2, rt);
             RELEASE_ASSERT(roundUpToMultipleOf<instructionSize>(from) == from);
             copy(from, &insn, sizeof(int));
-            linkJumpOrCall<false>(from + 1, fromInstruction + 1, to, copy);
+            linkJumpOrCall<BranchType_JMP, copy>(from + 1, fromInstruction + 1, to);
         }
     }
 
-    template<bool isCall>
+    template<BranchType type>
     static void relinkJumpOrCall(int* from, const int* fromInstruction, void* to)
     {
-        if (!isCall && disassembleNop(from)) {
+        static_assert(type == BranchType_JMP || type == BranchType_CALL, "");
+        if ((type == BranchType_JMP) && disassembleNop(from)) {
             unsigned op01;
             int imm19;
             Condition condition;
@@ -3113,12 +3099,12 @@ protected:
 
             if (isConditionalBranchImmediate) {
                 ASSERT_UNUSED(op01, !op01);
-                ASSERT_UNUSED(isCall, !isCall);
+                ASSERT(type == BranchType_JMP);
 
                 if (imm19 == 8)
                     condition = invert(condition);
 
-                linkConditionalBranch<false>(condition, from - 1, fromInstruction - 1, to);
+                linkConditionalBranch<IndirectBranch>(condition, from - 1, fromInstruction - 1, to);
                 return;
             }
 
@@ -3131,7 +3117,7 @@ protected:
                 if (imm19 == 8)
                     op = !op;
 
-                linkCompareAndBranch<false>(op ? ConditionNE : ConditionEQ, opSize == Datasize_64, rt, from - 1, fromInstruction - 1, to);
+                linkCompareAndBranch<IndirectBranch>(op ? ConditionNE : ConditionEQ, opSize == Datasize_64, rt, from - 1, fromInstruction - 1, to);
                 return;
             }
 
@@ -3143,12 +3129,12 @@ protected:
                 if (imm14 == 8)
                     op = !op;
 
-                linkTestAndBranch<false>(op ? ConditionNE : ConditionEQ, bitNumber, rt, from - 1, fromInstruction - 1, to);
+                linkTestAndBranch<IndirectBranch>(op ? ConditionNE : ConditionEQ, bitNumber, rt, from - 1, fromInstruction - 1, to);
                 return;
             }
         }
 
-        linkJumpOrCall<isCall>(from, fromInstruction, to);
+        linkJumpOrCall<type>(from, fromInstruction, to);
     }
 
     static int* addressOf(void* code, AssemblerLabel label)
index 91e73af..414cbd4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2009-2019 Apple Inc. All rights reserved.
  * Copyright (C) 2010 University of Szeged
  *
  * Redistribution and use in source and binary forms, with or without
@@ -1969,8 +1969,10 @@ public:
         return OP_NOP_T2a | (OP_NOP_T2b << 16);
     }
 
-    template <typename CopyFunction>
-    static void fillNops(void* base, size_t size, CopyFunction copy)
+    using CopyFunction = void*(&)(void*, const void*, size_t);
+
+    template <CopyFunction copy>
+    static void fillNops(void* base, size_t size)
     {
         RELEASE_ASSERT(!(size % sizeof(int16_t)));
 
@@ -2123,32 +2125,31 @@ public:
         return m_jumpsToLink;
     }
 
-    typedef void* (*CopyFunction)(void*, const void*, size_t);
-
-    static void ALWAYS_INLINE link(LinkRecord& record, uint8_t* from, const uint8_t* fromInstruction8, uint8_t* to, CopyFunction copy)
+    template<CopyFunction copy>
+    static void ALWAYS_INLINE link(LinkRecord& record, uint8_t* from, const uint8_t* fromInstruction8, uint8_t* to)
     {
         const uint16_t* fromInstruction = reinterpret_cast_ptr<const uint16_t*>(fromInstruction8);
         switch (record.linkType()) {
         case LinkJumpT1:
-            linkJumpT1(record.condition(), reinterpret_cast_ptr<uint16_t*>(from), fromInstruction, to, copy);
+            linkJumpT1<copy>(record.condition(), reinterpret_cast_ptr<uint16_t*>(from), fromInstruction, to);
             break;
         case LinkJumpT2:
-            linkJumpT2(reinterpret_cast_ptr<uint16_t*>(from), fromInstruction, to, copy);
+            linkJumpT2<copy>(reinterpret_cast_ptr<uint16_t*>(from), fromInstruction, to);
             break;
         case LinkJumpT3:
-            linkJumpT3(record.condition(), reinterpret_cast_ptr<uint16_t*>(from), fromInstruction, to, copy);
+            linkJumpT3<copy>(record.condition(), reinterpret_cast_ptr<uint16_t*>(from), fromInstruction, to);
             break;
         case LinkJumpT4:
-            linkJumpT4(reinterpret_cast_ptr<uint16_t*>(from), fromInstruction, to, copy);
+            linkJumpT4<copy>(reinterpret_cast_ptr<uint16_t*>(from), fromInstruction, to);
             break;
         case LinkConditionalJumpT4:
-            linkConditionalJumpT4(record.condition(), reinterpret_cast_ptr<uint16_t*>(from), fromInstruction, to, copy);
+            linkConditionalJumpT4<copy>(record.condition(), reinterpret_cast_ptr<uint16_t*>(from), fromInstruction, to);
             break;
         case LinkConditionalBX:
-            linkConditionalBX(record.condition(), reinterpret_cast_ptr<uint16_t*>(from), fromInstruction, to, copy);
+            linkConditionalBX<copy>(record.condition(), reinterpret_cast_ptr<uint16_t*>(from), fromInstruction, to);
             break;
         case LinkBX:
-            linkBX(reinterpret_cast_ptr<uint16_t*>(from), fromInstruction, to, copy);
+            linkBX<copy>(reinterpret_cast_ptr<uint16_t*>(from), fromInstruction, to);
             break;
         default:
             RELEASE_ASSERT_NOT_REACHED();
@@ -2598,8 +2599,9 @@ private:
         intptr_t relative = reinterpret_cast<intptr_t>(target) - (reinterpret_cast<intptr_t>(instruction));
         return ((relative << 7) >> 7) == relative;
     }
-    
-    static void linkJumpT1(Condition cond, uint16_t* writeTarget, const uint16_t* instruction, void* target, CopyFunction copy = performJITMemcpy)
+
+    template<CopyFunction copy = performJITMemcpy>
+    static void linkJumpT1(Condition cond, uint16_t* writeTarget, const uint16_t* instruction, void* target)
     {
         // FIMXE: this should be up in the MacroAssembler layer. :-(        
         ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1));
@@ -2617,8 +2619,9 @@ private:
         uint16_t newInstruction = OP_B_T1 | ((cond & 0xf) << 8) | ((relative & 0x1fe) >> 1);
         copy(writeTarget - 1, &newInstruction, sizeof(uint16_t));
     }
-    
-    static void linkJumpT2(uint16_t* writeTarget, const uint16_t* instruction, void* target, CopyFunction copy = performJITMemcpy)
+
+    template<CopyFunction copy = performJITMemcpy>
+    static void linkJumpT2(uint16_t* writeTarget, const uint16_t* instruction, void* target)
     {
         // FIMXE: this should be up in the MacroAssembler layer. :-(        
         ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1));
@@ -2637,7 +2640,8 @@ private:
         copy(writeTarget - 1, &newInstruction, sizeof(uint16_t));
     }
     
-    static void linkJumpT3(Condition cond, uint16_t* writeTarget, const uint16_t* instruction, void* target, CopyFunction copy = performJITMemcpy)
+    template<CopyFunction copy = performJITMemcpy>
+    static void linkJumpT3(Condition cond, uint16_t* writeTarget, const uint16_t* instruction, void* target)
     {
         // FIMXE: this should be up in the MacroAssembler layer. :-(
         ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1));
@@ -2654,7 +2658,8 @@ private:
         copy(writeTarget - 2, instructions, 2 * sizeof(uint16_t));
     }
     
-    static void linkJumpT4(uint16_t* writeTarget, const uint16_t* instruction, void* target, CopyFunction copy = performJITMemcpy)
+    template<CopyFunction copy = performJITMemcpy>
+    static void linkJumpT4(uint16_t* writeTarget, const uint16_t* instruction, void* target)
     {
         // FIMXE: this should be up in the MacroAssembler layer. :-(        
         ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1));
@@ -2673,8 +2678,9 @@ private:
         instructions[1] = OP_B_T4b | ((relative & 0x800000) >> 10) | ((relative & 0x400000) >> 11) | ((relative & 0xffe) >> 1);
         copy(writeTarget - 2, instructions, 2 * sizeof(uint16_t));
     }
-    
-    static void linkConditionalJumpT4(Condition cond, uint16_t* writeTarget, const uint16_t* instruction, void* target, CopyFunction copy = performJITMemcpy)
+
+    template<CopyFunction copy = performJITMemcpy>
+    static void linkConditionalJumpT4(Condition cond, uint16_t* writeTarget, const uint16_t* instruction, void* target)
     {
         // FIMXE: this should be up in the MacroAssembler layer. :-(        
         ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1));
@@ -2682,10 +2688,11 @@ private:
         
         uint16_t newInstruction = ifThenElse(cond) | OP_IT;
         copy(writeTarget - 3, &newInstruction, sizeof(uint16_t));
-        linkJumpT4(writeTarget, instruction, target, copy);
+        linkJumpT4<copy>(writeTarget, instruction, target);
     }
-    
-    static void linkBX(uint16_t* writeTarget, const uint16_t* instruction, void* target, CopyFunction copy = performJITMemcpy)
+
+    template<CopyFunction copy = performJITMemcpy>
+    static void linkBX(uint16_t* writeTarget, const uint16_t* instruction, void* target)
     {
         // FIMXE: this should be up in the MacroAssembler layer. :-(
         ASSERT_UNUSED(instruction, !(reinterpret_cast<intptr_t>(instruction) & 1));
@@ -2704,8 +2711,9 @@ private:
 
         copy(writeTarget - 5, instructions, 5 * sizeof(uint16_t));
     }
-    
-    static void linkConditionalBX(Condition cond, uint16_t* writeTarget, const uint16_t* instruction, void* target, CopyFunction copy = performJITMemcpy)
+
+    template<CopyFunction copy = performJITMemcpy>
+    static void linkConditionalBX(Condition cond, uint16_t* writeTarget, const uint16_t* instruction, void* target)
     {
         // FIMXE: this should be up in the MacroAssembler layer. :-(        
         ASSERT(!(reinterpret_cast<intptr_t>(instruction) & 1));
index f87b467..2a77664 100644 (file)
@@ -959,6 +959,14 @@ public:
         m_linkTasks.append(createSharedTask<void(LinkBuffer&)>(functor));
     }
 
+#if COMPILER(GCC)
+    // Workaround for GCC demanding that memcpy "must be the name of a function with external linkage".
+    static void* memcpy(void* dst, const void* src, size_t size)
+    {
+        return std::memcpy(dst, src, size);
+    }
+#endif
+
     void emitNops(size_t memoryToFillWithNopsInBytes)
     {
 #if CPU(ARM64)
@@ -970,7 +978,7 @@ public:
         size_t startCodeSize = buffer.codeSize();
         size_t targetCodeSize = startCodeSize + memoryToFillWithNopsInBytes;
         buffer.ensureSpace(memoryToFillWithNopsInBytes);
-        AssemblerType::fillNops(static_cast<char*>(buffer.data()) + startCodeSize, memoryToFillWithNopsInBytes, memcpy);
+        AssemblerType::template fillNops<memcpy>(static_cast<char*>(buffer.data()) + startCodeSize, memoryToFillWithNopsInBytes);
         buffer.setCodeSize(targetCodeSize);
 #endif
     }
index f474ef6..0fe46c4 100644 (file)
@@ -228,21 +228,24 @@ void LinkBuffer::copyCompactAndLinkCode(MacroAssembler& macroAssembler, void* ow
 
     recordLinkOffsets(m_assemblerStorage, readPtr, initialSize, readPtr - writePtr);
         
-#if CPU(ARM64E) && ENABLE(FAST_JIT_PERMISSIONS)
-    auto memcpyFunction = tagCFunctionPtr<CopyFunctionPtrTag>(memcpy);
-#else
-    auto memcpyFunction = tagCFunctionPtr<CopyFunctionPtrTag>(performJITMemcpy);
-#endif
     for (unsigned i = 0; i < jumpCount; ++i) {
         uint8_t* location = codeOutData + jumpsToLink[i].from();
         uint8_t* target = codeOutData + jumpsToLink[i].to() - executableOffsetFor(jumpsToLink[i].to());
-        MacroAssembler::link(jumpsToLink[i], outData + jumpsToLink[i].from(), location, target, memcpyFunction);
+#if CPU(ARM64E) && ENABLE(FAST_JIT_PERMISSIONS)
+        MacroAssembler::link<memcpy>(jumpsToLink[i], outData + jumpsToLink[i].from(), location, target);
+#else
+        MacroAssembler::link<performJITMemcpy>(jumpsToLink[i], outData + jumpsToLink[i].from(), location, target);
+#endif
     }
 
     size_t compactSize = writePtr + initialSize - readPtr;
     if (!m_executableMemory) {
         size_t nopSizeInBytes = initialSize - compactSize;
-        MacroAssembler::AssemblerType_T::fillNops(outData + compactSize, nopSizeInBytes, memcpy);
+#if CPU(ARM64E) && ENABLE(FAST_JIT_PERMISSIONS)
+        Assembler::fillNops<memcpy>(outData + compactSize, nopSizeInBytes);
+#else
+        Assembler::fillNops<performJITMemcpy>(outData + compactSize, nopSizeInBytes);
+#endif
     }
 
 #if CPU(ARM64E) && ENABLE(FAST_JIT_PERMISSIONS)
index a64e934..bf8ba89 100644 (file)
@@ -162,8 +162,10 @@ public:
         emitInst(0x00000000);
     }
     
-    template <typename CopyFunction>
-    static void fillNops(void* base, size_t size, CopyFunction copy)
+    using CopyFunction = void*(&)(void*, const void*, size_t);
+
+    template <CopyFunction copy>
+    static void fillNops(void* base, size_t size)
     {
         UNUSED_PARAM(copy);
         RELEASE_ASSERT(!(size % sizeof(int32_t)));
index b28e694..10ebbef 100644 (file)
@@ -83,8 +83,8 @@ public:
     static JumpLinkType computeJumpType(JumpType jumpType, const uint8_t* from, const uint8_t* to) { return Assembler::computeJumpType(jumpType, from, to); }
     static JumpLinkType computeJumpType(LinkRecord& record, const uint8_t* from, const uint8_t* to) { return Assembler::computeJumpType(record, from, to); }
     static int jumpSizeDelta(JumpType jumpType, JumpLinkType jumpLinkType) { return Assembler::jumpSizeDelta(jumpType, jumpLinkType); }
-    template <typename CopyFunction>
-    static void link(LinkRecord& record, uint8_t* from, const uint8_t* fromInstruction, uint8_t* to, CopyFunction copy) { return Assembler::link(record, from, fromInstruction, to, copy); }
+    template <Assembler::CopyFunction copy>
+    static void link(LinkRecord& record, uint8_t* from, const uint8_t* fromInstruction, uint8_t* to) { return Assembler::link<copy>(record, from, fromInstruction, to); }
 
     static const Scale ScalePtr = TimesEight;
 
index d14a3ec..c7a76bb 100644 (file)
@@ -69,8 +69,8 @@ public:
     static JumpLinkType computeJumpType(JumpType jumpType, const uint8_t* from, const uint8_t* to) { return ARMv7Assembler::computeJumpType(jumpType, from, to); }
     static JumpLinkType computeJumpType(LinkRecord& record, const uint8_t* from, const uint8_t* to) { return ARMv7Assembler::computeJumpType(record, from, to); }
     static int jumpSizeDelta(JumpType jumpType, JumpLinkType jumpLinkType) { return ARMv7Assembler::jumpSizeDelta(jumpType, jumpLinkType); }
-    template <typename CopyFunction>
-    static void link(LinkRecord& record, uint8_t* from, const uint8_t* fromInstruction, uint8_t* to, CopyFunction copy) { return ARMv7Assembler::link(record, from, fromInstruction, to, copy); }
+    template <Assembler::CopyFunction copy>
+    static void link(LinkRecord& record, uint8_t* from, const uint8_t* fromInstruction, uint8_t* to) { return ARMv7Assembler::link<copy>(record, from, fromInstruction, to); }
 
     struct ArmAddress {
         enum AddressType {
index 8e9d842..4ec5cc0 100644 (file)
@@ -3952,8 +3952,10 @@ public:
         m_formatter.oneByteOp(OP_NOP);
     }
 
-    template <typename CopyFunction>
-    static void fillNops(void* base, size_t size, CopyFunction copy)
+    using CopyFunction = void*(&)(void*, const void*, size_t);
+
+    template <CopyFunction copy>
+    static void fillNops(void* base, size_t size)
     {
         UNUSED_PARAM(copy);
 #if CPU(X86_64)
index 283fb46..c6b21cf 100644 (file)
@@ -122,7 +122,7 @@ extern JS_EXPORT_PRIVATE bool useFastPermisionsJITCopy;
 
 #endif // ENABLE(SEPARATED_WX_HEAP)
 
-static inline void* performJITMemcpy(void *dst, const void *src, size_t n)
+static ALWAYS_INLINE void* performJITMemcpy(void *dst, const void *src, size_t n)
 {
 #if CPU(ARM64)
     static constexpr size_t instructionSize = sizeof(unsigned);
index 0901e84..c4706fd 100644 (file)
@@ -35,7 +35,6 @@ using PtrTag = WTF::PtrTag;
     v(B3CCallPtrTag) \
     v(B3CompilationPtrTag) \
     v(BytecodePtrTag) \
-    v(CopyFunctionPtrTag) \
     v(DOMJITFunctionPtrTag) \
     v(DisassemblyPtrTag) \
     v(ExceptionHandlerPtrTag) \