Unify macOS ARM64 write protection holders with W^X ones (#54067)
authorJan Vorlicek <jan.vorlicek@volny.cz>
Sat, 12 Jun 2021 07:54:58 +0000 (09:54 +0200)
committerGitHub <noreply@github.com>
Sat, 12 Jun 2021 07:54:58 +0000 (09:54 +0200)
* Unify macOS ARM64 write protection holders with W^X ones

This change removes the original holders that were added for changing
memory protection for executable code and moves the actual switching to
the recently added W^X holders.

The unixexports files don't support target specific symbols. So I needed
to export a dummy version of the PAL_JitWriteProtect for macOS x64.

32 files changed:
src/coreclr/debug/ee/controller.cpp
src/coreclr/debug/ee/debugger.cpp
src/coreclr/debug/ee/debugger.h
src/coreclr/debug/inc/amd64/primitives.h
src/coreclr/debug/inc/arm/primitives.h
src/coreclr/debug/inc/arm64/primitives.h
src/coreclr/debug/inc/i386/primitives.h
src/coreclr/dlls/mscordac/mscordac_unixexports.src
src/coreclr/inc/executableallocator.h
src/coreclr/inc/loaderheap.h
src/coreclr/pal/inc/pal.h
src/coreclr/pal/src/map/virtual.cpp
src/coreclr/vm/arm64/arm64singlestepper.cpp
src/coreclr/vm/arm64/asmhelpers.S
src/coreclr/vm/arm64/asmhelpers.asm
src/coreclr/vm/arm64/stubs.cpp
src/coreclr/vm/callcounting.cpp
src/coreclr/vm/callhelpers.cpp
src/coreclr/vm/ceemain.cpp
src/coreclr/vm/codeman.cpp
src/coreclr/vm/comdelegate.cpp
src/coreclr/vm/dllimportcallback.cpp
src/coreclr/vm/dllimportcallback.h
src/coreclr/vm/dynamicmethod.cpp
src/coreclr/vm/eventing/eventpipe/ep-rt-coreclr.h
src/coreclr/vm/gccover.cpp
src/coreclr/vm/methoddescbackpatchinfo.cpp
src/coreclr/vm/precode.cpp
src/coreclr/vm/prestub.cpp
src/coreclr/vm/threads.cpp
src/coreclr/vm/threadsuspend.cpp
src/coreclr/vm/virtualcallstub.cpp

index 01aedf5..eed3c45 100644 (file)
@@ -83,7 +83,11 @@ SharedPatchBypassBuffer* DebuggerControllerPatch::GetOrCreateSharedPatchBypassBu
 
     if (m_pSharedPatchBypassBuffer == NULL)
     {
-        m_pSharedPatchBypassBuffer = new (interopsafeEXEC) SharedPatchBypassBuffer();
+        void *pSharedPatchBypassBufferRX = g_pDebugger->GetInteropSafeExecutableHeap()->Alloc(sizeof(SharedPatchBypassBuffer));
+        ExecutableWriterHolder<SharedPatchBypassBuffer> sharedPatchBypassBufferWriterHolder((SharedPatchBypassBuffer*)pSharedPatchBypassBufferRX, sizeof(SharedPatchBypassBuffer));
+        new (sharedPatchBypassBufferWriterHolder.GetRW()) SharedPatchBypassBuffer();
+        m_pSharedPatchBypassBuffer = (SharedPatchBypassBuffer*)pSharedPatchBypassBufferRX;
+
         _ASSERTE(m_pSharedPatchBypassBuffer);
         TRACE_ALLOC(m_pSharedPatchBypassBuffer);
     }
@@ -1364,9 +1368,7 @@ bool DebuggerController::ApplyPatch(DebuggerControllerPatch *patch)
 
         LPVOID baseAddress = (LPVOID)(patch->address);
 
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-        auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#else // defined(HOST_OSX) && defined(HOST_ARM64)
+#if !defined(HOST_OSX) || !defined(HOST_ARM64)
         DWORD oldProt;
 
         if (!VirtualProtect(baseAddress,
@@ -1376,7 +1378,7 @@ bool DebuggerController::ApplyPatch(DebuggerControllerPatch *patch)
             _ASSERTE(!"VirtualProtect of code page failed");
             return false;
         }
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
+#endif // !defined(HOST_OSX) || !defined(HOST_ARM64)
 
         patch->opcode = CORDbgGetInstruction(patch->address);
 
@@ -1391,7 +1393,7 @@ bool DebuggerController::ApplyPatch(DebuggerControllerPatch *patch)
             _ASSERTE(!"VirtualProtect of code page failed");
             return false;
         }
-#endif // !defined(HOST_OSX) || !defined(HOST_ARM64)
+#endif // !defined(HOST_OSX) || !defined(HOST_ARM64)        
     }
 // TODO: : determine if this is needed for AMD64
 #if defined(TARGET_X86) //REVISIT_TODO what is this?!
@@ -1408,12 +1410,14 @@ bool DebuggerController::ApplyPatch(DebuggerControllerPatch *patch)
             _ASSERTE(!"VirtualProtect of code page failed");
             return false;
         }
+
         patch->opcode =
           (unsigned int) *(unsigned short*)(patch->address+1);
 
         _ASSERTE(patch->opcode != CEE_BREAK);
 
-        *(unsigned short *) (patch->address+1) = CEE_BREAK;
+        ExecutableWriterHolder<BYTE> breakpointWriterHolder((BYTE*)patch->address, 2);
+        *(unsigned short *) (breakpointWriterHolder.GetRW()+1) = CEE_BREAK;
 
         if (!VirtualProtect((void *) patch->address, 2, oldProt, &oldProt))
         {
@@ -1460,9 +1464,7 @@ bool DebuggerController::UnapplyPatch(DebuggerControllerPatch *patch)
 
         LPVOID baseAddress = (LPVOID)(patch->address);
 
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-        auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#else // defined(HOST_OSX) && defined(HOST_ARM64)
+#if !defined(HOST_OSX) || !defined(HOST_ARM64)
         DWORD oldProt;
 
         if (!VirtualProtect(baseAddress,
@@ -1477,7 +1479,7 @@ bool DebuggerController::UnapplyPatch(DebuggerControllerPatch *patch)
             InitializePRD(&(patch->opcode));
             return false;
         }
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
+#endif // !defined(HOST_OSX) || !defined(HOST_ARM64)
 
         CORDbgSetInstruction((CORDB_ADDRESS_TYPE *)patch->address, patch->opcode);
 
@@ -1494,7 +1496,7 @@ bool DebuggerController::UnapplyPatch(DebuggerControllerPatch *patch)
             _ASSERTE(!"VirtualProtect of code page failed");
             return false;
         }
-#endif // !defined(HOST_OSX) || !defined(HOST_ARM64)
+#endif // !defined(HOST_OSX) || !defined(HOST_ARM64)        
     }
     else
     {
@@ -1519,7 +1521,8 @@ bool DebuggerController::UnapplyPatch(DebuggerControllerPatch *patch)
 #if defined(TARGET_X86)
         _ASSERTE(*(unsigned short*)(patch->address+1) == CEE_BREAK);
 
-        *(unsigned short *) (patch->address+1)
+        ExecutableWriterHolder<BYTE> breakpointWriterHolder((BYTE*)patch->address, 2);
+        *(unsigned short *) (breakpointWriterHolder.GetRW()+1)
           = (unsigned short) patch->opcode;
 #endif //this makes no sense on anything but X86
         //VERY IMPORTANT to zero out opcode, else we might mistake
index d879136..4706790 100644 (file)
@@ -67,7 +67,6 @@ bool g_EnableSIS = false;
 
 // The following instances are used for invoking overloaded new/delete
 InteropSafe interopsafe;
-InteropSafeExecutable interopsafeEXEC;
 
 #ifndef DACCESS_COMPILE
 
@@ -1316,16 +1315,15 @@ DebuggerEval::DebuggerEval(CONTEXT * pContext, DebuggerIPCE_FuncEvalInfo * pEval
 {
     WRAPPER_NO_CONTRACT;
 
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-    auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
     // Allocate the breakpoint instruction info in executable memory.
-    m_bpInfoSegment = new (interopsafeEXEC, nothrow) DebuggerEvalBreakpointInfoSegment(this);
+    void *bpInfoSegmentRX = g_pDebugger->GetInteropSafeExecutableHeap()->Alloc(sizeof(DebuggerEvalBreakpointInfoSegment));
+    ExecutableWriterHolder<DebuggerEvalBreakpointInfoSegment> bpInfoSegmentWriterHolder((DebuggerEvalBreakpointInfoSegment*)bpInfoSegmentRX, sizeof(DebuggerEvalBreakpointInfoSegment));
+    new (bpInfoSegmentWriterHolder.GetRW()) DebuggerEvalBreakpointInfoSegment(this);
+    m_bpInfoSegment = (DebuggerEvalBreakpointInfoSegment*)bpInfoSegmentRX;
 
     // This must be non-zero so that the saved opcode is non-zero, and on IA64 we want it to be 0x16
     // so that we can have a breakpoint instruction in any slot in the bundle.
-    m_bpInfoSegment->m_breakpointInstruction[0] = 0x16;
+    bpInfoSegmentWriterHolder.GetRW()->m_breakpointInstruction[0] = 0x16;
 #if defined(TARGET_ARM)
     USHORT *bp = (USHORT*)&m_bpInfoSegment->m_breakpointInstruction;
     *bp = CORDbg_BREAK_INSTRUCTION;
index d661986..9d80fb3 100644 (file)
@@ -1104,11 +1104,8 @@ struct DECLSPEC_ALIGN(4096) DebuggerHeapExecutableMemoryPage
 
     inline void SetNextPage(DebuggerHeapExecutableMemoryPage* nextPage)
     {
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-        auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
-        chunks[0].bookkeeping.nextPage = nextPage;
+        ExecutableWriterHolder<DebuggerHeapExecutableMemoryPage> debuggerHeapPageWriterHolder(this, sizeof(DebuggerHeapExecutableMemoryPage));
+        debuggerHeapPageWriterHolder.GetRW()->chunks[0].bookkeeping.nextPage = nextPage;
     }
 
     inline uint64_t GetPageOccupancy() const
@@ -1118,14 +1115,11 @@ struct DECLSPEC_ALIGN(4096) DebuggerHeapExecutableMemoryPage
 
     inline void SetPageOccupancy(uint64_t newOccupancy)
     {
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-        auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
         // Can't unset first bit of occupancy!
         ASSERT((newOccupancy & 0x8000000000000000) != 0);
 
-        chunks[0].bookkeeping.pageOccupancy = newOccupancy;
+        ExecutableWriterHolder<DebuggerHeapExecutableMemoryPage> debuggerHeapPageWriterHolder(this, sizeof(DebuggerHeapExecutableMemoryPage));
+        debuggerHeapPageWriterHolder.GetRW()->chunks[0].bookkeeping.pageOccupancy = newOccupancy;
     }
 
     inline void* GetPointerToChunk(int chunkNum) const
@@ -1135,16 +1129,14 @@ struct DECLSPEC_ALIGN(4096) DebuggerHeapExecutableMemoryPage
 
     DebuggerHeapExecutableMemoryPage()
     {
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-        auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
+        ExecutableWriterHolder<DebuggerHeapExecutableMemoryPage> debuggerHeapPageWriterHolder(this, sizeof(DebuggerHeapExecutableMemoryPage));
 
         SetPageOccupancy(0x8000000000000000); // only the first bit is set.
         for (uint8_t i = 1; i < sizeof(chunks)/sizeof(chunks[0]); i++)
         {
             ASSERT(i != 0);
-            chunks[i].data.startOfPage = this;
-            chunks[i].data.chunkNumber = i;
+            debuggerHeapPageWriterHolder.GetRW()->chunks[i].data.startOfPage = this;
+            debuggerHeapPageWriterHolder.GetRW()->chunks[i].data.chunkNumber = i;
         }
     }
 
@@ -3486,9 +3478,6 @@ public:
 class InteropSafe {};
 extern InteropSafe interopsafe;
 
-class InteropSafeExecutable {};
-extern InteropSafeExecutable interopsafeEXEC;
-
 #ifndef DACCESS_COMPILE
 inline void * __cdecl operator new(size_t n, const InteropSafe&)
 {
@@ -3631,62 +3620,6 @@ template<class T> void DeleteInteropSafe(T *p)
     }
 }
 
-inline void * __cdecl operator new(size_t n, const InteropSafeExecutable&)
-{
-    CONTRACTL
-    {
-        THROWS; // throw on OOM
-        GC_NOTRIGGER;
-    }
-    CONTRACTL_END;
-
-    _ASSERTE(g_pDebugger != NULL);
-    void *result = g_pDebugger->GetInteropSafeExecutableHeap()->Alloc((DWORD)n);
-    if (result == NULL) {
-        ThrowOutOfMemory();
-    }
-    return result;
-}
-
-inline void * __cdecl operator new(size_t n, const InteropSafeExecutable&, const NoThrow&) throw()
-{
-    CONTRACTL
-    {
-        NOTHROW;
-        GC_NOTRIGGER;
-    }
-    CONTRACTL_END;
-
-    _ASSERTE(g_pDebugger != NULL);
-    DebuggerHeap * pHeap = g_pDebugger->GetInteropSafeExecutableHeap_NoThrow();
-    if (pHeap == NULL)
-    {
-        return NULL;
-    }
-    void *result = pHeap->Alloc((DWORD)n);
-    return result;
-}
-
-// Note: there is no C++ syntax for manually invoking this, but if a constructor throws an exception I understand that
-// this delete operator will be invoked automatically to destroy the object.
-inline void __cdecl operator delete(void *p, const InteropSafeExecutable&)
-{
-    CONTRACTL
-    {
-        NOTHROW;
-        GC_NOTRIGGER;
-    }
-    CONTRACTL_END;
-
-    if (p != NULL)
-    {
-        _ASSERTE(g_pDebugger != NULL);
-        DebuggerHeap * pHeap = g_pDebugger->GetInteropSafeExecutableHeap_NoThrow();
-        _ASSERTE(pHeap != NULL); // should have had heap around if we're deleting
-        pHeap->Free(p);
-    }
-}
-
 //
 // Interop safe delete to match the interop safe new's above. There is no C++ syntax for actually invoking those interop
 // safe delete operators above, so we use this method to accomplish the same thing.
index a119c2b..d42dc66 100644 (file)
@@ -12,6 +12,8 @@
 #ifndef PRIMITIVES_H_
 #define PRIMITIVES_H_
 
+#include "executableallocator.h"
+
 #ifndef CORDB_ADDRESS_TYPE
 typedef const BYTE                  CORDB_ADDRESS_TYPE;
 typedef DPTR(CORDB_ADDRESS_TYPE)    PTR_CORDB_ADDRESS_TYPE;
@@ -187,7 +189,9 @@ inline void CORDbgInsertBreakpoint(UNALIGNED CORDB_ADDRESS_TYPE *address)
 {
     LIMITED_METHOD_CONTRACT;
 
-    *((unsigned char*)address) = 0xCC;  // int 3 (single byte patch)
+    ExecutableWriterHolder<void> breakpointWriterHolder((LPVOID)address, CORDbg_BREAK_INSTRUCTION_SIZE);
+
+    *((unsigned char*)breakpointWriterHolder.GetRW()) = 0xCC; // int 3 (single byte patch)
     FlushInstructionCache(GetCurrentProcess(), address, 1);
 
 }
@@ -198,7 +202,9 @@ inline void CORDbgSetInstruction(UNALIGNED CORDB_ADDRESS_TYPE* address,
     // In a DAC build, this function assumes the input is an host address.
     LIMITED_METHOD_DAC_CONTRACT;
 
-    *((unsigned char*)address) =
+    ExecutableWriterHolder<void> instructionWriterHolder((LPVOID)address, sizeof(unsigned char));
+
+    *((unsigned char*)instructionWriterHolder.GetRW()) =
         (unsigned char) instruction;    // setting one byte is important
     FlushInstructionCache(GetCurrentProcess(), address, 1);
 
index 269281e..eb29d83 100644 (file)
@@ -12,6 +12,8 @@
 #ifndef PRIMITIVES_H_
 #define PRIMITIVES_H_
 
+#include "executableallocator.h"
+
 #ifndef THUMB_CODE
 #define THUMB_CODE 1
 #endif
@@ -159,7 +161,9 @@ inline void CORDbgSetInstruction(CORDB_ADDRESS_TYPE* address,
     // In a DAC build, this function assumes the input is an host address.
     LIMITED_METHOD_DAC_CONTRACT;
 
-    CORDB_ADDRESS ptraddr = (CORDB_ADDRESS)address;
+    ExecutableWriterHolder<void> instructionWriterHolder((LPVOID)address, sizeof(PRD_TYPE));
+
+    CORDB_ADDRESS ptraddr = (CORDB_ADDRESS)instructionWriterHolder.GetRW();
     _ASSERTE(ptraddr & THUMB_CODE);
     ptraddr &= ~THUMB_CODE;
 
index f359680..1fb1b9c 100644 (file)
@@ -12,6 +12,8 @@
 #ifndef PRIMITIVES_H_
 #define PRIMITIVES_H_
 
+#include "executableallocator.h"
+
 typedef NEON128                     FPRegister64;
 typedef const BYTE                  CORDB_ADDRESS_TYPE;
 typedef DPTR(CORDB_ADDRESS_TYPE)    PTR_CORDB_ADDRESS_TYPE;
@@ -146,7 +148,9 @@ inline void CORDbgSetInstruction(CORDB_ADDRESS_TYPE* address,
     // In a DAC build, this function assumes the input is an host address.
     LIMITED_METHOD_DAC_CONTRACT;
 
-    ULONGLONG ptraddr = dac_cast<ULONGLONG>(address);
+    ExecutableWriterHolder<void> instructionWriterHolder((LPVOID)address, sizeof(PRD_TYPE));
+
+    ULONGLONG ptraddr = dac_cast<ULONGLONG>(instructionWriterHolder.GetRW());
     *(PRD_TYPE *)ptraddr = instruction;
     FlushInstructionCache(GetCurrentProcess(),
                           address,
index 980dc27..0c1d4bc 100644 (file)
@@ -12,6 +12,7 @@
 #ifndef PRIMITIVES_H_
 #define PRIMITIVES_H_
 
+#include "executableallocator.h"
 
 typedef const BYTE                  CORDB_ADDRESS_TYPE;
 typedef DPTR(CORDB_ADDRESS_TYPE)    PTR_CORDB_ADDRESS_TYPE;
@@ -148,7 +149,9 @@ inline void CORDbgInsertBreakpoint(UNALIGNED CORDB_ADDRESS_TYPE *address)
 {
     LIMITED_METHOD_CONTRACT;
 
-    *((unsigned char*)address) = 0xCC; // int 3 (single byte patch)
+    ExecutableWriterHolder<void> breakpointWriterHolder((LPVOID)address, CORDbg_BREAK_INSTRUCTION_SIZE);
+
+    *((unsigned char*)breakpointWriterHolder.GetRW()) = 0xCC; // int 3 (single byte patch)
     FlushInstructionCache(GetCurrentProcess(), address, 1);
 }
 
index 4fc0af3..aa7352b 100644 (file)
@@ -70,6 +70,7 @@ nativeStringResourceTable_mscorrc
 #PAL__open
 #PAL__pread
 #PAL__close
+#PAL_JitWriteProtect
 
 #_wcsicmp
 #_stricmp
index 6a2cecd..c71f613 100644 (file)
@@ -30,7 +30,13 @@ class ExecutableWriterHolder
 
     void Unmap()
     {
-        // TODO: this will be added with the double mapped allocator addition 
+        if (m_addressRX != NULL)
+        {
+            // TODO: mapping / unmapping for targets using double memory mapping  will be added with the double mapped allocator addition 
+#if defined(HOST_OSX) && defined(HOST_ARM64)
+            PAL_JitWriteProtect(false);
+#endif
+        }
     }
 
 public:
@@ -57,6 +63,9 @@ public:
     {
         m_addressRX = addressRX;
         m_addressRW = addressRX;
+#if defined(HOST_OSX) && defined(HOST_ARM64)
+        PAL_JitWriteProtect(true);
+#endif
     }
 
     ~ExecutableWriterHolder()
index 2dc1565..ac0669a 100644 (file)
@@ -554,10 +554,6 @@ private:
     {
         WRAPPER_NO_CONTRACT;
 
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-        auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
         void *pResult;
         TaggedMemAllocPtr tmap;
 
@@ -634,10 +630,6 @@ public:
     {
         WRAPPER_NO_CONTRACT;
 
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-        auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
         CRITSEC_Holder csh(m_CriticalSection);
 
 
index d22c9ba..69d9052 100644 (file)
@@ -2760,32 +2760,14 @@ VirtualFree(
         IN SIZE_T dwSize,
         IN DWORD dwFreeType);
 
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-#ifdef __cplusplus
-extern "C++" {
-struct PAL_JITWriteEnableHolder
-{
-public:
-  PAL_JITWriteEnableHolder(bool jitWriteEnable)
-  {
-      m_jitWriteEnableRestore = JITWriteEnable(jitWriteEnable);
-  };
-  ~PAL_JITWriteEnableHolder()
-  {
-      JITWriteEnable(m_jitWriteEnableRestore);
-  }
+#if defined(HOST_OSX)
 
-private:
-  bool JITWriteEnable(bool enable);
-  bool m_jitWriteEnableRestore;
-};
+PALIMPORT
+VOID
+PALAPI
+PAL_JitWriteProtect(bool writeEnable);
 
-inline
-PAL_JITWriteEnableHolder
-PAL_JITWriteEnable(IN bool enable) { return PAL_JITWriteEnableHolder(enable); }
-}
-#endif // __cplusplus
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
+#endif // defined(HOST_OSX)
 
 PALIMPORT
 BOOL
index cea55e8..9267f4f 100644 (file)
@@ -1760,22 +1760,29 @@ ExitVirtualProtect:
     return bRetVal;
 }
 
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-bool
-PAL_JITWriteEnableHolder::JITWriteEnable(bool writeEnable)
+#if defined(HOST_OSX)
+PALAPI VOID PAL_JitWriteProtect(bool writeEnable)
 {
-    // Use a thread local to track per thread JIT Write enable state
-    // Per Apple, new threads start with MAP_JIT pages readable and executable (R-X) by default.
-    thread_local bool enabled = false;
-    bool result = enabled;
-    if (enabled != writeEnable)
+#if defined(HOST_ARM64)
+    thread_local int enabledCount = 0;
+    if (writeEnable)
     {
-        pthread_jit_write_protect_np(writeEnable ? 0 : 1);
-        enabled = writeEnable;
+        if (enabledCount++ == 0)
+        {
+            pthread_jit_write_protect_np(0);
+        }
+    }
+    else
+    {
+        if (--enabledCount == 0)
+        {
+            pthread_jit_write_protect_np(1);
+        }
+        _ASSERTE(enabledCount >= 0);
     }
-    return result;
+#endif // HOST_ARM64
 }
-#endif
+#endif // HOST_OSX
 
 #if HAVE_VM_ALLOCATE
 //---------------------------------------------------------------------------------------
index 9ad5610..d459253 100644 (file)
@@ -206,9 +206,8 @@ void Arm64SingleStepper::Apply(T_CONTEXT *pCtx)
     //     control in the breakpoint fixup logic we can then reset the PC to its proper location.
 
     unsigned int idxNextInstruction = 0;
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-    auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
+
+    ExecutableWriterHolder<DWORD> codeWriterHolder(m_rgCode, sizeof(m_rgCode));
 
     if (TryEmulate(pCtx, opcode, false))
     {
@@ -220,11 +219,11 @@ void Arm64SingleStepper::Apply(T_CONTEXT *pCtx)
     {
         LOG((LF_CORDB, LL_INFO100000, "Arm64SingleStepper: Case 2: CopyInstruction.\n"));
         // Case 2: In all other cases copy the instruction to the buffer and we'll run it directly.
-        m_rgCode[idxNextInstruction++] = opcode;
+        codeWriterHolder.GetRW()[idxNextInstruction++] = opcode;
     }
 
     // Always terminate the redirection buffer with a breakpoint.
-    m_rgCode[idxNextInstruction++] = kBreakpointOp;
+    codeWriterHolder.GetRW()[idxNextInstruction++] = kBreakpointOp;
     _ASSERTE(idxNextInstruction <= kMaxCodeBuffer);
 
     // Set the thread up so it will redirect to our buffer when execution resumes.
index 78790be..e6b47d0 100644 (file)
@@ -213,7 +213,7 @@ LEAF_END ThePreStubPatch, _TEXT
     LEAF_END_MARKED \name, _TEXT
 .endm
 
-// void JIT_UpdateWriteBarrierState(bool skipEphemeralCheck)
+// void JIT_UpdateWriteBarrierState(bool skipEphemeralCheck, size_t writeableOffset)
 //
 // Update shadow copies of the various state info required for barrier
 //
@@ -232,6 +232,7 @@ WRITE_BARRIER_ENTRY JIT_UpdateWriteBarrierState
     // x12 will be used for pointers
 
     mov x8, x0
+    mov x9, x1 
 
     PREPARE_EXTERNAL_VAR g_card_table, x12
     ldr  x0, [x12]
@@ -272,6 +273,7 @@ LOCAL_LABEL(EphemeralCheckEnabled):
 #ifdef FEATURE_WRITEBARRIER_COPY
     PREPARE_EXTERNAL_VAR JIT_WriteBarrier_Table_Loc, x12
     ldr  x12, [x12]
+    add  x12, x12, x9
 #else // FEATURE_WRITEBARRIER_COPY
     adr  x12, LOCAL_LABEL(wbs_begin)
 #endif // FEATURE_WRITEBARRIER_COPY
index 304a659..ffbeb9f 100644 (file)
@@ -289,7 +289,7 @@ ThePreStubPatchLabel
     LEAF_END
 
 ;-----------------------------------------------------------------------------
-; void JIT_UpdateWriteBarrierState(bool skipEphemeralCheck)
+; void JIT_UpdateWriteBarrierState(bool skipEphemeralCheck, size_t writeableOffset)
 ;
 ; Update shadow copies of the various state info required for barrier
 ;
index a9fbb6d..54cf1c4 100644 (file)
@@ -571,10 +571,6 @@ void StubPrecode::Init(StubPrecode* pPrecodeRX, MethodDesc* pMD, LoaderAllocator
 {
     WRAPPER_NO_CONTRACT;
 
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-    auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
     int n = 0;
 
     m_rgCode[n++] = 0x10000089; // adr x9, #16
@@ -608,10 +604,6 @@ void NDirectImportPrecode::Init(NDirectImportPrecode* pPrecodeRX, MethodDesc* pM
 {
     WRAPPER_NO_CONTRACT;
 
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-    auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
     int n = 0;
 
     m_rgCode[n++] = 0x1000008B; // adr x11, #16
@@ -645,10 +637,6 @@ void FixupPrecode::Init(FixupPrecode* pPrecodeRX, MethodDesc* pMD, LoaderAllocat
 {
     WRAPPER_NO_CONTRACT;
 
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-    auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
     InitCommon();
 
     // Initialize chunk indices only if they are not initialized yet. This is necessary to make MethodDesc::Reset work.
@@ -1071,15 +1059,16 @@ void JIT_TailCall()
 }
 
 #if !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
-EXTERN_C void JIT_UpdateWriteBarrierState(bool skipEphemeralCheck);
+EXTERN_C void JIT_UpdateWriteBarrierState(bool skipEphemeralCheck, size_t writeableOffset);
+
+extern "C" void STDCALL JIT_PatchedCodeStart();
+extern "C" void STDCALL JIT_PatchedCodeLast();
 
 static void UpdateWriteBarrierState(bool skipEphemeralCheck)
 {
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-    auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
-    JIT_UpdateWriteBarrierState(GCHeapUtilities::IsServerHeap());
+    BYTE *writeBarrierCodeStart = GetWriteBarrierCodeLocation((void*)JIT_PatchedCodeStart);
+    ExecutableWriterHolder<BYTE> writeBarrierWriterHolder(writeBarrierCodeStart, (BYTE*)JIT_PatchedCodeLast - (BYTE*)JIT_PatchedCodeStart);
+    JIT_UpdateWriteBarrierState(GCHeapUtilities::IsServerHeap(), writeBarrierWriterHolder.GetRW() - writeBarrierCodeStart);
 }
 
 void InitJITHelpers1()
@@ -1227,9 +1216,6 @@ UMEntryThunk * UMEntryThunk::Decode(void *pCallback)
 
 void UMEntryThunkCode::Encode(UMEntryThunkCode *pEntryThunkCodeRX, BYTE* pTargetCode, void* pvSecretParam)
 {
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-    auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
     // adr x12, _label
     // ldp x16, x12, [x12]
     // br x16
@@ -1252,9 +1238,6 @@ void UMEntryThunkCode::Encode(UMEntryThunkCode *pEntryThunkCodeRX, BYTE* pTarget
 
 void UMEntryThunkCode::Poison()
 {
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-    auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
     ExecutableWriterHolder<UMEntryThunkCode> thunkWriterHolder(this, sizeof(UMEntryThunkCode));
     UMEntryThunkCode *pThisRW = thunkWriterHolder.GetRW();
 
@@ -1867,21 +1850,6 @@ void StubLinkerCPU::EmitCallManagedMethod(MethodDesc *pMD, BOOL fTailCall)
 
 #define DYNAMIC_HELPER_ALIGNMENT sizeof(TADDR)
 
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-#define BEGIN_DYNAMIC_HELPER_EMIT(size) \
-    SIZE_T cb = size; \
-    SIZE_T cbAligned = ALIGN_UP(cb, DYNAMIC_HELPER_ALIGNMENT); \
-    BYTE * pStart = (BYTE *)(void *)pAllocator->GetDynamicHelpersHeap()->AllocAlignedMem(cbAligned, DYNAMIC_HELPER_ALIGNMENT); \
-    BYTE * p = pStart; \
-    static const size_t rxOffset = 0; \
-    auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-
-#define END_DYNAMIC_HELPER_EMIT() \
-    _ASSERTE(pStart + cb == p); \
-    while (p < pStart + cbAligned) { *(DWORD*)p = 0xBADC0DF0; p += 4; }\
-    ClrFlushInstructionCache(pStart, cbAligned); \
-    return (PCODE)pStart
-#else // defined(HOST_OSX) && defined(HOST_ARM64)
 #define BEGIN_DYNAMIC_HELPER_EMIT(size) \
     SIZE_T cb = size; \
     SIZE_T cbAligned = ALIGN_UP(cb, DYNAMIC_HELPER_ALIGNMENT); \
@@ -1896,7 +1864,6 @@ void StubLinkerCPU::EmitCallManagedMethod(MethodDesc *pMD, BOOL fTailCall)
     while (p < pStart + cbAligned) { *(DWORD*)p = 0xBADC0DF0; p += 4; }\
     ClrFlushInstructionCache(pStartRX, cbAligned); \
     return (PCODE)pStartRX
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
 
 // Uses x8 as scratch register to store address of data label
 // After load x8 is increment to point to next data
index 80108bd..bdc4bc8 100644 (file)
@@ -251,10 +251,6 @@ const CallCountingStub *CallCountingManager::CallCountingStubAllocator::Allocate
     }
     CONTRACTL_END;
 
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-    auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
     LoaderHeap *heap = m_heap;
     if (heap == nullptr)
     {
index fa32e4e..1a1545d 100644 (file)
@@ -62,10 +62,6 @@ void CallDescrWorkerWithHandler(
 
 #endif
 
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-    auto jitWriteEnableHolder = PAL_JITWriteEnable(false);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
     BEGIN_CALL_TO_MANAGEDEX(fCriticalCall ? EEToManagedCriticalCall : EEToManagedDefault);
 
     CallDescrWorker(pCallDescrData);
index 6ccf233..14e9dd9 100644 (file)
@@ -984,10 +984,6 @@ void EEStartupHelper()
 
         Assembly::Initialize();
 
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-        PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
         SystemDomain::System()->Init();
 
 #ifdef PROFILING_SUPPORTED
index 0aabeda..171251a 100644 (file)
@@ -1901,10 +1901,6 @@ TaggedMemAllocPtr CodeFragmentHeap::RealAllocAlignedMem(size_t  dwRequestedSize
 {
     CrstHolder ch(&m_CritSec);
 
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-    auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
     dwRequestedSize = ALIGN_UP(dwRequestedSize, sizeof(TADDR));
 
     // We will try to batch up allocation of small blocks into one large allocation
@@ -1982,10 +1978,6 @@ void CodeFragmentHeap::RealBackoutMem(void *pMem
     CrstHolder ch(&m_CritSec);
 
     {
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-        auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
         ExecutableWriterHolder<BYTE> memWriterHolder((BYTE*)pMem, dwSize);
         ZeroMemory(memWriterHolder.GetRW(), dwSize);
     }
@@ -2693,6 +2685,7 @@ void EEJitManager::allocCode(MethodDesc* pMD, size_t blockSize, size_t reserveFo
         pCodeHdr = ((CodeHeader *)pCode) - 1;
 
         *pAllocatedSize = sizeof(CodeHeader) + totalSize;
+#define FEATURE_WXORX        
 #ifdef FEATURE_WXORX
         pCodeHdrRW = (CodeHeader *)new BYTE[*pAllocatedSize];
 #else
@@ -3465,10 +3458,6 @@ void EEJitManager::CleanupCodeHeaps()
     HostCodeHeap *pHeap = m_cleanupList;
     m_cleanupList = NULL;
 
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-    auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
     while (pHeap)
     {
         HostCodeHeap *pNextHeap = pHeap->m_pNextHeapToRelease;
@@ -4961,10 +4950,6 @@ void ExecutionManager::Unload(LoaderAllocator *pLoaderAllocator)
         GC_NOTRIGGER;
     } CONTRACTL_END;
 
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-    auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
     // a size of 0 is a signal to Nirvana to flush the entire cache
     FlushInstructionCache(GetCurrentProcess(),0,0);
 
index 599c75a..b6c1726 100644 (file)
@@ -1046,10 +1046,6 @@ FCIMPL5(FC_BOOL_RET, COMDelegate::BindToMethodInfo, Object* refThisUNSAFE, Objec
                                             flags,
                                             &fIsOpenDelegate))
     {
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-        auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
         // Initialize the delegate to point to the target method.
         BindToMethod(&gc.refThis,
                      &gc.refFirstArg,
@@ -1622,10 +1618,6 @@ FCIMPL3(void, COMDelegate::DelegateConstruct, Object* refThisUNSAFE, Object* tar
     // try to catch the easy garbage.
     _ASSERTE(isMemoryReadable(method, 1));
 
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-    auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
     MethodTable *pMTTarg = NULL;
 
     if (gc.target != NULL)
index 1420d18..4a88f81 100644 (file)
@@ -74,10 +74,6 @@ public:
 
         CrstHolder ch(&m_crst);
 
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-        auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
         if (m_pHead == NULL)
         {
             m_pHead = pThunkRX;
@@ -159,9 +155,6 @@ UMEntryThunk *UMEntryThunkCache::GetUMEntryThunk(MethodDesc *pMD)
     else
     {
         // cache miss -> create a new thunk
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-        auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
         pThunk = UMEntryThunk::CreateUMEntryThunk();
         Holder<UMEntryThunk *, DoNothing, UMEntryThunk::FreeUMEntryThunk> umHolder;
         umHolder.Assign(pThunk);
@@ -284,9 +277,6 @@ void STDCALL UMEntryThunk::DoRunTimeInit(UMEntryThunk* pUMEntryThunk)
     {
         GCX_PREEMP();
 
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-        auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
         ExecutableWriterHolder<UMEntryThunk> uMEntryThunkWriterHolder(pUMEntryThunk, sizeof(UMEntryThunk));
         uMEntryThunkWriterHolder.GetRW()->RunTimeInit(pUMEntryThunk);
     }
@@ -331,10 +321,6 @@ void UMEntryThunk::Terminate()
 
     if (GetObjectHandle())
     {
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-        auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
         DestroyLongWeakHandle(GetObjectHandle());
         thunkWriterHolder.GetRW()->m_pObjectHandle = 0;
     }
index f5c5d29..14b7db5 100644 (file)
@@ -153,10 +153,6 @@ public:
         }
         CONTRACTL_END;
 
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-        auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
         m_pManagedTarget = pManagedTarget;
         m_pObjectHandle     = pObjectHandle;
         m_pUMThunkMarshInfo = pUMThunkMarshInfo;
@@ -189,10 +185,6 @@ public:
         m_code.Encode(&pUMEntryThunkRX->m_code, (BYTE*)m_pUMThunkMarshInfo->GetExecStubEntryPoint(), pUMEntryThunkRX);
 
 #ifdef _DEBUG
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-    auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
         m_state = kRunTimeInited;
 #endif // _DEBUG
     }
index 565243c..9dae86a 100644 (file)
@@ -570,10 +570,6 @@ void HostCodeHeap::AddToFreeList(TrackAllocation *pBlockToInsert, TrackAllocatio
 
     LOG((LF_BCL, LL_INFO100, "Level2 - CodeHeap [0x%p] - Add to FreeList [%p, 0x%X]\n", this, pBlockToInsert, pBlockToInsert->size));
 
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-    auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
     // append to the list in the proper position and coalesce if needed
     if (m_pFreeList)
     {
index 38d5598..be90259 100644 (file)
@@ -1468,10 +1468,6 @@ void
 ep_rt_prepare_provider_invoke_callback (EventPipeProviderCallbackData *provider_callback_data)
 {
        STATIC_CONTRACT_NOTHROW;
-
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-       auto jitWriteEnableHolder = PAL_JITWriteEnable(false);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
 }
 
 static
index 26c07ba..be856db 100644 (file)
@@ -1256,9 +1256,6 @@ bool IsGcCoverageInterrupt(LPVOID ip)
 
 void RemoveGcCoverageInterrupt(TADDR instrPtr, BYTE * savedInstrPtr, GCCoverageInfo* gcCover, DWORD offset)
 {
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-        auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
     ExecutableWriterHolder<void> instrPtrWriterHolder((void*)instrPtr, 4);
 #ifdef TARGET_ARM
         if (GetARMInstructionLength(savedInstrPtr) == 2)
index 5a6bd15..94b4a1b 100644 (file)
@@ -28,10 +28,6 @@ void EntryPointSlots::Backpatch_Locked(TADDR slot, SlotType slotType, PCODE entr
     _ASSERTE(entryPoint != NULL);
     _ASSERTE(IS_ALIGNED((SIZE_T)slot, GetRequiredSlotAlignment(slotType)));
 
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-    auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
     switch (slotType)
     {
         case SlotType_Normal:
index 718b4cb..80731c1 100644 (file)
@@ -405,10 +405,6 @@ void Precode::ResetTargetInterlocked()
 {
     WRAPPER_NO_CONTRACT;
 
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-    auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
     PrecodeType precodeType = GetType();
     switch (precodeType)
     {
@@ -442,10 +438,6 @@ BOOL Precode::SetTargetInterlocked(PCODE target, BOOL fOnlyRedirectFromPrestub)
     if (fOnlyRedirectFromPrestub && !IsPointingToPrestub(expected))
         return FALSE;
 
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-    auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
     g_IBCLogger.LogMethodPrecodeWriteAccess(GetMethodDesc());
 
     PrecodeType precodeType = GetType();
index 41c83b0..f75d62b 100644 (file)
@@ -326,10 +326,6 @@ PCODE MethodDesc::PrepareCode(PrepareCodeConfig* pConfig)
 {
     STANDARD_VM_CONTRACT;
 
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-    auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
     // If other kinds of code need multi-versioning we could add more cases here,
     // but for now generation of all other code/stubs occurs in other code paths
     _ASSERTE(IsIL() || IsNoMetadata());
@@ -2034,10 +2030,6 @@ extern "C" PCODE STDCALL PreStubWorker(TransitionBlock* pTransitionBlock, Method
 
         GCX_PREEMP_THREAD_EXISTS(CURRENT_THREAD);
         {
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-            auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
             pbRetVal = pMD->DoPrestub(pDispatchingMT, CallerGCMode::Coop);
         }
 
index f6b9e89..ee66f3e 100644 (file)
@@ -659,11 +659,6 @@ Thread* SetupThread()
     }
 #endif
 
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-    // Initialize new threads to JIT Write disabled
-    auto jitWriteEnableHolder = PAL_JITWriteEnable(false);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
     // Normally, HasStarted is called from the thread's entrypoint to introduce it to
     // the runtime.  But sometimes that thread is used for DLL_THREAD_ATTACH notifications
     // that call into managed code.  In that case, a call to SetupThread here must
@@ -1151,11 +1146,11 @@ void InitThreadManager()
         COMPlusThrowWin32();
     }
 
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-    auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
-    memcpy(s_barrierCopy, (BYTE*)JIT_PatchedCodeStart, (BYTE*)JIT_PatchedCodeLast - (BYTE*)JIT_PatchedCodeStart);
+    {
+        size_t writeBarrierSize = (BYTE*)JIT_PatchedCodeLast - (BYTE*)JIT_PatchedCodeStart;
+        ExecutableWriterHolder<void> barrierWriterHolder(s_barrierCopy, writeBarrierSize);
+        memcpy(barrierWriterHolder.GetRW(), (BYTE*)JIT_PatchedCodeStart, writeBarrierSize);
+    }
 
     // Store the JIT_WriteBarrier copy location to a global variable so that helpers
     // can jump to it.
index 6233386..d9d2c9b 100644 (file)
@@ -3645,10 +3645,6 @@ void Thread::CommitGCStressInstructionUpdate()
         assert(pbDestCode != NULL);
         assert(pbSrcCode != NULL);
 
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-        auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
         ExecutableWriterHolder<BYTE> destCodeWriterHolder(pbDestCode, sizeof(DWORD));
 
 #if defined(TARGET_X86) || defined(TARGET_AMD64)
index 94a5c59..95d568d 100644 (file)
@@ -1725,10 +1725,6 @@ PCODE VirtualCallStubManager::ResolveWorker(StubCallSite* pCallSite,
         PRECONDITION(IsProtectedByGCFrame(protectedObj));
     } CONTRACTL_END;
 
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-    auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
     MethodTable* objectType = (*protectedObj)->GetMethodTable();
     CONSISTENCY_CHECK(CheckPointer(objectType));
 
@@ -2989,10 +2985,6 @@ LookupHolder *VirtualCallStubManager::GenerateLookupStub(PCODE addrOfResolver, s
         POSTCONDITION(CheckPointer(RETVAL));
     } CONTRACT_END;
 
-#if defined(HOST_OSX) && defined(HOST_ARM64)
-    auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
-#endif // defined(HOST_OSX) && defined(HOST_ARM64)
-
     //allocate from the requisite heap and copy the template over it.
     LookupHolder * holder     = (LookupHolder*) (void*) lookup_heap->AllocAlignedMem(sizeof(LookupHolder), CODE_SIZE_ALIGN);
     ExecutableWriterHolder<LookupHolder> lookupWriterHolder(holder, sizeof(LookupHolder));