Files

45 lines
1.7 KiB
C++
Raw Permalink Normal View History

// SPDX-FileCopyrightText: 2002-2026 PCSX2 Dev Team
2024-07-30 13:42:36 +02:00
// SPDX-License-Identifier: GPL-3.0+
2021-09-21 20:05:20 +10:00
#pragma once
#include "Pcsx2Defs.h"
#include <cstdint>
#include <cstddef>
struct fastjmp_buf
{
2022-03-21 09:43:18 +01:00
#if defined(_WIN32)
2021-09-21 20:05:20 +10:00
static constexpr std::size_t BUF_SIZE = 240;
2026-03-10 23:40:32 -05:00
#elif defined(ARCH_ARM64)
static constexpr std::size_t BUF_SIZE = 168;
2021-09-21 20:05:20 +10:00
#else
2022-03-21 09:43:18 +01:00
static constexpr std::size_t BUF_SIZE = 64;
2021-09-21 20:05:20 +10:00
#endif
alignas(16) std::uint8_t buf[BUF_SIZE];
};
// fastjmp_set can "return twice" (once normally with 0, and again via fastjmp_jmp with the
// passed value), exactly like setjmp. It MUST be marked returns_twice so the compiler does
// not optimize the calling function assuming the code after the call runs only once — most
// importantly, so it does not tail-call-optimize a subsequent call (which would deallocate
// the caller's frame that fastjmp_set captured the SP of, leaving fastjmp_jmp to restore a
// frame whose saved registers have since been clobbered).
#if defined(__GNUC__) || defined(__clang__)
#define FASTJMP_RETURNS_TWICE __attribute__((returns_twice))
#else
#define FASTJMP_RETURNS_TWICE
#endif
2021-09-21 20:05:20 +10:00
extern "C" {
// returns_twice is load-bearing: without it the optimizer may pop the
// caller's frame and tail-call the code reached after fastjmp_set returns
// (observed with clang LTO inlining execI into intStep), leaving the armed
// jmp_buf's saved SP pointing into a successor's live frame — fastjmp_jmp
// then resumes on a clobbered stack and the caller returns into garbage.
// The attribute (same contract as setjmp) pins the frame and disables
// tail-call/value-caching transforms across the call.
FASTJMP_RETURNS_TWICE int fastjmp_set(fastjmp_buf* buf);
__noreturn void fastjmp_jmp(const fastjmp_buf* buf, int ret);
2021-09-21 20:05:20 +10:00
}