Skip to content

Commit 6448d21

Browse files
committed
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): Canonical link: https://commits.webkit.org/225669@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@262670 268f45cc-cd09-0410-ab3c-d52691b4dbfc
1 parent 0bd9074 commit 6448d21

3 files changed

Lines changed: 98 additions & 38 deletions

File tree

Source/JavaScriptCore/ChangeLog

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,33 @@
1+
2020-06-05 Michael Saboff <msaboff@apple.com>
2+
3+
Make FAST_JIT_PERMISSIONS check in LinkBuffer::copyCompactAndLinkCode a runtime check
4+
https://bugs.webkit.org/show_bug.cgi?id=212825
5+
6+
Reviewed by Saam Barati.
7+
8+
Added useFastJITPermissions() for runtime checks of FAST_JIT_PERMISSIONS
9+
including the cases where it is conditional on OS settings. This is now
10+
used in a few places to declutter the code.
11+
12+
When using the fast JIT permissions path, the JIT memory is the direct output
13+
of the linking. Modified BranchCompactionLinkBuffer to hold a pointer to that
14+
output "buffer" or a temporarily allocated buffer depending on if fast JIT
15+
permissions are enabled.
16+
17+
Broke out the "verify hash" conditionally compiled code with a file local
18+
ENABLE_VERIFY_JIT_HASH macro for readability.
19+
20+
* assembler/LinkBuffer.cpp:
21+
(JSC::BranchCompactionLinkBuffer::BranchCompactionLinkBuffer):
22+
(JSC::BranchCompactionLinkBuffer::~BranchCompactionLinkBuffer):
23+
Changed this to use a provided buffer or a malloc'ed buffer. When using
24+
a malloc'ed buffer, we put it in a thread local cache.
25+
26+
(JSC::LinkBuffer::copyCompactAndLinkCode):
27+
* jit/ExecutableAllocator.h:
28+
(JSC::useFastJITPermissions):
29+
(JSC::performJITMemcpy):
30+
131
2020-06-05 Yusuke Suzuki <ysuzuki@apple.com>
232

333
[JSC] Put dfgOpNames in __DATA,__const section instead of __DATA,__data

Source/JavaScriptCore/assembler/LinkBuffer.cpp

Lines changed: 56 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,27 @@ LinkBuffer::CodeRef<LinkBufferPtrTag> LinkBuffer::finalizeCodeWithDisassemblyImp
119119
}
120120

121121
#if ENABLE(BRANCH_COMPACTION)
122-
#if !CPU(ARM64E) || !ENABLE(FAST_JIT_PERMISSIONS)
122+
#if CPU(ARM64E)
123+
#define ENABLE_VERIFY_JIT_HASH 1
124+
#else
125+
#define ENABLE_VERIFY_JIT_HASH 0
126+
#endif
127+
128+
#if ENABLE(FAST_JIT_PERMISSIONS) && !ENABLE(SEPARATED_WX_HEAP)
129+
# define IF_FAST_JIT_PERMISSIONS(thenStmt) thenStmt
130+
# define IF_FAST_JIT_PERMISSIONS_ELSE(thenStmt, elseStmt) thenStmt
131+
#elif ENABLE(FAST_JIT_PERMISSIONS)
132+
# define IF_FAST_JIT_PERMISSIONS(thenStmt) if (useFastJITPermissions()) \
133+
thenStmt
134+
# define IF_FAST_JIT_PERMISSIONS_ELSE(thenStmt, elseStmt) if (useFastJITPermissions()) \
135+
thenStmt; \
136+
else \
137+
elseStmt
138+
#else
139+
# define IF_FAST_JIT_PERMISSIONS(thenStmt)
140+
# define IF_FAST_JIT_PERMISSIONS_ELSE(thenStmt, elseStmt) elseStmt
141+
#endif
142+
123143
class BranchCompactionLinkBuffer;
124144

125145
using ThreadSpecificBranchCompactionLinkBuffer = ThreadSpecific<BranchCompactionLinkBuffer, WTF::CanBeGCThread::True>;
@@ -146,8 +166,15 @@ class BranchCompactionLinkBuffer {
146166
{
147167
}
148168

149-
BranchCompactionLinkBuffer(size_t size)
169+
BranchCompactionLinkBuffer(size_t size, uint8_t* userBuffer = nullptr)
150170
{
171+
if (userBuffer) {
172+
m_data = userBuffer;
173+
m_size = size;
174+
m_bufferProvided = true;
175+
return;
176+
}
177+
151178
auto& threadSpecific = threadSpecificBranchCompactionLinkBuffer();
152179

153180
if (threadSpecific->size() >= size)
@@ -160,6 +187,9 @@ class BranchCompactionLinkBuffer {
160187

161188
~BranchCompactionLinkBuffer()
162189
{
190+
if (m_bufferProvided)
191+
return;
192+
163193
auto& threadSpecific = threadSpecificBranchCompactionLinkBuffer();
164194
threadSpecific->takeBufferIfLarger(*this);
165195

@@ -195,8 +225,8 @@ class BranchCompactionLinkBuffer {
195225

196226
uint8_t* m_data { nullptr };
197227
size_t m_size { 0 };
228+
bool m_bufferProvided { false };
198229
};
199-
#endif
200230

201231
static ALWAYS_INLINE void recordLinkOffsets(AssemblerData& assemblerData, int32_t regionStart, int32_t regionEnd, int32_t offset)
202232
{
@@ -220,14 +250,15 @@ void LinkBuffer::copyCompactAndLinkCode(MacroAssembler& macroAssembler, JITCompi
220250
uint8_t* inData = reinterpret_cast<uint8_t*>(m_assemblerStorage.buffer());
221251

222252
uint8_t* codeOutData = m_code.dataLocation<uint8_t*>();
223-
#if CPU(ARM64E) && ENABLE(FAST_JIT_PERMISSIONS)
253+
254+
#if ENABLE(VERIFY_JIT_HASH)
224255
const uint32_t expectedFinalHash = macroAssembler.m_assembler.buffer().hash().finalHash();
225256
ARM64EHash verifyUncompactedHash;
226-
uint8_t* outData = codeOutData;
227-
#else
228-
BranchCompactionLinkBuffer outBuffer(m_size);
229-
uint8_t* outData = reinterpret_cast<uint8_t*>(outBuffer.data());
230257
#endif
258+
259+
BranchCompactionLinkBuffer outBuffer(m_size, useFastJITPermissions() ? codeOutData : 0);
260+
uint8_t* outData = outBuffer.data();
261+
231262
#if CPU(ARM64)
232263
RELEASE_ASSERT(roundUpToMultipleOf<sizeof(unsigned)>(outData) == outData);
233264
RELEASE_ASSERT(roundUpToMultipleOf<sizeof(unsigned)>(codeOutData) == codeOutData);
@@ -237,9 +268,7 @@ void LinkBuffer::copyCompactAndLinkCode(MacroAssembler& macroAssembler, JITCompi
237268
int writePtr = 0;
238269
unsigned jumpCount = jumpsToLink.size();
239270

240-
#if CPU(ARM64E) && ENABLE(FAST_JIT_PERMISSIONS)
241-
os_thread_self_restrict_rwx_to_rw();
242-
#endif
271+
IF_FAST_JIT_PERMISSIONS(os_thread_self_restrict_rwx_to_rw());
243272

244273
if (m_shouldPerformBranchCompaction) {
245274
for (unsigned i = 0; i < jumpCount; ++i) {
@@ -256,7 +285,7 @@ void LinkBuffer::copyCompactAndLinkCode(MacroAssembler& macroAssembler, JITCompi
256285
ASSERT(!(writePtr % 2));
257286
while (copySource != copyEnd) {
258287
InstructionType insn = *copySource++;
259-
#if CPU(ARM64E) && ENABLE(FAST_JIT_PERMISSIONS)
288+
#if ENABLE(VERIFY_JIT_HASH)
260289
static_assert(sizeof(InstructionType) == 4, "");
261290
verifyUncompactedHash.update(insn);
262291
#endif
@@ -305,14 +334,14 @@ void LinkBuffer::copyCompactAndLinkCode(MacroAssembler& macroAssembler, JITCompi
305334

306335
for (size_t i = 0; i < bytes; i += sizeof(InstructionType)) {
307336
InstructionType insn = *src++;
308-
#if CPU(ARM64E) && ENABLE(FAST_JIT_PERMISSIONS)
337+
#if ENABLE(VERIFY_JIT_HASH)
309338
verifyUncompactedHash.update(insn);
310339
#endif
311340
*dst++ = insn;
312341
}
313342
}
314343

315-
#if CPU(ARM64E) && ENABLE(FAST_JIT_PERMISSIONS)
344+
#if ENABLE(VERIFY_JIT_HASH)
316345
if (verifyUncompactedHash.finalHash() != expectedFinalHash) {
317346
#ifndef NDEBUG
318347
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,40 +356,32 @@ void LinkBuffer::copyCompactAndLinkCode(MacroAssembler& macroAssembler, JITCompi
327356
for (unsigned i = 0; i < jumpCount; ++i) {
328357
uint8_t* location = codeOutData + jumpsToLink[i].from();
329358
uint8_t* target = codeOutData + jumpsToLink[i].to() - executableOffsetFor(jumpsToLink[i].to());
330-
#if CPU(ARM64E) && ENABLE(FAST_JIT_PERMISSIONS)
331-
MacroAssembler::link<memcpy>(jumpsToLink[i], outData + jumpsToLink[i].from(), location, target);
332-
#else
333-
MacroAssembler::link<performJITMemcpy>(jumpsToLink[i], outData + jumpsToLink[i].from(), location, target);
334-
#endif
359+
IF_FAST_JIT_PERMISSIONS_ELSE(MacroAssembler::link<memcpy>(jumpsToLink[i], outData + jumpsToLink[i].from(), location, target), \
360+
MacroAssembler::link<performJITMemcpy>(jumpsToLink[i], outData + jumpsToLink[i].from(), location, target));
335361
}
336362

337363
size_t compactSize = writePtr + initialSize - readPtr;
338364
if (!m_executableMemory) {
339365
size_t nopSizeInBytes = initialSize - compactSize;
340-
#if CPU(ARM64E) && ENABLE(FAST_JIT_PERMISSIONS)
341-
Assembler::fillNops<memcpy>(outData + compactSize, nopSizeInBytes);
342-
#else
343-
Assembler::fillNops<performJITMemcpy>(outData + compactSize, nopSizeInBytes);
344-
#endif
366+
IF_FAST_JIT_PERMISSIONS_ELSE(Assembler::fillNops<memcpy>(outData + compactSize, nopSizeInBytes), \
367+
Assembler::fillNops<performJITMemcpy>(outData + compactSize, nopSizeInBytes));
345368
}
346369

347-
#if CPU(ARM64E) && ENABLE(FAST_JIT_PERMISSIONS)
348-
os_thread_self_restrict_rwx_to_rx();
349-
#endif
370+
IF_FAST_JIT_PERMISSIONS(os_thread_self_restrict_rwx_to_rx());
350371

351372
if (m_executableMemory) {
352373
m_size = compactSize;
353374
m_executableMemory->shrink(m_size);
354375
}
355376

356-
#if !CPU(ARM64E) || !ENABLE(FAST_JIT_PERMISSIONS)
357-
ASSERT(codeOutData != outData);
358-
performJITMemcpy(codeOutData, outData, m_size);
359-
#else
360-
ASSERT(codeOutData == outData);
361-
if (UNLIKELY(Options::dumpJITMemoryPath()))
362-
dumpJITMemory(outData, outData, m_size);
363-
#endif
377+
if (useFastJITPermissions()) {
378+
ASSERT(codeOutData == outData);
379+
if (UNLIKELY(Options::dumpJITMemoryPath()))
380+
dumpJITMemory(outData, outData, m_size);
381+
} else {
382+
ASSERT(codeOutData != outData);
383+
performJITMemcpy(codeOutData, outData, m_size);
384+
}
364385

365386
jumpsToLink.clear();
366387

Source/JavaScriptCore/jit/ExecutableAllocator.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,17 @@ JS_EXPORT_PRIVATE bool isJITPC(void* pc);
113113

114114
JS_EXPORT_PRIVATE void dumpJITMemory(const void*, const void*, size_t);
115115

116+
static ALWAYS_INLINE bool useFastJITPermissions()
117+
{
118+
#if ENABLE(FAST_JIT_PERMISSIONS) && !ENABLE(SEPARATED_WX_HEAP)
119+
return true;
120+
#elif ENABLE(FAST_JIT_PERMISSIONS)
121+
return g_jscConfig.useFastPermisionsJITCopy;
122+
#else
123+
return false;
124+
#endif
125+
}
126+
116127
static ALWAYS_INLINE void* performJITMemcpy(void *dst, const void *src, size_t n)
117128
{
118129
#if CPU(ARM64)
@@ -126,9 +137,7 @@ static ALWAYS_INLINE void* performJITMemcpy(void *dst, const void *src, size_t n
126137
if (UNLIKELY(Options::dumpJITMemoryPath()))
127138
dumpJITMemory(dst, src, n);
128139
#if ENABLE(FAST_JIT_PERMISSIONS)
129-
#if ENABLE(SEPARATED_WX_HEAP)
130-
if (g_jscConfig.useFastPermisionsJITCopy)
131-
#endif
140+
if (useFastJITPermissions())
132141
{
133142
os_thread_self_restrict_rwx_to_rw();
134143
memcpy(dst, src, n);

0 commit comments

Comments
 (0)