From 964e7c20b53673a909bbd13f9bbda2dcac0a4be3 Mon Sep 17 00:00:00 2001 From: kobalicek Date: Mon, 16 Jun 2025 10:13:04 +0200 Subject: [PATCH] [abi] API cleanup and documentation fixes * Added first node to Zone so the reset is simpler * Added x86::Xmm/Ymm/Zmm deprecated aliases of x86::Vec to make user code not break when using these deprecated types * Documentation fixes and clarifications --- .github/workflows/build.yml | 187 ++++++++++++++++---------------- src/asmjit/a64.h | 4 +- src/asmjit/arm/a64assembler.cpp | 2 +- src/asmjit/arm/a64operand.h | 8 ++ src/asmjit/core.h | 50 ++++++--- src/asmjit/core/assembler.cpp | 2 +- src/asmjit/core/codeholder.cpp | 8 +- src/asmjit/core/codeholder.h | 2 +- src/asmjit/core/zone.cpp | 144 ++++++++++++------------ src/asmjit/core/zone.h | 80 +++++--------- src/asmjit/x86.h | 4 +- src/asmjit/x86/x86assembler.cpp | 2 +- src/asmjit/x86/x86operand.h | 48 ++++++++ tools/configure-sanitizers.sh | 4 + 14 files changed, 300 insertions(+), 245 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6b803b0..6108f22 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -35,105 +35,100 @@ jobs: fail-fast: false matrix: include: - - { title: "diag-analyze" , host: "ubuntu-latest" , arch: "x64" , cc: "clang-19", conf: "Debug" , defs: "ASMJIT_TEST=0", diagnostics: "analyze-build"} - - { title: "diag-asan" , host: "ubuntu-latest" , arch: "x64" , cc: "clang-19", conf: "Release", defs: "ASMJIT_TEST=1", diagnostics: "asan", } - - { title: "diag-msan" , host: "ubuntu-latest" , arch: "x64" , cc: "clang-19", conf: "Release", defs: "ASMJIT_TEST=1", diagnostics: "msan", } - - { title: "diag-ubsan" , host: "ubuntu-latest" , arch: "x64" , cc: "clang-19", conf: "Release", defs: "ASMJIT_TEST=1", diagnostics: "ubsan", } - - { title: "diag-hardened" , host: "ubuntu-latest" , arch: "x64" , cc: "clang-19", conf: "Release", defs: "ASMJIT_TEST=1", diagnostics: "hardened", } - - { title: "diag-valgrind" , host: "ubuntu-latest" , arch: "x64" , cc: "clang-19", conf: "Release", defs: "ASMJIT_TEST=1", diagnostics: "valgrind", } - - { title: "no-deprecated" , host: "ubuntu-latest" , arch: "x64" , cc: "clang-19", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_DEPRECATED=1" } - - { title: "no-intrinsics" , host: "ubuntu-latest" , arch: "x64" , cc: "clang-19", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_INTRINSICS=1" } - - { title: "no-logging" , host: "ubuntu-latest" , arch: "x64" , cc: "clang-19", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_LOGGING=1" } - - { title: "no-logging-text" , host: "ubuntu-latest" , arch: "x64" , cc: "clang-19", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_LOGGING=1,ASMJIT_NO_TEXT=1" } - - { title: "no-builder" , host: "ubuntu-latest" , arch: "x64" , cc: "clang-19", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_BUILDER=1" } - - { title: "no-compiler" , host: "ubuntu-latest" , arch: "x64" , cc: "clang-19", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_COMPILER=1" } - - { title: "no-introspection", host: "ubuntu-latest" , arch: "x64" , cc: "clang-19", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_COMPILER=1,ASMJIT_NO_INTROSPECTION=1" } - - { title: "no-jit" , host: "ubuntu-latest" , arch: "x64" , cc: "clang-19", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_JIT=1" } - - { title: "no-validation" , host: "ubuntu-latest" , arch: "x64" , cc: "clang-19", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_VALIDATION=1" } - - { title: "no-x86" , host: "ubuntu-latest" , arch: "x64" , cc: "clang-19", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_X86=1" } - - { title: "no-aarch64" , host: "ubuntu-latest" , arch: "x64" , cc: "clang-19", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_AARCH64=1" } - - { title: "lang-c++20" , host: "ubuntu-latest" , arch: "x64" , cc: "clang-19", conf: "Debug" , defs: "ASMJIT_TEST=1,CMAKE_CXX_FLAGS=-std=c++20" } - - { title: "lang-c++23" , host: "ubuntu-latest" , arch: "x64" , cc: "clang-19", conf: "Debug" , defs: "ASMJIT_TEST=1,CMAKE_CXX_FLAGS=-std=c++23" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "gcc-9" , conf: "Debug" , defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "gcc-9" , conf: "Release", defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "gcc-9" , conf: "Debug" , defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "gcc-9" , conf: "Release", defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "gcc-10" , conf: "Debug" , defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "gcc-10" , conf: "Release", defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "gcc-10" , conf: "Debug" , defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "gcc-10" , conf: "Release", defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "gcc-11" , conf: "Debug" , defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "gcc-11" , conf: "Release", defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "gcc-11" , conf: "Debug" , defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "gcc-11" , conf: "Release", defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "gcc-12" , conf: "Debug" , defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "gcc-12" , conf: "Release", defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "gcc-12" , conf: "Debug" , defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "gcc-12" , conf: "Release", defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "gcc-13" , conf: "Debug" , defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "gcc-13" , conf: "Release", defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "gcc-13" , conf: "Debug" , defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "gcc-13" , conf: "Release", defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "clang-11", conf: "Debug" , defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "clang-11", conf: "Release", defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "clang-11", conf: "Debug" , defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "clang-11", conf: "Release", defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "clang-12", conf: "Debug" , defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "clang-12", conf: "Release", defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "clang-12", conf: "Debug" , defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "clang-12", conf: "Release", defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "clang-13", conf: "Debug" , defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "clang-13", conf: "Release", defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "clang-13", conf: "Debug" , defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "clang-13", conf: "Release", defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "clang-14", conf: "Debug" , defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "clang-14", conf: "Release", defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "clang-14", conf: "Debug" , defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "clang-14", conf: "Release", defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "clang-15", conf: "Debug" , defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "clang-15", conf: "Release", defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "clang-15", conf: "Debug" , defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "clang-15", conf: "Release", defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "clang-16", conf: "Debug" , defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "clang-16", conf: "Release", defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "clang-16", conf: "Debug" , defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "clang-16", conf: "Release", defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "clang-17", conf: "Debug" , defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "clang-17", conf: "Release", defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "clang-17", conf: "Debug" , defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "clang-17", conf: "Release", defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "clang-18", conf: "Debug" , defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x86" , cc: "clang-18", conf: "Release", defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "clang-18", conf: "Debug" , defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-22.04" , arch: "x64" , cc: "clang-18", conf: "Release", defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-24.04-arm", arch: "arm64" , cc: "clang-19", conf: "Debug" , defs: "ASMJIT_TEST=1" } - - { title: "linux" , host: "ubuntu-24.04-arm", arch: "arm64" , cc: "clang-19", conf: "Release", defs: "ASMJIT_TEST=1" } - - { title: "macos" , host: "macos-13" , arch: "x64" , cc: "gcc-14" , conf: "Debug" , defs: "ASMJIT_TEST=1" } - - { title: "macos" , host: "macos-13" , arch: "x64" , cc: "gcc-14" , conf: "Release", defs: "ASMJIT_TEST=1" } - - { title: "macos" , host: "macos-13" , arch: "x64" , cc: "clang" , conf: "Debug" , defs: "ASMJIT_TEST=1" } - - { title: "macos" , host: "macos-13" , arch: "x64" , cc: "clang" , conf: "Release", defs: "ASMJIT_TEST=1" } - - { title: "macos" , host: "macos-14" , arch: "arm64" , cc: "clang" , conf: "Debug" , defs: "ASMJIT_TEST=1" } - - { title: "macos" , host: "macos-14" , arch: "arm64" , cc: "clang" , conf: "Release", defs: "ASMJIT_TEST=1" } - - { title: "windows" , host: "windows-2022" , arch: "x86" , cc: "vs2022" , conf: "Debug" , defs: "ASMJIT_TEST=1" } - - { title: "windows" , host: "windows-2022" , arch: "x86" , cc: "vs2022" , conf: "Release", defs: "ASMJIT_TEST=1" } - - { title: "windows" , host: "windows-2022" , arch: "x64" , cc: "vs2022" , conf: "Debug" , defs: "ASMJIT_TEST=1" } - - { title: "windows" , host: "windows-2022" , arch: "x64" , cc: "vs2022" , conf: "Release", defs: "ASMJIT_TEST=1" } - - { title: "windows" , host: "windows-11-arm" , arch: "arm64" , cc: "vs2022" , conf: "Debug" , defs: "ASMJIT_TEST=1" } - - { title: "windows" , host: "windows-11-arm" , arch: "arm64" , cc: "vs2022" , conf: "Release", defs: "ASMJIT_TEST=1" } + - { title: "linux/analyze-build" , host: "ubuntu-24.04" , arch: "x64" , cc: "clang-19", conf: "Debug" , defs: "ASMJIT_TEST=0", diagnostics: "analyze-build"} + - { title: "linux/asan" , host: "ubuntu-24.04" , arch: "x64" , cc: "clang-19", conf: "Release", defs: "ASMJIT_TEST=1", diagnostics: "asan", } + - { title: "linux/msan" , host: "ubuntu-24.04" , arch: "x64" , cc: "clang-19", conf: "Release", defs: "ASMJIT_TEST=1", diagnostics: "msan", } + - { title: "linux/ubsan" , host: "ubuntu-24.04" , arch: "x64" , cc: "clang-19", conf: "Release", defs: "ASMJIT_TEST=1", diagnostics: "ubsan", } + - { title: "linux/hardened" , host: "ubuntu-24.04" , arch: "x64" , cc: "clang-19", conf: "Release", defs: "ASMJIT_TEST=1", diagnostics: "hardened", } + - { title: "linux/valgrind" , host: "ubuntu-24.04" , arch: "x64" , cc: "clang-19", conf: "Release", defs: "ASMJIT_TEST=1", diagnostics: "valgrind", } + - { title: "linux/no-deprecated" , host: "ubuntu-24.04" , arch: "x64" , cc: "clang-19", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_DEPRECATED=1" } + - { title: "linux/no-intrinsics" , host: "ubuntu-24.04" , arch: "x64" , cc: "clang-19", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_INTRINSICS=1" } + - { title: "linux/no-logging" , host: "ubuntu-24.04" , arch: "x64" , cc: "clang-19", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_LOGGING=1" } + - { title: "linux/no-logging-text" , host: "ubuntu-24.04" , arch: "x64" , cc: "clang-19", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_LOGGING=1,ASMJIT_NO_TEXT=1" } + - { title: "linux/no-builder" , host: "ubuntu-24.04" , arch: "x64" , cc: "clang-19", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_BUILDER=1" } + - { title: "linux/no-compiler" , host: "ubuntu-24.04" , arch: "x64" , cc: "clang-19", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_COMPILER=1" } + - { title: "linux/no-introspection", host: "ubuntu-24.04" , arch: "x64" , cc: "clang-19", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_COMPILER=1,ASMJIT_NO_INTROSPECTION=1" } + - { title: "linux/no-jit" , host: "ubuntu-24.04" , arch: "x64" , cc: "clang-19", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_JIT=1" } + - { title: "linux/no-validation" , host: "ubuntu-24.04" , arch: "x64" , cc: "clang-19", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_VALIDATION=1" } + - { title: "linux/no-x86" , host: "ubuntu-24.04" , arch: "x64" , cc: "clang-19", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_X86=1" } + - { title: "linux/no-aarch64" , host: "ubuntu-24.04" , arch: "x64" , cc: "clang-19", conf: "Release", defs: "ASMJIT_TEST=1,ASMJIT_NO_AARCH64=1" } + - { title: "linux/use-c++20" , host: "ubuntu-24.04" , arch: "x64" , cc: "clang-19", conf: "Debug" , defs: "ASMJIT_TEST=1,CMAKE_CXX_FLAGS=-std=c++20" } + - { title: "linux/use-c++23" , host: "ubuntu-24.04" , arch: "x64" , cc: "clang-19", conf: "Debug" , defs: "ASMJIT_TEST=1,CMAKE_CXX_FLAGS=-std=c++23" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x86" , cc: "gcc-9" , conf: "Debug" , defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x86" , cc: "gcc-9" , conf: "Release", defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x64" , cc: "gcc-9" , conf: "Debug" , defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x64" , cc: "gcc-9" , conf: "Release", defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x86" , cc: "gcc-10" , conf: "Debug" , defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x86" , cc: "gcc-10" , conf: "Release", defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x64" , cc: "gcc-10" , conf: "Debug" , defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x64" , cc: "gcc-10" , conf: "Release", defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x86" , cc: "gcc-11" , conf: "Debug" , defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x86" , cc: "gcc-11" , conf: "Release", defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x64" , cc: "gcc-11" , conf: "Debug" , defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x64" , cc: "gcc-11" , conf: "Release", defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x86" , cc: "gcc-12" , conf: "Debug" , defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x86" , cc: "gcc-12" , conf: "Release", defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x64" , cc: "gcc-12" , conf: "Debug" , defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x64" , cc: "gcc-12" , conf: "Release", defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x86" , cc: "gcc-13" , conf: "Debug" , defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x86" , cc: "gcc-13" , conf: "Release", defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x64" , cc: "gcc-13" , conf: "Debug" , defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x64" , cc: "gcc-13" , conf: "Release", defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x86" , cc: "gcc-14" , conf: "Debug" , defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x86" , cc: "gcc-14" , conf: "Release", defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x64" , cc: "gcc-14" , conf: "Debug" , defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x64" , cc: "gcc-14" , conf: "Release", defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x86" , cc: "clang-14", conf: "Debug" , defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x86" , cc: "clang-14", conf: "Release", defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x64" , cc: "clang-14", conf: "Debug" , defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x64" , cc: "clang-14", conf: "Release", defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x86" , cc: "clang-15", conf: "Debug" , defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x86" , cc: "clang-15", conf: "Release", defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x64" , cc: "clang-15", conf: "Debug" , defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x64" , cc: "clang-15", conf: "Release", defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x86" , cc: "clang-16", conf: "Debug" , defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x86" , cc: "clang-16", conf: "Release", defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x64" , cc: "clang-16", conf: "Debug" , defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x64" , cc: "clang-16", conf: "Release", defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x86" , cc: "clang-17", conf: "Debug" , defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x86" , cc: "clang-17", conf: "Release", defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x64" , cc: "clang-17", conf: "Debug" , defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x64" , cc: "clang-17", conf: "Release", defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x86" , cc: "clang-18", conf: "Debug" , defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x86" , cc: "clang-18", conf: "Release", defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x64" , cc: "clang-18", conf: "Debug" , defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x64" , cc: "clang-18", conf: "Release", defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x86" , cc: "clang-19", conf: "Debug" , defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x86" , cc: "clang-19", conf: "Release", defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x64" , cc: "clang-19", conf: "Debug" , defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04" , arch: "x64" , cc: "clang-19", conf: "Release", defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04-arm", arch: "arm64" , cc: "clang-19", conf: "Debug" , defs: "ASMJIT_TEST=1" } + - { title: "linux" , host: "ubuntu-24.04-arm", arch: "arm64" , cc: "clang-19", conf: "Release", defs: "ASMJIT_TEST=1" } + - { title: "macos" , host: "macos-13" , arch: "x64" , cc: "gcc-14" , conf: "Debug" , defs: "ASMJIT_TEST=1" } + - { title: "macos" , host: "macos-13" , arch: "x64" , cc: "gcc-14" , conf: "Release", defs: "ASMJIT_TEST=1" } + - { title: "macos" , host: "macos-13" , arch: "x64" , cc: "clang" , conf: "Debug" , defs: "ASMJIT_TEST=1" } + - { title: "macos" , host: "macos-13" , arch: "x64" , cc: "clang" , conf: "Release", defs: "ASMJIT_TEST=1" } + - { title: "macos" , host: "macos-14" , arch: "arm64" , cc: "clang" , conf: "Debug" , defs: "ASMJIT_TEST=1" } + - { title: "macos" , host: "macos-14" , arch: "arm64" , cc: "clang" , conf: "Release", defs: "ASMJIT_TEST=1" } + - { title: "windows" , host: "windows-2022" , arch: "x86" , cc: "vs2022" , conf: "Debug" , defs: "ASMJIT_TEST=1" } + - { title: "windows" , host: "windows-2022" , arch: "x86" , cc: "vs2022" , conf: "Release", defs: "ASMJIT_TEST=1" } + - { title: "windows" , host: "windows-2022" , arch: "x64" , cc: "vs2022" , conf: "Debug" , defs: "ASMJIT_TEST=1" } + - { title: "windows" , host: "windows-2022" , arch: "x64" , cc: "vs2022" , conf: "Release", defs: "ASMJIT_TEST=1" } + - { title: "windows" , host: "windows-11-arm" , arch: "arm64" , cc: "vs2022" , conf: "Debug" , defs: "ASMJIT_TEST=1" } + - { title: "windows" , host: "windows-11-arm" , arch: "arm64" , cc: "vs2022" , conf: "Release", defs: "ASMJIT_TEST=1" } # Cross compiled, cannot run tests (Windows/UWP). - - { title: "windows/uwp" , host: "windows-2022" , arch: "x64" , cc: "vs2022" , conf: "Release", defs: "ASMJIT_TEST=0,CMAKE_SYSTEM_NAME=WindowsStore,CMAKE_SYSTEM_VERSION=10.0,CMAKE_CXX_FLAGS=-D_WIN32_WINNT=0x0A00" } + - { title: "windows/uwp" , host: "windows-2022" , arch: "x64" , cc: "vs2022" , conf: "Release", defs: "ASMJIT_TEST=0,CMAKE_SYSTEM_NAME=WindowsStore,CMAKE_SYSTEM_VERSION=10.0,CMAKE_CXX_FLAGS=-D_WIN32_WINNT=0x0A00" } - - { title: "freebsd" , host: "ubuntu-latest" , arch: "x64" , cc: "clang" , conf: "Release", vm: "freebsd", vm_ver: "14.2", defs: "ASMJIT_TEST=1" } - - { title: "freebsd" , host: "ubuntu-latest" , arch: "arm64" , cc: "clang" , conf: "Release", vm: "freebsd", vm_ver: "14.2", defs: "ASMJIT_TEST=1" } - - { title: "netbsd" , host: "ubuntu-latest" , arch: "x64" , cc: "clang" , conf: "Release", vm: "netbsd" , vm_ver: "10.1", defs: "ASMJIT_TEST=1" } - - { title: "netbsd" , host: "ubuntu-latest" , arch: "arm64" , cc: "clang" , conf: "Release", vm: "netbsd" , vm_ver: "10.1", defs: "ASMJIT_TEST=1" } - - { title: "openbsd" , host: "ubuntu-latest" , arch: "x64" , cc: "clang" , conf: "Release", vm: "openbsd", vm_ver: "7.4" , defs: "ASMJIT_TEST=1" } - - { title: "openbsd" , host: "ubuntu-latest" , arch: "arm64" , cc: "clang" , conf: "Release", vm: "openbsd", vm_ver: "7.4" , defs: "ASMJIT_TEST=1" } - - - { title: "debian" , host: "ubuntu-latest" , arch: "arm/v7" , cc: "clang" , conf: "Release", vm: "debian:unstable", defs: "ASMJIT_TEST=1" } - - { title: "debian" , host: "ubuntu-latest" , arch: "riscv64", cc: "clang" , conf: "Release", vm: "debian:unstable", defs: "ASMJIT_TEST=1" } - - { title: "debian" , host: "ubuntu-latest" , arch: "ppc64le", cc: "clang" , conf: "Release", vm: "debian:unstable", defs: "ASMJIT_TEST=1" } + - { title: "freebsd" , host: "ubuntu-latest" , arch: "x64" , cc: "clang" , conf: "Release", vm: "freebsd", vm_ver: "14.2", defs: "ASMJIT_TEST=1" } + - { title: "freebsd" , host: "ubuntu-latest" , arch: "arm64" , cc: "clang" , conf: "Release", vm: "freebsd", vm_ver: "14.2", defs: "ASMJIT_TEST=1" } + - { title: "netbsd" , host: "ubuntu-latest" , arch: "x64" , cc: "clang" , conf: "Release", vm: "netbsd" , vm_ver: "10.1", defs: "ASMJIT_TEST=1" } + - { title: "netbsd" , host: "ubuntu-latest" , arch: "arm64" , cc: "clang" , conf: "Release", vm: "netbsd" , vm_ver: "10.1", defs: "ASMJIT_TEST=1" } + - { title: "openbsd" , host: "ubuntu-latest" , arch: "x64" , cc: "clang" , conf: "Release", vm: "openbsd", vm_ver: "7.4" , defs: "ASMJIT_TEST=1" } + - { title: "openbsd" , host: "ubuntu-latest" , arch: "arm64" , cc: "clang" , conf: "Release", vm: "openbsd", vm_ver: "7.4" , defs: "ASMJIT_TEST=1" } + - { title: "debian" , host: "ubuntu-latest" , arch: "arm/v7" , cc: "clang" , conf: "Release", vm: "debian:unstable", defs: "ASMJIT_TEST=1" } + - { title: "debian" , host: "ubuntu-latest" , arch: "riscv64", cc: "clang" , conf: "Release", vm: "debian:unstable", defs: "ASMJIT_TEST=1" } + - { title: "debian" , host: "ubuntu-latest" , arch: "ppc64le", cc: "clang" , conf: "Release", vm: "debian:unstable", defs: "ASMJIT_TEST=1" } name: "${{matrix.title}}/${{matrix.arch}}, ${{matrix.cc}} ${{matrix.conf}}" runs-on: "${{matrix.host}}" diff --git a/src/asmjit/a64.h b/src/asmjit/a64.h index 2aabf23..a2fd47b 100644 --- a/src/asmjit/a64.h +++ b/src/asmjit/a64.h @@ -26,8 +26,8 @@ //! //! ### Register Operands //! -//! - \ref a64::Gp - General purpose register (AArch64). -//! - \ref a64::Vec - Vector (SIMD) register. +//! - \ref a64::Gp - General purpose register (abstracts 32-bit and 64-bit general purpose registers). +//! - \ref a64::Vec - Vector register (abstracts B, H, S, D, and Q NEON register with possible element type and index). //! //! ### Memory Operands //! diff --git a/src/asmjit/arm/a64assembler.cpp b/src/asmjit/arm/a64assembler.cpp index fc7d4f8..69a4422 100644 --- a/src/asmjit/arm/a64assembler.cpp +++ b/src/asmjit/arm/a64assembler.cpp @@ -5115,7 +5115,7 @@ EmitOp_Rel: else { // Create a fixup referencing an non-bound label. size_t codeOffset = writer.offsetFrom(_bufferData); - Fixup* fixup = _code->newFixup(&le, _section->sectionId(), codeOffset, intptr_t(labelOffset), offsetFormat); + Fixup* fixup = _code->newFixup(le, _section->sectionId(), codeOffset, intptr_t(labelOffset), offsetFormat); if (ASMJIT_UNLIKELY(!fixup)) { goto OutOfMemory; diff --git a/src/asmjit/arm/a64operand.h b/src/asmjit/arm/a64operand.h index 646e9bf..2f5573b 100644 --- a/src/asmjit/arm/a64operand.h +++ b/src/asmjit/arm/a64operand.h @@ -677,10 +677,18 @@ namespace regs { [[nodiscard]] static ASMJIT_INLINE_CONSTEXPR Gp w(uint32_t id) noexcept { return Gp::make_r32(id); } +//! Creates a 32-bit W register operand. +[[nodiscard]] +static ASMJIT_INLINE_CONSTEXPR Gp gp32(uint32_t id) noexcept { return Gp::make_r32(id); } + //! Creates a 64-bit X register operand. [[nodiscard]] static ASMJIT_INLINE_CONSTEXPR Gp x(uint32_t id) noexcept { return Gp::make_r64(id); } +//! Creates a 64-bit X register operand. +[[nodiscard]] +static ASMJIT_INLINE_CONSTEXPR Gp gp64(uint32_t id) noexcept { return Gp::make_r64(id); } + //! Creates an 8-bit B register operand. [[nodiscard]] static ASMJIT_INLINE_CONSTEXPR Vec b(uint32_t id) noexcept { return Vec::make_v8(id); } diff --git a/src/asmjit/core.h b/src/asmjit/core.h index 6beedd4..216fa79 100644 --- a/src/asmjit/core.h +++ b/src/asmjit/core.h @@ -126,7 +126,7 @@ namespace asmjit { //! //! - Tested: //! -//! - **Clang** - Tested by GitHub Actions - Clang 10+ is officially supported and tested by CI, older Clang versions +//! - **Clang** - Tested by GitHub Actions - Clang 14+ is officially supported and tested by CI, older Clang versions //! having C++17 should work, but these versions are not tested anymore due to upgraded CI images. //! //! - **GNU** - Tested by GitHub Actions - GCC 9+ is officially supported and tested by CI, older GCC versions such @@ -134,18 +134,18 @@ namespace asmjit { //! //! - **MINGW** - Reported to work, but not tested in our CI environment (help welcome!). //! -//! - **MSVC** - Tested by GitHub Actions - VS2019 and onwards are officially supported and tested by CI, VS2015 and -//! VS2017 are not tested anymore due to upgraded CI images. +//! - **MSVC** - Tested by GitHub Actions - VS2022 and onwards are officially supported and tested by CI, VS2015, +//! VS2017, and VS2019 are not tested anymore due to upgraded CI images. VS2019 should work well. //! //! ### Supported Operating Systems and Platforms //! //! - Tested: //! //! - **BSD** - FreeBSD, NetBSD, and OpenBSD tested by GitHub Actions (only recent images are tested by CI). BSD -//! runners only test BSD images with clang compiler. +//! runners only test BSD images with Clang compiler. Both X86_64 and AArch64 host builds are tested. //! //! - **Linux** - Tested by GitHub Actions (only recent Ubuntu images are tested by CI, in general any distribution -//! should be supported as AsmJit has no dependencies). +//! should be supported as AsmJit has no dependencies). Linux tests X86, X86_64, and AArch64 host builds. //! //! - **Mac OS** - Tested by GitHub Actions. //! @@ -334,6 +334,11 @@ namespace asmjit { //! - Renamed `asmjit::BaseReg` to asmjit::Reg, added `asmjit::UniGp` and `asmjit::UniVec` which are now base //! classes for platform specific `[x86|a64]::Gp` and `[x86|a64]::Vec` //! +//! - Gp and Vec register API is now more platform independent - use `isGp32()` instead of `isGpd()`, similarly, +//! use `isGp64` instead of `isGpq()` (X86_64) or `isGpX()` (AArch64), etc... The same applies to vectors - +//! use `isVec128()` instead of `isXmm()` (X86) or `isVecQ()` (AArch64), `isVec256()` instead of `isYmm()`, +//! etc... +//! //! - Renamed some member functions in Operand and Reg: //! //! - `isType(regId)` -> `isReg(regId)` @@ -349,9 +354,18 @@ namespace asmjit { //! //! - Removed sub-registers `x86::Gpb`, `x86::GpbLo`, `x86::GpbHi`, `x86::Gpw`, `x86::Gpd`, `x86::Gpq`, `x86::Xmm`, //! `x86::Ymm`, `x86::Zmm` - use just `x86::Gp` and `x86::Vec`, which represent all removed X86 sub-registers. +//! From now, use `x86::Gp` to work with x86 general purpose registers and `x86::Vec` to work with XMM, YMM, +//! and ZMM registers. //! //! - Removed sub-registers `a64::GpW` and `a64::GpX`, `a64::VecB`, `a64::VecH`, `a64::VecS`, `a64::VecD`, -//! `a64::VecV`, which represent all removed AArch64 sub-registers. +//! `a64::VecV`, which represent all removed AArch64 sub-registers. From now, use `a64::Gp` to work with +//! general purpose registers and `a64::Vec` to work with NEON registers of any size, element type, and +//! element index. +//! +//! - Since sub-register types are gone it's no longer possible to write `gpb(id)` to get AL register, etc... +//! However, all register operands that can hold multiple register types now offer `Reg::make_xxx(id)` API, +//! which can be used as a convenience or just use platform specific API like `x86::gpd(id)` or `x86::gp32(id)`, +//! similarly for AArch64 use `a64::x(id)` or `a64::gp64(id)`, etc... //! //! - Renamed some id getters - `Section::id()` -> `Section::sectionId()`, etc... //! @@ -1114,11 +1128,15 @@ namespace asmjit { //! - \ref x86::Assembler - Assembler implementation targeting X86 and X86_64 architectures. //! - \ref a64::Assembler - Assembler implementation targeting AArch64 architecture. //! - \ref Operand and its variations: -//! - \ref BaseReg - Base class for a register operand, inherited by: -//! - \ref x86::Reg - Register operand specific to X86 and X86_64 architectures. -//! - \ref arm::Reg - Register operand specific to AArch64 architecture. +//! - \ref Reg - Base class for a register operand, inherited by: +//! - \ref UniGp - Universal abstraction of a general purpose register, inherited by: +//! - \ref x86::Gp - GP register operand specific to X86 and X86_64 architectures. +//! - \ref a64::Gp - GP Register operand specific to AArch64 architecture. +//! - \ref UniVec - Universal abstraction of a vector register, inherited by: +//! - \ref x86::Vec - Vector register operand specific to X86 and X86_64 architectures. +//! - \ref a64::Vec - Vector register operand specific to AArch64 architecture. //! - \ref BaseMem - Base class for a memory operand, inherited by: -//! - \ref x86::Mem - Memory operand specific to X86 architecture. +//! - \ref x86::Mem - Memory operand specific to X86 and X86_64 architectures. //! - \ref arm::Mem - Memory operand specific to AArch64 architecture. //! - \ref Imm - Immediate (value) operand. //! - \ref Label - Label operand. @@ -1972,7 +1990,7 @@ namespace asmjit { //! const ZoneVector& sections = code.sections(); //! //! // Contains all label entries managed by CodeHolder. -//! const ZoneVector& labelEntries = code.labelEntries(); +//! const ZoneVector& labelEntries = code.labelEntries(); //! //! // Contains all relocation entries managed by CodeHolder. //! const ZoneVector& relocEntries = code.relocEntries(); @@ -1987,11 +2005,11 @@ namespace asmjit { //! using namespace asmjit; //! //! void example(CodeHolder& code) { -//! for (LabelEntry* le : code.labelEntries()) { -//! printf("Label #%u {Bound=%s Offset=%llu}", -//! le->id(), -//! le->isBound() ? "true" : "false", -//! (unsigned long long)le->offset()); +//! for (uint32_t labelId = 0; labelId < code.labelCount(); labelId++) { +//! const LabelEntry& le = code.labelEntry(labelId); +//! if (le.isBound()) { +//! printf("Bound Label #%u at offset=%llu\n", labelId, (unsigned long long)le->offset()); +//! } //! } //! } //! ``` diff --git a/src/asmjit/core/assembler.cpp b/src/asmjit/core/assembler.cpp index c5c7361..a9f681d 100644 --- a/src/asmjit/core/assembler.cpp +++ b/src/asmjit/core/assembler.cpp @@ -306,7 +306,7 @@ Error BaseAssembler::embedLabel(const Label& label, size_t dataSize) { OffsetFormat of; of.resetToSimpleValue(OffsetType::kUnsignedOffset, dataSize); - Fixup* fixup = _code->newFixup(&le, _section->sectionId(), offset(), 0, of); + Fixup* fixup = _code->newFixup(le, _section->sectionId(), offset(), 0, of); if (ASMJIT_UNLIKELY(!fixup)) { return reportError(DebugUtils::errored(kErrorOutOfMemory)); } diff --git a/src/asmjit/core/codeholder.cpp b/src/asmjit/core/codeholder.cpp index fd29409..46b5709 100644 --- a/src/asmjit/core/codeholder.cpp +++ b/src/asmjit/core/codeholder.cpp @@ -664,23 +664,23 @@ static uint32_t CodeHolder_hashNameAndGetSize(const char* name, size_t& nameSize return hashCode; } -Fixup* CodeHolder::newFixup(LabelEntry* le, uint32_t sectionId, size_t offset, intptr_t rel, const OffsetFormat& format) noexcept { +Fixup* CodeHolder::newFixup(LabelEntry& le, uint32_t sectionId, size_t offset, intptr_t rel, const OffsetFormat& format) noexcept { // Cannot be bound if we are creating a link. - ASMJIT_ASSERT(!le->isBound()); + ASMJIT_ASSERT(!le.isBound()); Fixup* link = _fixupDataPool.alloc(_zone); if (ASMJIT_UNLIKELY(!link)) { return nullptr; } - link->next = le->_getFixups(); + link->next = le._getFixups(); link->sectionId = sectionId; link->labelOrRelocId = Globals::kInvalidId; link->offset = offset; link->rel = rel; link->format = format; - le->_setFixups(link); + le._setFixups(link); _unresolvedFixupCount++; return link; diff --git a/src/asmjit/core/codeholder.h b/src/asmjit/core/codeholder.h index 28cbb1f..dd60999 100644 --- a/src/asmjit/core/codeholder.h +++ b/src/asmjit/core/codeholder.h @@ -1124,7 +1124,7 @@ public: //! //! Returns `null` if the allocation failed. [[nodiscard]] - ASMJIT_API Fixup* newFixup(LabelEntry* le, uint32_t sectionId, size_t offset, intptr_t rel, const OffsetFormat& format) noexcept; + ASMJIT_API Fixup* newFixup(LabelEntry& le, uint32_t sectionId, size_t offset, intptr_t rel, const OffsetFormat& format) noexcept; //! Resolves cross-section fixups associated with each label that was used as a destination in code of a different //! section. It's only useful to people that use multiple sections as it will do nothing if the code only contains diff --git a/src/asmjit/core/zone.cpp b/src/asmjit/core/zone.cpp index 94e96c5..66ee09a 100644 --- a/src/asmjit/core/zone.cpp +++ b/src/asmjit/core/zone.cpp @@ -16,17 +16,15 @@ ASMJIT_BEGIN_NAMESPACE // and should never be modified. const Zone::Block Zone::_zeroBlock {}; -static inline void Zone_assignZeroBlock(Zone* zone) noexcept { - Zone::Block* block = const_cast(&zone->_zeroBlock); - zone->_ptr = block->data(); - zone->_end = block->data(); - zone->_block = block; +static ASMJIT_INLINE Zone::Block* Zone_getZeroBlock() noexcept { + return const_cast(&Zone::_zeroBlock); } -static inline void Zone_assignBlock(Zone* zone, Zone::Block* block) noexcept { +static ASMJIT_INLINE void Zone_assignBlock(Zone* zone, Zone::Block* block) noexcept { zone->_ptr = Support::alignUp(block->data(), Globals::kZoneAlignment); - zone->_end = block->data() + block->size; + zone->_end = block->end(); zone->_block = block; + ASMJIT_ASSERT(zone->_ptr <= zone->_end); } // Zone - Initialization & Reset @@ -36,8 +34,7 @@ void Zone::_init(size_t blockSize, const Support::Temporary* temporary) noexcept ASMJIT_ASSERT(blockSize >= kMinBlockSize); ASMJIT_ASSERT(blockSize <= kMaxBlockSize); - Zone_assignZeroBlock(this); - + Block* block = Zone_getZeroBlock(); size_t blockSizeShift = Support::bitSizeOf() - Support::clz(blockSize); _currentBlockSizeShift = uint8_t(blockSizeShift); @@ -48,65 +45,47 @@ void Zone::_init(size_t blockSize, const Support::Temporary* temporary) noexcept // Setup the first [temporary] block, if necessary. if (temporary) { - Block* block = temporary->data(); - block->prev = nullptr; + block = temporary->data(); block->next = nullptr; ASMJIT_ASSERT(temporary->size() >= kBlockSize); block->size = temporary->size() - kBlockSize; - - Zone_assignBlock(this, block); } + + _first = block; + Zone_assignBlock(this, block); } void Zone::reset(ResetPolicy resetPolicy) noexcept { - Block* cur = _block; - - // Can't be altered. - if (cur == &_zeroBlock) { - return; - } + Block* first = _first; if (resetPolicy == ResetPolicy::kHard) { - bool hasStatic = hasStaticBlock(); - Block* initial = const_cast(&_zeroBlock); + if (first == &_zeroBlock) { + return; + } + + Block* cur = first; + if (hasStaticBlock()) { + cur = cur->next; + first->next = nullptr; + } + else { + first = Zone_getZeroBlock(); + _first = first; + } - _ptr = initial->data(); - _end = initial->data(); - _block = initial; _currentBlockSizeShift = _minimumBlockSizeShift; - // Since cur can be in the middle of the double-linked list, we have to traverse both directions (`prev` and - // `next`) separately to visit all. - Block* next = cur->next; - do { - Block* prev = cur->prev; - - if (prev == nullptr && hasStatic) { - // If this is the first block and this Zone is actually a ZoneTmp then the first block cannot be freed. - cur->prev = nullptr; - cur->next = nullptr; - Zone_assignBlock(this, cur); - break; - } - - ::free(cur); - cur = prev; - } while (cur); - - cur = next; - while (cur) { - next = cur->next; - ::free(cur); - cur = next; + if (cur) { + do { + Block* next = cur->next; + ::free(cur); + cur = next; + } while (cur); } } - else { - while (cur->prev) { - cur = cur->prev; - } - Zone_assignBlock(this, cur); - } + + Zone_assignBlock(this, first); } // Zone - Alloc @@ -133,12 +112,14 @@ void* Zone::_alloc(size_t size) noexcept { // have to check for remaining bytes in that case. if (next) { uint8_t* ptr = Support::alignUp(next->data(), Globals::kZoneAlignment); - uint8_t* end = next->data() + next->size; + uint8_t* end = next->end(); if (size <= (size_t)(end - ptr)) { _block = next; _ptr = ptr + size; _end = end; + + ASMJIT_ASSERT(_ptr <= _end); return static_cast(ptr); } } @@ -170,30 +151,21 @@ void* Zone::_alloc(size_t size) noexcept { // Allocate new block. Block* newBlock = static_cast(::malloc(blockSize)); - if (ASMJIT_UNLIKELY(!newBlock)) { return nullptr; } - // blockSize includes the struct size, which must be avoided when assigning the size to a newly allocated block. + // blockSize includes the struct size, which must be accounted when assigning size to a newly allocated block. size_t realBlockSize = blockSize - kBlockSize; - // Align the pointer to `minimumAlignment` and adjust the size of this block accordingly. It's the same as using - // `minimumAlignment - Support::alignUpDiff()`, just written differently. - newBlock->prev = nullptr; - newBlock->next = nullptr; + newBlock->next = next; newBlock->size = realBlockSize; - if (curBlock != &_zeroBlock) { - newBlock->prev = curBlock; + if (curBlock == &_zeroBlock) { + _first = newBlock; + } + else { curBlock->next = newBlock; - - // Does only happen if there is a next block, but the requested memory can't fit into it. In this case a new - // buffer is allocated and inserted between the current block and the next one. - if (next) { - newBlock->next = next; - next->prev = newBlock; - } } uint8_t* ptr = Support::alignUp(newBlock->data(), Globals::kZoneAlignment); @@ -420,6 +392,40 @@ void ZoneAllocator::_releaseDynamic(void* p, size_t size) noexcept { // ============ #if defined(ASMJIT_TEST) +UNIT(zone) { + struct SomeData { + size_t _x; + size_t _y; + + inline SomeData(size_t x, size_t y) noexcept + : _x(x), _y(y) {} + }; + + { + Zone zone(1024u * 4u); + + for (size_t r = 0; r < 3u; r++) { + for (size_t i = 0; i < 100000u; i++) { + uint8_t* p = zone.alloc(32); + EXPECT_NOT_NULL(p); + } + zone.reset(r == 0 ? ResetPolicy::kSoft : ResetPolicy::kHard); + } + } + + { + Zone zone(1024u * 4u); + + for (size_t r = 0; r < 3u; r++) { + for (size_t i = 0; i < 100000u; i++) { + SomeData* p = zone.newT(r, i); + EXPECT_NOT_NULL(p); + } + zone.reset(r == 0 ? ResetPolicy::kSoft : ResetPolicy::kHard); + } + } +} + UNIT(zone_allocator_slots) { constexpr size_t kLoMaxSize = ZoneAllocator::kLoCount * ZoneAllocator::kLoGranularity; constexpr size_t kHiMaxSize = ZoneAllocator::kHiCount * ZoneAllocator::kHiGranularity + kLoMaxSize; diff --git a/src/asmjit/core/zone.h b/src/asmjit/core/zone.h index 05eb8fe..02353da 100644 --- a/src/asmjit/core/zone.h +++ b/src/asmjit/core/zone.h @@ -28,34 +28,24 @@ public: //! \cond INTERNAL //! A single block of memory managed by `Zone`. - struct Block { - inline uint8_t* data() const noexcept { + struct alignas(Globals::kZoneAlignment) Block { + //! Link to the next block (single-linked list). + Block* next; + //! Size represents the number of bytes that can be allocated (it doesn't include overhead). + size_t size; + + ASMJIT_INLINE_NODEBUG uint8_t* data() const noexcept { return const_cast(reinterpret_cast(this) + sizeof(*this)); } - //! Link to the previous block. - Block* prev; - //! Link to the next block. - Block* next; - //! Size of the block. - size_t size; - }; - - //! A state that can be saved and restored. - struct State { - //! Pointer in the current block. - uint8_t* ptr; - //! End of the current block. - uint8_t* end; - //! Current block. - Block* block; + ASMJIT_INLINE_NODEBUG uint8_t* end() const noexcept { + return data() + size; + } }; static inline constexpr size_t kMinBlockSize = 256; // The number is ridiculously small, but still possible. static inline constexpr size_t kMaxBlockSize = size_t(1) << (sizeof(size_t) * 8 - 1); - static inline constexpr size_t kBlockSize = sizeof(Block); - static inline constexpr size_t kBlockOverhead = kBlockSize + Globals::kAllocOverhead; static ASMJIT_API const Block _zeroBlock; @@ -75,6 +65,8 @@ public: uint8_t* _end; //! Current block. Block* _block; + //! First block (single-linked list). + Block* _first; //! Current block size shift - reverted to _minimumBlockSizeShift every time the Zone is `reset(ResetPolicy::kHard)`. uint8_t _currentBlockSizeShift; @@ -122,15 +114,17 @@ public: : _ptr(other._ptr), _end(other._end), _block(other._block), + _first(other._first), _currentBlockSizeShift(other._currentBlockSizeShift), _minimumBlockSizeShift(other._minimumBlockSizeShift), _maximumBlockSizeShift(other._maximumBlockSizeShift), _hasStaticBlock(other._hasStaticBlock), _reserved(other._reserved) { ASMJIT_ASSERT(!other.hasStaticBlock()); - other._block = const_cast(&_zeroBlock); other._ptr = other._block->data(); other._end = other._block->data(); + other._block = const_cast(&_zeroBlock); + other._first = const_cast(&_zeroBlock); } //! Destroys the `Zone` instance. @@ -208,6 +202,7 @@ public: std::swap(_ptr, other._ptr); std::swap(_end, other._end); std::swap(_block, other._block); + std::swap(_first, other._first); std::swap(_currentBlockSizeShift, other._currentBlockSizeShift); std::swap(_minimumBlockSizeShift, other._minimumBlockSizeShift); std::swap(_maximumBlockSizeShift, other._maximumBlockSizeShift); @@ -222,26 +217,6 @@ public: //! \} - //! \name State Save & Restore - //! \{ - - ASMJIT_INLINE State _saveState() const noexcept { - return State{_ptr, _end, _block}; - } - - ASMJIT_INLINE void _restoreState(const State& state) noexcept { - if (ASMJIT_LIKELY(state.block != nullptr)) { - _ptr = state.ptr; - _end = state.end; - _block = state.block; - } - else { - reset(ResetPolicy::kSoft); - } - } - - //! \} - //! \name Allocation //! \{ @@ -288,7 +263,6 @@ public: [[nodiscard]] ASMJIT_INLINE T* alloc(size_t size) noexcept { ASMJIT_ASSERT(Support::isAligned(size, Globals::kZoneAlignment)); - #if defined(__GNUC__) // We can optimize this function a little bit if we know that `size` is relatively small - which would mean // that we cannot possibly overflow `_ptr`. Since most of the time `alloc()` is used for known types (which @@ -300,9 +274,9 @@ public: return static_cast(_alloc(size)); } - uint8_t* ptr = _ptr; + uint8_t* p = _ptr; _ptr = after; - return static_cast(static_cast(ptr)); + return static_cast(static_cast(p)); } #endif @@ -310,9 +284,9 @@ public: return static_cast(_alloc(size)); } - uint8_t* ptr = _ptr; + uint8_t* p = _ptr; _ptr += size; - return static_cast(static_cast(ptr)); + return static_cast(static_cast(p)); } template @@ -329,20 +303,22 @@ public: template [[nodiscard]] ASMJIT_INLINE T* newT() noexcept { - void* ptr = alloc(alignedSizeOf()); - if (ASMJIT_UNLIKELY(!ptr)) + void* p = alloc(alignedSizeOf()); + if (ASMJIT_UNLIKELY(!p)) { return nullptr; - return new(Support::PlacementNew{ptr}) T(); + } + return new(Support::PlacementNew{p}) T(); } //! Like `new(std::nothrow) T(...)`, but allocated by `Zone`. template [[nodiscard]] ASMJIT_INLINE T* newT(Args&&... args) noexcept { - void* ptr = alloc(alignedSizeOf()); - if (ASMJIT_UNLIKELY(!ptr)) + void* p = alloc(alignedSizeOf()); + if (ASMJIT_UNLIKELY(!p)) { return nullptr; - return new(Support::PlacementNew{ptr}) T(std::forward(args)...); + } + return new(Support::PlacementNew{p}) T(std::forward(args)...); } //! Helper to duplicate data. diff --git a/src/asmjit/x86.h b/src/asmjit/x86.h index 7fdff3a..9a8ceb8 100644 --- a/src/asmjit/x86.h +++ b/src/asmjit/x86.h @@ -33,8 +33,8 @@ //! //! ### Register Operands //! -//! - \ref x86::Gp - General purpose register. -//! - \ref x86::Vec - Vector (SIMD) register. +//! - \ref x86::Gp - General purpose register (abstracts 8-bit, 16-bit, 32-bit, and 64-bit GP registers). +//! - \ref x86::Vec - Vector (SIMD) register (abstracts XMM, YMM, and ZMM registers). //! - \ref x86::Mm - 64-bit MMX register. //! - \ref x86::St - 80-bit FPU register. //! - \ref x86::KReg - opmask registers (AVX512+). diff --git a/src/asmjit/x86/x86assembler.cpp b/src/asmjit/x86/x86assembler.cpp index f9ee27c..8e4eb80 100644 --- a/src/asmjit/x86/x86assembler.cpp +++ b/src/asmjit/x86/x86assembler.cpp @@ -4951,7 +4951,7 @@ EmitRel: OffsetFormat of; of.resetToSimpleValue(OffsetType::kSignedOffset, relSize); - Fixup* fixup = _code->newFixup(label, _section->sectionId(), offset, relOffset, of); + Fixup* fixup = _code->newFixup(*label, _section->sectionId(), offset, relOffset, of); if (ASMJIT_UNLIKELY(!fixup)) { goto OutOfMemory; } diff --git a/src/asmjit/x86/x86operand.h b/src/asmjit/x86/x86operand.h index 5a5e53e..6559c52 100644 --- a/src/asmjit/x86/x86operand.h +++ b/src/asmjit/x86/x86operand.h @@ -32,6 +32,15 @@ class Rip; using Reg = Reg; //! General purpose register (X86|X86_64). +//! +//! To get a specific register you can use: +//! - specific registers directly, like `x86::eax` or `x86::rbx`, etc... +//! - construct a register operand dynamically, like `x86::gp8(id)`, `x86::gp64(id)`, etc... +//! - use `Gp::make_r[8|8lo|8hi|16|32|64](id)` API for convenience +//! +//! To cast a register to a specific type, use \ref r8(), \ref r8Lo(), \ref r8Hi(), \ref r16(), \ref r32(), +//! and \ref r64() member functions. Each cast first clones the register and then changes its signature to +//! match the register it has been casted to. class Gp : public UniGp { public: //! \name Constants @@ -124,6 +133,15 @@ public: }; //! Vector register (XMM|YMM|ZMM) (X86|X86_64). +//! +//! To get a specific register you can use: +//! - specific registers directly, like `x86::xmm0` or `x86::ymm1`, `x86::zmm2`, etc... +//! - construct a register operand dynamically, like `x86::xmm(id)`, `x86::ymm(id)`, and `x86::zmm(id)` +//! - use `Vec::make_v[128|256|512](id)` or `Vec::make_[xmm|ymm|zmm](id)` API for convenience +//! +//! To cast a register to a specific type, use \ref v128(), \ref v256(), \ref v512(), \ref xmm(), \ref ymm(), +//! and \ref zmm() member functions. Each cast first clones the register and then changes its signature to +//! match the register it has been casted to. class Vec : public Reg { ASMJIT_DEFINE_ABSTRACT_REG(Vec, Reg) @@ -204,6 +222,12 @@ class Vec : public Reg { //! \} }; +#if !defined(ASMJIT_NO_DEPRECATED) +using Xmm [[deprecated("Use x86::Vec instead of x86::Xmm")]] = Vec; +using Ymm [[deprecated("Use x86::Vec instead of x86::Ymm")]] = Vec; +using Zmm [[deprecated("Use x86::Vec instead of x86::Zmm")]] = Vec; +#endif // ASMJIT_NO_DEPRECATED + //! Segment register (X86|X86_64). class SReg : public Reg { ASMJIT_DEFINE_FINAL_REG(SReg, Reg, RegTraits) @@ -264,26 +288,50 @@ namespace regs { [[nodiscard]] static ASMJIT_INLINE_CONSTEXPR Gp gpb(uint32_t rId) noexcept { return Gp::make_r8(rId); } +//! Creates an 8-bit low GPB register operand. +[[nodiscard]] +static ASMJIT_INLINE_CONSTEXPR Gp gp8(uint32_t rId) noexcept { return Gp::make_r8(rId); } + //! Creates an 8-bit low GPB register operand. [[nodiscard]] static ASMJIT_INLINE_CONSTEXPR Gp gpb_lo(uint32_t rId) noexcept { return Gp::make_r8lo(rId); } +//! Creates an 8-bit low GPB register operand. +[[nodiscard]] +static ASMJIT_INLINE_CONSTEXPR Gp gp8_lo(uint32_t rId) noexcept { return Gp::make_r8lo(rId); } + //! Creates an 8-bit high GPB register operand. [[nodiscard]] static ASMJIT_INLINE_CONSTEXPR Gp gpb_hi(uint32_t rId) noexcept { return Gp::make_r8hi(rId); } +//! Creates an 8-bit high GPB register operand. +[[nodiscard]] +static ASMJIT_INLINE_CONSTEXPR Gp gp8_hi(uint32_t rId) noexcept { return Gp::make_r8hi(rId); } + //! Creates a 16-bit GPW register operand. [[nodiscard]] static ASMJIT_INLINE_CONSTEXPR Gp gpw(uint32_t rId) noexcept { return Gp::make_r16(rId); } +//! Creates a 16-bit GPW register operand. +[[nodiscard]] +static ASMJIT_INLINE_CONSTEXPR Gp gp16(uint32_t rId) noexcept { return Gp::make_r16(rId); } + //! Creates a 32-bit GPD register operand. [[nodiscard]] static ASMJIT_INLINE_CONSTEXPR Gp gpd(uint32_t rId) noexcept { return Gp::make_r32(rId); } +//! Creates a 32-bit GPD register operand. +[[nodiscard]] +static ASMJIT_INLINE_CONSTEXPR Gp gp32(uint32_t rId) noexcept { return Gp::make_r32(rId); } + //! Creates a 64-bit GPQ register operand (64-bit). [[nodiscard]] static ASMJIT_INLINE_CONSTEXPR Gp gpq(uint32_t rId) noexcept { return Gp::make_r64(rId); } +//! Creates a 64-bit GPQ register operand (64-bit). +[[nodiscard]] +static ASMJIT_INLINE_CONSTEXPR Gp gp64(uint32_t rId) noexcept { return Gp::make_r64(rId); } + //! Creates a 128-bit XMM register operand. [[nodiscard]] static ASMJIT_INLINE_CONSTEXPR Vec xmm(uint32_t rId) noexcept { return Vec::make_v128(rId); } diff --git a/tools/configure-sanitizers.sh b/tools/configure-sanitizers.sh index d35b9a4..eee697a 100755 --- a/tools/configure-sanitizers.sh +++ b/tools/configure-sanitizers.sh @@ -15,3 +15,7 @@ echo "" echo "== [Configuring Build - Release_MSAN] ==" eval cmake "${CURRENT_DIR}/.." -B "${BUILD_DIR}/Release_MSAN" ${BUILD_OPTIONS} -DCMAKE_BUILD_TYPE=Release -DASMJIT_SANITIZE=memory echo "" + +echo "== [Configuring Build - Debug_UBSAN] ==" +eval cmake "${CURRENT_DIR}/.." -B "${BUILD_DIR}/Debug_UBSAN" ${BUILD_OPTIONS} -DCMAKE_BUILD_TYPE=Debug -DASMJIT_SANITIZE=undefined +echo ""