diff --git a/make/autoconf/basic.m4 b/make/autoconf/basic.m4 index d55cbe4d4ba..fb06fa5426a 100644 --- a/make/autoconf/basic.m4 +++ b/make/autoconf/basic.m4 @@ -117,6 +117,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/flags-cflags.m4 b/make/autoconf/flags-cflags.m4 index 15df47434c0..588df7f0011 100644 --- a/make/autoconf/flags-cflags.m4 +++ b/make/autoconf/flags-cflags.m4 @@ -666,7 +666,9 @@ AC_DEFUN([FLAGS_SETUP_CFLAGS_CPU_DEP], # toolchain dependend, per-cpu if 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 2b1e22c7c4f..c2e77905663 100644 --- a/make/autoconf/flags-ldflags.m4 +++ b/make/autoconf/flags-ldflags.m4 @@ -165,14 +165,13 @@ AC_DEFUN([FLAGS_SETUP_LDFLAGS_CPU_DEP], 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 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" - else - $1_CPU_LDFLAGS_JVM_ONLY="-machine:AMD64" - $1_CPU_EXECUTABLE_LDFLAGS="-stack:1048576" fi fi diff --git a/make/autoconf/jvm-features.m4 b/make/autoconf/jvm-features.m4 index 5118ef0f1f0..04ca7b4e909 100644 --- a/make/autoconf/jvm-features.m4 +++ b/make/autoconf/jvm-features.m4 @@ -237,8 +237,9 @@ AC_DEFUN_ONCE([JVM_FEATURES_CHECK_AOT], JVM_FEATURES_CHECK_AVAILABILITY(aot, [ AC_MSG_CHECKING([if platform is supported by AOT]) # AOT is only available where JVMCI is available since it requires JVMCI. - if test "x$OPENJDK_TARGET_CPU" = "xx86_64" || \ - test "x$OPENJDK_TARGET_CPU" = "xaarch64"; then + if test "x$OPENJDK_TARGET_CPU" = "xx86_64"; then + AC_MSG_RESULT([yes]) + elif test "x$OPENJDK_TARGET_OS-$OPENJDK_TARGET_CPU" = "xlinux-aarch64"; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no, $OPENJDK_TARGET_CPU]) @@ -303,8 +304,9 @@ AC_DEFUN_ONCE([JVM_FEATURES_CHECK_GRAAL], JVM_FEATURES_CHECK_AVAILABILITY(graal, [ AC_MSG_CHECKING([if platform is supported by Graal]) # Graal is only available where JVMCI is available since it requires JVMCI. - if test "x$OPENJDK_TARGET_CPU" = "xx86_64" || \ - test "x$OPENJDK_TARGET_CPU" = "xaarch64" ; then + if test "x$OPENJDK_TARGET_CPU" = "xx86_64"; then + AC_MSG_RESULT([yes]) + elif test "x$OPENJDK_TARGET_OS-$OPENJDK_TARGET_CPU" = "xlinux-aarch64"; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no, $OPENJDK_TARGET_CPU]) @@ -336,8 +338,9 @@ AC_DEFUN_ONCE([JVM_FEATURES_CHECK_JVMCI], [ JVM_FEATURES_CHECK_AVAILABILITY(jvmci, [ AC_MSG_CHECKING([if platform is supported by JVMCI]) - if test "x$OPENJDK_TARGET_CPU" = "xx86_64" || \ - test "x$OPENJDK_TARGET_CPU" = "xaarch64" ; then + if test "x$OPENJDK_TARGET_CPU" = "xx86_64"; then + AC_MSG_RESULT([yes]) + elif test "x$OPENJDK_TARGET_OS-$OPENJDK_TARGET_CPU" = "xlinux-aarch64"; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no, $OPENJDK_TARGET_CPU]) diff --git a/make/autoconf/toolchain.m4 b/make/autoconf/toolchain.m4 index 25b89ecce36..6687cb6cd37 100644 --- a/make/autoconf/toolchain.m4 +++ b/make/autoconf/toolchain.m4 @@ -872,14 +872,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]) @@ -889,13 +893,20 @@ AC_DEFUN_ONCE([TOOLCHAIN_SETUP_BUILD_COMPILERS], AC_MSG_RESULT([$BUILD_DEVKIT_ROOT]) fi - BUILD_SYSROOT="$BUILD_DEVKIT_SYSROOT" - - # 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" + + 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 @@ -921,9 +932,37 @@ AC_DEFUN_ONCE([TOOLCHAIN_SETUP_BUILD_COMPILERS], UTIL_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]) + UTIL_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" @@ -974,6 +1013,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 ed99f4508fc..4644c0a9d7c 100644 --- a/make/autoconf/toolchain_windows.m4 +++ b/make/autoconf/toolchain_windows.m4 @@ -79,11 +79,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 @@ -123,10 +127,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 @@ -520,41 +526,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 - UTIL_REWRITE_AS_UNIX_PATH([testpath]) - if test -d "$testpath"; then - UTIL_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 - UTIL_REWRITE_AS_UNIX_PATH([testpath]) - if test -d "$testpath"; then - UTIL_FIXUP_PATH([libpath]) - SYSROOT_LDFLAGS="$SYSROOT_LDFLAGS -libpath:$libpath" - fi - IFS=";" - fi - done - IFS="$OLDIFS" + TOOLCHAIN_SETUP_VISUAL_STUDIO_SYSROOT_FLAGS AC_SUBST(VS_PATH_WINDOWS) fi @@ -593,10 +565,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 @@ -616,26 +593,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" UTIL_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" UTIL_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 @@ -667,13 +644,8 @@ AC_DEFUN([TOOLCHAIN_SETUP_MSVC_DLL], if test "x$VS100COMNTOOLS" != x; then CYGWIN_VS_TOOLS_DIR="$VS100COMNTOOLS/.." UTIL_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 @@ -683,17 +655,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 + if test "x$OPENJDK_TARGET_CPU" = xx86; then POSSIBLE_MSVC_DLL=`$FIND "$CYGWIN_VC_INSTALL_DIR" -name $DLL_NAME \ - | $GREP x64 | $HEAD --lines 1` - else - 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], @@ -757,9 +729,9 @@ AC_DEFUN([TOOLCHAIN_SETUP_VS_RUNTIME_DLLS], fi AC_ARG_WITH(vcruntime-1-dll, [AS_HELP_STRING([--with-vcruntime-1-dll], - [path to microsoft C++ runtime dll (vcruntime*_1.dll) (Windows only) @<:@probed@:>@])]) + [path to microsoft C++ runtime dll (vcruntime*_1.dll) (Windows 64-bits only) @<:@probed@:>@])]) - if test "x$VCRUNTIME_1_NAME" != "x"; then + if test "x$VCRUNTIME_1_NAME" != "x" -a "x$OPENJDK_TARGET_CPU_BITS" = x64; then if test "x$with_vcruntime_1_dll" != x; then # If given explicitly by user, do not probe. If not present, fail directly. TOOLCHAIN_CHECK_POSSIBLE_MSVC_DLL($VCRUNTIME_1_NAME, [$with_vcruntime_1_dll], @@ -801,9 +773,12 @@ AC_DEFUN([TOOLCHAIN_SETUP_VS_RUNTIME_DLLS], else CYGWIN_WINDOWSSDKDIR="${WINDOWSSDKDIR}" UTIL_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 @@ -826,3 +801,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], +[ + OLDIFS="$IFS" + IFS=";" + # Convert $1VS_INCLUDE into $1SYSROOT_CFLAGS + 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 + UTIL_REWRITE_AS_UNIX_PATH([testpath]) + if test -d "$testpath"; then + UTIL_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 + UTIL_REWRITE_AS_UNIX_PATH([testpath]) + if test -d "$testpath"; then + UTIL_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 a802b18a557..91227259bdf 100644 --- a/make/devkit/createWindowsDevkit2017.sh +++ b/make/devkit/createWindowsDevkit2017.sh @@ -113,19 +113,23 @@ REDIST_SUBDIR="VC/Redist/MSVC/$REDIST_VERSION" echo "Copying VC..." rm -rf $DEVKIT_ROOT/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/ @@ -134,7 +138,9 @@ cp -r "$VS_INSTALL_DIR/$REDIST_SUBDIR/x86" $DEVKIT_ROOT/VC/redist/ cp $DEVKIT_ROOT/VC/redist/x86/$MSVCR_DLL $DEVKIT_ROOT/VC/bin/x86 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/x64/$MSVCR_DLL $DEVKIT_ROOT/VC/bin/x64 +cp $DEVKIT_ROOT/VC/redist/arm64/$MSVCP_DLL $DEVKIT_ROOT/VC/bin/arm64 +cp $DEVKIT_ROOT/VC/redist/arm64/$MSVCP_DLL $DEVKIT_ROOT/VC/bin/arm64 ################################################################################ # Copy SDK files @@ -152,8 +158,10 @@ mkdir -p $DEVKIT_ROOT/$SDK_VERSION/bin 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 @@ -188,6 +196,13 @@ 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\"" +echo-info "" echo-info "DEVKIT_TOOLS_VERSION=\"$TOOLS_VERSION\"" echo-info "DEVKIT_REDIST_VERSION=\"$REDIST_VERSION\"" echo-info "DEVKIT_SDK_VERSION=\"$SDK_FULL_VERSION\"" diff --git a/make/devkit/createWindowsDevkit2019.sh b/make/devkit/createWindowsDevkit2019.sh index 8a97f0c2a3b..a5c89f09faa 100644 --- a/make/devkit/createWindowsDevkit2019.sh +++ b/make/devkit/createWindowsDevkit2019.sh @@ -117,19 +117,23 @@ REDIST_SUBDIR="VC/Redist/MSVC/$REDIST_VERSION" echo "Copying VC..." rm -rf $DEVKIT_ROOT/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/ @@ -139,6 +143,8 @@ cp $DEVKIT_ROOT/VC/redist/x86/$MSVCR_DLL $DEVKIT_ROOT/VC/bin/x86 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 ################################################################################ # Copy SDK files @@ -156,8 +162,10 @@ mkdir -p $DEVKIT_ROOT/$SDK_VERSION/bin 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 @@ -193,6 +201,14 @@ echo-info "DEVKIT_VCRUNTIME_1_DLL_x86_64=\"\$DEVKIT_ROOT/VC/redist/x64/$VCRUNTIM 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_VCRUNTIME_1_DLL_aarch64=\"\$DEVKIT_ROOT/VC/redist/arm64/$VCRUNTIME_1_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\"" +echo-info "" echo-info "DEVKIT_TOOLS_VERSION=\"$TOOLS_VERSION\"" echo-info "DEVKIT_REDIST_VERSION=\"$REDIST_VERSION\"" echo-info "DEVKIT_SDK_VERSION=\"$SDK_FULL_VERSION\"" diff --git a/make/hotspot/gensrc/GensrcAdlc.gmk b/make/hotspot/gensrc/GensrcAdlc.gmk index dea8c855803..733658d5d8b 100644 --- a/make/hotspot/gensrc/GensrcAdlc.gmk +++ b/make/hotspot/gensrc/GensrcAdlc.gmk @@ -88,6 +88,13 @@ ifeq ($(call check-jvm-feature, compiler2), true) ADLCFLAGS += -DAIX=1 else ifeq ($(call isTargetOs, macosx), true) ADLCFLAGS += -D_ALLBSD_SOURCE=1 -D_GNU_SOURCE=1 + else ifeq ($(call isTargetOs, windows), true) + ifeq ($(call isTargetCpuBits, 64), true) + ADLCFLAGS += -D_WIN64=1 + endif + ifeq ($(HOTSPOT_TARGET_CPU_ARCH), aarch64) + ADLCFLAGS += -DR18_RESERVED + endif endif ifeq ($(call isTargetOs, windows), false) diff --git a/make/modules/java.base/gensrc/GensrcMisc.gmk b/make/modules/java.base/gensrc/GensrcMisc.gmk index cd12f2ab318..31d816d1e34 100644 --- a/make/modules/java.base/gensrc/GensrcMisc.gmk +++ b/make/modules/java.base/gensrc/GensrcMisc.gmk @@ -60,6 +60,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 @@ -73,7 +79,7 @@ define generate-preproc-src $(call MakeDir, $(@D)) $(call ExecuteWithLog, $(SUPPORT_OUTPUTDIR)/gensrc/java.base/_$(@F), \ ( $(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/src/hotspot/cpu/aarch64/aarch64-asmtest.py b/src/hotspot/cpu/aarch64/aarch64-asmtest.py index f5a5c6b5aee..104104b09a9 100644 --- a/src/hotspot/cpu/aarch64/aarch64-asmtest.py +++ b/src/hotspot/cpu/aarch64/aarch64-asmtest.py @@ -13,6 +13,8 @@ class Register(Operand): def generate(self): self.number = random.randint(0, 30) + if self.number == 18: + self.number = 17 return self def astr(self, prefix): @@ -37,6 +39,8 @@ class GeneralRegisterOrZr(Register): def generate(self): self.number = random.randint(0, 31) + if self.number == 18: + self.number = 16 return self def astr(self, prefix = ""): @@ -54,6 +58,8 @@ class GeneralRegisterOrZr(Register): class GeneralRegisterOrSp(Register): def generate(self): self.number = random.randint(0, 31) + if self.number == 18: + self.number = 15 return self def astr(self, prefix = ""): @@ -1331,7 +1337,7 @@ generate(SpecialCases, [["ccmn", "__ ccmn(zr, zr, 3u, Assembler::LE);", ["st1w", "__ sve_st1w(z0, __ S, p1, Address(r0, 7));", "st1w\t{z0.s}, p1, [x0, #7, MUL VL]"], ["st1b", "__ sve_st1b(z0, __ B, p2, Address(sp, r1));", "st1b\t{z0.b}, p2, [sp, x1]"], ["st1h", "__ sve_st1h(z0, __ H, p3, Address(sp, r8));", "st1h\t{z0.h}, p3, [sp, x8, LSL #1]"], - ["st1d", "__ sve_st1d(z0, __ D, p4, Address(r0, r18));", "st1d\t{z0.d}, p4, [x0, x18, LSL #3]"], + ["st1d", "__ sve_st1d(z0, __ D, p4, Address(r0, r17));", "st1d\t{z0.d}, p4, [x0, x17, LSL #3]"], ["ldr", "__ sve_ldr(z0, Address(sp));", "ldr\tz0, [sp]"], ["ldr", "__ sve_ldr(z31, Address(sp, -256));", "ldr\tz31, [sp, #-256, MUL VL]"], ["str", "__ sve_str(z8, Address(r8, 255));", "str\tz8, [x8, #255, MUL VL]"], diff --git a/src/hotspot/cpu/aarch64/aarch64.ad b/src/hotspot/cpu/aarch64/aarch64.ad index 01ffc735290..ede4040491e 100644 --- a/src/hotspot/cpu/aarch64/aarch64.ad +++ b/src/hotspot/cpu/aarch64/aarch64.ad @@ -114,8 +114,8 @@ reg_def R16 ( SOC, SOC, Op_RegI, 16, r16->as_VMReg() ); reg_def R16_H ( SOC, SOC, Op_RegI, 16, r16->as_VMReg()->next()); reg_def R17 ( SOC, SOC, Op_RegI, 17, r17->as_VMReg() ); reg_def R17_H ( SOC, SOC, Op_RegI, 17, r17->as_VMReg()->next()); -reg_def R18 ( SOC, SOC, Op_RegI, 18, r18->as_VMReg() ); -reg_def R18_H ( SOC, SOC, Op_RegI, 18, r18->as_VMReg()->next()); +reg_def R18 ( SOC, SOC, Op_RegI, 18, r18_tls->as_VMReg() ); +reg_def R18_H ( SOC, SOC, Op_RegI, 18, r18_tls->as_VMReg()->next()); reg_def R19 ( SOC, SOE, Op_RegI, 19, r19->as_VMReg() ); reg_def R19_H ( SOC, SOE, Op_RegI, 19, r19->as_VMReg()->next()); reg_def R20 ( SOC, SOE, Op_RegI, 20, r20->as_VMReg() ); // caller esp @@ -716,6 +716,10 @@ reg_class any_reg %{ // Class for non-allocatable 32 bit registers reg_class non_allocatable_reg32( +#ifdef R18_RESERVED + // See comment in register_aarch64.hpp + R18, // tls on Windows +#endif R28, // thread R30, // lr R31 // sp @@ -723,6 +727,10 @@ reg_class non_allocatable_reg32( // Class for non-allocatable 64 bit registers reg_class non_allocatable_reg( +#ifdef R18_RESERVED + // See comment in register_aarch64.hpp + R18, R18_H, // tls on Windows, platform register on macOS +#endif R28, R28_H, // thread R30, R30_H, // lr R31, R31_H // sp @@ -6286,7 +6294,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 ccd9d46d626..29f63ba69a4 100644 --- a/src/hotspot/cpu/aarch64/assembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/assembler_aarch64.cpp @@ -101,7 +101,7 @@ void entry(CodeBuffer *cb) { __ adds(r28, r15, r8, Assembler::ASR, 39); // adds x28, x15, x8, ASR #39 __ subs(r7, r28, r30, Assembler::ASR, 57); // subs x7, x28, x30, ASR #57 __ addw(r9, r22, r27, Assembler::ASR, 15); // add w9, w22, w27, ASR #15 - __ subw(r3, r13, r18, Assembler::ASR, 30); // sub w3, w13, w18, ASR #30 + __ subw(r3, r13, r17, Assembler::ASR, 30); // sub w3, w13, w17, ASR #30 __ addsw(r14, r26, r8, Assembler::ASR, 17); // adds w14, w26, w8, ASR #17 __ subsw(r0, r22, r12, Assembler::ASR, 21); // subs w0, w22, w12, ASR #21 __ andr(r0, r15, r26, Assembler::LSL, 20); // and x0, x15, x26, LSL #20 @@ -109,8 +109,8 @@ void entry(CodeBuffer *cb) { __ eor(r24, r13, r2, Assembler::LSL, 32); // eor x24, x13, x2, LSL #32 __ ands(r28, r3, r17, Assembler::ASR, 35); // ands x28, x3, x17, ASR #35 __ andw(r25, r16, r29, Assembler::LSR, 18); // and w25, w16, w29, LSR #18 - __ orrw(r13, r18, r11, Assembler::LSR, 9); // orr w13, w18, w11, LSR #9 - __ eorw(r5, r5, r18, Assembler::LSR, 15); // eor w5, w5, w18, LSR #15 + __ orrw(r13, r17, r11, Assembler::LSR, 9); // orr w13, w17, w11, LSR #9 + __ eorw(r5, r5, r17, Assembler::LSR, 15); // eor w5, w5, w17, LSR #15 __ andsw(r2, r23, r27, Assembler::ASR, 26); // ands w2, w23, w27, ASR #26 __ bic(r27, r28, r16, Assembler::LSR, 45); // bic x27, x28, x16, LSR #45 __ orn(r8, r25, r26, Assembler::ASR, 37); // orn x8, x25, x26, ASR #37 @@ -135,7 +135,7 @@ void entry(CodeBuffer *cb) { __ andw(r6, r11, 4294049777ull); // and w6, w11, #0xfff1fff1 __ orrw(r28, r5, 4294966791ull); // orr w28, w5, #0xfffffe07 __ eorw(r1, r20, 134217216ull); // eor w1, w20, #0x7fffe00 - __ andsw(r7, r18, 1048576ull); // ands w7, w18, #0x100000 + __ andsw(r7, r17, 1048576ull); // ands w7, w17, #0x100000 __ andr(r14, r12, 9223372036854775808ull); // and x14, x12, #0x8000000000000000 __ orr(r9, r11, 562675075514368ull); // orr x9, x11, #0x1ffc000000000 __ eor(r17, r0, 18014398509481728ull); // eor x17, x0, #0x3fffffffffff00 @@ -283,7 +283,7 @@ void entry(CodeBuffer *cb) { // LoadStoreExclusiveOp __ stxrw(r22, r27, r19); // stxr w22, w27, [x19] __ stlxrw(r11, r16, r6); // stlxr w11, w16, [x6] - __ ldxrw(r18, r0); // ldxr w18, [x0] + __ ldxrw(r17, r0); // ldxr w17, [x0] __ ldaxrw(r4, r10); // ldaxr w4, [x10] __ stlrw(r24, r22); // stlr w24, [x22] __ ldarw(r10, r19); // ldar w10, [x19] @@ -311,7 +311,7 @@ void entry(CodeBuffer *cb) { __ stlxp(r12, r16, r13, r15); // stlxp w12, x16, x13, [x15] // LoadStoreExclusiveOp - __ ldxpw(r18, r21, r13); // ldxp w18, w21, [x13] + __ ldxpw(r17, r21, r13); // ldxp w17, w21, [x13] __ ldaxpw(r11, r30, r8); // ldaxp w11, w30, [x8] __ stxpw(r24, r13, r11, r1); // stxp w24, w13, w11, [x1] __ stlxpw(r26, r21, r27, r13); // stlxp w26, w21, w27, [x13] @@ -324,7 +324,7 @@ void entry(CodeBuffer *cb) { __ strh(r2, Address(r25, -50)); // strh w2, [x25, -50] __ ldr(r4, Address(r2, -241)); // ldr x4, [x2, -241] __ ldrw(r30, Address(r20, -31)); // ldr w30, [x20, -31] - __ ldrb(r18, Address(r23, -23)); // ldrb w18, [x23, -23] + __ ldrb(r17, Address(r23, -23)); // ldrb w17, [x23, -23] __ ldrh(r29, Address(r26, -1)); // ldrh w29, [x26, -1] __ ldrsb(r1, Address(r9, 6)); // ldrsb x1, [x9, 6] __ ldrsh(r11, Address(r12, 19)); // ldrsh x11, [x12, 19] @@ -375,14 +375,14 @@ void entry(CodeBuffer *cb) { // base_plus_reg // LoadStoreOp - __ str(r10, Address(r18, r21, Address::sxtw(3))); // str x10, [x18, w21, sxtw #3] + __ str(r10, Address(r17, r21, Address::sxtw(3))); // str x10, [x17, w21, sxtw #3] __ strw(r4, Address(r13, r22, Address::sxtw(2))); // str w4, [x13, w22, sxtw #2] __ strb(r13, Address(r0, r19, Address::uxtw(0))); // strb w13, [x0, w19, uxtw #0] __ strh(r12, Address(r27, r6, Address::sxtw(0))); // strh w12, [x27, w6, sxtw #0] __ ldr(r0, Address(r8, r16, Address::lsl(0))); // ldr x0, [x8, x16, lsl #0] __ ldrw(r0, Address(r4, r26, Address::sxtx(0))); // ldr w0, [x4, x26, sxtx #0] __ ldrb(r14, Address(r25, r5, Address::sxtw(0))); // ldrb w14, [x25, w5, sxtw #0] - __ ldrh(r9, Address(r4, r18, Address::uxtw(0))); // ldrh w9, [x4, w18, uxtw #0] + __ ldrh(r9, Address(r4, r17, Address::uxtw(0))); // ldrh w9, [x4, w17, uxtw #0] __ ldrsb(r27, Address(r4, r7, Address::lsl(0))); // ldrsb x27, [x4, x7, lsl #0] __ ldrsh(r15, Address(r17, r30, Address::sxtw(0))); // ldrsh x15, [x17, w30, sxtw #0] __ ldrshw(r16, Address(r0, r22, Address::sxtw(0))); // ldrsh w16, [x0, w22, sxtw #0] @@ -439,7 +439,7 @@ void entry(CodeBuffer *cb) { __ sbcs(r1, r24, r3); // sbcs x1, x24, x3 // AddSubExtendedOp - __ addw(r18, r24, r20, ext::uxtb, 2); // add w18, w24, w20, uxtb #2 + __ addw(r17, r24, r20, ext::uxtb, 2); // add w17, w24, w20, uxtb #2 __ addsw(r13, r28, r10, ext::uxth, 1); // adds w13, w28, w10, uxth #1 __ sub(r15, r16, r2, ext::sxth, 2); // sub x15, x16, x2, sxth #2 __ subsw(r29, r13, r13, ext::uxth, 2); // subs w29, w13, w13, uxth #2 @@ -450,8 +450,8 @@ void entry(CodeBuffer *cb) { // ConditionalCompareOp __ ccmnw(r0, r13, 14u, Assembler::MI); // ccmn w0, w13, #14, MI - __ ccmpw(r22, r18, 6u, Assembler::CC); // ccmp w22, w18, #6, CC - __ ccmn(r18, r30, 14u, Assembler::VS); // ccmn x18, x30, #14, VS + __ ccmpw(r22, r17, 6u, Assembler::CC); // ccmp w22, w17, #6, CC + __ ccmn(r17, r30, 14u, Assembler::VS); // ccmn x17, x30, #14, VS __ ccmp(r10, r19, 12u, Assembler::HI); // ccmp x10, x19, #12, HI // ConditionalCompareImmedOp @@ -476,7 +476,7 @@ void entry(CodeBuffer *cb) { __ revw(r29, r30); // rev w29, w30 __ clzw(r25, r21); // clz w25, w21 __ clsw(r4, r0); // cls w4, w0 - __ rbit(r18, r21); // rbit x18, x21 + __ rbit(r17, r21); // rbit x17, x21 __ rev16(r29, r16); // rev16 x29, x16 __ rev32(r21, r20); // rev32 x21, x20 __ rev(r6, r19); // rev x6, x19 @@ -486,16 +486,16 @@ void entry(CodeBuffer *cb) { // ThreeRegOp __ udivw(r11, r24, r0); // udiv w11, w24, w0 __ sdivw(r27, r25, r14); // sdiv w27, w25, w14 - __ lslvw(r3, r14, r18); // lslv w3, w14, w18 + __ lslvw(r3, r14, r17); // lslv w3, w14, w17 __ lsrvw(r7, r15, r24); // lsrv w7, w15, w24 __ asrvw(r28, r17, r25); // asrv w28, w17, w25 __ rorvw(r2, r26, r28); // rorv w2, w26, w28 __ udiv(r5, r25, r26); // udiv x5, x25, x26 - __ sdiv(r27, r16, r18); // sdiv x27, x16, x18 + __ sdiv(r27, r16, r17); // sdiv x27, x16, x17 __ lslv(r6, r21, r12); // lslv x6, x21, x12 __ lsrv(r0, r4, r12); // lsrv x0, x4, x12 __ asrv(r27, r17, r28); // asrv x27, x17, x28 - __ rorv(r28, r2, r18); // rorv x28, x2, x18 + __ rorv(r28, r2, r17); // rorv x28, x2, x17 __ umulh(r10, r15, r14); // umulh x10, x15, x14 __ smulh(r14, r3, r25); // smulh x14, x3, x25 @@ -540,7 +540,7 @@ void entry(CodeBuffer *cb) { __ fmovd(v24, v11); // fmov d24, d11 __ fabsd(v7, v1); // fabs d7, d1 __ fnegd(v11, v0); // fneg d11, d0 - __ fsqrtd(v3, v18); // fsqrt d3, d18 + __ fsqrtd(v3, v17); // fsqrt d3, d17 __ fcvtd(v28, v6); // fcvt s28, d6 // FloatConvertOp @@ -552,9 +552,9 @@ void entry(CodeBuffer *cb) { __ scvtfs(v25, r13); // scvtf s25, x13 __ scvtfwd(v11, r23); // scvtf d11, w23 __ scvtfd(v19, r8); // scvtf d19, x8 - __ fmovs(r18, v21); // fmov w18, s21 + __ fmovs(r17, v21); // fmov w17, s21 __ fmovd(r25, v20); // fmov x25, d20 - __ fmovs(v19, r18); // fmov s19, w18 + __ fmovs(v19, r17); // fmov s19, w17 __ fmovd(v2, r29); // fmov d2, x29 // TwoRegFloatOp @@ -598,11 +598,11 @@ void entry(CodeBuffer *cb) { __ ld1r(v29, __ T8B, Address(r17)); // ld1r {v29.8B}, [x17] __ ld1r(v24, __ T4S, Address(__ post(r23, 4))); // ld1r {v24.4S}, [x23], 4 __ ld1r(v10, __ T1D, Address(__ post(r5, r25))); // ld1r {v10.1D}, [x5], x25 - __ ld2(v18, v19, __ T2D, Address(r10)); // ld2 {v18.2D, v19.2D}, [x10] + __ ld2(v17, v18, __ T2D, Address(r10)); // ld2 {v17.2D, v18.2D}, [x10] __ ld2(v12, v13, __ T4H, Address(__ post(r15, 16))); // ld2 {v12.4H, v13.4H}, [x15], 16 - __ ld2r(v25, v26, __ T16B, Address(r18)); // ld2r {v25.16B, v26.16B}, [x18] + __ ld2r(v25, v26, __ T16B, Address(r17)); // ld2r {v25.16B, v26.16B}, [x17] __ ld2r(v1, v2, __ T2S, Address(__ post(r30, 8))); // ld2r {v1.2S, v2.2S}, [x30], 8 - __ ld2r(v16, v17, __ T2D, Address(__ post(r18, r9))); // ld2r {v16.2D, v17.2D}, [x18], x9 + __ ld2r(v16, v17, __ T2D, Address(__ post(r17, r9))); // ld2r {v16.2D, v17.2D}, [x17], x9 __ ld3(v25, v26, v27, __ T4S, Address(__ post(r12, r2))); // ld3 {v25.4S, v26.4S, v27.4S}, [x12], x2 __ ld3(v26, v27, v28, __ T2S, Address(r19)); // ld3 {v26.2S, v27.2S, v28.2S}, [x19] __ ld3r(v15, v16, v17, __ T8H, Address(r21)); // ld3r {v15.8H, v16.8H, v17.8H}, [x21] @@ -610,7 +610,7 @@ void entry(CodeBuffer *cb) { __ ld3r(v14, v15, v16, __ T1D, Address(__ post(r28, r29))); // ld3r {v14.1D, v15.1D, v16.1D}, [x28], x29 __ ld4(v17, v18, v19, v20, __ T8H, Address(__ post(r29, 64))); // ld4 {v17.8H, v18.8H, v19.8H, v20.8H}, [x29], 64 __ ld4(v27, v28, v29, v30, __ T8B, Address(__ post(r7, r0))); // ld4 {v27.8B, v28.8B, v29.8B, v30.8B}, [x7], x0 - __ ld4r(v24, v25, v26, v27, __ T8B, Address(r18)); // ld4r {v24.8B, v25.8B, v26.8B, v27.8B}, [x18] + __ ld4r(v24, v25, v26, v27, __ T8B, Address(r17)); // ld4r {v24.8B, v25.8B, v26.8B, v27.8B}, [x17] __ ld4r(v0, v1, v2, v3, __ T4H, Address(__ post(r26, 8))); // ld4r {v0.4H, v1.4H, v2.4H, v3.4H}, [x26], 8 __ ld4r(v12, v13, v14, v15, __ T2S, Address(__ post(r25, r2))); // ld4r {v12.2S, v13.2S, v14.2S, v15.2S}, [x25], x2 @@ -665,7 +665,7 @@ void entry(CodeBuffer *cb) { __ sve_st1w(z0, __ S, p1, Address(r0, 7)); // st1w {z0.s}, p1, [x0, #7, MUL VL] __ sve_st1b(z0, __ B, p2, Address(sp, r1)); // st1b {z0.b}, p2, [sp, x1] __ sve_st1h(z0, __ H, p3, Address(sp, r8)); // st1h {z0.h}, p3, [sp, x8, LSL #1] - __ sve_st1d(z0, __ D, p4, Address(r0, r18)); // st1d {z0.d}, p4, [x0, x18, LSL #3] + __ sve_st1d(z0, __ D, p4, Address(r0, r17)); // st1d {z0.d}, p4, [x0, x17, LSL #3] __ sve_ldr(z0, Address(sp)); // ldr z0, [sp] __ sve_ldr(z31, Address(sp, -256)); // ldr z31, [sp, #-256, MUL VL] __ sve_str(z8, Address(r8, 255)); // str z8, [x8, #255, MUL VL] @@ -716,7 +716,7 @@ void entry(CodeBuffer *cb) { __ ldumax(Assembler::xword, r11, r20, r12); // ldumax x11, x20, [x12] // LSEOp - __ swpa(Assembler::xword, r18, r22, r16); // swpa x18, x22, [x16] + __ swpa(Assembler::xword, r16, r22, r16); // swpa x16, x22, [x16] __ ldadda(Assembler::xword, r21, r24, r26); // ldadda x21, x24, [x26] __ ldbica(Assembler::xword, r6, r6, r16); // ldclra x6, x6, [x16] __ ldeora(Assembler::xword, r16, r25, r16); // ldeora x16, x25, [x16] @@ -734,14 +734,14 @@ void entry(CodeBuffer *cb) { __ ldorral(Assembler::xword, zr, r0, r19); // ldsetal xzr, x0, [x19] __ ldsminal(Assembler::xword, r29, r26, r9); // ldsminal x29, x26, [x9] __ ldsmaxal(Assembler::xword, r26, r12, r15); // ldsmaxal x26, x12, [x15] - __ lduminal(Assembler::xword, r11, r11, r18); // lduminal x11, x11, [x18] + __ lduminal(Assembler::xword, r11, r11, r15); // lduminal x11, x11, [x15] __ ldumaxal(Assembler::xword, r25, r22, r24); // ldumaxal x25, x22, [x24] // LSEOp __ swpl(Assembler::xword, r0, r17, r11); // swpl x0, x17, [x11] __ ldaddl(Assembler::xword, r6, r29, r6); // ldaddl x6, x29, [x6] __ ldbicl(Assembler::xword, r5, r5, r21); // ldclrl x5, x5, [x21] - __ ldeorl(Assembler::xword, r19, r16, r18); // ldeorl x19, x16, [x18] + __ ldeorl(Assembler::xword, r19, r16, r15); // ldeorl x19, x16, [x15] __ ldorrl(Assembler::xword, r30, r27, r28); // ldsetl x30, x27, [x28] __ ldsminl(Assembler::xword, r1, r28, r1); // ldsminl x1, x28, [x1] __ ldsmaxl(Assembler::xword, r20, r29, r16); // ldsmaxl x20, x29, [x16] @@ -767,7 +767,7 @@ void entry(CodeBuffer *cb) { __ ldorra(Assembler::word, r24, r4, r3); // ldseta w24, w4, [x3] __ ldsmina(Assembler::word, r12, zr, r28); // ldsmina w12, wzr, [x28] __ ldsmaxa(Assembler::word, r10, r26, r2); // ldsmaxa w10, w26, [x2] - __ ldumina(Assembler::word, r12, r18, sp); // ldumina w12, w18, [sp] + __ ldumina(Assembler::word, r12, r16, sp); // ldumina w12, w16, [sp] __ ldumaxa(Assembler::word, r1, r13, r29); // ldumaxa w1, w13, [x29] // LSEOp @@ -777,7 +777,7 @@ void entry(CodeBuffer *cb) { __ ldeoral(Assembler::word, r1, r26, r28); // ldeoral w1, w26, [x28] __ ldorral(Assembler::word, r4, r30, r4); // ldsetal w4, w30, [x4] __ ldsminal(Assembler::word, r6, r30, r26); // ldsminal w6, w30, [x26] - __ ldsmaxal(Assembler::word, r18, r9, r8); // ldsmaxal w18, w9, [x8] + __ ldsmaxal(Assembler::word, r16, r9, r8); // ldsmaxal w16, w9, [x8] __ lduminal(Assembler::word, r12, r0, r20); // lduminal w12, w0, [x20] __ ldumaxal(Assembler::word, r1, r24, r2); // ldumaxal w1, w24, [x2] @@ -785,7 +785,7 @@ void entry(CodeBuffer *cb) { __ swpl(Assembler::word, r0, r9, r24); // swpl w0, w9, [x24] __ ldaddl(Assembler::word, r26, r16, r30); // ldaddl w26, w16, [x30] __ ldbicl(Assembler::word, r3, r10, r23); // ldclrl w3, w10, [x23] - __ ldeorl(Assembler::word, r10, r4, r18); // ldeorl w10, w4, [x18] + __ ldeorl(Assembler::word, r10, r4, r15); // ldeorl w10, w4, [x15] __ ldorrl(Assembler::word, r2, r11, r8); // ldsetl w2, w11, [x8] __ ldsminl(Assembler::word, r10, r15, r17); // ldsminl w10, w15, [x17] __ ldsmaxl(Assembler::word, r2, r10, r12); // ldsmaxl w2, w10, [x12] @@ -817,19 +817,19 @@ void entry(CodeBuffer *cb) { __ sve_fmin(z19, __ D, p2, z4); // fmin z19.d, p2/m, z19.d, z4.d __ sve_fmul(z17, __ S, p4, z22); // fmul z17.s, p4/m, z17.s, z22.s __ sve_fneg(z28, __ D, p3, z21); // fneg z28.d, p3/m, z21.d - __ sve_frintm(z18, __ S, p5, z2); // frintm z18.s, p5/m, z2.s + __ sve_frintm(z17, __ S, p5, z2); // frintm z17.s, p5/m, z2.s __ sve_frintn(z6, __ S, p3, z15); // frintn z6.s, p3/m, z15.s __ sve_frintp(z12, __ D, p5, z1); // frintp z12.d, p5/m, z1.d - __ sve_fsqrt(z18, __ S, p1, z17); // fsqrt z18.s, p1/m, z17.s + __ sve_fsqrt(z17, __ S, p1, z17); // fsqrt z17.s, p1/m, z17.s __ sve_fsub(z15, __ S, p5, z13); // fsub z15.s, p5/m, z15.s, z13.s __ sve_fmla(z20, __ D, p7, z27, z11); // fmla z20.d, p7/m, z27.d, z11.d __ sve_fmls(z3, __ D, p0, z30, z23); // fmls z3.d, p0/m, z30.d, z23.d __ sve_fnmla(z17, __ S, p2, z27, z26); // fnmla z17.s, p2/m, z27.s, z26.s __ sve_fnmls(z6, __ D, p5, z22, z30); // fnmls z6.d, p5/m, z22.d, z30.d - __ sve_mla(z2, __ H, p7, z26, z18); // mla z2.h, p7/m, z26.h, z18.h + __ sve_mla(z2, __ H, p7, z26, z17); // mla z2.h, p7/m, z26.h, z17.h __ sve_mls(z22, __ B, p4, z2, z17); // mls z22.b, p4/m, z2.b, z17.b __ sve_and(z24, z25, z22); // and z24.d, z25.d, z22.d - __ sve_eor(z18, z12, z3); // eor z18.d, z12.d, z3.d + __ sve_eor(z17, z12, z3); // eor z17.d, z12.d, z3.d __ sve_orr(z29, z28, z16); // orr z29.d, z28.d, z16.d // SVEReductionOp @@ -857,7 +857,7 @@ Disassembly of section .text: 8: ab889dfc adds x28, x15, x8, asr #39 c: eb9ee787 subs x7, x28, x30, asr #57 10: 0b9b3ec9 add w9, w22, w27, asr #15 - 14: 4b9279a3 sub w3, w13, w18, asr #30 + 14: 4b9179a3 sub w3, w13, w17, asr #30 18: 2b88474e adds w14, w26, w8, asr #17 1c: 6b8c56c0 subs w0, w22, w12, asr #21 20: 8a1a51e0 and x0, x15, x26, lsl #20 @@ -865,8 +865,8 @@ Disassembly of section .text: 28: ca0281b8 eor x24, x13, x2, lsl #32 2c: ea918c7c ands x28, x3, x17, asr #35 30: 0a5d4a19 and w25, w16, w29, lsr #18 - 34: 2a4b264d orr w13, w18, w11, lsr #9 - 38: 4a523ca5 eor w5, w5, w18, lsr #15 + 34: 2a4b262d orr w13, w17, w11, lsr #9 + 38: 4a513ca5 eor w5, w5, w17, lsr #15 3c: 6a9b6ae2 ands w2, w23, w27, asr #26 40: 8a70b79b bic x27, x28, x16, lsr #45 44: aaba9728 orn x8, x25, x26, asr #37 @@ -887,7 +887,7 @@ Disassembly of section .text: 80: 120cb166 and w6, w11, #0xfff1fff1 84: 321764bc orr w28, w5, #0xfffffe07 88: 52174681 eor w1, w20, #0x7fffe00 - 8c: 720c0247 ands w7, w18, #0x100000 + 8c: 720c0227 ands w7, w17, #0x100000 90: 9241018e and x14, x12, #0x8000000000000000 94: b25a2969 orr x9, x11, #0x1ffc000000000 98: d278b411 eor x17, x0, #0x3fffffffffff00 @@ -1009,7 +1009,7 @@ Disassembly of section .text: 268: c8dffe95 ldar x21, [x20] 26c: 88167e7b stxr w22, w27, [x19] 270: 880bfcd0 stlxr w11, w16, [x6] - 274: 885f7c12 ldxr w18, [x0] + 274: 885f7c11 ldxr w17, [x0] 278: 885ffd44 ldaxr w4, [x10] 27c: 889ffed8 stlr w24, [x22] 280: 88dffe6a ldar w10, [x19] @@ -1029,7 +1029,7 @@ Disassembly of section .text: 2b8: c87fcc5e ldaxp x30, x19, [x2] 2bc: c8220417 stxp w2, x23, x1, [x0] 2c0: c82cb5f0 stlxp w12, x16, x13, [x15] - 2c4: 887f55b2 ldxp w18, w21, [x13] + 2c4: 887f55b1 ldxp w17, w21, [x13] 2c8: 887ff90b ldaxp w11, w30, [x8] 2cc: 88382c2d stxp w24, w13, w11, [x1] 2d0: 883aedb5 stlxp w26, w21, w27, [x13] @@ -1039,7 +1039,7 @@ Disassembly of section .text: 2e0: 781ce322 sturh w2, [x25, #-50] 2e4: f850f044 ldur x4, [x2, #-241] 2e8: b85e129e ldur w30, [x20, #-31] - 2ec: 385e92f2 ldurb w18, [x23, #-23] + 2ec: 385e92f1 ldurb w17, [x23, #-23] 2f0: 785ff35d ldurh w29, [x26, #-1] 2f4: 39801921 ldrsb x1, [x9, #6] 2f8: 7881318b ldursh x11, [x12, #19] @@ -1081,14 +1081,14 @@ Disassembly of section .text: 388: bc4155f9 ldr s25, [x15], #21 38c: fc05a6ee str d14, [x23], #90 390: bc1df408 str s8, [x0], #-33 - 394: f835da4a str x10, [x18, w21, sxtw #3] + 394: f835da2a str x10, [x17, w21, sxtw #3] 398: b836d9a4 str w4, [x13, w22, sxtw #2] 39c: 3833580d strb w13, [x0, w19, uxtw #0] 3a0: 7826cb6c strh w12, [x27, w6, sxtw] 3a4: f8706900 ldr x0, [x8, x16] 3a8: b87ae880 ldr w0, [x4, x26, sxtx] 3ac: 3865db2e ldrb w14, [x25, w5, sxtw #0] - 3b0: 78724889 ldrh w9, [x4, w18, uxtw] + 3b0: 78714889 ldrh w9, [x4, w17, uxtw] 3b4: 38a7789b ldrsb x27, [x4, x7, lsl #0] 3b8: 78beca2f ldrsh x15, [x17, w30, sxtw] 3bc: 78f6c810 ldrsh w16, [x0, w22, sxtw] @@ -1127,7 +1127,7 @@ Disassembly of section .text: 440: ba1e030c adcs x12, x24, x30 444: da0f0320 sbc x0, x25, x15 448: fa030301 sbcs x1, x24, x3 - 44c: 0b340b12 add w18, w24, w20, uxtb #2 + 44c: 0b340b11 add w17, w24, w20, uxtb #2 450: 2b2a278d adds w13, w28, w10, uxth #1 454: cb22aa0f sub x15, x16, w2, sxth #2 458: 6b2d29bd subs w29, w13, w13, uxth #2 @@ -1136,8 +1136,8 @@ Disassembly of section .text: 464: cb21c8ee sub x14, x7, w1, sxtw #2 468: eb3ba47d subs x29, x3, w27, sxth #1 46c: 3a4d400e ccmn w0, w13, #0xe, mi // mi = first - 470: 7a5232c6 ccmp w22, w18, #0x6, cc // cc = lo, ul, last - 474: ba5e624e ccmn x18, x30, #0xe, vs + 470: 7a5132c6 ccmp w22, w17, #0x6, cc // cc = lo, ul, last + 474: ba5e622e ccmn x17, x30, #0xe, vs 478: fa53814c ccmp x10, x19, #0xc, hi // hi = pmore 47c: 3a52d8c2 ccmn w6, #0x12, #0x2, le 480: 7a4d8924 ccmp w9, #0xd, #0x4, hi // hi = pmore @@ -1156,7 +1156,7 @@ Disassembly of section .text: 4b4: 5ac00bdd rev w29, w30 4b8: 5ac012b9 clz w25, w21 4bc: 5ac01404 cls w4, w0 - 4c0: dac002b2 rbit x18, x21 + 4c0: dac002b1 rbit x17, x21 4c4: dac0061d rev16 x29, x16 4c8: dac00a95 rev32 x21, x20 4cc: dac00e66 rev x6, x19 @@ -1164,16 +1164,16 @@ Disassembly of section .text: 4d4: dac01675 cls x21, x19 4d8: 1ac00b0b udiv w11, w24, w0 4dc: 1ace0f3b sdiv w27, w25, w14 - 4e0: 1ad221c3 lsl w3, w14, w18 + 4e0: 1ad121c3 lsl w3, w14, w17 4e4: 1ad825e7 lsr w7, w15, w24 4e8: 1ad92a3c asr w28, w17, w25 4ec: 1adc2f42 ror w2, w26, w28 4f0: 9ada0b25 udiv x5, x25, x26 - 4f4: 9ad20e1b sdiv x27, x16, x18 + 4f4: 9ad10e1b sdiv x27, x16, x17 4f8: 9acc22a6 lsl x6, x21, x12 4fc: 9acc2480 lsr x0, x4, x12 500: 9adc2a3b asr x27, x17, x28 - 504: 9ad22c5c ror x28, x2, x18 + 504: 9ad12c5c ror x28, x2, x17 508: 9bce7dea umulh x10, x15, x14 50c: 9b597c6e smulh x14, x3, x25 510: 1b0e166f madd w15, w19, w14, w5 @@ -1210,7 +1210,7 @@ Disassembly of section .text: 58c: 1e604178 fmov d24, d11 590: 1e60c027 fabs d7, d1 594: 1e61400b fneg d11, d0 - 598: 1e61c243 fsqrt d3, d18 + 598: 1e61c223 fsqrt d3, d17 59c: 1e6240dc fcvt s28, d6 5a0: 1e3800d6 fcvtzs w22, s6 5a4: 9e380360 fcvtzs x0, s27 @@ -1220,9 +1220,9 @@ Disassembly of section .text: 5b4: 9e2201b9 scvtf s25, x13 5b8: 1e6202eb scvtf d11, w23 5bc: 9e620113 scvtf d19, x8 - 5c0: 1e2602b2 fmov w18, s21 + 5c0: 1e2602b1 fmov w17, s21 5c4: 9e660299 fmov x25, d20 - 5c8: 1e270253 fmov s19, w18 + 5c8: 1e270233 fmov s19, w17 5cc: 9e6703a2 fmov d2, x29 5d0: 1e2822c0 fcmp s22, s8 5d4: 1e7322a0 fcmp d21, d19 @@ -1254,11 +1254,11 @@ Disassembly of section .text: 63c: 0d40c23d ld1r {v29.8b}, [x17] 640: 4ddfcaf8 ld1r {v24.4s}, [x23], #4 644: 0dd9ccaa ld1r {v10.1d}, [x5], x25 - 648: 4c408d52 ld2 {v18.2d, v19.2d}, [x10] + 648: 4c408d51 ld2 {v17.2d, v18.2d}, [x10] 64c: 0cdf85ec ld2 {v12.4h, v13.4h}, [x15], #16 - 650: 4d60c259 ld2r {v25.16b, v26.16b}, [x18] + 650: 4d60c239 ld2r {v25.16b, v26.16b}, [x17] 654: 0dffcbc1 ld2r {v1.2s, v2.2s}, [x30], #8 - 658: 4de9ce50 ld2r {v16.2d, v17.2d}, [x18], x9 + 658: 4de9ce30 ld2r {v16.2d, v17.2d}, [x17], x9 65c: 4cc24999 ld3 {v25.4s-v27.4s}, [x12], x2 660: 0c404a7a ld3 {v26.2s-v28.2s}, [x19] 664: 4d40e6af ld3r {v15.8h-v17.8h}, [x21] @@ -1266,7 +1266,7 @@ Disassembly of section .text: 66c: 0dddef8e ld3r {v14.1d-v16.1d}, [x28], x29 670: 4cdf07b1 ld4 {v17.8h-v20.8h}, [x29], #64 674: 0cc000fb ld4 {v27.8b-v30.8b}, [x7], x0 - 678: 0d60e258 ld4r {v24.8b-v27.8b}, [x18] + 678: 0d60e238 ld4r {v24.8b-v27.8b}, [x17] 67c: 0dffe740 ld4r {v0.4h-v3.4h}, [x26], #8 680: 0de2eb2c ld4r {v12.2s-v15.2s}, [x25], x2 684: ce648376 sha512h q22, q27, v4.2d @@ -1317,7 +1317,7 @@ Disassembly of section .text: 738: e547e400 st1w {z0.s}, p1, [x0, #7, mul vl] 73c: e4014be0 st1b {z0.b}, p2, [sp, x1] 740: e4a84fe0 st1h {z0.h}, p3, [sp, x8, lsl #1] - 744: e5f25000 st1d {z0.d}, p4, [x0, x18, lsl #3] + 744: e5f15000 st1d {z0.d}, p4, [x0, x17, lsl #3] 748: 858043e0 ldr z0, [sp] 74c: 85a043ff ldr z31, [sp, #-256, mul vl] 750: e59f5d08 str z8, [x8, #255, mul vl] @@ -1362,7 +1362,7 @@ Disassembly of section .text: 7ec: f82f41ee ldsmax x15, x14, [x15] 7f0: f82973b9 ldumin x9, x25, [x29] 7f4: f82b6194 ldumax x11, x20, [x12] - 7f8: f8b28216 swpa x18, x22, [x16] + 7f8: f8b08216 swpa x16, x22, [x16] 7fc: f8b50358 ldadda x21, x24, [x26] 800: f8a61206 ldclra x6, x6, [x16] 804: f8b02219 ldeora x16, x25, [x16] @@ -1378,12 +1378,12 @@ Disassembly of section .text: 82c: f8ff3260 ldsetal xzr, x0, [x19] 830: f8fd513a ldsminal x29, x26, [x9] 834: f8fa41ec ldsmaxal x26, x12, [x15] - 838: f8eb724b lduminal x11, x11, [x18] + 838: f8eb71eb lduminal x11, x11, [x15] 83c: f8f96316 ldumaxal x25, x22, [x24] 840: f8608171 swpl x0, x17, [x11] 844: f86600dd ldaddl x6, x29, [x6] 848: f86512a5 ldclrl x5, x5, [x21] - 84c: f8732250 ldeorl x19, x16, [x18] + 84c: f87321f0 ldeorl x19, x16, [x15] 850: f87e339b ldsetl x30, x27, [x28] 854: f861503c ldsminl x1, x28, [x1] 858: f874421d ldsmaxl x20, x29, [x16] @@ -1405,7 +1405,7 @@ Disassembly of section .text: 898: b8b83064 ldseta w24, w4, [x3] 89c: b8ac539f ldsmina w12, wzr, [x28] 8a0: b8aa405a ldsmaxa w10, w26, [x2] - 8a4: b8ac73f2 ldumina w12, w18, [sp] + 8a4: b8ac73f0 ldumina w12, w16, [sp] 8a8: b8a163ad ldumaxa w1, w13, [x29] 8ac: b8e08193 swpal w0, w19, [x12] 8b0: b8f101b6 ldaddal w17, w22, [x13] @@ -1413,13 +1413,13 @@ Disassembly of section .text: 8b8: b8e1239a ldeoral w1, w26, [x28] 8bc: b8e4309e ldsetal w4, w30, [x4] 8c0: b8e6535e ldsminal w6, w30, [x26] - 8c4: b8f24109 ldsmaxal w18, w9, [x8] + 8c4: b8f04109 ldsmaxal w16, w9, [x8] 8c8: b8ec7280 lduminal w12, w0, [x20] 8cc: b8e16058 ldumaxal w1, w24, [x2] 8d0: b8608309 swpl w0, w9, [x24] 8d4: b87a03d0 ldaddl w26, w16, [x30] 8d8: b86312ea ldclrl w3, w10, [x23] - 8dc: b86a2244 ldeorl w10, w4, [x18] + 8dc: b86a21e4 ldeorl w10, w4, [x15] 8e0: b862310b ldsetl w2, w11, [x8] 8e4: b86a522f ldsminl w10, w15, [x17] 8e8: b862418a ldsmaxl w2, w10, [x12] @@ -1449,19 +1449,19 @@ Disassembly of section .text: 948: 65c78893 fmin z19.d, p2/m, z19.d, z4.d 94c: 658292d1 fmul z17.s, p4/m, z17.s, z22.s 950: 04ddaebc fneg z28.d, p3/m, z21.d - 954: 6582b452 frintm z18.s, p5/m, z2.s + 954: 6582b451 frintm z17.s, p5/m, z2.s 958: 6580ade6 frintn z6.s, p3/m, z15.s 95c: 65c1b42c frintp z12.d, p5/m, z1.d - 960: 658da632 fsqrt z18.s, p1/m, z17.s + 960: 658da631 fsqrt z17.s, p1/m, z17.s 964: 658195af fsub z15.s, p5/m, z15.s, z13.s 968: 65eb1f74 fmla z20.d, p7/m, z27.d, z11.d 96c: 65f723c3 fmls z3.d, p0/m, z30.d, z23.d 970: 65ba4b71 fnmla z17.s, p2/m, z27.s, z26.s 974: 65fe76c6 fnmls z6.d, p5/m, z22.d, z30.d - 978: 04525f42 mla z2.h, p7/m, z26.h, z18.h + 978: 04515f42 mla z2.h, p7/m, z26.h, z17.h 97c: 04117056 mls z22.b, p4/m, z2.b, z17.b 980: 04363338 and z24.d, z25.d, z22.d - 984: 04a33192 eor z18.d, z12.d, z3.d + 984: 04a33191 eor z17.d, z12.d, z3.d 988: 0470339d orr z29.d, z28.d, z16.d 98c: 049a2b86 andv s6, p2, z28.s 990: 045824e7 orv h7, p1, z7.h @@ -1477,14 +1477,14 @@ Disassembly of section .text: static const unsigned int insns[] = { 0x8b0d82fa, 0xcb49970c, 0xab889dfc, 0xeb9ee787, - 0x0b9b3ec9, 0x4b9279a3, 0x2b88474e, 0x6b8c56c0, + 0x0b9b3ec9, 0x4b9179a3, 0x2b88474e, 0x6b8c56c0, 0x8a1a51e0, 0xaa11f4ba, 0xca0281b8, 0xea918c7c, - 0x0a5d4a19, 0x2a4b264d, 0x4a523ca5, 0x6a9b6ae2, + 0x0a5d4a19, 0x2a4b262d, 0x4a513ca5, 0x6a9b6ae2, 0x8a70b79b, 0xaaba9728, 0xca6dfe3d, 0xea627f1c, 0x0aa70f53, 0x2aaa0f06, 0x4a6176a4, 0x6a604eb0, 0x1105ed91, 0x3100583e, 0x5101f8bd, 0x710f0306, 0x9101a1a0, 0xb10a5cc8, 0xd10810aa, 0xf10fd061, - 0x120cb166, 0x321764bc, 0x52174681, 0x720c0247, + 0x120cb166, 0x321764bc, 0x52174681, 0x720c0227, 0x9241018e, 0xb25a2969, 0xd278b411, 0xf26aad01, 0x14000000, 0x17ffffd7, 0x14000242, 0x94000000, 0x97ffffd4, 0x9400023f, 0x3400000a, 0x34fffa2a, @@ -1515,14 +1515,14 @@ Disassembly of section .text: 0xd5033fdf, 0xd5033e9f, 0xd50332bf, 0xd61f0200, 0xd63f0280, 0xc80a7d1b, 0xc800fea1, 0xc85f7fb1, 0xc85fff9d, 0xc89ffee1, 0xc8dffe95, 0x88167e7b, - 0x880bfcd0, 0x885f7c12, 0x885ffd44, 0x889ffed8, + 0x880bfcd0, 0x885f7c11, 0x885ffd44, 0x889ffed8, 0x88dffe6a, 0x48017fc5, 0x4808fe2c, 0x485f7dc9, 0x485ffc27, 0x489ffe05, 0x48dffd82, 0x080a7c6c, 0x081cff4e, 0x085f7d5e, 0x085ffeae, 0x089ffd2d, 0x08dfff76, 0xc87f4d7c, 0xc87fcc5e, 0xc8220417, - 0xc82cb5f0, 0x887f55b2, 0x887ff90b, 0x88382c2d, + 0xc82cb5f0, 0x887f55b1, 0x887ff90b, 0x88382c2d, 0x883aedb5, 0xf819928b, 0xb803e21c, 0x381f713b, - 0x781ce322, 0xf850f044, 0xb85e129e, 0x385e92f2, + 0x781ce322, 0xf850f044, 0xb85e129e, 0x385e92f1, 0x785ff35d, 0x39801921, 0x7881318b, 0x78dce02b, 0xb8829313, 0xfc45f318, 0xbc5d50af, 0xfc001375, 0xbc1951b7, 0xf8008c0b, 0xb801dc03, 0x38009dcb, @@ -1533,9 +1533,9 @@ Disassembly of section .text: 0x7801b506, 0xf853654e, 0xb85d74b0, 0x384095c2, 0x785ec5bc, 0x389e15a9, 0x789dc703, 0x78c06474, 0xb89ff667, 0xfc57e51e, 0xbc4155f9, 0xfc05a6ee, - 0xbc1df408, 0xf835da4a, 0xb836d9a4, 0x3833580d, + 0xbc1df408, 0xf835da2a, 0xb836d9a4, 0x3833580d, 0x7826cb6c, 0xf8706900, 0xb87ae880, 0x3865db2e, - 0x78724889, 0x38a7789b, 0x78beca2f, 0x78f6c810, + 0x78714889, 0x38a7789b, 0x78beca2f, 0x78f6c810, 0xb8bef956, 0xfc6afabd, 0xbc734963, 0xfc3d5b8d, 0xbc25fbb7, 0xf9189d05, 0xb91ecb1d, 0x39187a33, 0x791f226d, 0xf95aa2f3, 0xb9587bb7, 0x395f7176, @@ -1544,19 +1544,19 @@ Disassembly of section .text: 0xbd1b1869, 0x58002cfb, 0x1800000b, 0xf8945060, 0xd8000000, 0xf8ae6ba0, 0xf99a0080, 0x1a070035, 0x3a0700a8, 0x5a0e0367, 0x7a11009b, 0x9a000380, - 0xba1e030c, 0xda0f0320, 0xfa030301, 0x0b340b12, + 0xba1e030c, 0xda0f0320, 0xfa030301, 0x0b340b11, 0x2b2a278d, 0xcb22aa0f, 0x6b2d29bd, 0x8b2cce8c, 0xab2b877e, 0xcb21c8ee, 0xeb3ba47d, 0x3a4d400e, - 0x7a5232c6, 0xba5e624e, 0xfa53814c, 0x3a52d8c2, + 0x7a5132c6, 0xba5e622e, 0xfa53814c, 0x3a52d8c2, 0x7a4d8924, 0xba4b3aab, 0xfa4d7882, 0x1a96804c, 0x1a912618, 0x5a90b0e6, 0x5a96976b, 0x9a9db06a, 0x9a9b374c, 0xda95c14f, 0xda89c6fe, 0x5ac0015e, 0x5ac005fd, 0x5ac00bdd, 0x5ac012b9, 0x5ac01404, - 0xdac002b2, 0xdac0061d, 0xdac00a95, 0xdac00e66, + 0xdac002b1, 0xdac0061d, 0xdac00a95, 0xdac00e66, 0xdac0107e, 0xdac01675, 0x1ac00b0b, 0x1ace0f3b, - 0x1ad221c3, 0x1ad825e7, 0x1ad92a3c, 0x1adc2f42, - 0x9ada0b25, 0x9ad20e1b, 0x9acc22a6, 0x9acc2480, - 0x9adc2a3b, 0x9ad22c5c, 0x9bce7dea, 0x9b597c6e, + 0x1ad121c3, 0x1ad825e7, 0x1ad92a3c, 0x1adc2f42, + 0x9ada0b25, 0x9ad10e1b, 0x9acc22a6, 0x9acc2480, + 0x9adc2a3b, 0x9ad12c5c, 0x9bce7dea, 0x9b597c6e, 0x1b0e166f, 0x1b1ae490, 0x9b023044, 0x9b089e3d, 0x9b391083, 0x9b24c73a, 0x9bb15f40, 0x9bbcc6af, 0x1e23095b, 0x1e3918e0, 0x1e2f28c9, 0x1e2a39fd, @@ -1565,10 +1565,10 @@ Disassembly of section .text: 0x1f2935da, 0x1f2574ea, 0x1f4b306f, 0x1f5ec7cf, 0x1f6f3e93, 0x1f6226a9, 0x1e2040fb, 0x1e20c3dd, 0x1e214031, 0x1e21c0c2, 0x1e22c06a, 0x1e604178, - 0x1e60c027, 0x1e61400b, 0x1e61c243, 0x1e6240dc, + 0x1e60c027, 0x1e61400b, 0x1e61c223, 0x1e6240dc, 0x1e3800d6, 0x9e380360, 0x1e78005a, 0x9e7800e5, 0x1e22017c, 0x9e2201b9, 0x1e6202eb, 0x9e620113, - 0x1e2602b2, 0x9e660299, 0x1e270253, 0x9e6703a2, + 0x1e2602b1, 0x9e660299, 0x1e270233, 0x9e6703a2, 0x1e2822c0, 0x1e7322a0, 0x1e202288, 0x1e602168, 0x293c19f4, 0x2966387b, 0x69762971, 0xa9041dc7, 0xa9475c0c, 0x29b61ccd, 0x29ee405e, 0x69ee0744, @@ -1576,10 +1576,10 @@ Disassembly of section .text: 0x68f61831, 0xa8b352ad, 0xa8c56d5e, 0x28024565, 0x2874134e, 0xa8027597, 0xa87b1aa0, 0x0c40734f, 0x4cdfa177, 0x0cc76ee8, 0x4cdf2733, 0x0d40c23d, - 0x4ddfcaf8, 0x0dd9ccaa, 0x4c408d52, 0x0cdf85ec, - 0x4d60c259, 0x0dffcbc1, 0x4de9ce50, 0x4cc24999, + 0x4ddfcaf8, 0x0dd9ccaa, 0x4c408d51, 0x0cdf85ec, + 0x4d60c239, 0x0dffcbc1, 0x4de9ce30, 0x4cc24999, 0x0c404a7a, 0x4d40e6af, 0x4ddfe9b9, 0x0dddef8e, - 0x4cdf07b1, 0x0cc000fb, 0x0d60e258, 0x0dffe740, + 0x4cdf07b1, 0x0cc000fb, 0x0d60e238, 0x0dffe740, 0x0de2eb2c, 0xce648376, 0xce6184c7, 0xcec081fa, 0xce6d89a2, 0xba5fd3e3, 0x3a5f03e5, 0xfa411be4, 0x7a42cbe2, 0x93df03ff, 0xc820ffff, 0x8822fc7f, @@ -1592,7 +1592,7 @@ Disassembly of section .text: 0x25b8efe2, 0x25f8f007, 0xa400a3e0, 0xa4a8a7ea, 0xa547a814, 0xa4084ffe, 0xa55c53e0, 0xa5e1540b, 0xe400fbf6, 0xe408ffff, 0xe547e400, 0xe4014be0, - 0xe4a84fe0, 0xe5f25000, 0x858043e0, 0x85a043ff, + 0xe4a84fe0, 0xe5f15000, 0x858043e0, 0x85a043ff, 0xe59f5d08, 0x1e601000, 0x1e603000, 0x1e621000, 0x1e623000, 0x1e641000, 0x1e643000, 0x1e661000, 0x1e663000, 0x1e681000, 0x1e683000, 0x1e6a1000, @@ -1603,21 +1603,21 @@ Disassembly of section .text: 0x1e7a3000, 0x1e7c1000, 0x1e7c3000, 0x1e7e1000, 0x1e7e3000, 0xf8388098, 0xf8340010, 0xf8241175, 0xf83e22d0, 0xf82432ef, 0xf83a5186, 0xf82f41ee, - 0xf82973b9, 0xf82b6194, 0xf8b28216, 0xf8b50358, + 0xf82973b9, 0xf82b6194, 0xf8b08216, 0xf8b50358, 0xf8a61206, 0xf8b02219, 0xf8bc3218, 0xf8ba514f, 0xf8ad428e, 0xf8a173d7, 0xf8ae60c2, 0xf8e38328, 0xf8e003db, 0xf8e513c5, 0xf8eb2019, 0xf8ff3260, - 0xf8fd513a, 0xf8fa41ec, 0xf8eb724b, 0xf8f96316, - 0xf8608171, 0xf86600dd, 0xf86512a5, 0xf8732250, + 0xf8fd513a, 0xf8fa41ec, 0xf8eb71eb, 0xf8f96316, + 0xf8608171, 0xf86600dd, 0xf86512a5, 0xf87321f0, 0xf87e339b, 0xf861503c, 0xf874421d, 0xf86d73aa, 0xf87d62d3, 0xb82a83e4, 0xb83503e8, 0xb833138a, 0xb82220b9, 0xb82332c8, 0xb83350ad, 0xb83d42b8, 0xb83a7078, 0xb83862fa, 0xb8af8075, 0xb8b80328, 0xb8b41230, 0xb8a22001, 0xb8b83064, 0xb8ac539f, - 0xb8aa405a, 0xb8ac73f2, 0xb8a163ad, 0xb8e08193, + 0xb8aa405a, 0xb8ac73f0, 0xb8a163ad, 0xb8e08193, 0xb8f101b6, 0xb8fc13fe, 0xb8e1239a, 0xb8e4309e, - 0xb8e6535e, 0xb8f24109, 0xb8ec7280, 0xb8e16058, - 0xb8608309, 0xb87a03d0, 0xb86312ea, 0xb86a2244, + 0xb8e6535e, 0xb8f04109, 0xb8ec7280, 0xb8e16058, + 0xb8608309, 0xb87a03d0, 0xb86312ea, 0xb86a21e4, 0xb862310b, 0xb86a522f, 0xb862418a, 0xb86c71af, 0xb8626287, 0x042401f9, 0x04b10564, 0x65ca0230, 0x65d90996, 0x65ca05dc, 0x0456afc1, 0x0400044f, @@ -1625,10 +1625,10 @@ Disassembly of section .text: 0x04901774, 0x0417b89a, 0x041eb3d6, 0x04480b6b, 0x048a17dc, 0x048105be, 0x04dcb35e, 0x65808d6f, 0x65cd9e06, 0x65869cfb, 0x65c78893, 0x658292d1, - 0x04ddaebc, 0x6582b452, 0x6580ade6, 0x65c1b42c, - 0x658da632, 0x658195af, 0x65eb1f74, 0x65f723c3, - 0x65ba4b71, 0x65fe76c6, 0x04525f42, 0x04117056, - 0x04363338, 0x04a33192, 0x0470339d, 0x049a2b86, + 0x04ddaebc, 0x6582b451, 0x6580ade6, 0x65c1b42c, + 0x658da631, 0x658195af, 0x65eb1f74, 0x65f723c3, + 0x65ba4b71, 0x65fe76c6, 0x04515f42, 0x04117056, + 0x04363338, 0x04a33191, 0x0470339d, 0x049a2b86, 0x045824e7, 0x04193509, 0x040837db, 0x044a221a, 0x65c73903, 0x65c63b55, 0x65982096, 0x04412071, @@ -1979,3 +1979,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 717be156e5c..711d9db07e5 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 @@ -640,7 +653,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 @@ -680,6 +693,8 @@ public: return Address(Post(base, idx)); } + static address locate_next_instruction(address inst); + Instruction_aarch64* current; void set_current(Instruction_aarch64* i) { current = i; } @@ -1555,6 +1570,11 @@ public: #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_Defs_aarch64.hpp b/src/hotspot/cpu/aarch64/c1_Defs_aarch64.hpp index fae09ac1a8d..4df27e7fde4 100644 --- a/src/hotspot/cpu/aarch64/c1_Defs_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/c1_Defs_aarch64.hpp @@ -44,13 +44,13 @@ enum { pd_nof_cpu_regs_frame_map = RegisterImpl::number_of_registers, // number of registers used during code emission pd_nof_fpu_regs_frame_map = FloatRegisterImpl::number_of_registers, // number of registers used during code emission - pd_nof_caller_save_cpu_regs_frame_map = 19 - 2, // number of registers killed by calls + pd_nof_caller_save_cpu_regs_frame_map = 19 - 2 /* rscratch1 and rscratch2 */ R18_RESERVED_ONLY(- 1), // number of registers killed by calls pd_nof_caller_save_fpu_regs_frame_map = 32, // number of registers killed by calls - pd_first_callee_saved_reg = 19 - 2, - pd_last_callee_saved_reg = 26 - 2, + pd_first_callee_saved_reg = 19 - 2 /* rscratch1 and rscratch2 */ R18_RESERVED_ONLY(- 1), + pd_last_callee_saved_reg = 26 - 2 /* rscratch1 and rscratch2 */ R18_RESERVED_ONLY(- 1), - pd_last_allocatable_cpu_reg = 16, + pd_last_allocatable_cpu_reg = 16 R18_RESERVED_ONLY(- 1), pd_nof_cpu_regs_reg_alloc = pd_last_allocatable_cpu_reg + 1, // number of registers that are visible to register allocator @@ -60,9 +60,9 @@ enum { pd_nof_fpu_regs_linearscan = pd_nof_fpu_regs_frame_map, // number of registers visible to linear scan pd_nof_xmm_regs_linearscan = 0, // don't have vector registers pd_first_cpu_reg = 0, - pd_last_cpu_reg = 16, + pd_last_cpu_reg = 16 R18_RESERVED_ONLY(- 1), pd_first_byte_reg = 0, - pd_last_byte_reg = 16, + pd_last_byte_reg = 16 R18_RESERVED_ONLY(- 1), pd_first_fpu_reg = pd_nof_cpu_regs_frame_map, pd_last_fpu_reg = pd_first_fpu_reg + 31, 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/c1_FrameMap_aarch64.cpp b/src/hotspot/cpu/aarch64/c1_FrameMap_aarch64.cpp index 4257e3445ea..42ff62a986c 100644 --- a/src/hotspot/cpu/aarch64/c1_FrameMap_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c1_FrameMap_aarch64.cpp @@ -181,7 +181,10 @@ void FrameMap::initialize() { map_register(i, r15); r15_opr = LIR_OprFact::single_cpu(i); i++; map_register(i, r16); r16_opr = LIR_OprFact::single_cpu(i); i++; map_register(i, r17); r17_opr = LIR_OprFact::single_cpu(i); i++; - map_register(i, r18); r18_opr = LIR_OprFact::single_cpu(i); i++; +#ifndef R18_RESERVED + // See comment in register_aarch64.hpp + map_register(i, r18_tls); r18_opr = LIR_OprFact::single_cpu(i); i++; +#endif map_register(i, r19); r19_opr = LIR_OprFact::single_cpu(i); i++; map_register(i, r20); r20_opr = LIR_OprFact::single_cpu(i); i++; map_register(i, r21); r21_opr = LIR_OprFact::single_cpu(i); i++; @@ -199,6 +202,11 @@ void FrameMap::initialize() { map_register(i, r8); r8_opr = LIR_OprFact::single_cpu(i); i++; // rscratch1 map_register(i, r9); r9_opr = LIR_OprFact::single_cpu(i); i++; // rscratch2 +#ifdef R18_RESERVED + // See comment in register_aarch64.hpp + map_register(i, r18_tls); r18_opr = LIR_OprFact::single_cpu(i); i++; +#endif + rscratch1_opr = r8_opr; rscratch2_opr = r9_opr; rscratch1_long_opr = LIR_OprFact::double_cpu(r8_opr->cpu_regnr(), r8_opr->cpu_regnr()); @@ -227,7 +235,10 @@ void FrameMap::initialize() { _caller_save_cpu_regs[13] = r15_opr; _caller_save_cpu_regs[14] = r16_opr; _caller_save_cpu_regs[15] = r17_opr; +#ifndef R18_RESERVED + // See comment in register_aarch64.hpp _caller_save_cpu_regs[16] = r18_opr; +#endif for (int i = 0; i < 8; i++) { _caller_save_fpu_regs[i] = LIR_OprFact::single_fpu(i); @@ -253,7 +264,7 @@ void FrameMap::initialize() { r15_oop_opr = as_oop_opr(r15); r16_oop_opr = as_oop_opr(r16); r17_oop_opr = as_oop_opr(r17); - r18_oop_opr = as_oop_opr(r18); + r18_oop_opr = as_oop_opr(r18_tls); r19_oop_opr = as_oop_opr(r19); r20_oop_opr = as_oop_opr(r20); r21_oop_opr = as_oop_opr(r21); diff --git a/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp index 5b3bc55035c..24b32187b7c 100644 --- a/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp @@ -543,7 +543,7 @@ void C2_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; bool isLL = ae == StrIntrinsicNode::LL; @@ -634,7 +634,7 @@ void C2_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) { @@ -660,10 +660,10 @@ void C2_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. @@ -687,7 +687,7 @@ void C2_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/gc/shenandoah/shenandoah_aarch64.ad b/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoah_aarch64.ad index 091bf091d10..0572e7d8d11 100644 --- a/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoah_aarch64.ad +++ b/src/hotspot/cpu/aarch64/gc/shenandoah/shenandoah_aarch64.ad @@ -23,6 +23,7 @@ // source_hpp %{ +#include "gc/shenandoah/shenandoahBarrierSet.hpp" #include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp" %} diff --git a/src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp b/src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp index 114140cca26..523dbf1e602 100644 --- a/src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/globalDefinitions_aarch64.hpp @@ -58,4 +58,13 @@ const bool CCallingConventionRequiresIntsAsLongs = false; #define COMPRESSED_CLASS_POINTERS_DEPENDS_ON_COMPRESSED_OOPS false +#if defined(_WIN64) +#define R18_RESERVED +#define R18_RESERVED_ONLY(code) code +#define NOT_R18_RESERVED(code) +#else +#define R18_RESERVED_ONLY(code) +#define NOT_R18_RESERVED(code) code +#endif + #endif // CPU_AARCH64_GLOBALDEFINITIONS_AARCH64_HPP diff --git a/src/hotspot/cpu/aarch64/icache_aarch64.hpp b/src/hotspot/cpu/aarch64/icache_aarch64.hpp index 5e689fb988e..9fd0e8575cb 100644 --- a/src/hotspot/cpu/aarch64/icache_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/icache_aarch64.hpp @@ -26,19 +26,6 @@ #ifndef CPU_AARCH64_ICACHE_AARCH64_HPP #define CPU_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 + 3)); - } - static void invalidate_range(address start, int nbytes) { - __builtin___clear_cache((char *)start, (char *)(start + nbytes)); - } -}; +#include OS_CPU_HEADER(icache) #endif // CPU_AARCH64_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 2d6f78db852..bf22a03de9a 100644 --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp @@ -2651,9 +2651,17 @@ void MacroAssembler::debug64(char* msg, int64_t pc, int64_t regs[]) fatal("DEBUG MESSAGE: %s", msg); } +RegSet MacroAssembler::call_clobbered_registers() { + RegSet regs = RegSet::range(r0, r17) - RegSet::of(rscratch1, rscratch2); +#ifndef R18_RESERVED + regs += r18_tls; +#endif + return regs; +} + void MacroAssembler::push_call_clobbered_registers_except(RegSet exclude) { int step = 4 * wordSize; - push(RegSet::range(r0, r18) - RegSet::of(rscratch1, rscratch2) - exclude, sp); + push(call_clobbered_registers() - exclude, sp); sub(sp, sp, step); mov(rscratch1, -step); // Push v0-v7, v16-v31. @@ -2673,7 +2681,7 @@ void MacroAssembler::pop_call_clobbered_registers_except(RegSet exclude) { as_FloatRegister(i+3), T1D, Address(post(sp, 4 * wordSize))); } - pop(RegSet::range(r0, r18) - RegSet::of(rscratch1, rscratch2) - exclude, sp); + pop(call_clobbered_registers() - exclude, sp); } void MacroAssembler::push_CPU_state(bool save_vectors, bool use_sve, diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp index be933be8e94..998f1afc1c7 100644 --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp @@ -188,7 +188,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 @@ -196,7 +204,7 @@ class MacroAssembler: public Assembler { inline void cmpw(Register Rd, T imm) { subsw(zr, Rd, imm); } inline void cmp(Register Rd, unsigned char imm8) { subs(zr, Rd, imm8); } - inline void cmp(Register Rd, unsigned imm) __attribute__ ((deprecated)); + inline void cmp(Register Rd, unsigned imm) = delete; inline void cmnw(Register Rd, unsigned imm) { addsw(zr, Rd, imm); } inline void cmn(Register Rd, unsigned imm) { adds(zr, Rd, imm); } @@ -470,6 +478,8 @@ public: void push_fp(RegSet regs, Register stack) { if (regs.bits()) push_fp(regs.bits(), stack); } void pop_fp(RegSet regs, Register stack) { if (regs.bits()) pop_fp(regs.bits(), stack); } + static RegSet call_clobbered_registers(); + // Push and pop everything that might be clobbered by a native // runtime call except rscratch1 and rscratch2. (They are always // scratch, so we don't have to protect them.) Only save the lower @@ -522,10 +532,10 @@ public: // 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); @@ -534,7 +544,7 @@ public: else branch = &Assembler::tbnz; - if (far) { + if (isfar) { Label L; (this->*branch)(Rt, bitpos, L); b(dest); diff --git a/src/hotspot/cpu/aarch64/macroAssembler_aarch64_trig.cpp b/src/hotspot/cpu/aarch64/macroAssembler_aarch64_trig.cpp index 4ef2d1d6c32..160be0d077d 100644 --- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64_trig.cpp +++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64_trig.cpp @@ -689,7 +689,7 @@ void MacroAssembler::generate__kernel_rem_pio2(address two_over_pi, address pio2 RECOMP_FOR1_CHECK; Register tmp2 = r1, n = r2, jv = r4, tmp5 = r5, jx = r6, tmp3 = r7, iqBase = r10, ih = r11, tmp4 = r12, tmp1 = r13, - jz = r14, j = r15, twoOverPiBase = r16, i = r17, qBase = r18; + jz = r14, j = r15, twoOverPiBase = r16, i = r17, qBase = r19; // jp = jk == init_jk[prec] = init_jk[2] == {2,3,4,6}[2] == 4 // jx = nx - 1 lea(twoOverPiBase, ExternalAddress(two_over_pi)); @@ -1421,6 +1421,12 @@ void MacroAssembler::generate_dsin_dcos(bool isCos, address npio2_hw, Label DONE, ARG_REDUCTION, TINY_X, RETURN_SIN, EARLY_CASE; Register X = r0, absX = r1, n = r2, ix = r3; FloatRegister y0 = v4, y1 = v5; + + enter(); + // r19 is used in TemplateInterpreterGenerator::generate_math_entry + RegSet saved_regs = RegSet::of(r19); + push (saved_regs, sp); + block_comment("check |x| ~< pi/4, NaN, Inf and |x| < 2**-27 cases"); { fmovd(X, v0); mov(rscratch2, 0x3e400000); @@ -1438,14 +1444,14 @@ void MacroAssembler::generate_dsin_dcos(bool isCos, address npio2_hw, // Set last bit unconditionally to make it NaN orr(r10, r10, 1); fmovd(v0, r10); - ret(lr); + b(DONE); } block_comment("kernel_sin/kernel_cos: if(ix<0x3e400000) {}"); { bind(TINY_X); if (isCos) { fmovd(v0, 1.0); } - ret(lr); + b(DONE); } bind(ARG_REDUCTION); /* argument reduction needed */ block_comment("n = __ieee754_rem_pio2(x,y);"); { @@ -1465,7 +1471,7 @@ void MacroAssembler::generate_dsin_dcos(bool isCos, address npio2_hw, tbz(n, 1, DONE); } fnegd(v0, v0); - ret(lr); + b(DONE); bind(RETURN_SIN); generate_kernel_sin(y0, true, dsin_coef); if (isCos) { @@ -1474,7 +1480,7 @@ void MacroAssembler::generate_dsin_dcos(bool isCos, address npio2_hw, tbz(n, 1, DONE); } fnegd(v0, v0); - ret(lr); + b(DONE); } bind(EARLY_CASE); eor(y1, T8B, y1, y1); @@ -1484,5 +1490,7 @@ void MacroAssembler::generate_dsin_dcos(bool isCos, address npio2_hw, generate_kernel_sin(v0, false, dsin_coef); } bind(DONE); + pop(saved_regs, sp); + leave(); ret(lr); } diff --git a/src/hotspot/cpu/aarch64/register_aarch64.cpp b/src/hotspot/cpu/aarch64/register_aarch64.cpp index d9ef055efce..24c3f32c2b6 100644 --- a/src/hotspot/cpu/aarch64/register_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/register_aarch64.cpp @@ -41,7 +41,7 @@ const char* RegisterImpl::name() const { "c_rarg0", "c_rarg1", "c_rarg2", "c_rarg3", "c_rarg4", "c_rarg5", "c_rarg6", "c_rarg7", "rscratch1", "rscratch2", "r10", "r11", "r12", "r13", "r14", "r15", "r16", - "r17", "r18", "r19", + "r17", "r18_tls", "r19", "resp", "rdispatch", "rbcp", "r23", "rlocals", "rmonitors", "rcpool", "rheapbase", "rthread", "rfp", "lr", "sp" }; diff --git a/src/hotspot/cpu/aarch64/register_aarch64.hpp b/src/hotspot/cpu/aarch64/register_aarch64.hpp index 11ebe91df0e..c567791e593 100644 --- a/src/hotspot/cpu/aarch64/register_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/register_aarch64.hpp @@ -27,6 +27,7 @@ #define CPU_AARCH64_REGISTER_AARCH64_HPP #include "asm/register.hpp" +#include "utilities/powerOfTwo.hpp" class VMRegImpl; typedef VMRegImpl* VMReg; @@ -91,7 +92,18 @@ CONSTANT_REGISTER_DECLARATION(Register, r14, (14)); CONSTANT_REGISTER_DECLARATION(Register, r15, (15)); CONSTANT_REGISTER_DECLARATION(Register, r16, (16)); CONSTANT_REGISTER_DECLARATION(Register, r17, (17)); -CONSTANT_REGISTER_DECLARATION(Register, r18, (18)); + +// In the ABI for Windows+AArch64 the register r18 is used to store the pointer +// to the current thread's TEB (where TLS variables are stored). We could +// carefully save and restore r18 at key places, however Win32 Structured +// Exception Handling (SEH) is using TLS to unwind the stack. If r18 is used +// for any other purpose at the time of an exception happening, SEH would not +// be able to unwind the stack properly and most likely crash. +// +// It's easier to avoid allocating r18 altogether. +// +// See https://docs.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions?view=vs-2019#integer-registers +CONSTANT_REGISTER_DECLARATION(Register, r18_tls, (18)); CONSTANT_REGISTER_DECLARATION(Register, r19, (19)); CONSTANT_REGISTER_DECLARATION(Register, r20, (20)); CONSTANT_REGISTER_DECLARATION(Register, r21, (21)); @@ -292,6 +304,8 @@ class ConcreteRegisterImpl : public AbstractRegisterImpl { static const int max_pr; }; +class RegSetIterator; + // A set of registers class RegSet { uint32_t _bitset; @@ -350,6 +364,49 @@ public: } uint32_t bits() const { return _bitset; } + +private: + + Register first() { + uint32_t first = _bitset & -_bitset; + return first ? as_Register(exact_log2(first)) : noreg; + } + +public: + + friend class RegSetIterator; + + RegSetIterator begin(); }; +class RegSetIterator { + RegSet _regs; + +public: + RegSetIterator(RegSet x): _regs(x) {} + RegSetIterator(const RegSetIterator& mit) : _regs(mit._regs) {} + + RegSetIterator& operator++() { + Register r = _regs.first(); + if (r != noreg) + _regs -= r; + return *this; + } + + bool operator==(const RegSetIterator& rhs) const { + return _regs.bits() == rhs._regs.bits(); + } + bool operator!=(const RegSetIterator& rhs) const { + return ! (rhs == *this); + } + + Register operator*() { + return _regs.first(); + } +}; + +inline RegSetIterator RegSet::begin() { + return RegSetIterator(*this); +} + #endif // CPU_AARCH64_REGISTER_AARCH64_HPP diff --git a/src/hotspot/cpu/aarch64/register_definitions_aarch64.cpp b/src/hotspot/cpu/aarch64/register_definitions_aarch64.cpp index 63d7146b4a4..f48c70d09e6 100644 --- a/src/hotspot/cpu/aarch64/register_definitions_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/register_definitions_aarch64.cpp @@ -50,7 +50,7 @@ REGISTER_DEFINITION(Register, r14); REGISTER_DEFINITION(Register, r15); REGISTER_DEFINITION(Register, r16); REGISTER_DEFINITION(Register, r17); -REGISTER_DEFINITION(Register, r18); +REGISTER_DEFINITION(Register, r18_tls); // see comment in register_aarch64.hpp REGISTER_DEFINITION(Register, r19); REGISTER_DEFINITION(Register, r20); REGISTER_DEFINITION(Register, r21); diff --git a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp index e5d02756a82..412578eea5c 100644 --- a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp @@ -1092,7 +1092,7 @@ class StubGenerator: public StubCodeGenerator { Label copy4, copy8, copy16, copy32, copy80, copy_big, finish; const Register t2 = r5, t3 = r6, t4 = r7, t5 = r8; const Register t6 = r9, t7 = r10, t8 = r11, t9 = r12; - const Register send = r17, dend = r18; + const Register send = r17, dend = r16; if (PrefetchCopyIntervalInBytes > 0) __ prfm(Address(s, 0), PLDL1KEEP); @@ -1282,11 +1282,15 @@ class StubGenerator: public StubCodeGenerator { void clobber_registers() { #ifdef ASSERT + RegSet clobbered + = MacroAssembler::call_clobbered_registers() - rscratch1; __ mov(rscratch1, (uint64_t)0xdeadbeef); __ orr(rscratch1, rscratch1, rscratch1, Assembler::LSL, 32); - for (Register r = r3; r <= r18; r++) - if (r != rscratch1) __ mov(r, rscratch1); + for (RegSetIterator it = clobbered.begin(); *it != noreg; ++it) { + __ mov(*it, rscratch1); + } #endif + } // Scan over array at a for count oops, verifying each one. @@ -1719,10 +1723,10 @@ class StubGenerator: public StubCodeGenerator { RegSet wb_pre_saved_regs = RegSet::range(c_rarg0, c_rarg4); RegSet wb_post_saved_regs = RegSet::of(count); - // Registers used as temps (r18, r19, r20 are save-on-entry) + // Registers used as temps (r19, r20, r21, r22 are save-on-entry) + const Register copied_oop = r22; // actual oop copied const Register count_save = r21; // orig elementscount const Register start_to = r20; // destination array start address - const Register copied_oop = r18; // actual oop copied const Register r19_klass = r19; // oop._klass //--------------------------------------------------------------- @@ -1759,8 +1763,7 @@ class StubGenerator: public StubCodeGenerator { // Empty array: Nothing to do. __ cbz(count, L_done); - - __ push(RegSet::of(r18, r19, r20, r21), sp); + __ push(RegSet::of(r19, r20, r21, r22), sp); #ifdef ASSERT BLOCK_COMMENT("assert consistent ckoff/ckval"); @@ -1829,7 +1832,7 @@ class StubGenerator: public StubCodeGenerator { bs->arraycopy_epilogue(_masm, decorators, is_oop, start_to, count_save, rscratch1, wb_post_saved_regs); __ bind(L_done_pop); - __ pop(RegSet::of(r18, r19, r20, r21), sp); + __ pop(RegSet::of(r19, r20, r21, r22), sp); inc_counter_np(SharedRuntime::_checkcast_array_copy_ctr); __ bind(L_done); @@ -2006,7 +2009,7 @@ class StubGenerator: public StubCodeGenerator { // registers used as temp const Register scratch_length = r16; // elements count to copy const Register scratch_src_klass = r17; // array klass - const Register lh = r18; // layout helper + const Register lh = r15; // layout helper // if (length < 0) return -1; __ movw(scratch_length, length); // length (elements count, 32-bits value) @@ -2077,7 +2080,7 @@ class StubGenerator: public StubCodeGenerator { // const Register rscratch1_offset = rscratch1; // array offset - const Register r18_elsize = lh; // element size + const Register r15_elsize = lh; // element size __ ubfx(rscratch1_offset, lh, Klass::_lh_header_size_shift, exact_log2(Klass::_lh_header_size_mask+1)); // array_offset @@ -2098,8 +2101,8 @@ class StubGenerator: public StubCodeGenerator { // The possible values of elsize are 0-3, i.e. exact_log2(element // size in bytes). We do a simple bitwise binary search. __ BIND(L_copy_bytes); - __ tbnz(r18_elsize, 1, L_copy_ints); - __ tbnz(r18_elsize, 0, L_copy_shorts); + __ tbnz(r15_elsize, 1, L_copy_ints); + __ tbnz(r15_elsize, 0, L_copy_shorts); __ lea(from, Address(src, src_pos));// src_addr __ lea(to, Address(dst, dst_pos));// dst_addr __ movw(count, scratch_length); // length @@ -2112,7 +2115,7 @@ class StubGenerator: public StubCodeGenerator { __ b(RuntimeAddress(short_copy_entry)); __ BIND(L_copy_ints); - __ tbnz(r18_elsize, 0, L_copy_longs); + __ tbnz(r15_elsize, 0, L_copy_longs); __ lea(from, Address(src, src_pos, Address::lsl(2)));// src_addr __ lea(to, Address(dst, dst_pos, Address::lsl(2)));// dst_addr __ movw(count, scratch_length); // length @@ -2123,8 +2126,8 @@ class StubGenerator: public StubCodeGenerator { { BLOCK_COMMENT("assert long copy {"); Label L; - __ andw(lh, lh, Klass::_lh_log2_element_size_mask); // lh -> r18_elsize - __ cmpw(r18_elsize, LogBytesPerLong); + __ andw(lh, lh, Klass::_lh_log2_element_size_mask); // lh -> r15_elsize + __ cmpw(r15_elsize, LogBytesPerLong); __ br(Assembler::EQ, L); __ stop("must be long copy, but elsize is wrong"); __ bind(L); @@ -2142,8 +2145,8 @@ class StubGenerator: public StubCodeGenerator { Label L_plain_copy, L_checkcast_copy; // test array classes for subtyping - __ load_klass(r18, dst); - __ cmp(scratch_src_klass, r18); // usual case is exact equality + __ load_klass(r15, dst); + __ cmp(scratch_src_klass, r15); // usual case is exact equality __ br(Assembler::NE, L_checkcast_copy); // Identically typed arrays can be copied without element-wise checks. @@ -2159,17 +2162,17 @@ class StubGenerator: public StubCodeGenerator { __ b(RuntimeAddress(oop_copy_entry)); __ BIND(L_checkcast_copy); - // live at this point: scratch_src_klass, scratch_length, r18 (dst_klass) + // live at this point: scratch_src_klass, scratch_length, r15 (dst_klass) { // Before looking at dst.length, make sure dst is also an objArray. - __ ldrw(rscratch1, Address(r18, lh_offset)); + __ ldrw(rscratch1, Address(r15, lh_offset)); __ movw(rscratch2, objArray_lh); __ eorw(rscratch1, rscratch1, rscratch2); __ cbnzw(rscratch1, L_failed); // It is safe to examine both src.length and dst.length. arraycopy_range_checks(src, src_pos, dst, dst_pos, scratch_length, - r18, L_failed); + r15, L_failed); __ load_klass(dst_klass, dst); // reload @@ -5066,42 +5069,42 @@ class StubGenerator: public StubCodeGenerator { // Register allocation - Register reg = c_rarg0; - Pa_base = reg; // Argument registers + RegSetIterator regs = (RegSet::range(r0, r26) - r18_tls).begin(); + Pa_base = *regs; // Argument registers if (squaring) Pb_base = Pa_base; else - Pb_base = ++reg; - Pn_base = ++reg; - Rlen= ++reg; - inv = ++reg; - Pm_base = ++reg; + Pb_base = *++regs; + Pn_base = *++regs; + Rlen= *++regs; + inv = *++regs; + Pm_base = *++regs; // Working registers: - Ra = ++reg; // The current digit of a, b, n, and m. - Rb = ++reg; - Rm = ++reg; - Rn = ++reg; + Ra = *++regs; // The current digit of a, b, n, and m. + Rb = *++regs; + Rm = *++regs; + Rn = *++regs; - Pa = ++reg; // Pointers to the current/next digit of a, b, n, and m. - Pb = ++reg; - Pm = ++reg; - Pn = ++reg; + Pa = *++regs; // Pointers to the current/next digit of a, b, n, and m. + Pb = *++regs; + Pm = *++regs; + Pn = *++regs; - t0 = ++reg; // Three registers which form a - t1 = ++reg; // triple-precision accumuator. - t2 = ++reg; + t0 = *++regs; // Three registers which form a + t1 = *++regs; // triple-precision accumuator. + t2 = *++regs; - Ri = ++reg; // Inner and outer loop indexes. - Rj = ++reg; + Ri = *++regs; // Inner and outer loop indexes. + Rj = *++regs; - Rhi_ab = ++reg; // Product registers: low and high parts - Rlo_ab = ++reg; // of a*b and m*n. - Rhi_mn = ++reg; - Rlo_mn = ++reg; + Rhi_ab = *++regs; // Product registers: low and high parts + Rlo_ab = *++regs; // of a*b and m*n. + Rhi_mn = *++regs; + Rlo_mn = *++regs; // r19 and up are callee-saved. - _toSave = RegSet::range(r19, reg) + Pm_base; + _toSave = RegSet::range(r19, *regs) + Pm_base; } private: 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 3c3063cff2f..0ac7faad767 100644 --- a/src/hotspot/os/windows/os_windows.cpp +++ b/src/hotspot/os/windows/os_windows.cpp @@ -32,6 +32,7 @@ #include "classfile/vmSymbols.hpp" #include "code/codeCache.hpp" #include "code/icBuffer.hpp" +#include "code/nativeInst.hpp" #include "code/vtableStubs.hpp" #include "compiler/compileBroker.hpp" #include "compiler/disassembler.hpp" @@ -119,13 +120,18 @@ 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 INCLUDE_AOT +#if defined(USE_VECTORED_EXCEPTION_HANDLING) +PVOID topLevelVectoredExceptionHandler = NULL; +LPTOP_LEVEL_EXCEPTION_FILTER previousUnhandledExceptionFilter = NULL; +#elif INCLUDE_AOT PVOID topLevelVectoredExceptionHandler = NULL; LONG WINAPI topLevelVectoredExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo); #endif @@ -148,7 +154,7 @@ BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved) { if (ForceTimeHighResolution) { timeEndPeriod(1L); } -#if INCLUDE_AOT +#if defined(USE_VECTORED_EXCEPTION_HANDLING) || INCLUDE_AOT if (topLevelVectoredExceptionHandler != NULL) { RemoveVectoredExceptionHandler(topLevelVectoredExceptionHandler); topLevelVectoredExceptionHandler = NULL; @@ -457,6 +463,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). @@ -466,6 +478,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. @@ -1428,15 +1441,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 @@ -1731,7 +1747,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"); } @@ -2139,7 +2156,14 @@ LONG Handle_Exception(struct _EXCEPTION_POINTERS* exceptionInfo, address handler) { Thread* thread = Thread::current_or_null(); // Save pc in thread -#ifdef _M_AMD64 +#if defined(_M_ARM64) + // Do not blow up if no thread info available. + if (thread) { + thread->as_Java_thread()->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Pc); + } + // Set pc to handler + exceptionInfo->ContextRecord->Pc = (DWORD64)handler; +#elif defined(_M_AMD64) // Do not blow up if no thread info available. if (thread != NULL) { thread->as_Java_thread()->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Rip); @@ -2237,7 +2261,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"); @@ -2268,6 +2302,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; @@ -2313,6 +2348,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) { @@ -2322,66 +2358,14 @@ 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; -} - -#if INCLUDE_AOT -LONG WINAPI topLevelVectoredExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) { - PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord; - address addr = (address) exceptionRecord->ExceptionInformation[1]; - address pc = (address) exceptionInfo->ContextRecord->Rip; - - // 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 - //----------------------------------------------------------------------------- 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; @@ -2464,18 +2448,22 @@ 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; } } #endif // _WIN64 +#if defined(_M_AMD64) || defined(_M_IX86) if ((exception_code == EXCEPTION_ACCESS_VIOLATION) && 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()) { JavaThread* thread = t->as_Java_thread(); @@ -2506,8 +2494,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) { @@ -2563,8 +2553,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 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -2587,6 +2579,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: @@ -2597,19 +2602,75 @@ 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) || INCLUDE_AOT +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. // jni_fast_GetField can trap at certain pc's if a GC kicks in and @@ -3455,7 +3516,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 @@ -3979,7 +4045,10 @@ jint os::init_2(void) { // Setup Windows Exceptions -#if INCLUDE_AOT +#if defined(USE_VECTORED_EXCEPTION_HANDLING) + topLevelVectoredExceptionHandler = AddVectoredExceptionHandler(1, topLevelVectoredExceptionFilter); + previousUnhandledExceptionFilter = SetUnhandledExceptionFilter(topLevelUnhandledExceptionFilter); +#elif INCLUDE_AOT // If AOT is enabled we need to install a vectored exception handler // in order to forward implicit exceptions from code in AOT // generated DLLs. This is necessary since these DLLs are not @@ -5446,7 +5515,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..970b37450ca --- /dev/null +++ b/src/hotspot/os_cpu/windows_aarch64/atomic_windows_aarch64.hpp @@ -0,0 +1,111 @@ +/* + * 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 { + template + D add_and_fetch(D volatile* dest, I add_value, atomic_memory_order order) const; + + template + D fetch_and_add(D volatile* dest, I add_value, atomic_memory_order order) const { + return add_and_fetch(dest, add_value, order) - add_value; + } +}; + +// 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(D volatile* dest, \ + I add_value, \ + 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 volatile* dest, \ + T exchange_value, \ + 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 volatile* dest, \ + T compare_value, \ + T exchange_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..11ec7322a9f --- /dev/null +++ b/src/hotspot/os_cpu/windows_aarch64/orderAccess_windows_aarch64.hpp @@ -0,0 +1,60 @@ +/* + * 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; +} + +inline void OrderAccess::cross_modify_fence() { } + +#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..0a61ef0e95f --- /dev/null +++ b/src/hotspot/os_cpu/windows_aarch64/os_windows_aarch64.cpp @@ -0,0 +1,311 @@ +/* + * 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_DISABLE_MSVC_WARNING(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; +} + +address os::fetch_frame_from_context(const void* ucVoid, + intptr_t** ret_sp, intptr_t** ret_fp) { + address epc; + CONTEXT* uc = (CONTEXT*)ucVoid; + + if (uc != NULL) { + epc = (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; + address epc = fetch_frame_from_context(ucVoid, &sp, &fp); + return frame(sp, fp, epc); +} + +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)) { + // interpreter performs stack banging after the fixed frame header has + // been generated while the compilers perform it before. To maintain + // semantic consistency between interpreted and compiled frames, the + // method returns the Java sender of the current frame. + *fr = os::fetch_frame_from_context((void*)exceptionInfo->ContextRecord); + if (!fr->is_first_java_frame()) { + assert(fr->safe_for_sender(thread), "Safety check"); + *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/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..2b004fd75af --- /dev/null +++ b/src/hotspot/os_cpu/windows_aarch64/thread_windows_aarch64.hpp @@ -0,0 +1,63 @@ +/* + * 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: + static ByteSize last_Java_fp_offset() { + return byte_offset_of(JavaThread, _anchor) + JavaFrameAnchor::last_Java_fp_offset(); + } + + 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(); + } + +#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..80270aa62e1 --- /dev/null +++ b/src/hotspot/os_cpu/windows_aarch64/vm_version_windows_aarch64.cpp @@ -0,0 +1,99 @@ +/* + * 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" + +int VM_Version::get_current_sve_vector_length() { + assert(_features & CPU_SVE, "should not call this"); + ShouldNotReachHere(); + return 0; +} + +int VM_Version::set_and_get_current_sve_vector_lenght(int length) { + assert(_features & CPU_SVE, "should not call this"); + ShouldNotReachHere(); + return 0; +} + +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, CPU_SVE, CPU_SVE2 + + __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 3d7f2401c72..0543463b68d 100644 --- a/src/hotspot/os_cpu/windows_x86/os_windows_x86.cpp +++ b/src/hotspot/os_cpu/windows_x86/os_windows_x86.cpp @@ -354,6 +354,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/gc/g1/g1HeapRegionAttr.hpp b/src/hotspot/share/gc/g1/g1HeapRegionAttr.hpp index 710d2862472..50fc8b8ca97 100644 --- a/src/hotspot/share/gc/g1/g1HeapRegionAttr.hpp +++ b/src/hotspot/share/gc/g1/g1HeapRegionAttr.hpp @@ -32,7 +32,13 @@ // lookups for that information all over the place. struct G1HeapRegionAttr { public: +#if defined(_M_ARM64)&& defined(_MSC_VER) && _MSC_VER <= 1927 + // workaround for MSCV ARM64 bug + // https://developercommunity.visualstudio.com/content/problem/1079221/arm64-bad-code-generation-around-signed-char-arith.html + typedef int32_t region_type_t; +#else typedef int8_t region_type_t; +#endif typedef uint8_t needs_remset_update_t; private: diff --git a/src/hotspot/share/prims/jni.cpp b/src/hotspot/share/prims/jni.cpp index f0f779e3a87..9cfd7e8ba0a 100644 --- a/src/hotspot/share/prims/jni.cpp +++ b/src/hotspot/share/prims/jni.cpp @@ -93,7 +93,7 @@ static jint CurrentVersion = JNI_VERSION_10; -#ifdef _WIN32 +#if defined(_WIN32) && !defined(USE_VECTORED_EXCEPTION_HANDLING) extern LONG WINAPI topLevelExceptionFilter(_EXCEPTION_POINTERS* ); #endif @@ -3841,11 +3841,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. } @@ -3913,11 +3913,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 a929b989f2d..0cf4ae5c721 100644 --- a/src/hotspot/share/utilities/globalDefinitions_visCPP.hpp +++ b/src/hotspot/share/utilities/globalDefinitions_visCPP.hpp @@ -136,4 +136,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_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 96599034c15..5f7dd4ea423 100644 --- a/src/java.base/windows/native/libjava/java_props_md.c +++ b/src/java.base/windows/native/libjava/java_props_md.c @@ -569,6 +569,8 @@ GetJavaProperties(JNIEnv* env) sprops.os_arch = "amd64"; #elif defined(_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..9a12c4bbbff 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, 2020, 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 class AttachProviderImpl extends HotSpotAttachProvider { "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 a9b2bbb85c9..37a12d8f0ac 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 @@ -530,8 +530,10 @@ public class HotSpotAgent { 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 06edec68037..55de9fc57ef 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.io.*; 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 class WindbgDebuggerLocal extends DebuggerBase implements WindbgDebugger 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 59d089ef6bb..80279b3d1c5 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,8 +28,9 @@ import java.util.*; import sun.jvm.hotspot.debugger.*; import sun.jvm.hotspot.types.*; -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; @@ -99,6 +100,8 @@ public class Threads { 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..70abbcefb6a --- /dev/null +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/win32_aarch64/Win32AARCH64JavaThreadPDAccess.java @@ -0,0 +1,140 @@ +/* + * 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.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.*; +import sun.jvm.hotspot.utilities.Observable; +import sun.jvm.hotspot.utilities.Observer; + +/** 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 c8ad8991b2f..52ce1f2d498 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