diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /js/src/jit/Linker.cpp | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'js/src/jit/Linker.cpp')
-rw-r--r-- | js/src/jit/Linker.cpp | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/js/src/jit/Linker.cpp b/js/src/jit/Linker.cpp new file mode 100644 index 0000000000..aedebcecbe --- /dev/null +++ b/js/src/jit/Linker.cpp @@ -0,0 +1,79 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * vim: set ts=8 sts=2 et sw=2 tw=80: + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "jit/Linker.h" + +#include "jit/JitZone.h" +#include "util/Memory.h" + +#include "gc/StoreBuffer-inl.h" + +namespace js { +namespace jit { + +JitCode* Linker::newCode(JSContext* cx, CodeKind kind) { + JS::AutoAssertNoGC nogc(cx); + if (masm.oom()) { + return fail(cx); + } + + static const size_t ExecutableAllocatorAlignment = sizeof(void*); + static_assert(CodeAlignment >= ExecutableAllocatorAlignment, + "Unexpected alignment requirements"); + + // We require enough bytes for the code, header, and worst-case alignment + // padding. + size_t bytesNeeded = masm.bytesNeeded() + sizeof(JitCodeHeader) + + (CodeAlignment - ExecutableAllocatorAlignment); + if (bytesNeeded >= MAX_BUFFER_SIZE) { + return fail(cx); + } + + // ExecutableAllocator requires bytesNeeded to be aligned. + bytesNeeded = AlignBytes(bytesNeeded, ExecutableAllocatorAlignment); + + JitZone* jitZone = cx->zone()->getJitZone(cx); + if (!jitZone) { + // Note: don't call fail(cx) here, getJitZone reports OOM. + return nullptr; + } + + ExecutablePool* pool; + uint8_t* result = + (uint8_t*)jitZone->execAlloc().alloc(cx, bytesNeeded, &pool, kind); + if (!result) { + return fail(cx); + } + + // The JitCodeHeader will be stored right before the code buffer. + uint8_t* codeStart = result + sizeof(JitCodeHeader); + + // Bump the code up to a nice alignment. + codeStart = (uint8_t*)AlignBytes((uintptr_t)codeStart, CodeAlignment); + MOZ_ASSERT(codeStart + masm.bytesNeeded() <= result + bytesNeeded); + uint32_t headerSize = codeStart - result; + JitCode* code = + JitCode::New<NoGC>(cx, codeStart, bytesNeeded, headerSize, pool, kind); + if (!code) { + return fail(cx); + } + if (masm.oom()) { + return fail(cx); + } + awjcf.emplace(result, bytesNeeded); + if (!awjcf->makeWritable()) { + return fail(cx); + } + code->copyFrom(masm); + masm.link(code); + if (masm.embedsNurseryPointers()) { + cx->runtime()->gc.storeBuffer().putWholeCell(code); + } + return code; +} + +} // namespace jit +} // namespace js |