From 3d94fcb547b72dbb31a220e5e490a6017561bb24 Mon Sep 17 00:00:00 2001 From: Reka Kovacs Date: Mon, 30 Aug 2021 10:23:05 +0200 Subject: [PATCH 1/5] Backport 9604ee82690f89320614b37bfef4178abc869777 --- make/autoconf/basics.m4 | 10 + make/autoconf/basics_windows.m4 | 53 ++- make/autoconf/flags-cflags.m4 | 4 +- make/autoconf/flags-ldflags.m4 | 11 +- make/autoconf/hotspot.m4 | 8 +- make/autoconf/toolchain.m4 | 67 +++- make/autoconf/toolchain_windows.m4 | 150 +++++---- make/devkit/createWindowsDevkit2017.sh | 15 + make/gensrc/GensrcMisc.gmk | 8 +- make/hotspot/gensrc/GensrcAdlc.gmk | 7 + src/hotspot/cpu/aarch64/aarch64.ad | 2 +- src/hotspot/cpu/aarch64/assembler_aarch64.cpp | 4 + src/hotspot/cpu/aarch64/assembler_aarch64.hpp | 22 +- .../cpu/aarch64/c1_FpuStackSim_aarch64.cpp | 1 + src/hotspot/cpu/aarch64/icache_aarch64.hpp | 15 +- src/hotspot/cpu/aarch64/immediate_aarch64.cpp | 8 +- .../cpu/aarch64/macroAssembler_aarch64.cpp | 20 +- .../cpu/aarch64/macroAssembler_aarch64.hpp | 14 +- .../cpu/aarch64/vm_version_ext_aarch64.cpp | 1 + src/hotspot/os/windows/os_windows.cpp | 180 +++++++--- .../linux_aarch64/icache_linux_aarch64.hpp | 44 +++ .../assembler_windows_aarch64.cpp | 26 ++ .../atomic_windows_aarch64.hpp | 108 ++++++ .../bytes_windows_aarch64.inline.hpp | 46 +++ .../copy_windows_aarch64.inline.hpp | 158 +++++++++ .../globals_windows_aarch64.hpp | 50 +++ .../icache_windows_aarch64.hpp | 44 +++ .../orderAccess_windows_aarch64.hpp | 58 ++++ .../windows_aarch64/os_windows_aarch64.cpp | 312 ++++++++++++++++++ .../windows_aarch64/os_windows_aarch64.hpp | 36 ++ .../os_windows_aarch64.inline.hpp | 30 ++ .../pauth_windows_aarch64.inline.hpp | 34 ++ .../prefetch_windows_aarch64.inline.hpp | 37 +++ .../thread_windows_aarch64.cpp | 100 ++++++ .../thread_windows_aarch64.hpp | 79 +++++ .../unwind_windows_aarch64.hpp | 102 ++++++ .../vmStructs_windows_aarch64.hpp | 49 +++ .../vm_version_windows_aarch64.cpp | 87 +++++ .../os_cpu/windows_x86/os_windows_x86.cpp | 35 ++ src/hotspot/share/prims/jni.cpp | 10 +- .../utilities/globalDefinitions_visCPP.hpp | 4 + .../windows/native/libjava/java_props_md.c | 2 + .../sun/tools/attach/AttachProviderImpl.java | 4 +- .../classes/sun/jvm/hotspot/HotSpotAgent.java | 4 +- .../debugger/windbg/WindbgDebuggerLocal.java | 4 + .../windbg/aarch64/WindbgAARCH64Thread.java | 94 ++++++ .../aarch64/WindbgAARCH64ThreadContext.java | 47 +++ .../aarch64/WindbgAARCH64ThreadFactory.java | 45 +++ .../sun/jvm/hotspot/runtime/Threads.java | 6 +- .../Win32AARCH64JavaThreadPDAccess.java | 138 ++++++++ .../windows/native/libsaproc/sawindbg.cpp | 3 + 51 files changed, 2210 insertions(+), 186 deletions(-) create mode 100644 src/hotspot/os_cpu/linux_aarch64/icache_linux_aarch64.hpp create mode 100644 src/hotspot/os_cpu/windows_aarch64/assembler_windows_aarch64.cpp create mode 100644 src/hotspot/os_cpu/windows_aarch64/atomic_windows_aarch64.hpp create mode 100644 src/hotspot/os_cpu/windows_aarch64/bytes_windows_aarch64.inline.hpp create mode 100644 src/hotspot/os_cpu/windows_aarch64/copy_windows_aarch64.inline.hpp create mode 100644 src/hotspot/os_cpu/windows_aarch64/globals_windows_aarch64.hpp create mode 100644 src/hotspot/os_cpu/windows_aarch64/icache_windows_aarch64.hpp create mode 100644 src/hotspot/os_cpu/windows_aarch64/orderAccess_windows_aarch64.hpp create mode 100644 src/hotspot/os_cpu/windows_aarch64/os_windows_aarch64.cpp create mode 100644 src/hotspot/os_cpu/windows_aarch64/os_windows_aarch64.hpp create mode 100644 src/hotspot/os_cpu/windows_aarch64/os_windows_aarch64.inline.hpp create mode 100644 src/hotspot/os_cpu/windows_aarch64/pauth_windows_aarch64.inline.hpp create mode 100644 src/hotspot/os_cpu/windows_aarch64/prefetch_windows_aarch64.inline.hpp create mode 100644 src/hotspot/os_cpu/windows_aarch64/thread_windows_aarch64.cpp create mode 100644 src/hotspot/os_cpu/windows_aarch64/thread_windows_aarch64.hpp create mode 100644 src/hotspot/os_cpu/windows_aarch64/unwind_windows_aarch64.hpp create mode 100644 src/hotspot/os_cpu/windows_aarch64/vmStructs_windows_aarch64.hpp create mode 100644 src/hotspot/os_cpu/windows_aarch64/vm_version_windows_aarch64.cpp create mode 100644 src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/windbg/aarch64/WindbgAARCH64Thread.java create mode 100644 src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/windbg/aarch64/WindbgAARCH64ThreadContext.java create mode 100644 src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/windbg/aarch64/WindbgAARCH64ThreadFactory.java create mode 100644 src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/win32_aarch64/Win32AARCH64JavaThreadPDAccess.java diff --git a/make/autoconf/basics.m4 b/make/autoconf/basics.m4 index 1b793d76e81..1258235fedf 100644 --- a/make/autoconf/basics.m4 +++ b/make/autoconf/basics.m4 @@ -672,6 +672,16 @@ AC_DEFUN([BASIC_EVAL_DEVKIT_VARIABLE], fi ]) +############################################################################### +# Evaluates platform specific overrides for build devkit variables. +# $1: Name of variable +AC_DEFUN([BASIC_EVAL_BUILD_DEVKIT_VARIABLE], +[ + if test "x[$]$1" = x; then + eval $1="\${$1_${OPENJDK_BUILD_CPU}}" + fi +]) + ############################################################################### AC_DEFUN_ONCE([BASIC_SETUP_DEVKIT], [ diff --git a/make/autoconf/basics_windows.m4 b/make/autoconf/basics_windows.m4 index e8b51e4345d..c1cc7a6ed60 100644 --- a/make/autoconf/basics_windows.m4 +++ b/make/autoconf/basics_windows.m4 @@ -381,10 +381,44 @@ AC_DEFUN_ONCE([BASIC_COMPILE_FIXPATH], # called fixpath. FIXPATH= if test "x$OPENJDK_BUILD_OS" = xwindows; then - AC_MSG_CHECKING([if fixpath can be created]) FIXPATH_SRC="$TOPDIR/make/src/native/fixpath.c" - FIXPATH_BIN="$CONFIGURESUPPORT_OUTPUTDIR/bin/fixpath.exe" FIXPATH_DIR="$CONFIGURESUPPORT_OUTPUTDIR/fixpath" + + if test "x$OPENJDK_TARGET_CPU" != "xaarch64"; then + AC_MSG_CHECKING([if fixpath can be created]) + + FIXPATH_BIN="$CONFIGURESUPPORT_OUTPUTDIR/bin/fixpath.exe" + FIXPATH_SRC_W="$FIXPATH_SRC" + FIXPATH_BIN_W="$FIXPATH_BIN" + BASIC_WINDOWS_REWRITE_AS_WINDOWS_MIXED_PATH([FIXPATH_SRC_W]) + BASIC_WINDOWS_REWRITE_AS_WINDOWS_MIXED_PATH([FIXPATH_BIN_W]) + $RM -rf $FIXPATH_BIN $FIXPATH_DIR + $MKDIR -p $FIXPATH_DIR $CONFIGURESUPPORT_OUTPUTDIR/bin + cd $FIXPATH_DIR + $CC $FIXPATH_SRC_W -Fe$FIXPATH_BIN_W > $FIXPATH_DIR/fixpath1.log 2>&1 + cd $CURDIR + + if test ! -x $FIXPATH_BIN; then + AC_MSG_RESULT([no]) + cat $FIXPATH_DIR/fixpath1.log + AC_MSG_ERROR([Could not create $FIXPATH_BIN]) + fi + AC_MSG_RESULT([yes]) + + else # OPENJDK_TARGET_CPU is aarch64 + AC_MSG_CHECKING([if fixpath is in place]) + + FIXPATH_BIN="$TOPDIR/fixpath.exe" + $RM -rf $FIXPATH_DIR + $MKDIR -p $FIXPATH_DIR + + if test ! -x $FIXPATH_BIN; then + AC_MSG_RESULT([no]) + AC_MSG_ERROR([Could not find fixpath.exe under $TOPDIR]) + fi + AC_MSG_RESULT([yes]) + fi + if test "x$OPENJDK_BUILD_OS_ENV" = xwindows.cygwin; then # Important to keep the .exe suffix on Cygwin for Hotspot makefiles FIXPATH="$FIXPATH_BIN -c" @@ -396,22 +430,7 @@ AC_DEFUN_ONCE([BASIC_COMPILE_FIXPATH], fixpath_argument_list=`echo $all_unique_prefixes | tr ' ' '@'` FIXPATH="$FIXPATH_BIN -m$fixpath_argument_list" fi - FIXPATH_SRC_W="$FIXPATH_SRC" - FIXPATH_BIN_W="$FIXPATH_BIN" - BASIC_WINDOWS_REWRITE_AS_WINDOWS_MIXED_PATH([FIXPATH_SRC_W]) - BASIC_WINDOWS_REWRITE_AS_WINDOWS_MIXED_PATH([FIXPATH_BIN_W]) - $RM -rf $FIXPATH_BIN $FIXPATH_DIR - $MKDIR -p $FIXPATH_DIR $CONFIGURESUPPORT_OUTPUTDIR/bin - cd $FIXPATH_DIR - $CC $FIXPATH_SRC_W -Fe$FIXPATH_BIN_W > $FIXPATH_DIR/fixpath1.log 2>&1 - cd $CURDIR - if test ! -x $FIXPATH_BIN; then - AC_MSG_RESULT([no]) - cat $FIXPATH_DIR/fixpath1.log - AC_MSG_ERROR([Could not create $FIXPATH_BIN]) - fi - AC_MSG_RESULT([yes]) AC_MSG_CHECKING([if fixpath.exe works]) cd $FIXPATH_DIR $FIXPATH $CC $FIXPATH_SRC -Fe$FIXPATH_DIR/fixpath2.exe \ diff --git a/make/autoconf/flags-cflags.m4 b/make/autoconf/flags-cflags.m4 index 54801870319..d3265855dd8 100644 --- a/make/autoconf/flags-cflags.m4 +++ b/make/autoconf/flags-cflags.m4 @@ -695,7 +695,9 @@ AC_DEFUN([FLAGS_SETUP_CFLAGS_CPU_DEP], $1_DEFINES_CPU_JDK="${$1_DEFINES_CPU_JDK} -DcpuIntel -Di586 -D$FLAGS_CPU_LEGACY_LIB" fi elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then - if test "x$FLAGS_CPU" = xx86_64; then + if test "x$FLAGS_CPU" = xaarch64; then + $1_DEFINES_CPU_JDK="${$1_DEFINES_CPU_JDK} -D_ARM64_ -Darm64" + elif test "x$FLAGS_CPU" = xx86_64; then $1_DEFINES_CPU_JDK="${$1_DEFINES_CPU_JDK} -D_AMD64_ -Damd64" else $1_DEFINES_CPU_JDK="${$1_DEFINES_CPU_JDK} -D_X86_ -Dx86" diff --git a/make/autoconf/flags-ldflags.m4 b/make/autoconf/flags-ldflags.m4 index ecc61a42951..8e6e05b6ff5 100644 --- a/make/autoconf/flags-ldflags.m4 +++ b/make/autoconf/flags-ldflags.m4 @@ -186,15 +186,14 @@ AC_DEFUN([FLAGS_SETUP_LDFLAGS_CPU_DEP], fi elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then - if test "x${OPENJDK_$1_CPU}" = "xx86"; then - $1_CPU_LDFLAGS="-safeseh" - # NOTE: Old build added -machine. Probably not needed. - $1_CPU_LDFLAGS_JVM_ONLY="-machine:I386" + if test "x${OPENJDK_$1_CPU_BITS}" = "x32"; then $1_CPU_EXECUTABLE_LDFLAGS="-stack:327680" - else - $1_CPU_LDFLAGS_JVM_ONLY="-machine:AMD64" + elif test "x${OPENJDK_$1_CPU_BITS}" = "x64"; then $1_CPU_EXECUTABLE_LDFLAGS="-stack:1048576" fi + if test "x${OPENJDK_$1_CPU}" = "xx86"; then + $1_CPU_LDFLAGS="-safeseh" + fi fi # JVM_VARIANT_PATH depends on if this is build or target... diff --git a/make/autoconf/hotspot.m4 b/make/autoconf/hotspot.m4 index d598b989797..858a806d477 100644 --- a/make/autoconf/hotspot.m4 +++ b/make/autoconf/hotspot.m4 @@ -221,7 +221,7 @@ AC_DEFUN_ONCE([HOTSPOT_ENABLE_DISABLE_AOT], if test "x$ENABLE_AOT" = "xtrue"; then # Only enable AOT on X64 platforms. - if test "x$OPENJDK_TARGET_CPU" = "xx86_64" || test "x$OPENJDK_TARGET_CPU" = "xaarch64" ; then + if test "x$OPENJDK_TARGET_CPU" = "xx86_64" || test "x$OPENJDK_TARGET_OS-$OPENJDK_TARGET_CPU" = "xlinux-aarch64" ; then if test -e "${TOPDIR}/src/jdk.aot"; then if test -e "${TOPDIR}/src/jdk.internal.vm.compiler"; then ENABLE_AOT="true" @@ -240,7 +240,7 @@ AC_DEFUN_ONCE([HOTSPOT_ENABLE_DISABLE_AOT], else ENABLE_AOT="false" if test "x$enable_aot" = "xyes"; then - AC_MSG_ERROR([AOT is currently only supported on x86_64 and aarch64. Remove --enable-aot.]) + AC_MSG_ERROR([AOT is currently only supported on x86_64 and linux-aarch64. Remove --enable-aot.]) fi fi fi @@ -355,7 +355,7 @@ AC_DEFUN_ONCE([HOTSPOT_SETUP_JVM_FEATURES], # Only enable Shenandoah on supported arches, and only if requested AC_MSG_CHECKING([if shenandoah can be built]) if HOTSPOT_CHECK_JVM_FEATURE(shenandoahgc); then - if test "x$OPENJDK_TARGET_CPU_ARCH" = "xx86" || test "x$OPENJDK_TARGET_CPU" = "xaarch64" ; then + if test "x$OPENJDK_TARGET_CPU_ARCH" = "xx86" || test "x$OPENJDK_TARGET_OS-$OPENJDK_TARGET_CPU" = "xlinux-aarch64" ; then AC_MSG_RESULT([yes]) else DISABLED_JVM_FEATURES="$DISABLED_JVM_FEATURES shenandoahgc" @@ -412,7 +412,7 @@ AC_DEFUN_ONCE([HOTSPOT_SETUP_JVM_FEATURES], # Only enable jvmci on x86_64, sparcv9 and aarch64 if test "x$OPENJDK_TARGET_CPU" = "xx86_64" || \ test "x$OPENJDK_TARGET_CPU" = "xsparcv9" || \ - test "x$OPENJDK_TARGET_CPU" = "xaarch64" ; then + test "x$OPENJDK_TARGET_OS-$OPENJDK_TARGET_CPU" = "xlinux-aarch64" ; then AC_MSG_RESULT([yes]) JVM_FEATURES_jvmci="jvmci" INCLUDE_JVMCI="true" diff --git a/make/autoconf/toolchain.m4 b/make/autoconf/toolchain.m4 index 3c0286d5e77..d54c82bbed9 100644 --- a/make/autoconf/toolchain.m4 +++ b/make/autoconf/toolchain.m4 @@ -918,14 +918,18 @@ AC_DEFUN_ONCE([TOOLCHAIN_SETUP_BUILD_COMPILERS], . $CONFIGURESUPPORT_OUTPUTDIR/build-devkit.info # This potentially sets the following: # A descriptive name of the devkit - BASIC_EVAL_DEVKIT_VARIABLE([BUILD_DEVKIT_NAME]) + BASIC_EVAL_BUILD_DEVKIT_VARIABLE([BUILD_DEVKIT_NAME]) # Corresponds to --with-extra-path - BASIC_EVAL_DEVKIT_VARIABLE([BUILD_DEVKIT_EXTRA_PATH]) + BASIC_EVAL_BUILD_DEVKIT_VARIABLE([BUILD_DEVKIT_EXTRA_PATH]) # Corresponds to --with-toolchain-path - BASIC_EVAL_DEVKIT_VARIABLE([BUILD_DEVKIT_TOOLCHAIN_PATH]) + BASIC_EVAL_BUILD_DEVKIT_VARIABLE([BUILD_DEVKIT_TOOLCHAIN_PATH]) # Corresponds to --with-sysroot - BASIC_EVAL_DEVKIT_VARIABLE([BUILD_DEVKIT_SYSROOT]) - # Skip the Window specific parts + BASIC_EVAL_BUILD_DEVKIT_VARIABLE([BUILD_DEVKIT_SYSROOT]) + + if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then + BASIC_EVAL_BUILD_DEVKIT_VARIABLE([BUILD_DEVKIT_VS_INCLUDE]) + BASIC_EVAL_BUILD_DEVKIT_VARIABLE([BUILD_DEVKIT_VS_LIB]) + fi fi AC_MSG_CHECKING([for build platform devkit]) @@ -935,13 +939,22 @@ AC_DEFUN_ONCE([TOOLCHAIN_SETUP_BUILD_COMPILERS], AC_MSG_RESULT([$BUILD_DEVKIT_ROOT]) fi - BUILD_SYSROOT="$BUILD_DEVKIT_SYSROOT" + PATH="$BUILD_DEVKIT_EXTRA_PATH:$PATH" - # Fallback default of just /bin if DEVKIT_PATH is not defined + # Fallback default of just /bin if DEVKIT_PATH is not defined if test "x$BUILD_DEVKIT_TOOLCHAIN_PATH" = x; then BUILD_DEVKIT_TOOLCHAIN_PATH="$BUILD_DEVKIT_ROOT/bin" fi - PATH="$BUILD_DEVKIT_TOOLCHAIN_PATH:$BUILD_DEVKIT_EXTRA_PATH" + PATH="$BUILD_DEVKIT_TOOLCHAIN_PATH:$PATH" + + BUILD_SYSROOT="$BUILD_DEVKIT_SYSROOT" + + if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then + BUILD_VS_INCLUDE="$BUILD_DEVKIT_VS_INCLUDE" + BUILD_VS_LIB="$BUILD_DEVKIT_VS_LIB" + + TOOLCHAIN_SETUP_VISUAL_STUDIO_SYSROOT_FLAGS([BUILD_]) + fi fi fi @@ -967,9 +980,37 @@ AC_DEFUN_ONCE([TOOLCHAIN_SETUP_BUILD_COMPILERS], BASIC_FIXUP_EXECUTABLE(BUILD_STRIP) # Assume the C compiler is the assembler BUILD_AS="$BUILD_CC -c" - # Just like for the target compiler, use the compiler as linker - BUILD_LD="$BUILD_CC" - BUILD_LDCXX="$BUILD_CXX" + if test "x$TOOLCHAIN_TYPE" = xmicrosoft; then + # In the Microsoft toolchain we have a separate LD command "link". + # Make sure we reject /usr/bin/link (as determined in CYGWIN_LINK), which is + # a cygwin program for something completely different. + AC_CHECK_PROG([BUILD_LD], [link$EXE_SUFFIX],[link$EXE_SUFFIX],,, [$CYGWIN_LINK]) + BASIC_FIXUP_EXECUTABLE(BUILD_LD) + # Verify that we indeed succeeded with this trick. + AC_MSG_CHECKING([if the found link.exe is actually the Visual Studio linker]) + + # Reset PATH since it can contain a mix of WSL/linux paths and Windows paths from VS, + # which, in combination with WSLENV, will make the WSL layer complain + old_path="$PATH" + PATH= + + "$BUILD_LD" --version > /dev/null + + if test $? -eq 0 ; then + AC_MSG_RESULT([no]) + AC_MSG_ERROR([This is the Cygwin link tool. Please check your PATH and rerun configure.]) + else + AC_MSG_RESULT([yes]) + fi + + PATH="$old_path" + + BUILD_LDCXX="$BUILD_LD" + else + # Just like for the target compiler, use the compiler as linker + BUILD_LD="$BUILD_CC" + BUILD_LDCXX="$BUILD_CXX" + fi PATH="$OLDPATH" @@ -1025,6 +1066,10 @@ AC_DEFUN_ONCE([TOOLCHAIN_MISC_CHECKS], if test "x$COMPILER_CPU_TEST" != "xx64"; then AC_MSG_ERROR([Target CPU mismatch. We are building for $OPENJDK_TARGET_CPU but CL is for "$COMPILER_CPU_TEST"; expected "x64".]) fi + elif test "x$OPENJDK_TARGET_CPU" = "xaarch64"; then + if test "x$COMPILER_CPU_TEST" != "xARM64"; then + AC_MSG_ERROR([Target CPU mismatch. We are building for $OPENJDK_TARGET_CPU but CL is for "$COMPILER_CPU_TEST"; expected "arm64".]) + fi fi fi diff --git a/make/autoconf/toolchain_windows.m4 b/make/autoconf/toolchain_windows.m4 index 0fafb098995..4fe760ba486 100644 --- a/make/autoconf/toolchain_windows.m4 +++ b/make/autoconf/toolchain_windows.m4 @@ -126,11 +126,15 @@ AC_DEFUN([TOOLCHAIN_CHECK_POSSIBLE_VISUAL_STUDIO_ROOT], if test -d "$VS_BASE"; then AC_MSG_NOTICE([Found Visual Studio installation at $VS_BASE using $METHOD]) - if test "x$OPENJDK_TARGET_CPU_BITS" = x32; then + if test "x$OPENJDK_TARGET_CPU" = xx86; then VCVARSFILES="vc/bin/vcvars32.bat vc/auxiliary/build/vcvars32.bat" - else + elif test "x$OPENJDK_TARGET_CPU" = xx86_64; then VCVARSFILES="vc/bin/amd64/vcvars64.bat vc/bin/x86_amd64/vcvarsx86_amd64.bat \ vc/auxiliary/build/vcvarsx86_amd64.bat vc/auxiliary/build/vcvars64.bat" + elif test "x$OPENJDK_TARGET_CPU" = xaarch64; then + # for host x86-64, target aarch64 + VCVARSFILES="vc/auxiliary/build/vcvarsamd64_arm64.bat \ + vc/auxiliary/build/vcvarsx86_arm64.bat" fi for VCVARSFILE in $VCVARSFILES; do @@ -170,10 +174,12 @@ AC_DEFUN([TOOLCHAIN_CHECK_POSSIBLE_WIN_SDK_ROOT], elif test -f "$WIN_SDK_BASE/Bin/SetEnv.Cmd"; then AC_MSG_NOTICE([Found Windows SDK installation at $WIN_SDK_BASE using $METHOD]) VS_ENV_CMD="$WIN_SDK_BASE/Bin/SetEnv.Cmd" - if test "x$OPENJDK_TARGET_CPU_BITS" = x32; then + if test "x$OPENJDK_TARGET_CPU" = xx86; then VS_ENV_ARGS="/x86" - else + elif test "x$OPENJDK_TARGET_CPU" = xx86_64; then VS_ENV_ARGS="/x64" + elif test "x$OPENJDK_TARGET_CPU" = xaarch64; then + VS_ENV_ARGS="/arm64" fi # PLATFORM_TOOLSET is used during the compilation of the freetype sources (see # 'LIB_BUILD_FREETYPE' in libraries.m4) and must be 'Windows7.1SDK' for Windows7.1SDK @@ -489,41 +495,7 @@ AC_DEFUN([TOOLCHAIN_SETUP_VISUAL_STUDIO_ENV], AC_SUBST(VS_INCLUDE) AC_SUBST(VS_LIB) - # Convert VS_INCLUDE into SYSROOT_CFLAGS - OLDIFS="$IFS" - IFS=";" - for i in $VS_INCLUDE; do - ipath=$i - # Only process non-empty elements - if test "x$ipath" != x; then - IFS="$OLDIFS" - # Check that directory exists before calling fixup_path - testpath=$ipath - BASIC_WINDOWS_REWRITE_AS_UNIX_PATH([testpath]) - if test -d "$testpath"; then - BASIC_FIXUP_PATH([ipath]) - SYSROOT_CFLAGS="$SYSROOT_CFLAGS -I$ipath" - fi - IFS=";" - fi - done - # Convert VS_LIB into SYSROOT_LDFLAGS - for i in $VS_LIB; do - libpath=$i - # Only process non-empty elements - if test "x$libpath" != x; then - IFS="$OLDIFS" - # Check that directory exists before calling fixup_path - testpath=$libpath - BASIC_WINDOWS_REWRITE_AS_UNIX_PATH([testpath]) - if test -d "$testpath"; then - BASIC_FIXUP_PATH([libpath]) - SYSROOT_LDFLAGS="$SYSROOT_LDFLAGS -libpath:$libpath" - fi - IFS=";" - fi - done - IFS="$OLDIFS" + TOOLCHAIN_SETUP_VISUAL_STUDIO_SYSROOT_FLAGS fi else AC_MSG_RESULT([not found]) @@ -560,10 +532,15 @@ AC_DEFUN([TOOLCHAIN_CHECK_POSSIBLE_MSVC_DLL], CORRECT_MSVCR_ARCH="PE32+ executable" fi else - if test "x$OPENJDK_TARGET_CPU_BITS" = x32; then + if test "x$OPENJDK_TARGET_CPU" = xx86; then CORRECT_MSVCR_ARCH=386 - else + elif test "x$OPENJDK_TARGET_CPU" = xx86_64; then CORRECT_MSVCR_ARCH=x86-64 + elif test "x$OPENJDK_TARGET_CPU" = xaarch64; then + # The cygwin 'file' command only returns "PE32+ executable (DLL) (console), for MS Windows", + # without specifying which architecture it is for specifically. This has been fixed upstream. + # https://github.com/file/file/commit/b849b1af098ddd530094bf779b58431395db2e10#diff-ff2eced09e6860de75057dd731d092aeR142 + CORRECT_MSVCR_ARCH="PE32+ executable" fi fi if $ECHO "$MSVC_DLL_FILETYPE" | $GREP "$CORRECT_MSVCR_ARCH" 2>&1 > /dev/null; then @@ -583,26 +560,26 @@ AC_DEFUN([TOOLCHAIN_SETUP_MSVC_DLL], DLL_NAME="$1" MSVC_DLL= + if test "x$OPENJDK_TARGET_CPU" = xx86; then + vs_target_cpu=x86 + elif test "x$OPENJDK_TARGET_CPU" = xx86_64; then + vs_target_cpu=x64 + elif test "x$OPENJDK_TARGET_CPU" = xaarch64; then + vs_target_cpu=arm64 + fi + if test "x$MSVC_DLL" = x; then if test "x$VCINSTALLDIR" != x; then CYGWIN_VC_INSTALL_DIR="$VCINSTALLDIR" BASIC_FIXUP_PATH(CYGWIN_VC_INSTALL_DIR) if test "$VS_VERSION" -lt 2017; then # Probe: Using well-known location from Visual Studio 12.0 and older - if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then - POSSIBLE_MSVC_DLL="$CYGWIN_VC_INSTALL_DIR/redist/x64/Microsoft.VC${VS_VERSION_INTERNAL}.CRT/$DLL_NAME" - else - POSSIBLE_MSVC_DLL="$CYGWIN_VC_INSTALL_DIR/redist/x86/Microsoft.VC${VS_VERSION_INTERNAL}.CRT/$DLL_NAME" - fi + POSSIBLE_MSVC_DLL="$CYGWIN_VC_INSTALL_DIR/redist/$vs_target_cpu/Microsoft.VC${VS_VERSION_INTERNAL}.CRT/$DLL_NAME" else CYGWIN_VC_TOOLS_REDIST_DIR="$VCToolsRedistDir" BASIC_FIXUP_PATH(CYGWIN_VC_TOOLS_REDIST_DIR) # Probe: Using well-known location from VS 2017 and VS 2019 - if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then - POSSIBLE_MSVC_DLL="`ls $CYGWIN_VC_TOOLS_REDIST_DIR/x64/Microsoft.VC${VS_VERSION_INTERNAL}.CRT/$DLL_NAME`" - else - POSSIBLE_MSVC_DLL="`ls $CYGWIN_VC_TOOLS_REDIST_DIR/x86/Microsoft.VC${VS_VERSION_INTERNAL}.CRT/$DLL_NAME`" - fi + POSSIBLE_MSVC_DLL="`ls $CYGWIN_VC_TOOLS_REDIST_DIR/$vs_target_cpu/Microsoft.VC${VS_VERSION_INTERNAL}.CRT/$DLL_NAME`" fi # In case any of the above finds more than one file, loop over them. for possible_msvc_dll in $POSSIBLE_MSVC_DLL; do @@ -634,13 +611,8 @@ AC_DEFUN([TOOLCHAIN_SETUP_MSVC_DLL], if test "x$VS100COMNTOOLS" != x; then CYGWIN_VS_TOOLS_DIR="$VS100COMNTOOLS/.." BASIC_WINDOWS_REWRITE_AS_UNIX_PATH(CYGWIN_VS_TOOLS_DIR) - if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then - POSSIBLE_MSVC_DLL=`$FIND "$CYGWIN_VS_TOOLS_DIR" -name $DLL_NAME \ - | $GREP -i /x64/ | $HEAD --lines 1` - else - POSSIBLE_MSVC_DLL=`$FIND "$CYGWIN_VS_TOOLS_DIR" -name $DLL_NAME \ - | $GREP -i /x86/ | $HEAD --lines 1` - fi + POSSIBLE_MSVC_DLL=`$FIND "$CYGWIN_VS_TOOLS_DIR" -name $DLL_NAME \ + | $GREP -i /$vs_target_cpu/ | $HEAD --lines 1` TOOLCHAIN_CHECK_POSSIBLE_MSVC_DLL([$DLL_NAME], [$POSSIBLE_MSVC_DLL], [search of VS100COMNTOOLS]) fi @@ -650,17 +622,17 @@ AC_DEFUN([TOOLCHAIN_SETUP_MSVC_DLL], # Probe: Search wildly in the VCINSTALLDIR. We've probably lost by now. # (This was the original behaviour; kept since it might turn something up) if test "x$CYGWIN_VC_INSTALL_DIR" != x; then - if test "x$OPENJDK_TARGET_CPU_BITS" = x64; then - POSSIBLE_MSVC_DLL=`$FIND "$CYGWIN_VC_INSTALL_DIR" -name $DLL_NAME \ - | $GREP x64 | $HEAD --lines 1` - else + if test "x$OPENJDK_TARGET_CPU" = xx86; then POSSIBLE_MSVC_DLL=`$FIND "$CYGWIN_VC_INSTALL_DIR" -name $DLL_NAME \ - | $GREP x86 | $GREP -v ia64 | $GREP -v x64 | $HEAD --lines 1` + | $GREP x86 | $GREP -v ia64 | $GREP -v x64 | $GREP -v arm64 | $HEAD --lines 1` if test "x$POSSIBLE_MSVC_DLL" = x; then # We're grasping at straws now... POSSIBLE_MSVC_DLL=`$FIND "$CYGWIN_VC_INSTALL_DIR" -name $DLL_NAME \ | $HEAD --lines 1` fi + else + POSSIBLE_MSVC_DLL=`$FIND "$CYGWIN_VC_INSTALL_DIR" -name $DLL_NAME \ + | $GREP $vs_target_cpu | $HEAD --lines 1` fi TOOLCHAIN_CHECK_POSSIBLE_MSVC_DLL([$DLL_NAME], [$POSSIBLE_MSVC_DLL], @@ -744,8 +716,12 @@ AC_DEFUN([TOOLCHAIN_SETUP_VS_RUNTIME_DLLS], CYGWIN_WINDOWSSDKDIR="${WINDOWSSDKDIR}" BASIC_FIXUP_PATH([CYGWIN_WINDOWSSDKDIR]) dll_subdir=$OPENJDK_TARGET_CPU - if test "x$dll_subdir" = "xx86_64"; then + if test "x$OPENJDK_TARGET_CPU" = "xaarch64"; then + dll_subdir="arm64" + elif test "x$OPENJDK_TARGET_CPU" = "xx86_64"; then dll_subdir="x64" + elif test "x$OPENJDK_TARGET_CPU" = "xx86"; then + dll_subdir="x86" fi UCRT_DLL_DIR="$CYGWIN_WINDOWSSDKDIR/Redist/ucrt/DLLs/$dll_subdir" if test -z "$(ls -d "$UCRT_DLL_DIR/"*.dll 2> /dev/null)"; then @@ -768,3 +744,49 @@ AC_DEFUN([TOOLCHAIN_SETUP_VS_RUNTIME_DLLS], fi AC_SUBST(UCRT_DLL_DIR) ]) + +# Setup the sysroot flags and add them to global CFLAGS and LDFLAGS so +# that configure can use them while detecting compilers. +# TOOLCHAIN_TYPE is available here. +# Param 1 - Optional prefix to all variables. (e.g BUILD_) +AC_DEFUN([TOOLCHAIN_SETUP_VISUAL_STUDIO_SYSROOT_FLAGS], +[ + # Convert $1VS_INCLUDE into $1SYSROOT_CFLAGS + OLDIFS="$IFS" + IFS=";" + for i in [$]$1VS_INCLUDE; do + ipath=$i + # Only process non-empty elements + if test "x$ipath" != x; then + IFS="$OLDIFS" + # Check that directory exists before calling fixup_path + testpath=$ipath + BASIC_WINDOWS_REWRITE_AS_UNIX_PATH([testpath]) + if test -d "$testpath"; then + BASIC_FIXUP_PATH([ipath]) + $1SYSROOT_CFLAGS="[$]$1SYSROOT_CFLAGS -I$ipath" + fi + IFS=";" + fi + done + # Convert $1VS_LIB into $1SYSROOT_LDFLAGS + for i in [$]$1VS_LIB; do + libpath=$i + # Only process non-empty elements + if test "x$libpath" != x; then + IFS="$OLDIFS" + # Check that directory exists before calling fixup_path + testpath=$libpath + BASIC_WINDOWS_REWRITE_AS_UNIX_PATH([testpath]) + if test -d "$testpath"; then + BASIC_FIXUP_PATH([libpath]) + $1SYSROOT_LDFLAGS="[$]$1SYSROOT_LDFLAGS -libpath:$libpath" + fi + IFS=";" + fi + done + IFS="$OLDIFS" + + AC_SUBST($1SYSROOT_CFLAGS) + AC_SUBST($1SYSROOT_LDFLAGS) +]) diff --git a/make/devkit/createWindowsDevkit2017.sh b/make/devkit/createWindowsDevkit2017.sh index 0dda08d1ecd..3b70b131e87 100644 --- a/make/devkit/createWindowsDevkit2017.sh +++ b/make/devkit/createWindowsDevkit2017.sh @@ -89,19 +89,23 @@ if [ ! -d $DEVKIT_ROOT/VC ]; then REDIST_SUBDIR="VC/Redist/MSVC/14.12.25810" echo "Copying VC..." mkdir -p $DEVKIT_ROOT/VC/bin + cp -r "$VS_INSTALL_DIR/${VC_SUBDIR}/bin/Hostx64/arm64" $DEVKIT_ROOT/VC/bin/ cp -r "$VS_INSTALL_DIR/${VC_SUBDIR}/bin/Hostx64/x64" $DEVKIT_ROOT/VC/bin/ cp -r "$VS_INSTALL_DIR/${VC_SUBDIR}/bin/Hostx86/x86" $DEVKIT_ROOT/VC/bin/ mkdir -p $DEVKIT_ROOT/VC/lib + cp -r "$VS_INSTALL_DIR/${VC_SUBDIR}/lib/arm64" $DEVKIT_ROOT/VC/lib/ cp -r "$VS_INSTALL_DIR/${VC_SUBDIR}/lib/x64" $DEVKIT_ROOT/VC/lib/ cp -r "$VS_INSTALL_DIR/${VC_SUBDIR}/lib/x86" $DEVKIT_ROOT/VC/lib/ cp -r "$VS_INSTALL_DIR/${VC_SUBDIR}/include" $DEVKIT_ROOT/VC/ mkdir -p $DEVKIT_ROOT/VC/atlmfc/lib + cp -r "$VS_INSTALL_DIR/${VC_SUBDIR}/atlmfc/lib/arm64" $DEVKIT_ROOT/VC/atlmfc/lib/ cp -r "$VS_INSTALL_DIR/${VC_SUBDIR}/atlmfc/lib/x64" $DEVKIT_ROOT/VC/atlmfc/lib/ cp -r "$VS_INSTALL_DIR/${VC_SUBDIR}/atlmfc/lib/x86" $DEVKIT_ROOT/VC/atlmfc/lib/ cp -r "$VS_INSTALL_DIR/${VC_SUBDIR}/atlmfc/include" $DEVKIT_ROOT/VC/atlmfc/ mkdir -p $DEVKIT_ROOT/VC/Auxiliary cp -r "$VS_INSTALL_DIR/VC/Auxiliary/Build" $DEVKIT_ROOT/VC/Auxiliary/ mkdir -p $DEVKIT_ROOT/VC/redist + cp -r "$VS_INSTALL_DIR/$REDIST_SUBDIR/arm64" $DEVKIT_ROOT/VC/redist/ cp -r "$VS_INSTALL_DIR/$REDIST_SUBDIR/x64" $DEVKIT_ROOT/VC/redist/ cp -r "$VS_INSTALL_DIR/$REDIST_SUBDIR/x86" $DEVKIT_ROOT/VC/redist/ @@ -111,6 +115,8 @@ if [ ! -d $DEVKIT_ROOT/VC ]; then cp $DEVKIT_ROOT/VC/redist/x86/$MSVCP_DLL $DEVKIT_ROOT/VC/bin/x86 cp $DEVKIT_ROOT/VC/redist/x64/$MSVCR_DLL $DEVKIT_ROOT/VC/bin/x64 cp $DEVKIT_ROOT/VC/redist/x64/$MSVCP_DLL $DEVKIT_ROOT/VC/bin/x64 + cp $DEVKIT_ROOT/VC/redist/arm64/$MSVCR_DLL $DEVKIT_ROOT/VC/bin/arm64 + cp $DEVKIT_ROOT/VC/redist/arm64/$MSVCP_DLL $DEVKIT_ROOT/VC/bin/arm64 fi ################################################################################ @@ -128,8 +134,10 @@ if [ ! -d $DEVKIT_ROOT/$SDK_VERSION ]; then cp -r "$SDK_INSTALL_DIR/bin/$SDK_FULL_VERSION/x64" $DEVKIT_ROOT/$SDK_VERSION/bin/ cp -r "$SDK_INSTALL_DIR/bin/$SDK_FULL_VERSION/x86" $DEVKIT_ROOT/$SDK_VERSION/bin/ mkdir -p $DEVKIT_ROOT/$SDK_VERSION/lib + cp -r "$SDK_INSTALL_DIR/lib/$SDK_FULL_VERSION/um/arm64" $DEVKIT_ROOT/$SDK_VERSION/lib/ cp -r "$SDK_INSTALL_DIR/lib/$SDK_FULL_VERSION/um/x64" $DEVKIT_ROOT/$SDK_VERSION/lib/ cp -r "$SDK_INSTALL_DIR/lib/$SDK_FULL_VERSION/um/x86" $DEVKIT_ROOT/$SDK_VERSION/lib/ + cp -r "$SDK_INSTALL_DIR/lib/$SDK_FULL_VERSION/ucrt/arm64" $DEVKIT_ROOT/$SDK_VERSION/lib/ cp -r "$SDK_INSTALL_DIR/lib/$SDK_FULL_VERSION/ucrt/x64" $DEVKIT_ROOT/$SDK_VERSION/lib/ cp -r "$SDK_INSTALL_DIR/lib/$SDK_FULL_VERSION/ucrt/x86" $DEVKIT_ROOT/$SDK_VERSION/lib/ mkdir -p $DEVKIT_ROOT/$SDK_VERSION/Redist @@ -164,6 +172,13 @@ echo-info "DEVKIT_VS_LIB_x86_64=\"\$DEVKIT_ROOT/VC/lib/x64;\$DEVKIT_ROOT/VC/atlm echo-info "DEVKIT_MSVCR_DLL_x86_64=\"\$DEVKIT_ROOT/VC/redist/x64/$MSVCR_DLL\"" echo-info "DEVKIT_MSVCP_DLL_x86_64=\"\$DEVKIT_ROOT/VC/redist/x64/$MSVCP_DLL\"" echo-info "DEVKIT_UCRT_DLL_DIR_x86_64=\"\$DEVKIT_ROOT/10/Redist/ucrt/DLLs/x64\"" +echo-info "" +echo-info "DEVKIT_TOOLCHAIN_PATH_aarch64=\"\$DEVKIT_ROOT/VC/bin/arm64:\$DEVKIT_ROOT/$SDK_VERSION/bin/x64:\$DEVKIT_ROOT/$SDK_VERSION/bin/x86\"" +echo-info "DEVKIT_VS_INCLUDE_aarch64=\"\$DEVKIT_ROOT/VC/include;\$DEVKIT_ROOT/VC/atlmfc/include;\$DEVKIT_ROOT/$SDK_VERSION/include/shared;\$DEVKIT_ROOT/$SDK_VERSION/include/ucrt;\$DEVKIT_ROOT/$SDK_VERSION/include/um;\$DEVKIT_ROOT/$SDK_VERSION/include/winrt\"" +echo-info "DEVKIT_VS_LIB_aarch64=\"\$DEVKIT_ROOT/VC/lib/arm64;\$DEVKIT_ROOT/VC/atlmfc/lib/arm64;\$DEVKIT_ROOT/$SDK_VERSION/lib/arm64\"" +echo-info "DEVKIT_MSVCR_DLL_aarch64=\"\$DEVKIT_ROOT/VC/redist/arm64/$MSVCR_DLL\"" +echo-info "DEVKIT_MSVCP_DLL_aarch64=\"\$DEVKIT_ROOT/VC/redist/arm64/$MSVCP_DLL\"" +echo-info "DEVKIT_UCRT_DLL_DIR_aarch64=\"\$DEVKIT_ROOT/10/Redist/ucrt/DLLs/arm64\"" ################################################################################ # Copy this script diff --git a/make/gensrc/GensrcMisc.gmk b/make/gensrc/GensrcMisc.gmk index b01dd174498..19c37a5f573 100644 --- a/make/gensrc/GensrcMisc.gmk +++ b/make/gensrc/GensrcMisc.gmk @@ -63,6 +63,12 @@ ifneq ($(filter $(TOOLCHAIN_TYPE), gcc clang), ) CPP_FLAGS += -x c else ifeq ($(TOOLCHAIN_TYPE), microsoft) CPP_FLAGS += -nologo + + ifeq ($(OPENJDK_TARGET_CPU),aarch64) + # cl.exe does only recognize few file extensions as valid (ex: .c, .h, .cpp), so + # make sure *.java.template files are recognized as valid input files + CPP_FILEPREFIX = -Tc + endif endif # Generate a java source file from a template through the C preprocessor for the @@ -75,7 +81,7 @@ endif define generate-preproc-src $(call MakeDir, $(@D)) ( $(NAWK) '/@@END_COPYRIGHT@@/{exit}1' $< && \ - $(CPP) $(CPP_FLAGS) $(SYSROOT_CFLAGS) $(CFLAGS_JDKLIB) $< \ + $(CPP) $(CPP_FLAGS) $(SYSROOT_CFLAGS) $(CFLAGS_JDKLIB) $(CPP_FILEPREFIX) $< \ 2> >($(GREP) -v '^$(&2) \ | $(NAWK) '/@@START_HERE@@/,0' \ | $(SED) -e 's/@@START_HERE@@/\/\/ AUTOMATICALLY GENERATED FILE - DO NOT EDIT/' \ diff --git a/make/hotspot/gensrc/GensrcAdlc.gmk b/make/hotspot/gensrc/GensrcAdlc.gmk index 68789625145..d25b517252f 100644 --- a/make/hotspot/gensrc/GensrcAdlc.gmk +++ b/make/hotspot/gensrc/GensrcAdlc.gmk @@ -99,6 +99,13 @@ ifeq ($(call check-jvm-feature, compiler2), true) ADLCFLAGS += -DAIX=1 else ifeq ($(OPENJDK_TARGET_OS), macosx) ADLCFLAGS += -D_ALLBSD_SOURCE=1 -D_GNU_SOURCE=1 + else ifeq ($(OPENJDK_TARGET_OS), windows) + ifeq ($(call isTargetCpuBits, 64), true) + ADLCFLAGS += -D_WIN64=1 + endif + ifeq ($(HOTSPOT_TARGET_CPU_ARCH), aarch64) + ADLCFLAGS += -DR18_RESERVED=1 + endif endif ifneq ($(OPENJDK_TARGET_OS), windows) diff --git a/src/hotspot/cpu/aarch64/aarch64.ad b/src/hotspot/cpu/aarch64/aarch64.ad index eaff134ebf1..991e479b02a 100644 --- a/src/hotspot/cpu/aarch64/aarch64.ad +++ b/src/hotspot/cpu/aarch64/aarch64.ad @@ -5440,7 +5440,7 @@ pipeline %{ attributes %{ // ARM instructions are of fixed length fixed_size_instructions; // Fixed size instructions TODO does - max_instructions_per_bundle = 2; // A53 = 2, A57 = 4 + max_instructions_per_bundle = 4; // A53 = 2, A57 = 4 // ARM instructions come in 32-bit word units instruction_unit_size = 4; // An instruction is 4 bytes long instruction_fetch_unit_size = 64; // The processor fetches one line diff --git a/src/hotspot/cpu/aarch64/assembler_aarch64.cpp b/src/hotspot/cpu/aarch64/assembler_aarch64.cpp index 02681c25477..8047ed8fd2a 100644 --- a/src/hotspot/cpu/aarch64/assembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/assembler_aarch64.cpp @@ -1783,3 +1783,7 @@ static float unpack(unsigned value) { ival = fp_immediate_for_encoding(value, 0); return val; } + +address Assembler::locate_next_instruction(address inst) { + return inst + Assembler::instruction_size; +} diff --git a/src/hotspot/cpu/aarch64/assembler_aarch64.hpp b/src/hotspot/cpu/aarch64/assembler_aarch64.hpp index a5b7d3e9047..4cf979d4365 100644 --- a/src/hotspot/cpu/aarch64/assembler_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/assembler_aarch64.hpp @@ -28,6 +28,19 @@ #include "asm/register.hpp" +#ifdef __GNUC__ + +// __nop needs volatile so that compiler doesn't optimize it away +#define NOP() asm volatile ("nop"); + +#elif defined(_MSC_VER) + +// Use MSVC instrinsic: https://docs.microsoft.com/en-us/cpp/intrinsics/arm64-intrinsics?view=vs-2019#I +#define NOP() __nop(); + +#endif + + // definitions of various symbolic names for machine registers // First intercalls between C and Java which use 8 general registers @@ -618,7 +631,7 @@ class Assembler : public AbstractAssembler { void emit_long(jint x) { if ((uintptr_t)pc() == asm_bp) - asm volatile ("nop"); + NOP(); AbstractAssembler::emit_int32(x); } #else @@ -650,6 +663,8 @@ class Assembler : public AbstractAssembler { return Address(Post(base, idx)); } + static address locate_next_instruction(address inst); + Instruction_aarch64* current; void set_current(Instruction_aarch64* i) { current = i; } @@ -1518,6 +1533,11 @@ class Assembler : public AbstractAssembler { #undef INSN +#ifdef _WIN64 +// In MSVC, `mvn` is defined as a macro and it affects compilation +#undef mvn +#endif + // Aliases for short forms of orn void mvn(Register Rd, Register Rm, enum shift_kind kind = LSL, unsigned shift = 0) { diff --git a/src/hotspot/cpu/aarch64/c1_FpuStackSim_aarch64.cpp b/src/hotspot/cpu/aarch64/c1_FpuStackSim_aarch64.cpp index 3e213003947..c50da1c8beb 100644 --- a/src/hotspot/cpu/aarch64/c1_FpuStackSim_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c1_FpuStackSim_aarch64.cpp @@ -28,3 +28,4 @@ //-------------------------------------------------------- // No FPU stack on AARCH64 +#include "precompiled.hpp" diff --git a/src/hotspot/cpu/aarch64/icache_aarch64.hpp b/src/hotspot/cpu/aarch64/icache_aarch64.hpp index 30c7a408a8d..4d01d11f17a 100644 --- a/src/hotspot/cpu/aarch64/icache_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/icache_aarch64.hpp @@ -26,19 +26,6 @@ #ifndef CPU_AARCH64_VM_ICACHE_AARCH64_HPP #define CPU_AARCH64_VM_ICACHE_AARCH64_HPP -// Interface for updating the instruction cache. Whenever the VM -// modifies code, part of the processor instruction cache potentially -// has to be flushed. - -class ICache : public AbstractICache { - public: - static void initialize(); - static void invalidate_word(address addr) { - __clear_cache((char *)addr, (char *)(addr + 3)); - } - static void invalidate_range(address start, int nbytes) { - __clear_cache((char *)start, (char *)(start + nbytes)); - } -}; +#include OS_CPU_HEADER(icache) #endif // CPU_AARCH64_VM_ICACHE_AARCH64_HPP diff --git a/src/hotspot/cpu/aarch64/immediate_aarch64.cpp b/src/hotspot/cpu/aarch64/immediate_aarch64.cpp index 7a67d9531a3..3e38b7cca04 100644 --- a/src/hotspot/cpu/aarch64/immediate_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/immediate_aarch64.cpp @@ -24,6 +24,9 @@ #include #include + +#include "precompiled.hpp" +#include "utilities/globalDefinitions.hpp" #include "immediate_aarch64.hpp" // there are at most 2^13 possible logical immediate encodings @@ -244,7 +247,10 @@ int expandLogicalImmediate(uint32_t immN, uint32_t immr, // constructor to initialise the lookup tables -static void initLITables() __attribute__ ((constructor)); +static void initLITables(); +// Use an empty struct with a construtor as MSVC doesn't support `__attribute__ ((constructor))` +// See https://stackoverflow.com/questions/1113409/attribute-constructor-equivalent-in-vc +static struct initLITables_t { initLITables_t(void) { initLITables(); } } _initLITables; static void initLITables() { li_table_entry_count = 0; diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp index 358c342ef0a..70e141efe02 100644 --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp @@ -297,7 +297,7 @@ void MacroAssembler::safepoint_poll(Label& slow_path) { ldr(rscratch1, Address(rthread, Thread::polling_page_offset())); tbnz(rscratch1, exact_log2(SafepointMechanism::poll_bit()), slow_path); } else { - unsigned long offset; + uint64_t offset; adrp(rscratch1, ExternalAddress(SafepointSynchronize::address_of_state()), offset); ldrw(rscratch1, Address(rscratch1, offset)); assert(SafepointSynchronize::_not_synchronized == 0, "rewrite this code"); @@ -1492,7 +1492,7 @@ void MacroAssembler::movptr(Register r, uintptr_t imm64) { #ifndef PRODUCT { char buffer[64]; - snprintf(buffer, sizeof(buffer), "0x%"PRIX64, (uint64_t)imm64); + snprintf(buffer, sizeof(buffer), PTR64_FORMAT, imm64); block_comment(buffer); } #endif @@ -1555,7 +1555,7 @@ void MacroAssembler::mov_immediate64(Register dst, uint64_t imm64) #ifndef PRODUCT { char buffer[64]; - snprintf(buffer, sizeof(buffer), "0x%"PRIX64, imm64); + snprintf(buffer, sizeof(buffer), PTR64_FORMAT, imm64); block_comment(buffer); } #endif @@ -1668,7 +1668,7 @@ void MacroAssembler::mov_immediate32(Register dst, uint32_t imm32) #ifndef PRODUCT { char buffer[64]; - snprintf(buffer, sizeof(buffer), "0x%"PRIX32, imm32); + snprintf(buffer, sizeof(buffer), PTR32_FORMAT, imm32); block_comment(buffer); } #endif @@ -4207,7 +4207,7 @@ void MacroAssembler::get_polling_page(Register dest, address page, relocInfo::re if (SafepointMechanism::uses_thread_local_poll()) { ldr(dest, Address(rthread, Thread::polling_page_offset())); } else { - unsigned long off; + uint64_t off; adrp(dest, Address(page, rtype), off); assert(off == 0, "polling page must be page aligned"); } @@ -4805,7 +4805,7 @@ void MacroAssembler::string_compare(Register str1, Register str2, Register cnt1, Register cnt2, Register result, Register tmp1, Register tmp2, FloatRegister vtmp1, FloatRegister vtmp2, FloatRegister vtmp3, int ae) { Label DONE, SHORT_LOOP, SHORT_STRING, SHORT_LAST, TAIL, STUB, - DIFFERENCE, NEXT_WORD, SHORT_LOOP_TAIL, SHORT_LAST2, SHORT_LAST_INIT, + DIFF, NEXT_WORD, SHORT_LOOP_TAIL, SHORT_LAST2, SHORT_LAST_INIT, SHORT_LOOP_START, TAIL_CHECK; const int STUB_THRESHOLD = 64 + 8; @@ -4892,7 +4892,7 @@ void MacroAssembler::string_compare(Register str1, Register str2, adds(cnt2, cnt2, isUL ? 4 : 8); br(GE, TAIL); eor(rscratch2, tmp1, tmp2); - cbnz(rscratch2, DIFFERENCE); + cbnz(rscratch2, DIFF); // main loop bind(NEXT_WORD); if (str1_isL == str2_isL) { @@ -4918,10 +4918,10 @@ void MacroAssembler::string_compare(Register str1, Register str2, eor(rscratch2, tmp1, tmp2); cbz(rscratch2, NEXT_WORD); - b(DIFFERENCE); + b(DIFF); bind(TAIL); eor(rscratch2, tmp1, tmp2); - cbnz(rscratch2, DIFFERENCE); + cbnz(rscratch2, DIFF); // Last longword. In the case where length == 4 we compare the // same longword twice, but that's still faster than another // conditional branch. @@ -4945,7 +4945,7 @@ void MacroAssembler::string_compare(Register str1, Register str2, // Find the first different characters in the longwords and // compute their difference. - bind(DIFFERENCE); + bind(DIFF); rev(rscratch2, rscratch2); clz(rscratch2, rscratch2); andr(rscratch2, rscratch2, isLL ? -8 : -16); diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp index 1c4a474a256..f9f7a3a9ee5 100644 --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp @@ -185,7 +185,15 @@ class MacroAssembler: public Assembler { mov(rscratch2, call_site); } +// Microsoft's MSVC team thinks that the __FUNCSIG__ is approximately (sympathy for calling conventions) equivalent to __PRETTY_FUNCTION__ +// Also, from Clang patch: "It is very similar to GCC's PRETTY_FUNCTION, except it prints the calling convention." +// https://reviews.llvm.org/D3311 + +#ifdef _WIN64 +#define call_Unimplemented() _call_Unimplemented((address)__FUNCSIG__) +#else #define call_Unimplemented() _call_Unimplemented((address)__PRETTY_FUNCTION__) +#endif // aliases defined in AARCH64 spec @@ -505,10 +513,10 @@ class MacroAssembler: public Assembler { // Generalized Test Bit And Branch, including a "far" variety which // spans more than 32KiB. - void tbr(Condition cond, Register Rt, int bitpos, Label &dest, bool far = false) { + void tbr(Condition cond, Register Rt, int bitpos, Label &dest, bool isfar = false) { assert(cond == EQ || cond == NE, "must be"); - if (far) + if (isfar) cond = ~cond; void (Assembler::* branch)(Register Rt, int bitpos, Label &L); @@ -517,7 +525,7 @@ class MacroAssembler: public Assembler { else branch = &Assembler::tbnz; - if (far) { + if (isfar) { Label L; (this->*branch)(Rt, bitpos, L); b(dest); diff --git a/src/hotspot/cpu/aarch64/vm_version_ext_aarch64.cpp b/src/hotspot/cpu/aarch64/vm_version_ext_aarch64.cpp index ebabc3723c2..8db351a6c1e 100644 --- a/src/hotspot/cpu/aarch64/vm_version_ext_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/vm_version_ext_aarch64.cpp @@ -22,6 +22,7 @@ * */ +#include "precompiled.hpp" #include "memory/allocation.hpp" #include "memory/allocation.inline.hpp" #include "runtime/os.inline.hpp" diff --git a/src/hotspot/os/windows/os_windows.cpp b/src/hotspot/os/windows/os_windows.cpp index 2730460730b..0dc527bf4bc 100644 --- a/src/hotspot/os/windows/os_windows.cpp +++ b/src/hotspot/os/windows/os_windows.cpp @@ -31,6 +31,7 @@ #include "classfile/systemDictionary.hpp" #include "classfile/vmSymbols.hpp" #include "code/icBuffer.hpp" +#include "code/nativeInst.hpp" #include "code/vtableStubs.hpp" #include "compiler/compileBroker.hpp" #include "compiler/disassembler.hpp" @@ -120,12 +121,19 @@ static FILETIME process_exit_time; static FILETIME process_user_time; static FILETIME process_kernel_time; -#ifdef _M_AMD64 +#if defined(_M_ARM64) + #define __CPU__ aarch64 +#elif defined(_M_AMD64) #define __CPU__ amd64 #else #define __CPU__ i486 #endif +#if defined(USE_VECTORED_EXCEPTION_HANDLING) +PVOID topLevelVectoredExceptionHandler = NULL; +LPTOP_LEVEL_EXCEPTION_FILTER previousUnhandledExceptionFilter = NULL; +#endif + // save DLL module handle, used by GetModuleFileName HINSTANCE vm_lib_handle; @@ -144,6 +152,12 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) { if (ForceTimeHighResolution) { timeEndPeriod(1L); } +#if defined(USE_VECTORED_EXCEPTION_HANDLING) + if (topLevelVectoredExceptionHandler != NULL) { + RemoveVectoredExceptionHandler(topLevelVectoredExceptionHandler); + topLevelVectoredExceptionHandler = NULL; + } +#endif break; default: break; @@ -454,6 +468,12 @@ static unsigned __stdcall thread_native_entry(Thread* thread) { log_info(os, thread)("Thread is alive (tid: " UINTX_FORMAT ").", os::current_thread_id()); +#ifdef USE_VECTORED_EXCEPTION_HANDLING + // Any exception is caught by the Vectored Exception Handler, so VM can + // generate error dump when an exception occurred in non-Java thread + // (e.g. VM thread). + thread->call_run(); +#else // Install a win32 structured exception handler around every thread created // by VM, so VM can generate error dump when an exception occurred in non- // Java thread (e.g. VM thread). @@ -463,6 +483,7 @@ static unsigned __stdcall thread_native_entry(Thread* thread) { (_EXCEPTION_POINTERS*)_exception_info())) { // Nothing to do. } +#endif // Note: at this point the thread object may already have deleted itself. // Do not dereference it from here on out. @@ -1426,15 +1447,18 @@ void * os::dll_load(const char *name, char *ebuf, int ebuflen) { static const arch_t arch_array[] = { {IMAGE_FILE_MACHINE_I386, (char*)"IA 32"}, - {IMAGE_FILE_MACHINE_AMD64, (char*)"AMD 64"} + {IMAGE_FILE_MACHINE_AMD64, (char*)"AMD 64"}, + {IMAGE_FILE_MACHINE_ARM64, (char*)"ARM 64"} }; -#if (defined _M_AMD64) +#if (defined _M_ARM64) + static const uint16_t running_arch = IMAGE_FILE_MACHINE_ARM64; +#elif (defined _M_AMD64) static const uint16_t running_arch = IMAGE_FILE_MACHINE_AMD64; #elif (defined _M_IX86) static const uint16_t running_arch = IMAGE_FILE_MACHINE_I386; #else #error Method os::dll_load requires that one of following \ - is defined :_M_AMD64 or _M_IX86 + is defined :_M_AMD64 or _M_IX86 or _M_ARM64 #endif @@ -1737,7 +1761,8 @@ void os::win32::print_windows_version(outputStream* st) { SYSTEM_INFO si; ZeroMemory(&si, sizeof(SYSTEM_INFO)); GetNativeSystemInfo(&si); - if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) { + if ((si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) || + (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM64)) { st->print(" , 64 bit"); } @@ -2149,6 +2174,8 @@ LONG Handle_Exception(struct _EXCEPTION_POINTERS* exceptionInfo, #define PC_NAME Rip #elif defined(_M_IX86) #define PC_NAME Eip +#elif defined(_M_ARM64) + #define PC_NAME Pc #else #error unknown architecture #endif @@ -2243,7 +2270,17 @@ const char* os::exception_name(int exception_code, char *buf, size_t size) { LONG Handle_IDiv_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) { // handle exception caused by idiv; should only happen for -MinInt/-1 // (division by zero is handled explicitly) -#ifdef _M_AMD64 +#if defined(_M_ARM64) + PCONTEXT ctx = exceptionInfo->ContextRecord; + address pc = (address)ctx->Sp; + assert(pc[0] == 0x83, "not an sdiv opcode"); //Fixme did i get the right opcode? + assert(ctx->X4 == min_jint, "unexpected idiv exception"); + // set correct result values and continue after idiv instruction + ctx->Pc = (uint64_t)pc + 4; // idiv reg, reg, reg is 4 bytes + ctx->X4 = (uint64_t)min_jint; // result + ctx->X5 = (uint64_t)0; // remainder + // Continue the execution +#elif defined(_M_AMD64) PCONTEXT ctx = exceptionInfo->ContextRecord; address pc = (address)ctx->Rip; assert(pc[0] >= Assembler::REX && pc[0] <= Assembler::REX_WRXB && pc[1] == 0xF7 || pc[0] == 0xF7, "not an idiv opcode"); @@ -2274,6 +2311,7 @@ LONG Handle_IDiv_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) { return EXCEPTION_CONTINUE_EXECUTION; } +#if defined(_M_AMD64) || defined(_M_IX86) //----------------------------------------------------------------------------- LONG WINAPI Handle_FLT_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) { PCONTEXT ctx = exceptionInfo->ContextRecord; @@ -2319,6 +2357,7 @@ LONG WINAPI Handle_FLT_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) { return EXCEPTION_CONTINUE_SEARCH; } +#endif static inline void report_error(Thread* t, DWORD exception_code, address addr, void* siginfo, void* context) { @@ -2328,48 +2367,15 @@ static inline void report_error(Thread* t, DWORD exception_code, // somewhere where we can find it in the minidump. } -bool os::win32::get_frame_at_stack_banging_point(JavaThread* thread, - struct _EXCEPTION_POINTERS* exceptionInfo, address pc, frame* fr) { - PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord; - address addr = (address) exceptionRecord->ExceptionInformation[1]; - if (Interpreter::contains(pc)) { - *fr = os::fetch_frame_from_context((void*)exceptionInfo->ContextRecord); - if (!fr->is_first_java_frame()) { - // get_frame_at_stack_banging_point() is only called when we - // have well defined stacks so java_sender() calls do not need - // to assert safe_for_sender() first. - *fr = fr->java_sender(); - } - } else { - // more complex code with compiled code - assert(!Interpreter::contains(pc), "Interpreted methods should have been handled above"); - CodeBlob* cb = CodeCache::find_blob(pc); - if (cb == NULL || !cb->is_nmethod() || cb->is_frame_complete_at(pc)) { - // Not sure where the pc points to, fallback to default - // stack overflow handling - return false; - } else { - *fr = os::fetch_frame_from_context((void*)exceptionInfo->ContextRecord); - // in compiled code, the stack banging is performed just after the return pc - // has been pushed on the stack - *fr = frame(fr->sp() + 1, fr->fp(), (address)*(fr->sp())); - if (!fr->is_java_frame()) { - // See java_sender() comment above. - *fr = fr->java_sender(); - } - } - } - assert(fr->is_java_frame(), "Safety check"); - return true; -} - //----------------------------------------------------------------------------- JNIEXPORT LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) { if (InterceptOSException) return EXCEPTION_CONTINUE_SEARCH; PEXCEPTION_RECORD exception_record = exceptionInfo->ExceptionRecord; DWORD exception_code = exception_record->ExceptionCode; -#ifdef _M_AMD64 +#if defined(_M_ARM64) + address pc = (address) exceptionInfo->ContextRecord->Pc; +#elif defined(_M_AMD64) address pc = (address) exceptionInfo->ContextRecord->Rip; #else address pc = (address) exceptionInfo->ContextRecord->Eip; @@ -2452,8 +2458,10 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) { // Last unguard failed or not unguarding tty->print_raw_cr("Execution protection violation"); +#if !defined(USE_VECTORED_EXCEPTION_HANDLING) report_error(t, exception_code, addr, exception_record, exceptionInfo->ContextRecord); +#endif return EXCEPTION_CONTINUE_SEARCH; } } @@ -2473,10 +2481,13 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) { return EXCEPTION_CONTINUE_EXECUTION; } } + +#if defined(_M_AMD64) || defined(_M_IX86) if (VM_Version::is_cpuinfo_segv_addr(pc)) { // Verify that OS save/restore AVX registers. return Handle_Exception(exceptionInfo, VM_Version::cpuinfo_cont_addr()); } +#endif } if (t != NULL && t->is_Java_thread()) { @@ -2508,8 +2519,10 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) { // Fatal red zone violation. thread->disable_stack_red_zone(); tty->print_raw_cr("An unrecoverable stack overflow has occurred."); +#if !defined(USE_VECTORED_EXCEPTION_HANDLING) report_error(t, exception_code, pc, exception_record, exceptionInfo->ContextRecord); +#endif return EXCEPTION_CONTINUE_SEARCH; } } else if (exception_code == EXCEPTION_ACCESS_VIOLATION) { @@ -2565,8 +2578,10 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) { #endif // Stack overflow or null pointer exception in native code. +#if !defined(USE_VECTORED_EXCEPTION_HANDLING) report_error(t, exception_code, pc, exception_record, exceptionInfo->ContextRecord); +#endif return EXCEPTION_CONTINUE_SEARCH; } // /EXCEPTION_ACCESS_VIOLATION // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -2584,6 +2599,19 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) { } } +#ifdef _M_ARM64 + if (in_java && + (exception_code == EXCEPTION_ILLEGAL_INSTRUCTION || + exception_code == EXCEPTION_ILLEGAL_INSTRUCTION_2)) { + if (nativeInstruction_at(pc)->is_sigill_zombie_not_entrant()) { + if (TraceTraps) { + tty->print_cr("trap: zombie_not_entrant"); + } + return Handle_Exception(exceptionInfo, SharedRuntime::get_handle_wrong_method_stub()); + } + } +#endif + if (in_java) { switch (exception_code) { case EXCEPTION_INT_DIVIDE_BY_ZERO: @@ -2594,18 +2622,74 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) { } // switch } + +#if defined(_M_AMD64) || defined(_M_IX86) if ((in_java || in_native) && exception_code != EXCEPTION_UNCAUGHT_CXX_EXCEPTION) { LONG result=Handle_FLT_Exception(exceptionInfo); if (result==EXCEPTION_CONTINUE_EXECUTION) return result; } +#endif } +#if !defined(USE_VECTORED_EXCEPTION_HANDLING) if (exception_code != EXCEPTION_BREAKPOINT) { report_error(t, exception_code, pc, exception_record, exceptionInfo->ContextRecord); } +#endif + return EXCEPTION_CONTINUE_SEARCH; +} + +#if defined(USE_VECTORED_EXCEPTION_HANDLING) +LONG WINAPI topLevelVectoredExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) { + PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord; +#if defined(_M_ARM64) + address pc = (address) exceptionInfo->ContextRecord->Pc; +#elif defined(_M_AMD64) + address pc = (address) exceptionInfo->ContextRecord->Rip; +#else + address pc = (address) exceptionInfo->ContextRecord->Eip; +#endif + + // Fast path for code part of the code cache + if (CodeCache::low_bound() <= pc && pc < CodeCache::high_bound()) { + return topLevelExceptionFilter(exceptionInfo); + } + + // Handle the case where we get an implicit exception in AOT generated + // code. AOT DLL's loaded are not registered for structured exceptions. + // If the exception occurred in the codeCache or AOT code, pass control + // to our normal exception handler. + CodeBlob* cb = CodeCache::find_blob(pc); + if (cb != NULL) { + return topLevelExceptionFilter(exceptionInfo); + } + return EXCEPTION_CONTINUE_SEARCH; } +#endif + +#if defined(USE_VECTORED_EXCEPTION_HANDLING) +LONG WINAPI topLevelUnhandledExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) { + if (InterceptOSException) goto exit; + DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode; +#if defined(_M_ARM64) + address pc = (address)exceptionInfo->ContextRecord->Pc; +#elif defined(_M_AMD64) + address pc = (address) exceptionInfo->ContextRecord->Rip; +#else + address pc = (address) exceptionInfo->ContextRecord->Eip; +#endif + Thread* t = Thread::current_or_null_safe(); + + if (exception_code != EXCEPTION_BREAKPOINT) { + report_error(t, exception_code, pc, exceptionInfo->ExceptionRecord, + exceptionInfo->ContextRecord); + } +exit: + return previousUnhandledExceptionFilter ? previousUnhandledExceptionFilter(exceptionInfo) : EXCEPTION_CONTINUE_SEARCH; +} +#endif #ifndef _WIN64 // Special care for fast JNI accessors. @@ -3455,7 +3539,12 @@ char* os::non_memory_address_word() { // Must never look like an address returned by reserve_memory, // even in its subfields (as defined by the CPU immediate fields, // if the CPU splits constants across multiple instructions). +#ifdef _M_ARM64 + // AArch64 has a maximum addressable space of 48-bits + return (char*)((1ull << 48) - 1); +#else return (char*)-1; +#endif } #define MAX_ERROR_COUNT 100 @@ -4129,6 +4218,11 @@ static jint initSock(); jint os::init_2(void) { // Setup Windows Exceptions +#if defined(USE_VECTORED_EXCEPTION_HANDLING) + topLevelVectoredExceptionHandler = AddVectoredExceptionHandler(1, topLevelVectoredExceptionFilter); + previousUnhandledExceptionFilter = SetUnhandledExceptionFilter(topLevelUnhandledExceptionFilter); +#endif + // for debugging float code generation bugs if (ForceFloatExceptions) { #ifndef _WIN64 @@ -5501,7 +5595,7 @@ int os::raw_send(int fd, char* buf, size_t nBytes, uint flags) { // WINDOWS CONTEXT Flags for THREAD_SAMPLING #if defined(IA32) #define sampling_context_flags (CONTEXT_FULL | CONTEXT_FLOATING_POINT | CONTEXT_EXTENDED_REGISTERS) -#elif defined (AMD64) +#elif defined(AMD64) || defined(_M_ARM64) #define sampling_context_flags (CONTEXT_FULL | CONTEXT_FLOATING_POINT) #endif diff --git a/src/hotspot/os_cpu/linux_aarch64/icache_linux_aarch64.hpp b/src/hotspot/os_cpu/linux_aarch64/icache_linux_aarch64.hpp new file mode 100644 index 00000000000..37221953a77 --- /dev/null +++ b/src/hotspot/os_cpu/linux_aarch64/icache_linux_aarch64.hpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, Red Hat Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_LINUX_AARCH64_ICACHE_AARCH64_HPP +#define OS_CPU_LINUX_AARCH64_ICACHE_AARCH64_HPP + +// Interface for updating the instruction cache. Whenever the VM +// modifies code, part of the processor instruction cache potentially +// has to be flushed. + +class ICache : public AbstractICache { + public: + static void initialize(); + static void invalidate_word(address addr) { + __builtin___clear_cache((char *)addr, (char *)(addr + 4)); + } + static void invalidate_range(address start, int nbytes) { + __builtin___clear_cache((char *)start, (char *)(start + nbytes)); + } +}; + +#endif // OS_CPU_LINUX_AARCH64_ICACHE_AARCH64_HPP \ No newline at end of file diff --git a/src/hotspot/os_cpu/windows_aarch64/assembler_windows_aarch64.cpp b/src/hotspot/os_cpu/windows_aarch64/assembler_windows_aarch64.cpp new file mode 100644 index 00000000000..965613fd1e5 --- /dev/null +++ b/src/hotspot/os_cpu/windows_aarch64/assembler_windows_aarch64.cpp @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020, Microsoft Corporation. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +// nothing required here +#include "precompiled.hpp" diff --git a/src/hotspot/os_cpu/windows_aarch64/atomic_windows_aarch64.hpp b/src/hotspot/os_cpu/windows_aarch64/atomic_windows_aarch64.hpp new file mode 100644 index 00000000000..04ca9a9cfdc --- /dev/null +++ b/src/hotspot/os_cpu/windows_aarch64/atomic_windows_aarch64.hpp @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2020, Microsoft Corporation. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_WINDOWS_AARCH64_ATOMIC_WINDOWS_AARCH64_HPP +#define OS_CPU_WINDOWS_AARCH64_ATOMIC_WINDOWS_AARCH64_HPP + +#include +#include "runtime/os.hpp" +#include "runtime/vm_version.hpp" + + +// As per atomic.hpp all read-modify-write operations have to provide two-way +// barriers semantics. The memory_order parameter is ignored - we always provide +// the strongest/most-conservative ordering +// +// For AARCH64 we add explicit barriers in the stubs. + +template +struct Atomic::PlatformAdd + : Atomic::AddAndFetch > +{ + template + D add_and_fetch(I add_value, D volatile* dest, atomic_memory_order order) const; +}; + +// The Interlocked* APIs only take long and will not accept __int32. That is +// acceptable on Windows, since long is a 32-bits integer type. + +#define DEFINE_INTRINSIC_ADD(IntrinsicName, IntrinsicType) \ + template<> \ + template \ + inline D Atomic::PlatformAdd::add_and_fetch(I add_value, \ + D volatile* dest, \ + atomic_memory_order order) const { \ + STATIC_ASSERT(sizeof(IntrinsicType) == sizeof(D)); \ + return PrimitiveConversions::cast( \ + IntrinsicName(reinterpret_cast(dest), \ + PrimitiveConversions::cast(add_value))); \ + } + +DEFINE_INTRINSIC_ADD(InterlockedAdd, long) +DEFINE_INTRINSIC_ADD(InterlockedAdd64, __int64) + +#undef DEFINE_INTRINSIC_ADD + +#define DEFINE_INTRINSIC_XCHG(IntrinsicName, IntrinsicType) \ + template<> \ + template \ + inline T Atomic::PlatformXchg::operator()(T exchange_value, \ + T volatile* dest, \ + atomic_memory_order order) const { \ + STATIC_ASSERT(sizeof(IntrinsicType) == sizeof(T)); \ + return PrimitiveConversions::cast( \ + IntrinsicName(reinterpret_cast(dest), \ + PrimitiveConversions::cast(exchange_value))); \ + } + +DEFINE_INTRINSIC_XCHG(InterlockedExchange, long) +DEFINE_INTRINSIC_XCHG(InterlockedExchange64, __int64) + +#undef DEFINE_INTRINSIC_XCHG + +// Note: the order of the parameters is different between +// Atomic::PlatformCmpxchg<*>::operator() and the +// InterlockedCompareExchange* API. + +#define DEFINE_INTRINSIC_CMPXCHG(IntrinsicName, IntrinsicType) \ + template<> \ + template \ + inline T Atomic::PlatformCmpxchg::operator()(T exchange_value, \ + T volatile* dest, \ + T compare_value, \ + atomic_memory_order order) const { \ + STATIC_ASSERT(sizeof(IntrinsicType) == sizeof(T)); \ + return PrimitiveConversions::cast( \ + IntrinsicName(reinterpret_cast(dest), \ + PrimitiveConversions::cast(exchange_value), \ + PrimitiveConversions::cast(compare_value))); \ + } + +DEFINE_INTRINSIC_CMPXCHG(_InterlockedCompareExchange8, char) // Use the intrinsic as InterlockedCompareExchange8 does not exist +DEFINE_INTRINSIC_CMPXCHG(InterlockedCompareExchange, long) +DEFINE_INTRINSIC_CMPXCHG(InterlockedCompareExchange64, __int64) + +#undef DEFINE_INTRINSIC_CMPXCHG + +#endif // OS_CPU_WINDOWS_AARCH64_ATOMIC_WINDOWS_AARCH64_HPP diff --git a/src/hotspot/os_cpu/windows_aarch64/bytes_windows_aarch64.inline.hpp b/src/hotspot/os_cpu/windows_aarch64/bytes_windows_aarch64.inline.hpp new file mode 100644 index 00000000000..55048963fa4 --- /dev/null +++ b/src/hotspot/os_cpu/windows_aarch64/bytes_windows_aarch64.inline.hpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2020, Microsoft Corporation. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_WINDOWS_AARCH64_BYTES_WINDOWS_AARCH64_INLINE_HPP +#define OS_CPU_WINDOWS_AARCH64_BYTES_WINDOWS_AARCH64_INLINE_HPP + +#include + +// Efficient swapping of data bytes from Java byte +// ordering to native byte ordering and vice versa. +inline u2 Bytes::swap_u2(u2 x) { + return _byteswap_ushort(x); +} + +inline u4 Bytes::swap_u4(u4 x) { + return _byteswap_ulong(x); +} + +inline u8 Bytes::swap_u8(u8 x) { + return _byteswap_uint64(x); +} + +#pragma warning(default: 4035) // Enable warning 4035: no return value + +#endif // OS_CPU_WINDOWS_AARCH64_BYTES_WINDOWS_AARCH64_INLINE_HPP diff --git a/src/hotspot/os_cpu/windows_aarch64/copy_windows_aarch64.inline.hpp b/src/hotspot/os_cpu/windows_aarch64/copy_windows_aarch64.inline.hpp new file mode 100644 index 00000000000..76cb66f1817 --- /dev/null +++ b/src/hotspot/os_cpu/windows_aarch64/copy_windows_aarch64.inline.hpp @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2020, Microsoft Corporation. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_WINDOWS_AARCH64_COPY_WINDOWS_AARCH64_INLINE_HPP +#define OS_CPU_WINDOWS_AARCH64_COPY_WINDOWS_AARCH64_INLINE_HPP + +#include + +static void pd_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) { + (void)memmove(to, from, count * HeapWordSize); +} + +static void pd_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) { + switch (count) { + case 8: to[7] = from[7]; + case 7: to[6] = from[6]; + case 6: to[5] = from[5]; + case 5: to[4] = from[4]; + case 4: to[3] = from[3]; + case 3: to[2] = from[2]; + case 2: to[1] = from[1]; + case 1: to[0] = from[0]; + case 0: break; + default: + (void)memcpy(to, from, count * HeapWordSize); + break; + } +} + +static void pd_disjoint_words_atomic(const HeapWord* from, HeapWord* to, size_t count) { + switch (count) { + case 8: to[7] = from[7]; + case 7: to[6] = from[6]; + case 6: to[5] = from[5]; + case 5: to[4] = from[4]; + case 4: to[3] = from[3]; + case 3: to[2] = from[2]; + case 2: to[1] = from[1]; + case 1: to[0] = from[0]; + case 0: break; + default: while (count-- > 0) { + *to++ = *from++; + } + break; + } +} + +static void pd_aligned_conjoint_words(const HeapWord* from, HeapWord* to, size_t count) { + // pd_conjoint_words(from, to, count); + (void)memmove(to, from, count * HeapWordSize); +} + +static void pd_aligned_disjoint_words(const HeapWord* from, HeapWord* to, size_t count) { + pd_disjoint_words(from, to, count); +} + +static void pd_conjoint_bytes(const void* from, void* to, size_t count) { + (void)memmove(to, from, count); +} + +static void pd_conjoint_bytes_atomic(const void* from, void* to, size_t count) { + pd_conjoint_bytes(from, to, count); +} + +static void pd_conjoint_jshorts_atomic(const jshort* from, jshort* to, size_t count) { + if (from > to) { + while (count-- > 0) { + // Copy forwards + *to++ = *from++; + } + } else { + from += count - 1; + to += count - 1; + while (count-- > 0) { + // Copy backwards + *to-- = *from--; + } + } +} + +static void pd_conjoint_jints_atomic(const jint* from, jint* to, size_t count) { + if (from > to) { + while (count-- > 0) { + // Copy forwards + *to++ = *from++; + } + } else { + from += count - 1; + to += count - 1; + while (count-- > 0) { + // Copy backwards + *to-- = *from--; + } + } +} + +static void pd_conjoint_jlongs_atomic(const jlong* from, jlong* to, size_t count) { + pd_conjoint_oops_atomic((const oop*)from, (oop*)to, count); +} + +static void pd_conjoint_oops_atomic(const oop* from, oop* to, size_t count) { + if (from > to) { + while (count-- > 0) { + // Copy forwards + *to++ = *from++; + } + } else { + from += count - 1; + to += count - 1; + while (count-- > 0) { + // Copy backwards + *to-- = *from--; + } + } +} + +static void pd_arrayof_conjoint_bytes(const HeapWord* from, HeapWord* to, size_t count) { + pd_conjoint_bytes_atomic(from, to, count); +} + +static void pd_arrayof_conjoint_jshorts(const HeapWord* from, HeapWord* to, size_t count) { + pd_conjoint_jshorts_atomic((const jshort*)from, (jshort*)to, count); +} + +static void pd_arrayof_conjoint_jints(const HeapWord* from, HeapWord* to, size_t count) { + pd_conjoint_jints_atomic((const jint*)from, (jint*)to, count); +} + +static void pd_arrayof_conjoint_jlongs(const HeapWord* from, HeapWord* to, size_t count) { + pd_conjoint_jlongs_atomic((const jlong*)from, (jlong*)to, count); +} + +static void pd_arrayof_conjoint_oops(const HeapWord* from, HeapWord* to, size_t count) { + pd_conjoint_oops_atomic((const oop*)from, (oop*)to, count); +} + +#endif // OS_CPU_WINDOWS_AARCH64_COPY_WINDOWS_AARCH64_INLINE_HPP diff --git a/src/hotspot/os_cpu/windows_aarch64/globals_windows_aarch64.hpp b/src/hotspot/os_cpu/windows_aarch64/globals_windows_aarch64.hpp new file mode 100644 index 00000000000..836fb463206 --- /dev/null +++ b/src/hotspot/os_cpu/windows_aarch64/globals_windows_aarch64.hpp @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2020, Microsoft Corporation. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_WINDOWS_AARCH64_GLOBALS_WINDOWS_AARCH64_HPP +#define OS_CPU_WINDOWS_AARCH64_GLOBALS_WINDOWS_AARCH64_HPP + +// Sets the default values for platform dependent flags used by the runtime system. +// (see globals.hpp) + +define_pd_global(bool, DontYieldALot, false); + +// Default stack size on Windows is determined by the executable (java.exe +// has a default value of 320K/1MB [32bit/64bit]). Depending on Windows version, changing +// ThreadStackSize to non-zero may have significant impact on memory usage. +// See comments in os_windows.cpp. +define_pd_global(intx, ThreadStackSize, 0); // 0 => use system default +define_pd_global(intx, VMThreadStackSize, 0); + +#ifdef ASSERT +define_pd_global(intx, CompilerThreadStackSize, 1024); +#else +define_pd_global(intx, CompilerThreadStackSize, 0); +#endif + +define_pd_global(uintx,JVMInvokeMethodSlack, 8192); + +// Used on 64 bit platforms for UseCompressedOops base address +define_pd_global(uintx,HeapBaseMinAddress, 2*G); +#endif // OS_CPU_WINDOWS_AARCH64_GLOBALS_WINDOWS_AARCH64_HPP diff --git a/src/hotspot/os_cpu/windows_aarch64/icache_windows_aarch64.hpp b/src/hotspot/os_cpu/windows_aarch64/icache_windows_aarch64.hpp new file mode 100644 index 00000000000..bf36b77d98e --- /dev/null +++ b/src/hotspot/os_cpu/windows_aarch64/icache_windows_aarch64.hpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, Red Hat Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_WINDOWS_AARCH64_ICACHE_AARCH64_HPP +#define OS_CPU_WINDOWS_AARCH64_ICACHE_AARCH64_HPP + +// Interface for updating the instruction cache. Whenever the VM +// modifies code, part of the processor instruction cache potentially +// has to be flushed. + +class ICache : public AbstractICache { + public: + static void initialize(); + static void invalidate_word(address addr) { + invalidate_range(addr, 4); + } + static void invalidate_range(address start, int nbytes) { + FlushInstructionCache((HANDLE)GetCurrentProcess(), start, (SIZE_T)(nbytes)); + } +}; + +#endif // OS_CPU_WINDOWS_AARCH64_ICACHE_AARCH64_HPP diff --git a/src/hotspot/os_cpu/windows_aarch64/orderAccess_windows_aarch64.hpp b/src/hotspot/os_cpu/windows_aarch64/orderAccess_windows_aarch64.hpp new file mode 100644 index 00000000000..1018860a2d3 --- /dev/null +++ b/src/hotspot/os_cpu/windows_aarch64/orderAccess_windows_aarch64.hpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2020, Microsoft Corporation. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_WINDOWS_AARCH64_ORDERACCESS_WINDOWS_AARCH64_HPP +#define OS_CPU_WINDOWS_AARCH64_ORDERACCESS_WINDOWS_AARCH64_HPP + +// Included in orderAccess.hpp header file. +#include +using std::atomic_thread_fence; +#include +#include "vm_version_aarch64.hpp" +#include "runtime/vm_version.hpp" + +// Implementation of class OrderAccess. + +inline void OrderAccess::loadload() { acquire(); } +inline void OrderAccess::storestore() { release(); } +inline void OrderAccess::loadstore() { acquire(); } +inline void OrderAccess::storeload() { fence(); } + +#define READ_MEM_BARRIER atomic_thread_fence(std::memory_order_acquire); +#define WRITE_MEM_BARRIER atomic_thread_fence(std::memory_order_release); +#define FULL_MEM_BARRIER atomic_thread_fence(std::memory_order_seq_cst); + +inline void OrderAccess::acquire() { + READ_MEM_BARRIER; +} + +inline void OrderAccess::release() { + WRITE_MEM_BARRIER; +} + +inline void OrderAccess::fence() { + FULL_MEM_BARRIER; +} + +#endif // OS_CPU_WINDOWS_AARCH64_ORDERACCESS_WINDOWS_AARCH64_HPP diff --git a/src/hotspot/os_cpu/windows_aarch64/os_windows_aarch64.cpp b/src/hotspot/os_cpu/windows_aarch64/os_windows_aarch64.cpp new file mode 100644 index 00000000000..6f50e429279 --- /dev/null +++ b/src/hotspot/os_cpu/windows_aarch64/os_windows_aarch64.cpp @@ -0,0 +1,312 @@ +/* + * Copyright (c) 2020, Microsoft Corporation. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "jvm.h" +#include "asm/macroAssembler.hpp" +#include "classfile/classLoader.hpp" +#include "classfile/systemDictionary.hpp" +#include "classfile/vmSymbols.hpp" +#include "code/codeCache.hpp" +#include "code/icBuffer.hpp" +#include "code/vtableStubs.hpp" +#include "code/nativeInst.hpp" +#include "interpreter/interpreter.hpp" +#include "memory/allocation.inline.hpp" +#include "prims/jniFastGetField.hpp" +#include "prims/jvm_misc.hpp" +#include "runtime/arguments.hpp" +#include "runtime/frame.inline.hpp" +#include "runtime/interfaceSupport.inline.hpp" +#include "runtime/java.hpp" +#include "runtime/javaCalls.hpp" +#include "runtime/mutexLocker.hpp" +#include "runtime/osThread.hpp" +#include "runtime/sharedRuntime.hpp" +#include "runtime/stubRoutines.hpp" +#include "runtime/thread.inline.hpp" +#include "runtime/timer.hpp" +#include "unwind_windows_aarch64.hpp" +#include "utilities/debug.hpp" +#include "utilities/events.hpp" +#include "utilities/vmError.hpp" + + +// put OS-includes here +# include +# include +# include +# include +# include +# include + +void os::os_exception_wrapper(java_call_t f, JavaValue* value, const methodHandle& method, JavaCallArguments* args, Thread* thread) { + f(value, method, args, thread); +} + +#pragma warning(disable: 4172) + +// Returns an estimate of the current stack pointer. Result must be guaranteed +// to point into the calling threads stack, and be no lower than the current +// stack pointer. +address os::current_stack_pointer() { + int dummy; + address sp = (address)&dummy; + return sp; +} + +#pragma warning(default: 4172) + +ExtendedPC os::fetch_frame_from_context(const void* ucVoid, + intptr_t** ret_sp, intptr_t** ret_fp) { + ExtendedPC epc; + CONTEXT* uc = (CONTEXT*)ucVoid; + + if (uc != NULL) { + epc = ExtendedPC((address)uc->Pc); + if (ret_sp) *ret_sp = (intptr_t*)uc->Sp; + if (ret_fp) *ret_fp = (intptr_t*)uc->Fp; + } else { + // construct empty ExtendedPC for return value checking + epc = NULL; + if (ret_sp) *ret_sp = (intptr_t *)NULL; + if (ret_fp) *ret_fp = (intptr_t *)NULL; + } + return epc; +} + +frame os::fetch_frame_from_context(const void* ucVoid) { + intptr_t* sp; + intptr_t* fp; + ExtendedPC epc = fetch_frame_from_context(ucVoid, &sp, &fp); + return frame(sp, fp, epc.pc()); +} + +bool os::win32::get_frame_at_stack_banging_point(JavaThread* thread, + struct _EXCEPTION_POINTERS* exceptionInfo, address pc, frame* fr) { + PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord; + address addr = (address) exceptionRecord->ExceptionInformation[1]; + if (Interpreter::contains(pc)) { + *fr = os::fetch_frame_from_context((void*)exceptionInfo->ContextRecord); + if (!fr->is_first_java_frame()) { + // get_frame_at_stack_banging_point() is only called when we + // have well defined stacks so java_sender() calls do not need + // to assert safe_for_sender() first. + *fr = fr->java_sender(); + } + } else { + // more complex code with compiled code + assert(!Interpreter::contains(pc), "Interpreted methods should have been handled above"); + CodeBlob* cb = CodeCache::find_blob(pc); + if (cb == NULL || !cb->is_nmethod() || cb->is_frame_complete_at(pc)) { + // Not sure where the pc points to, fallback to default + // stack overflow handling + return false; + } else { + // In compiled code, the stack banging is performed before LR + // has been saved in the frame. LR is live, and SP and FP + // belong to the caller. + intptr_t* fp = (intptr_t*)exceptionInfo->ContextRecord->Fp; + intptr_t* sp = (intptr_t*)exceptionInfo->ContextRecord->Sp; + address pc = (address)(exceptionInfo->ContextRecord->Lr + - NativeInstruction::instruction_size); + *fr = frame(sp, fp, pc); + if (!fr->is_java_frame()) { + assert(fr->safe_for_sender(thread), "Safety check"); + assert(!fr->is_first_frame(), "Safety check"); + *fr = fr->java_sender(); + } + } + } + assert(fr->is_java_frame(), "Safety check"); + return true; +} + +// By default, gcc always saves frame pointer rfp on this stack. This +// may get turned off by -fomit-frame-pointer. +frame os::get_sender_for_C_frame(frame* fr) { + return frame(fr->link(), fr->link(), fr->sender_pc()); +} + +frame os::current_frame() { + typedef intptr_t* get_fp_func (); + get_fp_func* func = CAST_TO_FN_PTR(get_fp_func*, + StubRoutines::aarch64::get_previous_fp_entry()); + if (func == NULL) return frame(); + intptr_t* fp = (*func)(); + if (fp == NULL) { + return frame(); + } + + frame myframe((intptr_t*)os::current_stack_pointer(), + (intptr_t*)fp, + CAST_FROM_FN_PTR(address, os::current_frame)); + if (os::is_first_C_frame(&myframe)) { + + // stack is not walkable + return frame(); + } else { + return os::get_sender_for_C_frame(&myframe); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// thread stack + +// Minimum usable stack sizes required to get to user code. Space for +// HotSpot guard pages is added later. + +///////////////////////////////////////////////////////////////////////////// +// helper functions for fatal error handler + +void os::print_context(outputStream *st, const void *context) { + if (context == NULL) return; + + const CONTEXT* uc = (const CONTEXT*)context; + + st->print_cr("Registers:"); + + st->print( "X0 =" INTPTR_FORMAT, uc->X0); + st->print(", X1 =" INTPTR_FORMAT, uc->X1); + st->print(", X2 =" INTPTR_FORMAT, uc->X2); + st->print(", X3 =" INTPTR_FORMAT, uc->X3); + st->cr(); + st->print( "X4 =" INTPTR_FORMAT, uc->X4); + st->print(", X5 =" INTPTR_FORMAT, uc->X5); + st->print(", X6 =" INTPTR_FORMAT, uc->X6); + st->print(", X7 =" INTPTR_FORMAT, uc->X7); + st->cr(); + st->print( "X8 =" INTPTR_FORMAT, uc->X8); + st->print(", X9 =" INTPTR_FORMAT, uc->X9); + st->print(", X10=" INTPTR_FORMAT, uc->X10); + st->print(", X11=" INTPTR_FORMAT, uc->X11); + st->cr(); + st->print( "X12=" INTPTR_FORMAT, uc->X12); + st->print(", X13=" INTPTR_FORMAT, uc->X13); + st->print(", X14=" INTPTR_FORMAT, uc->X14); + st->print(", X15=" INTPTR_FORMAT, uc->X15); + st->cr(); + st->print( "X16=" INTPTR_FORMAT, uc->X16); + st->print(", X17=" INTPTR_FORMAT, uc->X17); + st->print(", X18=" INTPTR_FORMAT, uc->X18); + st->print(", X19=" INTPTR_FORMAT, uc->X19); + st->cr(); + st->print(", X20=" INTPTR_FORMAT, uc->X20); + st->print(", X21=" INTPTR_FORMAT, uc->X21); + st->print(", X22=" INTPTR_FORMAT, uc->X22); + st->print(", X23=" INTPTR_FORMAT, uc->X23); + st->cr(); + st->print(", X24=" INTPTR_FORMAT, uc->X24); + st->print(", X25=" INTPTR_FORMAT, uc->X25); + st->print(", X26=" INTPTR_FORMAT, uc->X26); + st->print(", X27=" INTPTR_FORMAT, uc->X27); + st->print(", X28=" INTPTR_FORMAT, uc->X28); + st->cr(); + st->cr(); + + intptr_t *sp = (intptr_t *)uc->Sp; + st->print_cr("Top of Stack: (sp=" PTR_FORMAT ")", sp); + print_hex_dump(st, (address)sp, (address)(sp + 32), sizeof(intptr_t)); + st->cr(); + + // Note: it may be unsafe to inspect memory near pc. For example, pc may + // point to garbage if entry point in an nmethod is corrupted. Leave + // this at the end, and hope for the best. + address pc = (address)uc->Pc; + st->print_cr("Instructions: (pc=" PTR_FORMAT ")", pc); + print_hex_dump(st, pc - 32, pc + 32, sizeof(char)); + st->cr(); + +} + +void os::print_register_info(outputStream *st, const void *context) { + if (context == NULL) return; + + const CONTEXT* uc = (const CONTEXT*)context; + + st->print_cr("Register to memory mapping:"); + st->cr(); + // this is only for the "general purpose" registers + st->print(" X0="); print_location(st, uc->X0); + st->print(" X1="); print_location(st, uc->X1); + st->print(" X2="); print_location(st, uc->X2); + st->print(" X3="); print_location(st, uc->X3); + st->cr(); + st->print(" X4="); print_location(st, uc->X4); + st->print(" X5="); print_location(st, uc->X5); + st->print(" X6="); print_location(st, uc->X6); + st->print(" X7="); print_location(st, uc->X7); + st->cr(); + st->print(" X8="); print_location(st, uc->X8); + st->print(" X9="); print_location(st, uc->X9); + st->print("X10="); print_location(st, uc->X10); + st->print("X11="); print_location(st, uc->X11); + st->cr(); + st->print("X12="); print_location(st, uc->X12); + st->print("X13="); print_location(st, uc->X13); + st->print("X14="); print_location(st, uc->X14); + st->print("X15="); print_location(st, uc->X15); + st->cr(); + st->print("X16="); print_location(st, uc->X16); + st->print("X17="); print_location(st, uc->X17); + st->print("X18="); print_location(st, uc->X18); + st->print("X19="); print_location(st, uc->X19); + st->cr(); + st->print("X20="); print_location(st, uc->X20); + st->print("X21="); print_location(st, uc->X21); + st->print("X22="); print_location(st, uc->X22); + st->print("X23="); print_location(st, uc->X23); + st->cr(); + st->print("X24="); print_location(st, uc->X24); + st->print("X25="); print_location(st, uc->X25); + st->print("X26="); print_location(st, uc->X26); + st->print("X27="); print_location(st, uc->X27); + st->print("X28="); print_location(st, uc->X28); + + st->cr(); +} + +void os::setup_fpu() { +} + +bool os::supports_sse() { + return true; +} + +#ifndef PRODUCT +void os::verify_stack_alignment() { + assert(((intptr_t)os::current_stack_pointer() & (StackAlignmentInBytes-1)) == 0, "incorrect stack alignment"); +} +#endif + +int os::extra_bang_size_in_bytes() { + // AArch64 does not require the additional stack bang. + return 0; +} + +extern "C" { + int SpinPause() { + return 0; + } +}; diff --git a/src/hotspot/os_cpu/windows_aarch64/os_windows_aarch64.hpp b/src/hotspot/os_cpu/windows_aarch64/os_windows_aarch64.hpp new file mode 100644 index 00000000000..fedf5848f9e --- /dev/null +++ b/src/hotspot/os_cpu/windows_aarch64/os_windows_aarch64.hpp @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2020, Microsoft Corporation. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_WINDOWS_AARCH64_OS_WINDOWS_AARCH64_HPP +#define OS_CPU_WINDOWS_AARCH64_OS_WINDOWS_AARCH64_HPP + + static void setup_fpu(); + static bool supports_sse(); + + static bool register_code_area(char *low, char *high) { + // Using Vectored Exception Handling + return true; + } + +#endif // OS_CPU_WINDOWS_AARCH64_OS_WINDOWS_AARCH64_HPP diff --git a/src/hotspot/os_cpu/windows_aarch64/os_windows_aarch64.inline.hpp b/src/hotspot/os_cpu/windows_aarch64/os_windows_aarch64.inline.hpp new file mode 100644 index 00000000000..673cd3fa29d --- /dev/null +++ b/src/hotspot/os_cpu/windows_aarch64/os_windows_aarch64.inline.hpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2020, Microsoft Corporation. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_WINDOWS_AARCH64_OS_WINDOWS_AARCH64_INLINE_HPP +#define OS_CPU_WINDOWS_AARCH64_OS_WINDOWS_AARCH64_INLINE_HPP + +#include "runtime/os.hpp" + +#endif // OS_CPU_WINDOWS_AARCH64_OS_WINDOWS_AARCH64_INLINE_HPP diff --git a/src/hotspot/os_cpu/windows_aarch64/pauth_windows_aarch64.inline.hpp b/src/hotspot/os_cpu/windows_aarch64/pauth_windows_aarch64.inline.hpp new file mode 100644 index 00000000000..844291ee1e4 --- /dev/null +++ b/src/hotspot/os_cpu/windows_aarch64/pauth_windows_aarch64.inline.hpp @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2021, Arm Limited. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_WINDOWS_AARCH64_PAUTH_WINDOWS_AARCH64_INLINE_HPP +#define OS_CPU_WINDOWS_AARCH64_PAUTH_WINDOWS_AARCH64_INLINE_HPP + +inline address pauth_strip_pointer(address ptr) { + // No PAC support in windows as of yet. + return ptr; +} + +#endif // OS_CPU_WINDOWS_AARCH64_PAUTH_WINDOWS_AARCH64_INLINE_HPP + diff --git a/src/hotspot/os_cpu/windows_aarch64/prefetch_windows_aarch64.inline.hpp b/src/hotspot/os_cpu/windows_aarch64/prefetch_windows_aarch64.inline.hpp new file mode 100644 index 00000000000..d2bd8f14119 --- /dev/null +++ b/src/hotspot/os_cpu/windows_aarch64/prefetch_windows_aarch64.inline.hpp @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2020, Microsoft Corporation. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_WINDOWS_AARCH64_PREFETCH_WINDOWS_AARCH64_INLINE_HPP +#define OS_CPU_WINDOWS_AARCH64_PREFETCH_WINDOWS_AARCH64_INLINE_HPP + +#include "runtime/prefetch.hpp" + + +inline void Prefetch::read (void *loc, intx interval) { +} + +inline void Prefetch::write(void *loc, intx interval) { +} + +#endif // OS_CPU_WINDOWS_AARCH64_PREFETCH_WINDOWS_AARCH64_INLINE_HPP diff --git a/src/hotspot/os_cpu/windows_aarch64/thread_windows_aarch64.cpp b/src/hotspot/os_cpu/windows_aarch64/thread_windows_aarch64.cpp new file mode 100644 index 00000000000..d235b4850e8 --- /dev/null +++ b/src/hotspot/os_cpu/windows_aarch64/thread_windows_aarch64.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2020, Microsoft Corporation. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "memory/metaspaceShared.hpp" +#include "runtime/frame.inline.hpp" +#include "runtime/thread.inline.hpp" + +frame JavaThread::pd_last_frame() { + assert(has_last_Java_frame(), "must have last_Java_sp() when suspended"); + vmassert(_anchor.last_Java_pc() != NULL, "not walkable"); + return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc()); +} + +// For Forte Analyzer AsyncGetCallTrace profiling support - thread is +// currently interrupted by SIGPROF +bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr, + void* ucontext, bool isInJava) { + + assert(Thread::current() == this, "caller must be current thread"); + return pd_get_top_frame(fr_addr, ucontext, isInJava); +} + +bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava) { + return pd_get_top_frame(fr_addr, ucontext, isInJava); +} + +bool JavaThread::pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava) { + + assert(this->is_Java_thread(), "must be JavaThread"); + + JavaThread* jt = (JavaThread *)this; + + // If we have a last_Java_frame, then we should use it even if + // isInJava == true. It should be more reliable than CONTEXT info. + if (jt->has_last_Java_frame() && jt->frame_anchor()->walkable()) { + *fr_addr = jt->pd_last_frame(); + return true; + } + + // At this point, we don't have a last_Java_frame, so + // we try to glean some information out of the CONTEXT + // if we were running Java code when SIGPROF came in. + if (isInJava) { + frame ret_frame = os::fetch_frame_from_context(ucontext); + if (ret_frame.pc() == NULL || ret_frame.sp() == NULL ) { + // CONTEXT wasn't useful + return false; + } + + if (MetaspaceShared::is_in_trampoline_frame(ret_frame.pc())) { + // In the middle of a trampoline call. Bail out for safety. + // This happens rarely so shouldn't affect profiling. + return false; + } + + if (!ret_frame.safe_for_sender(jt)) { +#if COMPILER2_OR_JVMCI + // C2 and JVMCI use ebp as a general register see if NULL fp helps + frame ret_frame2(ret_frame.sp(), NULL, ret_frame.pc()); + if (!ret_frame2.safe_for_sender(jt)) { + // nothing else to try if the frame isn't good + return false; + } + ret_frame = ret_frame2; +#else + // nothing else to try if the frame isn't good + return false; +#endif // COMPILER2_OR_JVMCI + } + *fr_addr = ret_frame; + return true; + } + + // nothing else to try + return false; +} + +void JavaThread::cache_global_variables() { } diff --git a/src/hotspot/os_cpu/windows_aarch64/thread_windows_aarch64.hpp b/src/hotspot/os_cpu/windows_aarch64/thread_windows_aarch64.hpp new file mode 100644 index 00000000000..aaec153a4e4 --- /dev/null +++ b/src/hotspot/os_cpu/windows_aarch64/thread_windows_aarch64.hpp @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2020, Microsoft Corporation. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_WINDOWS_AARCH64_THREAD_WINDOWS_AARCH64_HPP +#define OS_CPU_WINDOWS_AARCH64_THREAD_WINDOWS_AARCH64_HPP + + private: + +#ifdef ASSERT + // spill stack holds N callee-save registers at each Java call and + // grows downwards towards limit + // we need limit to check we have space for a spill and base so we + // can identify all live spill frames at GC (eventually) + address _spill_stack; + address _spill_stack_base; + address _spill_stack_limit; +#endif // ASSERT + + void pd_initialize() { + _anchor.clear(); + } + + frame pd_last_frame(); + + public: + // Mutators are highly dangerous.... + intptr_t* last_Java_fp() { return _anchor.last_Java_fp(); } + void set_last_Java_fp(intptr_t* fp) { _anchor.set_last_Java_fp(fp); } + + void set_base_of_stack_pointer(intptr_t* base_sp) {} + + static ByteSize last_Java_fp_offset() { + return byte_offset_of(JavaThread, _anchor) + JavaFrameAnchor::last_Java_fp_offset(); + } + + intptr_t* base_of_stack_pointer() { return NULL; } + void record_base_of_stack_pointer() {} + + bool pd_get_top_frame_for_signal_handler(frame* fr_addr, void* ucontext, + bool isInJava); + + bool pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava); +private: + bool pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava); +public: + + static Thread *aarch64_get_thread_helper() { + return Thread::current(); + } + + public: + // These routines are only used on cpu architectures that + // have separate register stacks (Itanium). + static bool register_stack_overflow() { return false; } + static void enable_register_stack_guard() {} + static void disable_register_stack_guard() {} + +#endif // OS_CPU_WINDOWS_AARCH64_THREAD_WINDOWS_AARCH64_HPP diff --git a/src/hotspot/os_cpu/windows_aarch64/unwind_windows_aarch64.hpp b/src/hotspot/os_cpu/windows_aarch64/unwind_windows_aarch64.hpp new file mode 100644 index 00000000000..477e0b09457 --- /dev/null +++ b/src/hotspot/os_cpu/windows_aarch64/unwind_windows_aarch64.hpp @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2020, Microsoft Corporation. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_WINDOWS_AARCH64_UNWIND_WINDOWS_AARCH64_HPP +#define OS_CPU_WINDOWS_AARCH64_UNWIND_WINDOWS_AARCH64_HPP + + +typedef unsigned char UBYTE; + +#if _MSC_VER < 1700 + +/* Not needed for VS2012 compiler, comes from winnt.h. */ +#define UNW_FLAG_EHANDLER 0x01 +#define UNW_FLAG_UHANDLER 0x02 +#define UNW_FLAG_CHAININFO 0x04 + +#endif + +// See https://docs.microsoft.com/en-us/cpp/build/arm64-exception-handling#xdata-records +typedef struct _UNWIND_INFO_EH_ONLY { + DWORD FunctionLength : 18; + DWORD Version : 2; + DWORD X : 1; // = 1 + DWORD E : 1; // = 1 + DWORD EpilogCount : 5; // = 0 + DWORD CodeWords : 5; // = 1 + DWORD UnwindCode0 : 8; + DWORD UnwindCode1 : 8; + DWORD UnwindCode2 : 8; + DWORD UnwindCode3 : 8; + DWORD ExceptionHandler; +} UNWIND_INFO_EH_ONLY, *PUNWIND_INFO_EH_ONLY; + +/* +typedef struct _RUNTIME_FUNCTION { + DWORD BeginAddress; + union { + DWORD UnwindData; + struct { + DWORD Flag : 2; + DWORD FunctionLength : 11; + DWORD RegF : 3; + DWORD RegI : 4; + DWORD H : 1; + DWORD CR : 2; + DWORD FrameSize : 9; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; +} RUNTIME_FUNCTION, *PRUNTIME_FUNCTION; +*/ + +#if _MSC_VER < 1700 + +/* Not needed for VS2012 compiler, comes from winnt.h. */ +typedef struct _DISPATCHER_CONTEXT { + ULONG64 ControlPc; + ULONG64 ImageBase; + PRUNTIME_FUNCTION FunctionEntry; + ULONG64 EstablisherFrame; + ULONG64 TargetIp; + PCONTEXT ContextRecord; +// PEXCEPTION_ROUTINE LanguageHandler; + char * LanguageHandler; // double dependency problem + PVOID HandlerData; +} DISPATCHER_CONTEXT, *PDISPATCHER_CONTEXT; + +#endif + +#if _MSC_VER < 1500 + +/* Not needed for VS2008 compiler, comes from winnt.h. */ +typedef EXCEPTION_DISPOSITION (*PEXCEPTION_ROUTINE) ( + IN PEXCEPTION_RECORD ExceptionRecord, + IN ULONG64 EstablisherFrame, + IN OUT PCONTEXT ContextRecord, + IN OUT PDISPATCHER_CONTEXT DispatcherContext +); + +#endif + +#endif // OS_CPU_WINDOWS_AARCH64_UNWIND_WINDOWS_AARCH64_HPP diff --git a/src/hotspot/os_cpu/windows_aarch64/vmStructs_windows_aarch64.hpp b/src/hotspot/os_cpu/windows_aarch64/vmStructs_windows_aarch64.hpp new file mode 100644 index 00000000000..220787823dc --- /dev/null +++ b/src/hotspot/os_cpu/windows_aarch64/vmStructs_windows_aarch64.hpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2020, Microsoft Corporation. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_WINDOWS_AARCH64_VMSTRUCTS_WINDOWS_AARCH64_HPP +#define OS_CPU_WINDOWS_AARCH64_VMSTRUCTS_WINDOWS_AARCH64_HPP + +// These are the OS and CPU-specific fields, types and integer +// constants required by the Serviceability Agent. This file is +// referenced by vmStructs.cpp. + +#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \ + \ + /******************************/ \ + /* Threads (NOTE: incomplete) */ \ + /******************************/ \ + \ + nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) \ + unchecked_nonstatic_field(OSThread, _thread_handle, sizeof(HANDLE)) /* NOTE: no type */ + +#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) \ + \ + declare_unsigned_integer_type(OSThread::thread_id_t) + +#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) + +#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) + +#endif // OS_CPU_WINDOWS_AARCH64_VMSTRUCTS_WINDOWS_AARCH64_HPP diff --git a/src/hotspot/os_cpu/windows_aarch64/vm_version_windows_aarch64.cpp b/src/hotspot/os_cpu/windows_aarch64/vm_version_windows_aarch64.cpp new file mode 100644 index 00000000000..5548a31255e --- /dev/null +++ b/src/hotspot/os_cpu/windows_aarch64/vm_version_windows_aarch64.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2020, Microsoft Corporation. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "runtime/os.hpp" +#include "runtime/vm_version.hpp" + +void VM_Version::get_os_cpu_info() { + + if (IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE)) _features |= CPU_CRC32; + if (IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE)) _features |= CPU_AES | CPU_SHA1 | CPU_SHA2; + if (IsProcessorFeaturePresent(PF_ARM_VFP_32_REGISTERS_AVAILABLE)) _features |= CPU_ASIMD; + // No check for CPU_PMULL + + __int64 dczid_el0 = _ReadStatusReg(0x5807 /* ARM64_DCZID_EL0 */); + + if (!(dczid_el0 & 0x10)) { + _zva_length = 4 << (dczid_el0 & 0xf); + } + + { + PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buffer = NULL; + DWORD returnLength = 0; + + // See https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getlogicalprocessorinformation + GetLogicalProcessorInformation(NULL, &returnLength); + assert(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Unexpected return from GetLogicalProcessorInformation"); + + buffer = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)os::malloc(returnLength, mtInternal); + BOOL rc = GetLogicalProcessorInformation(buffer, &returnLength); + assert(rc, "Unexpected return from GetLogicalProcessorInformation"); + + _icache_line_size = _dcache_line_size = -1; + for (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION ptr = buffer; ptr < buffer + returnLength / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION); ptr++) { + switch (ptr->Relationship) { + case RelationCache: + // Cache data is in ptr->Cache, one CACHE_DESCRIPTOR structure for each cache. + PCACHE_DESCRIPTOR Cache = &ptr->Cache; + if (Cache->Level == 1) { + _icache_line_size = _dcache_line_size = Cache->LineSize; + } + break; + } + } + os::free(buffer); + } + + { + char* buf = ::getenv("PROCESSOR_IDENTIFIER"); + if (buf && strstr(buf, "Ampere(TM)") != NULL) { + _cpu = CPU_AMCC; + } else if (buf && strstr(buf, "Cavium Inc.") != NULL) { + _cpu = CPU_CAVIUM; + } else { + log_info(os)("VM_Version: unknown CPU model"); + } + + if (_cpu) { + SYSTEM_INFO si; + GetSystemInfo(&si); + _model = si.wProcessorLevel; + _variant = si.wProcessorRevision / 0xFF; + _revision = si.wProcessorRevision & 0xFF; + } + } +} diff --git a/src/hotspot/os_cpu/windows_x86/os_windows_x86.cpp b/src/hotspot/os_cpu/windows_x86/os_windows_x86.cpp index 7bd2a8b834b..9504f3552f7 100644 --- a/src/hotspot/os_cpu/windows_x86/os_windows_x86.cpp +++ b/src/hotspot/os_cpu/windows_x86/os_windows_x86.cpp @@ -488,6 +488,41 @@ address os::current_stack_pointer() { } #endif +bool os::win32::get_frame_at_stack_banging_point(JavaThread* thread, + struct _EXCEPTION_POINTERS* exceptionInfo, address pc, frame* fr) { + PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord; + address addr = (address) exceptionRecord->ExceptionInformation[1]; + if (Interpreter::contains(pc)) { + *fr = os::fetch_frame_from_context((void*)exceptionInfo->ContextRecord); + if (!fr->is_first_java_frame()) { + // get_frame_at_stack_banging_point() is only called when we + // have well defined stacks so java_sender() calls do not need + // to assert safe_for_sender() first. + *fr = fr->java_sender(); + } + } else { + // more complex code with compiled code + assert(!Interpreter::contains(pc), "Interpreted methods should have been handled above"); + CodeBlob* cb = CodeCache::find_blob(pc); + if (cb == NULL || !cb->is_nmethod() || cb->is_frame_complete_at(pc)) { + // Not sure where the pc points to, fallback to default + // stack overflow handling + return false; + } else { + // in compiled code, the stack banging is performed just after the return pc + // has been pushed on the stack + intptr_t* fp = (intptr_t*)exceptionInfo->ContextRecord->REG_FP; + intptr_t* sp = (intptr_t*)exceptionInfo->ContextRecord->REG_SP; + *fr = frame(sp + 1, fp, (address)*sp); + if (!fr->is_java_frame()) { + // See java_sender() comment above. + *fr = fr->java_sender(); + } + } + } + assert(fr->is_java_frame(), "Safety check"); + return true; +} #ifndef AMD64 intptr_t* _get_previous_fp() { diff --git a/src/hotspot/share/prims/jni.cpp b/src/hotspot/share/prims/jni.cpp index aa7e9e69706..e26b3a9d322 100644 --- a/src/hotspot/share/prims/jni.cpp +++ b/src/hotspot/share/prims/jni.cpp @@ -97,7 +97,7 @@ static jint CurrentVersion = JNI_VERSION_10; -#ifdef _WIN32 +#if defined(_WIN32) && !defined(USE_VECTORED_EXCEPTION_HANDLING) extern LONG WINAPI topLevelExceptionFilter(_EXCEPTION_POINTERS* ); #endif @@ -4093,11 +4093,11 @@ static jint JNI_CreateJavaVM_inner(JavaVM **vm, void **penv, void *args) { _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_CreateJavaVM(JavaVM **vm, void **penv, void *args) { jint result = JNI_ERR; // On Windows, let CreateJavaVM run with SEH protection -#ifdef _WIN32 +#if defined(_WIN32) && !defined(USE_VECTORED_EXCEPTION_HANDLING) __try { #endif result = JNI_CreateJavaVM_inner(vm, penv, args); -#ifdef _WIN32 +#if defined(_WIN32) && !defined(USE_VECTORED_EXCEPTION_HANDLING) } __except(topLevelExceptionFilter((_EXCEPTION_POINTERS*)_exception_info())) { // Nothing to do. } @@ -4165,11 +4165,11 @@ static jint JNICALL jni_DestroyJavaVM_inner(JavaVM *vm) { jint JNICALL jni_DestroyJavaVM(JavaVM *vm) { jint result = JNI_ERR; // On Windows, we need SEH protection -#ifdef _WIN32 +#if defined(_WIN32) && !defined(USE_VECTORED_EXCEPTION_HANDLING) __try { #endif result = jni_DestroyJavaVM_inner(vm); -#ifdef _WIN32 +#if defined(_WIN32) && !defined(USE_VECTORED_EXCEPTION_HANDLING) } __except(topLevelExceptionFilter((_EXCEPTION_POINTERS*)_exception_info())) { // Nothing to do. } diff --git a/src/hotspot/share/utilities/globalDefinitions_visCPP.hpp b/src/hotspot/share/utilities/globalDefinitions_visCPP.hpp index add42ba2b83..7742fb6428b 100644 --- a/src/hotspot/share/utilities/globalDefinitions_visCPP.hpp +++ b/src/hotspot/share/utilities/globalDefinitions_visCPP.hpp @@ -172,4 +172,8 @@ inline int g_isfinite(jdouble f) { return _finite(f); } // Alignment #define ATTRIBUTE_ALIGNED(x) __declspec(align(x)) +#ifdef _M_ARM64 +#define USE_VECTORED_EXCEPTION_HANDLING +#endif + #endif // SHARE_VM_UTILITIES_GLOBALDEFINITIONS_VISCPP_HPP diff --git a/src/java.base/windows/native/libjava/java_props_md.c b/src/java.base/windows/native/libjava/java_props_md.c index 256f76f7853..b17b57fbd85 100644 --- a/src/java.base/windows/native/libjava/java_props_md.c +++ b/src/java.base/windows/native/libjava/java_props_md.c @@ -590,6 +590,8 @@ GetJavaProperties(JNIEnv* env) sprops.os_arch = "amd64"; #elif _X86_ sprops.os_arch = "x86"; +#elif defined(_M_ARM64) + sprops.os_arch = "aarch64"; #else sprops.os_arch = "unknown"; #endif diff --git a/src/jdk.attach/windows/classes/sun/tools/attach/AttachProviderImpl.java b/src/jdk.attach/windows/classes/sun/tools/attach/AttachProviderImpl.java index c094622e7db..1c0fb927f5c 100644 --- a/src/jdk.attach/windows/classes/sun/tools/attach/AttachProviderImpl.java +++ b/src/jdk.attach/windows/classes/sun/tools/attach/AttachProviderImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,7 @@ public AttachProviderImpl() { "This provider is not supported on this version of Windows"); } String arch = System.getProperty("os.arch"); - if (!arch.equals("x86") && !arch.equals("amd64")) { + if (!arch.equals("x86") && !arch.equals("amd64") && !arch.equals("aarch64")) { throw new RuntimeException( "This provider is not supported on this processor architecture"); } diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HotSpotAgent.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HotSpotAgent.java index 33f20eadbb8..deec9df0a48 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HotSpotAgent.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HotSpotAgent.java @@ -555,8 +555,10 @@ private void setupDebuggerWin32() { machDesc = new MachineDescriptionIntelX86(); } else if (cpu.equals("amd64")) { machDesc = new MachineDescriptionAMD64(); + } else if (cpu.equals("aarch64")) { + machDesc = new MachineDescriptionAArch64(); } else { - throw new DebuggerException("Win32 supported under x86 and amd64 only"); + throw new DebuggerException("Win32 supported under x86, amd64 and aarch64 only"); } // Note we do not use a cache for the local debugger in server diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgDebuggerLocal.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgDebuggerLocal.java index 4536f215485..84a99ee1183 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgDebuggerLocal.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgDebuggerLocal.java @@ -28,8 +28,10 @@ import java.net.*; import java.util.*; import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.debugger.aarch64.*; import sun.jvm.hotspot.debugger.amd64.*; import sun.jvm.hotspot.debugger.x86.*; +import sun.jvm.hotspot.debugger.windbg.aarch64.*; import sun.jvm.hotspot.debugger.windbg.amd64.*; import sun.jvm.hotspot.debugger.windbg.x86.*; import sun.jvm.hotspot.debugger.win32.coff.*; @@ -113,6 +115,8 @@ public void checkAlignment(long address, long alignment) { threadFactory = new WindbgX86ThreadFactory(this); } else if (cpu.equals("amd64")) { threadFactory = new WindbgAMD64ThreadFactory(this); + } else if (cpu.equals("aarch64")) { + threadFactory = new WindbgAARCH64ThreadFactory(this); } if (useCache) { diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/windbg/aarch64/WindbgAARCH64Thread.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/windbg/aarch64/WindbgAARCH64Thread.java new file mode 100644 index 00000000000..cbc34f4cc7d --- /dev/null +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/windbg/aarch64/WindbgAARCH64Thread.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, Microsoft Corporation. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.debugger.windbg.aarch64; + +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.debugger.aarch64.*; +import sun.jvm.hotspot.debugger.windbg.*; + +class WindbgAARCH64Thread implements ThreadProxy { + private WindbgDebugger debugger; + private long sysId; + private boolean gotID; + private long id; + + // The address argument must be the address of the OSThread::_thread_id + WindbgAARCH64Thread(WindbgDebugger debugger, Address addr) { + this.debugger = debugger; + this.sysId = (long)addr.getCIntegerAt(0, 4, true); + gotID = false; + } + + WindbgAARCH64Thread(WindbgDebugger debugger, long sysId) { + this.debugger = debugger; + this.sysId = sysId; + gotID = false; + } + + public ThreadContext getContext() throws IllegalThreadStateException { + long[] data = debugger.getThreadIntegerRegisterSet(getThreadID()); + WindbgAARCH64ThreadContext context = new WindbgAARCH64ThreadContext(debugger); + for (int i = 0; i < data.length; i++) { + context.setRegister(i, data[i]); + } + return context; + } + + public boolean canSetContext() throws DebuggerException { + return false; + } + + public void setContext(ThreadContext thrCtx) + throws IllegalThreadStateException, DebuggerException { + throw new DebuggerException("Unimplemented"); + } + + public boolean equals(Object obj) { + if ((obj == null) || !(obj instanceof WindbgAARCH64Thread)) { + return false; + } + + return (((WindbgAARCH64Thread) obj).getThreadID() == getThreadID()); + } + + public int hashCode() { + return (int) getThreadID(); + } + + public String toString() { + return Long.toString(getThreadID()); + } + + /** Retrieves the thread ID of this thread by examining the Thread + Information Block. */ + private long getThreadID() { + if (!gotID) { + id = debugger.getThreadIdFromSysId(sysId); + } + + return id; + } +} diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/windbg/aarch64/WindbgAARCH64ThreadContext.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/windbg/aarch64/WindbgAARCH64ThreadContext.java new file mode 100644 index 00000000000..8da63ed1ad2 --- /dev/null +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/windbg/aarch64/WindbgAARCH64ThreadContext.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, Microsoft Corporation. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.debugger.windbg.aarch64; + +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.debugger.aarch64.*; +import sun.jvm.hotspot.debugger.windbg.*; + +class WindbgAARCH64ThreadContext extends AARCH64ThreadContext { + private WindbgDebugger debugger; + + public WindbgAARCH64ThreadContext(WindbgDebugger debugger) { + super(); + this.debugger = debugger; + } + + public void setRegisterAsAddress(int index, Address value) { + setRegister(index, debugger.getAddressValue(value)); + } + + public Address getRegisterAsAddress(int index) { + return debugger.newAddress(getRegister(index)); + } +} diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/windbg/aarch64/WindbgAARCH64ThreadFactory.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/windbg/aarch64/WindbgAARCH64ThreadFactory.java new file mode 100644 index 00000000000..6f1e929deec --- /dev/null +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/windbg/aarch64/WindbgAARCH64ThreadFactory.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, Microsoft Corporation. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.debugger.windbg.aarch64; + +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.debugger.windbg.*; + +public class WindbgAARCH64ThreadFactory implements WindbgThreadFactory { + private WindbgDebugger debugger; + + public WindbgAARCH64ThreadFactory(WindbgDebugger debugger) { + this.debugger = debugger; + } + + public ThreadProxy createThreadWrapper(Address threadIdentifierAddr) { + return new WindbgAARCH64Thread(debugger, threadIdentifierAddr); + } + + public ThreadProxy createThreadWrapper(long id) { + return new WindbgAARCH64Thread(debugger, id); + } +} diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Threads.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Threads.java index 1e471412d58..7dddf4c4ccb 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Threads.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Threads.java @@ -28,11 +28,13 @@ import sun.jvm.hotspot.debugger.*; import sun.jvm.hotspot.types.*; + import sun.jvm.hotspot.runtime.solaris_sparc.SolarisSPARCJavaThreadPDAccess; import sun.jvm.hotspot.runtime.solaris_x86.SolarisX86JavaThreadPDAccess; import sun.jvm.hotspot.runtime.solaris_amd64.SolarisAMD64JavaThreadPDAccess; -import sun.jvm.hotspot.runtime.win32_amd64.Win32AMD64JavaThreadPDAccess; import sun.jvm.hotspot.runtime.win32_x86.Win32X86JavaThreadPDAccess; +import sun.jvm.hotspot.runtime.win32_amd64.Win32AMD64JavaThreadPDAccess; +import sun.jvm.hotspot.runtime.win32_aarch64.Win32AARCH64JavaThreadPDAccess; import sun.jvm.hotspot.runtime.linux_x86.LinuxX86JavaThreadPDAccess; import sun.jvm.hotspot.runtime.linux_amd64.LinuxAMD64JavaThreadPDAccess; import sun.jvm.hotspot.runtime.linux_aarch64.LinuxAARCH64JavaThreadPDAccess; @@ -82,6 +84,8 @@ private static synchronized void initialize(TypeDataBase db) { access = new Win32X86JavaThreadPDAccess(); } else if (cpu.equals("amd64")) { access = new Win32AMD64JavaThreadPDAccess(); + } else if (cpu.equals("aarch64")) { + access = new Win32AARCH64JavaThreadPDAccess(); } } else if (os.equals("linux")) { if (cpu.equals("x86")) { diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/win32_aarch64/Win32AARCH64JavaThreadPDAccess.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/win32_aarch64/Win32AARCH64JavaThreadPDAccess.java new file mode 100644 index 00000000000..55fbc03ee60 --- /dev/null +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/win32_aarch64/Win32AARCH64JavaThreadPDAccess.java @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, Microsoft Corporation. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.runtime.win32_aarch64; + +import java.io.*; +import java.util.*; +import sun.jvm.hotspot.debugger.*; +import sun.jvm.hotspot.debugger.aarch64.*; +import sun.jvm.hotspot.runtime.*; +import sun.jvm.hotspot.runtime.aarch64.*; +import sun.jvm.hotspot.types.*; +import sun.jvm.hotspot.utilities.*; + +/** This class is only public to allow using the VMObjectFactory to + instantiate these. +*/ + +public class Win32AARCH64JavaThreadPDAccess implements JavaThreadPDAccess { + private static AddressField lastJavaFPField; + private static AddressField osThreadField; + + // Field from OSThread + private static Field osThreadThreadIDField; + + // This is currently unneeded but is being kept in case we change + // the currentFrameGuess algorithm + private static final long GUESS_SCAN_RANGE = 128 * 1024; + + static { + VM.registerVMInitializedObserver(new Observer() { + public void update(Observable o, Object data) { + initialize(VM.getVM().getTypeDataBase()); + } + }); + } + + private static synchronized void initialize(TypeDataBase db) { + Type type = db.lookupType("JavaThread"); + osThreadField = type.getAddressField("_osthread"); + + Type anchorType = db.lookupType("JavaFrameAnchor"); + lastJavaFPField = anchorType.getAddressField("_last_Java_fp"); + + Type osThreadType = db.lookupType("OSThread"); + osThreadThreadIDField = osThreadType.getField("_thread_id"); + } + + public Address getLastJavaFP(Address addr) { + return lastJavaFPField.getValue(addr.addOffsetTo(sun.jvm.hotspot.runtime.JavaThread.getAnchorField().getOffset())); + } + + public Address getLastJavaPC(Address addr) { + return null; + } + + public Address getBaseOfStackPointer(Address addr) { + return null; + } + + public Frame getLastFramePD(JavaThread thread, Address addr) { + Address fp = thread.getLastJavaFP(); + if (fp == null) { + return null; // no information + } + Address pc = thread.getLastJavaPC(); + if ( pc != null ) { + return new AARCH64Frame(thread.getLastJavaSP(), fp, pc); + } else { + return new AARCH64Frame(thread.getLastJavaSP(), fp); + } + } + + public RegisterMap newRegisterMap(JavaThread thread, boolean updateMap) { + return new AARCH64RegisterMap(thread, updateMap); + } + + public Frame getCurrentFrameGuess(JavaThread thread, Address addr) { + ThreadProxy t = getThreadProxy(addr); + AARCH64ThreadContext context = (AARCH64ThreadContext) t.getContext(); + AARCH64CurrentFrameGuess guesser = new AARCH64CurrentFrameGuess(context, thread); + if (!guesser.run(GUESS_SCAN_RANGE)) { + return null; + } + if (guesser.getPC() == null) { + return new AARCH64Frame(guesser.getSP(), guesser.getFP()); + } else { + return new AARCH64Frame(guesser.getSP(), guesser.getFP(), guesser.getPC()); + } + } + + public void printThreadIDOn(Address addr, PrintStream tty) { + tty.print(getThreadProxy(addr)); + } + + public void printInfoOn(Address threadAddr, PrintStream tty) { + } + + public Address getLastSP(Address addr) { + ThreadProxy t = getThreadProxy(addr); + AARCH64ThreadContext context = (AARCH64ThreadContext) t.getContext(); + return context.getRegisterAsAddress(AARCH64ThreadContext.SP); + } + + public ThreadProxy getThreadProxy(Address addr) { + // Addr is the address of the JavaThread. + // Fetch the OSThread (for now and for simplicity, not making a + // separate "OSThread" class in this package) + Address osThreadAddr = osThreadField.getValue(addr); + // Get the address of the thread_id within the OSThread + Address threadIdAddr = osThreadAddr.addOffsetTo(osThreadThreadIDField.getOffset()); + + JVMDebugger debugger = VM.getVM().getDebugger(); + return debugger.getThreadForIdentifierAddress(threadIdAddr); + } +} diff --git a/src/jdk.hotspot.agent/windows/native/libsaproc/sawindbg.cpp b/src/jdk.hotspot.agent/windows/native/libsaproc/sawindbg.cpp index 3eecaad7607..72f3d0774ea 100644 --- a/src/jdk.hotspot.agent/windows/native/libsaproc/sawindbg.cpp +++ b/src/jdk.hotspot.agent/windows/native/libsaproc/sawindbg.cpp @@ -36,6 +36,9 @@ #elif _M_AMD64 #include "sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext.h" #define NPRGREG sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_NPRGREG +#elif _M_ARM64 + #include "sun_jvm_hotspot_debugger_aarch64_AARCH64ThreadContext.h" + #define NPRGREG sun_jvm_hotspot_debugger_aarch64_AARCH64ThreadContext_NPRGREG #else #error "SA windbg back-end is not supported for your cpu!" #endif From c58ab585d7a21172a7e602c495fc1fb88b931978 Mon Sep 17 00:00:00 2001 From: Reka Kovacs Date: Wed, 3 Nov 2021 12:52:57 -0700 Subject: [PATCH 2/5] Remove unnecessary changes --- make/autoconf/flags-ldflags.m4 | 15 +++++++++------ src/hotspot/cpu/aarch64/aarch64.ad | 2 +- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/make/autoconf/flags-ldflags.m4 b/make/autoconf/flags-ldflags.m4 index 8e6e05b6ff5..a4c7fde34e4 100644 --- a/make/autoconf/flags-ldflags.m4 +++ b/make/autoconf/flags-ldflags.m4 @@ -185,14 +185,17 @@ AC_DEFUN([FLAGS_SETUP_LDFLAGS_CPU_DEP], $1_CPU_LDFLAGS_JVM_ONLY="-xarch=sparc" fi - elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then - if test "x${OPENJDK_$1_CPU_BITS}" = "x32"; then - $1_CPU_EXECUTABLE_LDFLAGS="-stack:327680" - elif test "x${OPENJDK_$1_CPU_BITS}" = "x64"; then - $1_CPU_EXECUTABLE_LDFLAGS="-stack:1048576" - fi + elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then if test "x${OPENJDK_$1_CPU}" = "xx86"; then $1_CPU_LDFLAGS="-safeseh" + # NOTE: Old build added -machine. Probably not needed. + $1_CPU_LDFLAGS_JVM_ONLY="-machine:I386" + $1_CPU_EXECUTABLE_LDFLAGS="-stack:327680" + elif test "x${OPENJDK_$1_CPU}" = "xaarch64"; then + $1_CPU_EXECUTABLE_LDFLAGS="-stack:1048576" + else + $1_CPU_LDFLAGS_JVM_ONLY="-machine:AMD64" + $1_CPU_EXECUTABLE_LDFLAGS="-stack:1048576" fi fi diff --git a/src/hotspot/cpu/aarch64/aarch64.ad b/src/hotspot/cpu/aarch64/aarch64.ad index 991e479b02a..eaff134ebf1 100644 --- a/src/hotspot/cpu/aarch64/aarch64.ad +++ b/src/hotspot/cpu/aarch64/aarch64.ad @@ -5440,7 +5440,7 @@ pipeline %{ attributes %{ // ARM instructions are of fixed length fixed_size_instructions; // Fixed size instructions TODO does - max_instructions_per_bundle = 4; // A53 = 2, A57 = 4 + max_instructions_per_bundle = 2; // A53 = 2, A57 = 4 // ARM instructions come in 32-bit word units instruction_unit_size = 4; // An instruction is 4 bytes long instruction_fetch_unit_size = 64; // The processor fetches one line From 697c339853a57fad73539fe15fc0e12d242177a5 Mon Sep 17 00:00:00 2001 From: Reka Kovacs Date: Thu, 4 Nov 2021 13:30:13 -0700 Subject: [PATCH 3/5] Remove unnecessary warning pragma --- .../os_cpu/windows_aarch64/bytes_windows_aarch64.inline.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/hotspot/os_cpu/windows_aarch64/bytes_windows_aarch64.inline.hpp b/src/hotspot/os_cpu/windows_aarch64/bytes_windows_aarch64.inline.hpp index 55048963fa4..35389c95159 100644 --- a/src/hotspot/os_cpu/windows_aarch64/bytes_windows_aarch64.inline.hpp +++ b/src/hotspot/os_cpu/windows_aarch64/bytes_windows_aarch64.inline.hpp @@ -41,6 +41,4 @@ inline u8 Bytes::swap_u8(u8 x) { return _byteswap_uint64(x); } -#pragma warning(default: 4035) // Enable warning 4035: no return value - #endif // OS_CPU_WINDOWS_AARCH64_BYTES_WINDOWS_AARCH64_INLINE_HPP From d33ac7612cc59feb298b0183fed938439fdce7b5 Mon Sep 17 00:00:00 2001 From: Reka Kovacs Date: Wed, 17 Nov 2021 19:08:34 -0800 Subject: [PATCH 4/5] Add comment to explain PCH include And a single space for consistency --- src/hotspot/cpu/aarch64/c1_FpuStackSim_aarch64.cpp | 2 ++ src/hotspot/os/windows/os_windows.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hotspot/cpu/aarch64/c1_FpuStackSim_aarch64.cpp b/src/hotspot/cpu/aarch64/c1_FpuStackSim_aarch64.cpp index c50da1c8beb..b3b8bdbc6c9 100644 --- a/src/hotspot/cpu/aarch64/c1_FpuStackSim_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c1_FpuStackSim_aarch64.cpp @@ -28,4 +28,6 @@ //-------------------------------------------------------- // No FPU stack on AARCH64 + +// This include is needed to avoid MSVC error C1010 on Windows. #include "precompiled.hpp" diff --git a/src/hotspot/os/windows/os_windows.cpp b/src/hotspot/os/windows/os_windows.cpp index 0dc527bf4bc..f30036c0045 100644 --- a/src/hotspot/os/windows/os_windows.cpp +++ b/src/hotspot/os/windows/os_windows.cpp @@ -2674,7 +2674,7 @@ LONG WINAPI topLevelUnhandledExceptionFilter(struct _EXCEPTION_POINTERS* excepti if (InterceptOSException) goto exit; DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode; #if defined(_M_ARM64) - address pc = (address)exceptionInfo->ContextRecord->Pc; + address pc = (address) exceptionInfo->ContextRecord->Pc; #elif defined(_M_AMD64) address pc = (address) exceptionInfo->ContextRecord->Rip; #else From 6792a10ab921782fa5cff98c5e1e5cae60749a05 Mon Sep 17 00:00:00 2001 From: Reka Kovacs Date: Wed, 24 Nov 2021 11:12:32 -0800 Subject: [PATCH 5/5] Work around MSVC bug on argument passing --- src/hotspot/share/runtime/java.hpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/hotspot/share/runtime/java.hpp b/src/hotspot/share/runtime/java.hpp index 6c809a11e8b..a947ad5aa0e 100644 --- a/src/hotspot/share/runtime/java.hpp +++ b/src/hotspot/share/runtime/java.hpp @@ -90,6 +90,19 @@ class JDK_Version { _thread_park_blocker(false), _post_vm_init_hook_enabled(false) {} + /** + * Letting MSVC generate the copy constructor results in incorrect ARM64 codegen + * on argument passing, triggering an assert failure in version_less_than() + * in src/hotspot/share/runtime/arguments.cpp. This trivial hand-written + * copy constructor works around the issue. + * https://developercommunity.visualstudio.com/t/arm64-incorrect-code-gen-when-compiler-decides-to/1541140 + */ + JDK_Version(const JDK_Version &v) : + _major(v._major), _minor(v._minor), _security(v._security), _patch(v._patch), + _build(v._build), _thread_park_blocker(v._thread_park_blocker), + _post_vm_init_hook_enabled(v._post_vm_init_hook_enabled) + {} + JDK_Version(uint8_t major, uint8_t minor = 0, uint8_t security = 0, uint8_t patch = 0, uint8_t build = 0, bool thread_park_blocker = false, bool post_vm_init_hook_enabled = false) :