Modified: trunk/Source/_javascript_Core/ChangeLog (262669 => 262670)
--- trunk/Source/_javascript_Core/ChangeLog 2020-06-06 04:00:42 UTC (rev 262669)
+++ trunk/Source/_javascript_Core/ChangeLog 2020-06-06 04:25:04 UTC (rev 262670)
@@ -1,3 +1,33 @@
+2020-06-05 Michael Saboff <msab...@apple.com>
+
+ Make FAST_JIT_PERMISSIONS check in LinkBuffer::copyCompactAndLinkCode a runtime check
+ https://bugs.webkit.org/show_bug.cgi?id=212825
+
+ Reviewed by Saam Barati.
+
+ Added useFastJITPermissions() for runtime checks of FAST_JIT_PERMISSIONS
+ including the cases where it is conditional on OS settings. This is now
+ used in a few places to declutter the code.
+
+ When using the fast JIT permissions path, the JIT memory is the direct output
+ of the linking. Modified BranchCompactionLinkBuffer to hold a pointer to that
+ output "buffer" or a temporarily allocated buffer depending on if fast JIT
+ permissions are enabled.
+
+ Broke out the "verify hash" conditionally compiled code with a file local
+ ENABLE_VERIFY_JIT_HASH macro for readability.
+
+ * assembler/LinkBuffer.cpp:
+ (JSC::BranchCompactionLinkBuffer::BranchCompactionLinkBuffer):
+ (JSC::BranchCompactionLinkBuffer::~BranchCompactionLinkBuffer):
+ Changed this to use a provided buffer or a malloc'ed buffer. When using
+ a malloc'ed buffer, we put it in a thread local cache.
+
+ (JSC::LinkBuffer::copyCompactAndLinkCode):
+ * jit/ExecutableAllocator.h:
+ (JSC::useFastJITPermissions):
+ (JSC::performJITMemcpy):
+
2020-06-05 Yusuke Suzuki <ysuz...@apple.com>
[JSC] Put dfgOpNames in __DATA,__const section instead of __DATA,__data
Modified: trunk/Source/_javascript_Core/assembler/LinkBuffer.cpp (262669 => 262670)
--- trunk/Source/_javascript_Core/assembler/LinkBuffer.cpp 2020-06-06 04:00:42 UTC (rev 262669)
+++ trunk/Source/_javascript_Core/assembler/LinkBuffer.cpp 2020-06-06 04:25:04 UTC (rev 262670)
@@ -119,7 +119,27 @@
}
#if ENABLE(BRANCH_COMPACTION)
-#if !CPU(ARM64E) || !ENABLE(FAST_JIT_PERMISSIONS)
+#if CPU(ARM64E)
+#define ENABLE_VERIFY_JIT_HASH 1
+#else
+#define ENABLE_VERIFY_JIT_HASH 0
+#endif
+
+#if ENABLE(FAST_JIT_PERMISSIONS) && !ENABLE(SEPARATED_WX_HEAP)
+# define IF_FAST_JIT_PERMISSIONS(thenStmt) thenStmt
+# define IF_FAST_JIT_PERMISSIONS_ELSE(thenStmt, elseStmt) thenStmt
+#elif ENABLE(FAST_JIT_PERMISSIONS)
+# define IF_FAST_JIT_PERMISSIONS(thenStmt) if (useFastJITPermissions()) \
+ thenStmt
+# define IF_FAST_JIT_PERMISSIONS_ELSE(thenStmt, elseStmt) if (useFastJITPermissions()) \
+ thenStmt; \
+ else \
+ elseStmt
+#else
+# define IF_FAST_JIT_PERMISSIONS(thenStmt)
+# define IF_FAST_JIT_PERMISSIONS_ELSE(thenStmt, elseStmt) elseStmt
+#endif
+
class BranchCompactionLinkBuffer;
using ThreadSpecificBranchCompactionLinkBuffer = ThreadSpecific<BranchCompactionLinkBuffer, WTF::CanBeGCThread::True>;
@@ -146,8 +166,15 @@
{
}
- BranchCompactionLinkBuffer(size_t size)
+ BranchCompactionLinkBuffer(size_t size, uint8_t* userBuffer = nullptr)
{
+ if (userBuffer) {
+ m_data = userBuffer;
+ m_size = size;
+ m_bufferProvided = true;
+ return;
+ }
+
auto& threadSpecific = threadSpecificBranchCompactionLinkBuffer();
if (threadSpecific->size() >= size)
@@ -160,6 +187,9 @@
~BranchCompactionLinkBuffer()
{
+ if (m_bufferProvided)
+ return;
+
auto& threadSpecific = threadSpecificBranchCompactionLinkBuffer();
threadSpecific->takeBufferIfLarger(*this);
@@ -195,8 +225,8 @@
uint8_t* m_data { nullptr };
size_t m_size { 0 };
+ bool m_bufferProvided { false };
};
-#endif
static ALWAYS_INLINE void recordLinkOffsets(AssemblerData& assemblerData, int32_t regionStart, int32_t regionEnd, int32_t offset)
{
@@ -220,14 +250,15 @@
uint8_t* inData = reinterpret_cast<uint8_t*>(m_assemblerStorage.buffer());
uint8_t* codeOutData = m_code.dataLocation<uint8_t*>();
-#if CPU(ARM64E) && ENABLE(FAST_JIT_PERMISSIONS)
+
+#if ENABLE(VERIFY_JIT_HASH)
const uint32_t expectedFinalHash = macroAssembler.m_assembler.buffer().hash().finalHash();
ARM64EHash verifyUncompactedHash;
- uint8_t* outData = codeOutData;
-#else
- BranchCompactionLinkBuffer outBuffer(m_size);
- uint8_t* outData = reinterpret_cast<uint8_t*>(outBuffer.data());
#endif
+
+ BranchCompactionLinkBuffer outBuffer(m_size, useFastJITPermissions() ? codeOutData : 0);
+ uint8_t* outData = outBuffer.data();
+
#if CPU(ARM64)
RELEASE_ASSERT(roundUpToMultipleOf<sizeof(unsigned)>(outData) == outData);
RELEASE_ASSERT(roundUpToMultipleOf<sizeof(unsigned)>(codeOutData) == codeOutData);
@@ -237,9 +268,7 @@
int writePtr = 0;
unsigned jumpCount = jumpsToLink.size();
-#if CPU(ARM64E) && ENABLE(FAST_JIT_PERMISSIONS)
- os_thread_self_restrict_rwx_to_rw();
-#endif
+ IF_FAST_JIT_PERMISSIONS(os_thread_self_restrict_rwx_to_rw());
if (m_shouldPerformBranchCompaction) {
for (unsigned i = 0; i < jumpCount; ++i) {
@@ -256,7 +285,7 @@
ASSERT(!(writePtr % 2));
while (copySource != copyEnd) {
InstructionType insn = *copySource++;
-#if CPU(ARM64E) && ENABLE(FAST_JIT_PERMISSIONS)
+#if ENABLE(VERIFY_JIT_HASH)
static_assert(sizeof(InstructionType) == 4, "");
verifyUncompactedHash.update(insn);
#endif
@@ -305,7 +334,7 @@
for (size_t i = 0; i < bytes; i += sizeof(InstructionType)) {
InstructionType insn = *src++;
-#if CPU(ARM64E) && ENABLE(FAST_JIT_PERMISSIONS)
+#if ENABLE(VERIFY_JIT_HASH)
verifyUncompactedHash.update(insn);
#endif
*dst++ = insn;
@@ -312,7 +341,7 @@
}
}
-#if CPU(ARM64E) && ENABLE(FAST_JIT_PERMISSIONS)
+#if ENABLE(VERIFY_JIT_HASH)
if (verifyUncompactedHash.finalHash() != expectedFinalHash) {
#ifndef NDEBUG
dataLogLn("Hashes don't match: ", RawPointer(bitwise_cast<void*>(static_cast<uintptr_t>(verifyUncompactedHash.finalHash()))), " ", RawPointer(bitwise_cast<void*>(static_cast<uintptr_t>(expectedFinalHash))));
@@ -327,26 +356,18 @@
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());
-#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
+ IF_FAST_JIT_PERMISSIONS_ELSE(MacroAssembler::link<memcpy>(jumpsToLink[i], outData + jumpsToLink[i].from(), location, target), \
+ MacroAssembler::link<performJITMemcpy>(jumpsToLink[i], outData + jumpsToLink[i].from(), location, target));
}
size_t compactSize = writePtr + initialSize - readPtr;
if (!m_executableMemory) {
size_t nopSizeInBytes = initialSize - compactSize;
-#if CPU(ARM64E) && ENABLE(FAST_JIT_PERMISSIONS)
- Assembler::fillNops<memcpy>(outData + compactSize, nopSizeInBytes);
-#else
- Assembler::fillNops<performJITMemcpy>(outData + compactSize, nopSizeInBytes);
-#endif
+ IF_FAST_JIT_PERMISSIONS_ELSE(Assembler::fillNops<memcpy>(outData + compactSize, nopSizeInBytes), \
+ Assembler::fillNops<performJITMemcpy>(outData + compactSize, nopSizeInBytes));
}
-#if CPU(ARM64E) && ENABLE(FAST_JIT_PERMISSIONS)
- os_thread_self_restrict_rwx_to_rx();
-#endif
+ IF_FAST_JIT_PERMISSIONS(os_thread_self_restrict_rwx_to_rx());
if (m_executableMemory) {
m_size = compactSize;
@@ -353,14 +374,14 @@
m_executableMemory->shrink(m_size);
}
-#if !CPU(ARM64E) || !ENABLE(FAST_JIT_PERMISSIONS)
- ASSERT(codeOutData != outData);
- performJITMemcpy(codeOutData, outData, m_size);
-#else
- ASSERT(codeOutData == outData);
- if (UNLIKELY(Options::dumpJITMemoryPath()))
- dumpJITMemory(outData, outData, m_size);
-#endif
+ if (useFastJITPermissions()) {
+ ASSERT(codeOutData == outData);
+ if (UNLIKELY(Options::dumpJITMemoryPath()))
+ dumpJITMemory(outData, outData, m_size);
+ } else {
+ ASSERT(codeOutData != outData);
+ performJITMemcpy(codeOutData, outData, m_size);
+ }
jumpsToLink.clear();
Modified: trunk/Source/_javascript_Core/jit/ExecutableAllocator.h (262669 => 262670)
--- trunk/Source/_javascript_Core/jit/ExecutableAllocator.h 2020-06-06 04:00:42 UTC (rev 262669)
+++ trunk/Source/_javascript_Core/jit/ExecutableAllocator.h 2020-06-06 04:25:04 UTC (rev 262670)
@@ -113,6 +113,17 @@
JS_EXPORT_PRIVATE void dumpJITMemory(const void*, const void*, size_t);
+static ALWAYS_INLINE bool useFastJITPermissions()
+{
+#if ENABLE(FAST_JIT_PERMISSIONS) && !ENABLE(SEPARATED_WX_HEAP)
+ return true;
+#elif ENABLE(FAST_JIT_PERMISSIONS)
+ return g_jscConfig.useFastPermisionsJITCopy;
+#else
+ return false;
+#endif
+}
+
static ALWAYS_INLINE void* performJITMemcpy(void *dst, const void *src, size_t n)
{
#if CPU(ARM64)
@@ -126,9 +137,7 @@
if (UNLIKELY(Options::dumpJITMemoryPath()))
dumpJITMemory(dst, src, n);
#if ENABLE(FAST_JIT_PERMISSIONS)
-#if ENABLE(SEPARATED_WX_HEAP)
- if (g_jscConfig.useFastPermisionsJITCopy)
-#endif
+ if (useFastJITPermissions())
{
os_thread_self_restrict_rwx_to_rw();
memcpy(dst, src, n);